mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-06-03 06:17:47 -05:00
Merge branch 'master' into mirror-move
This commit is contained in:
commit
341f1663df
|
|
@ -7,9 +7,9 @@ Pokémon Showdown is implemented in SockJS. SockJS is a compatibility
|
|||
layer over raw WebSocket, so you can actually connect to Pokémon
|
||||
Showdown directly using WebSocket:
|
||||
|
||||
ws://sim.smogon.com:8000/showdown/websocket
|
||||
or
|
||||
wss://sim3.psim.us/showdown/websocket
|
||||
or
|
||||
ws://sim3.psim.us:8000/showdown/websocket
|
||||
|
||||
Client implementations you might want to look at for reference include:
|
||||
|
||||
|
|
|
|||
1046
config/formats.ts
1046
config/formats.ts
File diff suppressed because it is too large
Load Diff
|
|
@ -1053,7 +1053,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
flags: {},
|
||||
name: "Dragonize",
|
||||
rating: 4,
|
||||
num: 312, // TODO confirm
|
||||
num: 312,
|
||||
},
|
||||
dragonsmaw: {
|
||||
onModifyAtkPriority: 5,
|
||||
|
|
@ -1111,7 +1111,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
}
|
||||
},
|
||||
onWeather(target, source, effect) {
|
||||
if (target.hasItem('utilityumbrella')) return;
|
||||
if (target.effectiveWeather() !== effect.id) return;
|
||||
if (effect.id === 'raindance' || effect.id === 'primordialsea') {
|
||||
this.heal(target.baseMaxhp / 8);
|
||||
} else if (effect.id === 'sunnyday' || effect.id === 'desolateland') {
|
||||
|
|
@ -1146,14 +1146,14 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
effectspore: {
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (this.checkMoveMakesContact(move, source, target) && !source.status && source.runStatusImmunity('powder')) {
|
||||
if (this.checkMoveMakesContact(move, source, target) && source.runStatusImmunity('powder')) {
|
||||
const r = this.random(100);
|
||||
if (r < 11) {
|
||||
source.setStatus('slp', target);
|
||||
source.trySetStatus('slp', target);
|
||||
} else if (r < 21) {
|
||||
source.setStatus('par', target);
|
||||
source.trySetStatus('par', target);
|
||||
} else if (r < 30) {
|
||||
source.setStatus('psn', target);
|
||||
source.trySetStatus('psn', target);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -2524,7 +2524,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
flags: {},
|
||||
name: "Mega Sol",
|
||||
rating: 3,
|
||||
num: 311, // TODO confirm
|
||||
num: 315,
|
||||
// Partially implemented in Pokemon.effectiveWeather() in sim/pokemon.ts
|
||||
},
|
||||
merciless: {
|
||||
|
|
@ -3237,6 +3237,17 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
rating: 0.5,
|
||||
num: 53,
|
||||
},
|
||||
piercingdrill: {
|
||||
isNonstandard: "Future",
|
||||
onModifyMove(move) {
|
||||
if (move.flags['contact']) delete move.flags['protect'];
|
||||
},
|
||||
// breaking protect handled in Battle#checkMoveBreaksProtect()
|
||||
flags: {},
|
||||
name: "Piercing Drill",
|
||||
rating: 1,
|
||||
num: 311,
|
||||
},
|
||||
pixilate: {
|
||||
onModifyTypePriority: -1,
|
||||
onModifyType(move, pokemon) {
|
||||
|
|
@ -3702,7 +3713,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
raindish: {
|
||||
onWeather(target, source, effect) {
|
||||
if (target.hasItem('utilityumbrella')) return;
|
||||
if (target.effectiveWeather() !== effect.id) return;
|
||||
if (effect.id === 'raindance' || effect.id === 'primordialsea') {
|
||||
this.heal(target.baseMaxhp / 16);
|
||||
}
|
||||
|
|
@ -4145,7 +4156,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
sheerforce: {
|
||||
onModifyMove(move, pokemon) {
|
||||
if (move.secondaries) {
|
||||
if (move.secondaries && !move.hasSheerForceBoost) {
|
||||
delete move.secondaries;
|
||||
// Technically not a secondary effect, but it is negated
|
||||
delete move.self;
|
||||
|
|
@ -4156,7 +4167,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
onBasePowerPriority: 21,
|
||||
onBasePower(basePower, pokemon, target, move) {
|
||||
if (move.hasSheerForce) return this.chainModify([5325, 4096]);
|
||||
if (move.hasSheerForce || move.hasSheerForceBoost) return this.chainModify([5325, 4096]);
|
||||
},
|
||||
flags: {},
|
||||
name: "Sheer Force",
|
||||
|
|
@ -4345,7 +4356,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
}
|
||||
},
|
||||
onWeather(target, source, effect) {
|
||||
if (target.hasItem('utilityumbrella')) return;
|
||||
if (target.effectiveWeather() !== effect.id) return;
|
||||
if (effect.id === 'sunnyday' || effect.id === 'desolateland') {
|
||||
this.damage(target.baseMaxhp / 8, target, target);
|
||||
}
|
||||
|
|
@ -4407,6 +4418,16 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
rating: 4.5,
|
||||
num: 3,
|
||||
},
|
||||
spicyspray: {
|
||||
isNonstandard: "Future",
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
source.trySetStatus('brn', target);
|
||||
},
|
||||
flags: {},
|
||||
name: "Spicy Spray",
|
||||
rating: 3,
|
||||
num: 318,
|
||||
},
|
||||
stakeout: {
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, attacker, defender) {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,11 @@ export const Aliases: import('../sim/dex').AliasesTable = {
|
|||
zeroused: "[Gen 9] ZU",
|
||||
mono: "[Gen 9] Monotype",
|
||||
ag: "[Gen 9] Anything Goes",
|
||||
bss: "[Gen 9] BSS Reg J",
|
||||
vgc: "[Gen 9] VGC 2026 Reg F",
|
||||
bsd: "[Gen 9] VGC 2026 Reg F",
|
||||
champsou: "[Gen 9 Champions] OU",
|
||||
cou: "[Gen 9 Champions] OU",
|
||||
bss: "[Gen 9 Champions] BSS Reg M-A",
|
||||
vgc: "[Gen 9 Champions] VGC 2026 Reg M-A",
|
||||
bsd: "[Gen 9 Champions] VGC 2026 Reg M-A",
|
||||
randdubs: "[Gen 9] Random Doubles Battle",
|
||||
doubles: "[Gen 9] Doubles OU",
|
||||
dou: "[Gen 9] Doubles OU",
|
||||
|
|
@ -91,10 +93,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] Linked",
|
||||
lcotm: "[Gen 9] 350 Cup",
|
||||
ommotm: "[Gen 9] Pokebilities AAA",
|
||||
ommspotlight: "[Gen 9] Pokebilities AAA",
|
||||
omotm: "[Gen 9] Alphabet Cup",
|
||||
lcotm: "[Gen 9] Cross Evolution",
|
||||
ommotm: "[Gen 9] STAAABmons",
|
||||
ommspotlight: "[Gen 9] STAAABmons",
|
||||
|
||||
// mega evos --- 1st ordered alphabetically by species, 2nd by alias
|
||||
megasnow: "Abomasnow-Mega",
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
return 5;
|
||||
},
|
||||
onWeatherModifyDamage(damage, attacker, defender, move) {
|
||||
if (defender.hasItem('utilityumbrella')) return;
|
||||
if (defender.effectiveWeather() !== 'raindance') return;
|
||||
if (move.type === 'Water') {
|
||||
this.debug('rain water boost');
|
||||
return this.chainModify(1.5);
|
||||
|
|
@ -525,7 +525,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
}
|
||||
},
|
||||
onWeatherModifyDamage(damage, attacker, defender, move) {
|
||||
if (defender.hasItem('utilityumbrella')) return;
|
||||
if (defender.effectiveWeather() !== 'primordialsea') return;
|
||||
if (move.type === 'Water') {
|
||||
this.debug('Rain water boost');
|
||||
return this.chainModify(1.5);
|
||||
|
|
@ -554,11 +554,11 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
return 5;
|
||||
},
|
||||
onWeatherModifyDamage(damage, attacker, defender, move) {
|
||||
if (move.id === 'hydrosteam' && !attacker.hasItem('utilityumbrella')) {
|
||||
if (move.id === 'hydrosteam' && attacker.effectiveWeather() === 'sunnyday') {
|
||||
this.debug('Sunny Day Hydro Steam boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
if (defender.hasItem('utilityumbrella')) return;
|
||||
if (defender.effectiveWeather() !== 'sunnyday') return;
|
||||
if (move.type === 'Fire') {
|
||||
this.debug('Sunny Day fire boost');
|
||||
return this.chainModify(1.5);
|
||||
|
|
@ -577,7 +577,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
}
|
||||
},
|
||||
onImmunity(type, pokemon) {
|
||||
if (pokemon.hasItem('utilityumbrella')) return;
|
||||
if (pokemon.effectiveWeather() !== 'sunnyday') return;
|
||||
if (type === 'frz') return false;
|
||||
},
|
||||
onFieldResidualOrder: 1,
|
||||
|
|
@ -603,9 +603,9 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
}
|
||||
},
|
||||
onWeatherModifyDamage(damage, attacker, defender, move) {
|
||||
if (defender.hasItem('utilityumbrella')) return;
|
||||
if (defender.effectiveWeather() !== 'desolateland') return;
|
||||
if (move.type === 'Fire') {
|
||||
this.debug('Sunny Day fire boost');
|
||||
this.debug('Desolate Land fire boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
|
|
@ -613,7 +613,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
this.add('-weather', 'DesolateLand', '[from] ability: ' + effect.name, `[of] ${source}`);
|
||||
},
|
||||
onImmunity(type, pokemon) {
|
||||
if (pokemon.hasItem('utilityumbrella')) return;
|
||||
if (pokemon.effectiveWeather() !== 'desolateland') return;
|
||||
if (type === 'frz') return false;
|
||||
},
|
||||
onFieldResidualOrder: 1,
|
||||
|
|
@ -894,11 +894,12 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
|
||||
if (ironHeadIndex >= 0) {
|
||||
const move = this.dex.moves.get('behemothblade');
|
||||
const pp = this.calculatePP(move, pokemon.ppUps[ironHeadIndex]);
|
||||
pokemon.baseMoveSlots[ironHeadIndex] = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
pp,
|
||||
maxpp: pp,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
disabledSource: '',
|
||||
|
|
@ -923,11 +924,12 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
|
||||
if (ironHeadIndex >= 0) {
|
||||
const move = this.dex.moves.get('behemothbash');
|
||||
const pp = this.calculatePP(move, pokemon.ppUps[ironHeadIndex]);
|
||||
pokemon.baseMoveSlots[ironHeadIndex] = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
pp,
|
||||
maxpp: pp,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
disabledSource: '',
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
beedrillmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
pidgey: {
|
||||
isNonstandard: "Past",
|
||||
|
|
@ -381,7 +381,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "NFE",
|
||||
},
|
||||
vileplume: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -464,7 +464,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "LC",
|
||||
},
|
||||
primeape: {
|
||||
tier: "ZU",
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
natDexTier: "NFE",
|
||||
},
|
||||
|
|
@ -475,7 +475,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "LC",
|
||||
},
|
||||
arcanine: {
|
||||
tier: "PU",
|
||||
tier: "NU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -613,7 +613,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
slowbro: {
|
||||
tier: "RU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "OU",
|
||||
},
|
||||
slowbromega: {
|
||||
isNonstandard: "Past",
|
||||
|
|
@ -621,7 +621,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "RUBL",
|
||||
},
|
||||
slowbrogalar: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -1116,7 +1116,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "NFE",
|
||||
},
|
||||
porygon2: {
|
||||
tier: "ZUBL",
|
||||
tier: "PU",
|
||||
doublesTier: "DUU",
|
||||
natDexTier: "NFE",
|
||||
},
|
||||
|
|
@ -1159,7 +1159,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "LC",
|
||||
},
|
||||
snorlax: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -1194,7 +1194,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
},
|
||||
moltresgalar: {
|
||||
tier: "UUBL",
|
||||
doublesTier: "DUU",
|
||||
doublesTier: "DOU",
|
||||
natDexTier: "RUBL",
|
||||
},
|
||||
dratini: {
|
||||
|
|
@ -1228,7 +1228,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "Uber",
|
||||
},
|
||||
mew: {
|
||||
tier: "RU",
|
||||
tier: "UU",
|
||||
doublesTier: "DUU",
|
||||
natDexTier: "UU",
|
||||
},
|
||||
|
|
@ -1316,7 +1316,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "LC",
|
||||
},
|
||||
lanturn: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -1521,17 +1521,19 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "RU",
|
||||
},
|
||||
heracross: {
|
||||
tier: "PUBL",
|
||||
tier: "PU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
heracrossmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RUBL",
|
||||
},
|
||||
sneasel: {
|
||||
tier: "NFE",
|
||||
tier: "ZU",
|
||||
doublesTier: "NFE",
|
||||
natDexTier: "NFE",
|
||||
},
|
||||
sneaselhisui: {
|
||||
tier: "ZU",
|
||||
|
|
@ -1557,7 +1559,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
ursaluna: {
|
||||
tier: "UUBL",
|
||||
doublesTier: "DOU",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RUBL",
|
||||
},
|
||||
ursalunabloodmoon: {
|
||||
tier: "Uber",
|
||||
|
|
@ -1579,7 +1581,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "NFE",
|
||||
},
|
||||
mamoswine: {
|
||||
tier: "RUBL",
|
||||
tier: "UU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RUBL",
|
||||
},
|
||||
|
|
@ -1700,7 +1702,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tyranitarmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
natDexTier: "UUBL",
|
||||
natDexTier: "OU",
|
||||
},
|
||||
lugia: {
|
||||
tier: "Uber",
|
||||
|
|
@ -1758,7 +1760,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
swampert: {
|
||||
tier: "NU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
natDexTier: "UU",
|
||||
},
|
||||
swampertmega: {
|
||||
isNonstandard: "Past",
|
||||
|
|
@ -1877,11 +1879,11 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
gardevoirmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
natDexTier: "RUBL",
|
||||
natDexTier: "UU",
|
||||
},
|
||||
gallade: {
|
||||
tier: "RU",
|
||||
doublesTier: "(DUU)",
|
||||
doublesTier: "DUU",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
gallademega: {
|
||||
|
|
@ -1980,7 +1982,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
sableyemega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
natDexTier: "RUBL",
|
||||
natDexTier: "UU",
|
||||
},
|
||||
mawile: {
|
||||
isNonstandard: "Past",
|
||||
|
|
@ -2701,7 +2703,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "LC",
|
||||
},
|
||||
skuntank: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -2838,12 +2840,12 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "RU",
|
||||
},
|
||||
rotommow: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
uxie: {
|
||||
tier: "PU",
|
||||
tier: "NU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -2926,7 +2928,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "Illegal",
|
||||
},
|
||||
shaymin: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -3136,7 +3138,9 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "LC",
|
||||
},
|
||||
gurdurr: {
|
||||
tier: "NFE",
|
||||
tier: "ZU",
|
||||
doublesTier: "NFE",
|
||||
natDexTier: "NFE",
|
||||
},
|
||||
conkeldurr: {
|
||||
tier: "UU",
|
||||
|
|
@ -3290,7 +3294,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "NFE",
|
||||
},
|
||||
scrafty: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
doublesTier: "DUU",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -3646,7 +3650,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
mandibuzz: {
|
||||
tier: "UU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
heatmor: {
|
||||
isNonstandard: "Past",
|
||||
|
|
@ -3665,7 +3669,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "NFE",
|
||||
},
|
||||
hydreigon: {
|
||||
tier: "RUBL",
|
||||
tier: "UU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "UU",
|
||||
},
|
||||
|
|
@ -3683,7 +3687,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "RU",
|
||||
},
|
||||
terrakion: {
|
||||
tier: "NUBL",
|
||||
tier: "RU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RUBL",
|
||||
},
|
||||
|
|
@ -3848,7 +3852,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "NFE",
|
||||
},
|
||||
talonflame: {
|
||||
tier: "RU",
|
||||
tier: "UU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -4197,7 +4201,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
},
|
||||
hoopaunbound: {
|
||||
tier: "UUBL",
|
||||
doublesTier: "(DUU)",
|
||||
doublesTier: "DUU",
|
||||
natDexTier: "UUBL",
|
||||
},
|
||||
volcanion: {
|
||||
|
|
@ -4241,7 +4245,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
primarina: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
pikipek: {
|
||||
tier: "LC",
|
||||
|
|
@ -4294,7 +4298,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "Illegal",
|
||||
},
|
||||
oricorio: {
|
||||
tier: "ZU",
|
||||
tier: "ZUBL",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -4304,7 +4308,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "RU",
|
||||
},
|
||||
oricoriopau: {
|
||||
tier: "ZU",
|
||||
tier: "ZUBL",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -4342,7 +4346,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "RU",
|
||||
},
|
||||
lycanrocdusk: {
|
||||
tier: "RU",
|
||||
tier: "NUBL",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -4448,7 +4452,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "RU",
|
||||
},
|
||||
passimian: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -4460,7 +4464,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
golisopod: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
golisopodmega: {
|
||||
isNonstandard: "Future",
|
||||
|
|
@ -4717,7 +4721,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "RU",
|
||||
},
|
||||
necrozma: {
|
||||
tier: "NUBL",
|
||||
tier: "RU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -4777,7 +4781,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
zeraora: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
natDexTier: "RU",
|
||||
natDexTier: "UU",
|
||||
},
|
||||
zeraoramega: {
|
||||
isNonstandard: "Future",
|
||||
|
|
@ -4808,7 +4812,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
rillaboom: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "OU",
|
||||
},
|
||||
rillaboomgmax: {
|
||||
isNonstandard: "Past",
|
||||
|
|
@ -4998,7 +5002,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "LC",
|
||||
},
|
||||
barraskewda: {
|
||||
tier: "NU",
|
||||
tier: "RU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -5006,7 +5010,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
tier: "LC",
|
||||
},
|
||||
toxtricity: {
|
||||
tier: "NU",
|
||||
tier: "RU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -5154,7 +5158,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
dracozolt: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
arctozolt: {
|
||||
isNonstandard: "Past",
|
||||
|
|
@ -5351,7 +5355,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
lokix: {
|
||||
tier: "UU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
rellor: {
|
||||
tier: "LC",
|
||||
|
|
@ -5548,7 +5552,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
garganacl: {
|
||||
tier: "OU",
|
||||
doublesTier: "DUU",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
glimmet: {
|
||||
tier: "LC",
|
||||
|
|
@ -5556,7 +5560,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
glimmora: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
natDexTier: "RU",
|
||||
natDexTier: "UU",
|
||||
},
|
||||
glimmoramega: {
|
||||
isNonstandard: "Future",
|
||||
|
|
@ -5686,7 +5690,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "Uber",
|
||||
},
|
||||
wochien: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -5727,7 +5731,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
ceruledge: {
|
||||
tier: "OU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "UUBL",
|
||||
natDexTier: "OU",
|
||||
},
|
||||
toedscool: {
|
||||
tier: "LC",
|
||||
|
|
@ -5772,7 +5776,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
},
|
||||
okidogi: {
|
||||
tier: "UUBL",
|
||||
doublesTier: "(DUU)",
|
||||
doublesTier: "DOU",
|
||||
natDexTier: "UUBL",
|
||||
},
|
||||
munkidori: {
|
||||
|
|
@ -5786,7 +5790,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
natDexTier: "RU",
|
||||
},
|
||||
ogerpon: {
|
||||
tier: "UU",
|
||||
tier: "OU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "RU",
|
||||
},
|
||||
|
|
@ -5828,7 +5832,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
ironboulder: {
|
||||
tier: "UUBL",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "RUBL",
|
||||
},
|
||||
ironcrown: {
|
||||
tier: "OU",
|
||||
|
|
@ -5848,7 +5852,7 @@ export const FormatsData: import('../sim/dex-species').SpeciesFormatsDataTable =
|
|||
pecharunt: {
|
||||
tier: "OU",
|
||||
doublesTier: "(DUU)",
|
||||
natDexTier: "UU",
|
||||
natDexTier: "UUBL",
|
||||
},
|
||||
missingno: {
|
||||
isNonstandard: "Custom",
|
||||
|
|
|
|||
|
|
@ -3362,8 +3362,8 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
|
|||
const moveSlot = pokemon.moveSlots.find(move => move.pp === 0) ||
|
||||
pokemon.moveSlots.find(move => move.pp < move.maxpp);
|
||||
if (!moveSlot) return;
|
||||
moveSlot.pp += 10;
|
||||
if (moveSlot.pp > moveSlot.maxpp) moveSlot.pp = moveSlot.maxpp;
|
||||
const addedPP = pokemon.hasAbility('ripen') ? 20 : 10;
|
||||
moveSlot.pp = Math.min(moveSlot.pp + addedPP, moveSlot.maxpp);
|
||||
this.add('-activate', pokemon, 'item: Leppa Berry', moveSlot.move, '[consumed]');
|
||||
},
|
||||
num: 154,
|
||||
|
|
|
|||
231
data/mods/afd/abilities.ts
Normal file
231
data/mods/afd/abilities.ts
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
|
||||
chaossaliva: {
|
||||
onSourceDamagingHit(damage, target, source, move) {
|
||||
// Despite not being a secondary, Shield Dust / Covert Cloak block Poison Touch's effect
|
||||
if (target.hasAbility('shielddust') || target.hasItem('covertcloak')) return;
|
||||
if (this.checkMoveMakesContact(move, target, source)) {
|
||||
if (this.randomChance(2, 10)) {
|
||||
target.trySetStatus('par', source);
|
||||
}
|
||||
if (this.randomChance(2, 10)) {
|
||||
target.addVolatile('confusion', source);
|
||||
}
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Chaos Saliva",
|
||||
gen: 9,
|
||||
shortDesc: "Contact moves have a 20% chance to paralyze and a 20% chance to confuse.",
|
||||
},
|
||||
faststart: {
|
||||
onStart(pokemon) {
|
||||
this.add('-start', pokemon, 'ability: Fast Start');
|
||||
this.effectState.counter = 5;
|
||||
},
|
||||
onResidualOrder: 28,
|
||||
onResidualSubOrder: 2,
|
||||
onResidual(pokemon) {
|
||||
if (pokemon.activeTurns && this.effectState.counter) {
|
||||
this.effectState.counter--;
|
||||
if (!this.effectState.counter) {
|
||||
this.add('-end', pokemon, 'Fast Start');
|
||||
delete this.effectState.counter;
|
||||
}
|
||||
}
|
||||
},
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, pokemon) {
|
||||
if (this.effectState.counter) {
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
onModifySpe(spe, pokemon) {
|
||||
if (this.effectState.counter) {
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
if (pokemon.beingCalledBack) return;
|
||||
this.add('-end', pokemon, 'Fast Start', '[silent]');
|
||||
},
|
||||
flags: {},
|
||||
name: "Fast Start",
|
||||
rating: -1,
|
||||
gen: 9,
|
||||
},
|
||||
ironfist: {
|
||||
inherit: true,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.flags['punch']) {
|
||||
this.debug('Iron Fist boost');
|
||||
return this.chainModify([8192, 4096]);
|
||||
}
|
||||
},
|
||||
},
|
||||
supermegalauncher: {
|
||||
onBasePowerPriority: 19,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.flags['pulse']) {
|
||||
return this.chainModify(4);
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Mega Launcher",
|
||||
desc: "This Pokemon's pulse moves have their power multiplied by 4. Heal Pulse restores 8/4 of a target's maximum HP, rounded half down.",
|
||||
shortDesc: "This Pokemon's pulse moves have 4x power. Heal Pulse heals 8/4 target's max HP.",
|
||||
rating: 3,
|
||||
gen: 9,
|
||||
},
|
||||
discourage: {
|
||||
onStart(pokemon) {
|
||||
let activated = false;
|
||||
for (const target of pokemon.adjacentFoes()) {
|
||||
if (!activated) {
|
||||
this.add('-ability', pokemon, 'Discourage', 'boost');
|
||||
activated = true;
|
||||
}
|
||||
if (target.volatiles['substitute']) {
|
||||
this.add('-immune', target);
|
||||
} else {
|
||||
this.boost({ spa: -1 }, target, pokemon, null, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Discourage",
|
||||
rating: 3.5,
|
||||
num: 999,
|
||||
gen: 9,
|
||||
},
|
||||
adaptability: {
|
||||
inherit: true,
|
||||
onModifySTAB(stab, source, target, move) {
|
||||
if (move.forceSTAB || source.hasType(move.type)) {
|
||||
const types = source.getTypes();
|
||||
if (types[0] === move.type) return 2.3;
|
||||
if (types[1] && types[1] === move.type) return 1.6;
|
||||
if (stab === 2.3) {
|
||||
return 2.55;
|
||||
}
|
||||
return 2.7;
|
||||
}
|
||||
},
|
||||
},
|
||||
icebody: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (this.checkMoveMakesContact(move, source, target)) {
|
||||
if (this.randomChance(1, 10)) {
|
||||
source.trySetStatus('frz', target);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
noretreat: {
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'move: No Retreat');
|
||||
},
|
||||
onFoeBeforeSwitchOut(pokemon) {
|
||||
if (!pokemon || pokemon.fainted || pokemon.hp <= 0 || pokemon.hasAbility('noretreat')) return;
|
||||
const success = !!this.damage(pokemon.maxhp / 4, pokemon, this.effectState.target);
|
||||
if (success) {
|
||||
pokemon.tryTrap();
|
||||
}
|
||||
},
|
||||
name: "No Retreat",
|
||||
flags: { breakable: 1 },
|
||||
},
|
||||
itsexcadrillintime: {
|
||||
onModifySpe(spe, pokemon) {
|
||||
if (this.field.isWeather('sandstorm')) {
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
onImmunity(type, pokemon) {
|
||||
if (type === 'sandstorm') return false;
|
||||
},
|
||||
onBasePowerPriority: 21,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (this.field.isWeather('sandstorm')) {
|
||||
if (move.type === 'Rock' || move.type === 'Ground' || move.type === 'Steel') {
|
||||
this.debug('Sand Force boost');
|
||||
return this.chainModify([5325, 4096]);
|
||||
}
|
||||
}
|
||||
},
|
||||
name: "It's Excadrillin' Time!",
|
||||
flags: {},
|
||||
},
|
||||
goodasgold: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (move.category !== 'Special' && target !== source) {
|
||||
this.add('-immune', target, '[from] ability: Good as Gold');
|
||||
return null;
|
||||
}
|
||||
},
|
||||
},
|
||||
intimidate2: {
|
||||
onStart(pokemon) {
|
||||
let activated = false;
|
||||
let timesActivated = 0;
|
||||
for (const target of pokemon.adjacentFoes()) {
|
||||
if (!activated) {
|
||||
this.add('-ability', pokemon, 'Intimidate 2', 'boost');
|
||||
activated = true;
|
||||
}
|
||||
if (target.volatiles['substitute']) {
|
||||
this.add('-immune', target);
|
||||
} else {
|
||||
this.boost({ atk: -1 }, target, pokemon, null, true);
|
||||
timesActivated++;
|
||||
}
|
||||
}
|
||||
if (timesActivated > 0) {
|
||||
for (let i = 0; i < timesActivated; i++) {
|
||||
this.boost({ atk: 1 }, pokemon, pokemon, null, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Intimidate 2",
|
||||
rating: 3.5,
|
||||
num: 22,
|
||||
},
|
||||
asonemonarch: {
|
||||
onSwitchInPriority: 1,
|
||||
onStart(pokemon) {
|
||||
if (this.effectState.unnerved) return;
|
||||
this.add('-ability', pokemon, 'As One');
|
||||
this.add('-ability', pokemon, 'Unnerve');
|
||||
this.effectState.unnerved = true;
|
||||
},
|
||||
onEnd() {
|
||||
this.effectState.unnerved = false;
|
||||
},
|
||||
onFoeTryEatItem() {
|
||||
return !this.effectState.unnerved;
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
|
||||
name: "As One (Monarch)",
|
||||
rating: 3.5,
|
||||
num: 266,
|
||||
},
|
||||
intimidate: {
|
||||
inherit: true,
|
||||
onStart(pokemon) {
|
||||
let activated = false;
|
||||
for (const target of pokemon.adjacentFoes()) {
|
||||
if (!activated) {
|
||||
this.add('-ability', pokemon, 'Intimidate', 'boost');
|
||||
activated = true;
|
||||
}
|
||||
if (target.volatiles['substitute']) {
|
||||
this.add('-immune', target);
|
||||
} else {
|
||||
this.boost({ atk: -2 }, target, pokemon, null, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
22
data/mods/afd/conditions.ts
Normal file
22
data/mods/afd/conditions.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDataTable = {
|
||||
sandstorm: {
|
||||
inherit: true,
|
||||
onWeatherModifyDamage(damage, attacker, defender, move) {
|
||||
if (defender.hasItem('utilityumbrella')) return;
|
||||
if (move.type === 'Rock') {
|
||||
this.debug('Sandstorm rock boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
snowscape: {
|
||||
inherit: true,
|
||||
onModifySpePriority: 10,
|
||||
onModifySpe(spe, pokemon) {
|
||||
if (!pokemon.getTypes(false, true).includes('Ice') && !pokemon.getTypes(false, true).includes('Steel') &&
|
||||
!pokemon.hasAbility(['slushrush', 'snowcloak', 'iceface', 'icebody']) && pokemon.effectiveWeather() === 'snowscape') {
|
||||
return this.modify(spe, 0.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
93
data/mods/afd/items.ts
Normal file
93
data/mods/afd/items.ts
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
||||
hoots: {
|
||||
name: "Hoots",
|
||||
spritenum: 715,
|
||||
fling: {
|
||||
basePower: 80,
|
||||
},
|
||||
num: 1120,
|
||||
gen: 8,
|
||||
// Hazard Immunity implemented in moves.ts
|
||||
},
|
||||
luckycharm: {
|
||||
name: "Lucky Charm",
|
||||
onModifyMovePriority: -2,
|
||||
onModifyMove(move, pokemon, target) {
|
||||
let trigger = false;
|
||||
if (move.secondaries) {
|
||||
this.debug('doubling secondary chance');
|
||||
for (const secondary of move.secondaries) {
|
||||
if (secondary.chance && secondary.chance < 100) {
|
||||
secondary.chance = 100;
|
||||
if (!trigger) trigger = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (move.self?.chance) {
|
||||
move.self.chance = 100;
|
||||
trigger = true;
|
||||
}
|
||||
if (trigger) {
|
||||
pokemon.useItem();
|
||||
}
|
||||
},
|
||||
spritenum: 707,
|
||||
fling: {
|
||||
basePower: 120,
|
||||
},
|
||||
num: 9999,
|
||||
gen: 9,
|
||||
},
|
||||
onikaburger: {
|
||||
name: "Onika Burger",
|
||||
desc: "PP and damage of every move is halved. Gain 25% max HP at the end of each turn.",
|
||||
shortDesc: "PP and damage of every move is halved. Gain 25% max HP at the end of each turn.",
|
||||
onStart(target) {
|
||||
if (target.m.onikaBurger) return;
|
||||
target.m.onikaBurger = true;
|
||||
for (const moveSlot of target.moveSlots) {
|
||||
const deductPP = target.deductPP(moveSlot.id, moveSlot.maxpp / 2, target);
|
||||
if (!deductPP) continue;
|
||||
this.add('-activate', target, 'item: Onika Burger', moveSlot.move, deductPP);
|
||||
}
|
||||
},
|
||||
onModifyDamage() {
|
||||
return this.chainModify(0.5);
|
||||
},
|
||||
onResidualOrder: 5,
|
||||
onResidualSubOrder: 4,
|
||||
onResidual(pokemon) {
|
||||
this.heal(pokemon.baseMaxhp / 4);
|
||||
},
|
||||
},
|
||||
wardtag: {
|
||||
name: "Ward Tag",
|
||||
desc: "Reflects back 125% of the damage that would've been dealt. One-time use.",
|
||||
shortDesc: "Reflects back 125% of the damage that would've been dealt. One-time use.",
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (source && target !== source && effect?.effectType === 'Move' && target.useItem()) {
|
||||
this.add('-activate', target, 'item: Ward Tag');
|
||||
this.damage(damage * 5 / 4, source, target);
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
strengthpolicy: {
|
||||
name: "Strength Policy",
|
||||
spritenum: 609,
|
||||
fling: {
|
||||
basePower: 80,
|
||||
},
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (!move.damage && !move.damageCallback && target.getMoveHitData(move).typeMod < 0) {
|
||||
target.useItem();
|
||||
}
|
||||
},
|
||||
boosts: {
|
||||
def: 2,
|
||||
spd: 2,
|
||||
},
|
||||
num: 639,
|
||||
gen: 6,
|
||||
},
|
||||
};
|
||||
599
data/mods/afd/moves.ts
Normal file
599
data/mods/afd/moves.ts
Normal file
|
|
@ -0,0 +1,599 @@
|
|||
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||
banefulbunker: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
if (!this.randomChance(2, 10)) {
|
||||
this.add('-activate', target, 'move: Protect');
|
||||
if (move.basePower >= 100) {
|
||||
this.add('message', '**BWUAHAAUAAAANGGGGGG**');
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
// Outrage counter is reset
|
||||
if (source.volatiles['lockedmove'].duration === 2) {
|
||||
delete source.volatiles['lockedmove'];
|
||||
}
|
||||
}
|
||||
if (this.checkMoveMakesContact(move, source, target)) {
|
||||
source.trySetStatus('psn', target);
|
||||
}
|
||||
return this.NOT_FAIL;
|
||||
},
|
||||
},
|
||||
},
|
||||
burningbulwark: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
if (!this.randomChance(2, 10)) {
|
||||
this.add('-activate', target, 'move: Protect');
|
||||
if (move.basePower >= 100) {
|
||||
this.add('message', '**BWUAHAAUAAAANGGGGGG**');
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
// Outrage counter is reset
|
||||
if (source.volatiles['lockedmove'].duration === 2) {
|
||||
delete source.volatiles['lockedmove'];
|
||||
}
|
||||
}
|
||||
if (this.checkMoveMakesContact(move, source, target)) {
|
||||
source.trySetStatus('brn', target);
|
||||
}
|
||||
return this.NOT_FAIL;
|
||||
},
|
||||
},
|
||||
},
|
||||
kingsshield: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
if (!this.randomChance(2, 10)) {
|
||||
this.add('-activate', target, 'move: Protect');
|
||||
if (move.basePower >= 100) {
|
||||
this.add('message', '**BWUAHAAUAAAANGGGGGG**');
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
// Outrage counter is reset
|
||||
if (source.volatiles['lockedmove'].duration === 2) {
|
||||
delete source.volatiles['lockedmove'];
|
||||
}
|
||||
}
|
||||
if (this.checkMoveMakesContact(move, source, target)) {
|
||||
this.boost({ atk: -1 }, source, target, this.dex.getActiveMove("King's Shield"));
|
||||
}
|
||||
return this.NOT_FAIL;
|
||||
},
|
||||
},
|
||||
},
|
||||
maxguard: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
const bypassesMaxGuard = [
|
||||
'acupressure', 'afteryou', 'allyswitch', 'aromatherapy', 'aromaticmist', 'coaching', 'confide', 'copycat', 'curse', 'decorate', 'doomdesire', 'feint', 'futuresight', 'gmaxoneblow', 'gmaxrapidflow', 'healbell', 'holdhands', 'howl', 'junglehealing', 'lifedew', 'meanlook', 'perishsong', 'playnice', 'powertrick', 'roar', 'roleplay', 'tearfullook',
|
||||
];
|
||||
if (bypassesMaxGuard.includes(move.id)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
if (!this.randomChance(2, 10)) {
|
||||
this.add('-activate', target, 'move: Protect');
|
||||
if (move.basePower >= 100) {
|
||||
this.add('message', '**BWUAHAAUAAAANGGGGGG**');
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
// Outrage counter is reset
|
||||
if (source.volatiles['lockedmove'].duration === 2) {
|
||||
delete source.volatiles['lockedmove'];
|
||||
}
|
||||
}
|
||||
return this.NOT_FAIL;
|
||||
},
|
||||
},
|
||||
},
|
||||
meteorbeam: {
|
||||
inherit: true,
|
||||
onTryMove(attacker, defender, move) {
|
||||
if (attacker.removeVolatile(move.id)) {
|
||||
return;
|
||||
}
|
||||
this.add('-prepare', attacker, move.name);
|
||||
this.boost({ spa: 1 }, attacker, attacker, move);
|
||||
if (['sandstorm'].includes(attacker.effectiveWeather())) {
|
||||
this.attrLastMove('[still]');
|
||||
this.addMove('-anim', attacker, move.name, defender);
|
||||
return;
|
||||
}
|
||||
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
||||
return;
|
||||
}
|
||||
attacker.addVolatile('twoturnmove', defender);
|
||||
return null;
|
||||
},
|
||||
},
|
||||
obstruct: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
if (!this.randomChance(2, 10)) {
|
||||
this.add('-activate', target, 'move: Protect');
|
||||
if (move.basePower >= 100) {
|
||||
this.add('message', '**BWUAHAAUAAAANGGGGGG**');
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
// Outrage counter is reset
|
||||
if (source.volatiles['lockedmove'].duration === 2) {
|
||||
delete source.volatiles['lockedmove'];
|
||||
}
|
||||
}
|
||||
if (this.checkMoveMakesContact(move, source, target)) {
|
||||
this.boost({ def: -2 }, source, target, this.dex.getActiveMove("Obstruct"));
|
||||
}
|
||||
return this.NOT_FAIL;
|
||||
},
|
||||
},
|
||||
},
|
||||
protect: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
if (!this.randomChance(2, 10)) {
|
||||
this.add('-activate', target, 'move: Protect');
|
||||
if (move.basePower >= 100) {
|
||||
this.add('message', '**BWUAHAAUAAAANGGGGGG**');
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
// Outrage counter is reset
|
||||
if (source.volatiles['lockedmove'].duration === 2) {
|
||||
delete source.volatiles['lockedmove'];
|
||||
}
|
||||
}
|
||||
return this.NOT_FAIL;
|
||||
},
|
||||
},
|
||||
},
|
||||
silktrap: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
if (!this.randomChance(2, 10)) {
|
||||
this.add('-activate', target, 'move: Protect');
|
||||
if (move.basePower >= 100) {
|
||||
this.add('message', '**BWUAHAAUAAAANGGGGGG**');
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
// Outrage counter is reset
|
||||
if (source.volatiles['lockedmove'].duration === 2) {
|
||||
delete source.volatiles['lockedmove'];
|
||||
}
|
||||
}
|
||||
if (this.checkMoveMakesContact(move, source, target)) {
|
||||
this.boost({ spe: -1 }, source, target, this.dex.getActiveMove("Silk Trap"));
|
||||
}
|
||||
return this.NOT_FAIL;
|
||||
},
|
||||
},
|
||||
},
|
||||
spikyshield: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
if (!this.randomChance(2, 10)) {
|
||||
this.add('-activate', target, 'move: Protect');
|
||||
if (move.basePower >= 100) {
|
||||
this.add('message', '**BWUAHAAUAAAANGGGGGG**');
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
// Outrage counter is reset
|
||||
if (source.volatiles['lockedmove'].duration === 2) {
|
||||
delete source.volatiles['lockedmove'];
|
||||
}
|
||||
}
|
||||
if (this.checkMoveMakesContact(move, source, target)) {
|
||||
this.damage(source.baseMaxhp / 8, source, target);
|
||||
}
|
||||
return this.NOT_FAIL;
|
||||
},
|
||||
},
|
||||
},
|
||||
stealthrock: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'Stealth Rock');
|
||||
this.effectState.layers = 1;
|
||||
},
|
||||
onSideRestart(side) {
|
||||
if (this.effectState.layers >= 5) return false;
|
||||
this.add('-sidestart', side, 'Stealth Rock');
|
||||
this.effectState.layers++;
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.hasItem(['heavydutyboots', 'hoots'])) return;
|
||||
const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6);
|
||||
const damageAmounts = [0, 1, 2, 3, 4, 5]; // 2 ** typeMod / 8
|
||||
this.damage((damageAmounts[this.effectState.layers] / 5) * pokemon.maxhp * ((2 ** typeMod) / 8));
|
||||
},
|
||||
},
|
||||
},
|
||||
gmaxsteelsurge: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'G-Max Steelsurge');
|
||||
this.effectState.layers = 1;
|
||||
},
|
||||
onSideRestart(side) {
|
||||
if (this.effectState.layers >= 5) return false;
|
||||
this.add('-sidestart', side, 'G-Max Steelsurge');
|
||||
this.effectState.layers++;
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.hasItem(['heavydutyboots', 'hoots'])) return;
|
||||
const steelHazard = this.dex.getActiveMove('Stealth Rock');
|
||||
steelHazard.type = 'Steel';
|
||||
const typeMod = this.clampIntRange(pokemon.runEffectiveness(steelHazard), -6, 6);
|
||||
const damageAmounts = [0, 1, 2, 3, 4, 5]; // 2 ** typeMod / 8
|
||||
this.damage((damageAmounts[this.effectState.layers] / 5) * pokemon.maxhp * ((2 ** typeMod) / 8));
|
||||
},
|
||||
},
|
||||
},
|
||||
spikes: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded() || pokemon.hasItem(['heavydutyboots', 'hoots'])) return;
|
||||
const damageAmounts = [0, 3, 4, 6]; // 1/8, 1/6, 1/4
|
||||
this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
|
||||
},
|
||||
},
|
||||
},
|
||||
stickyweb: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded() || pokemon.hasItem(['heavydutyboots', 'hoots'])) return;
|
||||
this.add('-activate', pokemon, 'move: Sticky Web');
|
||||
this.boost({ spe: -1 }, pokemon, pokemon.side.foe.active[0], this.dex.getActiveMove('stickyweb'));
|
||||
},
|
||||
},
|
||||
},
|
||||
toxicspikes: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded()) return;
|
||||
if (pokemon.hasType('Poison')) {
|
||||
this.add('-sideend', pokemon.side, 'move: Toxic Spikes', `[of] ${pokemon}`);
|
||||
pokemon.side.removeSideCondition('toxicspikes');
|
||||
} else if (pokemon.hasType('Steel') || pokemon.hasItem(['heavydutyboots', 'hoots'])) {
|
||||
// do nothing
|
||||
} else if (this.effectState.layers >= 2) {
|
||||
pokemon.trySetStatus('tox', pokemon.side.foe.active[0]);
|
||||
} else {
|
||||
pokemon.trySetStatus('psn', pokemon.side.foe.active[0]);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
suckerpunch: {
|
||||
inherit: true,
|
||||
onTry() { },
|
||||
onModifyPriority(priority, source, target, move) {
|
||||
if (!target) return priority - 1;
|
||||
const action = this.queue.willMove(target);
|
||||
const aMove = action?.choice === 'move' ? action.move : null;
|
||||
if (!aMove || (aMove.category === 'Status' && aMove.id !== 'mefirst') || target.volatiles['mustrecharge']) {
|
||||
return priority - 1;
|
||||
}
|
||||
return priority;
|
||||
},
|
||||
},
|
||||
thousandarrows: {
|
||||
inherit: true,
|
||||
basePower: 120,
|
||||
},
|
||||
healpulse: {
|
||||
inherit: true,
|
||||
onHit(target, source) {
|
||||
let success = false;
|
||||
if (source.hasAbility('supermegalauncher')) {
|
||||
success = !!this.heal(this.modify(target.baseMaxhp, 2));
|
||||
} else if (source.hasAbility('megalauncher')) {
|
||||
success = !!this.heal(this.modify(target.baseMaxhp, 0.75));
|
||||
} else {
|
||||
success = !!this.heal(Math.ceil(target.baseMaxhp * 0.5));
|
||||
}
|
||||
if (success && !target.isAlly(source)) {
|
||||
target.staleness = 'external';
|
||||
}
|
||||
if (!success) {
|
||||
this.add('-fail', target, 'heal');
|
||||
return this.NOT_FAIL;
|
||||
}
|
||||
return success;
|
||||
},
|
||||
},
|
||||
headsmash: {
|
||||
inherit: true,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, heal: 1 },
|
||||
secondary: {
|
||||
chance: 100,
|
||||
onHit(target, source, move) {
|
||||
if (!this.heal(this.modify(target.baseMaxhp, 0.25))) {
|
||||
return this.NOT_FAIL;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
knockoff: {
|
||||
inherit: true,
|
||||
accuracy: 90,
|
||||
},
|
||||
shitpulse: {
|
||||
num: -400,
|
||||
gen: 9,
|
||||
accuracy: 100,
|
||||
basePower: 75,
|
||||
category: "Special",
|
||||
name: "Shit Pulse",
|
||||
pp: 15,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, distance: 1, metronome: 1, pulse: 1 },
|
||||
secondary: {
|
||||
chance: 30,
|
||||
boosts: {
|
||||
accuracy: -2,
|
||||
},
|
||||
},
|
||||
target: "any",
|
||||
type: "Poison",
|
||||
shortDesc: "30% chance to lower foe's accuracy by 2.",
|
||||
},
|
||||
solarflare: {
|
||||
num: -4324534,
|
||||
gen: 9,
|
||||
accuracy: 100,
|
||||
basePower: 75,
|
||||
category: "Special",
|
||||
name: "Solar Flare",
|
||||
pp: 15,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
secondary: {
|
||||
chance: 50,
|
||||
onHit(target, source, move) {
|
||||
if (!['sunnyday', 'desolateland'].includes(target.effectiveWeather())) return;
|
||||
target.trySetStatus('brn', source, move);
|
||||
},
|
||||
},
|
||||
target: "normal",
|
||||
type: "Fire",
|
||||
shortDesc: "Sun active: 50% chance to burn.",
|
||||
},
|
||||
onslaught: {
|
||||
num: -3023,
|
||||
gen: 9,
|
||||
accuracy: 100,
|
||||
basePower: 100,
|
||||
category: "Physical",
|
||||
name: "Onslaught",
|
||||
pp: 5,
|
||||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
self: {
|
||||
boosts: {
|
||||
atk: -1,
|
||||
def: -1,
|
||||
},
|
||||
},
|
||||
target: "normal",
|
||||
type: "Dark",
|
||||
},
|
||||
scald: {
|
||||
inherit: true,
|
||||
onEffectiveness(typeMod, target, type) {
|
||||
if (type === 'Steel') return 1;
|
||||
},
|
||||
secondary: undefined,
|
||||
secondaries: [{
|
||||
chance: 30,
|
||||
status: 'brn',
|
||||
}, {
|
||||
chance: 100,
|
||||
onHit(target, source, move) {
|
||||
if (target.hasType(['Normal', 'Fairy'])) {
|
||||
target.trySetStatus('brn', source, move);
|
||||
}
|
||||
},
|
||||
}],
|
||||
},
|
||||
explosion: {
|
||||
inherit: true,
|
||||
onAfterMove(pokemon, target, move) {
|
||||
if (target && target.hp <= 0) {
|
||||
delete move.selfdestruct;
|
||||
return;
|
||||
}
|
||||
},
|
||||
},
|
||||
selfdestruct: {
|
||||
inherit: true,
|
||||
onAfterMove(pokemon, target, move) {
|
||||
if (target && target.hp <= 0) {
|
||||
delete move.selfdestruct;
|
||||
return;
|
||||
}
|
||||
},
|
||||
},
|
||||
mistyexplosion: {
|
||||
inherit: true,
|
||||
onAfterMove(pokemon, target, move) {
|
||||
if (target && target.hp <= 0) {
|
||||
delete move.selfdestruct;
|
||||
return;
|
||||
}
|
||||
},
|
||||
},
|
||||
moonblast: {
|
||||
inherit: true,
|
||||
basePower: 90,
|
||||
accuracy: 90,
|
||||
secondary: {
|
||||
chance: 10,
|
||||
boosts: {
|
||||
atk: -1,
|
||||
},
|
||||
},
|
||||
category: "Physical",
|
||||
},
|
||||
noretreat: {
|
||||
name: "No Retreat",
|
||||
// @ts-expect-error
|
||||
exists: false,
|
||||
},
|
||||
blastiodon: {
|
||||
num: -306345534534523,
|
||||
gen: 9,
|
||||
accuracy: 100,
|
||||
basePower: 0,
|
||||
basePowerCallback(pokemon, target) {
|
||||
const targetDef = target.getStat('def', false, true);
|
||||
const pokemonDef = pokemon.getStat('def', false, true);
|
||||
let bp;
|
||||
if (pokemonDef >= targetDef * 5) {
|
||||
bp = 150;
|
||||
} else if (pokemonDef >= targetDef * 4) {
|
||||
bp = 125;
|
||||
} else if (pokemonDef >= targetDef * 3) {
|
||||
bp = 100;
|
||||
} else if (pokemonDef >= targetDef * 2) {
|
||||
bp = 75;
|
||||
} else {
|
||||
bp = 50;
|
||||
}
|
||||
this.debug(`BP: ${bp}`);
|
||||
return bp;
|
||||
},
|
||||
category: "Physical",
|
||||
name: "Blastiodon",
|
||||
pp: 15,
|
||||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
overrideOffensiveStat: 'def',
|
||||
secondary: {
|
||||
chance: 50,
|
||||
boosts: {
|
||||
def: -1,
|
||||
},
|
||||
},
|
||||
target: "normal",
|
||||
type: "Rock",
|
||||
shortDesc: "Higher user Def than target Def = higher BP.",
|
||||
},
|
||||
focusblast: {
|
||||
inherit: true,
|
||||
accuracy: 100,
|
||||
recoil: [1, 4],
|
||||
category: "Physical",
|
||||
},
|
||||
darkvoid: {
|
||||
inherit: true,
|
||||
onModifyMove(move, pokemon, target) {
|
||||
if (pokemon.species.baseSpecies === 'Calyrex') {
|
||||
move.accuracy = 80;
|
||||
}
|
||||
},
|
||||
onTry(source, target, move) {
|
||||
if (source.species.baseSpecies === 'Darkrai' || source.species.baseSpecies === 'Calyrex' || move.hasBounced) {
|
||||
return;
|
||||
}
|
||||
this.add('-fail', source, 'move: Dark Void');
|
||||
this.hint("Only a Pokemon whose form is Darkrai can use this move.");
|
||||
return null;
|
||||
},
|
||||
},
|
||||
rapidspin: {
|
||||
inherit: true,
|
||||
type: "Dark",
|
||||
},
|
||||
};
|
||||
329
data/mods/afd/pokedex.ts
Normal file
329
data/mods/afd/pokedex.ts
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
|
||||
seaking: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 80, atk: 92, def: 65, spa: 65, spd: 80, spe: 98 },
|
||||
},
|
||||
clefablemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
victreebelmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
starmiemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
skarmorymega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
scolipedemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
scraftymega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
emboarmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
eelektrossmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
chesnaughtmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
delphoxmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
greninjamega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
pyroarmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
barbaraclemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
hawluchamega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
raichumegax: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
chimechomega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
baxcaliburmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
zeraoramega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
absolmegaz: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
staraptormega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
golisopodmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
meowsticfmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
crabominablemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
golurkmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
garchompmegaz: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
lucariomegaz: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
raichumegay: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
falinksmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "No Retreat" },
|
||||
},
|
||||
drampamega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
zygardemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
dragalgemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
darkraimega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
heatranmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
floettemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
chandeluremega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Shadow Tag" },
|
||||
},
|
||||
lickitung: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Own Tempo", 1: "Oblivious", H: "Chaos Saliva" },
|
||||
},
|
||||
mewtwo: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Pressure", 1: "Neuroforce", H: "Unnerve" },
|
||||
},
|
||||
scovillainmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Contrary" },
|
||||
},
|
||||
mew: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Synchronize", 1: "Neuroforce" },
|
||||
},
|
||||
smeargle: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Own Tempo", 1: "Prankster", H: "Moody" },
|
||||
},
|
||||
swampert: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Torrent", 1: "Sap Sipper", H: "Damp" },
|
||||
},
|
||||
bibarel: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 159, atk: 85, def: 60, spa: 55, spd: 60, spe: 151 },
|
||||
},
|
||||
skuntank: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 103, atk: 93, def: 67, spa: 106, spd: 61, spe: 84 },
|
||||
abilities: { 0: "Stench", 1: "Aftermath", H: "Mega Launcher" },
|
||||
},
|
||||
rampardos: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 97, atk: 225, def: 30, spa: 65, spd: 30, spe: 58 },
|
||||
abilities: { 0: "Rocky Payload", H: "Sheer Force" },
|
||||
},
|
||||
gallademega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Sharpness" },
|
||||
},
|
||||
garchompmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Sand Rush" },
|
||||
},
|
||||
dusknoir: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Damp" },
|
||||
},
|
||||
lickilicky: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Own Tempo", 1: "Oblivious", H: "Chaos Saliva" },
|
||||
},
|
||||
regigigas: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Slow Start", H: "Fast Start" },
|
||||
},
|
||||
serperior: {
|
||||
inherit: true,
|
||||
types: ['Grass', 'Dragon'],
|
||||
baseStats: { hp: 75, atk: 75, def: 95, spa: 105, spd: 95, spe: 113 },
|
||||
},
|
||||
simisage: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 120, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 },
|
||||
},
|
||||
excadrillmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "It's Excadrillin' Time!" },
|
||||
},
|
||||
chandelure: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Flash Fire", 1: "Flame Body", H: "Shadow Tag" },
|
||||
},
|
||||
delphox: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Blaze", H: "Discourage" },
|
||||
},
|
||||
clawitzer: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Super Mega Launcher" },
|
||||
},
|
||||
malamar: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 101, atk: 112, def: 88, spa: 68, spd: 75, spe: 73 },
|
||||
},
|
||||
malamarmega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 101, atk: 122, def: 88, spa: 98, spd: 120, spe: 88 },
|
||||
abilities: { 0: "Contrary" },
|
||||
},
|
||||
incineroar: {
|
||||
inherit: true,
|
||||
types: ['Fire', 'Fighting'],
|
||||
},
|
||||
incineroar2: {
|
||||
num: 2000,
|
||||
name: "Incineroar 2",
|
||||
types: ["Ghost", "Steel"],
|
||||
genderRatio: { M: 0.875, F: 0.125 },
|
||||
baseStats: { hp: 95, atk: 115, def: 90, spa: 80, spd: 90, spe: 60 },
|
||||
abilities: { 0: "Intimidate 2" },
|
||||
heightm: 1.8,
|
||||
weightkg: 83,
|
||||
color: "Red",
|
||||
eggGroups: ["Field"],
|
||||
},
|
||||
celesteela: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 5, atk: 5, def: 5, spa: 5, spd: 5, spe: 5 },
|
||||
},
|
||||
hatterene: {
|
||||
inherit: true,
|
||||
types: ['Psychic', 'Dark'],
|
||||
},
|
||||
glimmora: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 106, atk: 150, def: 70, spa: 194, spd: 120, spe: 140 },
|
||||
},
|
||||
glimmoramega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 106, atk: 185, def: 85, spa: 214, spd: 145, spe: 155 },
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
tatsugiri: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Commander", 1: "Parental Bond", H: "Storm Drain" },
|
||||
},
|
||||
tatsugiridroopy: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Commander", 1: "Parental Bond", H: "Storm Drain" },
|
||||
},
|
||||
tatsugiristretchy: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Commander", 1: "Parental Bond", H: "Storm Drain" },
|
||||
},
|
||||
tatsugiricurlymega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Parental Bond" },
|
||||
},
|
||||
tatsugiridroopymega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Parental Bond" },
|
||||
},
|
||||
tatsugiristretchymega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Parental Bond" },
|
||||
},
|
||||
calyrex: {
|
||||
num: 898,
|
||||
name: "Calyrex",
|
||||
types: ["Psychic", "Grass"],
|
||||
gender: "N",
|
||||
baseStats: { hp: 100, atk: 80, def: 80, spa: 80, spd: 80, spe: 80 },
|
||||
abilities: { 0: "Unnerve" },
|
||||
heightm: 1.1,
|
||||
weightkg: 7.7,
|
||||
color: "Green",
|
||||
eggGroups: ["Undiscovered"],
|
||||
tags: ["Restricted Legendary"],
|
||||
otherFormes: ["Calyrex-Ice", "Calyrex-Shadow", "Calyrex-Monarch"],
|
||||
formeOrder: ["Calyrex", "Calyrex-Ice", "Calyrex-Shadow", "Calyrex-Monarch"],
|
||||
},
|
||||
calyrexmonarch: {
|
||||
num: 898,
|
||||
name: "Calyrex-Monarch",
|
||||
baseSpecies: "Calyrex",
|
||||
forme: "Monarch",
|
||||
types: ["Psychic", "Grass"],
|
||||
gender: "N",
|
||||
baseStats: { hp: 200, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 },
|
||||
abilities: { 0: "As One (Calyrex)" },
|
||||
heightm: 2.2,
|
||||
weightkg: 15.4,
|
||||
color: "Green",
|
||||
eggGroups: ["Undiscovered"],
|
||||
changesFrom: "Calyrex",
|
||||
},
|
||||
spidops: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 100, atk: 100, def: 100, spa: 100, spd: 100, spe: 0 },
|
||||
},
|
||||
};
|
||||
788
data/mods/afd/random-teams.ts
Normal file
788
data/mods/afd/random-teams.ts
Normal file
|
|
@ -0,0 +1,788 @@
|
|||
import { Utils } from '../../../lib';
|
||||
import RandomTeams from '../../random-battles/gen9/teams';
|
||||
import { toID } from '../../../sim/dex';
|
||||
|
||||
export interface TeamData {
|
||||
typeCount: { [k: string]: number };
|
||||
typeComboCount: { [k: string]: number };
|
||||
baseFormes: { [k: string]: number };
|
||||
megaCount?: number;
|
||||
zCount?: number;
|
||||
wantsTeraCount?: number;
|
||||
has: { [k: string]: number };
|
||||
forceResult: boolean;
|
||||
weaknesses: { [k: string]: number };
|
||||
resistances: { [k: string]: number };
|
||||
weather?: string;
|
||||
eeveeLimCount?: number;
|
||||
gigantamax?: boolean;
|
||||
}
|
||||
export interface BattleFactorySpecies {
|
||||
sets: BattleFactorySet[];
|
||||
weight: number;
|
||||
}
|
||||
interface BattleFactorySet {
|
||||
species: string;
|
||||
weight: number;
|
||||
item: string[];
|
||||
ability: string[];
|
||||
nature: string[];
|
||||
moves: string[][];
|
||||
teraType: string[];
|
||||
gender?: string;
|
||||
wantsTera?: boolean;
|
||||
evs?: Partial<StatsTable>;
|
||||
ivs?: Partial<StatsTable>;
|
||||
shiny?: boolean;
|
||||
level?: number;
|
||||
}
|
||||
export class MoveCounter extends Utils.Multiset<string> {
|
||||
damagingMoves: Set<Move>;
|
||||
basePowerMoves: Set<Move>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.damagingMoves = new Set();
|
||||
this.basePowerMoves = new Set();
|
||||
}
|
||||
}
|
||||
// Moves that switch the user out
|
||||
const PIVOT_MOVES = [
|
||||
'chillyreception', 'flipturn', 'partingshot', 'shedtail', 'teleport', 'uturn', 'voltswitch',
|
||||
];
|
||||
|
||||
/** Pokemon who should never be in the lead slot */
|
||||
const NO_LEAD_POKEMON = [
|
||||
'Zacian', 'Zamazenta',
|
||||
];
|
||||
|
||||
const DEFENSIVE_TERA_BLAST_USERS = [
|
||||
'alcremie', 'bellossom', 'comfey', 'fezandipiti', 'florges',
|
||||
];
|
||||
|
||||
export class RandomAFDTeams extends RandomTeams {
|
||||
override shouldCullAbility(
|
||||
ability: string,
|
||||
types: string[],
|
||||
moves: Set<string>,
|
||||
abilities: string[],
|
||||
counter: MoveCounter,
|
||||
teamDetails: RandomTeamsTypes.TeamDetails,
|
||||
species: Species,
|
||||
isLead: boolean,
|
||||
isDoubles: boolean,
|
||||
teraType: string,
|
||||
role: RandomTeamsTypes.Role,
|
||||
): boolean {
|
||||
switch (ability) {
|
||||
// Abilities which are primarily useful for certain moves or with team support
|
||||
case 'Chlorophyll': case 'Solar Power':
|
||||
return !teamDetails.sun;
|
||||
case 'Defiant':
|
||||
return (species.id === 'thundurus' && !!counter.get('Status'));
|
||||
case 'Hydration': case 'Swift Swim':
|
||||
return !teamDetails.rain;
|
||||
case 'Iron Fist': case 'Skill Link':
|
||||
return !counter.get(toID(ability));
|
||||
case 'Overgrow':
|
||||
return !counter.get('Grass');
|
||||
case 'Prankster':
|
||||
return !counter.get('Status');
|
||||
case 'Sand Force': case 'Sand Rush': case 'It\'s Excadrillin\' Time!':
|
||||
return !teamDetails.sand;
|
||||
case 'Slush Rush':
|
||||
return !teamDetails.snow;
|
||||
case 'Swarm':
|
||||
return !counter.get('Bug');
|
||||
case 'Torrent':
|
||||
return (!counter.get('Water') && !moves.has('flipturn'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
override getAbility(
|
||||
types: string[],
|
||||
moves: Set<string>,
|
||||
abilities: string[],
|
||||
counter: MoveCounter,
|
||||
teamDetails: RandomTeamsTypes.TeamDetails,
|
||||
species: Species,
|
||||
isLead: boolean,
|
||||
isDoubles: boolean,
|
||||
teraType: string,
|
||||
role: RandomTeamsTypes.Role,
|
||||
): string {
|
||||
if (abilities.length <= 1) return abilities[0];
|
||||
|
||||
// Hard-code abilities here
|
||||
if (species.id === 'drifblim') return moves.has('defog') ? 'Aftermath' : 'Unburden';
|
||||
if (abilities.includes('Flash Fire') && this.dex.getEffectiveness('Fire', teraType) >= 1) return 'Flash Fire';
|
||||
if ((species.id === 'thundurus' || species.id === 'tornadus') && !counter.get('Physical')) return 'Prankster';
|
||||
if (species.id === 'toucannon' && counter.get('skilllink')) return 'Skill Link';
|
||||
if (abilities.includes('Slush Rush') && moves.has('snowscape')) return 'Slush Rush';
|
||||
if (species.id === 'golduck' && teamDetails.rain) return 'Swift Swim';
|
||||
|
||||
const abilityAllowed: string[] = [];
|
||||
// Obtain a list of abilities that are allowed (not culled)
|
||||
for (const ability of abilities) {
|
||||
if (!this.shouldCullAbility(
|
||||
ability, types, moves, abilities, counter, teamDetails, species, isLead, isDoubles, teraType, role
|
||||
)) {
|
||||
abilityAllowed.push(ability);
|
||||
}
|
||||
}
|
||||
|
||||
// Pick a random allowed ability
|
||||
if (abilityAllowed.length >= 1) return this.sample(abilityAllowed);
|
||||
|
||||
// If all abilities are rejected, prioritize weather abilities over non-weather abilities
|
||||
if (!abilityAllowed.length) {
|
||||
const weatherAbilities = abilities.filter(
|
||||
a => ['Chlorophyll', 'Hydration', 'Sand Force', 'Sand Rush', 'Slush Rush', 'Solar Power', 'Swift Swim'].includes(a)
|
||||
);
|
||||
if (weatherAbilities.length) return this.sample(weatherAbilities);
|
||||
}
|
||||
|
||||
// Pick a random ability
|
||||
return this.sample(abilities);
|
||||
}
|
||||
|
||||
override getPriorityItem(
|
||||
ability: string,
|
||||
types: string[],
|
||||
moves: Set<string>,
|
||||
counter: MoveCounter,
|
||||
teamDetails: RandomTeamsTypes.TeamDetails,
|
||||
species: Species,
|
||||
isLead: boolean,
|
||||
isDoubles: boolean,
|
||||
teraType: string,
|
||||
role: RandomTeamsTypes.Role,
|
||||
) {
|
||||
if (role === 'Fast Bulky Setup' && (ability === 'Quark Drive' || ability === 'Protosynthesis')) {
|
||||
return 'Booster Energy';
|
||||
}
|
||||
if (species.id === 'lokix') {
|
||||
return (role === 'Fast Attacker') ? 'Silver Powder' : 'Life Orb';
|
||||
}
|
||||
if (species.requiredItems && species.baseSpecies !== 'Magearna') {
|
||||
// Z-Crystals aren't available in Gen 9, so require Plates
|
||||
if (species.baseSpecies === 'Arceus') {
|
||||
return species.requiredItems[0];
|
||||
}
|
||||
return this.sample(species.requiredItems);
|
||||
}
|
||||
if (species.id === 'pikachu') return 'Light Ball';
|
||||
if (role === 'AV Pivot') return 'Assault Vest';
|
||||
if (species.id === 'regieleki') return 'Magnet';
|
||||
if (types.includes('Normal') && moves.has('doubleedge') && moves.has('fakeout')) return 'Silk Scarf';
|
||||
if (
|
||||
species.id === 'froslass' || moves.has('populationbomb') ||
|
||||
(ability === 'Hustle' && counter.get('setup') && !isDoubles && this.randomChance(1, 2))
|
||||
) return 'Wide Lens';
|
||||
if (species.id === 'smeargle') return 'Focus Sash';
|
||||
if (moves.has('clangoroussoul') || (species.id === 'toxtricity' && moves.has('shiftgear'))) return 'Throat Spray';
|
||||
if (
|
||||
(species.baseSpecies === 'Magearna' && role === 'Tera Blast user') ||
|
||||
((species.id === 'calyrexice' || species.id === 'necrozmaduskmane') && isDoubles)
|
||||
) return 'Weakness Policy';
|
||||
if (['dragonenergy', 'lastrespects', 'waterspout'].some(m => moves.has(m))) return 'Choice Scarf';
|
||||
if (
|
||||
!isDoubles && (ability === 'Imposter' || (species.id === 'magnezone' && role === 'Fast Attacker'))
|
||||
) return 'Choice Scarf';
|
||||
if (species.id === 'rampardos' && (role === 'Fast Attacker' || isDoubles)) return 'Choice Scarf';
|
||||
if (species.id === 'palkia' && counter.get('Status')) return 'Lustrous Orb';
|
||||
if (
|
||||
moves.has('courtchange') ||
|
||||
!isDoubles && (species.id === 'luvdisc' || (species.id === 'terapagos' && !moves.has('rest')))
|
||||
) return 'Hoots';
|
||||
if (['Cheek Pouch', 'Cud Chew', 'Harvest', 'Ripen'].some(m => ability === m)) {
|
||||
return 'Sitrus Berry';
|
||||
}
|
||||
if (moves.has('bellydrum') || moves.has('filletaway')) return 'Ward Tag';
|
||||
if (['healingwish', 'switcheroo', 'trick'].some(m => moves.has(m))) {
|
||||
if (
|
||||
species.baseStats.spe >= 60 && species.baseStats.spe <= 108 &&
|
||||
role !== 'Wallbreaker' && role !== 'Doubles Wallbreaker' && !counter.get('priority')
|
||||
) {
|
||||
return 'Choice Scarf';
|
||||
} else {
|
||||
return (counter.get('Physical') > counter.get('Special')) ? 'Choice Band' : 'Choice Specs';
|
||||
}
|
||||
}
|
||||
if (counter.get('Status') && (species.name === 'Latias' || species.name === 'Latios')) return 'Soul Dew';
|
||||
if (species.id === 'scyther' && !isDoubles) return (isLead && !moves.has('uturn')) ? 'Eviolite' : 'Hoots';
|
||||
if (ability === 'Poison Heal' || ability === 'Quick Feet') return 'Toxic Orb';
|
||||
if (species.nfe) return 'Eviolite';
|
||||
if ((ability === 'Guts' || moves.has('facade')) && !moves.has('sleeptalk')) {
|
||||
return (types.includes('Fire') || ability === 'Toxic Boost') ? 'Toxic Orb' : 'Flame Orb';
|
||||
}
|
||||
if (ability === 'Magic Guard' || (ability === 'Sheer Force' && counter.get('sheerforce'))) return 'Life Orb';
|
||||
if (ability === 'Anger Shell') return this.sample(['Expert Belt', 'Lum Berry', 'Scope Lens', 'Sitrus Berry']);
|
||||
if (moves.has('dragondance') && isDoubles) return 'Clear Amulet';
|
||||
if (counter.get('skilllink') && ability !== 'Skill Link' && species.id !== 'breloom') return 'Loaded Dice';
|
||||
if (ability === 'Unburden') {
|
||||
return (moves.has('closecombat') || moves.has('leafstorm')) ? 'White Herb' : 'Sitrus Berry';
|
||||
}
|
||||
if (moves.has('shellsmash') && ability !== 'Weak Armor') return 'White Herb';
|
||||
if (moves.has('meteorbeam') || (moves.has('electroshot') && !teamDetails.rain)) return 'Power Herb';
|
||||
if (moves.has('acrobatics') && ability !== 'Protosynthesis') return '';
|
||||
if (moves.has('auroraveil') || moves.has('lightscreen') && moves.has('reflect')) return 'Light Clay';
|
||||
if (ability === 'Gluttony') return `${this.sample(['Aguav', 'Figy', 'Iapapa', 'Mago', 'Wiki'])} Berry`;
|
||||
if (species.id === 'giratina' && !isDoubles && moves.has('rest') && !moves.has('sleeptalk')) return 'Leftovers';
|
||||
if (
|
||||
moves.has('rest') && !moves.has('sleeptalk') &&
|
||||
ability !== 'Natural Cure' && ability !== 'Shed Skin'
|
||||
) {
|
||||
return 'Chesto Berry';
|
||||
}
|
||||
if (
|
||||
species.id !== 'yanmega' &&
|
||||
this.dex.getEffectiveness('Rock', species) >= 2 && (!types.includes('Flying') || !isDoubles)
|
||||
) return 'Hoots';
|
||||
}
|
||||
|
||||
override getItem(
|
||||
ability: string,
|
||||
types: string[],
|
||||
moves: Set<string>,
|
||||
counter: MoveCounter,
|
||||
teamDetails: RandomTeamsTypes.TeamDetails,
|
||||
species: Species,
|
||||
isLead: boolean,
|
||||
teraType: string,
|
||||
role: RandomTeamsTypes.Role,
|
||||
): string {
|
||||
const lifeOrbReqs = ['flamecharge', 'nuzzle', 'rapidspin'].every(m => !moves.has(m));
|
||||
|
||||
if (
|
||||
species.id !== 'jirachi' && (counter.get('Physical') >= moves.size) &&
|
||||
['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')
|
||||
);
|
||||
return (scarfReqs && this.randomChance(1, 2)) ? 'Choice Scarf' : 'Choice Band';
|
||||
}
|
||||
if (
|
||||
(counter.get('Special') >= moves.size) ||
|
||||
(counter.get('Special') >= moves.size - 1 && ['flipturn', 'uturn'].some(m => moves.has(m)))
|
||||
) {
|
||||
const scarfReqs = (
|
||||
role !== 'Wallbreaker' &&
|
||||
species.baseStats.spa >= 100 &&
|
||||
species.baseStats.spe >= 60 && species.baseStats.spe <= 108 &&
|
||||
ability !== 'Speed Boost' && ability !== 'Tinted Lens' && !moves.has('uturn') && !counter.get('priority')
|
||||
);
|
||||
return (scarfReqs && this.randomChance(1, 2)) ? 'Choice Scarf' : 'Choice Specs';
|
||||
}
|
||||
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)
|
||||
) {
|
||||
return 'Assault Vest';
|
||||
}
|
||||
if (species.id === 'golem') return (counter.get('speedsetup')) ? 'Weakness Policy' : 'Custap Berry';
|
||||
if (moves.has('substitute')) return 'Leftovers';
|
||||
if (
|
||||
moves.has('stickyweb') && isLead &&
|
||||
(species.baseStats.hp + species.baseStats.def + species.baseStats.spd) <= 235
|
||||
) return 'Focus Sash';
|
||||
if (this.dex.getEffectiveness('Rock', species) >= 1) return 'Hoots';
|
||||
if (
|
||||
(moves.has('chillyreception') || (
|
||||
role === 'Fast Support' &&
|
||||
[...PIVOT_MOVES, 'defog', 'mortalspin', 'rapidspin'].some(m => moves.has(m)) &&
|
||||
!types.includes('Flying') && ability !== 'Levitate'
|
||||
))
|
||||
) return 'Hoots';
|
||||
|
||||
// Low Priority
|
||||
if (moves.has('dragondance') && role === 'Bulky Setup') return 'Weakness Policy';
|
||||
if (
|
||||
ability === 'Rough Skin' || (
|
||||
ability === 'Regenerator' && (role === 'Bulky Support' || role === 'Bulky Attacker') &&
|
||||
(species.baseStats.hp + species.baseStats.def) >= 180 && this.randomChance(1, 2)
|
||||
) || (
|
||||
ability !== 'Regenerator' && !counter.get('setup') && counter.get('recovery') &&
|
||||
this.dex.getEffectiveness('Fighting', species) < 1 &&
|
||||
(species.baseStats.hp + species.baseStats.def) > 200 && this.randomChance(1, 2)
|
||||
)
|
||||
) return 'Rocky Helmet';
|
||||
if (role === 'Bulky Support') return 'Onika Burger';
|
||||
if (moves.has('outrage') && counter.get('setup')) return 'Lum Berry';
|
||||
if (moves.has('protect') && ability !== 'Speed Boost') return 'Leftovers';
|
||||
if (
|
||||
role === 'Fast Support' && isLead && !counter.get('recovery') && !counter.get('recoil') &&
|
||||
(counter.get('hazards') || counter.get('setup')) &&
|
||||
(species.baseStats.hp + species.baseStats.def + species.baseStats.spd) < 258
|
||||
) return 'Focus Sash';
|
||||
if (
|
||||
!counter.get('setup') && ability !== 'Levitate' && this.dex.getEffectiveness('Ground', species) >= 2
|
||||
) return 'Air Balloon';
|
||||
if (['Bulky Attacker', 'Bulky Setup'].some(m => role === (m))) return 'Leftovers';
|
||||
if (species.id === 'pawmot' && moves.has('nuzzle')) return 'Leppa Berry';
|
||||
if (role === 'Fast Support' || role === 'Fast Bulky Setup') {
|
||||
return (
|
||||
counter.get('Physical') + counter.get('Special') > counter.get('Status') && lifeOrbReqs
|
||||
) ? 'Life Orb' : 'Leftovers';
|
||||
}
|
||||
if (role === 'Tera Blast user' && DEFENSIVE_TERA_BLAST_USERS.includes(species.id)) return 'Leftovers';
|
||||
if (
|
||||
lifeOrbReqs && ['Fast Attacker', 'Setup Sweeper', 'Tera Blast user', 'Wallbreaker'].some(m => role === (m))
|
||||
) return 'Life Orb';
|
||||
return 'Leftovers';
|
||||
}
|
||||
|
||||
override getLevel(species: Species): number {
|
||||
if (this.adjustLevel) return this.adjustLevel;
|
||||
const file = this.randomAFDSets[species.id] || this.randomSets[species.id];
|
||||
if (file["level"]) return file["level"];
|
||||
// Default to tier-based levelling
|
||||
const tier = species.tier;
|
||||
const tierScale: Partial<Record<Species['tier'], number>> = {
|
||||
Uber: 76,
|
||||
OU: 80,
|
||||
UUBL: 81,
|
||||
UU: 82,
|
||||
RUBL: 83,
|
||||
RU: 84,
|
||||
NUBL: 85,
|
||||
NU: 86,
|
||||
PUBL: 87,
|
||||
PU: 88, "(PU)": 88, NFE: 88,
|
||||
};
|
||||
return tierScale[tier] || 80;
|
||||
}
|
||||
|
||||
override getForme(species: Species): string {
|
||||
if (typeof species.battleOnly === 'string') {
|
||||
// Only change the forme. The species has custom moves, and may have different typing and requirements.
|
||||
return species.battleOnly;
|
||||
}
|
||||
if (species.cosmeticFormes) return this.sample([species.name].concat(species.cosmeticFormes));
|
||||
|
||||
// Consolidate mostly-cosmetic formes, at least for the purposes of Random Battles
|
||||
if (['Dudunsparce', 'Maushold', 'Polteageist', 'Sinistcha', 'Zarude'].includes(species.baseSpecies)) {
|
||||
return this.sample([species.name].concat(species.otherFormes!));
|
||||
}
|
||||
if (species.baseSpecies === 'Basculin') return 'Basculin' + this.sample(['', '-Blue-Striped']);
|
||||
if (species.baseSpecies === 'Magearna') return 'Magearna' + this.sample(['', '-Original']);
|
||||
if (species.baseSpecies === 'Pikachu') {
|
||||
return 'Pikachu' + this.sample(
|
||||
['', '-Original', '-Hoenn', '-Sinnoh', '-Unova', '-Kalos', '-Alola', '-Partner', '-World']
|
||||
);
|
||||
}
|
||||
return species.name;
|
||||
}
|
||||
|
||||
randomAFDSet(
|
||||
s: string | Species,
|
||||
teamDetails: RandomTeamsTypes.TeamDetails = {},
|
||||
isLead = false,
|
||||
isDoubles = false
|
||||
): RandomTeamsTypes.RandomSet {
|
||||
const species = this.dex.species.get(s);
|
||||
const forme = this.getForme(species);
|
||||
if (!this.randomAFDSets[species.id]) return this.randomSet(species, teamDetails, isLead, isDoubles);
|
||||
const sets = this.randomAFDSets[species.id]["sets"];
|
||||
const possibleSets: RandomTeamsTypes.RandomSetData[] = [];
|
||||
|
||||
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.
|
||||
const abilities = set.abilities!;
|
||||
if (
|
||||
isLead && (abilities.includes('Protosynthesis') || abilities.includes('Quark Drive')) &&
|
||||
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') {
|
||||
continue;
|
||||
}
|
||||
possibleSets.push(set);
|
||||
}
|
||||
const set = this.sampleIfArray(possibleSets);
|
||||
const role = set.role;
|
||||
const movePool: string[] = [];
|
||||
for (const movename of set.movepool) {
|
||||
movePool.push(this.dex.moves.get(movename).id);
|
||||
}
|
||||
const teraTypes = set.teraTypes!;
|
||||
let teraType = this.sampleIfArray(teraTypes);
|
||||
|
||||
let ability = '';
|
||||
let item = undefined;
|
||||
|
||||
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 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);
|
||||
|
||||
// Get ability
|
||||
ability = this.getAbility(types, moves, abilities, counter, teamDetails, species, isLead, isDoubles, teraType, role);
|
||||
|
||||
// Get items
|
||||
// First, the priority items
|
||||
item = this.getPriorityItem(ability, types, moves, counter, teamDetails, species, isLead, isDoubles, teraType, role);
|
||||
if (item === undefined) {
|
||||
item = this.getItem(ability, types, moves, counter, teamDetails, species, isLead, teraType, role);
|
||||
}
|
||||
|
||||
// Get level
|
||||
const level = this.getLevel(species);
|
||||
|
||||
// Prepare optimal HP
|
||||
const srImmunity = ability === 'Magic Guard' || item === 'Heavy-Duty Boots' || item === 'Hoots';
|
||||
let srWeakness = srImmunity ? 0 : this.dex.getEffectiveness('Rock', species);
|
||||
// Crash damage move users want an odd HP to survive two misses
|
||||
if (['axekick', 'highjumpkick', 'jumpkick', 'supercellslam'].some(m => moves.has(m))) srWeakness = 2;
|
||||
while (evs.hp > 1) {
|
||||
const hp = Math.floor(Math.floor(2 * species.baseStats.hp + ivs.hp + Math.floor(evs.hp / 4) + 100) * level / 100 + 10);
|
||||
if ((moves.has('substitute') && ['Sitrus Berry'].includes(item)) || species.id === 'minior') {
|
||||
// Two Substitutes should activate Sitrus Berry. Two switch-ins to Stealth Rock should activate Shields Down on Minior.
|
||||
if (hp % 4 === 0) break;
|
||||
} else if (
|
||||
(moves.has('bellydrum') || moves.has('filletaway') || moves.has('shedtail')) &&
|
||||
(item === 'Sitrus Berry' || ability === 'Gluttony')
|
||||
) {
|
||||
// Belly Drum should activate Sitrus Berry
|
||||
if (hp % 2 === 0) break;
|
||||
} else if (moves.has('substitute') && moves.has('endeavor')) {
|
||||
// Luvdisc should be able to Substitute down to very low HP
|
||||
if (hp % 4 > 0) break;
|
||||
} else {
|
||||
// Maximize number of Stealth Rock switch-ins in singles
|
||||
if (isDoubles) break;
|
||||
if (srWeakness <= 0 || ability === 'Regenerator' || ['Leftovers', 'Life Orb'].includes(item)) break;
|
||||
if (item !== 'Sitrus Berry' && hp % (4 / srWeakness) > 0) break;
|
||||
// Minimise number of Stealth Rock switch-ins to activate Sitrus Berry
|
||||
if (item === 'Sitrus Berry' && hp % (4 / srWeakness) === 0) break;
|
||||
}
|
||||
evs.hp -= 4;
|
||||
}
|
||||
|
||||
// Minimize confusion damage
|
||||
const noAttackStatMoves = [...moves].every(m => {
|
||||
const move = this.dex.moves.get(m);
|
||||
if (move.damageCallback || move.damage) return true;
|
||||
if (move.id === 'shellsidearm') return false;
|
||||
// Physical Tera Blast
|
||||
if (
|
||||
move.id === 'terablast' && (species.id === 'porygon2' || ['Contrary', 'Defiant'].includes(ability) ||
|
||||
moves.has('shiftgear') || species.baseStats.atk > species.baseStats.spa)
|
||||
) return false;
|
||||
return move.category !== 'Physical' || move.id === 'bodypress' || move.id === 'foulplay';
|
||||
});
|
||||
if (
|
||||
noAttackStatMoves && !moves.has('transform') && this.format.mod !== 'partnersincrime' &&
|
||||
!ruleTable.has('forceofthefallenmod')
|
||||
) {
|
||||
evs.atk = 0;
|
||||
ivs.atk = 0;
|
||||
}
|
||||
|
||||
if (moves.has('gyroball') || moves.has('trickroom')) {
|
||||
evs.spe = 0;
|
||||
ivs.spe = 0;
|
||||
}
|
||||
|
||||
// Enforce Tera Type after all set generation is done to prevent infinite generation
|
||||
if (this.forceTeraType) teraType = this.forceTeraType;
|
||||
|
||||
// shuffle moves to add more randomness to camomons
|
||||
const shuffledMoves = Array.from(moves);
|
||||
this.prng.shuffle(shuffledMoves);
|
||||
let name = species.baseSpecies;
|
||||
if (name === "Bruxish") name = "Brux";
|
||||
return {
|
||||
name,
|
||||
species: forme,
|
||||
speciesId: species.id,
|
||||
gender: species.baseSpecies === 'Greninja' ? 'M' : (species.gender || (this.random(2) ? 'F' : 'M')),
|
||||
shiny: this.randomChance(1, 1024),
|
||||
level,
|
||||
moves: shuffledMoves,
|
||||
ability,
|
||||
evs,
|
||||
ivs,
|
||||
item,
|
||||
teraType,
|
||||
role,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the new species is compatible with the other mons currently on the team.
|
||||
*/
|
||||
override getPokemonCompatibility(
|
||||
species: Species,
|
||||
pokemon: RandomTeamsTypes.RandomSet[]
|
||||
): boolean {
|
||||
const webSetters = [
|
||||
'ariados', 'smeargle', 'masquerain', 'kricketune', 'leavanny', 'galvantula', 'vikavolt', 'ribombee', 'araquanid', 'spidops',
|
||||
];
|
||||
const screenSetters = ['meowstic', 'grimmsnarl', 'ninetalesalola', 'abomasnow'];
|
||||
|
||||
const sunSetters = ['ninetales', 'torkoal', 'groudon', 'koraidon'];
|
||||
|
||||
const incompatiblePokemon = [
|
||||
// These Pokemon with support roles are considered too similar to each other.
|
||||
['blissey', 'chansey'],
|
||||
['illumise', 'volbeat'],
|
||||
|
||||
// These combinations are prevented to avoid double webs or screens.
|
||||
[webSetters, webSetters],
|
||||
[screenSetters, screenSetters],
|
||||
|
||||
// These Pokemon are incompatible because the presence of one actively harms the other.
|
||||
// Prevent Dry Skin + sun setting ability
|
||||
['toxicroak', sunSetters],
|
||||
];
|
||||
|
||||
const incompatibilityList = incompatiblePokemon;
|
||||
for (const pair of incompatibilityList) {
|
||||
const monsArrayA = (Array.isArray(pair[0])) ? pair[0] : [pair[0]];
|
||||
const monsArrayB = (Array.isArray(pair[1])) ? pair[1] : [pair[1]];
|
||||
if (monsArrayB.includes(species.id)) {
|
||||
if (pokemon.some(m => monsArrayA.includes(m.speciesId!))) return false;
|
||||
}
|
||||
if (monsArrayA.includes(species.id)) {
|
||||
if (pokemon.some(m => monsArrayB.includes(m.speciesId!))) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
randomAFDSets: { [species: string]: RandomTeamsTypes.RandomSpeciesData } = require('./sets.json');
|
||||
|
||||
override randomTeam() {
|
||||
this.enforceNoDirectCustomBanlistChanges();
|
||||
|
||||
const seed = this.prng.getSeed();
|
||||
const ruleTable = this.dex.formats.getRuleTable(this.format);
|
||||
const pokemon: RandomTeamsTypes.RandomSet[] = [];
|
||||
|
||||
// PotD stuff
|
||||
const usePotD = global.Config && Config.potd && ruleTable.has('potd');
|
||||
const potd = usePotD ? this.dex.species.get(Config.potd) : null;
|
||||
|
||||
const baseFormes: { [k: string]: number } = {};
|
||||
|
||||
const typeCount: { [k: string]: number } = {};
|
||||
const typeComboCount: { [k: string]: number } = {};
|
||||
const typeWeaknesses: { [k: string]: number } = {};
|
||||
const typeDoubleWeaknesses: { [k: string]: number } = {};
|
||||
const teamDetails: RandomTeamsTypes.TeamDetails = {};
|
||||
let numMaxLevelPokemon = 0;
|
||||
|
||||
const pokemonList = Object.keys(this.randomSets);
|
||||
const afdList = Object.keys(this.randomAFDSets);
|
||||
const zaMegaList = Object.keys(this.randomAFDSets).filter(x => (
|
||||
this.dex.species.get(x).isMega && this.dex.species.get(x).gen === 9
|
||||
));
|
||||
const [pokemonPool, baseSpeciesPool] = this.getPokemonPool('', pokemon, false, pokemonList);
|
||||
const [afdPool, baseAfdPool] = this.getPokemonPool('', pokemon, false, afdList);
|
||||
const [zaMegaPool, zaBaseMegaPool] = this.getPokemonPool('', pokemon, false, zaMegaList);
|
||||
|
||||
let leadsRemaining = this.format.gameType === 'doubles' ? 2 : 1;
|
||||
while (baseSpeciesPool.length && pokemon.length < this.maxTeamSize) {
|
||||
let baseSpecies, species;
|
||||
if (pokemon.length === 0) {
|
||||
baseSpecies = this.sampleNoReplace(zaBaseMegaPool);
|
||||
species = this.dex.species.get(this.sample(zaMegaPool[baseSpecies]));
|
||||
} else if (this.randomChance(1, 5)) {
|
||||
baseSpecies = this.sampleNoReplace(baseAfdPool);
|
||||
species = this.dex.species.get(this.sample(afdPool[baseSpecies]));
|
||||
} else {
|
||||
baseSpecies = this.sampleNoReplace(baseSpeciesPool);
|
||||
species = this.dex.species.get(this.sample(pokemonPool[baseSpecies]));
|
||||
}
|
||||
if (!species.exists) continue;
|
||||
|
||||
// Limit to one of each species (Species Clause)
|
||||
if (baseFormes[species.baseSpecies]) continue;
|
||||
|
||||
// Treat Ogerpon formes and Terapagos like the Tera Blast user role; reject if team has one already
|
||||
if (['ogerpon', 'ogerponhearthflame', 'terapagos'].includes(species.id) && teamDetails.teraBlast) continue;
|
||||
|
||||
// Illusion shouldn't be on the last slot
|
||||
if (species.baseSpecies === 'Zoroark' && pokemon.length >= (this.maxTeamSize - 1)) continue;
|
||||
|
||||
const types = species.types;
|
||||
const typeCombo = types.slice().sort().join();
|
||||
const weakToFreezeDry = (
|
||||
this.dex.getEffectiveness('Ice', species) > 0 ||
|
||||
(this.dex.getEffectiveness('Ice', species) > -2 && types.includes('Water'))
|
||||
);
|
||||
const weakToScald = (
|
||||
this.dex.getEffectiveness('Water', species) > 0 ||
|
||||
(this.dex.getEffectiveness('Water', species) > -2 && types.includes('Steel'))
|
||||
);
|
||||
// Dynamically scale limits for different team sizes. The default and minimum value is 1.
|
||||
const limitFactor = Math.round(this.maxTeamSize / 6) || 1;
|
||||
|
||||
let skip = false;
|
||||
|
||||
// Limit two of any type
|
||||
for (const typeName of types) {
|
||||
if (typeCount[typeName] >= 2 * limitFactor) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip) continue;
|
||||
|
||||
// Limit three weak to any type, and one double weak to any type
|
||||
for (const typeName of this.dex.types.names()) {
|
||||
// it's weak to the type
|
||||
if (this.dex.getEffectiveness(typeName, species) > 0) {
|
||||
if (!typeWeaknesses[typeName]) typeWeaknesses[typeName] = 0;
|
||||
if (typeWeaknesses[typeName] >= 3 * limitFactor) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.dex.getEffectiveness(typeName, species) > 1) {
|
||||
if (!typeDoubleWeaknesses[typeName]) typeDoubleWeaknesses[typeName] = 0;
|
||||
if (typeDoubleWeaknesses[typeName] >= limitFactor) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (skip) continue;
|
||||
|
||||
// Count Dry Skin/Fluffy as Fire weaknesses
|
||||
if (
|
||||
this.dex.getEffectiveness('Fire', species) === 0 &&
|
||||
Object.values(species.abilities).filter(a => ['Dry Skin', 'Fluffy'].includes(a)).length
|
||||
) {
|
||||
if (!typeWeaknesses['Fire']) typeWeaknesses['Fire'] = 0;
|
||||
if (typeWeaknesses['Fire'] >= 3 * limitFactor) continue;
|
||||
}
|
||||
|
||||
// Limit four weak to Freeze-Dry
|
||||
if (weakToFreezeDry) {
|
||||
if (!typeWeaknesses['Freeze-Dry']) typeWeaknesses['Freeze-Dry'] = 0;
|
||||
if (typeWeaknesses['Freeze-Dry'] >= 4 * limitFactor) continue;
|
||||
}
|
||||
if (weakToScald) {
|
||||
if (!typeWeaknesses['Scald']) typeWeaknesses['Scald'] = 0;
|
||||
if (typeWeaknesses['Scald'] >= 4 * limitFactor) continue;
|
||||
}
|
||||
|
||||
// Limit one level 100 Pokemon
|
||||
if (!this.adjustLevel && (this.getLevel(species) === 100) && numMaxLevelPokemon >= limitFactor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check compatibility with team
|
||||
if (!this.getPokemonCompatibility(species, pokemon)) continue;
|
||||
|
||||
// The Pokemon of the Day
|
||||
if (potd?.exists && (pokemon.length === 1 || this.maxTeamSize === 1)) species = potd;
|
||||
|
||||
let set: RandomTeamsTypes.RandomSet;
|
||||
|
||||
if (leadsRemaining) {
|
||||
if (NO_LEAD_POKEMON.includes(species.baseSpecies)) {
|
||||
if (pokemon.length + leadsRemaining === this.maxTeamSize) continue;
|
||||
set = this.randomAFDSet(species, teamDetails, false);
|
||||
pokemon.push(set);
|
||||
} else {
|
||||
set = this.randomAFDSet(species, teamDetails, true);
|
||||
pokemon.unshift(set);
|
||||
leadsRemaining--;
|
||||
}
|
||||
} else {
|
||||
set = this.randomAFDSet(species, teamDetails, false);
|
||||
pokemon.push(set);
|
||||
}
|
||||
|
||||
// Don't bother tracking details for the last Pokemon
|
||||
if (pokemon.length === this.maxTeamSize) break;
|
||||
|
||||
// Now that our Pokemon has passed all checks, we can increment our counters
|
||||
baseFormes[species.baseSpecies] = 1;
|
||||
|
||||
// Increment type counters
|
||||
for (const typeName of types) {
|
||||
if (typeName in typeCount) {
|
||||
typeCount[typeName]++;
|
||||
} else {
|
||||
typeCount[typeName] = 1;
|
||||
}
|
||||
}
|
||||
if (typeCombo in typeComboCount) {
|
||||
typeComboCount[typeCombo]++;
|
||||
} else {
|
||||
typeComboCount[typeCombo] = 1;
|
||||
}
|
||||
|
||||
// Increment weakness counter
|
||||
for (const typeName of this.dex.types.names()) {
|
||||
// it's weak to the type
|
||||
if (this.dex.getEffectiveness(typeName, species) > 0) {
|
||||
typeWeaknesses[typeName]++;
|
||||
}
|
||||
if (this.dex.getEffectiveness(typeName, species) > 1) {
|
||||
typeDoubleWeaknesses[typeName]++;
|
||||
}
|
||||
}
|
||||
// Count Dry Skin/Fluffy as Fire weaknesses
|
||||
if (['Dry Skin', 'Fluffy'].includes(set.ability) && this.dex.getEffectiveness('Fire', species) === 0) {
|
||||
typeWeaknesses['Fire']++;
|
||||
}
|
||||
if (weakToFreezeDry) typeWeaknesses['Freeze-Dry']++;
|
||||
if (weakToScald) typeWeaknesses['Scald']++;
|
||||
|
||||
// Increment level 100 counter
|
||||
if (set.level === 100) numMaxLevelPokemon++;
|
||||
|
||||
// Track what the team has
|
||||
if (set.ability === 'Drizzle' || set.moves.includes('raindance')) teamDetails.rain = 1;
|
||||
if (set.ability === 'Drought' || set.ability === 'Orichalcum Pulse' || set.moves.includes('sunnyday')) {
|
||||
teamDetails.sun = 1;
|
||||
}
|
||||
if (set.ability === 'Sand Stream') teamDetails.sand = 1;
|
||||
if (set.ability === 'Snow Warning' || set.moves.includes('snowscape') || set.moves.includes('chillyreception')) {
|
||||
teamDetails.snow = 1;
|
||||
}
|
||||
if (set.moves.includes('healbell')) teamDetails.statusCure = 1;
|
||||
if (set.moves.includes('spikes') || set.moves.includes('ceaselessedge')) {
|
||||
teamDetails.spikes = (teamDetails.spikes || 0) + 1;
|
||||
}
|
||||
if (set.moves.includes('toxicspikes') || set.ability === 'Toxic Debris') teamDetails.toxicSpikes = 1;
|
||||
if (set.moves.includes('stealthrock') || set.moves.includes('stoneaxe')) teamDetails.stealthRock = 1;
|
||||
if (set.moves.includes('stickyweb')) teamDetails.stickyWeb = 1;
|
||||
if (set.moves.includes('defog')) teamDetails.defog = 1;
|
||||
if (set.moves.includes('rapidspin') || set.moves.includes('mortalspin')) teamDetails.rapidSpin = 1;
|
||||
if (set.moves.includes('auroraveil') || (set.moves.includes('reflect') && set.moves.includes('lightscreen'))) {
|
||||
teamDetails.screens = 1;
|
||||
}
|
||||
if (set.role === 'Tera Blast user' || ['ogerpon', 'ogerponhearthflame', 'terapagos'].includes(species.id)) {
|
||||
teamDetails.teraBlast = 1;
|
||||
}
|
||||
}
|
||||
if (pokemon.length < this.maxTeamSize && pokemon.length < 12) { // large teams sometimes cannot be built
|
||||
throw new Error(`Could not build a random team for ${this.format} (seed=${seed})`);
|
||||
}
|
||||
|
||||
return pokemon;
|
||||
}
|
||||
}
|
||||
|
||||
export default RandomAFDTeams;
|
||||
622
data/mods/afd/scripts.ts
Normal file
622
data/mods/afd/scripts.ts
Normal file
|
|
@ -0,0 +1,622 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
gen: 9,
|
||||
init() {
|
||||
for (const id in this.data.Pokedex) {
|
||||
const species = this.data.Pokedex[id];
|
||||
if (species.isCosmeticForme) continue;
|
||||
if (species.types.includes('Ground')) {
|
||||
if (this.data.Learnsets[id]?.learnset) this.modData('Learnsets', id).learnset.thousandarrows = ['9L1'];
|
||||
}
|
||||
if (species.types.includes('Grass') && !species.types.includes('Fire')) {
|
||||
if (this.data.Learnsets[id]?.learnset) this.modData('Learnsets', id).learnset.solarflare = ['9L1'];
|
||||
}
|
||||
const abilities = this.modData('Pokedex', id, true).abilities;
|
||||
if (species.baseStats['atk'] >= 130) {
|
||||
const hasHP = Object.values(abilities).includes('Huge Power') ||
|
||||
Object.values(abilities).includes('Pure Power');
|
||||
if (!hasHP) {
|
||||
const slot = !abilities['1'] ? '1' : !abilities['H'] ? 'H' : 'S';
|
||||
abilities[slot] ||= 'Huge Power';
|
||||
}
|
||||
}
|
||||
const hasRegen = Object.values(abilities).includes('Regenerator');
|
||||
if (!hasRegen) {
|
||||
const slot = !abilities['1'] ? '1' : !abilities['H'] ? 'H' : 'S';
|
||||
abilities[slot] ||= 'Regenerator';
|
||||
}
|
||||
}
|
||||
this.modData('Learnsets', 'tyranitar').learnset.shoreup = ['9L1'];
|
||||
this.modData('Learnsets', 'bastiodon').learnset.blastiodon = ['9L1'];
|
||||
this.modData('Learnsets', 'seaking').learnset.boltbeak = ['9L1'];
|
||||
this.modData('Learnsets', 'seaking').learnset.fishiousrend = ['9L1'];
|
||||
this.modData('Learnsets', 'ampharos').learnset.tailglow = ['9L1'];
|
||||
this.modData('Learnsets', 'ampharos').learnset.dracometeor = ['9L1'];
|
||||
this.modData('Learnsets', 'serperior').learnset.dracometeor = ['9L1'];
|
||||
this.modData('Learnsets', 'serperior').learnset.overheat = ['9L1'];
|
||||
this.modData('Learnsets', 'serperior').learnset.makeitrain = ['9L1'];
|
||||
this.modData('Learnsets', 'rampardos').learnset.accelerock = ['9L1'];
|
||||
this.modData('Learnsets', 'bibarel').learnset.bellydrum = ['9L1'];
|
||||
this.modData('Learnsets', 'bibarel').learnset.storedpower = ['9L1'];
|
||||
this.modData('Learnsets', 'bibarel').learnset.powertrip = ['9L1'];
|
||||
this.modData('Learnsets', 'golisopod').learnset.bellydrum = ['9L1'];
|
||||
this.modData('Learnsets', 'skuntank').learnset.shitpulse = ['9L1'];
|
||||
this.modData('Learnsets', 'dusknoir').learnset = { explosion: ['9L1'] };
|
||||
for (const move of this.moves.all()) {
|
||||
if (move.flags['bite']) {
|
||||
this.modData('Learnsets', 'bruxish').learnset[move.id] = ['9L1'];
|
||||
}
|
||||
}
|
||||
for (const moveid in this.data.Learnsets['incineroar'].learnset) {
|
||||
if (this.moves.get(moveid).type === 'Dark') {
|
||||
delete this.modData('Learnsets', 'incineroar').learnset[moveid];
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
runMegaEvo(pokemon: Pokemon) {
|
||||
const speciesid = pokemon.canMegaEvo || pokemon.canUltraBurst;
|
||||
if (!speciesid) return false;
|
||||
|
||||
pokemon.formeChange(speciesid, pokemon.getItem(), true);
|
||||
|
||||
// Limit one mega evolution
|
||||
pokemon.canMegaEvo = null;
|
||||
|
||||
this.battle.runEvent('AfterMega', pokemon);
|
||||
return true;
|
||||
},
|
||||
switchIn(pokemon, pos, sourceEffect = null, isDrag) {
|
||||
if (!pokemon || pokemon.isActive) {
|
||||
this.battle.hint("A switch failed because the Pokémon trying to switch in is already in.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const side = pokemon.side;
|
||||
if (pos >= side.active.length) {
|
||||
throw new Error(`Invalid switch position ${pos} / ${side.active.length}`);
|
||||
}
|
||||
const oldActive = side.active[pos];
|
||||
const unfaintedActive = oldActive?.hp ? oldActive : null;
|
||||
if (unfaintedActive) {
|
||||
oldActive.beingCalledBack = true;
|
||||
let switchCopyFlag: 'copyvolatile' | 'shedtail' | boolean = false;
|
||||
if (sourceEffect && typeof (sourceEffect as Move).selfSwitch === 'string') {
|
||||
switchCopyFlag = (sourceEffect as Move).selfSwitch!;
|
||||
}
|
||||
if (!oldActive.skipBeforeSwitchOutEventFlag && !isDrag) {
|
||||
this.battle.runEvent('BeforeSwitchOut', oldActive);
|
||||
if (this.battle.gen >= 5) {
|
||||
this.battle.eachEvent('Update');
|
||||
}
|
||||
}
|
||||
oldActive.skipBeforeSwitchOutEventFlag = false;
|
||||
if (!this.battle.runEvent('SwitchOut', oldActive)) {
|
||||
// Warning: DO NOT interrupt a switch-out if you just want to trap a pokemon.
|
||||
// To trap a pokemon and prevent it from switching out, (e.g. Mean Look, Magnet Pull)
|
||||
// use the 'trapped' flag instead.
|
||||
|
||||
// Note: Nothing in the real games can interrupt a switch-out (except Pursuit KOing,
|
||||
// which is handled elsewhere); this is just for custom formats.
|
||||
return false;
|
||||
}
|
||||
if (!oldActive.hp) {
|
||||
// a pokemon fainted from Pursuit before it could switch
|
||||
return 'pursuitfaint';
|
||||
}
|
||||
|
||||
// will definitely switch out at this point
|
||||
|
||||
this.battle.singleEvent('End', oldActive.getAbility(), oldActive.abilityState, oldActive);
|
||||
this.battle.singleEvent('End', oldActive.getItem(), oldActive.itemState, oldActive);
|
||||
|
||||
// if a pokemon is forced out by Whirlwind/etc or Eject Button/Pack, it can't use its chosen move
|
||||
this.battle.queue.cancelAction(oldActive);
|
||||
|
||||
let newMove = null;
|
||||
if (this.battle.gen === 4 && sourceEffect) {
|
||||
newMove = oldActive.lastMove;
|
||||
}
|
||||
if (switchCopyFlag) {
|
||||
pokemon.copyVolatileFrom(oldActive, switchCopyFlag);
|
||||
}
|
||||
if (newMove) pokemon.lastMove = newMove;
|
||||
oldActive.clearVolatile();
|
||||
}
|
||||
if (oldActive) {
|
||||
oldActive.isActive = false;
|
||||
oldActive.isStarted = false;
|
||||
oldActive.usedItemThisTurn = false;
|
||||
oldActive.statsRaisedThisTurn = false;
|
||||
oldActive.statsLoweredThisTurn = false;
|
||||
oldActive.position = pokemon.position;
|
||||
if (oldActive.fainted) oldActive.status = '';
|
||||
if (this.battle.gen <= 4) {
|
||||
pokemon.lastItem = oldActive.lastItem;
|
||||
oldActive.lastItem = '';
|
||||
}
|
||||
pokemon.position = pos;
|
||||
side.pokemon[pokemon.position] = pokemon;
|
||||
side.pokemon[oldActive.position] = oldActive;
|
||||
}
|
||||
pokemon.isActive = true;
|
||||
side.active[pos] = pokemon;
|
||||
pokemon.activeTurns = 0;
|
||||
pokemon.activeMoveActions = 0;
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
moveSlot.used = false;
|
||||
}
|
||||
pokemon.abilityState = this.battle.initEffectState({ id: pokemon.ability, target: pokemon });
|
||||
pokemon.itemState = this.battle.initEffectState({ id: pokemon.item, target: pokemon });
|
||||
this.battle.runEvent('BeforeSwitchIn', pokemon);
|
||||
if (sourceEffect) {
|
||||
this.battle.add(isDrag ? 'drag' : 'switch', pokemon, pokemon.getFullDetails, `[from] ${sourceEffect}`);
|
||||
} else {
|
||||
this.battle.add(isDrag ? 'drag' : 'switch', pokemon, pokemon.getFullDetails);
|
||||
}
|
||||
if (isDrag && this.battle.gen === 2) pokemon.draggedIn = this.battle.turn;
|
||||
pokemon.previouslySwitchedIn++;
|
||||
|
||||
if (isDrag && this.battle.gen >= 5) {
|
||||
// runSwitch happens immediately so that Mold Breaker can make hazards bypass Clear Body and Levitate
|
||||
this.runSwitch(pokemon);
|
||||
} else {
|
||||
this.battle.queue.insertChoice({ choice: 'runSwitch', pokemon });
|
||||
}
|
||||
|
||||
if (pokemon.hasType('Flying')) {
|
||||
this.battle.field.addPseudoWeather('Tailwind', pokemon);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
useMoveInner(moveOrMoveName, pokemon, options) {
|
||||
let target = options?.target;
|
||||
let sourceEffect = options?.sourceEffect;
|
||||
const zMove = options?.zMove;
|
||||
const maxMove = options?.maxMove;
|
||||
if (!sourceEffect && this.battle.effect.id) sourceEffect = this.battle.effect;
|
||||
if (sourceEffect && ['instruct', 'custapberry'].includes(sourceEffect.id)) sourceEffect = null;
|
||||
|
||||
let move = this.dex.getActiveMove(moveOrMoveName);
|
||||
pokemon.lastMoveUsed = move;
|
||||
if (move.id === 'weatherball' && zMove) {
|
||||
// Z-Weather Ball only changes types if it's used directly,
|
||||
// not if it's called by Z-Sleep Talk or something.
|
||||
this.battle.singleEvent('ModifyType', move, null, pokemon, target, move, move);
|
||||
if (move.type !== 'Normal') sourceEffect = move;
|
||||
}
|
||||
if (zMove || (move.category !== 'Status' && sourceEffect && (sourceEffect as ActiveMove).isZ)) {
|
||||
move = this.getActiveZMove(move, pokemon);
|
||||
}
|
||||
if (maxMove && move.category !== 'Status') {
|
||||
// Max move outcome is dependent on the move type after type modifications from ability and the move itself
|
||||
this.battle.singleEvent('ModifyType', move, null, pokemon, target, move, move);
|
||||
this.battle.runEvent('ModifyType', pokemon, target, move, move);
|
||||
}
|
||||
if (maxMove || (move.category !== 'Status' && sourceEffect && (sourceEffect as ActiveMove).isMax)) {
|
||||
move = this.getActiveMaxMove(move, pokemon);
|
||||
}
|
||||
|
||||
if (this.battle.activeMove) {
|
||||
move.priority = this.battle.activeMove.priority;
|
||||
if (!move.hasBounced) move.pranksterBoosted = this.battle.activeMove.pranksterBoosted;
|
||||
}
|
||||
const baseTarget = move.target;
|
||||
let targetRelayVar = { target };
|
||||
targetRelayVar = this.battle.runEvent('ModifyTarget', pokemon, target, move, targetRelayVar, true);
|
||||
if (targetRelayVar.target !== undefined) target = targetRelayVar.target;
|
||||
if (target === undefined) target = this.battle.getRandomTarget(pokemon, move);
|
||||
if (move.target === 'self' || move.target === 'allies') {
|
||||
target = pokemon;
|
||||
}
|
||||
if (sourceEffect) {
|
||||
move.sourceEffect = sourceEffect.id;
|
||||
move.ignoreAbility = (sourceEffect as ActiveMove).ignoreAbility;
|
||||
}
|
||||
let moveResult = false;
|
||||
|
||||
this.battle.setActiveMove(move, pokemon, target);
|
||||
|
||||
this.battle.singleEvent('ModifyType', move, null, pokemon, target, move, move);
|
||||
this.battle.singleEvent('ModifyMove', move, null, pokemon, target, move, move);
|
||||
if (baseTarget !== move.target) {
|
||||
// Target changed in ModifyMove, so we must adjust it here
|
||||
// Adjust before the next event so the correct target is passed to the
|
||||
// event
|
||||
target = this.battle.getRandomTarget(pokemon, move);
|
||||
}
|
||||
move = this.battle.runEvent('ModifyType', pokemon, target, move, move);
|
||||
move = this.battle.runEvent('ModifyMove', pokemon, target, move, move);
|
||||
if (baseTarget !== move.target) {
|
||||
// Adjust again
|
||||
target = this.battle.getRandomTarget(pokemon, move);
|
||||
}
|
||||
if (!move || pokemon.fainted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let attrs = '';
|
||||
|
||||
let movename = move.name;
|
||||
if (move.id === 'hiddenpower') movename = 'Hidden Power';
|
||||
if (sourceEffect) attrs += `|[from] ${sourceEffect.fullname}`;
|
||||
if (zMove && move.isZ === true) {
|
||||
attrs = `|[anim]${movename}${attrs}`;
|
||||
movename = `Z-${movename}`;
|
||||
}
|
||||
this.battle.addMove('move', pokemon, movename, `${target}${attrs}`);
|
||||
|
||||
if (zMove) this.runZPower(move, pokemon);
|
||||
|
||||
if (!target) {
|
||||
this.battle.attrLastMove('[notarget]');
|
||||
this.battle.add(this.battle.gen >= 5 ? '-fail' : '-notarget', pokemon);
|
||||
return false;
|
||||
}
|
||||
|
||||
const { targets, pressureTargets } = pokemon.getMoveTargets(move, target);
|
||||
if (targets.length) {
|
||||
target = targets[targets.length - 1]; // in case of redirection
|
||||
}
|
||||
|
||||
const callerMoveForPressure = sourceEffect && (sourceEffect as ActiveMove).pp ? sourceEffect as ActiveMove : null;
|
||||
if (!sourceEffect || callerMoveForPressure || sourceEffect.id === 'pursuit') {
|
||||
let extraPP = 0;
|
||||
for (const source of pressureTargets) {
|
||||
const ppDrop = this.battle.runEvent('DeductPP', source, pokemon, move);
|
||||
if (ppDrop !== true) {
|
||||
extraPP += ppDrop || 0;
|
||||
}
|
||||
}
|
||||
if (extraPP > 0) {
|
||||
pokemon.deductPP(callerMoveForPressure || moveOrMoveName, extraPP);
|
||||
}
|
||||
}
|
||||
|
||||
let tryMoveResult = this.battle.singleEvent('TryMove', move, null, pokemon, target, move);
|
||||
if (tryMoveResult) {
|
||||
tryMoveResult = this.battle.runEvent('TryMove', pokemon, target, move);
|
||||
}
|
||||
if (!tryMoveResult) {
|
||||
move.mindBlownRecoil = false;
|
||||
return tryMoveResult;
|
||||
}
|
||||
|
||||
this.battle.singleEvent('UseMoveMessage', move, null, pokemon, target, move);
|
||||
|
||||
if (move.ignoreImmunity === undefined) {
|
||||
move.ignoreImmunity = (move.category === 'Status');
|
||||
}
|
||||
|
||||
if (this.battle.gen !== 4 && move.selfdestruct === 'always') {
|
||||
this.battle.faint(pokemon, pokemon, move);
|
||||
}
|
||||
|
||||
let damage: number | false | undefined | '' = false;
|
||||
if (move.target === 'all' || move.target === 'foeSide' || move.target === 'allySide' || move.target === 'allyTeam') {
|
||||
damage = this.tryMoveHit(targets, pokemon, move);
|
||||
if (damage === this.battle.NOT_FAIL) pokemon.moveThisTurnResult = null;
|
||||
if (damage || damage === 0 || damage === undefined) moveResult = true;
|
||||
} else {
|
||||
if (!targets.length) {
|
||||
this.battle.attrLastMove('[notarget]');
|
||||
this.battle.add(this.battle.gen >= 5 ? '-fail' : '-notarget', pokemon);
|
||||
return false;
|
||||
}
|
||||
if (this.battle.gen === 4 && move.selfdestruct === 'always') {
|
||||
this.battle.faint(pokemon, pokemon, move);
|
||||
}
|
||||
moveResult = this.trySpreadMoveHit(targets, pokemon, move);
|
||||
}
|
||||
if (move.selfBoost && moveResult) this.moveHit(pokemon, pokemon, move, move.selfBoost, false, true);
|
||||
if (!pokemon.hp) {
|
||||
this.battle.faint(pokemon, pokemon, move);
|
||||
}
|
||||
|
||||
if (!moveResult) {
|
||||
this.battle.singleEvent('MoveFail', move, null, target, pokemon, move);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(move.hasSheerForce && pokemon.hasAbility('sheerforce')) && !move.flags['futuremove']) {
|
||||
const originalHp = pokemon.hp;
|
||||
this.battle.singleEvent('AfterMoveSecondarySelf', move, null, pokemon, target, move);
|
||||
this.battle.runEvent('AfterMoveSecondarySelf', pokemon, target, move);
|
||||
if (pokemon && pokemon !== target && move.category !== 'Status') {
|
||||
if (pokemon.hp <= pokemon.maxhp / 2 && originalHp > pokemon.maxhp / 2) {
|
||||
this.battle.runEvent('EmergencyExit', pokemon, pokemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
canTerastallize(pokemon: Pokemon) {
|
||||
if (this.dex.gen !== 9) {
|
||||
return null;
|
||||
}
|
||||
return pokemon.teraType;
|
||||
},
|
||||
canMegaEvo(pokemon) {
|
||||
const species = pokemon.baseSpecies;
|
||||
const altForme = species.otherFormes && this.dex.species.get(species.otherFormes[0]);
|
||||
const item = pokemon.getItem();
|
||||
// Mega Rayquaza
|
||||
if ((this.battle.gen <= 7 || this.battle.ruleTable.has('+pokemontag:past') ||
|
||||
this.battle.ruleTable.has('+pokemontag:future')) &&
|
||||
altForme?.isMega && altForme?.requiredMove &&
|
||||
pokemon.baseMoves.includes(this.battle.toID(altForme.requiredMove)) && !item.zMove) {
|
||||
return altForme.name;
|
||||
}
|
||||
if (species.baseSpecies === 'Magearna' && !species.isMega) {
|
||||
return species.name.includes('Original') ? 'Magearna-Original-Mega' : 'Magearna-Mega';
|
||||
}
|
||||
if (!item.megaStone) return null;
|
||||
return item.megaStone[species.name];
|
||||
},
|
||||
modifyDamage(baseDamage, pokemon, target, move, suppressMessages = false) {
|
||||
const tr = this.battle.trunc;
|
||||
if (!move.type) move.type = '???';
|
||||
const type = move.type;
|
||||
|
||||
baseDamage += 2;
|
||||
|
||||
if (move.spreadHit) {
|
||||
// multi-target modifier (doubles only)
|
||||
const spreadModifier = this.battle.gameType === 'freeforall' ? 0.5 : 0.75;
|
||||
this.battle.debug(`Spread modifier: ${spreadModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, spreadModifier);
|
||||
} else if (move.multihitType === 'parentalbond' && move.hit > 1) {
|
||||
// Parental Bond modifier
|
||||
const bondModifier = this.battle.gen > 6 ? 0.25 : 0.5;
|
||||
this.battle.debug(`Parental Bond modifier: ${bondModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, bondModifier);
|
||||
}
|
||||
|
||||
// weather modifier
|
||||
baseDamage = this.battle.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
|
||||
|
||||
// crit - not a modifier
|
||||
const isCrit = target.getMoveHitData(move).crit;
|
||||
if (isCrit) {
|
||||
baseDamage = tr(baseDamage * (move.critModifier || (this.battle.gen >= 6 ? 1.5 : 2)));
|
||||
}
|
||||
|
||||
// random factor - also not a modifier
|
||||
baseDamage = this.battle.randomizer(baseDamage);
|
||||
|
||||
// STAB
|
||||
// The "???" type never gets STAB
|
||||
// Not even if you Roost in Gen 4 and somehow manage to use
|
||||
// Struggle in the same turn.
|
||||
// (On second thought, it might be easier to get a MissingNo.)
|
||||
if (type !== '???') {
|
||||
let stab: number | [number, number] = 1;
|
||||
|
||||
const pokeTypes = pokemon.getTypes(false, true);
|
||||
const isPrimarySTAB = move.forceSTAB || (pokemon.hasType(type) && pokeTypes[0] === type);
|
||||
const isSecondarySTAB = move.forceSTAB || (pokemon.hasType(type) && pokeTypes.length > 1 && pokeTypes[1] === type);
|
||||
const isSTAB = move.forceSTAB || pokemon.hasType(type) || pokemon.getTypes(false, true).includes(type);
|
||||
if (isPrimarySTAB) {
|
||||
stab = 1.7;
|
||||
}
|
||||
if (isSecondarySTAB) {
|
||||
stab = 1.2;
|
||||
}
|
||||
|
||||
// The Stellar tera type makes this incredibly confusing
|
||||
// If the move's type does not match one of the user's base types,
|
||||
// the Stellar tera type applies a one-time 1.2x damage boost for that type.
|
||||
//
|
||||
// If the move's type does match one of the user's base types,
|
||||
// then the Stellar tera type applies a one-time 2x STAB boost for that type,
|
||||
// and then goes back to using the regular 1.5x STAB boost for those types.
|
||||
if (pokemon.terastallized === 'Stellar') {
|
||||
if (!pokemon.stellarBoostedTypes.includes(type) || move.stellarBoosted) {
|
||||
stab = isSTAB ? 2.3 : [4915, 4096];
|
||||
move.stellarBoosted = true;
|
||||
if (pokemon.species.name !== 'Terapagos-Stellar') {
|
||||
pokemon.stellarBoostedTypes.push(type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pokemon.terastallized === type && pokeTypes.includes(type)) {
|
||||
stab = 2.3;
|
||||
}
|
||||
stab = this.battle.runEvent('ModifySTAB', pokemon, target, move, stab);
|
||||
}
|
||||
|
||||
baseDamage = this.battle.modify(baseDamage, stab);
|
||||
}
|
||||
|
||||
// types
|
||||
let typeMod = target.runEffectiveness(move);
|
||||
typeMod = this.battle.clampIntRange(typeMod, -6, 6);
|
||||
target.getMoveHitData(move).typeMod = typeMod;
|
||||
if (typeMod > 0) {
|
||||
if (!suppressMessages) this.battle.add('-supereffective', target);
|
||||
|
||||
for (let i = 0; i < typeMod; i++) {
|
||||
baseDamage *= 2;
|
||||
}
|
||||
}
|
||||
if (typeMod < 0) {
|
||||
if (!suppressMessages) this.battle.add('-resisted', target);
|
||||
|
||||
for (let i = 0; i > typeMod; i--) {
|
||||
baseDamage = tr(baseDamage / 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (isCrit && !suppressMessages) this.battle.add('-crit', target);
|
||||
|
||||
if (pokemon.status === 'brn' && move.category === 'Physical' && !pokemon.hasAbility('guts')) {
|
||||
if (this.battle.gen < 6 || move.id !== 'facade') {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
if (pokemon.status === 'psn' && move.category === 'Special') {
|
||||
if (this.battle.gen < 6 || move.id !== 'facade') {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
// Generation 5, but nothing later, sets damage to 1 before the final damage modifiers
|
||||
if (this.battle.gen === 5 && !baseDamage) baseDamage = 1;
|
||||
|
||||
// Final modifier. Modifiers that modify damage after min damage check, such as Life Orb.
|
||||
baseDamage = this.battle.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
|
||||
|
||||
if (move.isZOrMaxPowered && target.getMoveHitData(move).brokeProtect) {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.25);
|
||||
this.battle.add('-zbroken', target);
|
||||
}
|
||||
|
||||
// Generation 6-7 moves the check for minimum 1 damage after the final modifier...
|
||||
if (this.battle.gen !== 5 && !baseDamage) return 1;
|
||||
|
||||
// ...but 16-bit truncation happens even later, and can truncate to 0
|
||||
return tr(baseDamage, 16);
|
||||
},
|
||||
getDamage(source, target, move, suppressMessages = false) {
|
||||
if (typeof move === 'string') move = this.dex.getActiveMove(move);
|
||||
|
||||
if (typeof move === 'number') {
|
||||
const basePower = move;
|
||||
move = new Dex.Move({
|
||||
basePower,
|
||||
type: '???',
|
||||
category: 'Physical',
|
||||
willCrit: false,
|
||||
}) as ActiveMove;
|
||||
move.hit = 0;
|
||||
}
|
||||
|
||||
if (!target.runImmunity(move, !suppressMessages)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (move.ohko) return this.battle.gen === 3 ? target.hp : target.maxhp;
|
||||
if (move.damageCallback) return move.damageCallback.call(this.battle, source, target);
|
||||
if (move.damage === 'level') {
|
||||
return source.level;
|
||||
} else if (move.damage) {
|
||||
return move.damage;
|
||||
}
|
||||
|
||||
let category = this.battle.getCategory(move);
|
||||
|
||||
let basePower: number | false | null = move.basePower;
|
||||
if (move.basePowerCallback) {
|
||||
basePower = move.basePowerCallback.call(this.battle, source, target, move);
|
||||
}
|
||||
if (!basePower) return basePower === 0 ? undefined : basePower;
|
||||
basePower = this.battle.clampIntRange(basePower, 1);
|
||||
if (move.type === 'Electric' && move.category === 'Physical') {
|
||||
basePower += 15;
|
||||
category = 'Special';
|
||||
}
|
||||
|
||||
let critMult;
|
||||
let critRatio = this.battle.runEvent('ModifyCritRatio', source, target, move, move.critRatio || 0);
|
||||
if (this.battle.gen <= 5) {
|
||||
critRatio = this.battle.clampIntRange(critRatio, 0, 5);
|
||||
critMult = [0, 16, 8, 4, 3, 2];
|
||||
} else {
|
||||
critRatio = this.battle.clampIntRange(critRatio, 0, 4);
|
||||
if (this.battle.gen === 6) {
|
||||
critMult = [0, 16, 8, 2, 1];
|
||||
} else {
|
||||
critMult = [0, 24, 8, 2, 1];
|
||||
}
|
||||
}
|
||||
|
||||
const moveHit = target.getMoveHitData(move);
|
||||
moveHit.crit = move.willCrit || false;
|
||||
if (move.willCrit === undefined) {
|
||||
if (critRatio) {
|
||||
moveHit.crit = this.battle.randomChance(1, critMult[critRatio]);
|
||||
}
|
||||
}
|
||||
|
||||
if (moveHit.crit) {
|
||||
moveHit.crit = this.battle.runEvent('CriticalHit', target, null, move);
|
||||
}
|
||||
|
||||
// happens after crit calculation
|
||||
basePower = this.battle.runEvent('BasePower', source, target, move, basePower, true);
|
||||
|
||||
if (!basePower) return 0;
|
||||
basePower = this.battle.clampIntRange(basePower, 1);
|
||||
// Hacked Max Moves have 0 base power, even if you Dynamax
|
||||
if ((!source.volatiles['dynamax'] && move.isMax) || (move.isMax && this.dex.moves.get(move.baseMove).isMax)) {
|
||||
basePower = 0;
|
||||
}
|
||||
|
||||
const dexMove = this.dex.moves.get(move.id);
|
||||
if (source.terastallized && (source.terastallized === 'Stellar' ?
|
||||
!source.stellarBoostedTypes.includes(move.type) : source.hasType(move.type)) &&
|
||||
basePower < 60 && dexMove.priority <= 0 && !dexMove.multihit &&
|
||||
// Hard move.basePower check for moves like Dragon Energy that have variable BP
|
||||
!((move.basePower === 0 || move.basePower === 150) && move.basePowerCallback)
|
||||
) {
|
||||
basePower = 60;
|
||||
}
|
||||
|
||||
const level = source.level;
|
||||
|
||||
const attacker = move.overrideOffensivePokemon === 'target' ? target : source;
|
||||
const defender = move.overrideDefensivePokemon === 'source' ? source : target;
|
||||
|
||||
const isPhysical = move.category === 'Physical';
|
||||
let attackStat: StatIDExceptHP = move.overrideOffensiveStat || (isPhysical ? 'atk' : 'spa');
|
||||
const defenseStat: StatIDExceptHP = move.overrideDefensiveStat || (isPhysical ? 'def' : 'spd');
|
||||
|
||||
const statTable = { atk: 'Atk', def: 'Def', spa: 'SpA', spd: 'SpD', spe: 'Spe' };
|
||||
|
||||
let atkBoosts = attacker.boosts[attackStat];
|
||||
let defBoosts = defender.boosts[defenseStat];
|
||||
|
||||
let ignoreNegativeOffensive = !!move.ignoreNegativeOffensive;
|
||||
let ignorePositiveDefensive = !!move.ignorePositiveDefensive;
|
||||
|
||||
if (moveHit.crit) {
|
||||
ignoreNegativeOffensive = true;
|
||||
ignorePositiveDefensive = true;
|
||||
}
|
||||
const ignoreOffensive = !!(move.ignoreOffensive || (ignoreNegativeOffensive && atkBoosts < 0));
|
||||
const ignoreDefensive = !!(move.ignoreDefensive || (ignorePositiveDefensive && defBoosts > 0));
|
||||
|
||||
if (ignoreOffensive) {
|
||||
this.battle.debug('Negating (sp)atk boost/penalty.');
|
||||
atkBoosts = 0;
|
||||
}
|
||||
if (ignoreDefensive) {
|
||||
this.battle.debug('Negating (sp)def boost/penalty.');
|
||||
defBoosts = 0;
|
||||
}
|
||||
|
||||
let attack = attacker.calculateStat(attackStat, atkBoosts, 1, source);
|
||||
let defense = defender.calculateStat(defenseStat, defBoosts, 1, target);
|
||||
|
||||
attackStat = (category === 'Physical' ? 'atk' : 'spa');
|
||||
|
||||
// Apply Stat Modifiers
|
||||
attack = this.battle.runEvent('Modify' + statTable[attackStat], source, target, move, attack);
|
||||
defense = this.battle.runEvent('Modify' + statTable[defenseStat], target, source, move, defense);
|
||||
|
||||
if (this.battle.gen <= 4 && ['explosion', 'selfdestruct'].includes(move.id) && defenseStat === 'def') {
|
||||
defense = this.battle.clampIntRange(Math.floor(defense / 2), 1);
|
||||
}
|
||||
|
||||
const tr = this.battle.trunc;
|
||||
|
||||
// int(int(int(2 * L / 5 + 2) * A * P / D) / 50);
|
||||
const baseDamage = tr(tr(tr(tr(2 * level / 5 + 2) * basePower * attack) / defense) / 50);
|
||||
|
||||
// Calculate damage modifiers separately (order differs between generations)
|
||||
return this.modifyDamage(baseDamage, source, target, move, suppressMessages);
|
||||
},
|
||||
},
|
||||
};
|
||||
1052
data/mods/afd/sets.json
Normal file
1052
data/mods/afd/sets.json
Normal file
File diff suppressed because it is too large
Load Diff
49
data/mods/afd/typechart.ts
Normal file
49
data/mods/afd/typechart.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
export const TypeChart: import('../../../sim/dex-data').ModdedTypeDataTable = {
|
||||
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: 1,
|
||||
Poison: 1,
|
||||
Psychic: 0,
|
||||
Rock: 0,
|
||||
Steel: 1,
|
||||
Stellar: 0,
|
||||
Water: 0,
|
||||
},
|
||||
},
|
||||
ghost: {
|
||||
inherit: true,
|
||||
damageTaken: {
|
||||
Bug: 3,
|
||||
Dark: 1,
|
||||
Dragon: 1,
|
||||
Electric: 1,
|
||||
Fairy: 3,
|
||||
Fighting: 3,
|
||||
Fire: 1,
|
||||
Flying: 3,
|
||||
Ghost: 3,
|
||||
Grass: 1,
|
||||
Ground: 3,
|
||||
Ice: 1,
|
||||
Normal: 3,
|
||||
Poison: 3,
|
||||
Psychic: 1,
|
||||
Rock: 3,
|
||||
Steel: 3,
|
||||
Stellar: 0,
|
||||
Water: 1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -185,17 +185,20 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
(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 ppUps = move.noPPBoosts ? 0 : 3;
|
||||
const basePP = this.calculatePP(move, ppUps);
|
||||
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,
|
||||
pp: basePP,
|
||||
maxpp: basePP,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
pokemon.baseMoveSlots.push(newMove);
|
||||
pokemon.moveSlots.push(newMove);
|
||||
pokemon.ppUps.push(ppUps);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -298,17 +298,20 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
} else {
|
||||
source.m.scrambled.moves.push({ thing: targetAbility.id, inSlot: 'Ability' });
|
||||
const bmmMove = Dex.moves.get(targetAbility.id);
|
||||
const ppUps = move.noPPBoosts ? 0 : 3;
|
||||
const basePP = this.calculatePP(move, ppUps);
|
||||
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,
|
||||
pp: basePP,
|
||||
maxpp: basePP,
|
||||
target: bmmMove.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
source.baseMoveSlots.push(newMove);
|
||||
source.moveSlots.push(newMove);
|
||||
source.ppUps.push(ppUps);
|
||||
}
|
||||
}
|
||||
this.singleEvent('Start', sourceAbility, target.abilityState, target);
|
||||
|
|
@ -321,17 +324,20 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
} else {
|
||||
target.m.scrambled.moves.push({ thing: sourceAbility.id, inSlot: 'Ability' });
|
||||
const bmmMove = Dex.moves.get(sourceAbility.id);
|
||||
const ppUps = move.noPPBoosts ? 0 : 3;
|
||||
const basePP = this.calculatePP(move, ppUps);
|
||||
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,
|
||||
pp: basePP,
|
||||
maxpp: basePP,
|
||||
target: bmmMove.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
target.baseMoveSlots.push(newMove);
|
||||
target.moveSlots.push(newMove);
|
||||
target.ppUps.push(ppUps);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -167,11 +167,13 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
} else {
|
||||
this.m.scrambled.moves.push({ thing: ability.id, inSlot: 'Ability' });
|
||||
const move = Dex.moves.get(ability.id);
|
||||
const ppUps = move.noPPBoosts ? 0 : 3;
|
||||
const basePP = this.battle.calculatePP(move, ppUps);
|
||||
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,
|
||||
pp: basePP,
|
||||
maxpp: basePP,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
|
|
@ -179,6 +181,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
if (!isTransform) {
|
||||
this.baseMoveSlots.push(newMove);
|
||||
this.moveSlots.push(newMove);
|
||||
this.ppUps.push(ppUps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -322,17 +325,20 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
} else {
|
||||
this.m.scrambled.moves.push({ thing: item.id, inSlot: 'Item' });
|
||||
const move = Dex.moves.get(item.id);
|
||||
const ppUps = move.noPPBoosts ? 0 : 3;
|
||||
const basePP = this.battle.calculatePP(move, ppUps);
|
||||
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,
|
||||
pp: basePP,
|
||||
maxpp: basePP,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
this.baseMoveSlots.push(newMove);
|
||||
this.moveSlots.push(newMove);
|
||||
this.ppUps.push(ppUps);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -483,16 +489,17 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
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) {
|
||||
for (const [i, moveSlot] of pokemon.moveSlots.entries()) {
|
||||
let moveName = moveSlot.move;
|
||||
if (moveSlot.id === 'hiddenpower') {
|
||||
moveName = 'Hidden Power ' + this.hpType;
|
||||
}
|
||||
const move = this.battle.dex.moves.get(moveSlot.id);
|
||||
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,
|
||||
pp: Math.min(5, move.pp),
|
||||
maxpp: this.battle.gen >= 5 ? Math.min(5, move.pp) : moveSlot.maxpp,
|
||||
target: moveSlot.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
|
|
|
|||
31
data/mods/champions/abilities.ts
Normal file
31
data/mods/champions/abilities.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
|
||||
healer: {
|
||||
inherit: true,
|
||||
onResidual(pokemon) {
|
||||
for (const allyActive of pokemon.adjacentAllies()) {
|
||||
if (allyActive.status && this.randomChance(1, 2)) {
|
||||
this.add('-activate', pokemon, 'ability: Healer');
|
||||
allyActive.cureStatus();
|
||||
}
|
||||
}
|
||||
},
|
||||
desc: "50% chance this Pokemon's ally has its non-volatile status condition cured at the end of each turn.",
|
||||
shortDesc: "50% chance this Pokemon's ally has its status cured at the end of each turn.",
|
||||
},
|
||||
shedskin: {
|
||||
inherit: true,
|
||||
onResidual(pokemon) {
|
||||
if (pokemon.hp && pokemon.status && this.randomChance(3, 10)) {
|
||||
this.debug('shed skin');
|
||||
this.add('-activate', pokemon, 'ability: Shed Skin');
|
||||
pokemon.cureStatus();
|
||||
}
|
||||
},
|
||||
desc: "This Pokemon has a 30% chance to have its non-volatile status condition cured at the end of each turn.",
|
||||
shortDesc: "This Pokemon has a 30% chance to have its status cured at the end of each turn.",
|
||||
},
|
||||
unseenfist: {
|
||||
inherit: true,
|
||||
shortDesc: "This Pokemon's contact moves ignore a target's protection and deal 1/4 the usual damage.",
|
||||
},
|
||||
};
|
||||
136
data/mods/champions/conditions.ts
Normal file
136
data/mods/champions/conditions.ts
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDataTable = {
|
||||
par: {
|
||||
inherit: true,
|
||||
onBeforeMove(pokemon) {
|
||||
if (this.randomChance(1, 8)) {
|
||||
this.add('cant', pokemon, 'par');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
slp: {
|
||||
inherit: true,
|
||||
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 chance for a Pokemon to wake up on turn 2
|
||||
this.effectState.startTime = this.sample([2, 3, 3]);
|
||||
this.effectState.time = this.effectState.startTime;
|
||||
|
||||
if (target.removeVolatile('nightmare')) {
|
||||
this.add('-end', target, 'Nightmare', '[silent]');
|
||||
}
|
||||
},
|
||||
},
|
||||
frz: {
|
||||
inherit: true,
|
||||
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');
|
||||
}
|
||||
if (target.species.name === 'Shaymin-Sky' && target.baseSpecies.baseSpecies === 'Shaymin') {
|
||||
target.formeChange('Shaymin', this.effect, true);
|
||||
}
|
||||
|
||||
this.effectState.startTime = 3;
|
||||
this.effectState.time = this.effectState.startTime;
|
||||
},
|
||||
onBeforeMove(pokemon, target, move) {
|
||||
if (move.flags['defrost'] && !(move.id === 'burnup' && !pokemon.hasType('Fire'))) return;
|
||||
pokemon.statusState.time--;
|
||||
if (pokemon.statusState.time <= 0 || this.randomChance(1, 4)) {
|
||||
pokemon.cureStatus();
|
||||
return;
|
||||
}
|
||||
this.add('cant', pokemon, 'frz');
|
||||
return false;
|
||||
},
|
||||
},
|
||||
|
||||
raindance: {
|
||||
inherit: true,
|
||||
onWeatherModifyDamage(damage, attacker, defender, move) {
|
||||
if (attacker.effectiveWeather() !== 'raindance') return;
|
||||
if (move.type === 'Water') {
|
||||
this.debug('rain water boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
if (move.type === 'Fire') {
|
||||
this.debug('rain fire suppress');
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
primordialsea: {
|
||||
inherit: true,
|
||||
onWeatherModifyDamage(damage, attacker, defender, move) {
|
||||
if (attacker.effectiveWeather() !== 'primordialsea') return;
|
||||
if (move.type === 'Water') {
|
||||
this.debug('Rain water boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
sunnyday: {
|
||||
inherit: true,
|
||||
onWeatherModifyDamage(damage, attacker, defender, move) {
|
||||
if (attacker.effectiveWeather() !== 'sunnyday') return;
|
||||
if (move.id === 'hydrosteam') {
|
||||
this.debug('Sunny Day Hydro Steam boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
if (move.type === 'Fire') {
|
||||
this.debug('Sunny Day fire boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
if (move.type === 'Water') {
|
||||
this.debug('Sunny Day water suppress');
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
desolateland: {
|
||||
inherit: true,
|
||||
onWeatherModifyDamage(damage, attacker, defender, move) {
|
||||
if (attacker.effectiveWeather() !== 'desolateland') return;
|
||||
if (move.type === 'Fire') {
|
||||
this.debug('Desolate Land fire boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
sandstorm: {
|
||||
inherit: true,
|
||||
onModifySpD(spd, target, source) {
|
||||
if (target.hasType('Rock') && source.effectiveWeather() === 'sandstorm') {
|
||||
return this.modify(spd, 1.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
snowscape: {
|
||||
inherit: true,
|
||||
onModifyDef(def, target, source) {
|
||||
if (target.hasType('Ice') && source.effectiveWeather() === 'snowscape') {
|
||||
return this.modify(def, 1.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
// TODO: check Mega Sol's interaction with Deltastream
|
||||
// deltastream: {
|
||||
// inherit: true,
|
||||
// onEffectiveness(typeMod, target, type, move) {
|
||||
// if (move && move.effectType === 'Move' && move.category !== 'Status' && type === 'Flying' && typeMod > 0) {
|
||||
// this.add('-fieldactivate', 'Delta Stream');
|
||||
// return 0;
|
||||
// }
|
||||
// },
|
||||
// },
|
||||
};
|
||||
5039
data/mods/champions/formats-data.ts
Normal file
5039
data/mods/champions/formats-data.ts
Normal file
File diff suppressed because it is too large
Load Diff
1053
data/mods/champions/items.ts
Normal file
1053
data/mods/champions/items.ts
Normal file
File diff suppressed because it is too large
Load Diff
13451
data/mods/champions/learnsets.ts
Normal file
13451
data/mods/champions/learnsets.ts
Normal file
File diff suppressed because it is too large
Load Diff
1109
data/mods/champions/moves.ts
Normal file
1109
data/mods/champions/moves.ts
Normal file
File diff suppressed because it is too large
Load Diff
39
data/mods/champions/rulesets.ts
Normal file
39
data/mods/champions/rulesets.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
standardag: {
|
||||
inherit: true,
|
||||
ruleset: [
|
||||
'Obtainable', 'Team Preview', 'Cancel Mod', 'Endless Battle Clause',
|
||||
'Adjust Level = 50', 'Species Clause', 'Item Clause = 1',
|
||||
],
|
||||
onBegin() {
|
||||
this.reportPercentages = true;
|
||||
},
|
||||
},
|
||||
standard: {
|
||||
inherit: true,
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Sleep Moves Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
},
|
||||
standarddraft: {
|
||||
inherit: true,
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Nickname Clause', 'Beat Up Nicknames Mod', 'Sleep Clause Mod', 'OHKO Clause', 'Evasion Clause',
|
||||
],
|
||||
onBegin() {
|
||||
this.reportPercentages = true;
|
||||
},
|
||||
// timer: {starting: 60 * 60, grace: 0, addPerTurn: 10, maxPerTurn: 100, timeoutAutoChoose: true},
|
||||
},
|
||||
flatrules: {
|
||||
inherit: true,
|
||||
desc: "The in-game Flat Rules: Adjust Level 50, Species Clause, Item Clause = 1, -Mythical, -Restricted Legendary, Bring 6 Pick 3-6 depending on game type.",
|
||||
ruleset: ['Obtainable', 'Team Preview', 'Species Clause', 'Nickname Clause', 'Item Clause = 1', 'Adjust Level = 50', 'Picked Team Size = Auto', 'Cancel Mod'],
|
||||
banlist: ['Mythical', 'Restricted Legendary'],
|
||||
onBegin() {
|
||||
this.reportPercentages = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
498
data/mods/champions/scripts.ts
Normal file
498
data/mods/champions/scripts.ts
Normal file
|
|
@ -0,0 +1,498 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
gen: 9,
|
||||
init() {
|
||||
for (const i in this.data.Moves) {
|
||||
if (this.data.Moves[i].pp > 20) {
|
||||
this.modData('Moves', i).pp = 20;
|
||||
}
|
||||
}
|
||||
},
|
||||
statModify(baseStats, set, statName) {
|
||||
const tr = this.trunc;
|
||||
let stat = baseStats[statName];
|
||||
const evs = set.evs[statName];
|
||||
if (statName === 'hp') {
|
||||
return stat + evs + 75;
|
||||
}
|
||||
stat = stat + evs + 20;
|
||||
const nature = this.dex.natures.get(set.nature);
|
||||
// Natures are calculated with 16-bit truncation.
|
||||
// This only affects Eternatus-Eternamax in Pure Hackmons.
|
||||
if (nature.plus === statName) {
|
||||
stat = this.ruleTable.has('overflowstatmod') ? Math.min(stat, 595) : stat;
|
||||
stat = tr(tr(stat * 110, 16) / 100);
|
||||
} else if (nature.minus === statName) {
|
||||
stat = this.ruleTable.has('overflowstatmod') ? Math.min(stat, 728) : stat;
|
||||
stat = tr(tr(stat * 90, 16) / 100);
|
||||
}
|
||||
return stat;
|
||||
},
|
||||
calculatePP(move, ppUps) {
|
||||
return move.noPPBoosts ? move.pp : (move.pp / 5 + 1) * 4;
|
||||
},
|
||||
checkMoveBreaksProtect(move, attacker, defender, blockStatus = true) {
|
||||
if (move.flags['protect'] && (move.category !== 'Status' || blockStatus)) {
|
||||
return false;
|
||||
}
|
||||
if ((move.isZOrMaxPowered || attacker.hasAbility(['piercingdrill', 'unseenfist'])) &&
|
||||
!['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) {
|
||||
defender.getMoveHitData(move).brokeProtect = true;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
pokemon: {
|
||||
// Remove Trick Room underflow
|
||||
getActionSpeed() {
|
||||
let speed = this.getStat('spe', false, false);
|
||||
const trickRoomCheck = this.battle.ruleTable.has('twisteddimensionmod') ?
|
||||
!this.battle.field.getPseudoWeather('trickroom') : this.battle.field.getPseudoWeather('trickroom');
|
||||
if (trickRoomCheck) {
|
||||
speed = -speed;
|
||||
}
|
||||
return speed;
|
||||
},
|
||||
// Don't revert Mega Evolutions after fainting
|
||||
// TODO: confirm interaction with Revival Blessing
|
||||
formeChange(speciesId, source, isPermanent, abilitySlot = '0', message) {
|
||||
const rawSpecies = this.battle.dex.species.get(speciesId);
|
||||
|
||||
const species = this.setSpecies(rawSpecies, source);
|
||||
if (!species) return false;
|
||||
|
||||
if (this.battle.gen <= 2) return true;
|
||||
|
||||
// The species the opponent sees
|
||||
const apparentSpecies =
|
||||
this.illusion ? this.illusion.species.name : species.baseSpecies;
|
||||
if (isPermanent) {
|
||||
this.baseSpecies = rawSpecies;
|
||||
this.details = this.getUpdatedDetails();
|
||||
let details = (this.illusion || this).details;
|
||||
if (this.terastallized) details += `, tera:${this.terastallized}`;
|
||||
this.battle.add('detailschange', this, details);
|
||||
this.updateMaxHp();
|
||||
if (!source) {
|
||||
// Tera forme
|
||||
// Ogerpon/Terapagos text goes here
|
||||
this.formeRegression = true;
|
||||
} else if (source.effectType === 'Item') {
|
||||
this.canTerastallize = null; // National Dex behavior
|
||||
if (source.zMove) {
|
||||
this.battle.add('-burst', this, apparentSpecies, species.requiredItem);
|
||||
this.moveThisTurnResult = true; // Ultra Burst counts as an action for Truant
|
||||
} else if (source.isPrimalOrb) {
|
||||
if (this.illusion) {
|
||||
this.ability = '';
|
||||
this.battle.add('-primal', this.illusion, species.requiredItem);
|
||||
} else {
|
||||
this.battle.add('-primal', this, species.requiredItem);
|
||||
}
|
||||
} else {
|
||||
this.battle.add('-mega', this, apparentSpecies, species.requiredItem);
|
||||
this.moveThisTurnResult = true; // Mega Evolution counts as an action for Truant
|
||||
}
|
||||
} else if (source.effectType === 'Status') {
|
||||
// Shaymin-Sky -> Shaymin
|
||||
this.battle.add('-formechange', this, species.name, message);
|
||||
}
|
||||
} else {
|
||||
if (source?.effectType === 'Ability') {
|
||||
this.battle.add('-formechange', this, species.name, message, `[from] ability: ${source.name}`);
|
||||
} else {
|
||||
this.battle.add('-formechange', this, this.illusion ? this.illusion.species.name : species.name, message);
|
||||
}
|
||||
}
|
||||
if (isPermanent && (!source || !['disguise', 'iceface'].includes(source.id))) {
|
||||
if (this.illusion && source) {
|
||||
// Tera forme by Ogerpon or Terapagos breaks the Illusion
|
||||
this.ability = ''; // Don't allow Illusion to wear off
|
||||
}
|
||||
const ability = species.abilities[abilitySlot] || species.abilities['0'];
|
||||
// Ogerpon's forme change doesn't override permanent abilities
|
||||
if (source || !this.getAbility().flags['cantsuppress']) this.setAbility(ability, null, null, true);
|
||||
// However, its ability does reset upon switching out
|
||||
this.baseAbility = this.battle.toID(ability);
|
||||
}
|
||||
if (this.terastallized) {
|
||||
this.knownType = true;
|
||||
this.apparentType = this.terastallized;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// Announce status immunities from abilities without revealing the ability
|
||||
// TODO: check if this happens to other abilities besides Spicy Spray (Static, Poison Touch, etc.)
|
||||
setStatus(status, source, sourceEffect, ignoreImmunities) {
|
||||
if (!this.hp) return false;
|
||||
status = this.battle.dex.conditions.get(status);
|
||||
if (this.battle.event) {
|
||||
if (!source) source = this.battle.event.source;
|
||||
if (!sourceEffect) sourceEffect = this.battle.effect;
|
||||
}
|
||||
if (!source) source = this;
|
||||
|
||||
if (this.status === status.id) {
|
||||
if ((sourceEffect as Move)?.status === this.status) {
|
||||
this.battle.add('-fail', this, this.status);
|
||||
} else if ((sourceEffect as Move)?.status) {
|
||||
this.battle.add('-fail', source);
|
||||
this.battle.attrLastMove('[still]');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!ignoreImmunities && status.id && !(source?.hasAbility('corrosion') && ['tox', 'psn'].includes(status.id))
|
||||
) {
|
||||
// the game currently never ignores immunities
|
||||
if (!this.runStatusImmunity(status.id === 'tox' ? 'psn' : status.id)) {
|
||||
this.battle.debug('immune to status');
|
||||
if ((sourceEffect as Move)?.status || sourceEffect?.effectType === 'Ability') {
|
||||
this.battle.add('-immune', this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const prevStatus = this.status;
|
||||
const prevStatusState = this.statusState;
|
||||
if (status.id) {
|
||||
const result: boolean = this.battle.runEvent('SetStatus', this, source, sourceEffect, status);
|
||||
if (!result) {
|
||||
this.battle.debug('set status [' + status.id + '] interrupted');
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
this.status = status.id;
|
||||
this.statusState = this.battle.initEffectState({ id: status.id, target: this });
|
||||
if (source) this.statusState.source = source;
|
||||
if (status.duration) this.statusState.duration = status.duration;
|
||||
if (status.durationCallback) {
|
||||
this.statusState.duration = status.durationCallback.call(this.battle, this, source, sourceEffect);
|
||||
}
|
||||
|
||||
if (status.id && !this.battle.singleEvent('Start', status, this.statusState, this, source, sourceEffect)) {
|
||||
this.battle.debug('status start [' + status.id + '] interrupted');
|
||||
// cancel the setstatus
|
||||
this.status = prevStatus;
|
||||
this.statusState = prevStatusState;
|
||||
return false;
|
||||
}
|
||||
if (status.id && !this.battle.runEvent('AfterSetStatus', this, source, sourceEffect, status)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// Disable Fake Out if the user has already acted since switching in
|
||||
getMoves(lockedMove, restrictData) {
|
||||
if (lockedMove) {
|
||||
lockedMove = this.battle.toID(lockedMove);
|
||||
if (lockedMove === 'recharge') {
|
||||
return [{
|
||||
move: 'Recharge',
|
||||
id: 'recharge' as ID,
|
||||
}];
|
||||
}
|
||||
for (const moveSlot of this.moveSlots) {
|
||||
if (moveSlot.id !== lockedMove) continue;
|
||||
return [{
|
||||
move: moveSlot.move,
|
||||
id: moveSlot.id,
|
||||
}];
|
||||
}
|
||||
// does this happen?
|
||||
return [{
|
||||
move: this.battle.dex.moves.get(lockedMove).name,
|
||||
id: lockedMove,
|
||||
}];
|
||||
}
|
||||
const moves = [];
|
||||
let hasValidMove = false;
|
||||
for (const moveSlot of this.moveSlots) {
|
||||
let moveName = moveSlot.move;
|
||||
if (moveSlot.id === 'hiddenpower') {
|
||||
moveName = `Hidden Power ${this.hpType}`;
|
||||
if (this.battle.gen < 6) moveName += ` ${this.hpPower}`;
|
||||
} else if (moveSlot.id === 'return' || moveSlot.id === 'frustration') {
|
||||
const basePowerCallback = this.battle.dex.moves.get(moveSlot.id).basePowerCallback as (pokemon: Pokemon) => number;
|
||||
moveName += ` ${basePowerCallback(this)}`;
|
||||
}
|
||||
let target = moveSlot.target;
|
||||
switch (moveSlot.id) {
|
||||
case 'curse':
|
||||
if (!this.hasType('Ghost')) {
|
||||
target = this.battle.dex.moves.get('curse').nonGhostTarget;
|
||||
}
|
||||
break;
|
||||
case 'pollenpuff':
|
||||
// Heal Block only prevents Pollen Puff from targeting an ally when the user has Heal Block
|
||||
if (this.volatiles['healblock']) {
|
||||
target = 'adjacentFoe';
|
||||
}
|
||||
break;
|
||||
case 'terastarstorm':
|
||||
if (this.species.name === 'Terapagos-Stellar') {
|
||||
target = 'allAdjacentFoes';
|
||||
}
|
||||
break;
|
||||
}
|
||||
let disabled = moveSlot.disabled;
|
||||
if (this.volatiles['dynamax']) {
|
||||
// if each of a Pokemon's base moves are disabled by one of these effects, it will Struggle
|
||||
const canCauseStruggle = ['Encore', 'Disable', 'Taunt', 'Assault Vest', 'Belch', 'Stuff Cheeks'];
|
||||
disabled = this.maxMoveDisabled(moveSlot.id) || disabled && canCauseStruggle.includes(moveSlot.disabledSource!);
|
||||
} else if (moveSlot.pp <= 0 || (moveSlot.id === 'fakeout' && this.activeMoveActions > 0)) {
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
if (disabled === 'hidden') {
|
||||
disabled = !restrictData;
|
||||
}
|
||||
if (!disabled) {
|
||||
hasValidMove = true;
|
||||
}
|
||||
|
||||
moves.push({
|
||||
move: moveName,
|
||||
id: moveSlot.id,
|
||||
pp: moveSlot.pp,
|
||||
maxpp: moveSlot.maxpp,
|
||||
target,
|
||||
disabled,
|
||||
});
|
||||
}
|
||||
return hasValidMove ? moves : [];
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
canTerastallize(pokemon) {
|
||||
return null;
|
||||
},
|
||||
// Announce 4x and 0.25x effectiveness
|
||||
modifyDamage(baseDamage, pokemon, target, move, suppressMessages) {
|
||||
const tr = this.battle.trunc;
|
||||
if (!move.type) move.type = '???';
|
||||
const type = move.type;
|
||||
|
||||
baseDamage += 2;
|
||||
|
||||
if (move.spreadHit) {
|
||||
// multi-target modifier (doubles only)
|
||||
const spreadModifier = this.battle.gameType === 'freeforall' ? 0.5 : 0.75;
|
||||
this.battle.debug(`Spread modifier: ${spreadModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, spreadModifier);
|
||||
} else if (move.multihitType === 'parentalbond' && move.hit > 1) {
|
||||
// Parental Bond modifier
|
||||
const bondModifier = this.battle.gen > 6 ? 0.25 : 0.5;
|
||||
this.battle.debug(`Parental Bond modifier: ${bondModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, bondModifier);
|
||||
}
|
||||
|
||||
// weather modifier
|
||||
baseDamage = this.battle.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
|
||||
|
||||
// crit - not a modifier
|
||||
const isCrit = target.getMoveHitData(move).crit;
|
||||
if (isCrit) {
|
||||
baseDamage = tr(baseDamage * (move.critModifier || (this.battle.gen >= 6 ? 1.5 : 2)));
|
||||
}
|
||||
|
||||
// random factor - also not a modifier
|
||||
baseDamage = this.battle.randomizer(baseDamage);
|
||||
|
||||
// STAB
|
||||
// The "???" type never gets STAB
|
||||
// Not even if you Roost in Gen 4 and somehow manage to use
|
||||
// Struggle in the same turn.
|
||||
// (On second thought, it might be easier to get a MissingNo.)
|
||||
if (type !== '???') {
|
||||
let stab: number | [number, number] = 1;
|
||||
|
||||
const isSTAB = move.forceSTAB || pokemon.hasType(type) || pokemon.getTypes(false, true).includes(type);
|
||||
if (isSTAB) {
|
||||
stab = 1.5;
|
||||
}
|
||||
|
||||
// The Stellar tera type makes this incredibly confusing
|
||||
// If the move's type does not match one of the user's base types,
|
||||
// the Stellar tera type applies a one-time 1.2x damage boost for that type.
|
||||
//
|
||||
// If the move's type does match one of the user's base types,
|
||||
// then the Stellar tera type applies a one-time 2x STAB boost for that type,
|
||||
// and then goes back to using the regular 1.5x STAB boost for those types.
|
||||
if (pokemon.terastallized === 'Stellar') {
|
||||
if (!pokemon.stellarBoostedTypes.includes(type) || move.stellarBoosted) {
|
||||
stab = isSTAB ? 2 : [4915, 4096];
|
||||
move.stellarBoosted = true;
|
||||
if (pokemon.species.name !== 'Terapagos-Stellar') {
|
||||
pokemon.stellarBoostedTypes.push(type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pokemon.terastallized === type && pokemon.getTypes(false, true).includes(type)) {
|
||||
stab = 2;
|
||||
}
|
||||
stab = this.battle.runEvent('ModifySTAB', pokemon, target, move, stab);
|
||||
}
|
||||
|
||||
baseDamage = this.battle.modify(baseDamage, stab);
|
||||
}
|
||||
|
||||
// types
|
||||
let typeMod = target.runEffectiveness(move);
|
||||
typeMod = this.battle.clampIntRange(typeMod, -6, 6);
|
||||
target.getMoveHitData(move).typeMod = typeMod;
|
||||
if (typeMod > 0) {
|
||||
if (!suppressMessages) this.battle.add('-supereffective', target, Math.min(typeMod, 2));
|
||||
|
||||
for (let i = 0; i < typeMod; i++) {
|
||||
baseDamage *= 2;
|
||||
}
|
||||
}
|
||||
if (typeMod < 0) {
|
||||
if (!suppressMessages) this.battle.add('-resisted', target, Math.min(-typeMod, 2));
|
||||
|
||||
for (let i = 0; i > typeMod; i--) {
|
||||
baseDamage = tr(baseDamage / 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (isCrit && !suppressMessages) this.battle.add('-crit', target);
|
||||
|
||||
if (pokemon.status === 'brn' && move.category === 'Physical' && !pokemon.hasAbility('guts')) {
|
||||
if (this.battle.gen < 6 || move.id !== 'facade') {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
// Generation 5, but nothing later, sets damage to 1 before the final damage modifiers
|
||||
if (this.battle.gen === 5 && !baseDamage) baseDamage = 1;
|
||||
|
||||
// Final modifier. Modifiers that modify damage after min damage check, such as Life Orb.
|
||||
baseDamage = this.battle.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
|
||||
|
||||
if (target.getMoveHitData(move).brokeProtect) {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.25);
|
||||
if (move.isZOrMaxPowered) this.battle.add('-zbroken', target);
|
||||
}
|
||||
|
||||
// Generation 6-7 moves the check for minimum 1 damage after the final modifier...
|
||||
if (this.battle.gen !== 5 && !baseDamage) return 1;
|
||||
|
||||
// ...but 16-bit truncation happens even later, and can truncate to 0
|
||||
return tr(baseDamage, 16);
|
||||
},
|
||||
// Run `AfterHit` events even if the source fainted
|
||||
spreadMoveHit(targets, pokemon, moveOrMoveName, hitEffect?, isSecondary?, isSelf?) {
|
||||
// Hardcoded for single-target purposes
|
||||
// (no spread moves have any kind of onTryHit handler)
|
||||
const target = targets[0];
|
||||
let damage: (number | boolean | undefined)[] = [];
|
||||
for (const i of targets.keys()) {
|
||||
damage[i] = true;
|
||||
}
|
||||
const move = this.dex.getActiveMove(moveOrMoveName);
|
||||
let hitResult: boolean | number | null = true;
|
||||
let moveData = hitEffect!;
|
||||
if (!moveData) moveData = move;
|
||||
if (!moveData.flags) moveData.flags = {};
|
||||
if (move.target === 'all' && !isSelf) {
|
||||
hitResult = this.battle.singleEvent('TryHitField', moveData, {}, target || null, pokemon, move);
|
||||
} else if ((move.target === 'foeSide' || move.target === 'allySide' || move.target === 'allyTeam') && !isSelf) {
|
||||
hitResult = this.battle.singleEvent('TryHitSide', moveData, {}, target || null, pokemon, move);
|
||||
} else if (target) {
|
||||
hitResult = this.battle.singleEvent('TryHit', moveData, {}, target, pokemon, move);
|
||||
}
|
||||
if (!hitResult) {
|
||||
if (hitResult === false) {
|
||||
this.battle.add('-fail', pokemon);
|
||||
this.battle.attrLastMove('[still]');
|
||||
}
|
||||
return [[false], targets]; // single-target only
|
||||
}
|
||||
|
||||
// 0. check for substitute
|
||||
if (!isSecondary && !isSelf) {
|
||||
if (move.target !== 'all' && move.target !== 'allyTeam' && move.target !== 'allySide' && move.target !== 'foeSide') {
|
||||
damage = this.tryPrimaryHitEvent(damage, targets, pokemon, move, moveData, isSecondary);
|
||||
}
|
||||
}
|
||||
|
||||
for (const i of targets.keys()) {
|
||||
if (damage[i] === this.battle.HIT_SUBSTITUTE) {
|
||||
damage[i] = true;
|
||||
targets[i] = null;
|
||||
}
|
||||
if (targets[i] && isSecondary && !moveData.self) {
|
||||
damage[i] = true;
|
||||
}
|
||||
if (!damage[i]) targets[i] = false;
|
||||
}
|
||||
// 1. call to this.battle.getDamage
|
||||
damage = this.getSpreadDamage(damage, targets, pokemon, move, moveData, isSecondary, isSelf);
|
||||
|
||||
for (const i of targets.keys()) {
|
||||
if (damage[i] === false) targets[i] = false;
|
||||
}
|
||||
|
||||
// 2. call to this.battle.spreadDamage
|
||||
damage = this.battle.spreadDamage(damage, targets, pokemon, move);
|
||||
|
||||
for (const i of targets.keys()) {
|
||||
if (damage[i] === false) targets[i] = false;
|
||||
}
|
||||
|
||||
// 3. onHit event happens here
|
||||
damage = this.runMoveEffects(damage, targets, pokemon, move, moveData, isSecondary, isSelf);
|
||||
|
||||
for (const i of targets.keys()) {
|
||||
if (!damage[i] && damage[i] !== 0) targets[i] = false;
|
||||
}
|
||||
|
||||
// steps 4 and 5 can mess with this.battle.activeTarget, which needs to be preserved for Dancer
|
||||
const activeTarget = this.battle.activeTarget;
|
||||
|
||||
// 4. self drops (start checking for targets[i] === false here)
|
||||
if (moveData.self && !move.selfDropped) this.selfDrops(targets, pokemon, move, moveData, isSecondary);
|
||||
|
||||
// 5. secondary effects
|
||||
if (moveData.secondaries) this.secondaries(targets, pokemon, move, moveData, isSelf);
|
||||
|
||||
this.battle.activeTarget = activeTarget;
|
||||
|
||||
// 6. force switch
|
||||
if (moveData.forceSwitch) damage = this.forceSwitch(damage, targets, pokemon, move);
|
||||
|
||||
for (const i of targets.keys()) {
|
||||
if (!damage[i] && damage[i] !== 0) targets[i] = false;
|
||||
}
|
||||
|
||||
const damagedTargets: Pokemon[] = [];
|
||||
const damagedDamage = [];
|
||||
for (const [i, t] of targets.entries()) {
|
||||
if (typeof damage[i] === 'number' && t) {
|
||||
damagedTargets.push(t);
|
||||
damagedDamage.push(damage[i]);
|
||||
}
|
||||
}
|
||||
const pokemonOriginalHP = pokemon.hp;
|
||||
if (damagedDamage.length && !isSecondary && !isSelf) {
|
||||
if (this.battle.gen >= 5) {
|
||||
this.battle.runEvent('DamagingHit', damagedTargets, pokemon, move, damagedDamage);
|
||||
}
|
||||
if (moveData.onAfterHit) {
|
||||
for (const t of damagedTargets) {
|
||||
this.battle.singleEvent('AfterHit', moveData, {}, t, pokemon, move);
|
||||
}
|
||||
}
|
||||
if (this.battle.gen < 5) {
|
||||
this.battle.runEvent('DamagingHit', damagedTargets, pokemon, move, damagedDamage);
|
||||
}
|
||||
if (pokemon.hp && pokemon.hp <= pokemon.maxhp / 2 && pokemonOriginalHP > pokemon.maxhp / 2) {
|
||||
this.battle.runEvent('EmergencyExit', pokemon);
|
||||
}
|
||||
}
|
||||
|
||||
return [damage, targets];
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -575,7 +575,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
source.switchFlag = true;
|
||||
},
|
||||
hasSheerForce: true,
|
||||
hasSheerForceBoost: true,
|
||||
target: "normal",
|
||||
type: "Dragon",
|
||||
desc: "Dondozo eats a mon on the user's team, KOing it. Dondozo then gains a stat boost depending on the eaten mon's highest stat: +3 Attack for Atk/SpA, +2 Def/+2 SpD for Def/SpD, and +3 Speed for Speed.",
|
||||
|
|
@ -1106,10 +1106,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect'] || move.category === 'Status') {
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
onAfterMoveSelf(pokemon) {
|
||||
if (pokemon.statusState.time <= 0) pokemon.cureStatus();
|
||||
},
|
||||
onDisableMove(target) {
|
||||
target.maybeLocked = false; // the player knows it is locked
|
||||
},
|
||||
},
|
||||
frz: {
|
||||
name: 'frz',
|
||||
|
|
@ -98,6 +101,9 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
target.cureStatus();
|
||||
}
|
||||
},
|
||||
onDisableMove(target) {
|
||||
target.maybeLocked = false; // the player knows it is locked
|
||||
},
|
||||
},
|
||||
psn: {
|
||||
name: 'psn',
|
||||
|
|
@ -202,8 +208,11 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
onAccuracy(accuracy, target, source, move) {
|
||||
if (source === this.effectState.source) return true;
|
||||
},
|
||||
onDisableMovePriority: 1, // higher priority so it gets undone by frz, slp or Bide
|
||||
onDisableMove(target) {
|
||||
target.maybeLocked = true;
|
||||
if (this.effectState.maybeLocked) {
|
||||
target.maybeLocked = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
fakepartiallytrapped: {
|
||||
|
|
@ -211,6 +220,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
// Wrap ended this turn, but you don't know that
|
||||
// until you try to use an attack
|
||||
duration: 2,
|
||||
onDisableMovePriority: 1, // higher priority so it gets undone by frz, slp or Bide
|
||||
onDisableMove(target) {
|
||||
target.maybeLocked = true;
|
||||
},
|
||||
|
|
@ -230,9 +240,6 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
this.effectState.locked = foe;
|
||||
foe.addVolatile('partiallytrapped', target, effect);
|
||||
},
|
||||
onOverrideAction(pokemon, target, move) {
|
||||
return this.effectState.move;
|
||||
},
|
||||
onBeforeMove(pokemon, target, move) {
|
||||
if (target !== this.effectState.locked) {
|
||||
pokemon.removeVolatile('partialtrappinglock');
|
||||
|
|
@ -252,13 +259,18 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
}
|
||||
} else {
|
||||
target.addVolatile('partiallytrapped', pokemon, move);
|
||||
if (this.effectState.totalDuration - this.effectState.duration! > 0) {
|
||||
target.volatiles['partiallytrapped'].maybeLocked = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
onLockMove() {
|
||||
onSemiLockMove() {
|
||||
return this.effectState.move;
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
pokemon.maybeLocked = true;
|
||||
if (this.effectState.totalDuration - this.effectState.duration! > 1) {
|
||||
pokemon.maybeLocked = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
mustrecharge: {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
bide: {
|
||||
inherit: true,
|
||||
priority: 0,
|
||||
accuracy: true,
|
||||
condition: {
|
||||
onStart(pokemon) {
|
||||
|
|
@ -60,15 +59,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.add('-activate', pokemon, 'Bide');
|
||||
return false;
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
if (!pokemon.hasMove('bide')) {
|
||||
return;
|
||||
}
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id !== 'bide') {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
onSemiLockMove: 'bide',
|
||||
onDisableMove(target) {
|
||||
target.maybeLocked = false; // the player knows it is locked
|
||||
},
|
||||
},
|
||||
type: "???", // Will look as Normal but it's STAB-less
|
||||
|
|
@ -334,6 +327,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
for (const pokemon of this.getAllActive()) {
|
||||
pokemon.clearBoosts();
|
||||
if (pokemon !== source) {
|
||||
if (['frz', 'slp'].includes(pokemon.status)) {
|
||||
pokemon.side.lastSelectedMove = 'cannotmove' as ID;
|
||||
if (this.queue.willMove(pokemon)) {
|
||||
this.queue.changeAction(pokemon, { choice: 'move', pokemon, moveid: 'cannotmove' });
|
||||
}
|
||||
}
|
||||
pokemon.cureStatus(true);
|
||||
}
|
||||
if (pokemon.status === 'tox') {
|
||||
|
|
@ -463,7 +462,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
move: move.name,
|
||||
id: move.id,
|
||||
pp: source.moveSlots[moveslot].pp,
|
||||
maxpp: move.pp * 8 / 5,
|
||||
maxpp: this.calculatePP(move, source.ppUps[moveslot] || 0),
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,17 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
|
||||
if (!amount) amount = 1;
|
||||
ppData.pp -= amount;
|
||||
|
||||
if (ppData.pp < 0) {
|
||||
this.battle.hint("In Gen 1, if a Pokémon is forced to use a move with 0 PP, the move will underflow to have 63 PP.");
|
||||
}
|
||||
ppData.pp = ((ppData.pp % 64) + 64) % 64;
|
||||
|
||||
if (ppData.virtual && !this.transformed) {
|
||||
// sync PP from Mimic's slot, or Metronome/Mirror Move that called Mimic
|
||||
this.baseMoveSlots[this.side.lastSelectedMoveSlot].pp = ppData.pp;
|
||||
}
|
||||
|
||||
return amount;
|
||||
},
|
||||
getStat(statName, unmodified) {
|
||||
|
|
@ -156,50 +167,62 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
}
|
||||
|
||||
// If a faster partial trapping move misses against a user of Hyper Beam during a recharge turn,
|
||||
// the user of Hyper Beam will automatically use Hyper Beam during that turn.
|
||||
if (move.id === 'recharge' && !pokemon.volatiles['mustrecharge'] && !pokemon.volatiles['partiallytrapped']) {
|
||||
move = this.battle.dex.getActiveMove('hyperbeam');
|
||||
this.battle.hint(`In Gen 1, partial trapping moves like Wrap remove Hyper Beam recharges. ` +
|
||||
`If the target would have recharged, it will automatically use Hyper Beam instead.`, true);
|
||||
const abortMove = () => {
|
||||
this.battle.clearActiveMove(true);
|
||||
this.battle.runEvent('AfterMoveSelf', pokemon, target, move);
|
||||
};
|
||||
|
||||
if (move.id === 'cannotmove') {
|
||||
if (pokemon.status === 'slp') {
|
||||
this.battle.hint(
|
||||
"In Gen 1, if a Pokémon spends a turn partially trapped and switches to a Pokémon that is asleep, " +
|
||||
"the sleep counter will not decrease until you select a move with a different Pokémon."
|
||||
);
|
||||
} else if (pokemon.getLockedMove()) {
|
||||
this.battle.hint(
|
||||
"In Gen 1, when Haze cures the sleep/freeze status of a Pokémon during a multi-turn move, " +
|
||||
"that Pokémon will become soft-locked."
|
||||
);
|
||||
} else if (pokemon.getSemiLockedMove()) {
|
||||
this.battle.hint(
|
||||
"In Gen 1, when Haze cures the sleep/freeze status of a Pokémon during Bide, " +
|
||||
"the move execution will never resolve."
|
||||
);
|
||||
}
|
||||
abortMove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (target?.subFainted) target.subFainted = null;
|
||||
|
||||
this.battle.setActiveMove(move, pokemon, target);
|
||||
|
||||
if (pokemon.moveThisTurn || move.id === 'cantmove' || !this.battle.runEvent('BeforeMove', pokemon, target, move)) {
|
||||
this.battle.clearActiveMove(true);
|
||||
// This is only run for sleep.
|
||||
this.battle.runEvent('AfterMoveSelf', pokemon, target, move);
|
||||
if (pokemon.moveThisTurn || !this.battle.runEvent('BeforeMove', pokemon, target, move)) {
|
||||
abortMove();
|
||||
return;
|
||||
}
|
||||
if (move.beforeMoveCallback?.call(this.battle, pokemon, target, move)) {
|
||||
this.battle.clearActiveMove(true);
|
||||
abortMove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (move.id !== 'struggle') {
|
||||
const lockedMove = pokemon.getLockedMove();
|
||||
const lockedMove = pokemon.getLockedMove() || pokemon.getSemiLockedMove();
|
||||
if (lockedMove) sourceEffect = move;
|
||||
|
||||
// Locked moves don't deduct PP
|
||||
// Two-turn moves like Sky Attack deduct PP on their second turn.
|
||||
if ((!lockedMove && !TWO_TURN_MOVES.includes(move.id)) || pokemon.volatiles['twoturnmove']) {
|
||||
const moveSlot = pokemon.getMoveSlot(pokemon.side.lastSelectedMoveSlot);
|
||||
if (moveSlot && pokemon.deductPP(moveSlot.id, null, target) && moveSlot.pp < 0) {
|
||||
moveSlot.pp += 64;
|
||||
this.battle.hint("In Gen 1, if a Pokémon is forced to use a move with 0 PP, the move will underflow to have 63 PP.");
|
||||
}
|
||||
if (moveSlot) pokemon.deductPP(moveSlot.id, null, target);
|
||||
}
|
||||
|
||||
if (move.id !== pokemon.getMoveSlot(pokemon.side.lastSelectedMoveSlot)?.id) {
|
||||
if (!lockedMove && move.id !== pokemon.getMoveSlot(pokemon.side.lastSelectedMoveSlot)?.id) {
|
||||
this.battle.hint("Desync Clause Mod activated!");
|
||||
this.battle.hint(
|
||||
"In Gen 1, a Pokémon that thaws out might try to use a move that doesn't match the move " +
|
||||
"of the slot it last selected (switches reset to the first slot).",
|
||||
"In Gen 1, a Pokémon might default to using a move that doesn't match the move of the slot it last selected.",
|
||||
);
|
||||
this.battle.clearActiveMove(true);
|
||||
abortMove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -221,8 +244,16 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
if (sourceEffect) move.sourceEffect = sourceEffect.id;
|
||||
|
||||
if (sourceEffect?.id === 'metronome' || sourceEffect?.id === 'mirrormove') {
|
||||
const moveSlot = pokemon.getMoveSlot(pokemon.side.lastSelectedMoveSlot);
|
||||
if (moveSlot) pokemon.deductPP(moveSlot.id, -1, target);
|
||||
if (TWO_TURN_MOVES.includes(move.id)) {
|
||||
const moveSlot = pokemon.getMoveSlot(pokemon.side.lastSelectedMoveSlot);
|
||||
if (moveSlot) pokemon.deductPP(moveSlot.id, -1, target);
|
||||
}
|
||||
// FIXME: this should happen even if the slot was empty before Transform
|
||||
// https://bulbapedia.bulbagarden.net/wiki/List_of_Transform_glitches#Transform_.2B_Mirror_Move.2FMetronome_PP_error
|
||||
if (pokemon.transformed && pokemon.side.lastSelectedMoveSlot < pokemon.baseMoveSlots.length) {
|
||||
pokemon.baseMoveSlots[pokemon.side.lastSelectedMoveSlot].pp += 1;
|
||||
pokemon.baseMoveSlots[pokemon.side.lastSelectedMoveSlot].pp %= 64;
|
||||
}
|
||||
}
|
||||
|
||||
this.battle.singleEvent('ModifyMove', move, null, pokemon, target, move, move);
|
||||
|
|
@ -444,7 +475,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
let i: number;
|
||||
for (i = 0; i < hits && target.hp && pokemon.hp; i++) {
|
||||
move.hit = i + 1;
|
||||
if (move.hit === hits) move.lastHit = true;
|
||||
move.lastHit = move.hit === hits;
|
||||
moveDamage = this.moveHit(target, pokemon, move);
|
||||
if (moveDamage === false) break;
|
||||
damage = (moveDamage || 0);
|
||||
|
|
|
|||
|
|
@ -93,8 +93,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
return;
|
||||
}
|
||||
}
|
||||
let lockedMove = this.battle.runEvent('LockMove', pokemon);
|
||||
if (lockedMove === true) lockedMove = false;
|
||||
const lockedMove = pokemon.getLockedMove() || pokemon.getSemiLockedMove();
|
||||
if (
|
||||
!lockedMove &&
|
||||
(!pokemon.volatiles['partialtrappinglock'] || pokemon.volatiles['partialtrappinglock'].locked !== target)
|
||||
|
|
@ -332,7 +331,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
let i: number;
|
||||
for (i = 0; i < hits && target.hp && pokemon.hp; i++) {
|
||||
move.hit = i + 1;
|
||||
if (move.hit === hits) move.lastHit = true;
|
||||
move.lastHit = move.hit === hits;
|
||||
moveDamage = this.moveHit(target, pokemon, move);
|
||||
if (moveDamage === false) break;
|
||||
damage = (moveDamage || 0);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
durationCallback(target, source, effect) {
|
||||
return this.random(3, 5);
|
||||
},
|
||||
onLockMove: undefined, // no inherit
|
||||
onSemiLockMove: 'bide',
|
||||
},
|
||||
},
|
||||
counter: {
|
||||
|
|
@ -752,7 +754,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
triattack: {
|
||||
inherit: true,
|
||||
onHit(target, source, move) {
|
||||
move.statusRoll = ['par', 'frz', 'brn'][this.random(3)];
|
||||
move.statusRoll = this.sample(['par', 'frz', 'brn']);
|
||||
},
|
||||
secondary: {
|
||||
chance: 20,
|
||||
|
|
|
|||
|
|
@ -138,8 +138,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
}
|
||||
pokemon.lastDamage = 0;
|
||||
let lockedMove = this.battle.runEvent('LockMove', pokemon);
|
||||
if (lockedMove === true) lockedMove = false;
|
||||
const lockedMove = pokemon.getLockedMove() || pokemon.getSemiLockedMove();
|
||||
if (!lockedMove) {
|
||||
if (!pokemon.deductPP(move, null, target) && (move.id !== 'struggle')) {
|
||||
this.battle.add('cant', pokemon, 'nopp', move);
|
||||
|
|
@ -286,7 +285,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
for (i = 0; i < hits && target.hp && pokemon.hp; i++) {
|
||||
if (pokemon.status === 'slp' && !isSleepUsable) break;
|
||||
move.hit = i + 1;
|
||||
if (move.hit === hits) move.lastHit = true;
|
||||
move.lastHit = move.hit === hits;
|
||||
moveDamage = this.moveHit(target, pokemon, move);
|
||||
if (moveDamage === false) break;
|
||||
if (nullDamage && (moveDamage || moveDamage === 0 || moveDamage === undefined)) nullDamage = false;
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
for (i = 0; i < hits && target.hp && pokemon.hp; i++) {
|
||||
if (pokemon.status === 'slp' && !isSleepUsable) break;
|
||||
move.hit = i + 1;
|
||||
if (move.hit === hits) move.lastHit = true;
|
||||
move.lastHit = move.hit === hits;
|
||||
moveDamage = this.moveHit(target, pokemon, move);
|
||||
if (moveDamage === false) break;
|
||||
if (nullDamage && (moveDamage || moveDamage === 0 || moveDamage === undefined)) nullDamage = false;
|
||||
|
|
|
|||
|
|
@ -12,15 +12,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
effectspore: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact'] && !source.status) {
|
||||
const r = this.random(300);
|
||||
if (r < 10) {
|
||||
source.setStatus('slp', target);
|
||||
} else if (r < 20) {
|
||||
source.setStatus('par', target);
|
||||
} else if (r < 30) {
|
||||
source.setStatus('psn', target);
|
||||
}
|
||||
if (damage && move.flags['contact'] && this.randomChance(1, 10)) {
|
||||
const status = this.sample(['slp', 'par', 'psn']);
|
||||
source.trySetStatus(status, target);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -420,6 +420,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
for (i = 0; i < hits && target.hp && pokemon.hp; i++) {
|
||||
if (pokemon.status === 'slp' && !isSleepUsable) break;
|
||||
move.hit = i + 1;
|
||||
move.lastHit = move.hit === hits;
|
||||
|
||||
if (move.multiaccuracy && i > 0) {
|
||||
accuracy = move.accuracy;
|
||||
|
|
|
|||
63
data/mods/gen3frlg/abilities.ts
Normal file
63
data/mods/gen3frlg/abilities.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
function attemptStatuses(battle: Battle, target: Pokemon, source: Pokemon, move: ActiveMove, status: string) {
|
||||
const attackerStatused = source.trySetStatus(status, target);
|
||||
if (move.multihit && move.id !== 'triplekick' &&
|
||||
(move.lastHit || (attackerStatused && status === 'slp')) &&
|
||||
battle.randomChance(1, 100)) {
|
||||
const defenderStatused = target.trySetStatus(status, target, move);
|
||||
if (defenderStatused) {
|
||||
battle.hint("In Pokemon Ruby, Sapphire, FireRed, LeafGreen, and Colosseum, if the final hit of a multihit move (except for Triple Kick) that makes contact triggers an ability that inflicts status, then there is a 1% chance that the defender is afflicted by the same status.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
|
||||
effectspore: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact'] && !source.status) {
|
||||
const r = this.random(300);
|
||||
let status = null;
|
||||
if (r < 10) {
|
||||
status = 'slp';
|
||||
} else if (r < 20) {
|
||||
status = 'par';
|
||||
} else if (r < 30) {
|
||||
status = 'psn';
|
||||
}
|
||||
if (status) {
|
||||
attemptStatuses(this, target, source, move, status);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
flamebody: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact']) {
|
||||
if (this.randomChance(1, 3)) {
|
||||
attemptStatuses(this, target, source, move, 'brn');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
poisonpoint: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact']) {
|
||||
if (this.randomChance(1, 3)) {
|
||||
attemptStatuses(this, target, source, move, 'psn');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
static: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact']) {
|
||||
if (this.randomChance(1, 3)) {
|
||||
attemptStatuses(this, target, source, move, 'par');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
1354
data/mods/gen3frlg/formats-data.ts
Normal file
1354
data/mods/gen3frlg/formats-data.ts
Normal file
File diff suppressed because it is too large
Load Diff
146
data/mods/gen3frlg/items.ts
Normal file
146
data/mods/gen3frlg/items.ts
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
||||
aguavberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
apicotberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
brightpowder: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
choiceband: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
clawfossil: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
cornnberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
deepseascale: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
deepseatooth: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
diveball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
enigmaberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
figyberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
ganlonberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
grepaberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
hondewberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
kelpsyberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
lansatberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
liechiberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
lightball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
magoberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
magostberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
mentalherb: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
nomelberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
petayaberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
pomegberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
premierball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
qualotberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
rabutaberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
rootfossil: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
salacberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
scopelens: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
shellbell: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
souldew: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
starfberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
tamatoberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
whiteherb: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
wikiberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
};
|
||||
9336
data/mods/gen3frlg/learnsets.ts
Normal file
9336
data/mods/gen3frlg/learnsets.ts
Normal file
File diff suppressed because it is too large
Load Diff
40
data/mods/gen3frlg/rulesets.ts
Normal file
40
data/mods/gen3frlg/rulesets.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
standard: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard',
|
||||
desc: "The standard ruleset for all official Smogon singles tiers (Ubers, OU, etc.)",
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Sleep Clause Mod', 'Switch Priority Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
},
|
||||
standarddraft: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard Draft',
|
||||
desc: "The custom Draft League ruleset",
|
||||
ruleset: [
|
||||
'Obtainable', 'Nickname Clause', 'Beat Up Nicknames Mod', '+Unreleased', 'Sleep Clause Mod', 'OHKO Clause', 'Evasion Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod',
|
||||
'One Boost Passer Clause', 'Freeze Clause Mod', 'Accuracy Moves Clause', 'Baton Pass Trap Clause',
|
||||
],
|
||||
banlist: [
|
||||
'Uber', 'Smeargle + Ingrain', 'Swagger', 'Focus Band', 'King\'s Rock', 'Quick Claw', 'Baton Pass + Ancient Power', 'Baton Pass + Silver Wind',
|
||||
],
|
||||
// timer: {starting: 60 * 60, grace: 0, addPerTurn: 10, maxPerTurn: 100, timeoutAutoChoose: true},
|
||||
},
|
||||
obtainable: {
|
||||
inherit: true,
|
||||
onValidateSet(set) {
|
||||
const species = this.dex.species.get(set.species);
|
||||
if (['entei', 'raikou', 'suicune'].includes(species.id)) {
|
||||
if (!set.ivs) set.ivs = { hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31 };
|
||||
for (const stat in set.ivs) {
|
||||
if ((stat === 'atk' && set.ivs[stat] > 7) || (stat !== 'hp' && set.ivs[stat as 'def'] > 0)) {
|
||||
return [
|
||||
`${set.name} must have 7 or fewer Attack IVs and 0 IVs in all other stats except HP, due to the Roaming IVs glitch.`,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
3
data/mods/gen3frlg/scripts.ts
Normal file
3
data/mods/gen3frlg/scripts.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
inherit: 'gen3',
|
||||
};
|
||||
63
data/mods/gen3rs/abilities.ts
Normal file
63
data/mods/gen3rs/abilities.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
function attemptStatuses(battle: Battle, target: Pokemon, source: Pokemon, move: ActiveMove, status: string) {
|
||||
const attackerStatused = source.trySetStatus(status, target);
|
||||
if (move.multihit && move.id !== 'triplekick' &&
|
||||
(move.lastHit || (attackerStatused && status === 'slp')) &&
|
||||
battle.randomChance(1, 100)) {
|
||||
const defenderStatused = target.trySetStatus(status, target, move);
|
||||
if (defenderStatused) {
|
||||
battle.hint("In Pokemon Ruby, Sapphire, FireRed, LeafGreen, and Colosseum, if the final hit of a multihit move (except for Triple Kick) that makes contact triggers an ability that inflicts status, then there is a 1% chance that the defender is afflicted by the same status.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
|
||||
effectspore: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact'] && !source.status) {
|
||||
const r = this.random(300);
|
||||
let status = null;
|
||||
if (r < 10) {
|
||||
status = 'slp';
|
||||
} else if (r < 20) {
|
||||
status = 'par';
|
||||
} else if (r < 30) {
|
||||
status = 'psn';
|
||||
}
|
||||
if (status) {
|
||||
attemptStatuses(this, target, source, move, status);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
flamebody: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact']) {
|
||||
if (this.randomChance(1, 3)) {
|
||||
attemptStatuses(this, target, source, move, 'brn');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
poisonpoint: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact']) {
|
||||
if (this.randomChance(1, 3)) {
|
||||
attemptStatuses(this, target, source, move, 'psn');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
static: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact']) {
|
||||
if (this.randomChance(1, 3)) {
|
||||
attemptStatuses(this, target, source, move, 'par');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -92,15 +92,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
effectspore: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (damage && move.flags['contact'] && !source.status) {
|
||||
const r = this.random(100);
|
||||
if (r < 10) {
|
||||
source.setStatus('slp', target);
|
||||
} else if (r < 20) {
|
||||
source.setStatus('par', target);
|
||||
} else if (r < 30) {
|
||||
source.setStatus('psn', target);
|
||||
}
|
||||
if (damage && move.flags['contact'] && this.randomChance(3, 10)) {
|
||||
const status = this.sample(['slp', 'par', 'psn']);
|
||||
source.trySetStatus(status, target);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -284,6 +278,11 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
}
|
||||
},
|
||||
},
|
||||
multitype: {
|
||||
inherit: true,
|
||||
onTakeItem: false,
|
||||
onSetAbility: false, // redundant but hardcoded
|
||||
},
|
||||
naturalcure: {
|
||||
inherit: true,
|
||||
onCheckShow: undefined, // no inherit
|
||||
|
|
@ -413,6 +412,13 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
onResidualOrder: 10,
|
||||
onResidualSubOrder: 3,
|
||||
},
|
||||
stall: {
|
||||
inherit: true,
|
||||
onFractionalPriority(priority, pokemon) {
|
||||
// don't override Lagging Tail and Full Incense's -0.2 fractional priority
|
||||
if (priority >= 0) return -0.1;
|
||||
},
|
||||
},
|
||||
static: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
|
|
@ -512,10 +518,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
const target = pokemon.side.randomFoe();
|
||||
if (!target || target.fainted) return;
|
||||
const ability = target.getAbility();
|
||||
const bannedAbilities = ['forecast', 'multitype', 'trace'];
|
||||
if (bannedAbilities.includes(target.ability)) {
|
||||
return;
|
||||
}
|
||||
if (ability.flags['notrace']) return;
|
||||
pokemon.setAbility(ability, target);
|
||||
},
|
||||
flags: { notrace: 1 },
|
||||
|
|
|
|||
|
|
@ -164,6 +164,11 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
},
|
||||
},
|
||||
},
|
||||
fullincense: {
|
||||
inherit: true,
|
||||
onFractionalPriorityPriority: 1,
|
||||
onFractionalPriority: -0.2,
|
||||
},
|
||||
griseousorb: {
|
||||
inherit: true,
|
||||
onBasePower(basePower, user, target, move) {
|
||||
|
|
@ -171,6 +176,8 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
return this.chainModify(1.2);
|
||||
}
|
||||
},
|
||||
onTakeItem: false,
|
||||
onSetAbility: false,
|
||||
},
|
||||
heavyball: {
|
||||
inherit: true,
|
||||
|
|
@ -207,6 +214,11 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
}
|
||||
},
|
||||
},
|
||||
laggingtail: {
|
||||
inherit: true,
|
||||
onFractionalPriorityPriority: 1,
|
||||
onFractionalPriority: -0.2,
|
||||
},
|
||||
laxincense: {
|
||||
inherit: true,
|
||||
onModifyAccuracyPriority: 5,
|
||||
|
|
|
|||
|
|
@ -468,7 +468,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
onPrepareHit(target, source, move) {
|
||||
if (source.ignoringItem(true)) return false;
|
||||
if (source.hasAbility('multitype')) return false;
|
||||
const item = source.getItem();
|
||||
if (!this.singleEvent('TakeItem', item, source.itemState, source, source, move, item)) return false;
|
||||
if (!item.fling) return false;
|
||||
|
|
@ -696,7 +695,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
onAfterHit(target, source, move) {
|
||||
if (!target.item) return;
|
||||
if (target.ability === 'multitype') return;
|
||||
const item = target.getItem();
|
||||
if (this.runEvent('TakeItem', target, source, move, item)) {
|
||||
target.item = '';
|
||||
|
|
@ -870,8 +868,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
source.moveSlots[mimicIndex] = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: 5,
|
||||
maxpp: move.pp * 8 / 5,
|
||||
pp: Math.min(5, move.pp),
|
||||
maxpp: this.calculatePP(move, source.ppUps[mimicIndex] || 0),
|
||||
disabled: false,
|
||||
used: false,
|
||||
virtual: true,
|
||||
|
|
@ -1017,7 +1015,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect']) return;
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
this.add('-activate', target, 'Protect');
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
|
|
@ -1151,15 +1149,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
accuracy: 80,
|
||||
},
|
||||
roleplay: {
|
||||
inherit: true,
|
||||
onTryHit(target, source) {
|
||||
if (target.ability === source.ability || source.hasItem('griseousorb')) return false;
|
||||
if (target.getAbility().flags['failroleplay'] || source.ability === 'multitype') {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
safeguard: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
|
|
@ -1204,7 +1193,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.pp,
|
||||
maxpp: move.pp,
|
||||
maxpp: this.calculatePP(move, source.ppUps[sketchIndex] || 0),
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
|
|
@ -1232,9 +1221,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
snatchUser.removeVolatile('snatch');
|
||||
this.add('-activate', snatchUser, 'move: Snatch', `[of] ${source}`);
|
||||
if (this.actions.useMove(move.id, snatchUser)) {
|
||||
snatchUser.deductPP('snatch');
|
||||
|
||||
// check Pressure
|
||||
const ppDrop = this.runEvent('DeductPP', source, snatchUser, this.effectState.sourceEffect);
|
||||
const extraPP = ppDrop !== true ? ppDrop : 0;
|
||||
if (extraPP > 0) {
|
||||
snatchUser.deductPP(this.effectState.sourceEffect.id, extraPP);
|
||||
}
|
||||
|
||||
this.actions.useMove(move.id, snatchUser);
|
||||
return null;
|
||||
},
|
||||
},
|
||||
|
|
@ -1337,13 +1332,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
return !!source.volatiles['stockpile'];
|
||||
},
|
||||
},
|
||||
switcheroo: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (target.itemKnockedOff || source.itemKnockedOff) return false;
|
||||
if (target.hasAbility('multitype') || source.hasAbility('multitype')) return false;
|
||||
},
|
||||
},
|
||||
synthesis: {
|
||||
inherit: true,
|
||||
onHit(pokemon) {
|
||||
|
|
@ -1454,13 +1442,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
flags: { bypasssub: 1, metronome: 1, failencore: 1 },
|
||||
},
|
||||
trick: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (target.itemKnockedOff || source.itemKnockedOff) return false;
|
||||
if (target.hasAbility('multitype') || source.hasAbility('multitype')) return false;
|
||||
},
|
||||
},
|
||||
trickroom: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
|
|
@ -1529,15 +1510,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
recoil: [1, 3],
|
||||
},
|
||||
worryseed: {
|
||||
inherit: true,
|
||||
onTryHit(pokemon) {
|
||||
const bannedAbilities = ['multitype', 'truant'];
|
||||
if (bannedAbilities.includes(pokemon.ability) || pokemon.hasItem('griseousorb')) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
wrap: {
|
||||
inherit: true,
|
||||
accuracy: 85,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
|
|||
},
|
||||
flatrules: {
|
||||
inherit: true,
|
||||
ruleset: ['Obtainable', 'Species Clause', 'Nickname Clause', 'Beat Up Nicknames Mod', 'Item Clause = 1', 'Adjust Level Down = 50', 'Picked Team Size = Auto', 'Cancel Mod'],
|
||||
ruleset: ['Obtainable', 'Species Clause', 'Nickname Clause', 'Item Clause = 1', 'Adjust Level Down = 50', 'Picked Team Size = Auto', 'Cancel Mod'],
|
||||
},
|
||||
teampreview: {
|
||||
inherit: true,
|
||||
|
|
@ -30,26 +30,4 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
|
|||
this.makeRequest('teampreview');
|
||||
},
|
||||
},
|
||||
validatestats: {
|
||||
inherit: true,
|
||||
onValidateSet(set) {
|
||||
const species = this.dex.species.get(set.species);
|
||||
const item = this.dex.items.get(set.item);
|
||||
if (item && item.id === 'griseousorb' && species.num !== 487) {
|
||||
return ['Griseous Orb can only be held by Giratina in Generation 4.'];
|
||||
}
|
||||
if (species.num === 493 && set.evs) {
|
||||
const isEventArceus = set.moves.includes('roaroftime') || set.moves.includes('shadowforce') ||
|
||||
set.moves.includes('spacialrend');
|
||||
if (isEventArceus) {
|
||||
let stat: StatID;
|
||||
for (stat in set.evs) {
|
||||
if (set.evs[stat] > 100) {
|
||||
return ["Event Arceus may not have more than 100 of any EVs in Generation 4."];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,6 +15,17 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
this.modData('Moves', i).flags = { mirror: 1, ...move.flags };
|
||||
}
|
||||
}
|
||||
pokemon: {
|
||||
inherit: true,
|
||||
getActionSpeed() {
|
||||
let speed = this.getStat('spe', false, false);
|
||||
const trickRoomCheck = this.battle.ruleTable.has('twisteddimensionmod') ?
|
||||
!this.battle.field.getPseudoWeather('trickroom') : this.battle.field.getPseudoWeather('trickroom');
|
||||
if (trickRoomCheck) {
|
||||
speed = -speed;
|
||||
}
|
||||
return speed;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
inherit: true,
|
||||
|
|
@ -27,6 +38,15 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
// pokemon.lastMove is reset for all Pokemon on the field after a switch. This affects Mirror Move.
|
||||
for (const poke of this.battle.getAllActive()) poke.lastMove = null;
|
||||
if (this.battle.gen === 1) pokemon.side.lastSelectedMoveSlot = 0;
|
||||
for (const poke of pokemon.foes()) {
|
||||
if (poke.volatiles['partialtrappinglock'] && poke.moveSlots[poke.side.lastSelectedMoveSlot].id === 'metronome') {
|
||||
// this is not done for Mirror Move, potentially resulting in a desync
|
||||
poke.side.lastSelectedMove = 'metronome' as ID;
|
||||
if (this.battle.queue.willMove(poke)) {
|
||||
this.battle.queue.changeAction(poke, { choice: 'move', poke, moveid: 'metronome' });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pokemon.side.faintedThisTurn && pokemon.draggedIn !== this.battle.turn) {
|
||||
this.battle.runEvent('AfterSwitchInSelf', pokemon);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -663,12 +663,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, effect) {
|
||||
onTryHit(target, source, move) {
|
||||
// Quick Guard only blocks moves with a natural positive priority
|
||||
// (e.g. it doesn't block 0 priority moves boosted by Prankster)
|
||||
if (effect && (effect.id === 'feint' || this.dex.moves.get(effect.id).priority <= 0)) {
|
||||
if (move.id === 'feint' || this.dex.moves.get(move.id).priority <= 0) {
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
this.add('-activate', target, 'Quick Guard');
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
|
|
@ -685,6 +686,19 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
priority: 3,
|
||||
flags: { noassist: 1, failcopycat: 1 },
|
||||
condition: {
|
||||
inherit: true,
|
||||
onFoeRedirectTarget(target, source, source2, move) {
|
||||
const ragePowderUser = this.effectState.target;
|
||||
if (ragePowderUser.isSkyDropped()) return;
|
||||
|
||||
if (this.validTarget(ragePowderUser, source, move.target)) {
|
||||
if (move.smartTarget) move.smartTarget = false;
|
||||
this.debug("Rage Powder redirected target of move");
|
||||
return ragePowderUser;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
reflect: {
|
||||
inherit: true,
|
||||
|
|
|
|||
|
|
@ -169,14 +169,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, effect) {
|
||||
onTryHit(target, source, move) {
|
||||
// Wide Guard blocks damaging spread moves
|
||||
if (
|
||||
effect &&
|
||||
(effect.category === 'Status' || (effect.target !== 'allAdjacent' && effect.target !== 'allAdjacentFoes'))
|
||||
) {
|
||||
if (move.category === 'Status' || (move?.target !== 'allAdjacent' && move.target !== 'allAdjacentFoes')) {
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
this.add('-activate', target, 'move: Wide Guard');
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
|
|
|
|||
|
|
@ -1,369 +0,0 @@
|
|||
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
|
||||
merciless: {
|
||||
shortDesc: "This Pokemon's attacks are critical hits if the target is statused.",
|
||||
onModifyCritRatio(critRatio, source, target) {
|
||||
if (target?.status) return 5;
|
||||
},
|
||||
name: "Merciless",
|
||||
rating: 1.5,
|
||||
num: 196,
|
||||
gen: 6,
|
||||
},
|
||||
pocketdimension: {
|
||||
shortDesc: "This Pokemon switches out after using a status move.",
|
||||
onModifyMove(move, pokemon) {
|
||||
if (move.category === 'Status') {
|
||||
move.selfSwitch = true;
|
||||
this.add('-ability', pokemon, 'Pocket Dimension');
|
||||
this.add('-message', `${pokemon.name} will switch out if this moves lands!`);
|
||||
}
|
||||
},
|
||||
name: "Pocket Dimension",
|
||||
rating: 4.5,
|
||||
},
|
||||
grassysurge: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
mistysurge: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
neutralizinggas: {
|
||||
inherit: true,
|
||||
// Ability suppression cancelled in scripts.ts
|
||||
// new Ability suppression implemented in scripts.ts
|
||||
onSwitchIn: undefined, // no inherit
|
||||
onEnd: undefined, // no inherit
|
||||
onStart(pokemon) {
|
||||
this.add('-ability', pokemon, 'Neutralizing Gas');
|
||||
},
|
||||
// onModifyPriority implemented in relevant abilities
|
||||
onFoeBeforeMovePriority: 13,
|
||||
onFoeBeforeMove(attacker, defender, move) {
|
||||
attacker.addVolatile('neutralizinggas');
|
||||
},
|
||||
condition: {
|
||||
onAfterMove(pokemon) {
|
||||
pokemon.removeVolatile('neutralizinggas');
|
||||
},
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
|
||||
desc: "While this Pokemon is active, opposing Pokemon's moves and their effects ignore its own Ability. Does not affect the As One, Battle Bond, Comatose, Disguise, Gulp Missile, Ice Face, Multitype, Power Construct, RKS System, Schooling, Shields Down, Stance Change, or Zen Mode Abilities.",
|
||||
shortDesc: "While this Pokemon is active, opposing Pokemon's Ability has no effect when it uses moves.",
|
||||
gen: 6,
|
||||
},
|
||||
nostalgiatrip: {
|
||||
shortDesc: "This Pokemon's moves have the damage categories they would have in Gen 3. Fairy-type moves are Special.",
|
||||
onStart(pokemon) {
|
||||
this.add('-ability', pokemon, 'Nostalgia Trip');
|
||||
this.add('-message', `This Pokemon is experiencing a nostalgia trip!`);
|
||||
},
|
||||
onModifyMovePriority: 8,
|
||||
onModifyMove(move, pokemon) {
|
||||
if (move.category === "Status") return;
|
||||
if (['Fire', 'Water', 'Grass', 'Electric', 'Dark', 'Psychic', 'Dragon', 'Fairy', 'Ice'].includes(move.type)) {
|
||||
move.category = "Special";
|
||||
} else {
|
||||
move.category = "Physical";
|
||||
}
|
||||
},
|
||||
name: "Nostalgia Trip",
|
||||
rating: 4,
|
||||
gen: 6,
|
||||
},
|
||||
weatherreport: {
|
||||
onBeforeMovePriority: 0.5,
|
||||
onBeforeMove(target, source, move) {
|
||||
if (move.type === 'Fire') {
|
||||
this.field.setWeather('sunnyday');
|
||||
} else if (move.type === 'Water') {
|
||||
this.field.setWeather('raindance');
|
||||
}
|
||||
},
|
||||
name: "Weather Report",
|
||||
shortDesc: "Before using a Water or Fire-type move, this Pokemon sets Rain Dance or Sunny Day respectively.",
|
||||
rating: 4,
|
||||
gen: 6,
|
||||
},
|
||||
armortail: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
brainpower: {
|
||||
onModifySpAPriority: 5,
|
||||
onModifySpA(spa) {
|
||||
return this.chainModify(2);
|
||||
},
|
||||
name: "Brain Power",
|
||||
shortDesc: "This Pokemon's Special Attack is doubled.",
|
||||
rating: 5,
|
||||
},
|
||||
neuroforce: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
bugzapper: {
|
||||
onTryHit(target, source, move) {
|
||||
if (target !== source && move.type === 'Bug') {
|
||||
if (!source.addVolatile('trapped', target, move, 'trapper')) {
|
||||
this.add('-immune', target, '[from] ability: Bug Zapper');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
name: "Bug Zapper",
|
||||
shortDesc: "This Pokemon is immune to Bug-type moves and traps the foe if hit by one.",
|
||||
rating: 5,
|
||||
},
|
||||
exoskeleton: {
|
||||
onSourceModifyDamage(damage, source, target, move) {
|
||||
if (move.category === 'Physical') {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
name: "Exoskeleton",
|
||||
shortDesc: "This Pokemon receives 1/2 damage from physical attacks; Hazard immunity.",
|
||||
rating: 4,
|
||||
},
|
||||
icescales: {
|
||||
inherit: true,
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, attacker, defender, move) {
|
||||
if (move.type === 'Ice') {
|
||||
this.debug('Ice Scales boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onModifySpAPriority: 5,
|
||||
onModifySpA(atk, attacker, defender, move) {
|
||||
if (move.type === 'Ice') {
|
||||
this.debug('Ice Scales boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onImmunity(type, pokemon) {
|
||||
if (type === 'hail') return false;
|
||||
},
|
||||
shortDesc: "This Pokemon receives 1/2 damage from special attacks. Ice moves have 1.5x power. Hail immunity.",
|
||||
gen: 6,
|
||||
},
|
||||
eartheater: {
|
||||
inherit: true,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (effect && (effect.id === 'stealthrock' || effect.id === 'spikes')) {
|
||||
this.heal(damage);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
shortDesc: "Heals 1/4 of its max HP when hit by Ground; Ground immunity. Healed by Spikes and Stealth Rock.",
|
||||
gen: 6,
|
||||
},
|
||||
toxicchain: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
shellejection: {
|
||||
onModifyMovePriority: -1,
|
||||
onModifyMove(move, attacker) {
|
||||
if (move.category === 'Special') {
|
||||
attacker.addVolatile('shellejection');
|
||||
this.add('-ability', attacker, 'Shell Ejection');
|
||||
this.add('-message', `${attacker.name} is getting ready to leave the battlefield!`);
|
||||
this.add('-message', `${attacker.name} can no longer use status moves!`);
|
||||
}
|
||||
},
|
||||
condition: {
|
||||
duration: 2,
|
||||
onDisableMove(pokemon) {
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
const move = this.dex.moves.get(moveSlot.id);
|
||||
if (move.category === 'Status' && move.id !== 'mefirst') {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
onSwitchOut(pokemon) {
|
||||
pokemon.heal(pokemon.baseMaxhp / 3);
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
this.add('-ability', pokemon, 'Shell Ejection');
|
||||
this.add('-message', `${pokemon.name} ejected itself from its shell!`);
|
||||
pokemon.heal(pokemon.baseMaxhp / 3);
|
||||
pokemon.switchFlag = true;
|
||||
},
|
||||
},
|
||||
name: "Shell Ejection",
|
||||
rating: 3.5,
|
||||
gen: 6,
|
||||
shortDesc: "On using Special move: switching heals 1/3, can't use status, switches out at end of next turn.",
|
||||
},
|
||||
sharpness: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
dauntlessshield: {
|
||||
onStart(pokemon) {
|
||||
this.boost({ def: 1 }, pokemon);
|
||||
pokemon.addVolatile('dauntlessshield');
|
||||
},
|
||||
onResidualOrder: 6,
|
||||
onResidual(pokemon) {
|
||||
if (pokemon.positiveBoosts()) {
|
||||
this.heal(pokemon.baseMaxhp / 16);
|
||||
this.add('-message', `${pokemon.name}'s shield gives it strength!`);
|
||||
}
|
||||
},
|
||||
name: "Dauntless Shield",
|
||||
rating: 5,
|
||||
num: 235,
|
||||
shortDesc: "+1 Defense on switch-in. Heals 1/16 of max HP if it has a positive boost.",
|
||||
gen: 6,
|
||||
},
|
||||
confidence: {
|
||||
onSourceAfterFaint(length, target, source, effect) {
|
||||
if (effect && effect.effectType === 'Move') {
|
||||
this.boost({ spa: length }, source);
|
||||
}
|
||||
},
|
||||
name: "Confidence",
|
||||
rating: 3,
|
||||
shortDesc: "This Pokemon's Sp. Atk is raised by 1 stage if it attacks and KOes another Pokemon.",
|
||||
gen: 6,
|
||||
},
|
||||
electricsurge: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
goodasgold: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
opportunist: {
|
||||
inherit: true,
|
||||
onUpdate(pokemon) {
|
||||
let activate = false;
|
||||
const boosts: SparseBoostsTable = {};
|
||||
let i: BoostID;
|
||||
for (i in pokemon.boosts) {
|
||||
if (pokemon.boosts[i] < 0) {
|
||||
activate = true;
|
||||
boosts[i] = 0;
|
||||
}
|
||||
}
|
||||
if (this.effectState.herb) return;
|
||||
if (activate) {
|
||||
pokemon.setBoost(boosts);
|
||||
this.effectState.herb = true;
|
||||
this.add('-ability', pokemon, 'Opportunist');
|
||||
this.add('-clearnegativeboost', pokemon, '[silent]');
|
||||
}
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
delete this.effectState.herb;
|
||||
},
|
||||
shortDesc: "Copies foe's stat gains as they happen. Resets negative stat changes once per switch-in.",
|
||||
gen: 6,
|
||||
},
|
||||
intoxicate: {
|
||||
onModifyTypePriority: -1,
|
||||
onModifyType(move, pokemon) {
|
||||
const noModifyType = [
|
||||
'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'terrainpulse', 'weatherball',
|
||||
];
|
||||
if (move.type === 'Normal' && !noModifyType.includes(move.id) &&
|
||||
!(move.isZ && move.category !== 'Status') && !(move.name === 'Tera Blast' && pokemon.terastallized)) {
|
||||
move.type = 'Poison';
|
||||
move.typeChangerBoosted = this.effect;
|
||||
}
|
||||
},
|
||||
onBasePowerPriority: 23,
|
||||
onBasePower(basePower, pokemon, target, move) {
|
||||
if (move.typeChangerBoosted) return this.chainModify([5325, 4096]);
|
||||
},
|
||||
name: "Intoxicate",
|
||||
rating: 4,
|
||||
shortDesc: "This Pokemon's Normal-type moves become Poison-type and have 1.3x power.",
|
||||
},
|
||||
dragonsgale: {
|
||||
onStart(source) {
|
||||
this.field.setWeather('deltastream');
|
||||
},
|
||||
onAnySetWeather(target, source, weather) {
|
||||
const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
|
||||
if (this.field.getWeather().id === 'deltastream' && !strongWeathers.includes(weather.id)) return false;
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
if (this.field.weatherState.source !== pokemon) return;
|
||||
for (const target of this.getAllActive()) {
|
||||
if (target === pokemon) continue;
|
||||
if (target.hasAbility('dragonsgale')) {
|
||||
this.field.weatherState.source = target;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.field.clearWeather();
|
||||
},
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (effect && (effect.id === 'stealthrock' || effect.id === 'spikes')) {
|
||||
return damage / 2;
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Dragon's Gale",
|
||||
shortDesc: "On switch-in, sets Delta Stream. User takes halved damage from hazards.",
|
||||
rating: 5,
|
||||
},
|
||||
parentalbond: {
|
||||
onPrepareHit(source, target, move) {
|
||||
if (move.category === 'Status' || move.selfdestruct || move.multihit) return;
|
||||
if ([
|
||||
'endeavor', 'seismictoss', 'psywave', 'nightshade', 'sonicboom', 'dragonrage',
|
||||
'superfang', 'naturesmadness', 'bide', 'counter', 'mirrorcoat', 'metalburst',
|
||||
].includes(move.id)) return;
|
||||
if (!move.spreadHit && !move.isZ && !move.isMax) {
|
||||
move.multihit = 2;
|
||||
move.multihitType = 'parentalbond';
|
||||
}
|
||||
},
|
||||
onSourceModifySecondaries(secondaries, target, source, move) {
|
||||
if (move.multihitType === 'parentalbond' && move.id === 'secretpower' && move.hit < 2) {
|
||||
// hack to prevent accidentally suppressing King's Rock/Razor Fang
|
||||
return secondaries.filter(effect => effect.volatileStatus === 'flinch');
|
||||
}
|
||||
},
|
||||
name: "Parental Bond",
|
||||
rating: 4.5,
|
||||
shortDesc: "This Pokemon's damaging moves hit twice. The second hit has its damage quartered.",
|
||||
num: 184,
|
||||
},
|
||||
|
||||
// for ngas
|
||||
galewings: {
|
||||
// for ngas
|
||||
inherit: true,
|
||||
onModifyPriority(priority, pokemon, target, move) {
|
||||
for (const poke of this.getAllActive()) {
|
||||
if (poke.hasAbility('neutralizinggas') && poke.side.id !== pokemon.side.id && !poke.abilityState.ending) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (move && move.type === 'Flying') return priority + 1;
|
||||
},
|
||||
},
|
||||
prankster: {
|
||||
// for ngas
|
||||
inherit: true,
|
||||
onModifyPriority(priority, pokemon, target, move) {
|
||||
for (const poke of this.getAllActive()) {
|
||||
if (poke.hasAbility('neutralizinggas') && poke.side.id !== pokemon.side.id && !poke.abilityState.ending) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (move?.category === 'Status') {
|
||||
move.pranksterBoosted = true;
|
||||
return priority + 1;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormatsDataTable = {
|
||||
blaziken: {
|
||||
tier: "OU",
|
||||
},
|
||||
blazikenmega: {
|
||||
tier: "OU",
|
||||
},
|
||||
gengarmega: {
|
||||
tier: "OU",
|
||||
},
|
||||
kangaskhanmega: {
|
||||
tier: "OU",
|
||||
},
|
||||
lucariomega: {
|
||||
tier: "OU",
|
||||
},
|
||||
mawilemega: {
|
||||
tier: "OU",
|
||||
},
|
||||
sableyemega: {
|
||||
tier: "OU",
|
||||
},
|
||||
salamencemega: {
|
||||
tier: "OU",
|
||||
},
|
||||
};
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
||||
meteorite: {
|
||||
name: "Meteorite",
|
||||
spritenum: 615,
|
||||
megaStone: { "Rayquaza": "Rayquaza-Mega" },
|
||||
itemUser: ["Rayquaza"],
|
||||
onTakeItem(item, source) {
|
||||
return !item.megaStone?.[source.baseSpecies.baseSpecies];
|
||||
},
|
||||
desc: "If held by a Rayquaza, this item allows it to Mega Evolve in battle.",
|
||||
},
|
||||
};
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||
stealthrock: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Stealth Rock');
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) return;
|
||||
const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6);
|
||||
this.damage(pokemon.maxhp * (2 ** typeMod) / 8);
|
||||
},
|
||||
},
|
||||
},
|
||||
toxicspikes: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Toxic Spikes');
|
||||
this.effectState.layers = 1;
|
||||
},
|
||||
onSideRestart(side) {
|
||||
if (this.effectState.layers >= 2) return false;
|
||||
this.add('-sidestart', side, 'move: Toxic Spikes');
|
||||
this.effectState.layers++;
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded()) return;
|
||||
if (pokemon.hasType('Poison')) {
|
||||
this.add('-sideend', pokemon.side, 'move: Toxic Spikes', `[of] ${pokemon}`);
|
||||
pokemon.side.removeSideCondition('toxicspikes');
|
||||
} else if (pokemon.hasType('Steel') || pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) {
|
||||
// do nothing
|
||||
} else if (this.effectState.layers >= 2) {
|
||||
pokemon.trySetStatus('tox', pokemon.side.foe.active[0]);
|
||||
} else {
|
||||
pokemon.trySetStatus('psn', pokemon.side.foe.active[0]);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
spikes: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'Spikes');
|
||||
this.effectState.layers = 1;
|
||||
},
|
||||
onSideRestart(side) {
|
||||
if (this.effectState.layers >= 3) return false;
|
||||
this.add('-sidestart', side, 'Spikes');
|
||||
this.effectState.layers++;
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) return;
|
||||
const damageAmounts = [0, 3, 4, 6]; // 1/8, 1/6, 1/4
|
||||
this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
|
||||
},
|
||||
},
|
||||
},
|
||||
stickyweb: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Sticky Web');
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) return;
|
||||
this.add('-activate', pokemon, 'move: Sticky Web');
|
||||
this.boost({ spe: -1 }, pokemon, pokemon.side.foe.active[0], this.dex.getActiveMove('stickyweb'));
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1,249 +0,0 @@
|
|||
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
|
||||
audinomega: {
|
||||
inherit: true,
|
||||
types: ["Normal", "Electric"],
|
||||
baseStats: { hp: 103, atk: 60, def: 120, spa: 110, spd: 97, spe: 55 },
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
houndoommega: {
|
||||
inherit: true,
|
||||
types: ["Dark", "Fire"],
|
||||
baseStats: { hp: 75, atk: 90, def: 90, spa: 140, spd: 90, spe: 115 },
|
||||
abilities: { 0: "Merciless" },
|
||||
},
|
||||
lucariomega: {
|
||||
inherit: true,
|
||||
types: ["Fighting", "Steel"],
|
||||
baseStats: { hp: 70, atk: 125, def: 70, spa: 140, spd: 94, spe: 126 },
|
||||
abilities: { 0: "Lightning Rod" },
|
||||
},
|
||||
banettemega: {
|
||||
inherit: true,
|
||||
types: ["Ghost", "Steel"],
|
||||
baseStats: { hp: 64, atk: 149, def: 75, spa: 83, spd: 83, spe: 101 },
|
||||
abilities: { 0: "Pocket Dimension" },
|
||||
},
|
||||
glaliemega: {
|
||||
inherit: true,
|
||||
types: ["Ice", "Steel"],
|
||||
baseStats: { hp: 80, atk: 160, def: 70, spa: 95, spd: 70, spe: 105 },
|
||||
abilities: { 0: "Refrigerate" },
|
||||
},
|
||||
venusaurmega: {
|
||||
inherit: true,
|
||||
types: ["Grass", "Poison"],
|
||||
baseStats: { hp: 80, atk: 82, def: 123, spa: 120, spd: 120, spe: 100 },
|
||||
abilities: { 0: "Grassy Surge" },
|
||||
},
|
||||
blastoisemega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Fairy"],
|
||||
baseStats: { hp: 79, atk: 83, def: 130, spa: 135, spd: 105, spe: 98 },
|
||||
abilities: { 0: "Misty Surge" },
|
||||
},
|
||||
charizardmegay: {
|
||||
inherit: true,
|
||||
types: ["Fire", "Flying"],
|
||||
baseStats: { hp: 78, atk: 94, def: 93, spa: 159, spd: 110, spe: 100 },
|
||||
abilities: { 0: "Dragon's Gale" },
|
||||
},
|
||||
alakazammega: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Ice"],
|
||||
baseStats: { hp: 55, atk: 50, def: 75, spa: 155, spd: 125, spe: 140 },
|
||||
abilities: { 0: "Magic Guard" },
|
||||
},
|
||||
pinsirmega: {
|
||||
inherit: true,
|
||||
types: ["Bug", "Ice"],
|
||||
baseStats: { hp: 65, atk: 150, def: 110, spa: 80, spd: 85, spe: 110 },
|
||||
abilities: { 0: "Mountaineer" },
|
||||
},
|
||||
gengarmega: {
|
||||
inherit: true,
|
||||
types: ["Ghost", "Poison"],
|
||||
baseStats: { hp: 60, atk: 65, def: 105, spa: 155, spd: 105, spe: 110 },
|
||||
abilities: { 0: "Neutralizing Gas" },
|
||||
},
|
||||
aerodactylmega: {
|
||||
inherit: true,
|
||||
types: ["Rock", "Flying"],
|
||||
baseStats: { hp: 80, atk: 140, def: 65, spa: 85, spd: 100, spe: 145 },
|
||||
abilities: { 0: "Nostalgia Trip" },
|
||||
},
|
||||
steelixmega: {
|
||||
inherit: true,
|
||||
types: ["Steel", "Ground"],
|
||||
baseStats: { hp: 75, atk: 135, def: 210, spa: 55, spd: 105, spe: 30 },
|
||||
abilities: { 0: "Flash Fire" },
|
||||
weightkg: 999.9,
|
||||
},
|
||||
altariamega: {
|
||||
inherit: true,
|
||||
types: ["Dragon", "Fairy"],
|
||||
baseStats: { hp: 75, atk: 90, def: 90, spa: 140, spd: 115, spe: 80 },
|
||||
abilities: { 0: "Weather Report" },
|
||||
},
|
||||
sceptilemega: {
|
||||
inherit: true,
|
||||
types: ["Grass", "Dragon"],
|
||||
baseStats: { hp: 70, atk: 95, def: 79, spa: 145, spd: 99, spe: 142 },
|
||||
abilities: { 0: "Armor Tail" },
|
||||
},
|
||||
swampertmega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Poison"],
|
||||
baseStats: { hp: 100, atk: 145, def: 110, spa: 85, spd: 110, spe: 85 },
|
||||
abilities: { 0: "Toxic Chain" },
|
||||
},
|
||||
manectricmega: {
|
||||
inherit: true,
|
||||
types: ["Electric"],
|
||||
baseStats: { hp: 70, atk: 75, def: 80, spa: 135, spd: 85, spe: 130 },
|
||||
abilities: { 0: "Bug Zapper" },
|
||||
},
|
||||
absolmega: {
|
||||
inherit: true,
|
||||
types: ["Dark", "Fairy"],
|
||||
baseStats: { hp: 65, atk: 130, def: 60, spa: 135, spd: 60, spe: 115 },
|
||||
abilities: { 0: "Neuroforce" },
|
||||
},
|
||||
medichammega: {
|
||||
inherit: true,
|
||||
types: ["Fighting", "Psychic"],
|
||||
baseStats: { hp: 60, atk: 60, def: 100, spa: 90, spd: 100, spe: 100 },
|
||||
abilities: { 0: "Brain Power" },
|
||||
},
|
||||
sableyemega: {
|
||||
inherit: true,
|
||||
types: ["Dark", "Ghost"],
|
||||
baseStats: { hp: 50, atk: 95, def: 115, spa: 85, spd: 115, spe: 20 },
|
||||
},
|
||||
beedrillmega: {
|
||||
inherit: true,
|
||||
types: ["Bug", "Rock"],
|
||||
baseStats: { hp: 65, atk: 140, def: 85, spa: 45, spd: 85, spe: 75 },
|
||||
abilities: { 0: "Exoskeleton" },
|
||||
},
|
||||
mawilemega: {
|
||||
inherit: true,
|
||||
types: ["Steel", "Fairy"],
|
||||
baseStats: { hp: 50, atk: 90, def: 125, spa: 70, spd: 95, spe: 50 },
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
abomasnowmega: {
|
||||
inherit: true,
|
||||
types: ["Grass"],
|
||||
abilities: { 0: "Ice Scales" },
|
||||
},
|
||||
cameruptmega: {
|
||||
inherit: true,
|
||||
types: ["Fire", "Ground"],
|
||||
baseStats: { hp: 70, atk: 80, def: 140, spa: 135, spd: 115, spe: 20 },
|
||||
abilities: { 0: "Earth Eater" },
|
||||
},
|
||||
slowbromega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Psychic"],
|
||||
baseStats: { hp: 95, atk: 75, def: 150, spa: 120, spd: 120, spe: 30 },
|
||||
abilities: { 0: "Shell Ejection" },
|
||||
},
|
||||
gallademega: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Fighting"],
|
||||
baseStats: { hp: 68, atk: 150, def: 100, spa: 75, spd: 127, spe: 98 },
|
||||
abilities: { 0: "Sharpness" },
|
||||
},
|
||||
ampharosmega: {
|
||||
inherit: true,
|
||||
types: ["Electric", "Dragon"],
|
||||
baseStats: { hp: 90, atk: 95, def: 95, spa: 165, spd: 110, spe: 55 },
|
||||
abilities: { 0: "Mega Launcher" },
|
||||
},
|
||||
gyaradosmega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Flying"],
|
||||
baseStats: { hp: 95, atk: 130, def: 109, spa: 85, spd: 130, spe: 91 },
|
||||
abilities: { 0: "Aerilate" },
|
||||
},
|
||||
heracrossmega: {
|
||||
inherit: true,
|
||||
types: ["Bug", "Fighting"],
|
||||
baseStats: { hp: 80, atk: 150, def: 150, spa: 40, spd: 110, spe: 70 },
|
||||
abilities: { 0: "Iron Barbs" },
|
||||
},
|
||||
sharpedomega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Electric"],
|
||||
baseStats: { hp: 70, atk: 130, def: 55, spa: 145, spd: 55, spe: 105 },
|
||||
abilities: { 0: "No Guard" },
|
||||
},
|
||||
gardevoirmega: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Fairy"],
|
||||
baseStats: { hp: 68, atk: 65, def: 100, spa: 150, spd: 127, spe: 108 },
|
||||
},
|
||||
aggronmega: {
|
||||
inherit: true,
|
||||
types: ["Steel"],
|
||||
baseStats: { hp: 70, atk: 145, def: 185, spa: 85, spd: 85, spe: 60 },
|
||||
abilities: { 0: "Dauntless Shield" },
|
||||
},
|
||||
kangaskhanmega: {
|
||||
inherit: true,
|
||||
types: ["Normal", "Ground"],
|
||||
baseStats: { hp: 105, atk: 125, def: 105, spa: 50, spd: 105, spe: 100 },
|
||||
},
|
||||
salamencemega: {
|
||||
inherit: true,
|
||||
types: ["Dragon", "Flying"],
|
||||
baseStats: { hp: 95, atk: 135, def: 105, spa: 155, spd: 105, spe: 105 },
|
||||
abilities: { 0: "Confidence" },
|
||||
},
|
||||
garchompmega: {
|
||||
inherit: true,
|
||||
types: ["Dragon", "Ground"],
|
||||
baseStats: { hp: 108, atk: 150, def: 115, spa: 140, spd: 85, spe: 102 },
|
||||
abilities: { 0: "Water Absorb" },
|
||||
},
|
||||
tyranitarmega: {
|
||||
inherit: true,
|
||||
types: ["Rock", "Electric"],
|
||||
baseStats: { hp: 100, atk: 144, def: 120, spa: 110, spd: 144, spe: 82 },
|
||||
abilities: { 0: "Electric Surge" },
|
||||
},
|
||||
latiasmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Trace" },
|
||||
},
|
||||
latiosmega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 80, atk: 140, def: 100, spa: 150, spd: 120, spe: 110 },
|
||||
abilities: { 0: "Opportunist" },
|
||||
},
|
||||
dianciemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Good As Gold" },
|
||||
},
|
||||
blazikenmega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 80, atk: 150, def: 80, spa: 120, spd: 90, spe: 110 },
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
mewtwomegax: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Poison"],
|
||||
baseStats: { hp: 106, atk: 140, def: 130, spa: 154, spd: 120, spe: 130 },
|
||||
abilities: { 0: "Intoxicate" },
|
||||
},
|
||||
mewtwomegay: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Water"],
|
||||
baseStats: { hp: 106, atk: 120, def: 110, spa: 194, spd: 130, spe: 120 },
|
||||
abilities: { 0: "Levitate" },
|
||||
},
|
||||
rayquazamega: {
|
||||
inherit: true,
|
||||
requiredItem: "Meteorite",
|
||||
},
|
||||
};
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
megadatamod: {
|
||||
effectType: 'Rule',
|
||||
name: 'Mega Data Mod',
|
||||
desc: 'Gives data on stats, Ability and types when a Pokémon Mega Evolves or undergoes Ultra Burst.',
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.species.forme.startsWith('Mega') || pokemon.species.forme.startsWith('Ultra')) {
|
||||
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
|
||||
}
|
||||
},
|
||||
onAfterMega(pokemon) {
|
||||
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
|
||||
const species = pokemon.species;
|
||||
let buf = `<span class="col pokemonnamecol" style="white-space: nowrap">${species.name}</span> `;
|
||||
buf += `<span class="col typecol">`;
|
||||
buf += `<img src="https://${Config.routes.client}/sprites/types/${species.types[0]}.png" alt="${species.types[0]}" height="14" width="32">`;
|
||||
if (species.types[1]) {
|
||||
buf += `<img src="https://${Config.routes.client}/sprites/types/${species.types[1]}.png" alt="${species.types[1]}" height="14" width="32">`;
|
||||
}
|
||||
buf += `</span> `;
|
||||
buf += `<span style="float: left ; min-height: 26px"><span class="col abilitycol">${species.abilities[0]}</span><span class="col abilitycol"></span></span>`;
|
||||
const stats = [];
|
||||
let stat: StatID;
|
||||
for (stat in species.baseStats) {
|
||||
const statNames: { [k in StatID]: string } = { hp: "HP", atk: "Atk", def: "Def", spa: "SpA", spd: "SpD", spe: "Spe" };
|
||||
stats.push(`<span class="col statcol"><em>${statNames[stat]}</em><br>${species.baseStats[stat]}</span>`);
|
||||
}
|
||||
buf += `<span style="float: left ; min-height: 26px">${stats.join(' ')}</span>`;
|
||||
buf += `</span>`;
|
||||
this.add(`raw|<ul class="utilichart"><li class="result">${buf}</li><li style="clear: both"></li></ul>`);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1,237 +0,0 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
gen: 6,
|
||||
inherit: 'gen6',
|
||||
actions: {
|
||||
// for parental bond
|
||||
modifyDamage(
|
||||
baseDamage: number, pokemon: Pokemon, target: Pokemon, move: ActiveMove, suppressMessages = false
|
||||
) {
|
||||
const tr = this.battle.trunc;
|
||||
if (!move.type) move.type = '???';
|
||||
const type = move.type;
|
||||
baseDamage += 2;
|
||||
if (move.spreadHit) {
|
||||
// multi-target modifier (doubles only)
|
||||
const spreadModifier = this.battle.gameType === 'freeforall' ? 0.5 : 0.75;
|
||||
this.battle.debug(`Spread modifier: ${spreadModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, spreadModifier);
|
||||
} else if (move.multihitType === 'parentalbond' && move.hit > 1) {
|
||||
// Parental Bond modifier
|
||||
const bondModifier = 0.25;
|
||||
this.battle.debug(`Parental Bond modifier: ${bondModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, bondModifier);
|
||||
}
|
||||
baseDamage = this.battle.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
|
||||
const isCrit = target.getMoveHitData(move).crit;
|
||||
if (isCrit) {
|
||||
baseDamage = tr(baseDamage * (move.critModifier || (this.battle.gen >= 6 ? 1.5 : 2)));
|
||||
}
|
||||
baseDamage = this.battle.randomizer(baseDamage);
|
||||
if (type !== '???') {
|
||||
let stab: number | [number, number] = 1;
|
||||
const isSTAB = move.forceSTAB || pokemon.hasType(type) || pokemon.getTypes(false, true).includes(type);
|
||||
if (isSTAB) {
|
||||
stab = 1.5;
|
||||
}
|
||||
if (pokemon.terastallized === 'Stellar') {
|
||||
if (!pokemon.stellarBoostedTypes.includes(type) || move.stellarBoosted) {
|
||||
stab = isSTAB ? 2 : [4915, 4096];
|
||||
move.stellarBoosted = true;
|
||||
if (pokemon.species.name !== 'Terapagos-Stellar') {
|
||||
pokemon.stellarBoostedTypes.push(type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pokemon.terastallized === type && pokemon.getTypes(false, true).includes(type)) {
|
||||
stab = 2;
|
||||
}
|
||||
stab = this.battle.runEvent('ModifySTAB', pokemon, target, move, stab);
|
||||
}
|
||||
baseDamage = this.battle.modify(baseDamage, stab);
|
||||
}
|
||||
let typeMod = target.runEffectiveness(move);
|
||||
typeMod = this.battle.clampIntRange(typeMod, -6, 6);
|
||||
target.getMoveHitData(move).typeMod = typeMod;
|
||||
if (typeMod > 0) {
|
||||
if (!suppressMessages) this.battle.add('-supereffective', target);
|
||||
for (let i = 0; i < typeMod; i++) {
|
||||
baseDamage *= 2;
|
||||
}
|
||||
}
|
||||
if (typeMod < 0) {
|
||||
if (!suppressMessages) this.battle.add('-resisted', target);
|
||||
|
||||
for (let i = 0; i > typeMod; i--) {
|
||||
baseDamage = tr(baseDamage / 2);
|
||||
}
|
||||
}
|
||||
if (isCrit && !suppressMessages) this.battle.add('-crit', target);
|
||||
if (pokemon.status === 'brn' && move.category === 'Physical' && !pokemon.hasAbility('guts')) {
|
||||
if (this.battle.gen < 6 || move.id !== 'facade') {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.5);
|
||||
}
|
||||
}
|
||||
// Generation 5, but nothing later, sets damage to 1 before the final damage modifiers
|
||||
if (this.battle.gen === 5 && !baseDamage) baseDamage = 1;
|
||||
// Final modifier. Modifiers that modify damage after min damage check, such as Life Orb.
|
||||
baseDamage = this.battle.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
|
||||
if (move.isZOrMaxPowered && target.getMoveHitData(move).zBrokeProtect) {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.25);
|
||||
this.battle.add('-zbroken', target);
|
||||
}
|
||||
// Generation 6-7 moves the check for minimum 1 damage after the final modifier...
|
||||
if (this.battle.gen !== 5 && !baseDamage) return 1;
|
||||
// ...but 16-bit truncation happens even later, and can truncate to 0
|
||||
return tr(baseDamage, 16);
|
||||
},
|
||||
},
|
||||
pokemon: {
|
||||
// for neutralizing gas
|
||||
ignoringAbility() {
|
||||
if (this.battle.gen >= 5 && !this.isActive) return true;
|
||||
if (this.getAbility().flags['notransform'] && this.transformed) return true;
|
||||
if (this.getAbility().flags['cantsuppress']) return false;
|
||||
if (this.volatiles['gastroacid']) return true;
|
||||
if (this.ability === ('neutralizinggas' as ID)) return false;
|
||||
if (this.volatiles['neutralizinggas']) return true;
|
||||
return false;
|
||||
},
|
||||
},
|
||||
init() {
|
||||
this.modData("Learnsets", "lucario").learnset.meteormash = ["6L1"];
|
||||
this.modData("Learnsets", "lucario").learnset.machpunch = ["6L1"];
|
||||
this.modData("Learnsets", "houndoom").learnset.toxicspikes = ["6L1"];
|
||||
this.modData("Learnsets", "houndoom").learnset.venoshock = ["6L1"];
|
||||
this.modData("Learnsets", "houndoom").learnset.hex = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.discharge = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.voltswitch = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.chargebeam = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.charge = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.zapcannon = ["6L1"];
|
||||
this.modData("Learnsets", "glalie").learnset.thunderfang = ["6L1"];
|
||||
this.modData("Learnsets", "glalie").learnset.partingshot = ["6L1"];
|
||||
this.modData("Learnsets", "glalie").learnset.boomburst = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.ironhead = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.metalsound = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.powder = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.stealthrock = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.defog = ["6L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.psychic = ["6L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.calmmind = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.moonblast = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.mistyterrain = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.taunt = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.drainingkiss = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.dazzlinggleam = ["6L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.calmmind = ["6L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.hurricane = ["6L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.lavaplume = ["6L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.reflecttype = ["6L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.calmmind = ["6L1"];
|
||||
this.modData("Learnsets", "alakazam").learnset.blizzard = ["6L1"];
|
||||
this.modData("Learnsets", "alakazam").learnset.flashcannon = ["6L1"];
|
||||
this.modData("Learnsets", "alakazam").learnset.icebeam = ["6L1"];
|
||||
this.modData("Learnsets", "alakazam").learnset.hail = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.hail = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.megahorn = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.uturn = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.iceshard = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.iciclecrash = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.icebeam = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.blizzard = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.roost = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.iciclespear = ["6L1"];
|
||||
this.modData("Learnsets", "aerodactyl").learnset.powergem = ["6L1"];
|
||||
this.modData("Learnsets", "aerodactyl").learnset.shadowball = ["6L1"];
|
||||
this.modData("Learnsets", "aerodactyl").learnset.hurricane = ["6L1"];
|
||||
this.modData("Learnsets", "steelix").learnset.heatcrash = ["6L1"];
|
||||
this.modData("Learnsets", "steelix").learnset.rapidspin = ["6L1"];
|
||||
this.modData("Learnsets", "steelix").learnset.smackdown = ["6L1"];
|
||||
this.modData("Learnsets", "altaria").learnset.scald = ["6L1"];
|
||||
this.modData("Learnsets", "altaria").learnset.hydropump = ["6L1"];
|
||||
this.modData("Learnsets", "altaria").learnset.thunder = ["6L1"];
|
||||
this.modData("Learnsets", "sceptile").learnset.calmmind = ["6L1"];
|
||||
this.modData("Learnsets", "sceptile").learnset.sludgewave = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.sludgebomb = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.bulkup = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.toxicspikes = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.aquajet = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.gunkshot = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.poisonjab = ["6L1"];
|
||||
this.modData("Learnsets", "pidgeot").learnset.focusblast = ["6L1"];
|
||||
this.modData("Learnsets", "absol").learnset.closecombat = ["6L1"];
|
||||
this.modData("Learnsets", "absol").learnset.moonblast = ["6L1"];
|
||||
this.modData("Learnsets", "absol").learnset.moonlight = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.aurasphere = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.thunderbolt = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.closecombat = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.gunkshot = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.healingwish = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.earthquake = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.stoneedge = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.rockslide = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.smackdown = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.stealthrock = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.diamondstorm = ["6L1"];
|
||||
this.modData("Learnsets", "mawile").learnset.firepunch = ["6L1"];
|
||||
this.modData("Learnsets", "mawile").learnset.rockslide = ["6L1"];
|
||||
this.modData("Learnsets", "mawile").learnset.slackoff = ["6L1"];
|
||||
this.modData("Learnsets", "camerupt").learnset.morningsun = ["6L1"];
|
||||
this.modData("Learnsets", "abomasnow").learnset.spikyshield = ["6L1"];
|
||||
this.modData("Learnsets", "abomasnow").learnset.earthpower = ["6L1"];
|
||||
this.modData("Learnsets", "abomasnow").learnset.hornleech = ["6L1"];
|
||||
this.modData("Learnsets", "gallade").learnset.sacredsword = ["6L1"];
|
||||
this.modData("Learnsets", "gallade").learnset.machpunch = ["6L1"];
|
||||
this.modData('Moves', 'aerialace').flags.slicing = 1;
|
||||
this.modData('Moves', 'aircutter').flags.slicing = 1;
|
||||
this.modData('Moves', 'airslash').flags.slicing = 1;
|
||||
this.modData('Moves', 'behemothblade').flags.slicing = 1;
|
||||
this.modData('Moves', 'crosspoison').flags.slicing = 1;
|
||||
this.modData('Moves', 'cut').flags.slicing = 1;
|
||||
this.modData('Moves', 'furycutter').flags.slicing = 1;
|
||||
this.modData('Moves', 'nightslash').flags.slicing = 1;
|
||||
this.modData('Moves', 'psychocut').flags.slicing = 1;
|
||||
this.modData('Moves', 'razorleaf').flags.slicing = 1;
|
||||
this.modData('Moves', 'razorshell').flags.slicing = 1;
|
||||
this.modData('Moves', 'sacredsword').flags.slicing = 1;
|
||||
this.modData('Moves', 'slash').flags.slicing = 1;
|
||||
this.modData('Moves', 'solarblade').flags.slicing = 1;
|
||||
this.modData('Moves', 'xscissor').flags.slicing = 1;
|
||||
this.modData("Learnsets", "ampharos").learnset.waterpulse = ["6L1"];
|
||||
this.modData("Learnsets", "ampharos").learnset.aurasphere = ["6L1"];
|
||||
this.modData("Learnsets", "ampharos").learnset.darkpulse = ["6L1"];
|
||||
this.modData("Learnsets", "ampharos").learnset.defog = ["6L1"];
|
||||
this.modData("Learnsets", "ampharos").learnset.slackoff = ["6L1"];
|
||||
this.modData("Learnsets", "heracross").learnset.healorder = ["6L1"];
|
||||
this.modData("Learnsets", "heracross").learnset.circlethrow = ["6L1"];
|
||||
this.modData("Learnsets", "heracross").learnset.spikes = ["6L1"];
|
||||
this.modData("Learnsets", "heracross").learnset.icepunch = ["6L1"];
|
||||
this.modData("Learnsets", "sharpedo").learnset.thunder = ["6L1"];
|
||||
this.modData("Learnsets", "gardevoir").learnset.rapidspin = ["6L1"];
|
||||
this.modData("Learnsets", "gardevoir").learnset.mysticalfire = ["6L1"];
|
||||
this.modData("Learnsets", "aggron").learnset.voltswitch = ["6L1"];
|
||||
this.modData("Learnsets", "kangaskhan").learnset.milkdrink = ["6L1"];
|
||||
this.modData("Learnsets", "salamence").learnset.hurricane = ["6L1"];
|
||||
this.modData("Learnsets", "salamence").learnset.airslash = ["6L1"];
|
||||
this.modData("Learnsets", "salamence").learnset.ironhead = ["6L1"];
|
||||
this.modData("Learnsets", "tyranitar").learnset.wildcharge = ["6L1"];
|
||||
this.modData("Learnsets", "tyranitar").learnset.waterfall = ["6L1"];
|
||||
this.modData("Learnsets", "diancie").learnset.spikyshield = ["6L1"];
|
||||
this.modData("Learnsets", "blaziken").learnset.uturn = ["6L1"];
|
||||
this.modData("Learnsets", "blaziken").learnset.spikes = ["6L1"];
|
||||
this.modData("Learnsets", "blaziken").learnset.roost = ["6L1"];
|
||||
this.modData("Learnsets", "blaziken").learnset.closecombat = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.extremespeed = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.sludgewave = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.swordsdance = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.uturn = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.closecombat = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.drainpunch = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.machpunch = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.scald = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.surf = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.hydropump = ["6L1"];
|
||||
this.modData("Learnsets", "rayquaza").learnset.coil = ["6L1"];
|
||||
this.modData("Learnsets", "rayquaza").learnset.defog = ["6L1"];
|
||||
},
|
||||
};
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
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,
|
||||
},
|
||||
};
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
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;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -498,10 +498,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
condition: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect'] || move.category === 'Status') {
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
this.add('-activate', target, 'move: Protect');
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
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,
|
||||
},
|
||||
};
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
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;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
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;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -11,7 +11,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
if (pokemon.species.baseSpecies === 'Ogerpon' && !['Fire', 'Grass', 'Rock', 'Water'].includes(pokemon.teraType) &&
|
||||
(!pokemon.illusion || pokemon.illusion.species.baseSpecies === 'Ogerpon')) {
|
||||
this.battle.hint("If Ogerpon Terastallizes into a type other than Fire, Grass, Rock, or Water, the game softlocks.");
|
||||
this.battle.hint("If Ogerpon Terastallizes into a type other than Fire, Grass, Rock, or Water, the game crashes.", false, pokemon.side);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -87,16 +87,18 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
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) {
|
||||
for (const [i, moveSlot] of pokemon.moveSlots.entries()) {
|
||||
let moveName = moveSlot.move;
|
||||
if (moveSlot.id === 'hiddenpower') {
|
||||
moveName = 'Hidden Power ' + this.hpType;
|
||||
}
|
||||
const move = this.battle.dex.moves.get(moveSlot.id);
|
||||
const pp = Math.min(5, move.pp);
|
||||
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,
|
||||
pp,
|
||||
maxpp: this.battle.gen >= 5 ? pp : this.battle.calculatePP(move, this.ppUps[i] || 0),
|
||||
target: moveSlot.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
|
|
|
|||
|
|
@ -7,4 +7,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
inherit: true,
|
||||
isNonstandard: null,
|
||||
},
|
||||
piercingdrill: {
|
||||
inherit: true,
|
||||
isNonstandard: null,
|
||||
},
|
||||
spicyspray: {
|
||||
inherit: true,
|
||||
isNonstandard: null,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,4 @@
|
|||
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
|
||||
clefablemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Prankster" },
|
||||
},
|
||||
victreebelmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Triage" },
|
||||
},
|
||||
raichumegax: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Levitate" },
|
||||
|
|
@ -18,11 +10,6 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
starmiemega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 60, atk: 100, def: 105, spa: 130, spd: 105, spe: 120 },
|
||||
abilities: { 0: "Pure Power" },
|
||||
},
|
||||
dragonitemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Sheer Force" },
|
||||
},
|
||||
ampharosmega: {
|
||||
inherit: true,
|
||||
|
|
@ -32,14 +19,6 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
abilities: { 0: "Technician" },
|
||||
},
|
||||
chimechomega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Levitate" },
|
||||
},
|
||||
skarmorymega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Tough Claws" },
|
||||
},
|
||||
mawilemega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 50, atk: 105, def: 125, spa: 55, spd: 95, spe: 50 },
|
||||
|
|
@ -56,10 +35,6 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
abilities: { 0: "Sharpness" },
|
||||
},
|
||||
froslassmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Snow Warning" },
|
||||
},
|
||||
garchompmegaz: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Rough Skin" },
|
||||
|
|
@ -76,14 +51,6 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
abilities: { 0: "Dark Aura" },
|
||||
},
|
||||
excadrillmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Sand Rush" },
|
||||
},
|
||||
golurkmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Adaptability" },
|
||||
},
|
||||
audinomega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
|
|
@ -100,18 +67,6 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
abilities: { 0: "Hadron Engine" },
|
||||
},
|
||||
chandeluremega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Magic Guard" },
|
||||
},
|
||||
meowsticmmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Psychic Surge" },
|
||||
},
|
||||
meowsticfmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Psychic Surge" },
|
||||
},
|
||||
pyroarmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Drought" },
|
||||
|
|
@ -120,10 +75,6 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
floettemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
malamarmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Contrary" },
|
||||
|
|
@ -132,26 +83,14 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
abilities: { 0: "Tough Claws" },
|
||||
},
|
||||
hawluchamega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Stamina" },
|
||||
},
|
||||
zygardemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Aura Break" },
|
||||
},
|
||||
crabominablemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Ice Scales" },
|
||||
},
|
||||
golisopodmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Heatproof" },
|
||||
},
|
||||
drampamega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Adaptability" },
|
||||
},
|
||||
magearnamega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Soul-Heart" },
|
||||
|
|
@ -168,14 +107,6 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
abilities: { 0: "Dauntless Shield" },
|
||||
},
|
||||
scovillainmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Contrary" },
|
||||
},
|
||||
glimmoramega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Levitate" },
|
||||
},
|
||||
tatsugiricurlymega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Drizzle" },
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
jetpunch: {
|
||||
inherit: true,
|
||||
hasSheerForce: true,
|
||||
hasSheerForceBoost: true,
|
||||
},
|
||||
matchagotcha: {
|
||||
inherit: true,
|
||||
|
|
|
|||
277
data/mods/gen9regeneration/abilities.ts
Normal file
277
data/mods/gen9regeneration/abilities.ts
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
|
||||
// new
|
||||
wingsofvictory: {
|
||||
onStart(pokemon) {
|
||||
if (pokemon.side.foe.totalFainted) {
|
||||
this.add('-activate', pokemon, 'ability: Wings of Victory');
|
||||
const fallen = Math.min(pokemon.side.foe.totalFainted, 5);
|
||||
this.add('-start', pokemon, `fallen${fallen}`, '[silent]');
|
||||
this.effectState.fallen = fallen;
|
||||
}
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
this.add('-end', pokemon, `fallen${this.effectState.fallen}`, '[silent]');
|
||||
},
|
||||
onBasePowerPriority: 21,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (this.effectState.fallen) {
|
||||
const powMod = [4096, 4506, 4915, 5325, 5734, 6144];
|
||||
this.debug(`Wings of Victory boost: ${powMod[this.effectState.fallen]}/4096`);
|
||||
return this.chainModify([powMod[this.effectState.fallen], 4096]);
|
||||
}
|
||||
},
|
||||
name: "Wings of Victory",
|
||||
shortDesc: "This Pokemon's moves have 10% more power for each fainted foe, up to 5 foes.",
|
||||
rating: 3.5,
|
||||
},
|
||||
galaxybrain: {
|
||||
onStart(pokemon) {
|
||||
let totalatk = 0;
|
||||
let totalspa = 0;
|
||||
for (const target of pokemon.side.foe.active) {
|
||||
if (!target || target.fainted) continue;
|
||||
totalatk += target.getStat('atk', false, true);
|
||||
totalspa += target.getStat('spa', false, true);
|
||||
}
|
||||
if (totalatk && totalatk >= totalspa) {
|
||||
this.boost({ def: 1 });
|
||||
} else if (totalspa) {
|
||||
this.boost({ spd: 1 });
|
||||
}
|
||||
},
|
||||
name: "Galaxy Brain",
|
||||
shortDesc: "On switch-in, Defense or Sp. Def is raised 1 stage based on the foes' stronger offense.",
|
||||
rating: 4,
|
||||
},
|
||||
blackout: {
|
||||
onStart(source) {
|
||||
this.field.addPseudoWeather('magicroom', source);
|
||||
/* let activated = false;
|
||||
for (const pokemon of this.getAllActive()) {
|
||||
if (!activated) {
|
||||
this.add('-ability', source, 'Blackout');
|
||||
}
|
||||
activated = true;
|
||||
if (!pokemon.volatiles['embargo']) {
|
||||
pokemon.addVolatile('embargo');
|
||||
}
|
||||
} */
|
||||
},
|
||||
/* onAnySwitchIn(pokemon) {
|
||||
if (!pokemon.volatiles['embargo']) {
|
||||
pokemon.addVolatile('embargo');
|
||||
}
|
||||
}, */
|
||||
onEnd(pokemon) {
|
||||
this.field.removePseudoWeather('magicroom');
|
||||
/* for (const target of this.getAllActive()) {
|
||||
if (target === pokemon) continue;
|
||||
if (target.hasAbility('blackout')) return;
|
||||
}
|
||||
for (const target of this.getAllActive()) {
|
||||
target.removeVolatile('embargo');
|
||||
} */
|
||||
},
|
||||
name: "Blackout",
|
||||
shortDesc: "While this Pokemon is active, all held items are disabled.",
|
||||
rating: 5,
|
||||
},
|
||||
excavate: {
|
||||
onSwitchIn(pokemon) {
|
||||
let activated = false;
|
||||
for (const sideCondition of ['spikes', 'stealthrock']) {
|
||||
if (pokemon.side.getSideCondition(sideCondition) && !pokemon.side.getSideCondition('excavate')) {
|
||||
if (!activated) {
|
||||
this.add('-activate', pokemon, 'ability: Excavate');
|
||||
activated = true;
|
||||
}
|
||||
}
|
||||
if (pokemon.side.getSideCondition('spikes') && !pokemon.side.getSideCondition('excavate')) {
|
||||
this.add('-sideend', pokemon.side, 'move: Spikes', `[of] ${pokemon}`);
|
||||
pokemon.side.removeSideCondition('spikes');
|
||||
this.boost({ def: 1 }, pokemon);
|
||||
pokemon.side.addSideCondition('excavate');
|
||||
}
|
||||
if (pokemon.side.getSideCondition('stealthrock') && !pokemon.side.getSideCondition('excavate')) {
|
||||
this.add('-sideend', pokemon.side, 'move: Stealth Rock', `[of] ${pokemon}`);
|
||||
pokemon.side.removeSideCondition('stealthrock');
|
||||
this.boost({ def: 1 }, pokemon);
|
||||
pokemon.side.addSideCondition('excavate');
|
||||
}
|
||||
}
|
||||
},
|
||||
condition: {
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Excavate Used');
|
||||
},
|
||||
},
|
||||
name: "Excavate",
|
||||
shortDesc: "Once per game. Removes Stealth Rock and Spikes on switch-in, +1 Def for each hazard removed.",
|
||||
rating: 4,
|
||||
},
|
||||
lifeguard: {
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (move.type === 'Water') {
|
||||
this.boost({ def: 1 });
|
||||
}
|
||||
},
|
||||
onModifySecondaries(secondaries, target, source, move) {
|
||||
if (move.type === 'Water') return;
|
||||
this.debug('Lifeguard prevent secondary');
|
||||
return secondaries.filter(effect => !!effect.self);
|
||||
},
|
||||
name: "Lifeguard",
|
||||
shortDesc: "Boosts Defense when hit by a Water move; blocks additional effects of Water moves.",
|
||||
rating: 3,
|
||||
},
|
||||
ballooning: {
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (
|
||||
effect.effectType === "Move" &&
|
||||
!effect.multihit &&
|
||||
!(effect.hasSheerForce && source.hasAbility('sheerforce'))
|
||||
) {
|
||||
this.effectState.checkedBallooning = false;
|
||||
} else {
|
||||
this.effectState.checkedBallooning = true;
|
||||
}
|
||||
},
|
||||
onTryEatItem(item) {
|
||||
const healingItems = [
|
||||
'aguavberry', 'enigmaberry', 'figyberry', 'iapapaberry',
|
||||
'magoberry', 'sitrusberry', 'wikiberry', 'oranberry', 'berryjuice',
|
||||
];
|
||||
if (healingItems.includes(item.id)) {
|
||||
return this.effectState.checkedBallooning;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
onAfterMoveSecondary(target, source, move) {
|
||||
this.effectState.checkedBallooning = true;
|
||||
if (!source || source === target || !target.hp || !move.totalDamage) return;
|
||||
const lastAttackedBy = target.getLastAttackedBy();
|
||||
if (!lastAttackedBy) return;
|
||||
const damage = move.multihit ? move.totalDamage : lastAttackedBy.damage;
|
||||
if (target.hp <= target.maxhp / 2 && target.hp + damage > target.maxhp / 2) {
|
||||
this.boost({ atk: 1, spa: 1, spe: 1 }, target, target);
|
||||
target.addVolatile('perishsong');
|
||||
}
|
||||
},
|
||||
name: "Ballooning",
|
||||
shortDesc: "At 1/2 or less of this Pokemon's max HP: +1 Atk, Sp. Atk, Spe, and gains the Perish Song effect.",
|
||||
rating: 4,
|
||||
},
|
||||
ofafeather: {
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, attacker, defender, move) {
|
||||
if (move.type === 'Flying') {
|
||||
this.debug('Of A Feather boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onModifySpAPriority: 5,
|
||||
onModifySpA(atk, attacker, defender, move) {
|
||||
if (move.type === 'Flying') {
|
||||
this.debug('Of A Feather boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
name: "Of A Feather",
|
||||
rating: 3.5,
|
||||
shortDesc: "This Pokemon's Flying-type moves have 1.5x power.",
|
||||
},
|
||||
patriarch: {
|
||||
onStart(pokemon) {
|
||||
if (pokemon.side.pokemon.filter(ally => ally === pokemon || !ally.fainted && !ally.status)) {
|
||||
this.add('-activate', pokemon, 'ability: Patriarch');
|
||||
const healthy = Math.min(pokemon.side.pokemon
|
||||
.filter(ally => ally === pokemon || !ally.fainted && !ally.status).length, 5);
|
||||
this.add('-start', pokemon, `healthy{healthy}`, '[silent]');
|
||||
this.effectState.healthy = healthy;
|
||||
}
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
this.add('-end', pokemon, `healthy${this.effectState.healthy}`, '[silent]');
|
||||
},
|
||||
onBasePowerPriority: 21,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (this.effectState.healthy) {
|
||||
const powMod = [4096, 4506, 4915, 5325, 5734, 6144];
|
||||
this.debug(`Patriach boost: ${powMod[this.effectState.healthy]}/4096`);
|
||||
return this.chainModify([powMod[this.effectState.healthy], 4096]);
|
||||
}
|
||||
},
|
||||
name: "Patriarch",
|
||||
shortDesc: "This Pokemon's moves have 10% more power for each of its healthy allies.",
|
||||
rating: 3.5,
|
||||
},
|
||||
violentabandon: {
|
||||
onAfterUseItem(item, pokemon) {
|
||||
if (
|
||||
pokemon !== this.effectState.target &&
|
||||
pokemon.baseSpecies.baseSpecies !== 'Gyarados' ||
|
||||
pokemon.transformed
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (pokemon.species.forme !== 'Mega') {
|
||||
pokemon.formeChange('Gyarados-Mega', this.effect, true);
|
||||
}
|
||||
},
|
||||
onTakeItem(item, pokemon) {
|
||||
if (
|
||||
pokemon !== this.effectState.target &&
|
||||
pokemon.baseSpecies.baseSpecies !== 'Gyarados' ||
|
||||
pokemon.transformed
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (pokemon.species.forme !== 'Mega') {
|
||||
pokemon.formeChange('Gyarados-Mega', this.effect, true);
|
||||
}
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
|
||||
name: "Violent Abandon",
|
||||
shortDesc: "This Pokemon transforms into Mega Gyarados whenever its item is used or lost.",
|
||||
rating: 3.5,
|
||||
},
|
||||
tropicalcurrent: {
|
||||
onDamagePriority: 1,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (effect.id === 'brn') {
|
||||
this.heal(target.baseMaxhp / 8);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
name: "Tropical Current",
|
||||
shortDesc: "This Pokemon restored 1/8 of its max HP per turn if it's burned. Ignores burn attack drop.",
|
||||
rating: 4,
|
||||
},
|
||||
bullspirit: {
|
||||
onAfterMoveSecondarySelf(source, target, move) {
|
||||
if (!move || source.switchFlag === true || !move.hitTargets || move.type !== 'Normal') return;
|
||||
this.add('-ability', source, 'Bull Spirit');
|
||||
this.add('-message', `${source.name}'s next attack will be physical!`);
|
||||
source.addVolatile('bullspirit');
|
||||
},
|
||||
condition: {
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'ability: Bull Spirit');
|
||||
},
|
||||
duration: 2,
|
||||
onModifyMovePriority: 8,
|
||||
onModifyMove(move, pokemon) {
|
||||
if (move.category !== "Status") {
|
||||
move.category = "Physical";
|
||||
}
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'ability: Bull Spirit', '[silent]');
|
||||
},
|
||||
},
|
||||
flags: {},
|
||||
name: "Bull Spirit",
|
||||
rating: 1,
|
||||
shortDesc: "After using a Normal-type move, the user's next attack will always be physical.",
|
||||
},
|
||||
};
|
||||
674
data/mods/gen9regeneration/formats-data.ts
Normal file
674
data/mods/gen9regeneration/formats-data.ts
Normal file
|
|
@ -0,0 +1,674 @@
|
|||
export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormatsDataTable = {
|
||||
bulbasaur: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
ivysaur: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
venusaur: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
venusaurmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
charmander: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
charmeleon: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
charizard: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
charizardmegax: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
charizardmegay: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
squirtle: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
wartortle: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
blastoise: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
blastoisemega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
caterpie: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
metapod: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
butterfree: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
weedle: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
kakuna: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
beedrill: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
beedrillmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
pidgey: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
pidgeotto: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
pidgeot: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
pidgeotmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
rattata: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
raticate: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
spearow: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
fearow: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
ekans: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
arbok: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
pikachu: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
raichu: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
sandshrew: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
sandslash: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
nidoranf: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
nidorina: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
nidoqueen: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
nidoranm: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
nidorino: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
nidoking: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
cleffa: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
clefairy: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
clefable: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
vulpix: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
ninetales: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
igglybuff: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
jigglypuff: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
wigglytuff: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
zubat: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
golbat: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
oddish: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
gloom: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
vileplume: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
paras: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
parasect: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
venonat: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
venomoth: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
diglett: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
dugtrio: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
meowth: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
persian: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
psyduck: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
golduck: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
mankey: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
primeape: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
growlithe: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
arcanine: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
poliwag: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
poliwhirl: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
poliwrath: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
abra: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
kadabra: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
alakazam: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
alakazammega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
machop: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
machoke: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
machamp: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
bellsprout: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
weepinbell: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
victreebel: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
tentacool: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
tentacruel: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
geodude: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
graveler: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
golem: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
ponyta: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
rapidash: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
slowpoke: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
slowbro: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
slowbromega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
magnemite: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
magneton: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
farfetchd: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
doduo: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
dodrio: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
seel: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
dewgong: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
grimer: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
muk: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
shellder: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
cloyster: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
gastly: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
haunter: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
gengar: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
gengarmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
onix: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
drowzee: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
hypno: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
krabby: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
kingler: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
voltorb: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
electrode: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
exeggcute: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
exeggutor: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
cubone: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
marowak: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
hitmonlee: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
hitmonchan: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
lickitung: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
koffing: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
weezing: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
rhyhorn: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
rhydon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
chansey: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
tangela: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
kangaskhan: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
kangaskhanmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
horsea: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
seadra: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
goldeen: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
seaking: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
staryu: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
starmie: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
mrmime: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
scyther: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
jynx: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
electabuzz: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
magmar: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
pinsir: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
pinsirmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
tauros: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
magikarp: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
gyarados: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
gyaradosmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
lapras: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
ditto: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
eevee: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
vaporeon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
jolteon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
flareon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
porygon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
omanyte: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
omastar: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
kabuto: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
kabutops: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
aerodactyl: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
aerodactylmega: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
snorlax: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
articuno: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
zapdos: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
moltres: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
dratini: {
|
||||
tier: "LC",
|
||||
doublesTier: "LC",
|
||||
},
|
||||
dragonair: {
|
||||
tier: "NFE",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
dragonite: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
mewtwo: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
mewtwomegax: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
mewtwomegay: {
|
||||
isNonstandard: "Past",
|
||||
tier: "Illegal",
|
||||
},
|
||||
mew: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
};
|
||||
573
data/mods/gen9regeneration/moves.ts
Normal file
573
data/mods/gen9regeneration/moves.ts
Normal file
|
|
@ -0,0 +1,573 @@
|
|||
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||
// new
|
||||
vitalenergy: {
|
||||
accuracy: 100,
|
||||
basePower: 150,
|
||||
basePowerCallback(pokemon, target, move) {
|
||||
return move.basePower * pokemon.hp / pokemon.maxhp;
|
||||
},
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Seed Flare", target);
|
||||
},
|
||||
category: "Special",
|
||||
name: "Vital Energy",
|
||||
shortDesc: "Less power as user's HP decreases. Hits foe(s).",
|
||||
pp: 5,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1 },
|
||||
secondary: undefined,
|
||||
target: "allAdjacentFoes",
|
||||
type: "Grass",
|
||||
contestType: "Beautiful",
|
||||
},
|
||||
smokytorment: {
|
||||
accuracy: true,
|
||||
basePower: 75,
|
||||
category: "Physical",
|
||||
name: "Smoky Torment",
|
||||
shortDesc: "Applies the Torment effect on opponent.",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Outrage", target);
|
||||
},
|
||||
secondary: {
|
||||
chance: 100,
|
||||
volatileStatus: 'torment',
|
||||
},
|
||||
target: "normal",
|
||||
type: "Dark",
|
||||
contestType: "Cool",
|
||||
},
|
||||
powerwash: {
|
||||
accuracy: 100,
|
||||
basePower: 50,
|
||||
category: "Special",
|
||||
name: "Power Wash",
|
||||
shortDesc: "Removes all hazards in the field. If any are cleared, the user heals for 50% of its maximum HP.",
|
||||
pp: 40,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
onHit(target, source, move) {
|
||||
let success = false;
|
||||
const removeAll = [
|
||||
'spikes', 'toxicspikes', 'stealthrock', 'stickyweb', 'gmaxsteelsurge',
|
||||
];
|
||||
for (const sideCondition of removeAll) {
|
||||
if (source.side.removeSideCondition(sideCondition)) {
|
||||
this.add('-sideend', source.side, this.dex.conditions.get(sideCondition).name, '[from] move: Power Wash', `[of] ${source}`);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
this.heal(Math.ceil(source.maxhp * 0.5), source);
|
||||
return success;
|
||||
},
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Volt Switch", target);
|
||||
},
|
||||
target: "normal",
|
||||
type: "Water",
|
||||
contestType: "Cool",
|
||||
},
|
||||
brainwave: {
|
||||
accuracy: 100,
|
||||
basePower: 70,
|
||||
category: "Special",
|
||||
name: "Brainwave",
|
||||
shortDesc: "Uses user's Special Defense stat as Special Attack in damage calculation.",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
overrideOffensiveStat: 'spd',
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Expanding Force", target);
|
||||
},
|
||||
secondary: undefined,
|
||||
target: "normal",
|
||||
type: "Psychic",
|
||||
},
|
||||
illwind: {
|
||||
accuracy: 100,
|
||||
basePower: 100,
|
||||
category: "Special",
|
||||
name: "Ill Wind",
|
||||
shortDesc: "Lowers the user's Sp. Atk by 1, drains 25% damage, heals another 25% for each neg SpA boost.",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, heal: 1 },
|
||||
self: {
|
||||
boosts: {
|
||||
spa: -1,
|
||||
},
|
||||
},
|
||||
drain: [1, 4],
|
||||
/* onModifyMove(move, pokemon) {
|
||||
move.drain = [pokemon.negativeBoosts.spa(), 4];
|
||||
}, */
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Icy Wind", target);
|
||||
},
|
||||
secondary: undefined,
|
||||
target: "normal",
|
||||
type: "Ice",
|
||||
contestType: "Clever",
|
||||
},
|
||||
guardiandive: {
|
||||
accuracy: 100,
|
||||
basePower: 75,
|
||||
category: "Physical",
|
||||
name: "Guardian Dive",
|
||||
shortDesc: "Uses user's Defense stat as Attack in damage calculation.",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
overrideOffensiveStat: 'def',
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Acrobatics", target);
|
||||
},
|
||||
secondary: undefined,
|
||||
target: "normal",
|
||||
type: "Flying",
|
||||
},
|
||||
coralcrash: {
|
||||
accuracy: 100,
|
||||
basePower: 120,
|
||||
category: "Physical",
|
||||
name: "Coral Crash",
|
||||
shortDesc: "33% recoil. 10% chance to poison.",
|
||||
pp: 15,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
secondary: {
|
||||
chance: 10,
|
||||
status: 'psn',
|
||||
},
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Aqua Tail", target);
|
||||
},
|
||||
recoil: [33, 100],
|
||||
target: "normal",
|
||||
type: "Poison",
|
||||
contestType: "Tough",
|
||||
},
|
||||
slipaway: {
|
||||
accuracy: 100,
|
||||
basePower: 50,
|
||||
category: "Physical",
|
||||
name: "Slip Away",
|
||||
shortDesc: "100% chance to lower the target's Attack by 1, switches the user out.",
|
||||
pp: 20,
|
||||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
secondary: {
|
||||
chance: 100,
|
||||
boosts: {
|
||||
atk: -1,
|
||||
},
|
||||
},
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Aqua Tail", target);
|
||||
},
|
||||
selfSwitch: true,
|
||||
target: "normal",
|
||||
type: "Water",
|
||||
zMove: { effect: 'healreplacement' },
|
||||
contestType: "Cool",
|
||||
},
|
||||
flareout: {
|
||||
accuracy: 100,
|
||||
basePower: 70,
|
||||
category: "Physical",
|
||||
name: "Flare Out",
|
||||
shortDesc: "100% chance to lower the target's Defense by 1, switches the user out.",
|
||||
pp: 20,
|
||||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
secondary: {
|
||||
chance: 100,
|
||||
boosts: {
|
||||
def: -1,
|
||||
},
|
||||
},
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Flame Charge", target);
|
||||
},
|
||||
selfSwitch: true,
|
||||
target: "normal",
|
||||
type: "Fire",
|
||||
zMove: { effect: 'healreplacement' },
|
||||
contestType: "Cool",
|
||||
},
|
||||
buzzoff: {
|
||||
accuracy: 100,
|
||||
basePower: 60,
|
||||
category: "Special",
|
||||
name: "Buzz Off",
|
||||
shortDesc: "100% chance to lower the target's Speed by 1, switches the user out.",
|
||||
pp: 20,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
secondary: {
|
||||
chance: 100,
|
||||
boosts: {
|
||||
spe: -1,
|
||||
},
|
||||
},
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Volt Switch", target);
|
||||
},
|
||||
selfSwitch: true,
|
||||
target: "normal",
|
||||
type: "Electric",
|
||||
zMove: { effect: 'healreplacement' },
|
||||
contestType: "Cool",
|
||||
},
|
||||
powdergale: {
|
||||
accuracy: 100,
|
||||
basePower: 75,
|
||||
category: "Special",
|
||||
name: "Powder Gale",
|
||||
shortDesc: "100% chance to poison. Harshly lowers a random one of the target's stats.",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, wind: 1, metronome: 1 },
|
||||
onHit(target) {
|
||||
const stats: BoostID[] = [];
|
||||
let stat: BoostID;
|
||||
for (stat in target.boosts) {
|
||||
if (stat === 'accuracy' || stat === 'evasion') continue;
|
||||
if (target.boosts[stat] > -6) {
|
||||
stats.push(stat);
|
||||
}
|
||||
}
|
||||
if (stats.length) {
|
||||
const randomStat = this.sample(stats);
|
||||
const boost: SparseBoostsTable = {};
|
||||
boost[randomStat] = -2;
|
||||
this.boost(boost);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
},
|
||||
secondary: {
|
||||
chance: 100,
|
||||
status: 'psn',
|
||||
},
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Silver Wind", target);
|
||||
},
|
||||
target: "normal",
|
||||
type: "Bug",
|
||||
contestType: "Clever",
|
||||
},
|
||||
splashback: {
|
||||
accuracy: 100,
|
||||
basePower: 50,
|
||||
basePowerCallback(pokemon) {
|
||||
return Math.min(300, 50 + 50 * pokemon.timesAttacked);
|
||||
},
|
||||
/* onEnd(pokemon) {
|
||||
this.add('-end', pokemon, 'Splashback', '[silent]');
|
||||
}, */
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Flip Turn", target);
|
||||
},
|
||||
category: "Physical",
|
||||
name: "Splashback",
|
||||
shortDesc: "Base power increases by 50 every time this Pokemon is hit. Max 300 BP. Reset on switch out.",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
secondary: undefined,
|
||||
target: "normal",
|
||||
type: "Water",
|
||||
},
|
||||
ragingtorrent: {
|
||||
accuracy: 100,
|
||||
basePower: 90,
|
||||
category: "Physical",
|
||||
name: "Raging Torrent",
|
||||
shortDesc: "Lowers the target's Atk by 1. Inflicts Encore on the user.",
|
||||
pp: 20,
|
||||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
self: {
|
||||
volatileStatus: 'encore',
|
||||
},
|
||||
secondary: {
|
||||
chance: 100,
|
||||
boosts: {
|
||||
atk: -1,
|
||||
},
|
||||
},
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Breaking Swipe", target);
|
||||
},
|
||||
target: "allAdjacentFoes",
|
||||
type: "Water",
|
||||
contestType: "Tough",
|
||||
},
|
||||
familyonslaught: {
|
||||
accuracy: 100,
|
||||
basePower: 40,
|
||||
category: "Physical",
|
||||
shortDesc: "Hits 2-4 times.",
|
||||
name: "Family Onslaught",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
multihit: [2, 4],
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Population Bomb", target);
|
||||
},
|
||||
target: "normal",
|
||||
type: "Normal",
|
||||
contestType: "Cute",
|
||||
},
|
||||
pestspread: {
|
||||
accuracy: 100,
|
||||
basePower: 100,
|
||||
category: "Physical",
|
||||
shortDesc: "Changes the target's type to the user's type.",
|
||||
name: "Pest Spread",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
onAfterHit(target, source) {
|
||||
if (target.species && (target.species.num === 493 || target.species.num === 773)) return false;
|
||||
if (target.terastallized) return false;
|
||||
const oldApparentType = target.apparentType;
|
||||
let newBaseTypes = source.getTypes(true).filter(type => type !== '???');
|
||||
if (!newBaseTypes.length) {
|
||||
if (source.addedType) {
|
||||
newBaseTypes = ['Normal'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.add('-start', target, 'typechange', '[from] move: Pest Spread', `[of] ${target}`);
|
||||
target.setType(newBaseTypes);
|
||||
target.addedType = source.addedType;
|
||||
target.knownType = source.isAlly(source) && source.knownType;
|
||||
if (!target.knownType) target.apparentType = oldApparentType;
|
||||
},
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Sludge Bomb", target);
|
||||
},
|
||||
target: "normal",
|
||||
type: "Poison",
|
||||
},
|
||||
vengefulbone: {
|
||||
accuracy: 100,
|
||||
basePower: 80,
|
||||
category: "Physical",
|
||||
shortDesc: "Power doubles if an ally fainted last turn.",
|
||||
name: "Vengeful Bone",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Shadow Bone", target);
|
||||
},
|
||||
onBasePower(basePower, pokemon) {
|
||||
if (pokemon.side.faintedLastTurn) {
|
||||
this.debug('Boosted for a faint last turn');
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
target: "normal",
|
||||
type: "Ghost",
|
||||
contestType: "Cool",
|
||||
},
|
||||
escort: {
|
||||
accuracy: 100,
|
||||
basePower: 50,
|
||||
category: "Special",
|
||||
shortDesc: "User switches out. Switch-in is immune to hazards.",
|
||||
name: "Escort",
|
||||
pp: 15,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
selfSwitch: true,
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, "Baton Pass", source);
|
||||
},
|
||||
self: {
|
||||
sideCondition: 'escort',
|
||||
},
|
||||
condition: {
|
||||
duration: 1,
|
||||
},
|
||||
target: "normal",
|
||||
type: "Normal",
|
||||
contestType: "Clever",
|
||||
},
|
||||
stealthrock: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Stealth Rock');
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.hasItem('heavydutyboots') || pokemon.side.getSideCondition('escort')) return;
|
||||
const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6);
|
||||
this.damage(pokemon.maxhp * (2 ** typeMod) / 8);
|
||||
},
|
||||
},
|
||||
},
|
||||
gmaxsteelsurge: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: G-Max Steelsurge');
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.hasItem('heavydutyboots') || pokemon.side.getSideCondition('escort')) return;
|
||||
// Ice Face and Disguise correctly get typed damage from Stealth Rock
|
||||
// because Stealth Rock bypasses Substitute.
|
||||
// They don't get typed damage from Steelsurge because Steelsurge doesn't,
|
||||
// so we're going to test the damage of a Steel-type Stealth Rock instead.
|
||||
const steelHazard = this.dex.getActiveMove('Stealth Rock');
|
||||
steelHazard.type = 'Steel';
|
||||
const typeMod = this.clampIntRange(pokemon.runEffectiveness(steelHazard), -6, 6);
|
||||
this.damage(pokemon.maxhp * (2 ** typeMod) / 8);
|
||||
},
|
||||
},
|
||||
},
|
||||
spikes: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'Spikes');
|
||||
this.effectState.layers = 1;
|
||||
},
|
||||
onSideRestart(side) {
|
||||
if (this.effectState.layers >= 3) return false;
|
||||
this.add('-sidestart', side, 'Spikes');
|
||||
this.effectState.layers++;
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots') || pokemon.side.getSideCondition('escort')) return;
|
||||
const damageAmounts = [0, 3, 4, 6]; // 1/8, 1/6, 1/4
|
||||
this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
|
||||
},
|
||||
},
|
||||
},
|
||||
stickyweb: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Sticky Web');
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots') || pokemon.side.getSideCondition('escort')) return;
|
||||
this.add('-activate', pokemon, 'move: Sticky Web');
|
||||
this.boost({ spe: -1 }, pokemon, pokemon.side.foe.active[0], this.dex.getActiveMove('stickyweb'));
|
||||
},
|
||||
},
|
||||
},
|
||||
toxicspikes: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Toxic Spikes');
|
||||
this.effectState.layers = 1;
|
||||
},
|
||||
onSideRestart(side) {
|
||||
if (this.effectState.layers >= 2) return false;
|
||||
this.add('-sidestart', side, 'move: Toxic Spikes');
|
||||
this.effectState.layers++;
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded()) return;
|
||||
if (pokemon.hasType('Poison')) {
|
||||
this.add('-sideend', pokemon.side, 'move: Toxic Spikes', `[of] ${pokemon}`);
|
||||
pokemon.side.removeSideCondition('toxicspikes');
|
||||
} else if (pokemon.hasType('Steel') || pokemon.hasItem('heavydutyboots') || pokemon.side.getSideCondition('escort')) {
|
||||
// do nothing
|
||||
} else if (this.effectState.layers >= 2) {
|
||||
pokemon.trySetStatus('tox', pokemon.side.foe.active[0]);
|
||||
} else {
|
||||
pokemon.trySetStatus('psn', pokemon.side.foe.active[0]);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
/* // leftover placeholder for hidden power because teams.ts was not cooperating previously
|
||||
terablast: {
|
||||
num: 851,
|
||||
accuracy: 100,
|
||||
basePower: 60,
|
||||
category: "Special",
|
||||
name: "Tera Blast",
|
||||
pp: 15,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1, mustpressure: 1 },
|
||||
onPrepareHit(target, source, move) {
|
||||
this.attrLastMove('[anim] Tera Blast ' + source.teraType);
|
||||
},
|
||||
onModifyType(move, pokemon, target) {
|
||||
move.type = pokemon.teraType;
|
||||
this.add('-message', `This attack is ${pokemon.teraType}-type!`);
|
||||
},
|
||||
target: "normal",
|
||||
type: "Normal",
|
||||
}, */
|
||||
magicroom: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
durationCallback(source, effect) {
|
||||
if (source?.hasAbility('blackout')) {
|
||||
this.add('-activate', source, 'ability: blackout', '[move] Magic Room');
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
}
|
||||
},
|
||||
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);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
198
data/mods/gen9regeneration/pokedex.ts
Normal file
198
data/mods/gen9regeneration/pokedex.ts
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
|
||||
// new
|
||||
alakazam: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 80, atk: 50, def: 50, spa: 110, spd: 110, spe: 110 },
|
||||
abilities: { 0: "Galaxy Brain", 1: "Inner Focus", H: "Trace" },
|
||||
},
|
||||
gengar: {
|
||||
inherit: true,
|
||||
types: ["Ghost", "Ice"],
|
||||
baseStats: { hp: 65, atk: 65, def: 65, spa: 100, spd: 90, spe: 115 },
|
||||
abilities: { 0: "Blackout" },
|
||||
},
|
||||
dragonite: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 91, atk: 134, def: 95, spa: 95, spd: 84, spe: 101 },
|
||||
abilities: { 0: "Lifeguard", H: "Marvel Scale" },
|
||||
},
|
||||
venusaur: {
|
||||
inherit: true,
|
||||
types: ["Grass", "Fairy"],
|
||||
baseStats: { hp: 80, atk: 66, def: 98, spa: 111, spd: 100, spe: 70 },
|
||||
abilities: { 0: "Overgrow", H: "Misty Surge" },
|
||||
},
|
||||
charizard: {
|
||||
inherit: true,
|
||||
types: ["Fire", "Dark"],
|
||||
baseStats: { hp: 68, atk: 120, def: 89, spa: 60, spd: 87, spe: 109 },
|
||||
abilities: { 0: "Blaze", H: "Levitate" },
|
||||
},
|
||||
blastoise: {
|
||||
inherit: true,
|
||||
types: ["Water", "Electric"],
|
||||
baseStats: { hp: 79, atk: 53, def: 100, spa: 105, spd: 105, spe: 88 },
|
||||
abilities: { 0: "Torrent", H: "Motor Drive" },
|
||||
},
|
||||
beedrill: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 65, atk: 100, def: 40, spa: 35, spd: 94, spe: 116 },
|
||||
abilities: { 0: "Poison Touch", H: "Speed Boost" },
|
||||
},
|
||||
pidgeot: {
|
||||
inherit: true,
|
||||
types: ["Flying"],
|
||||
baseStats: { hp: 83, atk: 100, def: 75, spa: 50, spd: 70, spe: 112 },
|
||||
abilities: { 0: "Keen Eye", 1: "Tangled Feet", H: "Wings of Victory" },
|
||||
},
|
||||
onix: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
baseStats: { hp: 75, atk: 135, def: 140, spa: 30, spd: 75, spe: 70 },
|
||||
abilities: { 0: "Sturdy", 1: "Solid Rock", H: "Excavate" },
|
||||
},
|
||||
wigglytuff: {
|
||||
inherit: true,
|
||||
types: ["Fairy", "Dark"],
|
||||
baseStats: { hp: 140, atk: 75, def: 50, spa: 65, spd: 45, spe: 121 },
|
||||
abilities: { 0: "Cute Charm", 1: "Aftermath", H: "Ballooning" },
|
||||
},
|
||||
dodrio: {
|
||||
inherit: true,
|
||||
types: ["Ground", "Fighting"],
|
||||
baseStats: { hp: 85, atk: 115, def: 60, spa: 55, spd: 55, spe: 115 },
|
||||
abilities: { 0: "Sand Rush", 1: "Early Bird", H: "Of A Feather" },
|
||||
},
|
||||
seadra: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
types: ["Poison", "Dragon"],
|
||||
baseStats: { hp: 80, atk: 100, def: 95, spa: 100, spd: 70, spe: 85 },
|
||||
abilities: { 0: "Poison Point", 1: "Rain Dish", H: "Merciless" },
|
||||
},
|
||||
vaporeon: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Run Away", 1: "Trace", H: "Protean" },
|
||||
},
|
||||
flareon: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 110, atk: 130, def: 60, spa: 65, spd: 65, spe: 95 },
|
||||
abilities: { 0: "Run Away", 1: "Trace", H: "Protean" },
|
||||
},
|
||||
jolteon: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 65, atk: 65, def: 60, spa: 95, spd: 110, spe: 130 },
|
||||
abilities: { 0: "Run Away", 1: "Trace", H: "Protean" },
|
||||
},
|
||||
nidoking: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 81, atk: 102, def: 82, spa: 95, spd: 70, spe: 95 },
|
||||
abilities: { 0: "Poison Point", 1: "Patriarch", H: "Sheer Force" },
|
||||
},
|
||||
nidoqueen: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 100, atk: 82, def: 87, spa: 95, spd: 85, spe: 76 },
|
||||
abilities: { 0: "Poison Point", 1: "Natural Cure", H: "Sheer Force" },
|
||||
},
|
||||
butterfree: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 80, atk: 45, def: 52, spa: 92, spd: 79, spe: 106 },
|
||||
abilities: { 0: "Compound Eyes", 1: "Tinted Lens", H: "Multiscale" },
|
||||
},
|
||||
cloyster: {
|
||||
inherit: true,
|
||||
types: ["Water", "Steel"],
|
||||
baseStats: { hp: 80, atk: 90, def: 165, spa: 80, spd: 70, spe: 50 },
|
||||
abilities: { 0: "Shell Armor", 1: "Water Veil", H: "Regenerator" },
|
||||
},
|
||||
gyarados: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 100, atk: 100, def: 107, spa: 70, spd: 92, spe: 71 },
|
||||
abilities: { 0: "Violent Abandon" },
|
||||
},
|
||||
gyaradosmega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 100, atk: 125, def: 107, spa: 105, spd: 122, spe: 81 },
|
||||
abilities: { 0: "Violent Abandon" },
|
||||
requiredItem: "",
|
||||
},
|
||||
tentacruel: {
|
||||
inherit: true,
|
||||
types: ["Dark", "Poison"],
|
||||
baseStats: { hp: 80, atk: 50, def: 65, spa: 100, spd: 120, spe: 100 },
|
||||
abilities: { 0: "Tropical Current" },
|
||||
},
|
||||
raticate: {
|
||||
inherit: true,
|
||||
types: ["Normal", "Poison"],
|
||||
baseStats: { hp: 75, atk: 90, def: 70, spa: 40, spd: 75, spe: 125 },
|
||||
abilities: { 0: "Poison Touch", 1: "Hustle", H: "Guts" },
|
||||
},
|
||||
kangaskhan: {
|
||||
inherit: true,
|
||||
types: ["Normal", "Dragon"],
|
||||
baseStats: { hp: 115, atk: 110, def: 70, spa: 60, spd: 60, spe: 85 },
|
||||
abilities: { 0: "Early Bird", 1: "Bulletproof", H: "Skill Link" },
|
||||
},
|
||||
farfetchd: {
|
||||
inherit: true,
|
||||
types: ["Normal", "Fighting"],
|
||||
baseStats: { hp: 75, atk: 100, def: 80, spa: 60, spd: 75, spe: 90 },
|
||||
abilities: { 0: "Hustle", 1: "Scrappy", H: "Defiant" },
|
||||
},
|
||||
lapras: {
|
||||
inherit: true,
|
||||
types: ["Ice", "Water"],
|
||||
baseStats: { hp: 130, atk: 85, def: 80, spa: 85, spd: 95, spe: 60 },
|
||||
abilities: { 0: "Storm Drain", 1: "Shell Armor", H: "Hydration" },
|
||||
},
|
||||
tauros: {
|
||||
inherit: true,
|
||||
types: ["Normal", "Ground"],
|
||||
baseStats: { hp: 85, atk: 110, def: 105, spa: 30, spd: 70, spe: 110 },
|
||||
abilities: { 0: "Intimidate", 1: "Bull Spirit", H: "Sheer Force" },
|
||||
},
|
||||
marowak: {
|
||||
inherit: true,
|
||||
types: ["Ground", "Ghost"],
|
||||
baseStats: { hp: 80, atk: 80, def: 105, spa: 50, spd: 95, spe: 100 },
|
||||
abilities: { 0: "Battle Armor", 1: "Sand Force", H: "Justified" },
|
||||
},
|
||||
// Minor Changes (mostly to prevent unevolved Pokemons in gen 1 to hold Eviolite)
|
||||
golbat: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
},
|
||||
magneton: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
},
|
||||
lickitung: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
},
|
||||
rhydon: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
},
|
||||
chansey: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
},
|
||||
tangela: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
},
|
||||
electabuzz: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
},
|
||||
magmar: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
},
|
||||
porygon: {
|
||||
inherit: true,
|
||||
evos: [],
|
||||
},
|
||||
};
|
||||
329
data/mods/gen9regeneration/scripts.ts
Normal file
329
data/mods/gen9regeneration/scripts.ts
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
gen: 9,
|
||||
actions: {
|
||||
modifyDamage(
|
||||
baseDamage: number, pokemon: Pokemon, target: Pokemon, move: ActiveMove, suppressMessages = false
|
||||
) {
|
||||
const tr = this.battle.trunc;
|
||||
if (!move.type) move.type = '???';
|
||||
const type = move.type;
|
||||
|
||||
baseDamage += 2;
|
||||
|
||||
if (move.spreadHit) {
|
||||
// multi-target modifier (doubles only)
|
||||
const spreadModifier = this.battle.gameType === 'freeforall' ? 0.5 : 0.75;
|
||||
this.battle.debug(`Spread modifier: ${spreadModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, spreadModifier);
|
||||
} else if (move.multihitType === 'parentalbond' && move.hit > 1) {
|
||||
// Parental Bond modifier
|
||||
const bondModifier = this.battle.gen > 6 ? 0.25 : 0.5;
|
||||
this.battle.debug(`Parental Bond modifier: ${bondModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, bondModifier);
|
||||
}
|
||||
|
||||
// weather modifier
|
||||
baseDamage = this.battle.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
|
||||
|
||||
// crit - not a modifier
|
||||
const isCrit = target.getMoveHitData(move).crit;
|
||||
if (isCrit) {
|
||||
baseDamage = tr(baseDamage * (move.critModifier || (this.battle.gen >= 6 ? 1.5 : 2)));
|
||||
}
|
||||
|
||||
// random factor - also not a modifier
|
||||
baseDamage = this.battle.randomizer(baseDamage);
|
||||
|
||||
// STAB
|
||||
// The "???" type never gets STAB
|
||||
// Not even if you Roost in Gen 4 and somehow manage to use
|
||||
// Struggle in the same turn.
|
||||
// (On second thought, it might be easier to get a MissingNo.)
|
||||
if (type !== '???') {
|
||||
let stab: number | [number, number] = 1;
|
||||
|
||||
const isSTAB = move.forceSTAB || pokemon.hasType(type) || pokemon.getTypes(false, true).includes(type);
|
||||
if (isSTAB) {
|
||||
stab = 1.5;
|
||||
}
|
||||
|
||||
// The Stellar tera type makes this incredibly confusing
|
||||
// If the move's type does not match one of the user's base types,
|
||||
// the Stellar tera type applies a one-time 1.2x damage boost for that type.
|
||||
//
|
||||
// If the move's type does match one of the user's base types,
|
||||
// then the Stellar tera type applies a one-time 2x STAB boost for that type,
|
||||
// and then goes back to using the regular 1.5x STAB boost for those types.
|
||||
if (pokemon.terastallized === 'Stellar') {
|
||||
if (!pokemon.stellarBoostedTypes.includes(type) || move.stellarBoosted) {
|
||||
stab = isSTAB ? 2 : [4915, 4096];
|
||||
move.stellarBoosted = true;
|
||||
if (pokemon.species.name !== 'Terapagos-Stellar') {
|
||||
pokemon.stellarBoostedTypes.push(type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pokemon.terastallized === type && pokemon.getTypes(false, true).includes(type)) {
|
||||
stab = 2;
|
||||
}
|
||||
stab = this.battle.runEvent('ModifySTAB', pokemon, target, move, stab);
|
||||
}
|
||||
|
||||
baseDamage = this.battle.modify(baseDamage, stab);
|
||||
}
|
||||
|
||||
// types
|
||||
let typeMod = target.runEffectiveness(move);
|
||||
typeMod = this.battle.clampIntRange(typeMod, -6, 6);
|
||||
target.getMoveHitData(move).typeMod = typeMod;
|
||||
if (typeMod > 0) {
|
||||
if (!suppressMessages) this.battle.add('-supereffective', target);
|
||||
|
||||
for (let i = 0; i < typeMod; i++) {
|
||||
baseDamage *= 2;
|
||||
}
|
||||
}
|
||||
if (typeMod < 0) {
|
||||
if (!suppressMessages) this.battle.add('-resisted', target);
|
||||
|
||||
for (let i = 0; i > typeMod; i--) {
|
||||
baseDamage = tr(baseDamage / 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (isCrit && !suppressMessages) this.battle.add('-crit', target);
|
||||
|
||||
if (
|
||||
pokemon.status === 'brn' && move.category === 'Physical' &&
|
||||
!pokemon.hasAbility('guts') && !pokemon.hasAbility('tropicalcurrent')
|
||||
) {
|
||||
if (this.battle.gen < 6 || move.id !== 'facade') {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
// Generation 5, but nothing later, sets damage to 1 before the final damage modifiers
|
||||
if (this.battle.gen === 5 && !baseDamage) baseDamage = 1;
|
||||
|
||||
// Final modifier. Modifiers that modify damage after min damage check, such as Life Orb.
|
||||
baseDamage = this.battle.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
|
||||
|
||||
if (move.isZOrMaxPowered && target.getMoveHitData(move).brokeProtect) {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.25);
|
||||
this.battle.add('-zbroken', target);
|
||||
}
|
||||
|
||||
// Generation 6-7 moves the check for minimum 1 damage after the final modifier...
|
||||
if (this.battle.gen !== 5 && !baseDamage) return 1;
|
||||
|
||||
// ...but 16-bit truncation happens even later, and can truncate to 0
|
||||
return tr(baseDamage, 16);
|
||||
},
|
||||
},
|
||||
init() {
|
||||
this.modData("Learnsets", "alakazam").learnset.brainwave = ["9L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.avalanche = ["9L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.blizzard = ["9L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.focusenergy = ["9L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.frostbreath = ["9L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.icebeam = ["9L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.iceshard = ["9L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.powdersnow = ["9L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.snowscape = ["9L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.illwind = ["9L1"];
|
||||
this.modData("Learnsets", "dragonite").learnset.barrier = ["9L1"];
|
||||
this.modData("Learnsets", "dragonite").learnset.guardiandive = ["9L1"];
|
||||
this.modData("Learnsets", "dragonite").learnset.uturn = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.aromaticmist = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.calmmind = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.dazzlinggleam = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.drainingkiss = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.fairywind = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.floralhealing = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.flowershield = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.healpulse = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.playrough = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.psychic = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.vitalenergy = ["9L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.zenheadbutt = ["9L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.ceaselessedge = ["9L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.throatchop = ["9L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.smokytorment = ["9L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.suckerpunch = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.chargebeam = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.charge = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.iondeluge = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.powerwash = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.thunder = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.thunderwave = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.thunderbolt = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.thundershock = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.voltswitch = ["9L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.zapcannon = ["9L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.closecombat = ["9L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.flail = ["9L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.reversal = ["9L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.spikes = ["9L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.stickyweb = ["9L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.taunt = ["9L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.terablast = ["9L1"];
|
||||
this.modData("Learnsets", "pidgeot").learnset.acrobatics = ["9L1"];
|
||||
this.modData("Learnsets", "pidgeot").learnset.closecombat = ["9L1"];
|
||||
this.modData("Learnsets", "wigglytuff").learnset.crunch = ["9L1"];
|
||||
this.modData("Learnsets", "wigglytuff").learnset.darkpulse = ["9L1"];
|
||||
this.modData("Learnsets", "wigglytuff").learnset.rapidspin = ["9L1"];
|
||||
this.modData("Learnsets", "wigglytuff").learnset.taunt = ["9L1"];
|
||||
this.modData("Learnsets", "wigglytuff").learnset.uturn = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.brickbreak = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.bulldoze = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.dig = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.drillrun = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.earthquake = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.highjumpkick = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.lowkick = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.quickguard = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.rototiller = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.sandattack = ["9L1"];
|
||||
this.modData("Learnsets", "dodrio").learnset.triplekick = ["9L1"];
|
||||
this.modData("Learnsets", "seadra").learnset.acidspray = ["9L1"];
|
||||
this.modData("Learnsets", "seadra").learnset.coralcrash = ["9L1"];
|
||||
this.modData("Learnsets", "seadra").learnset.dracometeor = ["9L1"];
|
||||
this.modData("Learnsets", "seadra").learnset.sludgebomb = ["9L1"];
|
||||
this.modData("Learnsets", "seadra").learnset.sludgewave = ["9L1"];
|
||||
this.modData("Learnsets", "seadra").learnset.thunder = ["9L1"];
|
||||
this.modData("Learnsets", "seadra").learnset.thunderbolt = ["9L1"];
|
||||
this.modData("Learnsets", "seadra").learnset.toxicspikes = ["9L1"];
|
||||
this.modData("Learnsets", "vaporeon").learnset.slipaway = ["9L1"];
|
||||
this.modData("Learnsets", "flareon").learnset.crunch = ["9L1"];
|
||||
this.modData("Learnsets", "flareon").learnset.flareout = ["9L1"];
|
||||
this.modData("Learnsets", "flareon").learnset.playrough = ["9L1"];
|
||||
this.modData("Learnsets", "flareon").learnset.psychicfangs = ["9L1"];
|
||||
this.modData("Learnsets", "flareon").learnset.suckerpunch = ["9L1"];
|
||||
this.modData("Learnsets", "jolteon").learnset.buzzoff = ["9L1"];
|
||||
this.modData("Learnsets", "nidoking").learnset.barbbarrage = ["9L1"];
|
||||
this.modData("Learnsets", "nidoqueen").learnset.moonlight = ["9L1"];
|
||||
this.modData("Learnsets", "butterfree").learnset.strengthsap = ["9L1"];
|
||||
this.modData("Learnsets", "butterfree").learnset.powdergale = ["9L1"];
|
||||
delete this.modData('Learnsets', 'alakazam').learnset.focusblast;
|
||||
delete this.modData('Learnsets', 'alakazam').learnset.nastyplot;
|
||||
delete this.modData('Learnsets', 'gengar').learnset.focusblast;
|
||||
delete this.modData('Learnsets', 'gengar').learnset.nastyplot;
|
||||
delete this.modData('Learnsets', 'gengar').learnset.terablast;
|
||||
delete this.modData('Learnsets', 'gengar').learnset.thunderbolt;
|
||||
delete this.modData('Learnsets', 'gengar').learnset.thunder;
|
||||
delete this.modData('Learnsets', 'dragonite').learnset.dragonclaw;
|
||||
delete this.modData('Learnsets', 'dragonite').learnset.dragondance;
|
||||
delete this.modData('Learnsets', 'dragonite').learnset.dragonrush;
|
||||
delete this.modData('Learnsets', 'dragonite').learnset.dualwingbeat;
|
||||
delete this.modData('Learnsets', 'dragonite').learnset.honeclaws;
|
||||
delete this.modData('Learnsets', 'dragonite').learnset.outrage;
|
||||
delete this.modData('Learnsets', 'dragonite').learnset.poweruppunch;
|
||||
delete this.modData('Learnsets', 'dragonite').learnset.terablast;
|
||||
delete this.modData('Learnsets', 'venusaur').learnset.earthpower;
|
||||
delete this.modData('Learnsets', 'venusaur').learnset.weatherball;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.aurasphere;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.avalanche;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.blizzard;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.focusblast;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.hail;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.icebeam;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.icepunch;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.icywind;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.mist;
|
||||
delete this.modData('Learnsets', 'blastoise').learnset.shellsmash;
|
||||
delete this.modData('Learnsets', 'pidgeot').learnset.toxic;
|
||||
delete this.modData('Learnsets', 'dodrio').learnset.fly;
|
||||
delete this.modData('Learnsets', 'seadra').learnset.blizzard;
|
||||
delete this.modData('Learnsets', 'seadra').learnset.icebeam;
|
||||
// Removing the prevos' moves
|
||||
delete this.modData('Learnsets', 'gastly').learnset.nastyplot;
|
||||
delete this.modData('Learnsets', 'gastly').learnset.terablast;
|
||||
delete this.modData('Learnsets', 'gastly').learnset.thunderbolt;
|
||||
delete this.modData('Learnsets', 'gastly').learnset.thunder;
|
||||
delete this.modData('Learnsets', 'haunter').learnset.focusblast;
|
||||
delete this.modData('Learnsets', 'haunter').learnset.nastyplot;
|
||||
delete this.modData('Learnsets', 'haunter').learnset.terablast;
|
||||
delete this.modData('Learnsets', 'haunter').learnset.thunderbolt;
|
||||
delete this.modData('Learnsets', 'haunter').learnset.thunder;
|
||||
delete this.modData('Learnsets', 'dratini').learnset.dragondance;
|
||||
delete this.modData('Learnsets', 'dratini').learnset.dragonrush;
|
||||
delete this.modData('Learnsets', 'dratini').learnset.outrage;
|
||||
delete this.modData('Learnsets', 'dratini').learnset.terablast;
|
||||
delete this.modData('Learnsets', 'dragonair').learnset.dragondance;
|
||||
delete this.modData('Learnsets', 'dragonair').learnset.dragonrush;
|
||||
delete this.modData('Learnsets', 'dragonair').learnset.outrage;
|
||||
delete this.modData('Learnsets', 'dragonair').learnset.terablast;
|
||||
delete this.modData('Learnsets', 'bulbasaur').learnset.weatherball;
|
||||
delete this.modData('Learnsets', 'ivysaur').learnset.weatherball;
|
||||
delete this.modData('Learnsets', 'squirtle').learnset.aurasphere;
|
||||
delete this.modData('Learnsets', 'squirtle').learnset.blizzard;
|
||||
delete this.modData('Learnsets', 'squirtle').learnset.hail;
|
||||
delete this.modData('Learnsets', 'squirtle').learnset.icebeam;
|
||||
delete this.modData('Learnsets', 'squirtle').learnset.icepunch;
|
||||
delete this.modData('Learnsets', 'squirtle').learnset.mist;
|
||||
delete this.modData('Learnsets', 'squirtle').learnset.shellsmash;
|
||||
delete this.modData('Learnsets', 'wartortle').learnset.aurasphere;
|
||||
delete this.modData('Learnsets', 'wartortle').learnset.blizzard;
|
||||
delete this.modData('Learnsets', 'wartortle').learnset.hail;
|
||||
delete this.modData('Learnsets', 'wartortle').learnset.icebeam;
|
||||
delete this.modData('Learnsets', 'wartortle').learnset.icepunch;
|
||||
delete this.modData('Learnsets', 'wartortle').learnset.mist;
|
||||
delete this.modData('Learnsets', 'wartortle').learnset.shellsmash;
|
||||
delete this.modData('Learnsets', 'pidgey').learnset.toxic;
|
||||
delete this.modData('Learnsets', 'pidgeotto').learnset.toxic;
|
||||
delete this.modData('Learnsets', 'doduo').learnset.fly;
|
||||
delete this.modData('Learnsets', 'horsea').learnset.blizzard;
|
||||
delete this.modData('Learnsets', 'horsea').learnset.icebeam;
|
||||
this.modData("Learnsets", "raticate").learnset.gunkshot = ["9L1"];
|
||||
this.modData("Learnsets", "raticate").learnset.poisonjab = ["9L1"];
|
||||
this.modData("Learnsets", "raticate").learnset.sludgebomb = ["9L1"];
|
||||
this.modData("Learnsets", "raticate").learnset.sludgewave = ["9L1"];
|
||||
this.modData("Learnsets", "raticate").learnset.sludge = ["9L1"];
|
||||
this.modData("Learnsets", "raticate").learnset.closecombat = ["9L1"];
|
||||
this.modData("Learnsets", "raticate").learnset.pestspread = ["9L1"];
|
||||
delete this.modData('Learnsets', 'raticate').learnset.swordsdance;
|
||||
delete this.modData('Learnsets', 'raticate').learnset.stompingtantrum;
|
||||
delete this.modData('Learnsets', 'raticate').learnset.suckerpunch;
|
||||
delete this.modData('Learnsets', 'raticate').learnset.pursuit;
|
||||
delete this.modData('Learnsets', 'raticate').learnset.zenheadbutt;
|
||||
delete this.modData('Learnsets', 'rattata').learnset.swordsdance;
|
||||
delete this.modData('Learnsets', 'rattata').learnset.stompingtantrum;
|
||||
delete this.modData('Learnsets', 'rattata').learnset.suckerpunch;
|
||||
delete this.modData('Learnsets', 'rattata').learnset.pursuit;
|
||||
delete this.modData('Learnsets', 'rattata').learnset.zenheadbutt;
|
||||
this.modData("Learnsets", "kangaskhan").learnset.familyonslaught = ["9L1"];
|
||||
this.modData("Learnsets", "kangaskhan").learnset.dragontail = ["9L1"];
|
||||
this.modData("Learnsets", "kangaskhan").learnset.dragonclaw = ["9L1"];
|
||||
this.modData("Learnsets", "kangaskhan").learnset.dracometeor = ["9L1"];
|
||||
this.modData("Learnsets", "kangaskhan").learnset.dragondance = ["9L1"];
|
||||
this.modData("Learnsets", "kangaskhan").learnset.uturn = ["9L1"];
|
||||
this.modData("Learnsets", "farfetchd").learnset.bulkup = ["9L1"];
|
||||
this.modData("Learnsets", "farfetchd").learnset.sacredsword = ["9L1"];
|
||||
delete this.modData('Learnsets', 'farfetchd').learnset.toxic;
|
||||
this.modData("Learnsets", "lapras").learnset.escort = ["9L1"];
|
||||
this.modData("Learnsets", "lapras").learnset.wish = ["9L1"];
|
||||
this.modData("Learnsets", "tauros").learnset.escort = ["9L1"];
|
||||
this.modData("Learnsets", "tauros").learnset.headlongrush = ["9L1"];
|
||||
this.modData("Learnsets", "marowak").learnset.knockoff = ["9L1"];
|
||||
this.modData("Learnsets", "marowak").learnset.vengefulbone = ["9L1"];
|
||||
this.modData("Learnsets", "marowak").learnset.closecombat = ["9L1"];
|
||||
this.modData("Learnsets", "gyarados").learnset.acrobatics = ["9L1"];
|
||||
this.modData("Learnsets", "gyarados").learnset.ragingtorrent = ["9L1"];
|
||||
this.modData("Learnsets", "cloyster").learnset.bulletpunch = ["9L1"];
|
||||
this.modData("Learnsets", "cloyster").learnset.curse = ["9L1"];
|
||||
this.modData("Learnsets", "cloyster").learnset.explosion = ["9L1"];
|
||||
this.modData("Learnsets", "cloyster").learnset.ironhead = ["9L1"];
|
||||
this.modData("Learnsets", "cloyster").learnset.splashback = ["9L1"];
|
||||
this.modData("Learnsets", "tentacruel").learnset.darkpulse = ["9L1"];
|
||||
this.modData("Learnsets", "tentacruel").learnset.foulplay = ["9L1"];
|
||||
this.modData("Learnsets", "tentacruel").learnset.nastyplot = ["9L1"];
|
||||
delete this.modData('Learnsets', 'cloyster').learnset.iceshard;
|
||||
delete this.modData('Learnsets', 'cloyster').learnset.lifedew;
|
||||
delete this.modData('Learnsets', 'cloyster').learnset.shellsmash;
|
||||
delete this.modData('Learnsets', 'tentacruel').learnset.scald;
|
||||
delete this.modData('Learnsets', 'shellder').learnset.iceshard;
|
||||
delete this.modData('Learnsets', 'shellder').learnset.lifedew;
|
||||
delete this.modData('Learnsets', 'shellder').learnset.shellsmash;
|
||||
delete this.modData('Learnsets', 'tentacool').learnset.scald;
|
||||
},
|
||||
};
|
||||
|
|
@ -942,11 +942,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
this.boost({ spe: 1 });
|
||||
this.heal(pokemon.maxhp);
|
||||
const move = this.dex.moves.get('finalgambit');
|
||||
const pp = this.calculatePP(move);
|
||||
const finalGambit = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
pp,
|
||||
maxpp: pp,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
|
|
|
|||
|
|
@ -18,11 +18,12 @@ export const Conditions: { [id: IDEntry]: ModdedConditionData & { innateName?: s
|
|||
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
|
||||
if (ironHeadIndex >= 0) {
|
||||
const move = this.dex.moves.get('behemothblade');
|
||||
const pp = this.calculatePP(move, pokemon.ppUps[ironHeadIndex]);
|
||||
pokemon.baseMoveSlots[ironHeadIndex] = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
pp,
|
||||
maxpp: pp,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
disabledSource: '',
|
||||
|
|
@ -47,11 +48,12 @@ export const Conditions: { [id: IDEntry]: ModdedConditionData & { innateName?: s
|
|||
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
|
||||
if (ironHeadIndex >= 0) {
|
||||
const move = this.dex.moves.get('behemothbash');
|
||||
const pp = this.calculatePP(move, pokemon.ppUps[ironHeadIndex]);
|
||||
pokemon.baseMoveSlots[ironHeadIndex] = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
pp,
|
||||
maxpp: pp,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
disabledSource: '',
|
||||
|
|
|
|||
|
|
@ -1060,11 +1060,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect']) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -1174,11 +1170,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect']) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -3136,14 +3128,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
flags: {},
|
||||
volatileStatus: 'curse',
|
||||
onHit(target, source) {
|
||||
const result = this.random(3);
|
||||
if (result === 0) {
|
||||
target.trySetStatus('psn', target);
|
||||
} else if (result === 1) {
|
||||
target.trySetStatus('par', target);
|
||||
} else {
|
||||
target.trySetStatus('brn', target);
|
||||
}
|
||||
const status = this.sample(['psn', 'par', 'brn']);
|
||||
target.trySetStatus(status, source);
|
||||
this.boost({ spe: 1 }, source);
|
||||
},
|
||||
onPrepareHit(target, source) {
|
||||
|
|
@ -3455,7 +3441,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
attacker.addVolatile('twoturnmove', defender);
|
||||
return null;
|
||||
},
|
||||
hasSheerForce: true,
|
||||
hasSheerForceBoost: true,
|
||||
onPrepareHit(target, source) {
|
||||
this.attrLastMove('[still]');
|
||||
this.add('-anim', source, 'Lunar Dance', target);
|
||||
|
|
@ -3726,14 +3712,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
if (randomStat2 && randomStat === randomStat2) boost[randomStat] = 4;
|
||||
else if (randomStat2) boost[randomStat2] = 2;
|
||||
this.boost(boost, source);
|
||||
const result = this.random(3);
|
||||
if (result === 0) {
|
||||
this.actions.useMove("laserfocus", target);
|
||||
} else if (result === 1) {
|
||||
this.actions.useMove("lockon", target);
|
||||
} else {
|
||||
this.actions.useMove("charge", target);
|
||||
} // This is easier than implementing each condition manually
|
||||
// This is easier than implementing each condition manually
|
||||
const move = this.sample(['lockon', 'laserfocus', 'charge']);
|
||||
this.actions.useMove(move, target);
|
||||
this.heal(target.maxhp / 4, target, target, this.effect);
|
||||
},
|
||||
target: "self",
|
||||
|
|
@ -4013,12 +3994,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect']) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (move && (move.target === 'self' || move.category === 'Status')) return;
|
||||
if (move.target === 'self') return;
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
this.add('-activate', target, 'move: Alting', move.name);
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
|
|
@ -6604,7 +6581,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
if (!target.isGrounded()) {
|
||||
const baseMove = this.dex.moves.get(effect.id);
|
||||
if (baseMove.priority > 0) {
|
||||
this.hint("Psychic Terrain doesn't affect Pokémon immune to Ground.");
|
||||
this.hint("Psychic Terrain doesn't affect airborne Pokémon.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,11 +142,12 @@ export function changeMoves(context: Battle, pokemon: Pokemon, newMoves: (string
|
|||
const moveName = Array.isArray(newMove) ? newMove[context.random(newMove.length)] : newMove;
|
||||
const move = context.dex.moves.get(context.toID(moveName));
|
||||
if (!move.id) continue;
|
||||
const pp = context.calculatePP(move);
|
||||
const moveSlot = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: Math.floor((move.noPPBoosts ? move.pp : move.pp * 8 / 5) * carryOver[slot]),
|
||||
maxpp: (move.noPPBoosts ? move.pp : move.pp * 8 / 5),
|
||||
pp: pp * carryOver[slot],
|
||||
maxpp: pp,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
disabledSource: '',
|
||||
|
|
@ -771,7 +772,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
// Final modifier. Modifiers that modify damage after min damage check, such as Life Orb.
|
||||
baseDamage = this.battle.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
|
||||
|
||||
if (move.isZOrMaxPowered && target.getMoveHitData(move).zBrokeProtect) {
|
||||
if (move.isZOrMaxPowered && target.getMoveHitData(move).brokeProtect) {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.25);
|
||||
this.battle.add('-zbroken', target);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
init() {
|
||||
this.modData('Abilities', 'dragonize').isNonstandard = null;
|
||||
this.modData('Abilities', 'megasol').isNonstandard = null;
|
||||
this.modData('Abilities', 'piercingdrill').isNonstandard = null;
|
||||
this.modData('Abilities', 'spicyspray').isNonstandard = null;
|
||||
for (const i in this.data.Items) {
|
||||
const item = this.data.Items[i];
|
||||
if (!item.megaStone && !item.onDrive && !(item.onPlate && !item.zMove) && !item.onMemory) continue;
|
||||
|
|
@ -125,14 +127,15 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
const behemothMove: { [k: string]: string } = {
|
||||
'Rusted Sword': 'behemothblade', 'Rusted Shield': 'behemothbash',
|
||||
};
|
||||
const ironHead = pokemon.baseMoves.indexOf('ironhead');
|
||||
if (ironHead >= 0) {
|
||||
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
|
||||
if (ironHeadIndex >= 0) {
|
||||
const move = this.dex.moves.get(behemothMove[pokemon.getItem().name]);
|
||||
pokemon.baseMoveSlots[ironHead] = {
|
||||
const pp = this.calculatePP(move, pokemon.ppUps[ironHeadIndex]);
|
||||
pokemon.baseMoveSlots[ironHeadIndex] = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
pp,
|
||||
maxpp: pp,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
disabledSource: '',
|
||||
|
|
|
|||
|
|
@ -407,17 +407,18 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
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) {
|
||||
for (const [i, moveSlot] of pokemon.moveSlots.entries()) {
|
||||
let moveName = moveSlot.move;
|
||||
if (!pokemon.m.curMoves.includes(moveSlot.id)) continue;
|
||||
if (moveSlot.id === 'hiddenpower') {
|
||||
moveName = 'Hidden Power ' + this.hpType;
|
||||
}
|
||||
const move = this.battle.dex.moves.get(moveSlot.id);
|
||||
const pp = Math.min(5, move.pp);
|
||||
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,
|
||||
pp,
|
||||
maxpp: this.battle.gen >= 5 ? pp : this.battle.calculatePP(move, this.ppUps[i] || 0),
|
||||
target: moveSlot.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
|
|
|
|||
|
|
@ -215,11 +215,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect']) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -70,16 +70,18 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
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) {
|
||||
for (const [i, moveSlot] of pokemon.moveSlots.entries()) {
|
||||
let moveName = moveSlot.move;
|
||||
if (moveSlot.id === 'hiddenpower') {
|
||||
moveName = 'Hidden Power ' + this.hpType;
|
||||
}
|
||||
const move = this.battle.dex.moves.get(moveSlot.id);
|
||||
const pp = Math.min(5, move.pp);
|
||||
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,
|
||||
pp,
|
||||
maxpp: this.battle.gen >= 5 ? pp : this.battle.calculatePP(move, this.ppUps[i] || 0),
|
||||
target: moveSlot.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
|
|
|
|||
|
|
@ -574,7 +574,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
if (!target.isGrounded()) {
|
||||
const baseMove = this.dex.moves.get(effect.id);
|
||||
if (baseMove.priority > 0) {
|
||||
this.hint("Psychic Terrain doesn't affect Pokémon immune to Ground.");
|
||||
this.hint("Psychic Terrain doesn't affect airborne Pokémon.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,16 +251,18 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
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) {
|
||||
for (const [i, moveSlot] of pokemon.moveSlots.entries()) {
|
||||
let moveName = moveSlot.move;
|
||||
if (moveSlot.id === 'hiddenpower') {
|
||||
moveName = 'Hidden Power ' + this.hpType;
|
||||
}
|
||||
const move = this.battle.dex.moves.get(moveSlot.id);
|
||||
const pp = Math.min(5, move.pp);
|
||||
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,
|
||||
pp,
|
||||
maxpp: this.battle.gen >= 5 ? pp : this.battle.calculatePP(move, this.ppUps[i] || 0),
|
||||
target: moveSlot.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
|
|
|
|||
134
data/moves.ts
134
data/moves.ts
|
|
@ -1006,11 +1006,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect']) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -2042,11 +2038,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect'] || move.category === 'Status') {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -2232,7 +2224,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, slicing: 1 },
|
||||
onAfterHit(target, source, move) {
|
||||
if (!move.hasSheerForce && source.hp) {
|
||||
if (!move.hasSheerForce) {
|
||||
for (const side of source.side.foeSidesWithConditions()) {
|
||||
side.addSideCondition('spikes');
|
||||
}
|
||||
|
|
@ -3643,14 +3635,8 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
secondary: {
|
||||
chance: 50,
|
||||
onHit(target, source) {
|
||||
const result = this.random(3);
|
||||
if (result === 0) {
|
||||
target.trySetStatus('psn', source);
|
||||
} else if (result === 1) {
|
||||
target.trySetStatus('par', source);
|
||||
} else {
|
||||
target.trySetStatus('slp', source);
|
||||
}
|
||||
const status = this.sample(['psn', 'par', 'slp']);
|
||||
target.trySetStatus(status, source);
|
||||
},
|
||||
},
|
||||
target: "normal",
|
||||
|
|
@ -4664,7 +4650,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
attacker.addVolatile('twoturnmove', defender);
|
||||
return null;
|
||||
},
|
||||
hasSheerForce: true,
|
||||
hasSheerForceBoost: true,
|
||||
target: "normal",
|
||||
type: "Electric",
|
||||
},
|
||||
|
|
@ -6733,14 +6719,8 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
self: {
|
||||
onHit(source) {
|
||||
for (const pokemon of source.foes()) {
|
||||
const result = this.random(3);
|
||||
if (result === 0) {
|
||||
pokemon.trySetStatus('slp', source);
|
||||
} else if (result === 1) {
|
||||
pokemon.trySetStatus('par', source);
|
||||
} else {
|
||||
pokemon.trySetStatus('psn', source);
|
||||
}
|
||||
const status = this.sample(['slp', 'par', 'psn']);
|
||||
pokemon.trySetStatus(status, source);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -9439,9 +9419,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
onAfterHit(target, source) {
|
||||
if (source.hp) {
|
||||
this.field.clearTerrain();
|
||||
}
|
||||
this.field.clearTerrain();
|
||||
},
|
||||
onAfterSubDamage(damage, target, source) {
|
||||
if (source.hp) {
|
||||
|
|
@ -9944,11 +9922,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect'] || move.category === 'Status') {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -9994,11 +9968,9 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
}
|
||||
},
|
||||
onAfterHit(target, source) {
|
||||
if (source.hp) {
|
||||
const item = target.takeItem();
|
||||
if (item) {
|
||||
this.add('-enditem', target, item.name, '[from] move: Knock Off', `[of] ${source}`);
|
||||
}
|
||||
const item = target.takeItem();
|
||||
if (item) {
|
||||
this.add('-enditem', target, item.name, '[from] move: Knock Off', `[of] ${source}`);
|
||||
}
|
||||
},
|
||||
target: "normal",
|
||||
|
|
@ -11028,12 +11000,8 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect']) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (move && (move.target === 'self' || move.category === 'Status')) return;
|
||||
if (move.target === 'self') return;
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
this.add('-activate', target, 'move: Mat Block', move.name);
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
|
|
@ -12353,16 +12321,16 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
onAfterHit(target, pokemon, move) {
|
||||
if (!move.hasSheerForce) {
|
||||
if (pokemon.hp && pokemon.removeVolatile('leechseed')) {
|
||||
if (pokemon.removeVolatile('leechseed')) {
|
||||
this.add('-end', pokemon, 'Leech Seed', '[from] move: Mortal Spin', `[of] ${pokemon}`);
|
||||
}
|
||||
const sideConditions = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb', 'gmaxsteelsurge'];
|
||||
for (const condition of sideConditions) {
|
||||
if (pokemon.hp && pokemon.side.removeSideCondition(condition)) {
|
||||
if (pokemon.side.removeSideCondition(condition)) {
|
||||
this.add('-sideend', pokemon.side, this.dex.conditions.get(condition).name, '[from] move: Mortal Spin', `[of] ${pokemon}`);
|
||||
}
|
||||
}
|
||||
if (pokemon.hp && pokemon.volatiles['partiallytrapped']) {
|
||||
if (pokemon.volatiles['partiallytrapped']) {
|
||||
pokemon.removeVolatile('partiallytrapped');
|
||||
}
|
||||
}
|
||||
|
|
@ -12926,11 +12894,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect'] || move.category === 'Status') {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -13097,7 +13061,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
break;
|
||||
}
|
||||
},
|
||||
hasSheerForce: true,
|
||||
hasSheerForceBoost: true,
|
||||
target: "normal",
|
||||
type: "Dragon",
|
||||
},
|
||||
|
|
@ -14017,11 +13981,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect']) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -14159,7 +14119,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
if (!target.isGrounded()) {
|
||||
const baseMove = this.dex.moves.get(effect.id);
|
||||
if (baseMove.priority > 0) {
|
||||
this.hint("Psychic Terrain doesn't affect Pokémon immune to Ground.");
|
||||
this.hint("Psychic Terrain doesn't affect airborne Pokémon.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -14551,11 +14511,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
// Quick Guard blocks moves with positive priority, even those given increased priority by Prankster or Gale Wings.
|
||||
// (e.g. it blocks 0 priority moves boosted by Prankster or Gale Wings; Quick Claw/Custap Berry do not count)
|
||||
if (move.priority <= 0.1) return;
|
||||
if (!move.flags['protect']) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
this.add('-activate', target, 'move: Quick Guard');
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
|
|
@ -14745,16 +14701,16 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
onAfterHit(target, pokemon, move) {
|
||||
if (!move.hasSheerForce) {
|
||||
if (pokemon.hp && pokemon.removeVolatile('leechseed')) {
|
||||
if (pokemon.removeVolatile('leechseed')) {
|
||||
this.add('-end', pokemon, 'Leech Seed', '[from] move: Rapid Spin', `[of] ${pokemon}`);
|
||||
}
|
||||
const sideConditions = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb', 'gmaxsteelsurge'];
|
||||
for (const condition of sideConditions) {
|
||||
if (pokemon.hp && pokemon.side.removeSideCondition(condition)) {
|
||||
if (pokemon.side.removeSideCondition(condition)) {
|
||||
this.add('-sideend', pokemon.side, this.dex.conditions.get(condition).name, '[from] move: Rapid Spin', `[of] ${pokemon}`);
|
||||
}
|
||||
}
|
||||
if (pokemon.hp && pokemon.volatiles['partiallytrapped']) {
|
||||
if (pokemon.volatiles['partiallytrapped']) {
|
||||
pokemon.removeVolatile('partiallytrapped');
|
||||
}
|
||||
}
|
||||
|
|
@ -16474,10 +16430,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect'] || move.category === 'Status') {
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target, false)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -17285,7 +17238,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
return;
|
||||
}
|
||||
this.add('-prepare', attacker, move.name);
|
||||
if (['sunnyday', 'desolateland'].includes(attacker.effectiveWeather())) {
|
||||
if (['sunnyday', 'desolateland'].includes(attacker.effectiveWeather(true))) {
|
||||
this.attrLastMove('[still]');
|
||||
this.addMove('-anim', attacker, move.name, defender);
|
||||
return;
|
||||
|
|
@ -17321,7 +17274,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
return;
|
||||
}
|
||||
this.add('-prepare', attacker, move.name);
|
||||
if (['sunnyday', 'desolateland'].includes(attacker.effectiveWeather())) {
|
||||
if (['sunnyday', 'desolateland'].includes(attacker.effectiveWeather(true))) {
|
||||
this.attrLastMove('[still]');
|
||||
this.addMove('-anim', attacker, move.name, defender);
|
||||
return;
|
||||
|
|
@ -17603,11 +17556,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
},
|
||||
onTryHitPriority: 3,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect']) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -18135,7 +18084,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, slicing: 1 },
|
||||
onAfterHit(target, source, move) {
|
||||
if (!move.hasSheerForce && source.hp) {
|
||||
if (!move.hasSheerForce) {
|
||||
for (const side of source.side.foeSidesWithConditions()) {
|
||||
side.addSideCondition('stealthrock');
|
||||
}
|
||||
|
|
@ -18715,7 +18664,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
onHit(target, source, move) {
|
||||
const yourItem = target.takeItem(source);
|
||||
const myItem = source.takeItem();
|
||||
if (target.item || source.item || (!yourItem && !myItem)) {
|
||||
if (yourItem === false || myItem === false || (!yourItem && !myItem)) {
|
||||
if (yourItem) target.item = yourItem.id;
|
||||
if (myItem) source.item = myItem.id;
|
||||
return false;
|
||||
|
|
@ -19915,14 +19864,8 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
secondary: {
|
||||
chance: 20,
|
||||
onHit(target, source) {
|
||||
const result = this.random(3);
|
||||
if (result === 0) {
|
||||
target.trySetStatus('brn', source);
|
||||
} else if (result === 1) {
|
||||
target.trySetStatus('par', source);
|
||||
} else {
|
||||
target.trySetStatus('frz', source);
|
||||
}
|
||||
const status = this.sample(['brn', 'par', 'frz']);
|
||||
target.trySetStatus(status, source);
|
||||
},
|
||||
},
|
||||
target: "normal",
|
||||
|
|
@ -19944,7 +19887,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
onHit(target, source, move) {
|
||||
const yourItem = target.takeItem(source);
|
||||
const myItem = source.takeItem();
|
||||
if (target.item || source.item || (!yourItem && !myItem)) {
|
||||
if (yourItem === false || myItem === false || (!yourItem && !myItem)) {
|
||||
if (yourItem) target.item = yourItem.id;
|
||||
if (myItem) source.item = myItem.id;
|
||||
return false;
|
||||
|
|
@ -20177,7 +20120,6 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
isNonstandard: "Past",
|
||||
name: "Trump Card",
|
||||
pp: 5,
|
||||
noPPBoosts: true,
|
||||
priority: 0,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
target: "normal",
|
||||
|
|
@ -20900,11 +20842,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
if (move?.target !== 'allAdjacent' && move.target !== 'allAdjacentFoes') {
|
||||
return;
|
||||
}
|
||||
if (move.isZ || move.isMax) {
|
||||
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
|
||||
target.getMoveHitData(move).zBrokeProtect = true;
|
||||
return;
|
||||
}
|
||||
if (this.checkMoveBreaksProtect(move, source, target)) return;
|
||||
this.add('-activate', target, 'move: Wide Guard');
|
||||
const lockedmove = source.getVolatile('lockedmove');
|
||||
if (lockedmove) {
|
||||
|
|
|
|||
|
|
@ -1039,7 +1039,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
types: ["Fairy", "Flying"],
|
||||
genderRatio: { M: 0.25, F: 0.75 },
|
||||
baseStats: { hp: 95, atk: 80, def: 93, spa: 135, spd: 110, spe: 70 },
|
||||
abilities: { 0: "Cute Charm", 1: "Magic Guard", H: "Unaware" },
|
||||
abilities: { 0: "Magic Bounce" },
|
||||
heightm: 1.7,
|
||||
weightkg: 42.3,
|
||||
color: "Pink",
|
||||
|
|
@ -1723,7 +1723,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Grass", "Poison"],
|
||||
baseStats: { hp: 80, atk: 125, def: 85, spa: 135, spd: 95, spe: 70 },
|
||||
abilities: { 0: "Chlorophyll", H: "Gluttony" },
|
||||
abilities: { 0: "Innards Out" },
|
||||
heightm: 4.5,
|
||||
weightkg: 125.5,
|
||||
color: "Green",
|
||||
|
|
@ -2736,9 +2736,8 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Water", "Psychic"],
|
||||
gender: "N",
|
||||
// FIXME: change stats on generation shift
|
||||
baseStats: { hp: 60, atk: 140, def: 105, spa: 130, spd: 105, spe: 120 },
|
||||
abilities: { 0: "Illuminate", 1: "Natural Cure", H: "Analytic" },
|
||||
baseStats: { hp: 60, atk: 100, def: 105, spa: 130, spd: 105, spe: 120 },
|
||||
abilities: { 0: "Huge Power" },
|
||||
heightm: 2.3,
|
||||
weightkg: 80,
|
||||
color: "Purple",
|
||||
|
|
@ -3352,7 +3351,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Dragon", "Flying"],
|
||||
baseStats: { hp: 91, atk: 124, def: 115, spa: 145, spd: 125, spe: 100 },
|
||||
abilities: { 0: "Inner Focus", H: "Multiscale" },
|
||||
abilities: { 0: "Multiscale" },
|
||||
heightm: 2.2,
|
||||
weightkg: 290,
|
||||
color: "Brown",
|
||||
|
|
@ -4636,7 +4635,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Steel", "Flying"],
|
||||
baseStats: { hp: 65, atk: 140, def: 110, spa: 40, spd: 100, spe: 110 },
|
||||
abilities: { 0: "Keen Eye", 1: "Sturdy", H: "Weak Armor" },
|
||||
abilities: { 0: "Stalwart" },
|
||||
heightm: 1.7,
|
||||
weightkg: 40.4,
|
||||
color: "Gray",
|
||||
|
|
@ -8708,7 +8707,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
types: ["Ice", "Ghost"],
|
||||
gender: "F",
|
||||
baseStats: { hp: 70, atk: 80, def: 70, spa: 140, spd: 100, spe: 120 },
|
||||
abilities: { 0: "Snow Cloak", H: "Cursed Body" },
|
||||
abilities: { 0: "Snow Warning" },
|
||||
heightm: 2.6,
|
||||
weightkg: 29.6,
|
||||
color: "White",
|
||||
|
|
@ -9913,7 +9912,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Ground", "Steel"],
|
||||
baseStats: { hp: 110, atk: 165, def: 100, spa: 65, spd: 65, spe: 103 },
|
||||
abilities: { 0: "Sand Rush", 1: "Sand Force", H: "Mold Breaker" },
|
||||
abilities: { 0: "Piercing Drill" },
|
||||
heightm: 0.9,
|
||||
weightkg: 60,
|
||||
color: "Gray",
|
||||
|
|
@ -11144,7 +11143,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
baseStats: { hp: 85, atk: 145, def: 80, spa: 135, spd: 90, spe: 80 },
|
||||
abilities: { 0: "Levitate" },
|
||||
heightm: 3,
|
||||
weightkg: 160,
|
||||
weightkg: 180,
|
||||
color: "Blue",
|
||||
eggGroups: ["Amorphous"],
|
||||
requiredItem: "Eelektrossite",
|
||||
|
|
@ -11224,7 +11223,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Ghost", "Fire"],
|
||||
baseStats: { hp: 60, atk: 75, def: 110, spa: 175, spd: 110, spe: 90 },
|
||||
abilities: { 0: "Flash Fire", 1: "Flame Body", H: "Infiltrator" },
|
||||
abilities: { 0: "Infiltrator" },
|
||||
heightm: 2.5,
|
||||
weightkg: 69.6,
|
||||
color: "Black",
|
||||
|
|
@ -11433,7 +11432,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
types: ["Ground", "Ghost"],
|
||||
gender: "N",
|
||||
baseStats: { hp: 89, atk: 159, def: 105, spa: 70, spd: 105, spe: 55 },
|
||||
abilities: { 0: "Iron Fist", 1: "Klutz", H: "No Guard" },
|
||||
abilities: { 0: "Unseen Fist" },
|
||||
heightm: 4,
|
||||
weightkg: 330,
|
||||
color: "Green",
|
||||
|
|
@ -12573,7 +12572,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
types: ["Fairy"],
|
||||
gender: "F",
|
||||
baseStats: { hp: 74, atk: 85, def: 87, spa: 155, spd: 148, spe: 102 },
|
||||
abilities: { 0: "Flower Veil", H: "Symbiosis" },
|
||||
abilities: { 0: "Fairy Aura" },
|
||||
heightm: 0.2,
|
||||
weightkg: 100.8,
|
||||
color: "White",
|
||||
|
|
@ -12729,7 +12728,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
types: ["Psychic"],
|
||||
gender: "M",
|
||||
baseStats: { hp: 74, atk: 48, def: 76, spa: 143, spd: 101, spe: 124 },
|
||||
abilities: { 0: "Keen Eye", 1: "Infiltrator", H: "Competitive" },
|
||||
abilities: { 0: "Trace" },
|
||||
heightm: 0.8,
|
||||
weightkg: 10.1,
|
||||
color: "Blue",
|
||||
|
|
@ -12746,7 +12745,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
types: ["Psychic"],
|
||||
gender: "F",
|
||||
baseStats: { hp: 74, atk: 48, def: 76, spa: 143, spd: 101, spe: 124 },
|
||||
abilities: { 0: "Keen Eye", 1: "Infiltrator", H: "Competitive" },
|
||||
abilities: { 0: "Trace" },
|
||||
heightm: 0.8,
|
||||
weightkg: 10.1,
|
||||
color: "White",
|
||||
|
|
@ -13134,7 +13133,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Fighting", "Flying"],
|
||||
baseStats: { hp: 78, atk: 137, def: 100, spa: 74, spd: 93, spe: 118 },
|
||||
abilities: { 0: "Limber", 1: "Unburden", H: "Mold Breaker" },
|
||||
abilities: { 0: "No Guard" },
|
||||
heightm: 1,
|
||||
weightkg: 25,
|
||||
color: "Green",
|
||||
|
|
@ -13960,7 +13959,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Fighting", "Ice"],
|
||||
baseStats: { hp: 97, atk: 157, def: 122, spa: 62, spd: 107, spe: 33 },
|
||||
abilities: { 0: "Hyper Cutter", 1: "Iron Fist", H: "Anger Point" },
|
||||
abilities: { 0: "Iron Fist" },
|
||||
heightm: 2.6,
|
||||
weightkg: 252.8,
|
||||
color: "White",
|
||||
|
|
@ -15075,9 +15074,9 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Normal", "Dragon"],
|
||||
baseStats: { hp: 78, atk: 85, def: 110, spa: 160, spd: 116, spe: 36 },
|
||||
abilities: { 0: "Berserk", 1: "Sap Sipper", H: "Cloud Nine" },
|
||||
abilities: { 0: "Berserk" },
|
||||
heightm: 3,
|
||||
weightkg: 185,
|
||||
weightkg: 240.5,
|
||||
color: "White",
|
||||
eggGroups: ["Monster", "Dragon"],
|
||||
requiredItem: "Drampanite",
|
||||
|
|
@ -18281,7 +18280,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Grass", "Fire"],
|
||||
baseStats: { hp: 65, atk: 138, def: 85, spa: 138, spd: 85, spe: 75 },
|
||||
abilities: { 0: "Chlorophyll", 1: "Insomnia", H: "Moody" },
|
||||
abilities: { 0: "Spicy Spray" },
|
||||
heightm: 1.2,
|
||||
weightkg: 22,
|
||||
color: "Green",
|
||||
|
|
@ -18541,7 +18540,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
forme: "Mega",
|
||||
types: ["Rock", "Poison"],
|
||||
baseStats: { hp: 83, atk: 90, def: 105, spa: 150, spd: 96, spe: 101 },
|
||||
abilities: { 0: "Toxic Debris", H: "Corrosion" },
|
||||
abilities: { 0: "Adaptability" },
|
||||
heightm: 2.8,
|
||||
weightkg: 77,
|
||||
color: "Blue",
|
||||
|
|
@ -18682,7 +18681,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
baseStats: { hp: 68, atk: 65, def: 90, spa: 135, spd: 125, spe: 92 },
|
||||
abilities: { 0: "Commander", H: "Storm Drain" },
|
||||
heightm: 0.3,
|
||||
weightkg: 8,
|
||||
weightkg: 24,
|
||||
color: "Red",
|
||||
eggGroups: ["Water 2"],
|
||||
requiredItem: "Tatsugirinite",
|
||||
|
|
@ -18697,7 +18696,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
baseStats: { hp: 68, atk: 65, def: 90, spa: 135, spd: 125, spe: 92 },
|
||||
abilities: { 0: "Commander", H: "Storm Drain" },
|
||||
heightm: 0.3,
|
||||
weightkg: 8,
|
||||
weightkg: 24,
|
||||
color: "Pink",
|
||||
eggGroups: ["Water 2"],
|
||||
requiredItem: "Tatsugirinite",
|
||||
|
|
@ -18712,7 +18711,7 @@ export const Pokedex: import('../sim/dex-species').SpeciesDataTable = {
|
|||
baseStats: { hp: 68, atk: 65, def: 90, spa: 135, spd: 125, spe: 92 },
|
||||
abilities: { 0: "Commander", H: "Storm Drain" },
|
||||
heightm: 0.3,
|
||||
weightkg: 8,
|
||||
weightkg: 24,
|
||||
color: "Yellow",
|
||||
eggGroups: ["Water 2"],
|
||||
requiredItem: "Tatsugirinite",
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@
|
|||
"movepool": ["earthquake", "fireblast", "icebeam", "shadowball", "sludgebomb", "substitute", "thunderbolt"],
|
||||
"abilities": ["Poison Point"]
|
||||
},
|
||||
{
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
"movepool": ["earthquake", "fireblast", "icebeam", "rockslide", "shadowball", "sludgebomb"],
|
||||
"abilities": ["Poison Point"]
|
||||
|
|
@ -619,7 +619,7 @@
|
|||
"movepool": ["doubleedge", "hiddenpowerghost", "hiddenpowerground", "surf", "swordsdance"],
|
||||
"abilities": ["Hyper Cutter"]
|
||||
},
|
||||
{
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
"movepool": ["doubleedge", "hiddenpowerghost", "mudshot", "swordsdance"],
|
||||
"abilities": ["Hyper Cutter"]
|
||||
|
|
@ -1237,7 +1237,7 @@
|
|||
]
|
||||
},
|
||||
"crobat": {
|
||||
"level": 77,
|
||||
"level": 78,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -1485,7 +1485,7 @@
|
|||
]
|
||||
},
|
||||
"slowking": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -1600,7 +1600,7 @@
|
|||
]
|
||||
},
|
||||
"steelix": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -1636,7 +1636,7 @@
|
|||
]
|
||||
},
|
||||
"qwilfish": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -1734,7 +1734,7 @@
|
|||
]
|
||||
},
|
||||
"magcargo": {
|
||||
"level": 99,
|
||||
"level": 100,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -1785,7 +1785,7 @@
|
|||
]
|
||||
},
|
||||
"delibird": {
|
||||
"level": 99,
|
||||
"level": 98,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -2378,7 +2378,7 @@
|
|||
]
|
||||
},
|
||||
"mawile": {
|
||||
"level": 95,
|
||||
"level": 96,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -2567,7 +2567,7 @@
|
|||
]
|
||||
},
|
||||
"torkoal": {
|
||||
"level": 91,
|
||||
"level": 90,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@
|
|||
]
|
||||
},
|
||||
"parasect": {
|
||||
"level": 99,
|
||||
"level": 100,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -340,7 +340,7 @@
|
|||
]
|
||||
},
|
||||
"alakazam": {
|
||||
"level": 80,
|
||||
"level": 79,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -388,7 +388,7 @@
|
|||
]
|
||||
},
|
||||
"golem": {
|
||||
"level": 87,
|
||||
"level": 86,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -565,7 +565,7 @@
|
|||
]
|
||||
},
|
||||
"marowak": {
|
||||
"level": 89,
|
||||
"level": 88,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -856,7 +856,7 @@
|
|||
]
|
||||
},
|
||||
"snorlax": {
|
||||
"level": 78,
|
||||
"level": 77,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -1158,7 +1158,7 @@
|
|||
]
|
||||
},
|
||||
"sunflora": {
|
||||
"level": 100,
|
||||
"level": 99,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -1427,7 +1427,7 @@
|
|||
]
|
||||
},
|
||||
"mantine": {
|
||||
"level": 89,
|
||||
"level": 90,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -1529,7 +1529,7 @@
|
|||
]
|
||||
},
|
||||
"hitmontop": {
|
||||
"level": 86,
|
||||
"level": 85,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -2319,7 +2319,7 @@
|
|||
]
|
||||
},
|
||||
"cradily": {
|
||||
"level": 88,
|
||||
"level": 87,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -2734,7 +2734,7 @@
|
|||
]
|
||||
},
|
||||
"torterra": {
|
||||
"level": 86,
|
||||
"level": 85,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -2852,7 +2852,7 @@
|
|||
]
|
||||
},
|
||||
"rampardos": {
|
||||
"level": 87,
|
||||
"level": 86,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -2944,7 +2944,7 @@
|
|||
]
|
||||
},
|
||||
"floatzel": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -3268,7 +3268,7 @@
|
|||
]
|
||||
},
|
||||
"tangrowth": {
|
||||
"level": 89,
|
||||
"level": 90,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -3499,7 +3499,7 @@
|
|||
]
|
||||
},
|
||||
"rotomfrost": {
|
||||
"level": 79,
|
||||
"level": 78,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -3695,7 +3695,7 @@
|
|||
]
|
||||
},
|
||||
"manaphy": {
|
||||
"level": 75,
|
||||
"level": 76,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@
|
|||
]
|
||||
},
|
||||
"fearow": {
|
||||
"level": 89,
|
||||
"level": 88,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -393,7 +393,7 @@
|
|||
]
|
||||
},
|
||||
"machamp": {
|
||||
"level": 82,
|
||||
"level": 81,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -606,7 +606,7 @@
|
|||
]
|
||||
},
|
||||
"hitmonlee": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -799,7 +799,7 @@
|
|||
]
|
||||
},
|
||||
"ditto": {
|
||||
"level": 87,
|
||||
"level": 88,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Support",
|
||||
|
|
@ -950,7 +950,7 @@
|
|||
]
|
||||
},
|
||||
"dragonair": {
|
||||
"level": 86,
|
||||
"level": 85,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -1078,7 +1078,7 @@
|
|||
]
|
||||
},
|
||||
"ariados": {
|
||||
"level": 98,
|
||||
"level": 99,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -1256,7 +1256,7 @@
|
|||
]
|
||||
},
|
||||
"murkrow": {
|
||||
"level": 88,
|
||||
"level": 89,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -1576,7 +1576,7 @@
|
|||
]
|
||||
},
|
||||
"smeargle": {
|
||||
"level": 88,
|
||||
"level": 89,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Support",
|
||||
|
|
@ -1596,7 +1596,7 @@
|
|||
]
|
||||
},
|
||||
"miltank": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -1951,7 +1951,7 @@
|
|||
]
|
||||
},
|
||||
"shedinja": {
|
||||
"level": 95,
|
||||
"level": 96,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -2163,7 +2163,7 @@
|
|||
]
|
||||
},
|
||||
"camerupt": {
|
||||
"level": 88,
|
||||
"level": 89,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -2394,7 +2394,7 @@
|
|||
]
|
||||
},
|
||||
"kecleon": {
|
||||
"level": 95,
|
||||
"level": 96,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -2434,7 +2434,7 @@
|
|||
]
|
||||
},
|
||||
"chimecho": {
|
||||
"level": 95,
|
||||
"level": 96,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -2920,7 +2920,7 @@
|
|||
]
|
||||
},
|
||||
"wormadamsandy": {
|
||||
"level": 92,
|
||||
"level": 91,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Staller",
|
||||
|
|
@ -3062,7 +3062,7 @@
|
|||
{
|
||||
"role": "Wallbreaker",
|
||||
"movepool": ["hiddenpowerfighting", "shadowball", "thunderbolt", "trick"],
|
||||
"abilities": ["Levitate"]
|
||||
"abilities": ["Levitate"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -3433,7 +3433,7 @@
|
|||
]
|
||||
},
|
||||
"porygonz": {
|
||||
"level": 81,
|
||||
"level": 80,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -3529,7 +3529,7 @@
|
|||
]
|
||||
},
|
||||
"rotomfan": {
|
||||
"level": 83,
|
||||
"level": 84,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -3723,7 +3723,7 @@
|
|||
]
|
||||
},
|
||||
"shaymin": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Support",
|
||||
|
|
@ -4007,7 +4007,7 @@
|
|||
]
|
||||
},
|
||||
"samurott": {
|
||||
"level": 86,
|
||||
"level": 87,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -4129,7 +4129,7 @@
|
|||
]
|
||||
},
|
||||
"zebstrika": {
|
||||
"level": 86,
|
||||
"level": 85,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -4387,7 +4387,7 @@
|
|||
]
|
||||
},
|
||||
"cofagrigus": {
|
||||
"level": 87,
|
||||
"level": 86,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -4412,7 +4412,7 @@
|
|||
]
|
||||
},
|
||||
"archeops": {
|
||||
"level": 78,
|
||||
"level": 77,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -4463,7 +4463,7 @@
|
|||
]
|
||||
},
|
||||
"reuniclus": {
|
||||
"level": 83,
|
||||
"level": 84,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -4473,7 +4473,7 @@
|
|||
]
|
||||
},
|
||||
"swanna": {
|
||||
"level": 86,
|
||||
"level": 85,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -4499,7 +4499,7 @@
|
|||
]
|
||||
},
|
||||
"sawsbuck": {
|
||||
"level": 85,
|
||||
"level": 84,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -4647,7 +4647,7 @@
|
|||
]
|
||||
},
|
||||
"haxorus": {
|
||||
"level": 74,
|
||||
"level": 75,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -4657,7 +4657,7 @@
|
|||
]
|
||||
},
|
||||
"beartic": {
|
||||
"level": 92,
|
||||
"level": 93,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -4875,7 +4875,7 @@
|
|||
]
|
||||
},
|
||||
"tornadus": {
|
||||
"level": 79,
|
||||
"level": 78,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -4915,7 +4915,7 @@
|
|||
]
|
||||
},
|
||||
"thundurustherian": {
|
||||
"level": 77,
|
||||
"level": 76,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
]
|
||||
},
|
||||
"charizard": {
|
||||
"level": 83,
|
||||
"level": 84,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -224,7 +224,7 @@
|
|||
]
|
||||
},
|
||||
"nidoking": {
|
||||
"level": 82,
|
||||
"level": 81,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -297,7 +297,7 @@
|
|||
]
|
||||
},
|
||||
"venomoth": {
|
||||
"level": 84,
|
||||
"level": 83,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -630,7 +630,7 @@
|
|||
]
|
||||
},
|
||||
"electrode": {
|
||||
"level": 88,
|
||||
"level": 87,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -834,7 +834,7 @@
|
|||
]
|
||||
},
|
||||
"pinsir": {
|
||||
"level": 85,
|
||||
"level": 84,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -2530,7 +2530,7 @@
|
|||
]
|
||||
},
|
||||
"altariamega": {
|
||||
"level": 78,
|
||||
"level": 77,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -2899,7 +2899,7 @@
|
|||
]
|
||||
},
|
||||
"regirock": {
|
||||
"level": 86,
|
||||
"level": 85,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -3020,7 +3020,7 @@
|
|||
]
|
||||
},
|
||||
"groudon": {
|
||||
"level": 74,
|
||||
"level": 73,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -3121,7 +3121,7 @@
|
|||
]
|
||||
},
|
||||
"deoxysdefense": {
|
||||
"level": 84,
|
||||
"level": 83,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -3323,7 +3323,7 @@
|
|||
]
|
||||
},
|
||||
"mothim": {
|
||||
"level": 94,
|
||||
"level": 95,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -3395,7 +3395,7 @@
|
|||
]
|
||||
},
|
||||
"ambipom": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -3519,7 +3519,7 @@
|
|||
]
|
||||
},
|
||||
"spiritomb": {
|
||||
"level": 88,
|
||||
"level": 87,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -3549,7 +3549,7 @@
|
|||
]
|
||||
},
|
||||
"garchompmega": {
|
||||
"level": 76,
|
||||
"level": 75,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -3735,7 +3735,7 @@
|
|||
]
|
||||
},
|
||||
"tangrowth": {
|
||||
"level": 88,
|
||||
"level": 87,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -3792,7 +3792,7 @@
|
|||
]
|
||||
},
|
||||
"yanmega": {
|
||||
"level": 82,
|
||||
"level": 81,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -4130,7 +4130,7 @@
|
|||
]
|
||||
},
|
||||
"cresselia": {
|
||||
"level": 80,
|
||||
"level": 79,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -4155,7 +4155,7 @@
|
|||
]
|
||||
},
|
||||
"manaphy": {
|
||||
"level": 76,
|
||||
"level": 77,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -4641,7 +4641,7 @@
|
|||
]
|
||||
},
|
||||
"audino": {
|
||||
"level": 90,
|
||||
"level": 91,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -5127,7 +5127,7 @@
|
|||
]
|
||||
},
|
||||
"haxorus": {
|
||||
"level": 77,
|
||||
"level": 76,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -5618,7 +5618,7 @@
|
|||
]
|
||||
},
|
||||
"talonflame": {
|
||||
"level": 79,
|
||||
"level": 78,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
import RandomGen6Teams from '../gen6/teams';
|
||||
|
||||
export class RandomMRTeams extends RandomGen6Teams {
|
||||
override randomSets: { [species: string]: RandomTeamsTypes.RandomSpeciesData } = require('./sets.json');
|
||||
}
|
||||
|
||||
export default RandomMRTeams;
|
||||
|
|
@ -455,7 +455,7 @@
|
|||
]
|
||||
},
|
||||
"golduck": {
|
||||
"level": 93,
|
||||
"level": 92,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -467,7 +467,7 @@
|
|||
"role": "Fast Attacker",
|
||||
"movepool": ["calmmind", "encore", "focusblast", "hydropump", "icebeam"],
|
||||
"abilities": ["Cloud Nine", "Swift Swim"],
|
||||
"preferredTypes": ["Ice"]
|
||||
"preferredTypes": ["Ice"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -535,7 +535,7 @@
|
|||
]
|
||||
},
|
||||
"alakazammega": {
|
||||
"level": 78,
|
||||
"level": 77,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -778,7 +778,7 @@
|
|||
]
|
||||
},
|
||||
"kingler": {
|
||||
"level": 87,
|
||||
"level": 88,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -831,7 +831,7 @@
|
|||
]
|
||||
},
|
||||
"marowak": {
|
||||
"level": 88,
|
||||
"level": 89,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Wallbreaker",
|
||||
|
|
@ -1018,7 +1018,7 @@
|
|||
]
|
||||
},
|
||||
"pinsir": {
|
||||
"level": 84,
|
||||
"level": 85,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -1029,7 +1029,7 @@
|
|||
]
|
||||
},
|
||||
"pinsirmega": {
|
||||
"level": 74,
|
||||
"level": 73,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -1177,7 +1177,7 @@
|
|||
]
|
||||
},
|
||||
"aerodactyl": {
|
||||
"level": 82,
|
||||
"level": 81,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -1608,7 +1608,7 @@
|
|||
]
|
||||
},
|
||||
"wobbuffet": {
|
||||
"level": 94,
|
||||
"level": 95,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -2216,7 +2216,7 @@
|
|||
]
|
||||
},
|
||||
"beautifly": {
|
||||
"level": 99,
|
||||
"level": 98,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -2410,7 +2410,7 @@
|
|||
]
|
||||
},
|
||||
"shedinja": {
|
||||
"level": 96,
|
||||
"level": 97,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -2477,7 +2477,7 @@
|
|||
]
|
||||
},
|
||||
"mawile": {
|
||||
"level": 89,
|
||||
"level": 90,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -2513,7 +2513,7 @@
|
|||
]
|
||||
},
|
||||
"aggronmega": {
|
||||
"level": 81,
|
||||
"level": 80,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -2621,7 +2621,7 @@
|
|||
]
|
||||
},
|
||||
"swalot": {
|
||||
"level": 90,
|
||||
"level": 91,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -2667,7 +2667,7 @@
|
|||
]
|
||||
},
|
||||
"camerupt": {
|
||||
"level": 90,
|
||||
"level": 91,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -3001,7 +3001,7 @@
|
|||
]
|
||||
},
|
||||
"absolmega": {
|
||||
"level": 82,
|
||||
"level": 81,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -3554,7 +3554,7 @@
|
|||
]
|
||||
},
|
||||
"bastiodon": {
|
||||
"level": 94,
|
||||
"level": 93,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -4295,7 +4295,7 @@
|
|||
]
|
||||
},
|
||||
"rotomfrost": {
|
||||
"level": 86,
|
||||
"level": 85,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -5635,7 +5635,7 @@
|
|||
]
|
||||
},
|
||||
"bisharp": {
|
||||
"level": 82,
|
||||
"level": 81,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -5858,7 +5858,7 @@
|
|||
]
|
||||
},
|
||||
"zekrom": {
|
||||
"level": 74,
|
||||
"level": 75,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Setup Sweeper",
|
||||
|
|
@ -5918,7 +5918,7 @@
|
|||
]
|
||||
},
|
||||
"kyurem": {
|
||||
"level": 80,
|
||||
"level": 79,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Staller",
|
||||
|
|
@ -6186,7 +6186,7 @@
|
|||
]
|
||||
},
|
||||
"furfrou": {
|
||||
"level": 86,
|
||||
"level": 87,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -6339,7 +6339,7 @@
|
|||
]
|
||||
},
|
||||
"tyrantrum": {
|
||||
"level": 81,
|
||||
"level": 80,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -6741,7 +6741,7 @@
|
|||
]
|
||||
},
|
||||
"oricoriopompom": {
|
||||
"level": 87,
|
||||
"level": 86,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -6965,7 +6965,7 @@
|
|||
]
|
||||
},
|
||||
"comfey": {
|
||||
"level": 87,
|
||||
"level": 88,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ export class RandomGen7Teams extends RandomGen8Teams {
|
|||
if (move.priority > 0) counter.add('priority');
|
||||
}
|
||||
// Moves with secondary effects:
|
||||
if (move.secondary || move.hasSheerForce) {
|
||||
if (move.secondary || move.hasSheerForceBoost) {
|
||||
counter.add('sheerforce');
|
||||
if (sereneGraceBenefits(move)) {
|
||||
counter.add('serenegrace');
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@
|
|||
"doublesMoves": ["closecombat", "fakeout", "knockoff", "poisonjab", "protect", "rockslide"]
|
||||
},
|
||||
"hitmonchan": {
|
||||
"level": 88,
|
||||
"level": 87,
|
||||
"moves": ["bulkup", "drainpunch", "icepunch", "machpunch", "rapidspin", "throatchop"],
|
||||
"doublesLevel": 88,
|
||||
"doublesMoves": ["coaching", "drainpunch", "feint", "firepunch", "icepunch", "machpunch"]
|
||||
|
|
@ -319,7 +319,7 @@
|
|||
"doublesMoves": ["dazzlinggleam", "fakeout", "icywind", "lightscreen", "psychic", "reflect"]
|
||||
},
|
||||
"mrmimegalar": {
|
||||
"level": 84,
|
||||
"level": 83,
|
||||
"moves": ["focusblast", "freezedry", "nastyplot", "psychic", "rapidspin"]
|
||||
},
|
||||
"scyther": {
|
||||
|
|
@ -353,7 +353,7 @@
|
|||
"doublesMoves": ["bounce", "dragondance", "icefang", "powerwhip", "protect", "waterfall"]
|
||||
},
|
||||
"laprasgmax": {
|
||||
"level": 85,
|
||||
"level": 84,
|
||||
"moves": ["freezedry", "icebeam", "protect", "sparklingaria", "thunderbolt", "toxic"],
|
||||
"doublesLevel": 84,
|
||||
"doublesMoves": ["freezedry", "helpinghand", "hydropump", "icywind", "protect", "thunderbolt"]
|
||||
|
|
@ -430,13 +430,13 @@
|
|||
"doublesMoves": ["heatwave", "hurricane", "roost", "tailwind", "thunderbolt", "voltswitch"]
|
||||
},
|
||||
"zapdosgalar": {
|
||||
"level": 74,
|
||||
"level": 73,
|
||||
"moves": ["bravebird", "bulkup", "closecombat", "throatchop", "uturn"],
|
||||
"doublesLevel": 76,
|
||||
"doublesMoves": ["bravebird", "bulkup", "closecombat", "throatchop", "thunderouskick", "uturn"]
|
||||
},
|
||||
"moltres": {
|
||||
"level": 79,
|
||||
"level": 78,
|
||||
"moves": ["airslash", "defog", "fireblast", "roost", "uturn"],
|
||||
"doublesLevel": 81,
|
||||
"doublesMoves": ["bravebird", "fireblast", "heatwave", "protect", "roost", "tailwind"],
|
||||
|
|
@ -457,7 +457,7 @@
|
|||
"noDynamaxMoves": ["dragondance", "dualwingbeat", "earthquake", "outrage", "roost"]
|
||||
},
|
||||
"mewtwo": {
|
||||
"level": 71,
|
||||
"level": 72,
|
||||
"moves": ["aurasphere", "fireblast", "nastyplot", "psystrike", "recover"],
|
||||
"doublesLevel": 74,
|
||||
"doublesMoves": ["aurasphere", "icebeam", "nastyplot", "psystrike", "recover"]
|
||||
|
|
@ -531,7 +531,7 @@
|
|||
"doublesMoves": ["calmmind", "dazzlinggleam", "morningsun", "protect", "psychic", "shadowball"]
|
||||
},
|
||||
"umbreon": {
|
||||
"level": 82,
|
||||
"level": 81,
|
||||
"moves": ["foulplay", "protect", "toxic", "wish"],
|
||||
"doublesLevel": 88,
|
||||
"doublesMoves": ["foulplay", "helpinghand", "moonlight", "protect", "snarl", "toxic"]
|
||||
|
|
@ -556,7 +556,7 @@
|
|||
"noDynamaxMoves": ["counter", "destinybond", "encore", "mirrorcoat"]
|
||||
},
|
||||
"dunsparce": {
|
||||
"level": 90,
|
||||
"level": 91,
|
||||
"moves": ["bodyslam", "coil", "earthquake", "roost"],
|
||||
"doublesLevel": 90,
|
||||
"doublesMoves": ["glare", "headbutt", "protect", "rockslide"]
|
||||
|
|
@ -647,7 +647,7 @@
|
|||
"doublesMoves": ["closecombat", "coaching", "fakeout", "helpinghand", "rapidspin", "suckerpunch", "tripleaxel"]
|
||||
},
|
||||
"miltank": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"moves": ["bodyslam", "earthquake", "healbell", "milkdrink", "stealthrock", "toxic"],
|
||||
"doublesLevel": 86,
|
||||
"doublesMoves": ["bodypress", "bodyslam", "helpinghand", "icywind", "milkdrink", "protect", "rockslide"]
|
||||
|
|
@ -659,7 +659,7 @@
|
|||
"doublesMoves": ["allyswitch", "healpulse", "helpinghand", "protect", "seismictoss", "softboiled", "thunderwave", "toxic"]
|
||||
},
|
||||
"raikou": {
|
||||
"level": 79,
|
||||
"level": 80,
|
||||
"moves": ["aurasphere", "calmmind", "scald", "substitute", "thunderbolt", "voltswitch"],
|
||||
"doublesLevel": 82,
|
||||
"doublesMoves": ["aurasphere", "calmmind", "protect", "scald", "snarl", "thunderbolt", "voltswitch"]
|
||||
|
|
@ -739,7 +739,7 @@
|
|||
"noDynamaxMoves": ["defog", "knockoff", "leafblade", "lowkick", "rockslide", "suckerpunch", "swordsdance"]
|
||||
},
|
||||
"pelipper": {
|
||||
"level": 87,
|
||||
"level": 86,
|
||||
"moves": ["defog", "hurricane", "hydropump", "roost", "scald", "uturn"],
|
||||
"doublesLevel": 83,
|
||||
"doublesMoves": ["hurricane", "hydropump", "protect", "roost", "tailwind", "wideguard"]
|
||||
|
|
@ -879,7 +879,7 @@
|
|||
"doublesMoves": ["closecombat", "knockoff", "protect", "suckerpunch", "swordsdance"]
|
||||
},
|
||||
"glalie": {
|
||||
"level": 96,
|
||||
"level": 95,
|
||||
"moves": ["earthquake", "freezedry", "spikes", "superfang", "taunt"],
|
||||
"doublesLevel": 94,
|
||||
"doublesMoves": ["disable", "foulplay", "freezedry", "helpinghand", "icywind", "protect"]
|
||||
|
|
@ -971,7 +971,7 @@
|
|||
"doublesMoves": ["playrough", "protect", "superpower", "voltswitch", "wildcharge"]
|
||||
},
|
||||
"roserade": {
|
||||
"level": 84,
|
||||
"level": 83,
|
||||
"moves": ["leafstorm", "sleeppowder", "sludgebomb", "spikes", "synthesis", "toxicspikes"],
|
||||
"doublesLevel": 86,
|
||||
"doublesMoves": ["energyball", "leafstorm", "protect", "sleeppowder", "sludgebomb"]
|
||||
|
|
@ -1005,7 +1005,7 @@
|
|||
"doublesMoves": ["calmmind", "icywind", "shadowball", "strengthsap"]
|
||||
},
|
||||
"lopunny": {
|
||||
"level": 95,
|
||||
"level": 96,
|
||||
"moves": ["closecombat", "facade", "healingwish", "switcheroo"],
|
||||
"doublesLevel": 92,
|
||||
"doublesMoves": ["closecombat", "fakeout", "switcheroo", "uturn"]
|
||||
|
|
@ -1077,13 +1077,13 @@
|
|||
"doublesMoves": ["bodypress", "electroweb", "flashcannon", "protect", "thunderbolt", "voltswitch"]
|
||||
},
|
||||
"lickilicky": {
|
||||
"level": 86,
|
||||
"level": 87,
|
||||
"moves": ["bodyslam", "earthquake", "explosion", "healbell", "knockoff", "protect", "swordsdance", "wish"],
|
||||
"doublesLevel": 88,
|
||||
"doublesMoves": ["bodyslam", "explosion", "helpinghand", "icywind", "knockoff"]
|
||||
},
|
||||
"rhyperior": {
|
||||
"level": 79,
|
||||
"level": 80,
|
||||
"moves": ["earthquake", "firepunch", "megahorn", "rockpolish", "stoneedge"],
|
||||
"doublesLevel": 84,
|
||||
"doublesMoves": ["highhorsepower", "icepunch", "megahorn", "protect", "rockslide", "stoneedge"]
|
||||
|
|
@ -1095,7 +1095,7 @@
|
|||
"doublesMoves": ["focusblast", "knockoff", "powerwhip", "ragepowder", "sleeppowder"]
|
||||
},
|
||||
"electivire": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"moves": ["crosschop", "earthquake", "flamethrower", "icepunch", "voltswitch", "wildcharge"],
|
||||
"doublesLevel": 88,
|
||||
"doublesMoves": ["crosschop", "flamethrower", "icepunch", "stompingtantrum", "wildcharge"]
|
||||
|
|
@ -1228,7 +1228,7 @@
|
|||
"doublesMoves": ["earthpower", "eruption", "flashcannon", "heatwave", "protect"]
|
||||
},
|
||||
"regigigas": {
|
||||
"level": 82,
|
||||
"level": 83,
|
||||
"moves": ["bodyslam", "protect", "substitute", "toxic"],
|
||||
"doublesLevel": 86,
|
||||
"doublesMoves": ["bodyslam", "knockoff", "protect", "thunderwave"]
|
||||
|
|
@ -1265,7 +1265,7 @@
|
|||
"doublesMoves": ["facade", "helpinghand", "superpower", "thunderwave"]
|
||||
},
|
||||
"liepard": {
|
||||
"level": 91,
|
||||
"level": 92,
|
||||
"moves": ["copycat", "encore", "knockoff", "playrough", "thunderwave", "uturn"],
|
||||
"doublesLevel": 88,
|
||||
"doublesMoves": ["copycat", "encore", "fakeout", "foulplay", "snarl", "taunt", "thunderwave"]
|
||||
|
|
@ -1388,7 +1388,7 @@
|
|||
"doublesMoves": ["acupressure", "helpinghand", "leafstorm", "leechseed", "spikyshield"]
|
||||
},
|
||||
"crustle": {
|
||||
"level": 81,
|
||||
"level": 82,
|
||||
"moves": ["earthquake", "shellsmash", "stoneedge", "xscissor"],
|
||||
"doublesLevel": 84,
|
||||
"doublesMoves": ["knockoff", "protect", "rockslide", "shellsmash", "xscissor"]
|
||||
|
|
@ -1454,7 +1454,7 @@
|
|||
"doublesMoves": ["focusblast", "protect", "psychic", "shadowball", "trickroom"]
|
||||
},
|
||||
"vanilluxe": {
|
||||
"level": 82,
|
||||
"level": 81,
|
||||
"moves": ["auroraveil", "blizzard", "explosion", "flashcannon", "freezedry"],
|
||||
"doublesLevel": 82,
|
||||
"doublesMoves": ["auroraveil", "blizzard", "explosion", "freezedry", "protect"]
|
||||
|
|
@ -1466,7 +1466,7 @@
|
|||
"doublesMoves": ["acrobatics", "helpinghand", "nuzzle", "tailwind", "taunt", "voltswitch"]
|
||||
},
|
||||
"escavalier": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"moves": ["closecombat", "drillrun", "ironhead", "knockoff", "megahorn", "swordsdance"],
|
||||
"doublesLevel": 86,
|
||||
"doublesMoves": ["closecombat", "drillrun", "ironhead", "knockoff", "megahorn", "protect", "swordsdance"]
|
||||
|
|
@ -1478,7 +1478,7 @@
|
|||
"doublesMoves": ["clearsmog", "pollenpuff", "protect", "ragepowder", "spore"]
|
||||
},
|
||||
"jellicent": {
|
||||
"level": 86,
|
||||
"level": 87,
|
||||
"moves": ["icebeam", "recover", "scald", "shadowball", "toxic", "willowisp"],
|
||||
"doublesLevel": 84,
|
||||
"doublesMoves": ["scald", "shadowball", "strengthsap", "trickroom", "willowisp"]
|
||||
|
|
@ -1539,7 +1539,7 @@
|
|||
"noDynamaxMoves": ["bugbuzz", "encore", "energyball", "focusblast", "spikes", "toxic"]
|
||||
},
|
||||
"stunfisk": {
|
||||
"level": 83,
|
||||
"level": 84,
|
||||
"moves": ["discharge", "earthpower", "foulplay", "sludgebomb", "stealthrock"],
|
||||
"doublesLevel": 88,
|
||||
"doublesMoves": ["earthpower", "electroweb", "foulplay", "stealthrock", "thunderbolt"]
|
||||
|
|
@ -1563,7 +1563,7 @@
|
|||
"doublesMoves": ["dragonclaw", "firepunch", "glare", "gunkshot", "protect", "suckerpunch"]
|
||||
},
|
||||
"golurk": {
|
||||
"level": 82,
|
||||
"level": 83,
|
||||
"moves": ["dynamicpunch", "earthquake", "poltergeist", "rockpolish", "stoneedge"],
|
||||
"doublesLevel": 86,
|
||||
"doublesMoves": ["dynamicpunch", "highhorsepower", "icepunch", "poltergeist", "protect"]
|
||||
|
|
@ -1813,7 +1813,7 @@
|
|||
"doublesMoves": ["closecombat", "dragonclaw", "dragondance", "headsmash", "highhorsepower"]
|
||||
},
|
||||
"aurorus": {
|
||||
"level": 84,
|
||||
"level": 85,
|
||||
"moves": ["ancientpower", "blizzard", "earthpower", "freezedry", "stealthrock", "thunderwave"],
|
||||
"doublesLevel": 88,
|
||||
"doublesMoves": ["auroraveil", "blizzard", "earthpower", "freezedry", "protect", "thunderwave"]
|
||||
|
|
@ -1825,7 +1825,7 @@
|
|||
"doublesMoves": ["calmmind", "hypervoice", "mysticalfire", "protect", "psyshock"]
|
||||
},
|
||||
"hawlucha": {
|
||||
"level": 78,
|
||||
"level": 79,
|
||||
"moves": ["bravebird", "closecombat", "roost", "stoneedge", "swordsdance", "throatchop"],
|
||||
"doublesLevel": 80,
|
||||
"doublesMoves": ["bravebird", "closecombat", "protect", "swordsdance"]
|
||||
|
|
@ -1867,7 +1867,7 @@
|
|||
"doublesMoves": ["leechseed", "poltergeist", "powerwhip", "substitute", "willowisp"]
|
||||
},
|
||||
"gourgeistsmall": {
|
||||
"level": 82,
|
||||
"level": 83,
|
||||
"moves": ["leechseed", "poltergeist", "powerwhip", "substitute", "willowisp"],
|
||||
"doublesLevel": 88,
|
||||
"doublesMoves": ["leechseed", "poltergeist", "powerwhip", "substitute", "willowisp"]
|
||||
|
|
@ -1897,7 +1897,7 @@
|
|||
"doublesMoves": ["boomburst", "dracometeor", "flamethrower", "hurricane", "protect", "tailwind"]
|
||||
},
|
||||
"xerneas": {
|
||||
"level": 65,
|
||||
"level": 64,
|
||||
"moves": ["focusblast", "geomancy", "moonblast", "psyshock"],
|
||||
"doublesLevel": 70,
|
||||
"doublesMoves": ["dazzlinggleam", "focusblast", "geomancy", "moonblast", "thunderbolt"]
|
||||
|
|
@ -1946,7 +1946,7 @@
|
|||
"doublesMoves": ["fakeout", "flareblitz", "knockoff", "partingshot", "uturn"]
|
||||
},
|
||||
"primarina": {
|
||||
"level": 80,
|
||||
"level": 81,
|
||||
"moves": ["energyball", "hydropump", "moonblast", "psychic", "scald"],
|
||||
"doublesLevel": 82,
|
||||
"doublesMoves": ["dazzlinggleam", "flipturn", "hypervoice", "moonblast", "protect", "psychic"]
|
||||
|
|
@ -2066,7 +2066,7 @@
|
|||
"doublesMoves": ["hypnosis", "protect", "scorchingsands", "shadowball", "shoreup", "stealthrock"]
|
||||
},
|
||||
"pyukumuku": {
|
||||
"level": 86,
|
||||
"level": 85,
|
||||
"moves": ["counter", "mirrorcoat", "recover", "toxic"],
|
||||
"doublesLevel": 100,
|
||||
"doublesMoves": ["helpinghand", "lightscreen", "memento", "reflect"]
|
||||
|
|
@ -2214,7 +2214,7 @@
|
|||
"doublesMoves": ["anchorshot", "knockoff", "powerwhip", "protect"]
|
||||
},
|
||||
"kommoo": {
|
||||
"level": 80,
|
||||
"level": 81,
|
||||
"moves": ["clangingscales", "clangoroussoul", "closecombat", "poisonjab", "stealthrock"],
|
||||
"doublesLevel": 80,
|
||||
"doublesMoves": ["bodypress", "dracometeor", "irondefense", "protect"]
|
||||
|
|
@ -2318,7 +2318,7 @@
|
|||
"doublesMoves": ["heatwave", "moongeistbeam", "photongeyser", "protect", "thunderwave"]
|
||||
},
|
||||
"magearna": {
|
||||
"level": 73,
|
||||
"level": 72,
|
||||
"moves": ["agility", "calmmind", "flashcannon", "fleurcannon"],
|
||||
"doublesLevel": 72,
|
||||
"doublesMoves": ["agility", "aurasphere", "dazzlinggleam", "flashcannon", "fleurcannon", "protect", "trick"]
|
||||
|
|
@ -2355,7 +2355,7 @@
|
|||
"doublesMoves": ["closecombat", "fakeout", "grassknot", "knockoff", "plasmafists", "snarl"]
|
||||
},
|
||||
"melmetal": {
|
||||
"level": 73,
|
||||
"level": 72,
|
||||
"moves": ["doubleironbash", "earthquake", "superpower", "thunderpunch", "thunderwave"],
|
||||
"doublesLevel": 76,
|
||||
"doublesMoves": ["acidarmor", "bodypress", "doubleironbash", "protect", "thunderpunch", "thunderwave"]
|
||||
|
|
@ -2480,7 +2480,7 @@
|
|||
"doublesMoves": ["bravebird", "icebeam", "protect", "roost", "surf", "tailwind"]
|
||||
},
|
||||
"barraskewda": {
|
||||
"level": 80,
|
||||
"level": 79,
|
||||
"moves": ["closecombat", "crunch", "flipturn", "liquidation"],
|
||||
"doublesLevel": 84,
|
||||
"doublesMoves": ["closecombat", "drillrun", "flipturn", "liquidation", "poisonjab"]
|
||||
|
|
@ -2654,13 +2654,13 @@
|
|||
"doublesMoves": ["blizzard", "boltbeak", "iciclecrash", "lowkick", "protect"]
|
||||
},
|
||||
"dracovish": {
|
||||
"level": 77,
|
||||
"level": 78,
|
||||
"moves": ["crunch", "fishiousrend", "icefang", "lowkick", "psychicfangs"],
|
||||
"doublesLevel": 78,
|
||||
"doublesMoves": ["crunch", "dragonrush", "fishiousrend", "icefang", "psychicfangs"]
|
||||
},
|
||||
"arctovish": {
|
||||
"level": 87,
|
||||
"level": 88,
|
||||
"moves": ["bodyslam", "fishiousrend", "freezedry", "iciclecrash", "psychicfangs"],
|
||||
"doublesLevel": 88,
|
||||
"doublesMoves": ["blizzard", "fishiousrend", "iciclecrash", "protect", "superfang"]
|
||||
|
|
@ -2678,25 +2678,25 @@
|
|||
"doublesMoves": ["dragondarts", "fireblast", "protect", "shadowball", "thunderbolt", "thunderwave"]
|
||||
},
|
||||
"zacian": {
|
||||
"level": 66,
|
||||
"level": 67,
|
||||
"moves": ["closecombat", "crunch", "playrough", "psychicfangs", "swordsdance"],
|
||||
"doublesLevel": 72,
|
||||
"doublesMoves": ["closecombat", "crunch", "playrough", "protect", "psychicfangs", "swordsdance"]
|
||||
},
|
||||
"zaciancrowned": {
|
||||
"level": 61,
|
||||
"level": 62,
|
||||
"moves": ["behemothblade", "closecombat", "playrough", "psychicfangs", "swordsdance"],
|
||||
"doublesLevel": 65,
|
||||
"doublesMoves": ["behemothblade", "closecombat", "playrough", "protect", "psychicfangs", "swordsdance"]
|
||||
},
|
||||
"zamazenta": {
|
||||
"level": 69,
|
||||
"level": 70,
|
||||
"moves": ["closecombat", "crunch", "psychicfangs", "wildcharge"],
|
||||
"doublesLevel": 74,
|
||||
"doublesMoves": ["closecombat", "crunch", "playrough", "protect", "psychicfangs"]
|
||||
},
|
||||
"zamazentacrowned": {
|
||||
"level": 68,
|
||||
"level": 67,
|
||||
"moves": ["behemothbash", "closecombat", "crunch", "howl", "psychicfangs"],
|
||||
"doublesLevel": 72,
|
||||
"doublesMoves": ["behemothbash", "closecombat", "crunch", "howl", "protect"]
|
||||
|
|
@ -2734,7 +2734,7 @@
|
|||
"doublesMoves": ["closecombat", "darkestlariat", "junglehealing", "powerwhip", "protect"]
|
||||
},
|
||||
"regieleki": {
|
||||
"level": 78,
|
||||
"level": 77,
|
||||
"moves": ["explosion", "substitute", "thunderbolt", "voltswitch"],
|
||||
"doublesLevel": 82,
|
||||
"doublesMoves": ["electroweb", "extremespeed", "protect", "thundercage", "voltswitch"],
|
||||
|
|
@ -2759,7 +2759,7 @@
|
|||
"doublesMoves": ["darkpulse", "nastyplot", "protect", "shadowball"]
|
||||
},
|
||||
"calyrex": {
|
||||
"level": 88,
|
||||
"level": 89,
|
||||
"moves": ["calmmind", "gigadrain", "leechseed", "psyshock", "substitute"],
|
||||
"doublesLevel": 94,
|
||||
"doublesMoves": ["helpinghand", "leafstorm", "pollenpuff", "protect"]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"venusaur": {
|
||||
"level": 86,
|
||||
"level": 87,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Offensive Protect",
|
||||
|
|
@ -609,7 +609,7 @@
|
|||
]
|
||||
},
|
||||
"weezinggalar": {
|
||||
"level": 88,
|
||||
"level": 89,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Bulky Attacker",
|
||||
|
|
@ -907,7 +907,7 @@
|
|||
"role": "Doubles Bulky Attacker",
|
||||
"movepool": ["Brave Bird", "Fire Blast", "Heat Wave", "Scorching Sands", "Tailwind"],
|
||||
"abilities": ["Flame Body"],
|
||||
"teraTypes": ["Ground"]
|
||||
"teraTypes": ["Ground"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -1674,7 +1674,7 @@
|
|||
]
|
||||
},
|
||||
"shiftry": {
|
||||
"level": 84,
|
||||
"level": 83,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Wallbreaker",
|
||||
|
|
@ -1702,7 +1702,7 @@
|
|||
]
|
||||
},
|
||||
"gardevoir": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Choice Item user",
|
||||
|
|
@ -1736,7 +1736,7 @@
|
|||
]
|
||||
},
|
||||
"breloom": {
|
||||
"level": 84,
|
||||
"level": 83,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Fast Attacker",
|
||||
|
|
@ -1960,7 +1960,7 @@
|
|||
]
|
||||
},
|
||||
"altaria": {
|
||||
"level": 91,
|
||||
"level": 90,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Bulky Attacker",
|
||||
|
|
@ -2055,7 +2055,7 @@
|
|||
]
|
||||
},
|
||||
"tropius": {
|
||||
"level": 94,
|
||||
"level": 93,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Support",
|
||||
|
|
@ -2664,7 +2664,7 @@
|
|||
]
|
||||
},
|
||||
"sneasler": {
|
||||
"level": 77,
|
||||
"level": 76,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Wallbreaker",
|
||||
|
|
@ -3229,7 +3229,7 @@
|
|||
]
|
||||
},
|
||||
"arceusdragon": {
|
||||
"level": 73,
|
||||
"level": 72,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Setup Sweeper",
|
||||
|
|
@ -3313,7 +3313,7 @@
|
|||
]
|
||||
},
|
||||
"arceusghost": {
|
||||
"level": 72,
|
||||
"level": 71,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Bulky Setup",
|
||||
|
|
@ -4048,7 +4048,7 @@
|
|||
]
|
||||
},
|
||||
"tornadustherian": {
|
||||
"level": 77,
|
||||
"level": 78,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Setup Sweeper",
|
||||
|
|
@ -4292,7 +4292,7 @@
|
|||
"abilities": ["Compound Eyes"],
|
||||
"teraTypes": ["Flying", "Steel"]
|
||||
},
|
||||
{
|
||||
{
|
||||
"role": "Doubles Fast Attacker",
|
||||
"movepool": ["Hurricane", "Protect", "Sleep Powder", "Tailwind"],
|
||||
"abilities": ["Compound Eyes"],
|
||||
|
|
@ -4401,7 +4401,7 @@
|
|||
]
|
||||
},
|
||||
"sylveon": {
|
||||
"level": 79,
|
||||
"level": 78,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Protect",
|
||||
|
|
@ -4663,7 +4663,7 @@
|
|||
]
|
||||
},
|
||||
"gumshoos": {
|
||||
"level": 93,
|
||||
"level": 94,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Choice Item user",
|
||||
|
|
@ -4781,7 +4781,7 @@
|
|||
]
|
||||
},
|
||||
"lycanroc": {
|
||||
"level": 85,
|
||||
"level": 84,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Offensive Protect",
|
||||
|
|
@ -4959,7 +4959,7 @@
|
|||
]
|
||||
},
|
||||
"komala": {
|
||||
"level": 92,
|
||||
"level": 93,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Doubles Bulky Attacker",
|
||||
|
|
@ -5775,7 +5775,7 @@
|
|||
]
|
||||
},
|
||||
"calyrexshadow": {
|
||||
"level": 63,
|
||||
"level": 62,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Offensive Protect",
|
||||
|
|
@ -5978,7 +5978,7 @@
|
|||
"role": "Offensive Protect",
|
||||
"movepool": ["First Impression", "Knock Off", "Leech Life", "Protect"],
|
||||
"abilities": ["Tinted Lens"],
|
||||
"teraTypes": ["Bug"]
|
||||
"teraTypes": ["Bug"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -6141,7 +6141,7 @@
|
|||
"abilities": ["Competitive"],
|
||||
"teraTypes": ["Flying", "Steel"]
|
||||
},
|
||||
{
|
||||
{
|
||||
"role": "Doubles Wallbreaker",
|
||||
"movepool": ["Hurricane", "Protect", "Tailwind", "Thunderbolt"],
|
||||
"abilities": ["Competitive"],
|
||||
|
|
@ -6358,7 +6358,7 @@
|
|||
]
|
||||
},
|
||||
"orthworm": {
|
||||
"level": 88,
|
||||
"level": 89,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Protect",
|
||||
|
|
|
|||
|
|
@ -3294,7 +3294,7 @@
|
|||
]
|
||||
},
|
||||
"rotomwash": {
|
||||
"level": 83,
|
||||
"level": 82,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
@ -3812,7 +3812,7 @@
|
|||
]
|
||||
},
|
||||
"arceusice": {
|
||||
"level": 73,
|
||||
"level": 72,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -4115,7 +4115,7 @@
|
|||
]
|
||||
},
|
||||
"krookodile": {
|
||||
"level": 80,
|
||||
"level": 79,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Fast Attacker",
|
||||
|
|
@ -4132,7 +4132,7 @@
|
|||
]
|
||||
},
|
||||
"scrafty": {
|
||||
"level": 84,
|
||||
"level": 83,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Setup",
|
||||
|
|
@ -5524,7 +5524,7 @@
|
|||
]
|
||||
},
|
||||
"komala": {
|
||||
"level": 89,
|
||||
"level": 88,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -6488,7 +6488,7 @@
|
|||
"role": "Bulky Attacker",
|
||||
"movepool": ["Aqua Step", "Close Combat", "Rapid Spin", "Roost", "Swords Dance"],
|
||||
"abilities": ["Moxie"],
|
||||
"teraTypes": ["Steel"]
|
||||
"teraTypes": ["Steel"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -7072,7 +7072,7 @@
|
|||
]
|
||||
},
|
||||
"farigiraf": {
|
||||
"level": 91,
|
||||
"level": 90,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Support",
|
||||
|
|
@ -7140,7 +7140,7 @@
|
|||
]
|
||||
},
|
||||
"brutebonnet": {
|
||||
"level": 81,
|
||||
"level": 80,
|
||||
"sets": [
|
||||
{
|
||||
"role": "Bulky Attacker",
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@ export class RandomTeams {
|
|||
}
|
||||
}
|
||||
// Moves with secondary effects:
|
||||
if (move.secondary || move.hasSheerForce) {
|
||||
if (move.secondary || move.hasSheerForceBoost) {
|
||||
counter.add('sheerforce');
|
||||
if (sereneGraceBenefits(move)) {
|
||||
counter.add('serenegrace');
|
||||
|
|
|
|||
1093
data/random-battles/gen9regeneration/random-sets.json
Normal file
1093
data/random-battles/gen9regeneration/random-sets.json
Normal file
File diff suppressed because it is too large
Load Diff
1149
data/random-battles/gen9regeneration/teams.ts
Normal file
1149
data/random-battles/gen9regeneration/teams.ts
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user