mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-03-21 17:25:10 -05:00
This adds some new `data/text/` files, which are the new home for item/move/ability descriptions, as well as in-game messages, in one place for ease of translation.
19461 lines
416 KiB
TypeScript
19461 lines
416 KiB
TypeScript
/*
|
|
|
|
List of flags and their descriptions:
|
|
|
|
authentic: Ignores a target's substitute.
|
|
bite: Power is multiplied by 1.5 when used by a Pokemon with the Strong Jaw Ability.
|
|
bullet: Has no effect on Pokemon with the Bulletproof Ability.
|
|
charge: The user is unable to make a move between turns.
|
|
contact: Makes contact.
|
|
dance: When used by a Pokemon, other Pokemon with the Dancer Ability can attempt to execute the same move.
|
|
defrost: Thaws the user if executed successfully while the user is frozen.
|
|
distance: Can target a Pokemon positioned anywhere in a Triple Battle.
|
|
gravity: Prevented from being executed or selected during Gravity's effect.
|
|
heal: Prevented from being executed or selected during Heal Block's effect.
|
|
mirror: Can be copied by Mirror Move.
|
|
mystery: Unknown effect.
|
|
nonsky: Prevented from being executed or selected in a Sky Battle.
|
|
powder: Has no effect on Grass-type Pokemon, Pokemon with the Overcoat Ability, and Pokemon holding Safety Goggles.
|
|
protect: Blocked by Detect, Protect, Spiky Shield, and if not a Status move, King's Shield.
|
|
pulse: Power is multiplied by 1.5 when used by a Pokemon with the Mega Launcher Ability.
|
|
punch: Power is multiplied by 1.2 when used by a Pokemon with the Iron Fist Ability.
|
|
recharge: If this move is successful, the user must recharge on the following turn and cannot make a move.
|
|
reflectable: Bounced back to the original user by Magic Coat or the Magic Bounce Ability.
|
|
snatch: Can be stolen from the original user and instead used by another Pokemon using Snatch.
|
|
sound: Has no effect on Pokemon with the Soundproof Ability.
|
|
|
|
*/
|
|
|
|
export const Moves: {[moveid: string]: MoveData} = {
|
|
"10000000voltthunderbolt": {
|
|
num: 719,
|
|
accuracy: true,
|
|
basePower: 195,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "10,000,000 Volt Thunderbolt",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "pikashuniumz",
|
|
critRatio: 3,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
absorb: {
|
|
num: 71,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Special",
|
|
name: "Absorb",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, heal: 1},
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever",
|
|
},
|
|
accelerock: {
|
|
num: 709,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Accelerock",
|
|
pp: 20,
|
|
priority: 1,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Cool",
|
|
},
|
|
acid: {
|
|
num: 51,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Acid",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Poison",
|
|
contestType: "Clever",
|
|
},
|
|
acidarmor: {
|
|
num: 151,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Acid Armor",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Poison",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Tough",
|
|
},
|
|
aciddownpour: {
|
|
num: 628,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Acid Downpour",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "poisoniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Cool",
|
|
},
|
|
acidspray: {
|
|
num: 491,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Acid Spray",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spd: -2,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Beautiful",
|
|
},
|
|
acrobatics: {
|
|
num: 512,
|
|
accuracy: 100,
|
|
basePower: 55,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (!pokemon.item) {
|
|
this.debug("Power doubled for no item");
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Acrobatics",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, distance: 1},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
acupressure: {
|
|
num: 367,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Acupressure",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {},
|
|
onHit(target) {
|
|
const stats: BoostName[] = [];
|
|
let stat: BoostName;
|
|
for (stat in target.boosts) {
|
|
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 false;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentAllyOrSelf",
|
|
type: "Normal",
|
|
zMove: {effect: 'crit2'},
|
|
contestType: "Tough",
|
|
},
|
|
aerialace: {
|
|
num: 332,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Aerial Ace",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, distance: 1},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
aeroblast: {
|
|
num: 177,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Aeroblast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, distance: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
afteryou: {
|
|
num: 495,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "After You",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {authentic: 1, mystery: 1},
|
|
onHit(target) {
|
|
if (target.side.active.length < 2) return false; // fails in singles
|
|
const action = this.queue.willMove(target);
|
|
if (action) {
|
|
this.queue.prioritizeAction(action);
|
|
this.add('-activate', target, 'move: After You');
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
agility: {
|
|
num: 97,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Agility",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
spe: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cool",
|
|
},
|
|
aircutter: {
|
|
num: 314,
|
|
accuracy: 95,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Air Cutter",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
airslash: {
|
|
num: 403,
|
|
accuracy: 95,
|
|
basePower: 75,
|
|
category: "Special",
|
|
name: "Air Slash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, distance: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
alloutpummeling: {
|
|
num: 624,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "All-Out Pummeling",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "fightiniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
allyswitch: {
|
|
num: 502,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Ally Switch",
|
|
pp: 15,
|
|
priority: 2,
|
|
flags: {},
|
|
onTryHit(source) {
|
|
if (source.side.active.length === 1) return false;
|
|
if (source.side.active.length === 3 && source.position === 1) return false;
|
|
},
|
|
onHit(pokemon) {
|
|
const newPosition = (pokemon.position === 0 ? pokemon.side.active.length - 1 : 0);
|
|
if (!pokemon.side.active[newPosition]) return false;
|
|
if (pokemon.side.active[newPosition].fainted) return false;
|
|
this.swapPosition(pokemon, newPosition, '[from] move: Ally Switch');
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
amnesia: {
|
|
num: 133,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Amnesia",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
spd: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
anchorshot: {
|
|
num: 677,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Anchor Shot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target, source, move) {
|
|
if (source.isActive) target.addVolatile('trapped', source, move, 'trapper');
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Tough",
|
|
},
|
|
ancientpower: {
|
|
num: 246,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Ancient Power",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough",
|
|
},
|
|
appleacid: {
|
|
num: 787,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Apple Acid",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
aquajet: {
|
|
num: 453,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Aqua Jet",
|
|
pp: 20,
|
|
priority: 1,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
aquaring: {
|
|
num: 392,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Aqua Ring",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
volatileStatus: 'aquaring',
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'Aqua Ring');
|
|
},
|
|
onResidualOrder: 6,
|
|
onResidual(pokemon) {
|
|
this.heal(pokemon.baseMaxhp / 16);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Water",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
aquatail: {
|
|
num: 401,
|
|
accuracy: 90,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Aqua Tail",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
armthrust: {
|
|
num: 292,
|
|
accuracy: 100,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Arm Thrust",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
aromatherapy: {
|
|
num: 312,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Aromatherapy",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, distance: 1},
|
|
onHit(pokemon, source, move) {
|
|
this.add('-activate', source, 'move: Aromatherapy');
|
|
let success = false;
|
|
for (const ally of pokemon.side.pokemon) {
|
|
if (ally !== source && ((ally.hasAbility('sapsipper')) ||
|
|
(ally.volatiles['substitute'] && !move.infiltrates))) {
|
|
continue;
|
|
}
|
|
if (ally.cureStatus()) success = true;
|
|
}
|
|
return success;
|
|
},
|
|
target: "allyTeam",
|
|
type: "Grass",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Clever",
|
|
},
|
|
aromaticmist: {
|
|
num: 597,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Aromatic Mist",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {authentic: 1},
|
|
boosts: {
|
|
spd: 1,
|
|
},
|
|
secondary: null,
|
|
target: "adjacentAlly",
|
|
type: "Fairy",
|
|
zMove: {boost: {spd: 2}},
|
|
contestType: "Beautiful",
|
|
},
|
|
assist: {
|
|
num: 274,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Assist",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {},
|
|
onHit(target) {
|
|
const noAssist = [
|
|
'assist', 'banefulbunker', 'beakblast', 'belch', 'bestow', 'bounce', 'celebrate', 'chatter', 'circlethrow', 'copycat', 'counter', 'covet', 'destinybond', 'detect', 'dig', 'dive', 'dragontail', 'endure', 'feint', 'fly', 'focuspunch', 'followme', 'helpinghand', 'holdhands', 'kingsshield', 'matblock', 'mefirst', 'metronome', 'mimic', 'mirrorcoat', 'mirrormove', 'naturepower', 'phantomforce', 'protect', 'ragepowder', 'roar', 'shadowforce', 'shelltrap', 'sketch', 'skydrop', 'sleeptalk', 'snatch', 'spikyshield', 'spotlight', 'struggle', 'switcheroo', 'thief', 'transform', 'trick', 'whirlwind',
|
|
];
|
|
|
|
const moves = [];
|
|
for (const pokemon of target.side.pokemon) {
|
|
if (pokemon === target) continue;
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
const moveid = moveSlot.id;
|
|
if (noAssist.includes(moveid)) continue;
|
|
const move = this.dex.getMove(moveid);
|
|
if (move.isZ || move.isMax) {
|
|
continue;
|
|
}
|
|
moves.push(moveid);
|
|
}
|
|
}
|
|
let randomMove = '';
|
|
if (moves.length) randomMove = this.sample(moves);
|
|
if (!randomMove) {
|
|
return false;
|
|
}
|
|
this.useMove(randomMove, target);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
assurance: {
|
|
num: 372,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.hurtThisTurn) {
|
|
this.debug('Boosted for being damaged this turn');
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Assurance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
astonish: {
|
|
num: 310,
|
|
accuracy: 100,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Astonish",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cute",
|
|
},
|
|
attackorder: {
|
|
num: 454,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Attack Order",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Clever",
|
|
},
|
|
attract: {
|
|
num: 213,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Attract",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
volatileStatus: 'attract',
|
|
condition: {
|
|
noCopy: true, // doesn't get copied by Baton Pass
|
|
onStart(pokemon, source, effect) {
|
|
if (!(pokemon.gender === 'M' && source.gender === 'F') && !(pokemon.gender === 'F' && source.gender === 'M')) {
|
|
this.debug('incompatible gender');
|
|
return false;
|
|
}
|
|
if (!this.runEvent('Attract', pokemon, source)) {
|
|
this.debug('Attract event failed');
|
|
return false;
|
|
}
|
|
|
|
if (effect.id === 'cutecharm') {
|
|
this.add('-start', pokemon, 'Attract', '[from] ability: Cute Charm', '[of] ' + source);
|
|
} else if (effect.id === 'destinyknot') {
|
|
this.add('-start', pokemon, 'Attract', '[from] item: Destiny Knot', '[of] ' + source);
|
|
} else {
|
|
this.add('-start', pokemon, 'Attract');
|
|
}
|
|
},
|
|
onUpdate(pokemon) {
|
|
if (this.effectData.source && !this.effectData.source.isActive && pokemon.volatiles['attract']) {
|
|
this.debug('Removing Attract volatile on ' + pokemon);
|
|
pokemon.removeVolatile('attract');
|
|
}
|
|
},
|
|
onBeforeMovePriority: 2,
|
|
onBeforeMove(pokemon, target, move) {
|
|
this.add('-activate', pokemon, 'move: Attract', '[of] ' + this.effectData.source);
|
|
if (this.randomChance(1, 2)) {
|
|
this.add('cant', pokemon, 'Attract');
|
|
return false;
|
|
}
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add('-end', pokemon, 'Attract', '[silent]');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
aurasphere: {
|
|
num: 396,
|
|
accuracy: true,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Aura Sphere",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, pulse: 1, mirror: 1, distance: 1},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Fighting",
|
|
contestType: "Beautiful",
|
|
},
|
|
aurawheel: {
|
|
num: 783,
|
|
accuracy: 100,
|
|
basePower: 110,
|
|
category: "Physical",
|
|
name: "Aura Wheel",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1,
|
|
},
|
|
},
|
|
},
|
|
onTry(pokemon) {
|
|
if (pokemon.species.baseSpecies === 'Morpeko') {
|
|
return;
|
|
}
|
|
this.hint("Only a Pokemon whose form is Morpeko or Morpeko-Hangry can use this move.");
|
|
this.add('-fail', pokemon, 'move: Aura Wheel');
|
|
return null;
|
|
},
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.species.name === 'Morpeko-Hangry') {
|
|
move.type = 'Dark';
|
|
} else {
|
|
move.type = 'Electric';
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
},
|
|
aurorabeam: {
|
|
num: 62,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Aurora Beam",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
atk: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
auroraveil: {
|
|
num: 694,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Aurora Veil",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
sideCondition: 'auroraveil',
|
|
onTryHitSide() {
|
|
if (!this.field.isWeather('hail')) return false;
|
|
},
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasItem('lightclay')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onAnyModifyDamage(damage, source, target, move) {
|
|
if (target !== source && target.side === this.effectData.target) {
|
|
if ((target.side.getSideCondition('reflect') && this.getCategory(move) === 'Physical') ||
|
|
(target.side.getSideCondition('lightscreen') && this.getCategory(move) === 'Special')) {
|
|
return;
|
|
}
|
|
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
|
|
this.debug('Aurora Veil weaken');
|
|
if (target.side.active.length > 1) return this.chainModify([0xAAC, 0x1000]);
|
|
return this.chainModify(0.5);
|
|
}
|
|
}
|
|
},
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'move: Aurora Veil');
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 1,
|
|
onEnd(side) {
|
|
this.add('-sideend', side, 'move: Aurora Veil');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Ice",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
autotomize: {
|
|
num: 475,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Autotomize",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onTryHit(pokemon) {
|
|
const hasContrary = pokemon.hasAbility('contrary');
|
|
if ((!hasContrary && pokemon.boosts.spe === 6) || (hasContrary && pokemon.boosts.spe === -6)) {
|
|
return false;
|
|
}
|
|
},
|
|
boosts: {
|
|
spe: 2,
|
|
},
|
|
onHit(pokemon) {
|
|
if (pokemon.weighthg > 1) {
|
|
pokemon.weighthg = Math.max(1, pokemon.weighthg - 1000);
|
|
this.add('-start', pokemon, 'Autotomize');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Steel",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
avalanche: {
|
|
num: 419,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const damagedByTarget = pokemon.attackedBy.some(
|
|
p => p.source === target && p.damage > 0 && p.thisTurn
|
|
);
|
|
if (damagedByTarget) {
|
|
this.debug('Boosted for getting hit by ' + target);
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Avalanche",
|
|
pp: 10,
|
|
priority: -4,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
babydolleyes: {
|
|
num: 608,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Baby-Doll Eyes",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
boosts: {
|
|
atk: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
baddybad: {
|
|
num: 737,
|
|
accuracy: 95,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Baddy Bad",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
self: {
|
|
sideCondition: 'reflect',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
banefulbunker: {
|
|
num: 661,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Baneful Bunker",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {},
|
|
stallingMove: true,
|
|
volatileStatus: 'banefulbunker',
|
|
onTryHit(target, source, move) {
|
|
return !!this.queue.willAct() && this.runEvent('StallMove', target);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'move: Protect');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags['protect']) {
|
|
if (move.isZ || (move.isMax && !move.breaksProtect)) target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add('-activate', target, 'move: Protect');
|
|
}
|
|
const lockedmove = source.getVolatile('lockedmove');
|
|
if (lockedmove) {
|
|
// Outrage counter is reset
|
|
if (source.volatiles['lockedmove'].duration === 2) {
|
|
delete source.volatiles['lockedmove'];
|
|
}
|
|
}
|
|
if (move.flags['contact']) {
|
|
source.trySetStatus('psn', target);
|
|
}
|
|
return this.NOT_FAIL;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZOrMaxPowered && move.flags['contact']) {
|
|
source.trySetStatus('psn', target);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Poison",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
barrage: {
|
|
num: 140,
|
|
accuracy: 85,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Barrage",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
barrier: {
|
|
num: 112,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Barrier",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cool",
|
|
},
|
|
batonpass: {
|
|
num: 226,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Baton Pass",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {},
|
|
selfSwitch: 'copyvolatile',
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
beakblast: {
|
|
num: 690,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Beak Blast",
|
|
pp: 15,
|
|
priority: -3,
|
|
flags: {bullet: 1, protect: 1},
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile('beakblast');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add('-singleturn', pokemon, 'move: Beak Blast');
|
|
},
|
|
onHit(pokemon, source, move) {
|
|
if (move.flags['contact']) {
|
|
source.trySetStatus('brn', pokemon);
|
|
}
|
|
},
|
|
},
|
|
// FIXME: onMoveAborted(pokemon) {pokemon.removeVolatile('beakblast')},
|
|
onAfterMove(pokemon) {
|
|
pokemon.removeVolatile('beakblast');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
contestType: "Tough",
|
|
},
|
|
beatup: {
|
|
num: 251,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return 5 + Math.floor(move.allies!.shift()!.species.baseStats.atk / 10);
|
|
},
|
|
category: "Physical",
|
|
name: "Beat Up",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, mystery: 1},
|
|
onModifyMove(move, pokemon) {
|
|
move.allies = pokemon.side.pokemon.filter(ally => ally === pokemon || !ally.fainted && !ally.status);
|
|
move.multihit = move.allies.length;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
behemothbash: {
|
|
num: 782,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Behemoth Bash",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
},
|
|
behemothblade: {
|
|
num: 781,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Behemoth Blade",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
},
|
|
belch: {
|
|
num: 562,
|
|
accuracy: 90,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Belch",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
// Move disabling implemented in Battle#nextTurn in sim/battle.js
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough",
|
|
},
|
|
bellydrum: {
|
|
num: 187,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Belly Drum",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onHit(target) {
|
|
if (target.hp <= target.maxhp / 2 || target.boosts.atk >= 6 || target.maxhp === 1) { // Shedinja clause
|
|
return false;
|
|
}
|
|
this.directDamage(target.maxhp / 2);
|
|
this.boost({atk: 12}, target);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Cute",
|
|
},
|
|
bestow: {
|
|
num: 516,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Bestow",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {mirror: 1, authentic: 1, mystery: 1},
|
|
onHit(target, source, move) {
|
|
if (target.item) {
|
|
return false;
|
|
}
|
|
const myItem = source.takeItem();
|
|
if (!myItem) return false;
|
|
if (!this.singleEvent('TakeItem', myItem, source.itemData, target, source, move, myItem) || !target.setItem(myItem)) {
|
|
source.item = myItem.id;
|
|
return false;
|
|
}
|
|
this.add('-item', target, myItem.name, '[from] move: Bestow', '[of] ' + source);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 2}},
|
|
contestType: "Cute",
|
|
},
|
|
bide: {
|
|
num: 117,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Bide",
|
|
pp: 10,
|
|
priority: 1,
|
|
flags: {contact: 1, protect: 1},
|
|
volatileStatus: 'bide',
|
|
ignoreImmunity: true,
|
|
beforeMoveCallback(pokemon) {
|
|
if (pokemon.volatiles['bide']) return true;
|
|
},
|
|
condition: {
|
|
duration: 3,
|
|
onLockMove: 'bide',
|
|
onStart(pokemon) {
|
|
this.effectData.totalDamage = 0;
|
|
this.add('-start', pokemon, 'move: Bide');
|
|
},
|
|
onDamagePriority: -101,
|
|
onDamage(damage, target, source, move) {
|
|
if (!move || move.effectType !== 'Move' || !source) return;
|
|
this.effectData.totalDamage += damage;
|
|
this.effectData.lastDamageSource = source;
|
|
},
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (this.effectData.duration === 1) {
|
|
this.add('-end', pokemon, 'move: Bide');
|
|
target = this.effectData.lastDamageSource;
|
|
if (!target || !this.effectData.totalDamage) {
|
|
this.attrLastMove('[still]');
|
|
this.add('-fail', pokemon);
|
|
return false;
|
|
}
|
|
if (!target.isActive) {
|
|
const possibleTarget = this.getRandomTarget(pokemon, this.dex.getMove('pound'));
|
|
if (!possibleTarget) {
|
|
this.add('-miss', pokemon);
|
|
return false;
|
|
}
|
|
target = possibleTarget;
|
|
}
|
|
const moveData: Partial<ActiveMove> = {
|
|
id: 'bide' as ID,
|
|
name: "Bide",
|
|
accuracy: true,
|
|
damage: this.effectData.totalDamage * 2,
|
|
category: "Physical",
|
|
priority: 1,
|
|
flags: {contact: 1, protect: 1},
|
|
effectType: 'Move',
|
|
type: 'Normal',
|
|
};
|
|
this.tryMoveHit(target, pokemon, moveData as ActiveMove);
|
|
return false;
|
|
}
|
|
this.add('-activate', pokemon, 'move: Bide');
|
|
},
|
|
onMoveAborted(pokemon) {
|
|
pokemon.removeVolatile('bide');
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add('-end', pokemon, 'move: Bide', '[silent]');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
bind: {
|
|
num: 20,
|
|
accuracy: 85,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Bind",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
volatileStatus: 'partiallytrapped',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
bite: {
|
|
num: 44,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Bite",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough",
|
|
},
|
|
blackholeeclipse: {
|
|
num: 654,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Black Hole Eclipse",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "darkiniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool",
|
|
},
|
|
blastburn: {
|
|
num: 307,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Blast Burn",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {recharge: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
blazekick: {
|
|
num: 299,
|
|
accuracy: 90,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Blaze Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
blizzard: {
|
|
num: 59,
|
|
accuracy: 70,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Blizzard",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyMove(move) {
|
|
if (this.field.isWeather('hail')) move.accuracy = true;
|
|
},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'frz',
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
block: {
|
|
num: 335,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Block",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {reflectable: 1, mirror: 1},
|
|
onHit(target, source, move) {
|
|
return target.addVolatile('trapped', source, move, 'trapper');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
bloomdoom: {
|
|
num: 644,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Bloom Doom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "grassiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
blueflare: {
|
|
num: 551,
|
|
accuracy: 85,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Blue Flare",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
bodypress: {
|
|
num: 776,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Body Press",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
useSourceDefensiveAsOffensive: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
},
|
|
bodyslam: {
|
|
num: 34,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Body Slam",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
boltbeak: {
|
|
num: 754,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.newlySwitched || this.queue.willMove(target)) {
|
|
this.debug('Bolt Beak damage boost');
|
|
return move.basePower * 2;
|
|
}
|
|
this.debug('Bolt Beak NOT boosted');
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Bolt Beak",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
},
|
|
boltstrike: {
|
|
num: 550,
|
|
accuracy: 85,
|
|
basePower: 130,
|
|
category: "Physical",
|
|
name: "Bolt Strike",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Beautiful",
|
|
},
|
|
boneclub: {
|
|
num: 125,
|
|
accuracy: 85,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Bone Club",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough",
|
|
},
|
|
bonemerang: {
|
|
num: 155,
|
|
accuracy: 90,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Bonemerang",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
maxMove: {basePower: 130},
|
|
contestType: "Tough",
|
|
},
|
|
bonerush: {
|
|
num: 198,
|
|
accuracy: 90,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Bone Rush",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Tough",
|
|
},
|
|
boomburst: {
|
|
num: 586,
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Special",
|
|
name: "Boomburst",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
bounce: {
|
|
num: 340,
|
|
accuracy: 85,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Bounce",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onInvulnerability(target, source, move) {
|
|
if (['gust', 'twister', 'skyuppercut', 'thunder', 'hurricane', 'smackdown', 'thousandarrows'].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onSourceBasePower(basePower, target, source, move) {
|
|
if (move.id === 'gust' || move.id === 'twister') {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cute",
|
|
},
|
|
bouncybubble: {
|
|
num: 733,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Bouncy Bubble",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, heal: 1},
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Clever",
|
|
},
|
|
branchpoke: {
|
|
num: 785,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Branch Poke",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
bravebird: {
|
|
num: 413,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Brave Bird",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, distance: 1},
|
|
recoil: [33, 100],
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
breakingswipe: {
|
|
num: 784,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Breaking Swipe",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
atk: -1,
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon",
|
|
},
|
|
breakneckblitz: {
|
|
num: 622,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Breakneck Blitz",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "normaliumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
brickbreak: {
|
|
num: 280,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Brick Break",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTryHit(pokemon) {
|
|
// will shatter screens through sub, before you hit
|
|
if (pokemon.runImmunity('Fighting')) {
|
|
pokemon.side.removeSideCondition('reflect');
|
|
pokemon.side.removeSideCondition('lightscreen');
|
|
pokemon.side.removeSideCondition('auroraveil');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
brine: {
|
|
num: 362,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Brine",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onBasePower(basePower, pokemon, target) {
|
|
if (target.hp * 2 <= target.maxhp) {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough",
|
|
},
|
|
brutalswing: {
|
|
num: 693,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Brutal Swing",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Dark",
|
|
contestType: "Tough",
|
|
},
|
|
bubble: {
|
|
num: 145,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Bubble",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Cute",
|
|
},
|
|
bubblebeam: {
|
|
num: 61,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Bubble Beam",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
bugbite: {
|
|
num: 450,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Bug Bite",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onHit(target, source) {
|
|
const item = target.getItem();
|
|
if (source.hp && item.isBerry && target.takeItem(source)) {
|
|
this.add('-enditem', target, item.name, '[from] stealeat', '[move] Bug Bite', '[of] ' + source);
|
|
if (this.singleEvent('Eat', item, null, source, null, null)) {
|
|
this.runEvent('EatItem', source, null, null, item);
|
|
if (item.id === 'leppaberry') target.staleness = 'external';
|
|
}
|
|
if (item.onEat) source.ateBerry = true;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute",
|
|
},
|
|
bugbuzz: {
|
|
num: 405,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Bug Buzz",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Beautiful",
|
|
},
|
|
bulkup: {
|
|
num: 339,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Bulk Up",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fighting",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
bulldoze: {
|
|
num: 523,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Bulldoze",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Ground",
|
|
contestType: "Tough",
|
|
},
|
|
bulletpunch: {
|
|
num: 418,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Bullet Punch",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Tough",
|
|
},
|
|
bulletseed: {
|
|
num: 331,
|
|
accuracy: 100,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Bullet Seed",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cool",
|
|
},
|
|
burningjealousy: {
|
|
num: 807,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
name: "Burning Jealousy",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target, source, move) {
|
|
if (target?.statsRaisedThisTurn) {
|
|
target.trySetStatus('brn', source, move);
|
|
}
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Tough",
|
|
},
|
|
burnup: {
|
|
num: 682,
|
|
accuracy: 100,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Burn Up",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, defrost: 1},
|
|
onTryMove(pokemon, target, move) {
|
|
if (pokemon.hasType('Fire')) return;
|
|
this.add('-fail', pokemon, 'move: Burn Up');
|
|
this.attrLastMove('[still]');
|
|
return null;
|
|
},
|
|
self: {
|
|
onHit(pokemon) {
|
|
pokemon.setType(pokemon.getTypes(true).map(type => type === "Fire" ? "???" : type));
|
|
this.add('-start', pokemon, 'typechange', pokemon.types.join('/'), '[from] move: Burn Up');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Clever",
|
|
},
|
|
buzzybuzz: {
|
|
num: 734,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Buzzy Buzz",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Clever",
|
|
},
|
|
calmmind: {
|
|
num: 347,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Calm Mind",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
spa: 1,
|
|
spd: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
camouflage: {
|
|
num: 293,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Camouflage",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onHit(target) {
|
|
let newType = 'Normal';
|
|
if (this.field.isTerrain('electricterrain')) {
|
|
newType = 'Electric';
|
|
} else if (this.field.isTerrain('grassyterrain')) {
|
|
newType = 'Grass';
|
|
} else if (this.field.isTerrain('mistyterrain')) {
|
|
newType = 'Fairy';
|
|
} else if (this.field.isTerrain('psychicterrain')) {
|
|
newType = 'Psychic';
|
|
}
|
|
|
|
if (target.getTypes().join() === newType || !target.setType(newType)) return false;
|
|
this.add('-start', target, 'typechange', newType);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {evasion: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
captivate: {
|
|
num: 445,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Captivate",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
onTryImmunity(pokemon, source) {
|
|
return (pokemon.gender === 'M' && source.gender === 'F') || (pokemon.gender === 'F' && source.gender === 'M');
|
|
},
|
|
boosts: {
|
|
spa: -2,
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: {boost: {spd: 2}},
|
|
contestType: "Cute",
|
|
},
|
|
catastropika: {
|
|
num: 658,
|
|
accuracy: true,
|
|
basePower: 210,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Catastropika",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {contact: 1},
|
|
isZ: "pikaniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
celebrate: {
|
|
num: 606,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Celebrate",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryHit(target, source) {
|
|
this.add('-activate', target, 'move: Celebrate');
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1, def: 1, spa: 1, spd: 1, spe: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
charge: {
|
|
num: 268,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Charge",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
volatileStatus: 'charge',
|
|
onHit(pokemon) {
|
|
this.add('-activate', pokemon, 'move: Charge');
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onRestart(pokemon) {
|
|
this.effectData.duration = 2;
|
|
},
|
|
onBasePowerPriority: 9,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === 'Electric') {
|
|
this.debug('charge boost');
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
},
|
|
boosts: {
|
|
spd: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Electric",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
chargebeam: {
|
|
num: 451,
|
|
accuracy: 90,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Charge Beam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 70,
|
|
self: {
|
|
boosts: {
|
|
spa: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Beautiful",
|
|
},
|
|
charm: {
|
|
num: 204,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Charm",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
boosts: {
|
|
atk: -2,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
chatter: {
|
|
num: 448,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Chatter",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, distance: 1, authentic: 1},
|
|
noSketch: true,
|
|
secondary: {
|
|
chance: 100,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cute",
|
|
},
|
|
chipaway: {
|
|
num: 498,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Chip Away",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
ignoreDefensive: true,
|
|
ignoreEvasion: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
circlethrow: {
|
|
num: 509,
|
|
accuracy: 90,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Circle Throw",
|
|
pp: 10,
|
|
priority: -6,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
forceSwitch: true,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
clamp: {
|
|
num: 128,
|
|
accuracy: 85,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Clamp",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
volatileStatus: 'partiallytrapped',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough",
|
|
},
|
|
clangingscales: {
|
|
num: 691,
|
|
accuracy: 100,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Clanging Scales",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
selfBoost: {
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon",
|
|
contestType: "Tough",
|
|
},
|
|
clangoroussoul: {
|
|
num: 775,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Clangorous Soul",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, sound: 1, dance: 1},
|
|
onTryHit(pokemon, target, move) {
|
|
if (pokemon.hp <= (pokemon.maxhp * 33 / 100) || pokemon.maxhp === 1) {
|
|
return false;
|
|
}
|
|
if (!this.boost(move.boosts as SparseBoostsTable)) return null;
|
|
delete move.boosts;
|
|
},
|
|
onHit(pokemon) {
|
|
this.directDamage(pokemon.maxhp * 33 / 100);
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dragon",
|
|
},
|
|
clangoroussoulblaze: {
|
|
num: 728,
|
|
accuracy: true,
|
|
basePower: 185,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Clangorous Soulblaze",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {sound: 1, authentic: 1},
|
|
selfBoost: {
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1,
|
|
},
|
|
},
|
|
isZ: "kommoniumz",
|
|
secondary: {
|
|
// Sheer Force negates the selfBoost even though it is not secondary
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon",
|
|
contestType: "Cool",
|
|
},
|
|
clearsmog: {
|
|
num: 499,
|
|
accuracy: true,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Clear Smog",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onHit(target) {
|
|
target.clearBoosts();
|
|
this.add('-clearboost', target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Beautiful",
|
|
},
|
|
closecombat: {
|
|
num: 370,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Close Combat",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
boosts: {
|
|
def: -1,
|
|
spd: -1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
coaching: {
|
|
num: 811,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Coaching",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {authentic: 1},
|
|
secondary: null,
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
},
|
|
target: "adjacentAlly",
|
|
type: "Fighting",
|
|
},
|
|
coil: {
|
|
num: 489,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Coil",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
accuracy: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Poison",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Tough",
|
|
},
|
|
cometpunch: {
|
|
num: 4,
|
|
accuracy: 85,
|
|
basePower: 18,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Comet Punch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
maxMove: {basePower: 100},
|
|
contestType: "Tough",
|
|
},
|
|
confide: {
|
|
num: 590,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Confide",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {reflectable: 1, mirror: 1, sound: 1, authentic: 1},
|
|
boosts: {
|
|
spa: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
confuseray: {
|
|
num: 109,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Confuse Ray",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
volatileStatus: 'confusion',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
confusion: {
|
|
num: 93,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Confusion",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
constrict: {
|
|
num: 132,
|
|
accuracy: 100,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Constrict",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
continentalcrush: {
|
|
num: 632,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Continental Crush",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "rockiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Cool",
|
|
},
|
|
conversion: {
|
|
num: 160,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Conversion",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onHit(target) {
|
|
const type = this.dex.getMove(target.moveSlots[0].id).type;
|
|
if (target.hasType(type) || !target.setType(type)) return false;
|
|
this.add('-start', target, 'typechange', type);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1, def: 1, spa: 1, spd: 1, spe: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
conversion2: {
|
|
num: 176,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Conversion 2",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {authentic: 1},
|
|
onHit(target, source) {
|
|
if (!target.lastMove) {
|
|
return false;
|
|
}
|
|
const possibleTypes = [];
|
|
const attackType = target.lastMove.type;
|
|
for (const type in this.dex.data.TypeChart) {
|
|
if (source.hasType(type)) continue;
|
|
const typeCheck = this.dex.data.TypeChart[type].damageTaken[attackType];
|
|
if (typeCheck === 2 || typeCheck === 3) {
|
|
possibleTypes.push(type);
|
|
}
|
|
}
|
|
if (!possibleTypes.length) {
|
|
return false;
|
|
}
|
|
const randomType = this.sample(possibleTypes);
|
|
|
|
if (!source.setType(randomType)) return false;
|
|
this.add('-start', source, 'typechange', randomType);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Beautiful",
|
|
},
|
|
copycat: {
|
|
num: 383,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Copycat",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {},
|
|
onHit(pokemon) {
|
|
const noCopycat = [
|
|
'assist', 'banefulbunker', 'beakblast', 'belch', 'bestow', 'celebrate', 'chatter', 'circlethrow', 'copycat', 'counter', 'covet', 'craftyshield', 'destinybond', 'detect', 'dragontail', 'dynamaxcannon', 'endure', 'feint', 'focuspunch', 'followme', 'helpinghand', 'holdhands', 'kingsshield', 'matblock', 'mefirst', 'metronome', 'mimic', 'mirrorcoat', 'mirrormove', 'naturepower', 'obstruct', 'protect', 'ragepowder', 'roar', 'shelltrap', 'sketch', 'sleeptalk', 'snatch', 'spikyshield', 'spotlight', 'struggle', 'switcheroo', 'thief', 'transform', 'trick', 'whirlwind',
|
|
];
|
|
let move: Move | ActiveMove | null = this.lastMove;
|
|
if (!move) return;
|
|
|
|
if (move.isMax && move.baseMove) move = this.dex.getMove(move.baseMove);
|
|
if (noCopycat.includes(move.id) || move.isZ || move.isMax) {
|
|
return false;
|
|
}
|
|
this.useMove(move.id, pokemon);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {accuracy: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
coreenforcer: {
|
|
num: 687,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Core Enforcer",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onHit(target) {
|
|
const noAbilityChange = [
|
|
'battlebond', 'comatose', 'disguise', 'multitype', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'zenmode',
|
|
];
|
|
if (noAbilityChange.includes(target.ability)) return;
|
|
if (target.newlySwitched || this.queue.willMove(target)) return;
|
|
target.addVolatile('gastroacid');
|
|
},
|
|
onAfterSubDamage(damage, target) {
|
|
const noAbilityChange = [
|
|
'battlebond', 'comatose', 'disguise', 'multitype', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'zenmode',
|
|
];
|
|
if (noAbilityChange.includes(target.ability)) return;
|
|
if (target.newlySwitched || this.queue.willMove(target)) return;
|
|
target.addVolatile('gastroacid');
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon",
|
|
zMove: {basePower: 140},
|
|
contestType: "Tough",
|
|
},
|
|
corkscrewcrash: {
|
|
num: 638,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Corkscrew Crash",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "steeliumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
corrosivegas: {
|
|
num: 810,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Corrosive Gas",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
const item = target.takeItem(source);
|
|
if (item) {
|
|
this.add('-enditem', target, item.name, '[from] move: Corrosive Gas', '[of] ' + source);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Poison",
|
|
},
|
|
cosmicpower: {
|
|
num: 322,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Cosmic Power",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: 1,
|
|
spd: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
cottonguard: {
|
|
num: 538,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Cotton Guard",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: 3,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
cottonspore: {
|
|
num: 178,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Cotton Spore",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {powder: 1, protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
spe: -2,
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Grass",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
counter: {
|
|
num: 68,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
if (!pokemon.volatiles['counter']) return 0;
|
|
return pokemon.volatiles['counter'].damage || 1;
|
|
},
|
|
category: "Physical",
|
|
name: "Counter",
|
|
pp: 20,
|
|
priority: -5,
|
|
flags: {contact: 1, protect: 1},
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile('counter');
|
|
},
|
|
onTryHit(target, source, move) {
|
|
if (!source.volatiles['counter']) return false;
|
|
if (source.volatiles['counter'].position === null) return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
noCopy: true,
|
|
onStart(target, source, move) {
|
|
this.effectData.position = null;
|
|
this.effectData.damage = 0;
|
|
},
|
|
onRedirectTargetPriority: -1,
|
|
onRedirectTarget(target, source, source2) {
|
|
if (source !== this.effectData.target) return;
|
|
return source.side.foe.active[this.effectData.position];
|
|
},
|
|
onDamagingHit(damage, target, source, move) {
|
|
if (source.side !== target.side && this.getCategory(move) === 'Physical') {
|
|
this.effectData.position = source.position;
|
|
this.effectData.damage = 2 * damage;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "scripted",
|
|
type: "Fighting",
|
|
maxMove: {basePower: 75},
|
|
contestType: "Tough",
|
|
},
|
|
courtchange: {
|
|
num: 756,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Court Change",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {mirror: 1},
|
|
onHitField(target, source) {
|
|
const sourceSide = source.side;
|
|
const targetSide = source.side.foe;
|
|
const sideConditions = [
|
|
'mist', 'lightscreen', 'reflect', 'spikes', 'safeguard', 'tailwind', 'toxicspikes', 'stealthrock', 'waterpledge', 'firepledge', 'grasspledge', 'stickyweb', 'auroraveil', 'gmaxsteelsurge', 'gmaxcannonade', 'gmaxvinelash', 'gmaxwildfire',
|
|
];
|
|
let success = false;
|
|
for (const id of sideConditions) {
|
|
const effectName = this.dex.getEffect(id).name;
|
|
if (sourceSide.sideConditions[id] && targetSide.sideConditions[id]) {
|
|
[sourceSide.sideConditions[id], targetSide.sideConditions[id]] = [
|
|
targetSide.sideConditions[id], sourceSide.sideConditions[id],
|
|
];
|
|
this.add('-sideend', sourceSide, effectName, '[silent]');
|
|
this.add('-sideend', targetSide, effectName, '[silent]');
|
|
} else if (sourceSide.sideConditions[id] && !targetSide.sideConditions[id]) {
|
|
targetSide.sideConditions[id] = sourceSide.sideConditions[id];
|
|
delete sourceSide.sideConditions[id];
|
|
this.add('-sideend', sourceSide, effectName, '[silent]');
|
|
} else if (targetSide.sideConditions[id] && !sourceSide.sideConditions[id]) {
|
|
sourceSide.sideConditions[id] = targetSide.sideConditions[id];
|
|
delete targetSide.sideConditions[id];
|
|
this.add('-sideend', targetSide, effectName, '[silent]');
|
|
} else {
|
|
continue;
|
|
}
|
|
let sourceLayers = sourceSide.sideConditions[id] ? (sourceSide.sideConditions[id].layers || 1) : 0;
|
|
let targetLayers = targetSide.sideConditions[id] ? (targetSide.sideConditions[id].layers || 1) : 0;
|
|
for (; sourceLayers > 0; sourceLayers--) {
|
|
this.add('-sidestart', sourceSide, effectName, '[silent]');
|
|
}
|
|
for (; targetLayers > 0; targetLayers--) {
|
|
this.add('-sidestart', targetSide, effectName, '[silent]');
|
|
}
|
|
success = true;
|
|
}
|
|
if (!success) return false;
|
|
this.add('-activate', source, 'move: Court Change');
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Normal",
|
|
},
|
|
covet: {
|
|
num: 343,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Covet",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onAfterHit(target, source, move) {
|
|
if (source.item || source.volatiles['gem']) {
|
|
return;
|
|
}
|
|
const yourItem = target.takeItem(source);
|
|
if (!yourItem) {
|
|
return;
|
|
}
|
|
if (
|
|
!this.singleEvent('TakeItem', yourItem, target.itemData, source, target, move, yourItem) ||
|
|
!source.setItem(yourItem)
|
|
) {
|
|
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
|
|
return;
|
|
}
|
|
this.add('-item', source, yourItem, '[from] move: Covet', '[of] ' + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
crabhammer: {
|
|
num: 152,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Crabhammer",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough",
|
|
},
|
|
craftyshield: {
|
|
num: 578,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Crafty Shield",
|
|
pp: 10,
|
|
priority: 3,
|
|
flags: {},
|
|
sideCondition: 'craftyshield',
|
|
onTryHitSide(side, source) {
|
|
return !!this.queue.willAct();
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source) {
|
|
this.add('-singleturn', source, 'Crafty Shield');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (['self', 'all'].includes(move.target) || move.category !== 'Status') return;
|
|
this.add('-activate', target, 'move: Crafty Shield');
|
|
return this.NOT_FAIL;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Fairy",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
crosschop: {
|
|
num: 238,
|
|
accuracy: 80,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Cross Chop",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
crosspoison: {
|
|
num: 440,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Cross Poison",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'psn',
|
|
},
|
|
critRatio: 2,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Cool",
|
|
},
|
|
crunch: {
|
|
num: 242,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Crunch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough",
|
|
},
|
|
crushclaw: {
|
|
num: 306,
|
|
accuracy: 95,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Crush Claw",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
crushgrip: {
|
|
num: 462,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
return Math.floor(Math.floor((120 * (100 * Math.floor(target.hp * 4096 / target.maxhp)) + 2048 - 1) / 4096) / 100) || 1;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Crush Grip",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 190},
|
|
maxMove: {basePower: 140},
|
|
contestType: "Tough",
|
|
},
|
|
curse: {
|
|
num: 174,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Curse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {authentic: 1},
|
|
volatileStatus: 'curse',
|
|
onModifyMove(move, source, target) {
|
|
if (!source.hasType('Ghost')) {
|
|
move.target = move.nonGhostTarget as MoveTarget;
|
|
}
|
|
},
|
|
onTryHit(target, source, move) {
|
|
if (!source.hasType('Ghost')) {
|
|
delete move.volatileStatus;
|
|
delete move.onHit;
|
|
move.self = {boosts: {spe: -1, atk: 1, def: 1}};
|
|
} else if (move.volatileStatus && target.volatiles['curse']) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
this.directDamage(source.maxhp / 2, source, source);
|
|
},
|
|
condition: {
|
|
onStart(pokemon, source) {
|
|
this.add('-start', pokemon, 'Curse', '[of] ' + source);
|
|
},
|
|
onResidualOrder: 10,
|
|
onResidual(pokemon) {
|
|
this.damage(pokemon.baseMaxhp / 4);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
nonGhostTarget: "self",
|
|
type: "Ghost",
|
|
zMove: {effect: 'curse'},
|
|
contestType: "Tough",
|
|
},
|
|
cut: {
|
|
num: 15,
|
|
accuracy: 95,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Cut",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
darkestlariat: {
|
|
num: 663,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Darkest Lariat",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
ignoreEvasion: true,
|
|
ignoreDefensive: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool",
|
|
},
|
|
darkpulse: {
|
|
num: 399,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Dark Pulse",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, pulse: 1, mirror: 1, distance: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "any",
|
|
type: "Dark",
|
|
contestType: "Cool",
|
|
},
|
|
darkvoid: {
|
|
num: 464,
|
|
accuracy: 50,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Dark Void",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'slp',
|
|
onTryMove(pokemon, target, move) {
|
|
if (pokemon.species.name === 'Darkrai' || move.hasBounced) {
|
|
return;
|
|
}
|
|
this.add('-fail', pokemon, 'move: Dark Void');
|
|
this.hint("Only a Pokemon whose form is Darkrai can use this move.");
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Dark",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
dazzlinggleam: {
|
|
num: 605,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Dazzling Gleam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fairy",
|
|
contestType: "Beautiful",
|
|
},
|
|
decorate: {
|
|
num: 777,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Decorate",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {mystery: 1},
|
|
secondary: null,
|
|
boosts: {
|
|
atk: 2,
|
|
spa: 2,
|
|
},
|
|
target: "normal",
|
|
type: "Fairy",
|
|
},
|
|
defendorder: {
|
|
num: 455,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Defend Order",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: 1,
|
|
spd: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
defensecurl: {
|
|
num: 111,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Defense Curl",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: 1,
|
|
},
|
|
volatileStatus: 'defensecurl',
|
|
condition: {
|
|
noCopy: true,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {accuracy: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
defog: {
|
|
num: 432,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Defog",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
onHit(target, source, move) {
|
|
let success = false;
|
|
if (!target.volatiles['substitute'] || move.infiltrates) success = !!this.boost({evasion: -1});
|
|
const removeTarget = [
|
|
'reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb', 'gmaxsteelsurge',
|
|
];
|
|
const removeAll = [
|
|
'spikes', 'toxicspikes', 'stealthrock', 'stickyweb', 'gmaxsteelsurge',
|
|
];
|
|
for (const targetCondition of removeTarget) {
|
|
if (target.side.removeSideCondition(targetCondition)) {
|
|
if (!removeAll.includes(targetCondition)) continue;
|
|
this.add('-sideend', target.side, this.dex.getEffect(targetCondition).name, '[from] move: Defog', '[of] ' + source);
|
|
success = true;
|
|
}
|
|
}
|
|
for (const sideCondition of removeAll) {
|
|
if (source.side.removeSideCondition(sideCondition)) {
|
|
this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Defog', '[of] ' + source);
|
|
success = true;
|
|
}
|
|
}
|
|
this.field.clearTerrain();
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
zMove: {boost: {accuracy: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
destinybond: {
|
|
num: 194,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Destiny Bond",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {authentic: 1},
|
|
volatileStatus: 'destinybond',
|
|
onPrepareHit(pokemon) {
|
|
return !pokemon.removeVolatile('destinybond');
|
|
},
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add('-singlemove', pokemon, 'Destiny Bond');
|
|
},
|
|
onFaint(target, source, effect) {
|
|
if (!source || !effect || target.side === source.side) return;
|
|
if (effect.effectType === 'Move' && !effect.isFutureMove) {
|
|
if (source.volatiles['dynamax']) {
|
|
this.add('-hint', "Dynamaxed Pokémon are immune to Destiny Bond.");
|
|
return;
|
|
}
|
|
this.add('-activate', target, 'move: Destiny Bond');
|
|
source.faint();
|
|
}
|
|
},
|
|
onBeforeMovePriority: -1,
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (move.id === 'destinybond') return;
|
|
this.debug('removing Destiny Bond before attack');
|
|
pokemon.removeVolatile('destinybond');
|
|
},
|
|
onMoveAborted(pokemon, target, move) {
|
|
pokemon.removeVolatile('destinybond');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ghost",
|
|
zMove: {effect: 'redirect'},
|
|
contestType: "Clever",
|
|
},
|
|
detect: {
|
|
num: 197,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Detect",
|
|
pp: 5,
|
|
priority: 4,
|
|
flags: {},
|
|
stallingMove: true,
|
|
volatileStatus: 'protect',
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent('StallMove', pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fighting",
|
|
zMove: {boost: {evasion: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
devastatingdrake: {
|
|
num: 652,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Devastating Drake",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "dragoniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Cool",
|
|
},
|
|
diamondstorm: {
|
|
num: 591,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Diamond Storm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
self: {
|
|
boosts: {
|
|
def: 2,
|
|
},
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Rock",
|
|
contestType: "Beautiful",
|
|
},
|
|
dig: {
|
|
num: 91,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Dig",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onImmunity(type, pokemon) {
|
|
if (type === 'sandstorm' || type === 'hail') return false;
|
|
},
|
|
onInvulnerability(target, source, move) {
|
|
if (['earthquake', 'magnitude'].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onSourceModifyDamage(damage, source, target, move) {
|
|
if (move.id === 'earthquake' || move.id === 'magnitude') {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough",
|
|
},
|
|
disable: {
|
|
num: 50,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Disable",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
volatileStatus: 'disable',
|
|
onTryHit(target) {
|
|
if (!target.lastMove || target.lastMove.isZ || target.lastMove.isMax) {
|
|
return false;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 5,
|
|
noCopy: true, // doesn't get copied by Baton Pass
|
|
onStart(pokemon, source, effect) {
|
|
// The target hasn't taken its turn, or Cursed Body activated and the move was not used through Dancer or Instruct
|
|
if (
|
|
this.queue.willMove(pokemon) ||
|
|
(pokemon === this.activePokemon && this.activeMove && !this.activeMove.isExternal)
|
|
) {
|
|
this.effectData.duration--;
|
|
}
|
|
if (!pokemon.lastMove) {
|
|
this.debug('pokemon hasn\'t moved yet');
|
|
return false;
|
|
}
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (moveSlot.id === pokemon.lastMove.id) {
|
|
if (!moveSlot.pp) {
|
|
this.debug('Move out of PP');
|
|
return false;
|
|
} else {
|
|
if (effect.id === 'cursedbody') {
|
|
this.add('-start', pokemon, 'Disable', moveSlot.move, '[from] ability: Cursed Body', '[of] ' + source);
|
|
} else {
|
|
this.add('-start', pokemon, 'Disable', moveSlot.move);
|
|
}
|
|
this.effectData.move = pokemon.lastMove.id;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
// this can happen if Disable works on a Z-move
|
|
return false;
|
|
},
|
|
onResidualOrder: 14,
|
|
onEnd(pokemon) {
|
|
this.add('-end', pokemon, 'Disable');
|
|
},
|
|
onBeforeMovePriority: 7,
|
|
onBeforeMove(attacker, defender, move) {
|
|
if (!move.isZ && move.id === this.effectData.move) {
|
|
this.add('cant', attacker, 'Disable', move);
|
|
return false;
|
|
}
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (moveSlot.id === this.effectData.move) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
disarmingvoice: {
|
|
num: 574,
|
|
accuracy: true,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Disarming Voice",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fairy",
|
|
contestType: "Cute",
|
|
},
|
|
discharge: {
|
|
num: 435,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Discharge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Electric",
|
|
contestType: "Beautiful",
|
|
},
|
|
dive: {
|
|
num: 291,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Dive",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
if (attacker.hasAbility('gulpmissile') && attacker.species.name === 'Cramorant' && !attacker.transformed) {
|
|
const forme = attacker.hp <= attacker.maxhp / 2 ? 'cramorantgorging' : 'cramorantgulping';
|
|
attacker.formeChange(forme, move);
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onImmunity(type, pokemon) {
|
|
if (type === 'sandstorm' || type === 'hail') return false;
|
|
},
|
|
onInvulnerability(target, source, move) {
|
|
if (['surf', 'whirlpool'].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onSourceModifyDamage(damage, source, target, move) {
|
|
if (move.id === 'surf' || move.id === 'whirlpool') {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
dizzypunch: {
|
|
num: 146,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Dizzy Punch",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
doomdesire: {
|
|
num: 353,
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Special",
|
|
name: "Doom Desire",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isFutureMove: true,
|
|
onTry(source, target) {
|
|
if (!target.side.addSlotCondition(target, 'futuremove')) return false;
|
|
Object.assign(target.side.slotConditions[target.position]['futuremove'], {
|
|
move: 'doomdesire',
|
|
source: source,
|
|
moveData: {
|
|
id: 'doomdesire',
|
|
name: "Doom Desire",
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Special",
|
|
priority: 0,
|
|
flags: {},
|
|
effectType: 'Move',
|
|
isFutureMove: true,
|
|
type: 'Steel',
|
|
},
|
|
});
|
|
this.add('-start', source, 'Doom Desire');
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Beautiful",
|
|
},
|
|
doubleedge: {
|
|
num: 38,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Double-Edge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
recoil: [33, 100],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
doublehit: {
|
|
num: 458,
|
|
accuracy: 90,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
name: "Double Hit",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 120},
|
|
contestType: "Cool",
|
|
},
|
|
doubleironbash: {
|
|
num: 742,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Double Iron Bash",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
multihit: 2,
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: {basePower: 180},
|
|
maxMove: {basePower: 140},
|
|
contestType: "Clever",
|
|
},
|
|
doublekick: {
|
|
num: 24,
|
|
accuracy: 100,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Double Kick",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
maxMove: {basePower: 80},
|
|
contestType: "Cool",
|
|
},
|
|
doubleslap: {
|
|
num: 3,
|
|
accuracy: 85,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Double Slap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
doubleteam: {
|
|
num: 104,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Double Team",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
evasion: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cool",
|
|
},
|
|
dracometeor: {
|
|
num: 434,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Draco Meteor",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
self: {
|
|
boosts: {
|
|
spa: -2,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Beautiful",
|
|
},
|
|
dragonascent: {
|
|
num: 620,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Dragon Ascent",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, distance: 1},
|
|
self: {
|
|
boosts: {
|
|
def: -1,
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Beautiful",
|
|
},
|
|
dragonbreath: {
|
|
num: 225,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Dragon Breath",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Cool",
|
|
},
|
|
dragonclaw: {
|
|
num: 337,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Dragon Claw",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Cool",
|
|
},
|
|
dragondance: {
|
|
num: 349,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Dragon Dance",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1, dance: 1},
|
|
boosts: {
|
|
atk: 1,
|
|
spe: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dragon",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cool",
|
|
},
|
|
dragondarts: {
|
|
num: 751,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Dragon Darts",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
multihit: 2,
|
|
smartTarget: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
maxMove: {basePower: 130},
|
|
},
|
|
dragonhammer: {
|
|
num: 692,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Dragon Hammer",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Tough",
|
|
},
|
|
dragonpulse: {
|
|
num: 406,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Special",
|
|
name: "Dragon Pulse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, pulse: 1, mirror: 1, distance: 1},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Dragon",
|
|
contestType: "Beautiful",
|
|
},
|
|
dragonrage: {
|
|
num: 82,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damage: 40,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Dragon Rage",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Cool",
|
|
},
|
|
dragonrush: {
|
|
num: 407,
|
|
accuracy: 75,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Dragon Rush",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Tough",
|
|
},
|
|
dragontail: {
|
|
num: 525,
|
|
accuracy: 90,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Dragon Tail",
|
|
pp: 10,
|
|
priority: -6,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
forceSwitch: true,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Tough",
|
|
},
|
|
drainingkiss: {
|
|
num: 577,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Draining Kiss",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, heal: 1},
|
|
drain: [3, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Cute",
|
|
},
|
|
drainpunch: {
|
|
num: 409,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Drain Punch",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1, heal: 1},
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
dreameater: {
|
|
num: 138,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Dream Eater",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, heal: 1},
|
|
drain: [1, 2],
|
|
onTryImmunity(target) {
|
|
return target.status === 'slp' || target.hasAbility('comatose');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
drillpeck: {
|
|
num: 65,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Drill Peck",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, distance: 1},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
drillrun: {
|
|
num: 529,
|
|
accuracy: 95,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Drill Run",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough",
|
|
},
|
|
drumbeating: {
|
|
num: 778,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Drum Beating",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
dualchop: {
|
|
num: 530,
|
|
accuracy: 90,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Dual Chop",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
maxMove: {basePower: 130},
|
|
contestType: "Tough",
|
|
},
|
|
dualwingbeat: {
|
|
num: 814,
|
|
accuracy: 90,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Dual Wingbeat",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
maxMove: {basePower: 130},
|
|
},
|
|
dynamaxcannon: {
|
|
num: 744,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Dynamax Cannon",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
},
|
|
dynamicpunch: {
|
|
num: 223,
|
|
accuracy: 50,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Dynamic Punch",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
earthpower: {
|
|
num: 414,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Earth Power",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Beautiful",
|
|
},
|
|
earthquake: {
|
|
num: 89,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Earthquake",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Ground",
|
|
contestType: "Tough",
|
|
},
|
|
echoedvoice: {
|
|
num: 497,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
basePowerCallback() {
|
|
if (this.field.pseudoWeather.echoedvoice) {
|
|
return 40 * this.field.pseudoWeather.echoedvoice.multiplier;
|
|
}
|
|
return 40;
|
|
},
|
|
category: "Special",
|
|
name: "Echoed Voice",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
onTry() {
|
|
this.field.addPseudoWeather('echoedvoice');
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onStart() {
|
|
this.effectData.multiplier = 1;
|
|
},
|
|
onRestart() {
|
|
if (this.effectData.duration !== 2) {
|
|
this.effectData.duration = 2;
|
|
if (this.effectData.multiplier < 5) {
|
|
this.effectData.multiplier++;
|
|
}
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
eerieimpulse: {
|
|
num: 598,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Eerie Impulse",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
spa: -2,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
eggbomb: {
|
|
num: 121,
|
|
accuracy: 75,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Egg Bomb",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
electricterrain: {
|
|
num: 604,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Electric Terrain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {nonsky: 1},
|
|
terrain: 'electricterrain',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasItem('terrainextender')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onSetStatus(status, target, source, effect) {
|
|
if (status.id === 'slp' && target.isGrounded() && !target.isSemiInvulnerable()) {
|
|
if (effect.id === 'yawn' || (effect.effectType === 'Move' && !effect.secondaries)) {
|
|
this.add('-activate', target, 'move: Electric Terrain');
|
|
}
|
|
return false;
|
|
}
|
|
},
|
|
onTryAddVolatile(status, target) {
|
|
if (!target.isGrounded() || target.isSemiInvulnerable()) return;
|
|
if (status.id === 'yawn') {
|
|
this.add('-activate', target, 'move: Electric Terrain');
|
|
return null;
|
|
}
|
|
},
|
|
onBasePowerPriority: 6,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === 'Electric' && attacker.isGrounded() && !attacker.isSemiInvulnerable()) {
|
|
this.debug('electric terrain boost');
|
|
return this.chainModify([0x14CD, 0x1000]);
|
|
}
|
|
},
|
|
onStart(battle, source, effect) {
|
|
if (effect?.effectType === 'Ability') {
|
|
this.add('-fieldstart', 'move: Electric Terrain', '[from] ability: ' + effect, '[of] ' + source);
|
|
} else {
|
|
this.add('-fieldstart', 'move: Electric Terrain');
|
|
}
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 2,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Electric Terrain');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Electric",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
electrify: {
|
|
num: 582,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Electrify",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, mystery: 1},
|
|
volatileStatus: 'electrify',
|
|
onTryHit(target) {
|
|
if (!this.queue.willMove(target) && target.activeTurns) return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'move: Electrify');
|
|
},
|
|
onModifyTypePriority: -2,
|
|
onModifyType(move) {
|
|
if (move.id !== 'struggle') {
|
|
this.debug('Electrify making move type electric');
|
|
move.type = 'Electric';
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
electroball: {
|
|
num: 486,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
let ratio = Math.floor(pokemon.getStat('spe') / target.getStat('spe'));
|
|
if (!isFinite(ratio)) ratio = 0;
|
|
const bp = [40, 60, 80, 120, 150][Math.min(ratio, 4)];
|
|
this.debug(`${bp} bp`);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
name: "Electro Ball",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cool",
|
|
},
|
|
electroweb: {
|
|
num: 527,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Special",
|
|
name: "Electroweb",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Electric",
|
|
contestType: "Beautiful",
|
|
},
|
|
embargo: {
|
|
num: 373,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Embargo",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
volatileStatus: 'embargo',
|
|
condition: {
|
|
duration: 5,
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'Embargo');
|
|
},
|
|
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
|
|
onResidualOrder: 18,
|
|
onEnd(pokemon) {
|
|
this.add('-end', pokemon, 'Embargo');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
ember: {
|
|
num: 52,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Ember",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cute",
|
|
},
|
|
encore: {
|
|
num: 227,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Encore",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
volatileStatus: 'encore',
|
|
condition: {
|
|
duration: 3,
|
|
noCopy: true, // doesn't get copied by Z-Baton Pass
|
|
onStart(target) {
|
|
const noEncore = [
|
|
'assist', 'copycat', 'encore', 'mefirst', 'metronome', 'mimic', 'mirrormove', 'naturepower', 'sketch', 'sleeptalk', 'struggle', 'transform',
|
|
];
|
|
let move: Move | ActiveMove | null = target.lastMove;
|
|
if (!move || target.volatiles['dynamax']) return false;
|
|
|
|
if (move.isMax && move.baseMove) move = this.dex.getMove(move.baseMove);
|
|
const moveIndex = target.moves.indexOf(move.id);
|
|
if (move.isZ || noEncore.includes(move.id) || !target.moveSlots[moveIndex] || target.moveSlots[moveIndex].pp <= 0) {
|
|
// it failed
|
|
return false;
|
|
}
|
|
this.effectData.move = move.id;
|
|
this.add('-start', target, 'Encore');
|
|
if (!this.queue.willMove(target)) {
|
|
this.effectData.duration++;
|
|
}
|
|
},
|
|
onOverrideAction(pokemon, target, move) {
|
|
if (move.id !== this.effectData.move) return this.effectData.move;
|
|
},
|
|
onResidualOrder: 13,
|
|
onResidual(target) {
|
|
if (target.moves.includes(this.effectData.move) &&
|
|
target.moveSlots[target.moves.indexOf(this.effectData.move)].pp <= 0) {
|
|
// early termination if you run out of PP
|
|
target.removeVolatile('encore');
|
|
}
|
|
},
|
|
onEnd(target) {
|
|
this.add('-end', target, 'Encore');
|
|
},
|
|
onDisableMove(pokemon) {
|
|
if (!this.effectData.move || !pokemon.hasMove(this.effectData.move)) {
|
|
return;
|
|
}
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (moveSlot.id !== this.effectData.move) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
endeavor: {
|
|
num: 283,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
return target.getUndynamaxedHP() - pokemon.hp;
|
|
},
|
|
category: "Physical",
|
|
name: "Endeavor",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTryImmunity(target, pokemon) {
|
|
return pokemon.hp < target.hp;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Tough",
|
|
},
|
|
endure: {
|
|
num: 203,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Endure",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {},
|
|
stallingMove: true,
|
|
volatileStatus: 'endure',
|
|
onTryHit(pokemon) {
|
|
return this.queue.willAct() && this.runEvent('StallMove', pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'move: Endure');
|
|
},
|
|
onDamagePriority: -10,
|
|
onDamage(damage, target, source, effect) {
|
|
if (effect?.effectType === 'Move' && damage >= target.hp) {
|
|
this.add('-activate', target, 'move: Endure');
|
|
return target.hp - 1;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Tough",
|
|
},
|
|
energyball: {
|
|
num: 412,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Energy Ball",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful",
|
|
},
|
|
entrainment: {
|
|
num: 494,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Entrainment",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
onTryHit(target, source) {
|
|
if (target === source || target.volatiles['dynamax']) return false;
|
|
const bannedTargetAbilities = [
|
|
'battlebond', 'comatose', 'disguise', 'multitype', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'truant',
|
|
];
|
|
const bannedSourceAbilities = [
|
|
'battlebond', 'comatose', 'disguise', 'flowergift', 'forecast', 'illusion', 'imposter', 'multitype', 'neutralizinggas', 'powerconstruct', 'powerofalchemy', 'receiver', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'trace', 'zenmode',
|
|
];
|
|
if (
|
|
bannedTargetAbilities.includes(target.ability) || bannedSourceAbilities.includes(source.ability) ||
|
|
target.ability === source.ability
|
|
) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
const oldAbility = target.setAbility(source.ability);
|
|
if (oldAbility) {
|
|
this.add('-ability', target, target.getAbility().name, '[from] move: Entrainment');
|
|
if (target.side !== source.side) target.volatileStaleness = 'external';
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
eruption: {
|
|
num: 284,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return move.basePower * pokemon.hp / pokemon.maxhp;
|
|
},
|
|
category: "Special",
|
|
name: "Eruption",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
eternabeam: {
|
|
num: 795,
|
|
accuracy: 90,
|
|
basePower: 160,
|
|
category: "Special",
|
|
name: "Eternabeam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {recharge: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
},
|
|
expandingforce: {
|
|
num: 797,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Expanding Force",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onBasePower(basePower, source) {
|
|
if (this.field.isTerrain('psychicterrain') && source.isGrounded()) {
|
|
this.debug('terrain buff');
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
onModifyMove(move, source, target) {
|
|
if (this.field.isTerrain('psychicterrain') && source.isGrounded()) {
|
|
move.target = 'allAdjacentFoes';
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
},
|
|
explosion: {
|
|
num: 153,
|
|
accuracy: 100,
|
|
basePower: 250,
|
|
category: "Physical",
|
|
name: "Explosion",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
selfdestruct: "always",
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
extrasensory: {
|
|
num: 326,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Extrasensory",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
extremeevoboost: {
|
|
num: 702,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Extreme Evoboost",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "eeviumz",
|
|
boosts: {
|
|
atk: 2,
|
|
def: 2,
|
|
spa: 2,
|
|
spd: 2,
|
|
spe: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
extremespeed: {
|
|
num: 245,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Extreme Speed",
|
|
pp: 5,
|
|
priority: 2,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
facade: {
|
|
num: 263,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Facade",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onBasePower(basePower, pokemon) {
|
|
if (pokemon.status && pokemon.status !== 'slp') {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
fairylock: {
|
|
num: 587,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Fairy Lock",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {mirror: 1, authentic: 1},
|
|
pseudoWeather: 'fairylock',
|
|
condition: {
|
|
duration: 2,
|
|
onStart(target) {
|
|
this.add('-fieldactivate', 'move: Fairy Lock');
|
|
},
|
|
onTrapPokemon(pokemon) {
|
|
pokemon.tryTrap();
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fairy",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
fairywind: {
|
|
num: 584,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Fairy Wind",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Beautiful",
|
|
},
|
|
fakeout: {
|
|
num: 252,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Fake Out",
|
|
pp: 10,
|
|
priority: 3,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTry(pokemon, target) {
|
|
if (pokemon.activeMoveActions > 1) {
|
|
this.attrLastMove('[still]');
|
|
this.add('-fail', pokemon);
|
|
this.hint("Fake Out only works on your first turn out.");
|
|
return null;
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
faketears: {
|
|
num: 313,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Fake Tears",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
boosts: {
|
|
spd: -2,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
falsesurrender: {
|
|
num: 793,
|
|
accuracy: true,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "False Surrender",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
falseswipe: {
|
|
num: 206,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "False Swipe",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
noFaint: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
featherdance: {
|
|
num: 297,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Feather Dance",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1, dance: 1},
|
|
boosts: {
|
|
atk: -2,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
feint: {
|
|
num: 364,
|
|
accuracy: 100,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Feint",
|
|
pp: 10,
|
|
priority: 2,
|
|
flags: {mirror: 1},
|
|
breaksProtect: true,
|
|
// Breaking protection implemented in scripts.js
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Clever",
|
|
},
|
|
feintattack: {
|
|
num: 185,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Feint Attack",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
fellstinger: {
|
|
num: 565,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Fell Stinger",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onAfterMoveSecondarySelf(pokemon, target, move) {
|
|
if (!target || target.fainted || target.hp <= 0) this.boost({atk: 3}, pokemon, pokemon, move);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool",
|
|
},
|
|
fierydance: {
|
|
num: 552,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Fiery Dance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, dance: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
self: {
|
|
boosts: {
|
|
spa: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
finalgambit: {
|
|
num: 515,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
const damage = pokemon.hp;
|
|
pokemon.faint();
|
|
return damage;
|
|
},
|
|
category: "Special",
|
|
name: "Final Gambit",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
selfdestruct: "ifHit",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
zMove: {basePower: 180},
|
|
contestType: "Tough",
|
|
},
|
|
fireblast: {
|
|
num: 126,
|
|
accuracy: 85,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Fire Blast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
firefang: {
|
|
num: 424,
|
|
accuracy: 95,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Fire Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
secondaries: [
|
|
{
|
|
chance: 10,
|
|
status: 'brn',
|
|
}, {
|
|
chance: 10,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
],
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
firelash: {
|
|
num: 680,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Fire Lash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cute",
|
|
},
|
|
firepledge: {
|
|
num: 519,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
basePowerCallback(target, source, move) {
|
|
if (['grasspledge', 'waterpledge'].includes(move.sourceEffect)) {
|
|
this.add('-combine');
|
|
return 150;
|
|
}
|
|
return 80;
|
|
},
|
|
category: "Special",
|
|
name: "Fire Pledge",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
onPrepareHit(target, source, move) {
|
|
for (const action of this.queue) {
|
|
if (
|
|
// @ts-ignore
|
|
!action.move || !action.pokemon || !action.pokemon.isActive ||
|
|
// @ts-ignore
|
|
action.pokemon.fainted || action.maxMove || action.zmove
|
|
) {
|
|
continue;
|
|
}
|
|
// @ts-ignore
|
|
if (action.pokemon.side === source.side && ['grasspledge', 'waterpledge'].includes(action.move.id)) {
|
|
// @ts-ignore
|
|
this.queue.prioritizeAction(action, move);
|
|
this.add('-waiting', source, action.pokemon);
|
|
return null;
|
|
}
|
|
}
|
|
},
|
|
onModifyMove(move) {
|
|
if (move.sourceEffect === 'waterpledge') {
|
|
move.type = 'Water';
|
|
move.forceSTAB = true;
|
|
move.self = {sideCondition: 'waterpledge'};
|
|
}
|
|
if (move.sourceEffect === 'grasspledge') {
|
|
move.type = 'Fire';
|
|
move.forceSTAB = true;
|
|
move.sideCondition = 'firepledge';
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onStart(targetSide) {
|
|
this.add('-sidestart', targetSide, 'Fire Pledge');
|
|
},
|
|
onEnd(targetSide) {
|
|
for (const pokemon of targetSide.active) {
|
|
if (pokemon && !pokemon.hasType('Fire')) {
|
|
this.damage(pokemon.baseMaxhp / 8, pokemon);
|
|
}
|
|
}
|
|
this.add('-sideend', targetSide, 'Fire Pledge');
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1,
|
|
onResidual(side) {
|
|
for (const pokemon of side.active) {
|
|
if (pokemon && !pokemon.hasType('Fire')) {
|
|
this.damage(pokemon.baseMaxhp / 8, pokemon);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
firepunch: {
|
|
num: 7,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Fire Punch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Tough",
|
|
},
|
|
firespin: {
|
|
num: 83,
|
|
accuracy: 85,
|
|
basePower: 35,
|
|
category: "Special",
|
|
name: "Fire Spin",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
volatileStatus: 'partiallytrapped',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
firstimpression: {
|
|
num: 660,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "First Impression",
|
|
pp: 10,
|
|
priority: 2,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTry(pokemon, target) {
|
|
if (pokemon.activeMoveActions > 1) {
|
|
this.add('-fail', pokemon);
|
|
this.attrLastMove('[still]');
|
|
this.hint("First Impression only works on your first turn out.");
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute",
|
|
},
|
|
fishiousrend: {
|
|
num: 755,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.newlySwitched || this.queue.willMove(target)) {
|
|
this.debug('Fishious Rend damage boost');
|
|
return move.basePower * 2;
|
|
}
|
|
this.debug('Fishious Rend NOT boosted');
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Fishious Rend",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
},
|
|
fissure: {
|
|
num: 90,
|
|
accuracy: 30,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Fissure",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
ohko: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
zMove: {basePower: 180},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Tough",
|
|
},
|
|
flail: {
|
|
num: 175,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const ratio = pokemon.hp * 48 / pokemon.maxhp;
|
|
if (ratio < 2) {
|
|
return 200;
|
|
}
|
|
if (ratio < 5) {
|
|
return 150;
|
|
}
|
|
if (ratio < 10) {
|
|
return 100;
|
|
}
|
|
if (ratio < 17) {
|
|
return 80;
|
|
}
|
|
if (ratio < 33) {
|
|
return 40;
|
|
}
|
|
return 20;
|
|
},
|
|
category: "Physical",
|
|
name: "Flail",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cute",
|
|
},
|
|
flameburst: {
|
|
num: 481,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Flame Burst",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onHit(target, source, move) {
|
|
if (target.side.active.length === 1) {
|
|
return;
|
|
}
|
|
for (const ally of target.side.active) {
|
|
if (ally && this.isAdjacent(target, ally)) {
|
|
this.damage(ally.baseMaxhp / 16, ally, source, this.dex.getEffect('Flame Burst'));
|
|
}
|
|
}
|
|
},
|
|
onAfterSubDamage(damage, target, source, move) {
|
|
if (target.side.active.length === 1) {
|
|
return;
|
|
}
|
|
for (const ally of target.side.active) {
|
|
if (ally && this.isAdjacent(target, ally)) {
|
|
this.damage(ally.baseMaxhp / 16, ally, source, this.dex.getEffect('Flame Burst'));
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
flamecharge: {
|
|
num: 488,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Flame Charge",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
flamewheel: {
|
|
num: 172,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Flame Wheel",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, defrost: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
flamethrower: {
|
|
num: 53,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Flamethrower",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
flareblitz: {
|
|
num: 394,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Flare Blitz",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, defrost: 1},
|
|
recoil: [33, 100],
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
flash: {
|
|
num: 148,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Flash",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {evasion: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
flashcannon: {
|
|
num: 430,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Flash Cannon",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Beautiful",
|
|
},
|
|
flatter: {
|
|
num: 260,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Flatter",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
volatileStatus: 'confusion',
|
|
boosts: {
|
|
spa: 1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
fleurcannon: {
|
|
num: 705,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Fleur Cannon",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
self: {
|
|
boosts: {
|
|
spa: -2,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Beautiful",
|
|
},
|
|
fling: {
|
|
num: 374,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Fling",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, mystery: 1},
|
|
onPrepareHit(target, source, move) {
|
|
if (source.ignoringItem()) return false;
|
|
const item = source.getItem();
|
|
if (!this.singleEvent('TakeItem', item, source.itemData, source, source, move, item)) return false;
|
|
if (!item.fling) return false;
|
|
move.basePower = item.fling.basePower;
|
|
if (item.isBerry) {
|
|
move.onHit = function (foe) {
|
|
if (this.singleEvent('Eat', item, null, foe, null, null)) {
|
|
this.runEvent('EatItem', foe, null, null, item);
|
|
if (item.id === 'leppaberry') foe.staleness = 'external';
|
|
}
|
|
if (item.onEat) foe.ateBerry = true;
|
|
};
|
|
} else if (item.fling.effect) {
|
|
move.onHit = item.fling.effect;
|
|
} else {
|
|
if (!move.secondaries) move.secondaries = [];
|
|
if (item.fling.status) {
|
|
move.secondaries.push({status: item.fling.status});
|
|
} else if (item.fling.volatileStatus) {
|
|
move.secondaries.push({volatileStatus: item.fling.volatileStatus});
|
|
}
|
|
}
|
|
source.setItem('');
|
|
source.lastItem = item.id;
|
|
source.usedItemThisTurn = true;
|
|
this.add("-enditem", source, item.name, '[from] move: Fling');
|
|
this.runEvent('AfterUseItem', source, null, null, item);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cute",
|
|
},
|
|
flipturn: {
|
|
num: 812,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Flip Turn",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
},
|
|
floatyfall: {
|
|
num: 731,
|
|
accuracy: 95,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Floaty Fall",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, gravity: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
floralhealing: {
|
|
num: 666,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Floral Healing",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, heal: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
let success = false;
|
|
if (this.field.isTerrain('grassyterrain')) {
|
|
success = !!this.heal(this.modify(target.baseMaxhp, 0.667)); // TODO: find out the real value
|
|
} else {
|
|
success = !!this.heal(Math.ceil(target.baseMaxhp * 0.5));
|
|
}
|
|
if (success && target.side !== source.side) {
|
|
target.staleness = 'external';
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
flowershield: {
|
|
num: 579,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Flower Shield",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {distance: 1},
|
|
onHitField(t, source, move) {
|
|
const targets: Pokemon[] = [];
|
|
for (const pokemon of this.getAllActive()) {
|
|
if (pokemon.hasType('Grass')) {
|
|
// This move affects every Grass-type Pokemon in play.
|
|
targets.push(pokemon);
|
|
}
|
|
}
|
|
let success = false;
|
|
for (const target of targets) {
|
|
success = this.boost({def: 1}, target, source, move) || success;
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fairy",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
fly: {
|
|
num: 19,
|
|
accuracy: 95,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Fly",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onInvulnerability(target, source, move) {
|
|
if (['gust', 'twister', 'skyuppercut', 'thunder', 'hurricane', 'smackdown', 'thousandarrows'].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onSourceModifyDamage(damage, source, target, move) {
|
|
if (move.id === 'gust' || move.id === 'twister') {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Clever",
|
|
},
|
|
flyingpress: {
|
|
num: 560,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Flying Press",
|
|
pp: 10,
|
|
flags: {contact: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, nonsky: 1},
|
|
onEffectiveness(typeMod, target, type, move) {
|
|
return typeMod + this.dex.getEffectiveness('Flying', type);
|
|
},
|
|
priority: 0,
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Fighting",
|
|
zMove: {basePower: 170},
|
|
contestType: "Tough",
|
|
},
|
|
focusblast: {
|
|
num: 411,
|
|
accuracy: 70,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Focus Blast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
focusenergy: {
|
|
num: 116,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Focus Energy",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
volatileStatus: 'focusenergy',
|
|
condition: {
|
|
onStart(target, source, effect) {
|
|
if (effect?.id === 'zpower') {
|
|
this.add('-start', target, 'move: Focus Energy', '[zeffect]');
|
|
} else if (effect && (['imposter', 'psychup', 'transform'].includes(effect.id))) {
|
|
this.add('-start', target, 'move: Focus Energy', '[silent]');
|
|
} else {
|
|
this.add('-start', target, 'move: Focus Energy');
|
|
}
|
|
},
|
|
onModifyCritRatio(critRatio) {
|
|
return critRatio + 2;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {accuracy: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
focuspunch: {
|
|
num: 264,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
name: "Focus Punch",
|
|
pp: 20,
|
|
priority: -3,
|
|
flags: {contact: 1, protect: 1, punch: 1},
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile('focuspunch');
|
|
},
|
|
beforeMoveCallback(pokemon) {
|
|
if (pokemon.volatiles['focuspunch'] && pokemon.volatiles['focuspunch'].lostFocus) {
|
|
this.add('cant', pokemon, 'Focus Punch', 'Focus Punch');
|
|
return true;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add('-singleturn', pokemon, 'move: Focus Punch');
|
|
},
|
|
onHit(pokemon, source, move) {
|
|
if (move.category !== 'Status') {
|
|
pokemon.volatiles['focuspunch'].lostFocus = true;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
followme: {
|
|
num: 266,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Follow Me",
|
|
pp: 20,
|
|
priority: 2,
|
|
flags: {},
|
|
volatileStatus: 'followme',
|
|
onTryHit(target) {
|
|
if (target.side.active.length < 2) return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source, effect) {
|
|
if (effect?.id === 'zpower') {
|
|
this.add('-singleturn', target, 'move: Follow Me', '[zeffect]');
|
|
} else {
|
|
this.add('-singleturn', target, 'move: Follow Me');
|
|
}
|
|
},
|
|
onFoeRedirectTargetPriority: 1,
|
|
onFoeRedirectTarget(target, source, source2, move) {
|
|
if (!this.effectData.target.isSkyDropped() && this.validTarget(this.effectData.target, source, move.target)) {
|
|
if (move.smartTarget) move.smartTarget = false;
|
|
this.debug("Follow Me redirected target of move");
|
|
return this.effectData.target;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
forcepalm: {
|
|
num: 395,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Force Palm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
foresight: {
|
|
num: 193,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Foresight",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
volatileStatus: 'foresight',
|
|
onTryHit(target) {
|
|
if (target.volatiles['miracleeye']) return false;
|
|
},
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'Foresight');
|
|
},
|
|
onNegateImmunity(pokemon, type) {
|
|
if (pokemon.hasType('Ghost') && ['Normal', 'Fighting'].includes(type)) return false;
|
|
},
|
|
onModifyBoost(boosts) {
|
|
if (boosts.evasion && boosts.evasion > 0) {
|
|
boosts.evasion = 0;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {effect: 'crit2'},
|
|
contestType: "Clever",
|
|
},
|
|
forestscurse: {
|
|
num: 571,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Forest's Curse",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
onHit(target) {
|
|
if (target.hasType('Grass')) return false;
|
|
if (!target.addType('Grass')) return false;
|
|
this.add('-start', target, 'typeadd', 'Grass', '[from] move: Forest\'s Curse');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {boost: {atk: 1, def: 1, spa: 1, spd: 1, spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
foulplay: {
|
|
num: 492,
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Physical",
|
|
name: "Foul Play",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
useTargetOffensive: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
freezedry: {
|
|
num: 573,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
name: "Freeze-Dry",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onEffectiveness(typeMod, target, type) {
|
|
if (type === 'Water') return 1;
|
|
},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'frz',
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
freezeshock: {
|
|
num: 553,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Physical",
|
|
name: "Freeze Shock",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {charge: 1, protect: 1, mirror: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
freezyfrost: {
|
|
num: 739,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Freezy Frost",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
onHit() {
|
|
this.add('-clearallboost');
|
|
for (const pokemon of this.getAllActive()) {
|
|
pokemon.clearBoosts();
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Clever",
|
|
},
|
|
frenzyplant: {
|
|
num: 338,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Frenzy Plant",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {recharge: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
frostbreath: {
|
|
num: 524,
|
|
accuracy: 90,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Frost Breath",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
willCrit: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
frustration: {
|
|
num: 218,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
return Math.floor(((255 - pokemon.happiness) * 10) / 25) || 1;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Frustration",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cute",
|
|
},
|
|
furyattack: {
|
|
num: 31,
|
|
accuracy: 85,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Fury Attack",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
furycutter: {
|
|
num: 210,
|
|
accuracy: 95,
|
|
basePower: 40,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (!pokemon.volatiles['furycutter'] || move.hit === 1) {
|
|
pokemon.addVolatile('furycutter');
|
|
}
|
|
return this.clampIntRange(move.basePower * pokemon.volatiles['furycutter'].multiplier, 1, 160);
|
|
},
|
|
category: "Physical",
|
|
name: "Fury Cutter",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
condition: {
|
|
duration: 2,
|
|
onStart() {
|
|
this.effectData.multiplier = 1;
|
|
},
|
|
onRestart() {
|
|
if (this.effectData.multiplier < 4) {
|
|
this.effectData.multiplier <<= 1;
|
|
}
|
|
this.effectData.duration = 2;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool",
|
|
},
|
|
furyswipes: {
|
|
num: 154,
|
|
accuracy: 80,
|
|
basePower: 18,
|
|
category: "Physical",
|
|
name: "Fury Swipes",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
maxMove: {basePower: 100},
|
|
contestType: "Tough",
|
|
},
|
|
fusionbolt: {
|
|
num: 559,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Fusion Bolt",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onBasePower(basePower, pokemon) {
|
|
if (this.lastSuccessfulMoveThisTurn === 'fusionflare') {
|
|
this.debug('double power');
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
fusionflare: {
|
|
num: 558,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Fusion Flare",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, defrost: 1},
|
|
onBasePower(basePower, pokemon) {
|
|
if (this.lastSuccessfulMoveThisTurn === 'fusionbolt') {
|
|
this.debug('double power');
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
futuresight: {
|
|
num: 248,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Future Sight",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
ignoreImmunity: true,
|
|
isFutureMove: true,
|
|
onTry(source, target) {
|
|
if (!target.side.addSlotCondition(target, 'futuremove')) return false;
|
|
Object.assign(target.side.slotConditions[target.position]['futuremove'], {
|
|
duration: 3,
|
|
move: 'futuresight',
|
|
source: source,
|
|
moveData: {
|
|
id: 'futuresight',
|
|
name: "Future Sight",
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
priority: 0,
|
|
flags: {},
|
|
ignoreImmunity: false,
|
|
effectType: 'Move',
|
|
isFutureMove: true,
|
|
type: 'Psychic',
|
|
},
|
|
});
|
|
this.add('-start', source, 'move: Future Sight');
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
gastroacid: {
|
|
num: 380,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Gastro Acid",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
volatileStatus: 'gastroacid',
|
|
onTryHit(pokemon) {
|
|
const bannedAbilities = [
|
|
'battlebond', 'comatose', 'disguise', 'multitype', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'zenmode',
|
|
];
|
|
if (bannedAbilities.includes(pokemon.ability)) {
|
|
return false;
|
|
}
|
|
},
|
|
condition: {
|
|
// Ability suppression implemented in Pokemon.ignoringAbility() within sim/pokemon.js
|
|
onStart(pokemon) {
|
|
this.add('-endability', pokemon);
|
|
this.singleEvent('End', pokemon.getAbility(), pokemon.abilityData, pokemon, pokemon, 'gastroacid');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
geargrind: {
|
|
num: 544,
|
|
accuracy: 85,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Gear Grind",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: {basePower: 180},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Clever",
|
|
},
|
|
gearup: {
|
|
num: 674,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Gear Up",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1, authentic: 1},
|
|
onHitSide(side, source, move) {
|
|
const targets = [];
|
|
for (const pokemon of side.active) {
|
|
if (pokemon.hasAbility(['plus', 'minus'])) {
|
|
targets.push(pokemon);
|
|
}
|
|
}
|
|
if (!targets.length) return false;
|
|
let didSomething = false;
|
|
for (const target of targets) {
|
|
didSomething = this.boost({atk: 1, spa: 1}, target, source, move, false, true) || didSomething;
|
|
}
|
|
return didSomething;
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Steel",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
genesissupernova: {
|
|
num: 703,
|
|
accuracy: true,
|
|
basePower: 185,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Genesis Supernova",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "mewniumz",
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
onHit() {
|
|
this.field.setTerrain('psychicterrain');
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
geomancy: {
|
|
num: 601,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Geomancy",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {charge: 1, nonsky: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
boosts: {
|
|
spa: 2,
|
|
spd: 2,
|
|
spe: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fairy",
|
|
zMove: {boost: {atk: 1, def: 1, spa: 1, spd: 1, spe: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
gigadrain: {
|
|
num: 202,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Special",
|
|
name: "Giga Drain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, heal: 1},
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever",
|
|
},
|
|
gigaimpact: {
|
|
num: 416,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
name: "Giga Impact",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, recharge: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
gigavolthavoc: {
|
|
num: 646,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Gigavolt Havoc",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "electriumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
glaciate: {
|
|
num: 549,
|
|
accuracy: 95,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Glaciate",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
glare: {
|
|
num: 137,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Glare",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'par',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
glitzyglow: {
|
|
num: 736,
|
|
accuracy: 95,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Glitzy Glow",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
self: {
|
|
sideCondition: 'lightscreen',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
gmaxbefuddle: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Befuddle",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Butterfree",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
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);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Bug",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxcannonade: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Cannonade",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Blastoise",
|
|
self: {
|
|
onHit(source) {
|
|
source.side.foe.addSideCondition('gmaxcannonade');
|
|
},
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onStart(targetSide) {
|
|
this.add('-sidestart', targetSide, 'G-Max Cannonade');
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1.1,
|
|
onResidual(targetSide) {
|
|
for (const pokemon of targetSide.active) {
|
|
if (!pokemon.hasType('Water')) this.damage(pokemon.baseMaxhp / 6, pokemon);
|
|
}
|
|
},
|
|
onEnd(targetSide) {
|
|
for (const pokemon of targetSide.active) {
|
|
if (!pokemon.hasType('Water')) this.damage(pokemon.baseMaxhp / 6, pokemon);
|
|
}
|
|
this.add('-sideend', targetSide, 'G-Max Cannonade');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxcentiferno: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Centiferno",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Centiskorch",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
pokemon.addVolatile('partiallytrapped', source, this.dex.getActiveMove('G-Max Centiferno'));
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxchistrike: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Chi Strike",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Machamp",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.active) {
|
|
pokemon.addVolatile('gmaxchistrike');
|
|
}
|
|
},
|
|
},
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(target, source, effect) {
|
|
this.effectData.layers = 1;
|
|
if (!['imposter', 'psychup', 'transform'].includes(effect?.id)) {
|
|
this.add('-start', target, 'move: G-Max Chi Strike');
|
|
}
|
|
},
|
|
onRestart(target, source, effect) {
|
|
if (this.effectData.layers >= 3) return false;
|
|
this.effectData.layers++;
|
|
if (!['imposter', 'psychup', 'transform'].includes(effect?.id)) {
|
|
this.add('-start', target, 'move: G-Max Chi Strike');
|
|
}
|
|
},
|
|
onModifyCritRatio(critRatio) {
|
|
return critRatio + this.effectData.layers;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxcuddle: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Cuddle",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Eevee",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
pokemon.addVolatile('attract');
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxdepletion: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Depletion",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Duraludon",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
const move = pokemon.lastMove;
|
|
if (move && !move.isZ && !move.isMax) {
|
|
const ppDeducted = pokemon.deductPP(move.id, 4);
|
|
if (ppDeducted) {
|
|
this.add("-activate", pokemon, 'move: Max Depletion', move.name, ppDeducted);
|
|
return;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Dragon",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxdrumsolo: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 160,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Drum Solo",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Rillaboom",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxfinale: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Finale",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Alcremie",
|
|
self: {
|
|
onHit(target, source, move) {
|
|
for (const pokemon of source.side.active) {
|
|
this.heal(pokemon.maxhp / 6, pokemon, source, move);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fairy",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxfireball: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 160,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Fireball",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Cinderace",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxfoamburst: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Foam Burst",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Kingler",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
this.boost({spe: -2}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxgoldrush: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Gold Rush",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Meowth",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
pokemon.addVolatile('confusion');
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxgravitas: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Gravitas",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Orbeetle",
|
|
self: {
|
|
pseudoWeather: 'gravity',
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxhydrosnipe: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 160,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Hydrosnipe",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Inteleon",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxmalodor: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Malodor",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Garbodor",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
pokemon.trySetStatus('psn', source);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Poison",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxmeltdown: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Meltdown",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Melmetal",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
if (!pokemon.volatiles['dynamax']) pokemon.addVolatile('torment');
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxoneblow: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max One Blow",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Urshifu",
|
|
breaksProtect: true,
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Dark",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxrapidflow: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Rapid Flow",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Urshifu-Rapid-Strike",
|
|
breaksProtect: true,
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxreplenish: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Replenish",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Snorlax",
|
|
self: {
|
|
onHit(source) {
|
|
if (this.random(2) === 0) return;
|
|
for (const pokemon of source.side.active) {
|
|
if (!pokemon.item && pokemon.lastItem && this.dex.getItem(pokemon.lastItem).isBerry) {
|
|
const item = pokemon.lastItem;
|
|
pokemon.lastItem = '';
|
|
this.add('-item', pokemon, this.dex.getItem(item), '[from] move: G-Max Replenish');
|
|
pokemon.setItem(item);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxresonance: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Resonance",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Lapras",
|
|
self: {
|
|
sideCondition: 'auroraveil',
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Ice",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxsandblast: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Sandblast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Sandaconda",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
pokemon.addVolatile('partiallytrapped', source, this.dex.getActiveMove('G-Max Sandblast'));
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Ground",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxsmite: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Smite",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Hatterene",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
pokemon.addVolatile('confusion', source);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fairy",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxsnooze: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Snooze",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Grimmsnarl",
|
|
onHit(target) {
|
|
if (target.status || !target.runStatusImmunity('slp')) return;
|
|
if (this.random(2) === 0) return;
|
|
target.addVolatile('yawn');
|
|
},
|
|
onAfterSubDamage(damage, target) {
|
|
if (target.status || !target.runStatusImmunity('slp')) return;
|
|
if (this.random(2) === 0) return;
|
|
target.addVolatile('yawn');
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Dark",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxsteelsurge: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Steelsurge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Copperajah",
|
|
self: {
|
|
onHit(source) {
|
|
source.side.foe.addSideCondition('gmaxsteelsurge');
|
|
},
|
|
},
|
|
condition: {
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'move: G-Max Steelsurge');
|
|
},
|
|
onSwitchIn(pokemon) {
|
|
if (pokemon.hasItem('heavydutyboots')) 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 * Math.pow(2, typeMod) / 8);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxstonesurge: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Stonesurge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Drednaw",
|
|
self: {
|
|
onHit(source) {
|
|
source.side.foe.addSideCondition('stealthrock');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxstunshock: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Stun Shock",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Toxtricity",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
const result = this.random(2);
|
|
if (result === 0) {
|
|
pokemon.trySetStatus('par', source);
|
|
} else {
|
|
pokemon.trySetStatus('psn', source);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxsweetness: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Sweetness",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Appletun",
|
|
self: {
|
|
onHit(source) {
|
|
for (const ally of source.side.pokemon) {
|
|
ally.cureStatus();
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxtartness: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Tartness",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Flapple",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
this.boost({evasion: -1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxterror: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Terror",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Gengar",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
pokemon.addVolatile('trapped', source, null, 'trapper');
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxvinelash: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Vine Lash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Venusaur",
|
|
self: {
|
|
onHit(source) {
|
|
source.side.foe.addSideCondition('gmaxvinelash');
|
|
},
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onStart(targetSide) {
|
|
this.add('-sidestart', targetSide, 'G-Max Vine Lash');
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1.1,
|
|
onResidual(targetSide) {
|
|
for (const pokemon of targetSide.active) {
|
|
if (!pokemon.hasType('Grass')) this.damage(pokemon.baseMaxhp / 6, pokemon);
|
|
}
|
|
},
|
|
onEnd(targetSide) {
|
|
for (const pokemon of targetSide.active) {
|
|
if (!pokemon.hasType('Grass')) this.damage(pokemon.baseMaxhp / 6, pokemon);
|
|
}
|
|
this.add('-sideend', targetSide, 'G-Max Vine Lash');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxvolcalith: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Volcalith",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Coalossal",
|
|
self: {
|
|
onHit(source) {
|
|
source.side.foe.addSideCondition('gmaxvolcalith');
|
|
},
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onStart(targetSide) {
|
|
this.add('-sidestart', targetSide, 'G-Max Volcalith');
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1.1,
|
|
onResidual(targetSide) {
|
|
for (const pokemon of targetSide.active) {
|
|
if (!pokemon.hasType('Rock')) this.damage(pokemon.baseMaxhp / 6, pokemon);
|
|
}
|
|
},
|
|
onEnd(targetSide) {
|
|
for (const pokemon of targetSide.active) {
|
|
if (!pokemon.hasType('Rock')) this.damage(pokemon.baseMaxhp / 6, pokemon);
|
|
}
|
|
this.add('-sideend', targetSide, 'G-Max Volcalith');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Rock",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxvoltcrash: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Volt Crash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Pikachu",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.side.foe.active) {
|
|
pokemon.trySetStatus('par', source);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxwildfire: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Wildfire",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Charizard",
|
|
self: {
|
|
onHit(source) {
|
|
source.side.foe.addSideCondition('gmaxwildfire');
|
|
},
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onStart(targetSide) {
|
|
this.add('-sidestart', targetSide, 'G-Max Wildfire');
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1.1,
|
|
onResidual(targetSide) {
|
|
for (const pokemon of targetSide.active) {
|
|
if (!pokemon.hasType('Fire')) this.damage(pokemon.baseMaxhp / 6, pokemon);
|
|
}
|
|
},
|
|
onEnd(targetSide) {
|
|
for (const pokemon of targetSide.active) {
|
|
if (!pokemon.hasType('Fire')) this.damage(pokemon.baseMaxhp / 6, pokemon);
|
|
}
|
|
this.add('-sideend', targetSide, 'G-Max Wildfire');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
gmaxwindrage: {
|
|
num: 1000,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax", name: "G-Max Wind Rage",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Corviknight",
|
|
self: {
|
|
onHit(source) {
|
|
let success = false;
|
|
const removeTarget = [
|
|
'reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb',
|
|
];
|
|
const removeAll = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb', 'gmaxsteelsurge'];
|
|
for (const targetCondition of removeTarget) {
|
|
if (source.side.foe.removeSideCondition(targetCondition)) {
|
|
if (!removeAll.includes(targetCondition)) continue;
|
|
this.add('-sideend', source.side.foe, this.dex.getEffect(targetCondition).name, '[from] move: G-Max Wind Rage', '[of] ' + source);
|
|
success = true;
|
|
}
|
|
}
|
|
for (const sideCondition of removeAll) {
|
|
if (source.side.removeSideCondition(sideCondition)) {
|
|
this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: G-Max Wind Rage', '[of] ' + source);
|
|
success = true;
|
|
}
|
|
}
|
|
this.field.clearTerrain();
|
|
return success;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
grassknot: {
|
|
num: 447,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const targetWeight = target.getWeight();
|
|
if (targetWeight >= 2000) {
|
|
this.debug('120 bp');
|
|
return 120;
|
|
}
|
|
if (targetWeight >= 1000) {
|
|
this.debug('100 bp');
|
|
return 100;
|
|
}
|
|
if (targetWeight >= 500) {
|
|
this.debug('80 bp');
|
|
return 80;
|
|
}
|
|
if (targetWeight >= 250) {
|
|
this.debug('60 bp');
|
|
return 60;
|
|
}
|
|
if (targetWeight >= 100) {
|
|
this.debug('40 bp');
|
|
return 40;
|
|
}
|
|
this.debug('20 bp');
|
|
return 20;
|
|
},
|
|
category: "Special",
|
|
name: "Grass Knot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
onTryHit(target, source, move) {
|
|
if (target.volatiles['dynamax']) {
|
|
this.add('-fail', source, 'move: Grass Knot', '[from] Dynamax');
|
|
this.attrLastMove('[still]');
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cute",
|
|
},
|
|
grasspledge: {
|
|
num: 520,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
basePowerCallback(target, source, move) {
|
|
if (['waterpledge', 'firepledge'].includes(move.sourceEffect)) {
|
|
this.add('-combine');
|
|
return 150;
|
|
}
|
|
return 80;
|
|
},
|
|
category: "Special",
|
|
name: "Grass Pledge",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
onPrepareHit(target, source, move) {
|
|
for (const action of this.queue) {
|
|
if (
|
|
// @ts-ignore
|
|
!action.move || !action.pokemon || !action.pokemon.isActive ||
|
|
// @ts-ignore
|
|
action.pokemon.fainted || action.maxMove || action.zmove
|
|
) {
|
|
continue;
|
|
}
|
|
// @ts-ignore
|
|
if (action.pokemon.side === source.side && ['waterpledge', 'firepledge'].includes(action.move.id)) {
|
|
// @ts-ignore
|
|
this.queue.prioritizeAction(action, move);
|
|
this.add('-waiting', source, action.pokemon);
|
|
return null;
|
|
}
|
|
}
|
|
},
|
|
onModifyMove(move) {
|
|
if (move.sourceEffect === 'waterpledge') {
|
|
move.type = 'Grass';
|
|
move.forceSTAB = true;
|
|
move.sideCondition = 'grasspledge';
|
|
}
|
|
if (move.sourceEffect === 'firepledge') {
|
|
move.type = 'Fire';
|
|
move.forceSTAB = true;
|
|
move.sideCondition = 'firepledge';
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onStart(targetSide) {
|
|
this.add('-sidestart', targetSide, 'Grass Pledge');
|
|
},
|
|
onEnd(targetSide) {
|
|
this.add('-sideend', targetSide, 'Grass Pledge');
|
|
},
|
|
onModifySpe(spe, pokemon) {
|
|
return this.chainModify(0.25);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful",
|
|
},
|
|
grasswhistle: {
|
|
num: 320,
|
|
accuracy: 55,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Grass Whistle",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, authentic: 1},
|
|
status: 'slp',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
grassyglide: {
|
|
num: 803,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Grassy Glide",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mystery: 1},
|
|
onModifyPriority(priority, source, target, move) {
|
|
if (this.field.isTerrain('grassyterrain') && source.isGrounded()) {
|
|
return priority + 1;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
grassyterrain: {
|
|
num: 580,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Grassy Terrain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {nonsky: 1},
|
|
terrain: 'grassyterrain',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasItem('terrainextender')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onBasePowerPriority: 6,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
const weakenedMoves = ['earthquake', 'bulldoze', 'magnitude'];
|
|
if (weakenedMoves.includes(move.id)) {
|
|
this.debug('move weakened by grassy terrain');
|
|
return this.chainModify(0.5);
|
|
}
|
|
if (move.type === 'Grass' && attacker.isGrounded()) {
|
|
this.debug('grassy terrain boost');
|
|
return this.chainModify([0x14CD, 0x1000]);
|
|
}
|
|
},
|
|
onStart(battle, source, effect) {
|
|
if (effect?.effectType === 'Ability') {
|
|
this.add('-fieldstart', 'move: Grassy Terrain', '[from] ability: ' + effect, '[of] ' + source);
|
|
} else {
|
|
this.add('-fieldstart', 'move: Grassy Terrain');
|
|
}
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 3,
|
|
onResidual() {
|
|
this.eachEvent('Terrain');
|
|
},
|
|
onTerrain(pokemon) {
|
|
if (pokemon.isGrounded() && !pokemon.isSemiInvulnerable()) {
|
|
this.debug('Pokemon is grounded, healing through Grassy Terrain.');
|
|
this.heal(pokemon.baseMaxhp / 16, pokemon, pokemon);
|
|
}
|
|
},
|
|
onEnd() {
|
|
if (!this.effectData.duration) this.eachEvent('Terrain');
|
|
this.add('-fieldend', 'move: Grassy Terrain');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Grass",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
gravapple: {
|
|
num: 788,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Grav Apple",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onBasePower(basePower) {
|
|
if (this.field.getPseudoWeather('gravity')) {
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
gravity: {
|
|
num: 356,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Gravity",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {nonsky: 1},
|
|
pseudoWeather: 'gravity',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasAbility('persistent')) {
|
|
this.add('-activate', source, 'ability: Persistent', effect);
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onStart() {
|
|
this.add('-fieldstart', 'move: Gravity');
|
|
for (const pokemon of this.getAllActive()) {
|
|
let applies = false;
|
|
if (pokemon.removeVolatile('bounce') || pokemon.removeVolatile('fly')) {
|
|
applies = true;
|
|
this.queue.cancelMove(pokemon);
|
|
pokemon.removeVolatile('twoturnmove');
|
|
}
|
|
if (pokemon.volatiles['skydrop']) {
|
|
applies = true;
|
|
this.queue.cancelMove(pokemon);
|
|
|
|
if (pokemon.volatiles['skydrop'].source) {
|
|
this.add('-end', pokemon.volatiles['twoturnmove'].source, 'Sky Drop', '[interrupt]');
|
|
}
|
|
pokemon.removeVolatile('skydrop');
|
|
pokemon.removeVolatile('twoturnmove');
|
|
}
|
|
if (pokemon.volatiles['magnetrise']) {
|
|
applies = true;
|
|
delete pokemon.volatiles['magnetrise'];
|
|
}
|
|
if (pokemon.volatiles['telekinesis']) {
|
|
applies = true;
|
|
delete pokemon.volatiles['telekinesis'];
|
|
}
|
|
if (applies) this.add('-activate', pokemon, 'move: Gravity');
|
|
}
|
|
},
|
|
onModifyAccuracy(accuracy) {
|
|
if (typeof accuracy !== 'number') return;
|
|
return accuracy * 5 / 3;
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (this.dex.getMove(moveSlot.id).flags['gravity']) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
// groundedness implemented in battle.engine.js:BattlePokemon#isGrounded
|
|
onBeforeMovePriority: 6,
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (move.flags['gravity']) {
|
|
this.add('cant', pokemon, 'move: Gravity', move);
|
|
return false;
|
|
}
|
|
},
|
|
onResidualOrder: 22,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Gravity');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
growl: {
|
|
num: 45,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Growl",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, authentic: 1},
|
|
boosts: {
|
|
atk: -1,
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
growth: {
|
|
num: 74,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Growth",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onModifyMove(move, pokemon) {
|
|
if (['sunnyday', 'desolateland'].includes(pokemon.effectiveWeather())) move.boosts = {atk: 2, spa: 2};
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
spa: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
grudge: {
|
|
num: 288,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Grudge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {authentic: 1},
|
|
volatileStatus: 'grudge',
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add('-singlemove', pokemon, 'Grudge');
|
|
},
|
|
onFaint(target, source, effect) {
|
|
if (!source || source.fainted || !effect) return;
|
|
if (effect.effectType === 'Move' && !effect.isFutureMove && source.lastMove) {
|
|
for (const moveSlot of source.moveSlots) {
|
|
if (moveSlot.id === source.lastMove.id) {
|
|
moveSlot.pp = 0;
|
|
this.add('-activate', source, 'move: Grudge', this.dex.getMove(source.lastMove.id).name);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
onBeforeMovePriority: 100,
|
|
onBeforeMove(pokemon) {
|
|
this.debug('removing Grudge before attack');
|
|
pokemon.removeVolatile('grudge');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ghost",
|
|
zMove: {effect: 'redirect'},
|
|
contestType: "Tough",
|
|
},
|
|
guardianofalola: {
|
|
num: 698,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
const hp75 = Math.floor(target.getUndynamaxedHP() * 3 / 4);
|
|
if (
|
|
target.volatiles['protect'] || target.volatiles['banefulbunker'] || target.volatiles['kingsshield'] ||
|
|
target.volatiles['spikyshield'] || target.side.getSideCondition('matblock')
|
|
) {
|
|
this.add('-zbroken', target);
|
|
return this.clampIntRange(Math.ceil(hp75 / 4 - 0.5), 1);
|
|
}
|
|
return this.clampIntRange(hp75, 1);
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Guardian of Alola",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "tapuniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Tough",
|
|
},
|
|
guardsplit: {
|
|
num: 470,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Guard Split",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
const newdef = Math.floor((target.storedStats.def + source.storedStats.def) / 2);
|
|
target.storedStats.def = newdef;
|
|
source.storedStats.def = newdef;
|
|
const newspd = Math.floor((target.storedStats.spd + source.storedStats.spd) / 2);
|
|
target.storedStats.spd = newspd;
|
|
source.storedStats.spd = newspd;
|
|
this.add('-activate', source, 'move: Guard Split', '[of] ' + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
guardswap: {
|
|
num: 385,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Guard Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, authentic: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
const targetBoosts: SparseBoostsTable = {};
|
|
const sourceBoosts: SparseBoostsTable = {};
|
|
|
|
const defSpd: BoostName[] = ['def', 'spd'];
|
|
for (const stat of defSpd) {
|
|
targetBoosts[stat] = target.boosts[stat];
|
|
sourceBoosts[stat] = source.boosts[stat];
|
|
}
|
|
|
|
source.setBoost(targetBoosts);
|
|
target.setBoost(sourceBoosts);
|
|
|
|
this.add('-swapboost', source, target, 'def, spd', '[from] move: Guard Swap');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
guillotine: {
|
|
num: 12,
|
|
accuracy: 30,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Guillotine",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
ohko: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 180},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cool",
|
|
},
|
|
gunkshot: {
|
|
num: 441,
|
|
accuracy: 80,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Gunk Shot",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough",
|
|
},
|
|
gust: {
|
|
num: 16,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Gust",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, distance: 1},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Clever",
|
|
},
|
|
gyroball: {
|
|
num: 360,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
let power = Math.floor(25 * target.getStat('spe') / pokemon.getStat('spe')) + 1;
|
|
if (!isFinite(power)) power = 1;
|
|
if (power > 150) power = 150;
|
|
this.debug(`${power} bp`);
|
|
return power;
|
|
},
|
|
category: "Physical",
|
|
name: "Gyro Ball",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {bullet: 1, contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cool",
|
|
},
|
|
hail: {
|
|
num: 258,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Hail",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
weather: 'hail',
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ice",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
hammerarm: {
|
|
num: 359,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Hammer Arm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
self: {
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
happyhour: {
|
|
num: 603,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Happy Hour",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryHit(target, source) {
|
|
this.add('-activate', target, 'move: Happy Hour');
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1, def: 1, spa: 1, spd: 1, spe: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
harden: {
|
|
num: 106,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Harden",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
haze: {
|
|
num: 114,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Haze",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {authentic: 1},
|
|
onHitField() {
|
|
this.add('-clearallboost');
|
|
for (const pokemon of this.getAllActive()) {
|
|
pokemon.clearBoosts();
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ice",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Beautiful",
|
|
},
|
|
headbutt: {
|
|
num: 29,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Headbutt",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
headcharge: {
|
|
num: 543,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Head Charge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
recoil: [1, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
headsmash: {
|
|
num: 457,
|
|
accuracy: 80,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
name: "Head Smash",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
recoil: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough",
|
|
},
|
|
healbell: {
|
|
num: 215,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Heal Bell",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, sound: 1, distance: 1, authentic: 1},
|
|
onHit(pokemon, source) {
|
|
this.add('-activate', source, 'move: Heal Bell');
|
|
const side = pokemon.side;
|
|
let success = false;
|
|
for (const ally of side.pokemon) {
|
|
if (ally !== source && ally.hasAbility('soundproof')) continue;
|
|
if (ally.cureStatus()) success = true;
|
|
}
|
|
return success;
|
|
},
|
|
target: "allyTeam",
|
|
type: "Normal",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Beautiful",
|
|
},
|
|
healblock: {
|
|
num: 377,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Heal Block",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
volatileStatus: 'healblock',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasAbility('persistent')) {
|
|
this.add('-activate', source, 'ability: Persistent', effect);
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'move: Heal Block');
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (this.dex.getMove(moveSlot.id).flags['heal']) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
onBeforeMovePriority: 6,
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (move.flags['heal'] && !move.isZ && !move.isMax) {
|
|
this.add('cant', pokemon, 'move: Heal Block', move);
|
|
return false;
|
|
}
|
|
},
|
|
onResidualOrder: 17,
|
|
onEnd(pokemon) {
|
|
this.add('-end', pokemon, 'move: Heal Block');
|
|
},
|
|
onTryHeal(damage, target, source, effect) {
|
|
if ((effect?.id === 'zpower') || this.effectData.isZ) return damage;
|
|
return false;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Psychic",
|
|
zMove: {boost: {spa: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
healingwish: {
|
|
num: 361,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Healing Wish",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onTryHit(pokemon, target, move) {
|
|
if (!this.canSwitch(pokemon.side)) {
|
|
delete move.selfdestruct;
|
|
return false;
|
|
}
|
|
},
|
|
selfdestruct: "ifHit",
|
|
slotCondition: 'healingwish',
|
|
condition: {
|
|
onSwap(target) {
|
|
if (!target.fainted && (target.hp < target.maxhp || target.status)) {
|
|
target.heal(target.maxhp);
|
|
target.setStatus('');
|
|
this.add('-heal', target, target.getHealth, '[from] move: Healing Wish');
|
|
target.side.removeSlotCondition(target, 'healingwish');
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
contestType: "Beautiful",
|
|
},
|
|
healorder: {
|
|
num: 456,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Heal Order",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
healpulse: {
|
|
num: 505,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Heal Pulse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, pulse: 1, reflectable: 1, distance: 1, heal: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
let success = false;
|
|
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.side !== source.side) {
|
|
target.staleness = 'external';
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Psychic",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
heartstamp: {
|
|
num: 531,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Heart Stamp",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cute",
|
|
},
|
|
heartswap: {
|
|
num: 391,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Heart Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, authentic: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
const targetBoosts: SparseBoostsTable = {};
|
|
const sourceBoosts: SparseBoostsTable = {};
|
|
|
|
let i: BoostName;
|
|
for (i in target.boosts) {
|
|
targetBoosts[i] = target.boosts[i];
|
|
sourceBoosts[i] = source.boosts[i];
|
|
}
|
|
|
|
target.setBoost(sourceBoosts);
|
|
source.setBoost(targetBoosts);
|
|
|
|
this.add('-swapboost', source, target, '[from] move: Heart Swap');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {effect: 'crit2'},
|
|
contestType: "Clever",
|
|
},
|
|
heatcrash: {
|
|
num: 535,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const targetWeight = target.getWeight();
|
|
const pokemonWeight = pokemon.getWeight();
|
|
if (pokemonWeight > targetWeight * 5) {
|
|
return 120;
|
|
}
|
|
if (pokemonWeight > targetWeight * 4) {
|
|
return 100;
|
|
}
|
|
if (pokemonWeight > targetWeight * 3) {
|
|
return 80;
|
|
}
|
|
if (pokemonWeight > targetWeight * 2) {
|
|
return 60;
|
|
}
|
|
return 40;
|
|
},
|
|
category: "Physical",
|
|
name: "Heat Crash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
onTryHit(target, pokemon, move) {
|
|
if (target.volatiles['dynamax']) {
|
|
this.add('-fail', pokemon, 'Dynamax');
|
|
this.attrLastMove('[still]');
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Tough",
|
|
},
|
|
heatwave: {
|
|
num: 257,
|
|
accuracy: 90,
|
|
basePower: 95,
|
|
category: "Special",
|
|
name: "Heat Wave",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'brn',
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
heavyslam: {
|
|
num: 484,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const targetWeight = target.getWeight();
|
|
const pokemonWeight = pokemon.getWeight();
|
|
if (pokemonWeight > targetWeight * 5) {
|
|
return 120;
|
|
}
|
|
if (pokemonWeight > targetWeight * 4) {
|
|
return 100;
|
|
}
|
|
if (pokemonWeight > targetWeight * 3) {
|
|
return 80;
|
|
}
|
|
if (pokemonWeight > targetWeight * 2) {
|
|
return 60;
|
|
}
|
|
return 40;
|
|
},
|
|
category: "Physical",
|
|
name: "Heavy Slam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
onTryHit(target, pokemon, move) {
|
|
if (target.volatiles['dynamax']) {
|
|
this.add('-fail', pokemon, 'Dynamax');
|
|
this.attrLastMove('[still]');
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Tough",
|
|
},
|
|
helpinghand: {
|
|
num: 270,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Helping Hand",
|
|
pp: 20,
|
|
priority: 5,
|
|
flags: {authentic: 1},
|
|
volatileStatus: 'helpinghand',
|
|
onTryHit(target) {
|
|
if (!target.newlySwitched && !this.queue.willMove(target)) return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source) {
|
|
this.effectData.multiplier = 1.5;
|
|
this.add('-singleturn', target, 'Helping Hand', '[of] ' + source);
|
|
},
|
|
onRestart(target, source) {
|
|
this.effectData.multiplier *= 1.5;
|
|
this.add('-singleturn', target, 'Helping Hand', '[of] ' + source);
|
|
},
|
|
onBasePowerPriority: 10,
|
|
onBasePower(basePower) {
|
|
this.debug('Boosting from Helping Hand: ' + this.effectData.multiplier);
|
|
return this.chainModify(this.effectData.multiplier);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentAlly",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
hex: {
|
|
num: 506,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.status || target.hasAbility('comatose')) return move.basePower * 2;
|
|
return move.basePower;
|
|
},
|
|
category: "Special",
|
|
name: "Hex",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: {basePower: 160},
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpower: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyType(move, pokemon) {
|
|
move.type = pokemon.hpType || 'Dark';
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerbug: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Bug",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerdark: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Dark",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerdragon: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Dragon",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerelectric: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Electric",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerfighting: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Fighting",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerfire: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Fire",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerflying: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Flying",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerghost: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Ghost",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowergrass: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Grass",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerground: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Ground",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerice: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Ice",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerpoison: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Poison",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerpsychic: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Psychic",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerrock: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Rock",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowersteel: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Steel",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Clever",
|
|
},
|
|
hiddenpowerwater: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Water",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Clever",
|
|
},
|
|
highhorsepower: {
|
|
num: 667,
|
|
accuracy: 95,
|
|
basePower: 95,
|
|
category: "Physical",
|
|
name: "High Horsepower",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough",
|
|
},
|
|
highjumpkick: {
|
|
num: 136,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Physical",
|
|
name: "High Jump Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, gravity: 1},
|
|
hasCrashDamage: true,
|
|
onMoveFail(target, source, move) {
|
|
this.damage(source.baseMaxhp / 2, source, source, this.dex.getEffect('High Jump Kick'));
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
holdback: {
|
|
num: 610,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Hold Back",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
noFaint: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
holdhands: {
|
|
num: 615,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Hold Hands",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {authentic: 1},
|
|
secondary: null,
|
|
target: "adjacentAlly",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1, def: 1, spa: 1, spd: 1, spe: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
honeclaws: {
|
|
num: 468,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Hone Claws",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
atk: 1,
|
|
accuracy: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dark",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
hornattack: {
|
|
num: 30,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Horn Attack",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
horndrill: {
|
|
num: 32,
|
|
accuracy: 30,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Horn Drill",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
ohko: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 180},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cool",
|
|
},
|
|
hornleech: {
|
|
num: 532,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Horn Leech",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, heal: 1},
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough",
|
|
},
|
|
howl: {
|
|
num: 336,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Howl",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {snatch: 1, sound: 1},
|
|
boosts: {
|
|
atk: 1,
|
|
},
|
|
secondary: null,
|
|
target: "allies",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
hurricane: {
|
|
num: 542,
|
|
accuracy: 70,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Hurricane",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, distance: 1},
|
|
onModifyMove(move, pokemon, target) {
|
|
switch (target.effectiveWeather()) {
|
|
case 'raindance':
|
|
case 'primordialsea':
|
|
move.accuracy = true;
|
|
break;
|
|
case 'sunnyday':
|
|
case 'desolateland':
|
|
move.accuracy = 50;
|
|
break;
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Tough",
|
|
},
|
|
hydrocannon: {
|
|
num: 308,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Hydro Cannon",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {recharge: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
hydropump: {
|
|
num: 56,
|
|
accuracy: 80,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Hydro Pump",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
hydrovortex: {
|
|
num: 642,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Hydro Vortex",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "wateriumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
hyperbeam: {
|
|
num: 63,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Hyper Beam",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {recharge: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
hyperfang: {
|
|
num: 158,
|
|
accuracy: 90,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Hyper Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
hyperspacefury: {
|
|
num: 621,
|
|
accuracy: true,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Hyperspace Fury",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {mirror: 1, authentic: 1},
|
|
breaksProtect: true,
|
|
onTry(pokemon) {
|
|
if (pokemon.species.name === 'Hoopa-Unbound') {
|
|
return;
|
|
}
|
|
this.hint("Only a Pokemon whose form is Hoopa Unbound can use this move.");
|
|
if (pokemon.species.name === 'Hoopa') {
|
|
this.add('-fail', pokemon, 'move: Hyperspace Fury', '[forme]');
|
|
return null;
|
|
}
|
|
this.add('-fail', pokemon, 'move: Hyperspace Fury');
|
|
return null;
|
|
},
|
|
self: {
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough",
|
|
},
|
|
hyperspacehole: {
|
|
num: 593,
|
|
accuracy: true,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Hyperspace Hole",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {mirror: 1, authentic: 1},
|
|
breaksProtect: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
hypervoice: {
|
|
num: 304,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Hyper Voice",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
hypnosis: {
|
|
num: 95,
|
|
accuracy: 60,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Hypnosis",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'slp',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
iceball: {
|
|
num: 301,
|
|
accuracy: 90,
|
|
basePower: 30,
|
|
basePowerCallback(pokemon, target, move) {
|
|
let bp = move.basePower;
|
|
if (pokemon.volatiles['iceball'] && pokemon.volatiles['iceball'].hitCount) {
|
|
bp *= Math.pow(2, pokemon.volatiles['iceball'].hitCount);
|
|
}
|
|
if (pokemon.status !== 'slp') pokemon.addVolatile('iceball');
|
|
if (pokemon.volatiles['defensecurl']) {
|
|
bp *= 2;
|
|
}
|
|
this.debug("Ice Ball bp: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Ice Ball",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {bullet: 1, contact: 1, protect: 1, mirror: 1},
|
|
condition: {
|
|
duration: 2,
|
|
onLockMove: 'iceball',
|
|
onStart() {
|
|
this.effectData.hitCount = 1;
|
|
},
|
|
onRestart() {
|
|
this.effectData.hitCount++;
|
|
if (this.effectData.hitCount < 5) {
|
|
this.effectData.duration = 2;
|
|
}
|
|
},
|
|
onResidual(target) {
|
|
if (target.lastMove && target.lastMove.id === 'struggle') {
|
|
// don't lock
|
|
delete target.volatiles['iceball'];
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
icebeam: {
|
|
num: 58,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Ice Beam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'frz',
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
iceburn: {
|
|
num: 554,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Special",
|
|
name: "Ice Burn",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {charge: 1, protect: 1, mirror: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
icefang: {
|
|
num: 423,
|
|
accuracy: 95,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Ice Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
secondaries: [
|
|
{
|
|
chance: 10,
|
|
status: 'frz',
|
|
}, {
|
|
chance: 10,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
],
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Cool",
|
|
},
|
|
icehammer: {
|
|
num: 665,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Ice Hammer",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
self: {
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Tough",
|
|
},
|
|
icepunch: {
|
|
num: 8,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Ice Punch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'frz',
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
iceshard: {
|
|
num: 420,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Ice Shard",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
iciclecrash: {
|
|
num: 556,
|
|
accuracy: 90,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Icicle Crash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
iciclespear: {
|
|
num: 333,
|
|
accuracy: 100,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Icicle Spear",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Beautiful",
|
|
},
|
|
icywind: {
|
|
num: 196,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Special",
|
|
name: "Icy Wind",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
imprison: {
|
|
num: 286,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Imprison",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, authentic: 1},
|
|
volatileStatus: 'imprison',
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(target) {
|
|
this.add('-start', target, 'move: Imprison');
|
|
},
|
|
onFoeDisableMove(pokemon) {
|
|
for (const moveSlot of this.effectData.source.moveSlots) {
|
|
if (moveSlot.id === 'struggle') continue;
|
|
pokemon.disableMove(moveSlot.id, 'hidden');
|
|
}
|
|
pokemon.maybeDisabled = true;
|
|
},
|
|
onFoeBeforeMovePriority: 4,
|
|
onFoeBeforeMove(attacker, defender, move) {
|
|
if (move.id !== 'struggle' && this.effectData.source.hasMove(move.id) && !move.isZ && !move.isMax) {
|
|
this.add('cant', attacker, 'move: Imprison', move);
|
|
return false;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
pressureTarget: "foeSide",
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {boost: {spd: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
incinerate: {
|
|
num: 510,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Incinerate",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onHit(pokemon, source) {
|
|
const item = pokemon.getItem();
|
|
if ((item.isBerry || item.isGem) && pokemon.takeItem(source)) {
|
|
this.add('-enditem', pokemon, item.name, '[from] move: Incinerate');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Tough",
|
|
},
|
|
inferno: {
|
|
num: 517,
|
|
accuracy: 50,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Inferno",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
infernooverdrive: {
|
|
num: 640,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Inferno Overdrive",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "firiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
infestation: {
|
|
num: 611,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Special",
|
|
name: "Infestation",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
volatileStatus: 'partiallytrapped',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute",
|
|
},
|
|
ingrain: {
|
|
num: 275,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Ingrain",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1, nonsky: 1},
|
|
volatileStatus: 'ingrain',
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'move: Ingrain');
|
|
},
|
|
onResidualOrder: 7,
|
|
onResidual(pokemon) {
|
|
this.heal(pokemon.baseMaxhp / 16);
|
|
},
|
|
onTrapPokemon(pokemon) {
|
|
pokemon.tryTrap();
|
|
},
|
|
// groundedness implemented in battle.engine.js:BattlePokemon#isGrounded
|
|
onDragOut(pokemon) {
|
|
this.add('-activate', pokemon, 'move: Ingrain');
|
|
return null;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
instruct: {
|
|
num: 689,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Instruct",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, authentic: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
if (!target.lastMove || target.volatiles['dynamax']) return false;
|
|
const lastMove = target.lastMove;
|
|
const moveIndex = target.moves.indexOf(lastMove.id);
|
|
const noInstruct = [
|
|
'assist', 'beakblast', 'bide', 'celebrate', 'copycat', 'dynamaxcannon', 'focuspunch', 'iceball', 'instruct', 'kingsshield', 'mefirst', 'metronome', 'mimic', 'mirrormove', 'naturepower', 'outrage', 'petaldance', 'rollout', 'shelltrap', 'sketch', 'sleeptalk', 'thrash', 'transform',
|
|
];
|
|
if (
|
|
noInstruct.includes(lastMove.id) || lastMove.isZ || lastMove.isMax ||
|
|
lastMove.flags['charge'] || lastMove.flags['recharge'] ||
|
|
target.volatiles['beakblast'] || target.volatiles['focuspunch'] || target.volatiles['shelltrap'] ||
|
|
(target.moveSlots[moveIndex] && target.moveSlots[moveIndex].pp <= 0)
|
|
) {
|
|
return false;
|
|
}
|
|
this.add('-singleturn', target, 'move: Instruct', '[of] ' + source);
|
|
this.runMove(target.lastMove.id, target, target.lastMoveTargetLoc!);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
iondeluge: {
|
|
num: 569,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Ion Deluge",
|
|
pp: 25,
|
|
priority: 1,
|
|
flags: {},
|
|
pseudoWeather: 'iondeluge',
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-fieldactivate', 'move: Ion Deluge');
|
|
},
|
|
onModifyTypePriority: -2,
|
|
onModifyType(move) {
|
|
if (move.type === 'Normal') {
|
|
move.type = 'Electric';
|
|
this.debug(move.name + "'s type changed to Electric");
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Electric",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
irondefense: {
|
|
num: 334,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Iron Defense",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Steel",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Tough",
|
|
},
|
|
ironhead: {
|
|
num: 442,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Iron Head",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Tough",
|
|
},
|
|
irontail: {
|
|
num: 231,
|
|
accuracy: 75,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Iron Tail",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
jawlock: {
|
|
num: 746,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Jaw Lock",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
onHit(target, source, move) {
|
|
source.addVolatile('trapped', target, move, 'trapper');
|
|
target.addVolatile('trapped', source, move, 'trapper');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
judgment: {
|
|
num: 449,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Judgment",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.ignoringItem()) return;
|
|
const item = pokemon.getItem();
|
|
if (item.id && item.onPlate && !item.zMove) {
|
|
move.type = item.onPlate;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
jumpkick: {
|
|
num: 26,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Jump Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, gravity: 1},
|
|
hasCrashDamage: true,
|
|
onMoveFail(target, source, move) {
|
|
this.damage(source.baseMaxhp / 2, source, source, this.dex.getEffect('Jump Kick'));
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
junglehealing: {
|
|
num: 816,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Jungle Healing",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {distance: 1, heal: 1, authentic: 1, mystery: 1},
|
|
onHit(pokemon) {
|
|
pokemon.cureStatus();
|
|
},
|
|
heal: [1, 4],
|
|
secondary: null,
|
|
target: "allies",
|
|
type: "Grass",
|
|
},
|
|
karatechop: {
|
|
num: 2,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Karate Chop",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
kinesis: {
|
|
num: 134,
|
|
accuracy: 80,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Kinesis",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {evasion: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
kingsshield: {
|
|
num: 588,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "King's Shield",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {},
|
|
stallingMove: true,
|
|
volatileStatus: 'kingsshield',
|
|
onTryHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent('StallMove', pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'Protect');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags['protect'] || move.category === 'Status') {
|
|
if (move.isZ || (move.isMax && !move.breaksProtect)) target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add('-activate', target, 'move: Protect');
|
|
}
|
|
const lockedmove = source.getVolatile('lockedmove');
|
|
if (lockedmove) {
|
|
// Outrage counter is reset
|
|
if (source.volatiles['lockedmove'].duration === 2) {
|
|
delete source.volatiles['lockedmove'];
|
|
}
|
|
}
|
|
if (move.flags['contact']) {
|
|
this.boost({atk: -1}, source, target, this.dex.getActiveMove("King's Shield"));
|
|
}
|
|
return this.NOT_FAIL;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZOrMaxPowered && move.flags['contact']) {
|
|
this.boost({atk: -1}, source, target, this.dex.getActiveMove("King's Shield"));
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Steel",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cool",
|
|
},
|
|
knockoff: {
|
|
num: 282,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Knock Off",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onBasePower(basePower, source, target, move) {
|
|
const item = target.getItem();
|
|
if (!this.singleEvent('TakeItem', item, target.itemData, target, target, move, item)) return;
|
|
if (item.id) {
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
onAfterHit(target, source) {
|
|
if (source.hp) {
|
|
const item = target.takeItem();
|
|
if (item) {
|
|
this.add('-enditem', target, item.name, '[from] move: Knock Off', '[of] ' + source);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
landswrath: {
|
|
num: 616,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Land's Wrath",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Ground",
|
|
zMove: {basePower: 185},
|
|
contestType: "Beautiful",
|
|
},
|
|
laserfocus: {
|
|
num: 673,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Laser Focus",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
volatileStatus: 'laserfocus',
|
|
condition: {
|
|
duration: 2,
|
|
onStart(pokemon, source, effect) {
|
|
if (effect && (['imposter', 'psychup', 'transform'].includes(effect.id))) {
|
|
this.add('-start', pokemon, 'move: Laser Focus', '[silent]');
|
|
} else {
|
|
this.add('-start', pokemon, 'move: Laser Focus');
|
|
}
|
|
},
|
|
onRestart(pokemon) {
|
|
this.effectData.duration = 2;
|
|
this.add('-start', pokemon, 'move: Laser Focus');
|
|
},
|
|
onModifyCritRatio(critRatio) {
|
|
return 5;
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add('-end', pokemon, 'move: Laser Focus', '[silent]');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
lashout: {
|
|
num: 808,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Lash Out",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onBasePower(basePower, source) {
|
|
if (source.statsLoweredThisTurn) {
|
|
this.debug('lashout buff');
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
lastresort: {
|
|
num: 387,
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Physical",
|
|
name: "Last Resort",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTry(pokemon, target) {
|
|
if (pokemon.moveSlots.length < 2) return false; // Last Resort fails unless the user knows at least 2 moves
|
|
let hasLastResort = false; // User must actually have Last Resort for it to succeed
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (moveSlot.id === 'lastresort') {
|
|
hasLastResort = true;
|
|
continue;
|
|
}
|
|
if (!moveSlot.used) return false;
|
|
}
|
|
return hasLastResort;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
lavaplume: {
|
|
num: 436,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Lava Plume",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'brn',
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Fire",
|
|
contestType: "Tough",
|
|
},
|
|
leafage: {
|
|
num: 670,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Leafage",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough",
|
|
},
|
|
leafblade: {
|
|
num: 348,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Leaf Blade",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
leafstorm: {
|
|
num: 437,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Leaf Storm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
self: {
|
|
boosts: {
|
|
spa: -2,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful",
|
|
},
|
|
leaftornado: {
|
|
num: 536,
|
|
accuracy: 90,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Leaf Tornado",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
leechlife: {
|
|
num: 141,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Leech Life",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, heal: 1},
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Clever",
|
|
},
|
|
leechseed: {
|
|
num: 73,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Leech Seed",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
volatileStatus: 'leechseed',
|
|
condition: {
|
|
onStart(target) {
|
|
this.add('-start', target, 'move: Leech Seed');
|
|
},
|
|
onResidualOrder: 8,
|
|
onResidual(pokemon) {
|
|
const target = this.effectData.source.side.active[pokemon.volatiles['leechseed'].sourcePosition];
|
|
if (!target || target.fainted || target.hp <= 0) {
|
|
this.debug('Nothing to leech into');
|
|
return;
|
|
}
|
|
const damage = this.damage(pokemon.baseMaxhp / 8, pokemon, target);
|
|
if (damage) {
|
|
this.heal(damage, target, pokemon);
|
|
}
|
|
},
|
|
},
|
|
onTryImmunity(target) {
|
|
return !target.hasType('Grass');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
leer: {
|
|
num: 43,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Leer",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
letssnuggleforever: {
|
|
num: 726,
|
|
accuracy: true,
|
|
basePower: 190,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Let's Snuggle Forever",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {contact: 1},
|
|
isZ: "mimikiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Cool",
|
|
},
|
|
lick: {
|
|
num: 122,
|
|
accuracy: 100,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Lick",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cute",
|
|
},
|
|
lifedew: {
|
|
num: 791,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Life Dew",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1, authentic: 1},
|
|
heal: [1, 4],
|
|
secondary: null,
|
|
target: "allies",
|
|
type: "Water",
|
|
},
|
|
lightofruin: {
|
|
num: 617,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Light of Ruin",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
recoil: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Beautiful",
|
|
},
|
|
lightscreen: {
|
|
num: 113,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Light Screen",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
sideCondition: 'lightscreen',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasItem('lightclay')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onAnyModifyDamage(damage, source, target, move) {
|
|
if (target !== source && target.side === this.effectData.target && this.getCategory(move) === 'Special') {
|
|
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
|
|
this.debug('Light Screen weaken');
|
|
if (target.side.active.length > 1) return this.chainModify([0xAAC, 0x1000]);
|
|
return this.chainModify(0.5);
|
|
}
|
|
}
|
|
},
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'move: Light Screen');
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 1,
|
|
onEnd(side) {
|
|
this.add('-sideend', side, 'move: Light Screen');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Psychic",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
lightthatburnsthesky: {
|
|
num: 723,
|
|
accuracy: true,
|
|
basePower: 200,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Light That Burns the Sky",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onModifyMove(move, pokemon) {
|
|
if (pokemon.getStat('atk', false, true) > pokemon.getStat('spa', false, true)) move.category = 'Physical';
|
|
},
|
|
ignoreAbility: true,
|
|
isZ: "ultranecroziumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
liquidation: {
|
|
num: 710,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Liquidation",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
lockon: {
|
|
num: 199,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Lock-On",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryHit(target, source) {
|
|
if (source.volatiles['lockon']) return false;
|
|
},
|
|
onHit(target, source) {
|
|
source.addVolatile('lockon', target);
|
|
this.add('-activate', source, 'move: Lock-On', '[of] ' + target);
|
|
},
|
|
condition: {
|
|
noCopy: true, // doesn't get copied by Baton Pass
|
|
duration: 2,
|
|
onSourceInvulnerabilityPriority: 1,
|
|
onSourceInvulnerability(target, source, move) {
|
|
if (move && source === this.effectData.target && target === this.effectData.source) return 0;
|
|
},
|
|
onSourceAccuracy(accuracy, target, source, move) {
|
|
if (move && source === this.effectData.target && target === this.effectData.source) return true;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
lovelykiss: {
|
|
num: 142,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Lovely Kiss",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'slp',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
lowkick: {
|
|
num: 67,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const targetWeight = target.getWeight();
|
|
if (targetWeight >= 2000) {
|
|
return 120;
|
|
}
|
|
if (targetWeight >= 1000) {
|
|
return 100;
|
|
}
|
|
if (targetWeight >= 500) {
|
|
return 80;
|
|
}
|
|
if (targetWeight >= 250) {
|
|
return 60;
|
|
}
|
|
if (targetWeight >= 100) {
|
|
return 40;
|
|
}
|
|
return 20;
|
|
},
|
|
category: "Physical",
|
|
name: "Low Kick",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTryHit(target, pokemon, move) {
|
|
if (target.volatiles['dynamax']) {
|
|
this.add('-fail', pokemon, 'Dynamax');
|
|
this.attrLastMove('[still]');
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
zMove: {basePower: 160},
|
|
contestType: "Tough",
|
|
},
|
|
lowsweep: {
|
|
num: 490,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Low Sweep",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Clever",
|
|
},
|
|
luckychant: {
|
|
num: 381,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Lucky Chant",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
sideCondition: 'luckychant',
|
|
condition: {
|
|
duration: 5,
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'move: Lucky Chant'); // "The Lucky Chant shielded [side.name]'s team from critical hits!"
|
|
},
|
|
onCriticalHit: false,
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 5,
|
|
onEnd(side) {
|
|
this.add('-sideend', side, 'move: Lucky Chant'); // "[side.name]'s team's Lucky Chant wore off!"
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Normal",
|
|
zMove: {boost: {evasion: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
lunardance: {
|
|
num: 461,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Lunar Dance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1, dance: 1},
|
|
onTryHit(pokemon, target, move) {
|
|
if (!this.canSwitch(pokemon.side)) {
|
|
delete move.selfdestruct;
|
|
return false;
|
|
}
|
|
},
|
|
selfdestruct: "ifHit",
|
|
sideCondition: 'lunardance',
|
|
condition: {
|
|
duration: 2,
|
|
onStart(side, source) {
|
|
this.debug('Lunar Dance started on ' + side.name);
|
|
this.effectData.positions = [];
|
|
for (const i of side.active.keys()) {
|
|
this.effectData.positions[i] = false;
|
|
}
|
|
this.effectData.positions[source.position] = true;
|
|
},
|
|
onRestart(side, source) {
|
|
this.effectData.positions[source.position] = true;
|
|
},
|
|
onSwitchInPriority: 1,
|
|
onSwitchIn(target) {
|
|
const positions: boolean[] = this.effectData.positions;
|
|
if (target.position !== this.effectData.sourcePosition) {
|
|
return;
|
|
}
|
|
if (!target.fainted) {
|
|
target.heal(target.maxhp);
|
|
target.setStatus('');
|
|
for (const moveSlot of target.moveSlots) {
|
|
moveSlot.pp = moveSlot.maxpp;
|
|
}
|
|
this.add('-heal', target, target.getHealth, '[from] move: Lunar Dance');
|
|
positions[target.position] = false;
|
|
}
|
|
if (!positions.some(affected => affected === true)) {
|
|
target.side.removeSideCondition('lunardance');
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
contestType: "Beautiful",
|
|
},
|
|
lunge: {
|
|
num: 679,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Lunge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
atk: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute",
|
|
},
|
|
lusterpurge: {
|
|
num: 295,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Luster Purge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
machpunch: {
|
|
num: 183,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Mach Punch",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
magicalleaf: {
|
|
num: 345,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Magical Leaf",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful",
|
|
},
|
|
magiccoat: {
|
|
num: 277,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Magic Coat",
|
|
pp: 15,
|
|
priority: 4,
|
|
flags: {},
|
|
volatileStatus: 'magiccoat',
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source, effect) {
|
|
this.add('-singleturn', target, 'move: Magic Coat');
|
|
if (effect?.effectType === 'Move') {
|
|
this.effectData.pranksterBoosted = effect.pranksterBoosted;
|
|
}
|
|
},
|
|
onTryHitPriority: 2,
|
|
onTryHit(target, source, move) {
|
|
if (target === source || move.hasBounced || !move.flags['reflectable']) {
|
|
return;
|
|
}
|
|
const newMove = this.dex.getActiveMove(move.id);
|
|
newMove.hasBounced = true;
|
|
newMove.pranksterBoosted = this.effectData.pranksterBoosted;
|
|
this.useMove(newMove, target, source);
|
|
return null;
|
|
},
|
|
onAllyTryHitSide(target, source, move) {
|
|
if (target.side === source.side || move.hasBounced || !move.flags['reflectable']) {
|
|
return;
|
|
}
|
|
const newMove = this.dex.getActiveMove(move.id);
|
|
newMove.hasBounced = true;
|
|
newMove.pranksterBoosted = false;
|
|
this.useMove(newMove, this.effectData.target, source);
|
|
return null;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {boost: {spd: 2}},
|
|
contestType: "Beautiful",
|
|
},
|
|
magicpowder: {
|
|
num: 750,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Magic Powder",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {powder: 1, protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
onHit(target) {
|
|
if (target.getTypes().join() === 'Psychic' || !target.setType('Psychic')) return false;
|
|
this.add('-start', target, 'typechange', 'Psychic');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
},
|
|
magicroom: {
|
|
num: 478,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Magic Room",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {mirror: 1},
|
|
pseudoWeather: 'magicroom',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasAbility('persistent')) {
|
|
this.add('-activate', source, 'ability: Persistent', effect);
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onStart(target, source) {
|
|
this.add('-fieldstart', 'move: Magic Room', '[of] ' + source);
|
|
},
|
|
onRestart(target, source) {
|
|
this.field.removePseudoWeather('magicroom');
|
|
},
|
|
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
|
|
onResidualOrder: 25,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Magic Room', '[of] ' + this.effectData.source);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
magmastorm: {
|
|
num: 463,
|
|
accuracy: 75,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Magma Storm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
volatileStatus: 'partiallytrapped',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Tough",
|
|
},
|
|
magnetbomb: {
|
|
num: 443,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Magnet Bomb",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
magneticflux: {
|
|
num: 602,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Magnetic Flux",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1, distance: 1, authentic: 1},
|
|
onHitSide(side, source, move) {
|
|
const targets = [];
|
|
for (const pokemon of side.active) {
|
|
if (pokemon.hasAbility(['plus', 'minus'])) {
|
|
targets.push(pokemon);
|
|
}
|
|
}
|
|
if (!targets.length) return false;
|
|
let didSomething = false;
|
|
for (const target of targets) {
|
|
didSomething = this.boost({def: 1, spd: 1}, target, source, move, false, true) || didSomething;
|
|
}
|
|
return didSomething;
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Electric",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
magnetrise: {
|
|
num: 393,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Magnet Rise",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, gravity: 1},
|
|
volatileStatus: 'magnetrise',
|
|
condition: {
|
|
duration: 5,
|
|
onStart(target) {
|
|
if (target.volatiles['smackdown'] || target.volatiles['ingrain']) return false;
|
|
this.add('-start', target, 'Magnet Rise');
|
|
},
|
|
onImmunity(type) {
|
|
if (type === 'Ground') return false;
|
|
},
|
|
onResidualOrder: 15,
|
|
onEnd(target) {
|
|
this.add('-end', target, 'Magnet Rise');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Electric",
|
|
zMove: {boost: {evasion: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
magnitude: {
|
|
num: 222,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Magnitude",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
onModifyMove(move, pokemon) {
|
|
const i = this.random(100);
|
|
if (i < 5) {
|
|
move.magnitude = 4;
|
|
move.basePower = 10;
|
|
} else if (i < 15) {
|
|
move.magnitude = 5;
|
|
move.basePower = 30;
|
|
} else if (i < 35) {
|
|
move.magnitude = 6;
|
|
move.basePower = 50;
|
|
} else if (i < 65) {
|
|
move.magnitude = 7;
|
|
move.basePower = 70;
|
|
} else if (i < 85) {
|
|
move.magnitude = 8;
|
|
move.basePower = 90;
|
|
} else if (i < 95) {
|
|
move.magnitude = 9;
|
|
move.basePower = 110;
|
|
} else {
|
|
move.magnitude = 10;
|
|
move.basePower = 150;
|
|
}
|
|
},
|
|
onUseMoveMessage(pokemon, target, move) {
|
|
this.add('-activate', pokemon, 'move: Magnitude', move.magnitude);
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Ground",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 140},
|
|
contestType: "Tough",
|
|
},
|
|
maliciousmoonsault: {
|
|
num: 696,
|
|
accuracy: true,
|
|
basePower: 180,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Malicious Moonsault",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {contact: 1},
|
|
isZ: "inciniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool",
|
|
},
|
|
matblock: {
|
|
num: 561,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Mat Block",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, nonsky: 1},
|
|
stallingMove: true,
|
|
sideCondition: 'matblock',
|
|
onTryHitSide(side, source) {
|
|
if (source.activeMoveActions > 1) {
|
|
this.hint("Mat Block only works on your first turn out.");
|
|
return false;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source) {
|
|
this.add('-singleturn', source, 'Mat Block');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags['protect']) {
|
|
if (move.isZ || (move.isMax && !move.breaksProtect)) target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move && (move.target === 'self' || move.category === 'Status')) return;
|
|
this.add('-activate', target, 'move: Mat Block', move.name);
|
|
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;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Fighting",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
maxairstream: {
|
|
num: 766,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Airstream",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.active) {
|
|
this.boost({spe: 1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
maxdarkness: {
|
|
num: 772,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Darkness",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.foe.active) {
|
|
this.boost({spd: -1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Dark",
|
|
contestType: "Cool",
|
|
},
|
|
maxflare: {
|
|
num: 757,
|
|
accuracy: true,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Max Flare",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
this.field.setWeather('sunnyday');
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
maxflutterby: {
|
|
num: 758,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Flutterby",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.foe.active) {
|
|
this.boost({spa: -1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Bug",
|
|
contestType: "Cool",
|
|
},
|
|
maxgeyser: {
|
|
num: 765,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Geyser",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
this.field.setWeather('raindance');
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
maxguard: {
|
|
num: 743,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Max Guard",
|
|
pp: 5,
|
|
priority: 4,
|
|
flags: {},
|
|
isMax: true,
|
|
stallingMove: true,
|
|
volatileStatus: 'maxguard',
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent('StallMove', pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'Max Guard');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (move.isMax && move.breaksProtect) return;
|
|
/** moves blocked by Max Guard but not Protect */
|
|
const overrideBypassProtect = [
|
|
'block', 'flowershield', 'gearup', 'magneticflux', 'phantomforce', 'psychup', 'teatime', 'transform',
|
|
];
|
|
const blockedByMaxGuard = (this.dex.getMove(move.id).flags['protect'] ||
|
|
move.isZ || move.isMax || overrideBypassProtect.includes(move.id));
|
|
if (!blockedByMaxGuard) {
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add('-activate', target, 'move: Max Guard');
|
|
}
|
|
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;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
maxhailstorm: {
|
|
num: 763,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Hailstorm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
this.field.setWeather('hail');
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Ice",
|
|
contestType: "Cool",
|
|
},
|
|
maxknuckle: {
|
|
num: 761,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Knuckle",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.active) {
|
|
this.boost({atk: 1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
maxlightning: {
|
|
num: 759,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Lightning",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
this.field.setTerrain('electricterrain');
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
maxmindstorm: {
|
|
num: 769,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Mindstorm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
this.field.setTerrain('psychicterrain');
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
maxooze: {
|
|
num: 764,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Ooze",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.active) {
|
|
this.boost({spa: 1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Poison",
|
|
contestType: "Cool",
|
|
},
|
|
maxovergrowth: {
|
|
num: 773,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Overgrowth",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
this.field.setTerrain('grassyterrain');
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
maxphantasm: {
|
|
num: 762,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Phantasm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.foe.active) {
|
|
this.boost({def: -1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
maxquake: {
|
|
num: 771,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Quake",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.active) {
|
|
this.boost({spd: 1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Ground",
|
|
contestType: "Cool",
|
|
},
|
|
maxrockfall: {
|
|
num: 770,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Rockfall",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
this.field.setWeather('sandstorm');
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Rock",
|
|
contestType: "Cool",
|
|
},
|
|
maxstarfall: {
|
|
num: 767,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Starfall",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
this.field.setTerrain('mistyterrain');
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Fairy",
|
|
contestType: "Cool",
|
|
},
|
|
maxsteelspike: {
|
|
num: 774,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Steelspike",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.active) {
|
|
this.boost({def: 1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
maxstrike: {
|
|
num: 760,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Strike",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.foe.active) {
|
|
this.boost({spe: -1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
maxwyrmwind: {
|
|
num: 768,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
name: "Max Wyrmwind",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles['dynamax']) return;
|
|
for (const pokemon of source.side.foe.active) {
|
|
this.boost({atk: -1}, pokemon);
|
|
}
|
|
},
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Dragon",
|
|
contestType: "Cool",
|
|
},
|
|
meanlook: {
|
|
num: 212,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Mean Look",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {reflectable: 1, mirror: 1},
|
|
onHit(target, source, move) {
|
|
return target.addVolatile('trapped', source, move, 'trapper');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
meditate: {
|
|
num: 96,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Meditate",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
atk: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
mefirst: {
|
|
num: 382,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Me First",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, authentic: 1},
|
|
onTryHit(target, pokemon) {
|
|
const action = this.queue.willMove(target);
|
|
if (!action) return false;
|
|
|
|
const noMeFirst = [
|
|
'beakblast', 'chatter', 'counter', 'covet', 'focuspunch', 'mefirst', 'metalburst', 'mirrorcoat', 'shelltrap', 'struggle', 'thief',
|
|
];
|
|
const move = this.dex.getActiveMove(action.move.id);
|
|
if (action.zmove || move.isZ || move.isMax) return false;
|
|
if (move.category === 'Status' || noMeFirst.includes(move.id)) return false;
|
|
|
|
pokemon.addVolatile('mefirst');
|
|
this.useMove(move, pokemon, target);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onBasePowerPriority: 12,
|
|
onBasePower(basePower) {
|
|
return this.chainModify(1.5);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
megadrain: {
|
|
num: 72,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Mega Drain",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, heal: 1},
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {basePower: 120},
|
|
contestType: "Clever",
|
|
},
|
|
megahorn: {
|
|
num: 224,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Megahorn",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool",
|
|
},
|
|
megakick: {
|
|
num: 25,
|
|
accuracy: 75,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Mega Kick",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
megapunch: {
|
|
num: 5,
|
|
accuracy: 85,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Mega Punch",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
memento: {
|
|
num: 262,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Memento",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
boosts: {
|
|
atk: -2,
|
|
spa: -2,
|
|
},
|
|
selfdestruct: "ifHit",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {effect: 'healreplacement'},
|
|
contestType: "Tough",
|
|
},
|
|
menacingmoonrazemaelstrom: {
|
|
num: 725,
|
|
accuracy: true,
|
|
basePower: 200,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Menacing Moonraze Maelstrom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "lunaliumz",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
metalburst: {
|
|
num: 368,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
if (!pokemon.volatiles['metalburst']) return 0;
|
|
return pokemon.volatiles['metalburst'].damage || 1;
|
|
},
|
|
category: "Physical",
|
|
name: "Metal Burst",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile('metalburst');
|
|
},
|
|
onTryHit(target, source, move) {
|
|
if (!source.volatiles['metalburst']) return false;
|
|
if (source.volatiles['metalburst'].position === null) return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
noCopy: true,
|
|
onStart(target, source, move) {
|
|
this.effectData.position = null;
|
|
this.effectData.damage = 0;
|
|
},
|
|
onRedirectTargetPriority: -1,
|
|
onRedirectTarget(target, source, source2) {
|
|
if (source !== this.effectData.target) return;
|
|
return source.side.foe.active[this.effectData.position];
|
|
},
|
|
onDamagingHit(damage, target, source, effect) {
|
|
if (source.side !== target.side) {
|
|
this.effectData.position = source.position;
|
|
this.effectData.damage = 1.5 * damage;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "scripted",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
metalclaw: {
|
|
num: 232,
|
|
accuracy: 95,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Metal Claw",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
metalsound: {
|
|
num: 319,
|
|
accuracy: 85,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Metal Sound",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, authentic: 1, mystery: 1},
|
|
boosts: {
|
|
spd: -2,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
meteorassault: {
|
|
num: 794,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
name: "Meteor Assault",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, recharge: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
},
|
|
meteorbeam: {
|
|
num: 800,
|
|
accuracy: 90,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Meteor Beam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {charge: 1, protect: 1, mirror: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
this.boost({spa: 1}, attacker, attacker, move);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
},
|
|
meteormash: {
|
|
num: 309,
|
|
accuracy: 90,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Meteor Mash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
metronome: {
|
|
num: 118,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Metronome",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
noMetronome: [
|
|
"After You", "Apple Acid", "Assist", "Aura Wheel", "Baneful Bunker", "Beak Blast", "Behemoth Bash", "Behemoth Blade", "Belch", "Bestow", "Body Press", "Branch Poke", "Breaking Swipe", "Celebrate", "Chatter", "Clangorous Soul", "Copycat", "Counter", "Covet", "Crafty Shield", "Decorate", "Destiny Bond", "Detect", "Diamond Storm", "Double Iron Bash", "Dragon Ascent", "Drum Beating", "Dynamax Cannon", "Endure", "Eternabeam", "False Surrender", "Feint", "Fleur Cannon", "Focus Punch", "Follow Me", "Freeze Shock", "Grav Apple", "Helping Hand", "Hold Hands", "Hyperspace Fury", "Hyperspace Hole", "Ice Burn", "Instruct", "Jungle Healing", "King's Shield", "Life Dew", "Light of Ruin", "Mat Block", "Me First", "Meteor Assault", "Metronome", "Mimic", "Mind Blown", "Mirror Coat", "Mirror Move", "Moongeist Beam", "Nature Power", "Nature's Madness", "Obstruct", "Origin Pulse", "Overdrive", "Photon Geyser", "Plasma Fists", "Precipice Blades", "Protect", "Pyro Ball", "Quash", "Quick Guard", "Rage Powder", "Relic Song", "Secret Sword", "Shell Trap", "Sketch", "Sleep Talk", "Snap Trap", "Snarl", "Snatch", "Snore", "Spectral Thief", "Spiky Shield", "Spirit Break", "Spotlight", "Steam Eruption", "Steel Beam", "Strange Steam", "Struggle", "Sunsteel Strike", "Surging Strikes", "Switcheroo", "Techno Blast", "Thief", "Thousand Arrows", "Thousand Waves", "Transform", "Trick", "V-create", "Wicked Blow", "Wide Guard",
|
|
],
|
|
onHit(target, source, effect) {
|
|
const moves: MoveData[] = [];
|
|
for (const id in Moves) {
|
|
const move = Moves[id];
|
|
if (move.realMove) continue;
|
|
if (move.isZ || move.isMax || move.isNonstandard) continue;
|
|
if (effect.noMetronome!.includes(move.name)) continue;
|
|
if (this.dex.getMove(id).gen > this.gen) continue;
|
|
moves.push(move);
|
|
}
|
|
let randomMove = '';
|
|
if (moves.length) {
|
|
moves.sort((a, b) => a.num! - b.num!);
|
|
randomMove = this.sample(moves).name;
|
|
}
|
|
if (!randomMove) {
|
|
return false;
|
|
}
|
|
this.useMove(randomMove, target);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
milkdrink: {
|
|
num: 208,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Milk Drink",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
mimic: {
|
|
num: 102,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Mimic",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, authentic: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
const disallowedMoves = ['chatter', 'mimic', 'sketch', 'struggle', 'transform'];
|
|
const move = target.lastMove;
|
|
if (source.transformed || !move || disallowedMoves.includes(move.id) || source.moves.includes(move.id)) {
|
|
return false;
|
|
}
|
|
if (move.isZ || move.isMax) return false;
|
|
const mimicIndex = source.moves.indexOf('mimic');
|
|
if (mimicIndex < 0) return false;
|
|
|
|
source.moveSlots[mimicIndex] = {
|
|
move: move.name,
|
|
id: move.id,
|
|
pp: move.pp,
|
|
maxpp: move.pp,
|
|
target: move.target,
|
|
disabled: false,
|
|
used: false,
|
|
virtual: true,
|
|
};
|
|
this.add('-start', source, 'Mimic', move.name);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {accuracy: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
mindblown: {
|
|
num: 720,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Mind Blown",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
mindBlownRecoil: true,
|
|
onAfterMove(pokemon, target, move) {
|
|
if (move.mindBlownRecoil && !move.multihit) {
|
|
this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.getEffect('Mind Blown'), true);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
mindreader: {
|
|
num: 170,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Mind Reader",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryHit(target, source) {
|
|
if (source.volatiles['lockon']) return false;
|
|
},
|
|
onHit(target, source) {
|
|
source.addVolatile('lockon', target);
|
|
this.add('-activate', source, 'move: Mind Reader', '[of] ' + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
minimize: {
|
|
num: 107,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Minimize",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
volatileStatus: 'minimize',
|
|
condition: {
|
|
noCopy: true,
|
|
onSourceModifyDamage(damage, source, target, move) {
|
|
const boostedMoves = [
|
|
'stomp', 'steamroller', 'bodyslam', 'flyingpress', 'dragonrush', 'heatcrash', 'heavyslam', 'maliciousmoonsault',
|
|
];
|
|
if (boostedMoves.includes(move.id)) {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
onAccuracy(accuracy, target, source, move) {
|
|
const boostedMoves = [
|
|
'stomp', 'steamroller', 'bodyslam', 'flyingpress', 'dragonrush', 'heatcrash', 'heavyslam', 'maliciousmoonsault',
|
|
];
|
|
if (boostedMoves.includes(move.id)) {
|
|
return true;
|
|
}
|
|
return accuracy;
|
|
},
|
|
},
|
|
boosts: {
|
|
evasion: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
miracleeye: {
|
|
num: 357,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Miracle Eye",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
volatileStatus: 'miracleeye',
|
|
onTryHit(target) {
|
|
if (target.volatiles['foresight']) return false;
|
|
},
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'Miracle Eye');
|
|
},
|
|
onNegateImmunity(pokemon, type) {
|
|
if (pokemon.hasType('Dark') && type === 'Psychic') return false;
|
|
},
|
|
onModifyBoost(boosts) {
|
|
if (boosts.evasion && boosts.evasion > 0) {
|
|
boosts.evasion = 0;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
mirrorcoat: {
|
|
num: 243,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
if (!pokemon.volatiles['mirrorcoat']) return 0;
|
|
return pokemon.volatiles['mirrorcoat'].damage || 1;
|
|
},
|
|
category: "Special",
|
|
name: "Mirror Coat",
|
|
pp: 20,
|
|
priority: -5,
|
|
flags: {protect: 1},
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile('mirrorcoat');
|
|
},
|
|
onTryHit(target, source, move) {
|
|
if (!source.volatiles['mirrorcoat']) return false;
|
|
if (source.volatiles['mirrorcoat'].position === null) return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
noCopy: true,
|
|
onStart(target, source, move) {
|
|
this.effectData.position = null;
|
|
this.effectData.damage = 0;
|
|
},
|
|
onRedirectTargetPriority: -1,
|
|
onRedirectTarget(target, source, source2) {
|
|
if (source !== this.effectData.target) return;
|
|
return source.side.foe.active[this.effectData.position];
|
|
},
|
|
onDamagingHit(damage, target, source, move) {
|
|
if (source.side !== target.side && this.getCategory(move) === 'Special') {
|
|
this.effectData.position = source.position;
|
|
this.effectData.damage = 2 * damage;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "scripted",
|
|
type: "Psychic",
|
|
contestType: "Beautiful",
|
|
},
|
|
mirrormove: {
|
|
num: 119,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Mirror Move",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryHit(target, pokemon) {
|
|
const move = target.lastMove;
|
|
if (!move || !move.flags['mirror'] || move.isZ || move.isMax) {
|
|
return false;
|
|
}
|
|
this.useMove(move.id, pokemon, target);
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
zMove: {boost: {atk: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
mirrorshot: {
|
|
num: 429,
|
|
accuracy: 85,
|
|
basePower: 65,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Mirror Shot",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Beautiful",
|
|
},
|
|
mist: {
|
|
num: 54,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Mist",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
sideCondition: 'mist',
|
|
condition: {
|
|
duration: 5,
|
|
onBoost(boost, target, source, effect) {
|
|
if (effect.effectType === 'Move' && effect.infiltrates && target.side !== source.side) return;
|
|
if (source && target !== source) {
|
|
let showMsg = false;
|
|
let i: BoostName;
|
|
for (i in boost) {
|
|
if (boost[i]! < 0) {
|
|
delete boost[i];
|
|
showMsg = true;
|
|
}
|
|
}
|
|
if (showMsg && !(effect as ActiveMove).secondaries) {
|
|
this.add('-activate', target, 'move: Mist');
|
|
}
|
|
}
|
|
},
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'Mist');
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 3,
|
|
onEnd(side) {
|
|
this.add('-sideend', side, 'Mist');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Ice",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Beautiful",
|
|
},
|
|
mistball: {
|
|
num: 296,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Mist Ball",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
spa: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
mistyexplosion: {
|
|
num: 802,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Misty Explosion",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
selfdestruct: "always",
|
|
onBasePower(basePower, source) {
|
|
if (this.field.isTerrain('mistyterrain') && source.isGrounded()) {
|
|
this.debug('misty terrain boost');
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Fairy",
|
|
},
|
|
mistyterrain: {
|
|
num: 581,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Misty Terrain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {nonsky: 1},
|
|
terrain: 'mistyterrain',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasItem('terrainextender')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onSetStatus(status, target, source, effect) {
|
|
if (!target.isGrounded() || target.isSemiInvulnerable()) return;
|
|
if (effect && ((effect as Move).status || effect.id === 'yawn')) {
|
|
this.add('-activate', target, 'move: Misty Terrain');
|
|
}
|
|
return false;
|
|
},
|
|
onTryAddVolatile(status, target, source, effect) {
|
|
if (!target.isGrounded() || target.isSemiInvulnerable()) return;
|
|
if (status.id === 'confusion') {
|
|
if (effect.effectType === 'Move' && !effect.secondaries) this.add('-activate', target, 'move: Misty Terrain');
|
|
return null;
|
|
}
|
|
},
|
|
onBasePowerPriority: 6,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === 'Dragon' && defender.isGrounded() && !defender.isSemiInvulnerable()) {
|
|
this.debug('misty terrain weaken');
|
|
return this.chainModify(0.5);
|
|
}
|
|
},
|
|
onStart(battle, source, effect) {
|
|
if (effect?.effectType === 'Ability') {
|
|
this.add('-fieldstart', 'move: Misty Terrain', '[from] ability: ' + effect, '[of] ' + source);
|
|
} else {
|
|
this.add('-fieldstart', 'move: Misty Terrain');
|
|
}
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 2,
|
|
onEnd(side) {
|
|
this.add('-fieldend', 'Misty Terrain');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fairy",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
moonblast: {
|
|
num: 585,
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Special",
|
|
name: "Moonblast",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
spa: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Beautiful",
|
|
},
|
|
moongeistbeam: {
|
|
num: 714,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Moongeist Beam",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
moonlight: {
|
|
num: 236,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Moonlight",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onHit(pokemon) {
|
|
let factor = 0.5;
|
|
switch (pokemon.effectiveWeather()) {
|
|
case 'sunnyday':
|
|
case 'desolateland':
|
|
factor = 0.667;
|
|
break;
|
|
case 'raindance':
|
|
case 'primordialsea':
|
|
case 'sandstorm':
|
|
case 'hail':
|
|
factor = 0.25;
|
|
break;
|
|
}
|
|
return !!this.heal(this.modify(pokemon.maxhp, factor));
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fairy",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
morningsun: {
|
|
num: 234,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Morning Sun",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onHit(pokemon) {
|
|
let factor = 0.5;
|
|
switch (pokemon.effectiveWeather()) {
|
|
case 'sunnyday':
|
|
case 'desolateland':
|
|
factor = 0.667;
|
|
break;
|
|
case 'raindance':
|
|
case 'primordialsea':
|
|
case 'sandstorm':
|
|
case 'hail':
|
|
factor = 0.25;
|
|
break;
|
|
}
|
|
return !!this.heal(this.modify(pokemon.maxhp, factor));
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
mudbomb: {
|
|
num: 426,
|
|
accuracy: 85,
|
|
basePower: 65,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Mud Bomb",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Cute",
|
|
},
|
|
mudshot: {
|
|
num: 341,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Special",
|
|
name: "Mud Shot",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough",
|
|
},
|
|
mudslap: {
|
|
num: 189,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Special",
|
|
name: "Mud-Slap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Cute",
|
|
},
|
|
mudsport: {
|
|
num: 300,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Mud Sport",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {nonsky: 1},
|
|
pseudoWeather: 'mudsport',
|
|
condition: {
|
|
duration: 5,
|
|
onStart(side, source) {
|
|
this.add('-fieldstart', 'move: Mud Sport', '[of] ' + source);
|
|
},
|
|
onBasePowerPriority: 1,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === 'Electric') {
|
|
this.debug('mud sport weaken');
|
|
return this.chainModify([0x548, 0x1000]);
|
|
}
|
|
},
|
|
onResidualOrder: 21,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Mud Sport');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ground",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
muddywater: {
|
|
num: 330,
|
|
accuracy: 85,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Muddy Water",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Tough",
|
|
},
|
|
multiattack: {
|
|
num: 718,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Multi-Attack",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.ignoringItem()) return;
|
|
move.type = this.runEvent('Memory', pokemon, null, move, 'Normal');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 185},
|
|
maxMove: {basePower: 95},
|
|
contestType: "Tough",
|
|
},
|
|
mysticalfire: {
|
|
num: 595,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Special",
|
|
name: "Mystical Fire",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
nastyplot: {
|
|
num: 417,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Nasty Plot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
spa: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dark",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
naturalgift: {
|
|
num: 363,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Natural Gift",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.ignoringItem()) return;
|
|
const item = pokemon.getItem();
|
|
if (!item.naturalGift) return;
|
|
move.type = item.naturalGift.type;
|
|
},
|
|
onPrepareHit(target, pokemon, move) {
|
|
if (pokemon.ignoringItem()) return false;
|
|
const item = pokemon.getItem();
|
|
if (!item.naturalGift) return false;
|
|
move.basePower = item.naturalGift.basePower;
|
|
pokemon.setItem('');
|
|
pokemon.lastItem = item.id;
|
|
pokemon.usedItemThisTurn = true;
|
|
this.runEvent('AfterUseItem', pokemon, null, null, item);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Clever",
|
|
},
|
|
naturepower: {
|
|
num: 267,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Nature Power",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryHit(target, pokemon) {
|
|
let move = 'triattack';
|
|
if (this.field.isTerrain('electricterrain')) {
|
|
move = 'thunderbolt';
|
|
} else if (this.field.isTerrain('grassyterrain')) {
|
|
move = 'energyball';
|
|
} else if (this.field.isTerrain('mistyterrain')) {
|
|
move = 'moonblast';
|
|
} else if (this.field.isTerrain('psychicterrain')) {
|
|
move = 'psychic';
|
|
}
|
|
this.useMove(move, pokemon, target);
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
naturesmadness: {
|
|
num: 717,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
return this.clampIntRange(Math.floor(target.getUndynamaxedHP() / 2), 1);
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Nature's Madness",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Tough",
|
|
},
|
|
needlearm: {
|
|
num: 302,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Needle Arm",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever",
|
|
},
|
|
neverendingnightmare: {
|
|
num: 636,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Never-Ending Nightmare",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "ghostiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
nightdaze: {
|
|
num: 539,
|
|
accuracy: 95,
|
|
basePower: 85,
|
|
category: "Special",
|
|
name: "Night Daze",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 40,
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool",
|
|
},
|
|
nightmare: {
|
|
num: 171,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Nightmare",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
volatileStatus: 'nightmare',
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
if (pokemon.status !== 'slp' && !pokemon.hasAbility('comatose')) {
|
|
return false;
|
|
}
|
|
this.add('-start', pokemon, 'Nightmare');
|
|
},
|
|
onResidualOrder: 9,
|
|
onResidual(pokemon) {
|
|
this.damage(pokemon.baseMaxhp / 4);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
nightshade: {
|
|
num: 101,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damage: 'level',
|
|
category: "Special",
|
|
name: "Night Shade",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever",
|
|
},
|
|
nightslash: {
|
|
num: 400,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Night Slash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool",
|
|
},
|
|
nobleroar: {
|
|
num: 568,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Noble Roar",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, authentic: 1},
|
|
boosts: {
|
|
atk: -1,
|
|
spa: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
noretreat: {
|
|
num: 748,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "No Retreat",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
volatileStatus: 'noretreat',
|
|
onTryHit(target, source, move) {
|
|
if (target.volatiles['noretreat']) return false;
|
|
if (target.volatiles['trapped']) {
|
|
delete move.volatileStatus;
|
|
}
|
|
},
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'move: No Retreat');
|
|
},
|
|
onTrapPokemon(pokemon) {
|
|
pokemon.tryTrap();
|
|
},
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fighting",
|
|
},
|
|
nuzzle: {
|
|
num: 609,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Physical",
|
|
name: "Nuzzle",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cute",
|
|
},
|
|
oblivionwing: {
|
|
num: 613,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Oblivion Wing",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, distance: 1, heal: 1},
|
|
drain: [3, 4],
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
obstruct: {
|
|
num: 792,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Obstruct",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {},
|
|
stallingMove: true,
|
|
volatileStatus: 'obstruct',
|
|
onTryHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent('StallMove', pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'Protect');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags['protect'] || move.category === 'Status') {
|
|
if (move.isZ || (move.isMax && !move.breaksProtect)) target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add('-activate', target, 'move: Protect');
|
|
}
|
|
const lockedmove = source.getVolatile('lockedmove');
|
|
if (lockedmove) {
|
|
// Outrage counter is reset
|
|
if (source.volatiles['lockedmove'].duration === 2) {
|
|
delete source.volatiles['lockedmove'];
|
|
}
|
|
}
|
|
if (move.flags['contact']) {
|
|
this.boost({def: -2}, source, target, this.dex.getActiveMove("Obstruct"));
|
|
}
|
|
return this.NOT_FAIL;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZOrMaxPowered && move.flags['contact']) {
|
|
this.boost({def: -2}, source, target, this.dex.getActiveMove("Obstruct"));
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dark",
|
|
},
|
|
oceanicoperetta: {
|
|
num: 697,
|
|
accuracy: true,
|
|
basePower: 195,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Oceanic Operetta",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "primariumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
octazooka: {
|
|
num: 190,
|
|
accuracy: 85,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Octazooka",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough",
|
|
},
|
|
octolock: {
|
|
num: 753,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Octolock",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryImmunity(target) {
|
|
return this.dex.getImmunity('trapped', target);
|
|
},
|
|
volatileStatus: 'octolock',
|
|
condition: {
|
|
onStart(pokemon, source) {
|
|
this.add('-start', pokemon, 'move: Octolock', '[of] ' + source);
|
|
},
|
|
onResidualOrder: 11,
|
|
onResidual(pokemon) {
|
|
const source = this.effectData.source;
|
|
if (source && (!source.isActive || source.hp <= 0 || !source.activeTurns)) {
|
|
delete pokemon.volatiles['octolock'];
|
|
this.add('-end', pokemon, 'Octolock', '[partiallytrapped]', '[silent]');
|
|
return;
|
|
}
|
|
this.boost({def: -1, spd: -1}, pokemon, source, this.dex.getActiveMove('octolock'));
|
|
},
|
|
onTrapPokemon(pokemon) {
|
|
if (this.effectData.source && this.effectData.source.isActive) pokemon.tryTrap();
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
},
|
|
odorsleuth: {
|
|
num: 316,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Odor Sleuth",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1, mystery: 1},
|
|
volatileStatus: 'foresight',
|
|
onTryHit(target) {
|
|
if (target.volatiles['miracleeye']) return false;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
ominouswind: {
|
|
num: 466,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Ominous Wind",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Beautiful",
|
|
},
|
|
originpulse: {
|
|
num: 618,
|
|
accuracy: 85,
|
|
basePower: 110,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Origin Pulse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, pulse: 1, mirror: 1},
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
outrage: {
|
|
num: 200,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Outrage",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'lockedmove',
|
|
},
|
|
onAfterMove(pokemon) {
|
|
if (pokemon.volatiles['lockedmove'] && pokemon.volatiles['lockedmove'].duration === 1) {
|
|
pokemon.removeVolatile('lockedmove');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Dragon",
|
|
contestType: "Cool",
|
|
},
|
|
overdrive: {
|
|
num: 786,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Overdrive",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Electric",
|
|
},
|
|
overheat: {
|
|
num: 315,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Overheat",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
self: {
|
|
boosts: {
|
|
spa: -2,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
painsplit: {
|
|
num: 220,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Pain Split",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, mystery: 1},
|
|
onHit(target, pokemon) {
|
|
const targetHP = target.getUndynamaxedHP();
|
|
const averagehp = Math.floor((targetHP + pokemon.hp) / 2) || 1;
|
|
const targetChange = targetHP - averagehp;
|
|
target.sethp(target.hp - targetChange);
|
|
this.add('-sethp', target, target.getHealth, '[from] move: Pain Split', '[silent]');
|
|
pokemon.sethp(averagehp);
|
|
this.add('-sethp', pokemon, pokemon.getHealth, '[from] move: Pain Split');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
paleowave: {
|
|
num: 0,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Special",
|
|
isNonstandard: "CAP",
|
|
name: "Paleo Wave",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
atk: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Beautiful",
|
|
},
|
|
paraboliccharge: {
|
|
num: 570,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Parabolic Charge",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, heal: 1},
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Electric",
|
|
contestType: "Clever",
|
|
},
|
|
partingshot: {
|
|
num: 575,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Parting Shot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, authentic: 1},
|
|
onHit(target, source, move) {
|
|
const success = this.boost({atk: -1, spa: -1}, target, source);
|
|
if (!success && !target.hasAbility('mirrorarmor')) {
|
|
delete move.selfSwitch;
|
|
}
|
|
},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {effect: 'healreplacement'},
|
|
contestType: "Cool",
|
|
},
|
|
payback: {
|
|
num: 371,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.newlySwitched || this.queue.willMove(target)) {
|
|
this.debug('Payback NOT boosted');
|
|
return move.basePower;
|
|
}
|
|
this.debug('Payback damage boost');
|
|
return move.basePower * 2;
|
|
},
|
|
category: "Physical",
|
|
name: "Payback",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough",
|
|
},
|
|
payday: {
|
|
num: 6,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Pay Day",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onHit() {
|
|
this.add('-fieldactivate', 'move: Pay Day');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Clever",
|
|
},
|
|
peck: {
|
|
num: 64,
|
|
accuracy: 100,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
name: "Peck",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, distance: 1},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
perishsong: {
|
|
num: 195,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Perish Song",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {sound: 1, distance: 1, authentic: 1},
|
|
onHitField(target, source, move) {
|
|
let result = false;
|
|
let message = false;
|
|
for (const pokemon of this.getAllActive()) {
|
|
if (this.runEvent('Invulnerability', pokemon, source, move) === false) {
|
|
this.add('-miss', source, pokemon);
|
|
result = true;
|
|
} else if (this.runEvent('TryHit', pokemon, source, move) === null) {
|
|
result = true;
|
|
} else if (!pokemon.volatiles['perishsong']) {
|
|
pokemon.addVolatile('perishsong');
|
|
this.add('-start', pokemon, 'perish3', '[silent]');
|
|
result = true;
|
|
message = true;
|
|
}
|
|
}
|
|
if (!result) return false;
|
|
if (message) this.add('-fieldactivate', 'move: Perish Song');
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onEnd(target) {
|
|
this.add('-start', target, 'perish0');
|
|
target.faint();
|
|
},
|
|
onResidualOrder: 20,
|
|
onResidual(pokemon) {
|
|
const duration = pokemon.volatiles['perishsong'].duration;
|
|
this.add('-start', pokemon, 'perish' + duration);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
petalblizzard: {
|
|
num: 572,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Petal Blizzard",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Grass",
|
|
contestType: "Beautiful",
|
|
},
|
|
petaldance: {
|
|
num: 80,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Petal Dance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, dance: 1},
|
|
self: {
|
|
volatileStatus: 'lockedmove',
|
|
},
|
|
onAfterMove(pokemon) {
|
|
if (pokemon.volatiles['lockedmove'] && pokemon.volatiles['lockedmove'].duration === 1) {
|
|
pokemon.removeVolatile('lockedmove');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Grass",
|
|
contestType: "Beautiful",
|
|
},
|
|
phantomforce: {
|
|
num: 566,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Phantom Force",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, charge: 1, mirror: 1},
|
|
breaksProtect: true,
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onInvulnerability: false,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
photongeyser: {
|
|
num: 722,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Photon Geyser",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyMove(move, pokemon) {
|
|
if (pokemon.getStat('atk', false, true) > pokemon.getStat('spa', false, true)) move.category = 'Physical';
|
|
},
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
pikapapow: {
|
|
num: 732,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
return Math.floor((pokemon.happiness * 10) / 25) || 1;
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Pika Papow",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cute",
|
|
},
|
|
pinmissile: {
|
|
num: 42,
|
|
accuracy: 95,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Pin Missile",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cool",
|
|
},
|
|
plasmafists: {
|
|
num: 721,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Plasma Fists",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
pseudoWeather: 'iondeluge',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
playnice: {
|
|
num: 589,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Play Nice",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {reflectable: 1, mirror: 1, authentic: 1},
|
|
boosts: {
|
|
atk: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
playrough: {
|
|
num: 583,
|
|
accuracy: 90,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Play Rough",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
atk: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Cute",
|
|
},
|
|
pluck: {
|
|
num: 365,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Pluck",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, distance: 1},
|
|
onHit(target, source) {
|
|
const item = target.getItem();
|
|
if (source.hp && item.isBerry && target.takeItem(source)) {
|
|
this.add('-enditem', target, item.name, '[from] stealeat', '[move] Pluck', '[of] ' + source);
|
|
if (this.singleEvent('Eat', item, null, source, null, null)) {
|
|
this.runEvent('EatItem', source, null, null, item);
|
|
if (item.id === 'leppaberry') target.staleness = 'external';
|
|
}
|
|
if (item.onEat) source.ateBerry = true;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cute",
|
|
},
|
|
poisonfang: {
|
|
num: 305,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Poison Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
status: 'tox',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Clever",
|
|
},
|
|
poisongas: {
|
|
num: 139,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Poison Gas",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'psn',
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Poison",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
poisonjab: {
|
|
num: 398,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Poison Jab",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough",
|
|
},
|
|
poisonpowder: {
|
|
num: 77,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Poison Powder",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {powder: 1, protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'psn',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
poisonsting: {
|
|
num: 40,
|
|
accuracy: 100,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Poison Sting",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Clever",
|
|
},
|
|
poisontail: {
|
|
num: 342,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Poison Tail",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Clever",
|
|
},
|
|
pollenpuff: {
|
|
num: 676,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Pollen Puff",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
onTryHit(target, source, move) {
|
|
if (source.side === target.side) {
|
|
move.basePower = 0;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
if (source.side === target.side) {
|
|
this.heal(Math.floor(target.baseMaxhp * 0.5));
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute",
|
|
},
|
|
poltergeist: {
|
|
num: 809,
|
|
accuracy: 90,
|
|
basePower: 110,
|
|
category: "Physical",
|
|
name: "Poltergeist",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTry(pokemon, target) {
|
|
if (!target.item) {
|
|
this.attrLastMove('[still]');
|
|
this.add('-fail', pokemon);
|
|
return null;
|
|
}
|
|
},
|
|
onTryHit(target, source, move) {
|
|
this.add('-activate', target, 'move: Poltergeist', this.dex.getItem(target.item).name);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
},
|
|
pound: {
|
|
num: 1,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Pound",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
powder: {
|
|
num: 600,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Powder",
|
|
pp: 20,
|
|
priority: 1,
|
|
flags: {powder: 1, protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
volatileStatus: 'powder',
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'Powder');
|
|
},
|
|
onTryMovePriority: -1,
|
|
onTryMove(pokemon, target, move) {
|
|
if (move.type === 'Fire') {
|
|
this.add('-activate', pokemon, 'move: Powder');
|
|
this.damage(this.clampIntRange(Math.round(pokemon.maxhp / 4), 1));
|
|
return false;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
zMove: {boost: {spd: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
powdersnow: {
|
|
num: 181,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Powder Snow",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'frz',
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Ice",
|
|
contestType: "Beautiful",
|
|
},
|
|
powergem: {
|
|
num: 408,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Power Gem",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Beautiful",
|
|
},
|
|
powersplit: {
|
|
num: 471,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Power Split",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
const newatk = Math.floor((target.storedStats.atk + source.storedStats.atk) / 2);
|
|
target.storedStats.atk = newatk;
|
|
source.storedStats.atk = newatk;
|
|
const newspa = Math.floor((target.storedStats.spa + source.storedStats.spa) / 2);
|
|
target.storedStats.spa = newspa;
|
|
source.storedStats.spa = newspa;
|
|
this.add('-activate', source, 'move: Power Split', '[of] ' + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
powerswap: {
|
|
num: 384,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Power Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, authentic: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
const targetBoosts: SparseBoostsTable = {};
|
|
const sourceBoosts: SparseBoostsTable = {};
|
|
|
|
const atkSpa: BoostName[] = ['atk', 'spa'];
|
|
for (const stat of atkSpa) {
|
|
targetBoosts[stat] = target.boosts[stat];
|
|
sourceBoosts[stat] = source.boosts[stat];
|
|
}
|
|
|
|
source.setBoost(targetBoosts);
|
|
target.setBoost(sourceBoosts);
|
|
|
|
this.add('-swapboost', source, target, 'atk, spa', '[from] move: Power Swap');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
powertrick: {
|
|
num: 379,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Power Trick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
volatileStatus: 'powertrick',
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'Power Trick');
|
|
const newatk = pokemon.storedStats.def;
|
|
const newdef = pokemon.storedStats.atk;
|
|
pokemon.storedStats.atk = newatk;
|
|
pokemon.storedStats.def = newdef;
|
|
},
|
|
onCopy(pokemon) {
|
|
const newatk = pokemon.storedStats.def;
|
|
const newdef = pokemon.storedStats.atk;
|
|
pokemon.storedStats.atk = newatk;
|
|
pokemon.storedStats.def = newdef;
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add('-end', pokemon, 'Power Trick');
|
|
const newatk = pokemon.storedStats.def;
|
|
const newdef = pokemon.storedStats.atk;
|
|
pokemon.storedStats.atk = newatk;
|
|
pokemon.storedStats.def = newdef;
|
|
},
|
|
onRestart(pokemon) {
|
|
pokemon.removeVolatile('Power Trick');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
powertrip: {
|
|
num: 681,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return move.basePower + 20 * pokemon.positiveBoosts();
|
|
},
|
|
category: "Physical",
|
|
name: "Power Trip",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Clever",
|
|
},
|
|
poweruppunch: {
|
|
num: 612,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Power-Up Punch",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
powerwhip: {
|
|
num: 438,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Power Whip",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough",
|
|
},
|
|
precipiceblades: {
|
|
num: 619,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Precipice Blades",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
target: "allAdjacentFoes",
|
|
type: "Ground",
|
|
contestType: "Cool",
|
|
},
|
|
present: {
|
|
num: 217,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Present",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyMove(move, pokemon, target) {
|
|
const rand = this.random(10);
|
|
if (rand < 2) {
|
|
move.heal = [1, 4];
|
|
} else if (rand < 6) {
|
|
move.basePower = 40;
|
|
} else if (rand < 9) {
|
|
move.basePower = 80;
|
|
} else {
|
|
move.basePower = 120;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
prismaticlaser: {
|
|
num: 711,
|
|
accuracy: 100,
|
|
basePower: 160,
|
|
category: "Special",
|
|
name: "Prismatic Laser",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {recharge: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
protect: {
|
|
num: 182,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Protect",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {},
|
|
stallingMove: true,
|
|
volatileStatus: 'protect',
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent('StallMove', pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'Protect');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags['protect']) {
|
|
if (move.isZ || (move.isMax && !move.breaksProtect)) target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add('-activate', target, 'move: Protect');
|
|
}
|
|
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;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
psybeam: {
|
|
num: 60,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Psybeam",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Beautiful",
|
|
},
|
|
psychup: {
|
|
num: 244,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Psych Up",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {authentic: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
let i: BoostName;
|
|
for (i in target.boosts) {
|
|
source.boosts[i] = target.boosts[i];
|
|
}
|
|
const volatilesToCopy = ['focusenergy', 'gmaxchistrike', 'laserfocus'];
|
|
for (const volatile of volatilesToCopy) {
|
|
if (target.volatiles[volatile]) {
|
|
source.addVolatile(volatile);
|
|
if (volatile === 'gmaxchistrike') source.volatiles[volatile].layers = target.volatiles[volatile].layers;
|
|
} else {
|
|
source.removeVolatile(volatile);
|
|
}
|
|
}
|
|
this.add('-copyboost', source, target, '[from] move: Psych Up');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Clever",
|
|
},
|
|
psychic: {
|
|
num: 94,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Psychic",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
psychicfangs: {
|
|
num: 706,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Psychic Fangs",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
onTryHit(pokemon) {
|
|
// will shatter screens through sub, before you hit
|
|
if (pokemon.runImmunity('Psychic')) {
|
|
pokemon.side.removeSideCondition('reflect');
|
|
pokemon.side.removeSideCondition('lightscreen');
|
|
pokemon.side.removeSideCondition('auroraveil');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
psychicterrain: {
|
|
num: 678,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Psychic Terrain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {nonsky: 1},
|
|
terrain: 'psychicterrain',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasItem('terrainextender')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onTryHitPriority: 4,
|
|
onTryHit(target, source, effect) {
|
|
if (effect && (effect.priority <= 0.1 || effect.target === 'self')) {
|
|
return;
|
|
}
|
|
if (target.isSemiInvulnerable() || target.side === source.side) return;
|
|
if (!target.isGrounded()) {
|
|
const baseMove = this.dex.getMove(effect.id);
|
|
if (baseMove.priority > 0) {
|
|
this.hint("Psychic Terrain doesn't affect Pokémon immune to Ground.");
|
|
}
|
|
return;
|
|
}
|
|
this.add('-activate', target, 'move: Psychic Terrain');
|
|
return null;
|
|
},
|
|
onBasePowerPriority: 6,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === 'Psychic' && attacker.isGrounded() && !attacker.isSemiInvulnerable()) {
|
|
this.debug('psychic terrain boost');
|
|
return this.chainModify([0x14CD, 0x1000]);
|
|
}
|
|
},
|
|
onStart(battle, source, effect) {
|
|
if (effect?.effectType === 'Ability') {
|
|
this.add('-fieldstart', 'move: Psychic Terrain', '[from] ability: ' + effect, '[of] ' + source);
|
|
} else {
|
|
this.add('-fieldstart', 'move: Psychic Terrain');
|
|
}
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 2,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Psychic Terrain');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
psychoboost: {
|
|
num: 354,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Psycho Boost",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
self: {
|
|
boosts: {
|
|
spa: -2,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
psychocut: {
|
|
num: 427,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Psycho Cut",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
psychoshift: {
|
|
num: 375,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Psycho Shift",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onPrepareHit(target, source, move) {
|
|
if (!source.status) return false;
|
|
move.status = source.status;
|
|
},
|
|
self: {
|
|
onHit(pokemon) {
|
|
pokemon.cureStatus();
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spa: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
psyshock: {
|
|
num: 473,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
defensiveCategory: "Physical",
|
|
name: "Psyshock",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Beautiful",
|
|
},
|
|
psystrike: {
|
|
num: 540,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
defensiveCategory: "Physical",
|
|
name: "Psystrike",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
psywave: {
|
|
num: 149,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
return (this.random(50, 151) * pokemon.level) / 100;
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Psywave",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
pulverizingpancake: {
|
|
num: 701,
|
|
accuracy: true,
|
|
basePower: 210,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Pulverizing Pancake",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {contact: 1},
|
|
isZ: "snorliumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
punishment: {
|
|
num: 386,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
let power = 60 + 20 * target.positiveBoosts();
|
|
if (power > 200) power = 200;
|
|
return power;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Punishment",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cool",
|
|
},
|
|
purify: {
|
|
num: 685,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Purify",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, heal: 1},
|
|
onHit(target, source) {
|
|
if (!target.cureStatus()) return false;
|
|
this.heal(Math.ceil(source.maxhp * 0.5), source);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: {boost: {atk: 1, def: 1, spa: 1, spd: 1, spe: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
pursuit: {
|
|
num: 228,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
basePowerCallback(pokemon, target, move) {
|
|
// You can't get here unless the pursuit succeeds
|
|
if (target.beingCalledBack) {
|
|
this.debug('Pursuit damage boost');
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Pursuit",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
beforeTurnCallback(pokemon) {
|
|
for (const side of this.sides) {
|
|
if (side === pokemon.side) continue;
|
|
side.addSideCondition('pursuit', pokemon);
|
|
const data = side.getSideConditionData('pursuit');
|
|
if (!data.sources) {
|
|
data.sources = [];
|
|
}
|
|
data.sources.push(pokemon);
|
|
}
|
|
},
|
|
onModifyMove(move, source, target) {
|
|
if (target?.beingCalledBack) move.accuracy = true;
|
|
},
|
|
onTryHit(target, pokemon) {
|
|
target.side.removeSideCondition('pursuit');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onBeforeSwitchOut(pokemon) {
|
|
this.debug('Pursuit start');
|
|
let alreadyAdded = false;
|
|
pokemon.removeVolatile('destinybond');
|
|
for (const source of this.effectData.sources) {
|
|
if (!this.queue.cancelMove(source) || !source.hp) continue;
|
|
if (!alreadyAdded) {
|
|
this.add('-activate', pokemon, 'move: Pursuit');
|
|
alreadyAdded = true;
|
|
}
|
|
// Run through each action in queue to check if the Pursuit user is supposed to Mega Evolve this turn.
|
|
// If it is, then Mega Evolve before moving.
|
|
if (source.canMegaEvo || source.canUltraBurst) {
|
|
for (const [actionIndex, action] of this.queue.entries()) {
|
|
if (action.pokemon === source && action.choice === 'megaEvo') {
|
|
this.runMegaEvo(source);
|
|
this.queue.list.splice(actionIndex, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
this.runMove('pursuit', source, this.getTargetLoc(pokemon, source));
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
pyroball: {
|
|
num: 780,
|
|
accuracy: 90,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Pyro Ball",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, defrost: 1, bullet: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
quash: {
|
|
num: 511,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Quash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onHit(target) {
|
|
if (target.side.active.length < 2) return false; // fails in singles
|
|
const action = this.queue.willMove(target);
|
|
if (!action) return false;
|
|
|
|
action.order = 201;
|
|
this.add('-activate', target, 'move: Quash');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
quickattack: {
|
|
num: 98,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Quick Attack",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
quickguard: {
|
|
num: 501,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Quick Guard",
|
|
pp: 15,
|
|
priority: 3,
|
|
flags: {snatch: 1},
|
|
sideCondition: 'quickguard',
|
|
onTryHitSide(side, source) {
|
|
return !!this.queue.willAct();
|
|
},
|
|
onHitSide(side, source) {
|
|
source.addVolatile('stall');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source) {
|
|
this.add('-singleturn', source, 'Quick Guard');
|
|
},
|
|
onTryHitPriority: 4,
|
|
onTryHit(target, source, move) {
|
|
// 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 (move.isZ || (move.isMax && !move.breaksProtect)) target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
this.add('-activate', target, 'move: Quick Guard');
|
|
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;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Fighting",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
quiverdance: {
|
|
num: 483,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Quiver Dance",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1, dance: 1},
|
|
boosts: {
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
rage: {
|
|
num: 99,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Rage",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'rage',
|
|
},
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add('-singlemove', pokemon, 'Rage');
|
|
},
|
|
onHit(target, source, move) {
|
|
if (target !== source && move.category !== 'Status') {
|
|
this.boost({atk: 1});
|
|
}
|
|
},
|
|
onBeforeMovePriority: 100,
|
|
onBeforeMove(pokemon) {
|
|
this.debug('removing Rage before attack');
|
|
pokemon.removeVolatile('rage');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
ragepowder: {
|
|
num: 476,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Rage Powder",
|
|
pp: 20,
|
|
priority: 2,
|
|
flags: {powder: 1},
|
|
volatileStatus: 'ragepowder',
|
|
onTryHit(target) {
|
|
if (target.side.active.length < 2) return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add('-singleturn', pokemon, 'move: Rage Powder');
|
|
},
|
|
onFoeRedirectTargetPriority: 1,
|
|
onFoeRedirectTarget(target, source, source2, move) {
|
|
const ragePowderUser = this.effectData.target;
|
|
if (ragePowderUser.isSkyDropped()) return;
|
|
|
|
if (source.runStatusImmunity('powder') && this.validTarget(ragePowderUser, source, move.target)) {
|
|
if (move.smartTarget) move.smartTarget = false;
|
|
this.debug("Rage Powder redirected target of move");
|
|
return ragePowderUser;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
raindance: {
|
|
num: 240,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Rain Dance",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
weather: 'RainDance',
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Water",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
rapidspin: {
|
|
num: 229,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Rapid Spin",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onAfterHit(target, pokemon) {
|
|
if (pokemon.hp && 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)) {
|
|
this.add('-sideend', pokemon.side, this.dex.getEffect(condition).name, '[from] move: Rapid Spin', '[of] ' + pokemon);
|
|
}
|
|
}
|
|
if (pokemon.hp && pokemon.volatiles['partiallytrapped']) {
|
|
pokemon.removeVolatile('partiallytrapped');
|
|
}
|
|
},
|
|
onAfterSubDamage(damage, target, pokemon) {
|
|
if (pokemon.hp && 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)) {
|
|
this.add('-sideend', pokemon.side, this.dex.getEffect(condition).name, '[from] move: Rapid Spin', '[of] ' + pokemon);
|
|
}
|
|
}
|
|
if (pokemon.hp && pokemon.volatiles['partiallytrapped']) {
|
|
pokemon.removeVolatile('partiallytrapped');
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
razorleaf: {
|
|
num: 75,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Physical",
|
|
name: "Razor Leaf",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
razorshell: {
|
|
num: 534,
|
|
accuracy: 95,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Razor Shell",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
razorwind: {
|
|
num: 13,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Razor Wind",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {charge: 1, protect: 1, mirror: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
recover: {
|
|
num: 105,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Recover",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
recycle: {
|
|
num: 278,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Recycle",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onHit(pokemon) {
|
|
if (pokemon.item || !pokemon.lastItem) return false;
|
|
const item = pokemon.lastItem;
|
|
pokemon.lastItem = '';
|
|
this.add('-item', pokemon, this.dex.getItem(item), '[from] move: Recycle');
|
|
pokemon.setItem(item);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
reflect: {
|
|
num: 115,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Reflect",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
sideCondition: 'reflect',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasItem('lightclay')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onAnyModifyDamage(damage, source, target, move) {
|
|
if (target !== source && target.side === this.effectData.target && this.getCategory(move) === 'Physical') {
|
|
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
|
|
this.debug('Reflect weaken');
|
|
if (target.side.active.length > 1) return this.chainModify([0xAAC, 0x1000]);
|
|
return this.chainModify(0.5);
|
|
}
|
|
}
|
|
},
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'Reflect');
|
|
},
|
|
onResidualOrder: 21,
|
|
onEnd(side) {
|
|
this.add('-sideend', side, 'Reflect');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Psychic",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
reflecttype: {
|
|
num: 513,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Reflect Type",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, authentic: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
if (source.species && (source.species.num === 493 || source.species.num === 773)) return false;
|
|
let newBaseTypes = target.getTypes(true).filter(type => type !== '???');
|
|
if (!newBaseTypes.length) {
|
|
if (target.addedType) {
|
|
newBaseTypes = ['Normal'];
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
this.add('-start', source, 'typechange', '[from] move: Reflect Type', '[of] ' + target);
|
|
source.setType(newBaseTypes);
|
|
source.addedType = target.addedType;
|
|
source.knownType = target.side === source.side && target.knownType;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
refresh: {
|
|
num: 287,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Refresh",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onHit(pokemon) {
|
|
if (['', 'slp', 'frz'].includes(pokemon.status)) return false;
|
|
pokemon.cureStatus();
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Cute",
|
|
},
|
|
relicsong: {
|
|
num: 547,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Relic Song",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'slp',
|
|
},
|
|
onHit(target, pokemon, move) {
|
|
if (pokemon.baseSpecies.baseSpecies === 'Meloetta' && !pokemon.transformed) {
|
|
move.willChangeForme = true;
|
|
}
|
|
},
|
|
onAfterMoveSecondarySelf(pokemon, target, move) {
|
|
if (move.willChangeForme) {
|
|
const meloettaForme = pokemon.species.id === 'meloettapirouette' ? '' : '-Pirouette';
|
|
pokemon.formeChange('Meloetta' + meloettaForme, this.effect, false, '[msg]');
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
rest: {
|
|
num: 156,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Rest",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onTryMove(pokemon) {
|
|
if (pokemon.hp === pokemon.maxhp) {
|
|
this.add('-fail', pokemon, 'heal');
|
|
return null;
|
|
}
|
|
if (pokemon.status === 'slp' || pokemon.hasAbility('comatose')) {
|
|
this.add('-fail', pokemon);
|
|
return null;
|
|
}
|
|
},
|
|
onHit(target, source, move) {
|
|
if (!target.setStatus('slp', source, move)) return false;
|
|
target.statusData.time = 3;
|
|
target.statusData.startTime = 3;
|
|
this.heal(target.maxhp); // Aesthetic only as the healing happens after you fall asleep in-game
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
retaliate: {
|
|
num: 514,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Retaliate",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onBasePower(basePower, pokemon) {
|
|
if (pokemon.side.faintedLastTurn) {
|
|
this.debug('Boosted for a faint last turn');
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
return: {
|
|
num: 216,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
return Math.floor((pokemon.happiness * 10) / 25) || 1;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Return",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cute",
|
|
},
|
|
revelationdance: {
|
|
num: 686,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Revelation Dance",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, dance: 1},
|
|
onModifyType(move, pokemon) {
|
|
let type = pokemon.types[0];
|
|
if (type === "Bird") type = "???";
|
|
move.type = type;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
revenge: {
|
|
num: 279,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const damagedByTarget = pokemon.attackedBy.some(
|
|
p => p.source === target && p.damage > 0 && p.thisTurn
|
|
);
|
|
if (damagedByTarget) {
|
|
this.debug('Boosted for getting hit by ' + target);
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Revenge",
|
|
pp: 10,
|
|
priority: -4,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
reversal: {
|
|
num: 179,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const ratio = pokemon.hp * 48 / pokemon.maxhp;
|
|
if (ratio < 2) {
|
|
return 200;
|
|
}
|
|
if (ratio < 5) {
|
|
return 150;
|
|
}
|
|
if (ratio < 10) {
|
|
return 100;
|
|
}
|
|
if (ratio < 17) {
|
|
return 80;
|
|
}
|
|
if (ratio < 33) {
|
|
return 40;
|
|
}
|
|
return 20;
|
|
},
|
|
category: "Physical",
|
|
name: "Reversal",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
zMove: {basePower: 160},
|
|
contestType: "Cool",
|
|
},
|
|
risingvoltage: {
|
|
num: 804,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
name: "Rising Voltage",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onBasePower(basePower, pokemon, target) {
|
|
if (this.field.isTerrain('electricterrain') && target.isGrounded()) {
|
|
this.debug('terrain buff');
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
maxMove: {basePower: 140},
|
|
},
|
|
roar: {
|
|
num: 46,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Roar",
|
|
pp: 20,
|
|
priority: -6,
|
|
flags: {reflectable: 1, mirror: 1, sound: 1, authentic: 1, mystery: 1},
|
|
forceSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
roaroftime: {
|
|
num: 459,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Roar of Time",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {recharge: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Beautiful",
|
|
},
|
|
rockblast: {
|
|
num: 350,
|
|
accuracy: 90,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Rock Blast",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Tough",
|
|
},
|
|
rockclimb: {
|
|
num: 431,
|
|
accuracy: 85,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Rock Climb",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
rockpolish: {
|
|
num: 397,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Rock Polish",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
spe: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Rock",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Tough",
|
|
},
|
|
rockslide: {
|
|
num: 157,
|
|
accuracy: 90,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Rock Slide",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Rock",
|
|
contestType: "Tough",
|
|
},
|
|
rocksmash: {
|
|
num: 249,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Rock Smash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
rockthrow: {
|
|
num: 88,
|
|
accuracy: 90,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Rock Throw",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough",
|
|
},
|
|
rocktomb: {
|
|
num: 317,
|
|
accuracy: 95,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Rock Tomb",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Clever",
|
|
},
|
|
rockwrecker: {
|
|
num: 439,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
name: "Rock Wrecker",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {bullet: 1, recharge: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'mustrecharge',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough",
|
|
},
|
|
roleplay: {
|
|
num: 272,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Role Play",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {authentic: 1, mystery: 1},
|
|
onTryHit(target, source) {
|
|
if (target.ability === source.ability) return false;
|
|
|
|
const bannedTargetAbilities = [
|
|
'battlebond', 'comatose', 'disguise', 'flowergift', 'forecast', 'illusion', 'imposter', 'multitype', 'neutralizinggas', 'powerconstruct', 'powerofalchemy', 'receiver', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'trace', 'wonderguard', 'zenmode',
|
|
];
|
|
const bannedSourceAbilities = [
|
|
'battlebond', 'comatose', 'disguise', 'multitype', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange',
|
|
];
|
|
if (bannedTargetAbilities.includes(target.ability) || bannedSourceAbilities.includes(source.ability)) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
const oldAbility = source.setAbility(target.ability);
|
|
if (oldAbility) {
|
|
this.add('-ability', source, source.getAbility().name, '[from] move: Role Play', '[of] ' + target);
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
rollingkick: {
|
|
num: 27,
|
|
accuracy: 85,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Rolling Kick",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
rollout: {
|
|
num: 205,
|
|
accuracy: 90,
|
|
basePower: 30,
|
|
basePowerCallback(pokemon, target, move) {
|
|
let bp = move.basePower;
|
|
if (pokemon.volatiles['rollout'] && pokemon.volatiles['rollout'].hitCount) {
|
|
bp *= Math.pow(2, pokemon.volatiles['rollout'].hitCount);
|
|
}
|
|
if (pokemon.status !== 'slp') pokemon.addVolatile('rollout');
|
|
if (pokemon.volatiles['defensecurl']) {
|
|
bp *= 2;
|
|
}
|
|
this.debug("Rollout bp: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Rollout",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
condition: {
|
|
duration: 2,
|
|
onLockMove: 'rollout',
|
|
onStart() {
|
|
this.effectData.hitCount = 1;
|
|
},
|
|
onRestart() {
|
|
this.effectData.hitCount++;
|
|
if (this.effectData.hitCount < 5) {
|
|
this.effectData.duration = 2;
|
|
}
|
|
},
|
|
onResidual(target) {
|
|
if (target.lastMove && target.lastMove.id === 'struggle') {
|
|
// don't lock
|
|
delete target.volatiles['rollout'];
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Cute",
|
|
},
|
|
roost: {
|
|
num: 355,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Roost",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
heal: [1, 2],
|
|
self: {
|
|
volatileStatus: 'roost',
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onResidualOrder: 20,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'move: Roost');
|
|
},
|
|
onTypePriority: -1,
|
|
onType(types, pokemon) {
|
|
this.effectData.typeWas = types;
|
|
return types.filter(type => type !== 'Flying');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Flying",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
rototiller: {
|
|
num: 563,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Rototiller",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {distance: 1, nonsky: 1},
|
|
onHitField(target, source) {
|
|
const targets: Pokemon[] = [];
|
|
let anyAirborne = false;
|
|
for (const pokemon of this.getAllActive()) {
|
|
if (!pokemon.runImmunity('Ground')) {
|
|
this.add('-immune', pokemon);
|
|
anyAirborne = true;
|
|
continue;
|
|
}
|
|
if (pokemon.hasType('Grass')) {
|
|
// This move affects every grounded Grass-type Pokemon in play.
|
|
targets.push(pokemon);
|
|
}
|
|
}
|
|
if (!targets.length && !anyAirborne) return false; // Fails when there are no grounded Grass types or airborne Pokemon
|
|
for (const pokemon of targets) {
|
|
this.boost({atk: 1, spa: 1}, pokemon, source);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ground",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
round: {
|
|
num: 496,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
basePowerCallback(target, source, move) {
|
|
if (move.sourceEffect === 'round') {
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Special",
|
|
name: "Round",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
onTry(target, source, move) {
|
|
for (const action of this.queue) {
|
|
// @ts-ignore
|
|
if (!action.pokemon || !action.move || action.maxMove || action.zmove) continue;
|
|
// @ts-ignore
|
|
if (action.move?.id === 'round') {
|
|
// @ts-ignore
|
|
this.queue.prioritizeAction(action, move);
|
|
return;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
sacredfire: {
|
|
num: 221,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Sacred Fire",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, defrost: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful",
|
|
},
|
|
sacredsword: {
|
|
num: 533,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Sacred Sword",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
ignoreEvasion: true,
|
|
ignoreDefensive: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
safeguard: {
|
|
num: 219,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Safeguard",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
sideCondition: 'safeguard',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasAbility('persistent')) {
|
|
this.add('-activate', source, 'ability: Persistent', effect);
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onSetStatus(status, target, source, effect) {
|
|
if (!effect || !source) return;
|
|
if (effect.id === 'yawn') return;
|
|
if (effect.effectType === 'Move' && effect.infiltrates && target.side !== source.side) return;
|
|
if (target !== source) {
|
|
this.debug('interrupting setStatus');
|
|
if (effect.id === 'synchronize' || (effect.effectType === 'Move' && !effect.secondaries)) {
|
|
this.add('-activate', target, 'move: Safeguard');
|
|
}
|
|
return null;
|
|
}
|
|
},
|
|
onTryAddVolatile(status, target, source, effect) {
|
|
if (!effect || !source) return;
|
|
if (effect.effectType === 'Move' && effect.infiltrates && target.side !== source.side) return;
|
|
if ((status.id === 'confusion' || status.id === 'yawn') && target !== source) {
|
|
if (effect.effectType === 'Move' && !effect.secondaries) this.add('-activate', target, 'move: Safeguard');
|
|
return null;
|
|
}
|
|
},
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'Safeguard');
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 2,
|
|
onEnd(side) {
|
|
this.add('-sideend', side, 'Safeguard');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
sandattack: {
|
|
num: 28,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sand Attack",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
zMove: {boost: {evasion: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
sandstorm: {
|
|
num: 201,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sandstorm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
weather: 'Sandstorm',
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Rock",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
sandtomb: {
|
|
num: 328,
|
|
accuracy: 85,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
name: "Sand Tomb",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
volatileStatus: 'partiallytrapped',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Clever",
|
|
},
|
|
sappyseed: {
|
|
num: 738,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Sappy Seed",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1},
|
|
onHit(target, source) {
|
|
if (target.hasType('Grass')) return null;
|
|
target.addVolatile('leechseed', source);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever",
|
|
},
|
|
savagespinout: {
|
|
num: 634,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Savage Spin-Out",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "buginiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool",
|
|
},
|
|
scald: {
|
|
num: 503,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Scald",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, defrost: 1},
|
|
thawsTarget: true,
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough",
|
|
},
|
|
scaleshot: {
|
|
num: 799,
|
|
accuracy: 90,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Scale Shot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
selfBoost: {
|
|
boosts: {
|
|
def: -1,
|
|
spe: 1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 130},
|
|
},
|
|
scaryface: {
|
|
num: 184,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Scary Face",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
boosts: {
|
|
spe: -2,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
scorchingsands: {
|
|
num: 815,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
name: "Scorching Sands",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, defrost: 1},
|
|
thawsTarget: true,
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
},
|
|
scratch: {
|
|
num: 10,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Scratch",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
screech: {
|
|
num: 103,
|
|
accuracy: 85,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Screech",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, authentic: 1, mystery: 1},
|
|
boosts: {
|
|
def: -2,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
searingshot: {
|
|
num: 545,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Searing Shot",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'brn',
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Fire",
|
|
contestType: "Cool",
|
|
},
|
|
searingsunrazesmash: {
|
|
num: 724,
|
|
accuracy: true,
|
|
basePower: 200,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Searing Sunraze Smash",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {contact: 1},
|
|
isZ: "solganiumz",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
secretpower: {
|
|
num: 290,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Secret Power",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyMove(move, pokemon) {
|
|
if (this.field.isTerrain('')) return;
|
|
move.secondaries = [];
|
|
if (this.field.isTerrain('electricterrain')) {
|
|
move.secondaries.push({
|
|
chance: 30,
|
|
status: 'par',
|
|
});
|
|
} else if (this.field.isTerrain('grassyterrain')) {
|
|
move.secondaries.push({
|
|
chance: 30,
|
|
status: 'slp',
|
|
});
|
|
} else if (this.field.isTerrain('mistyterrain')) {
|
|
move.secondaries.push({
|
|
chance: 30,
|
|
boosts: {
|
|
spa: -1,
|
|
},
|
|
});
|
|
} else if (this.field.isTerrain('psychicterrain')) {
|
|
move.secondaries.push({
|
|
chance: 30,
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
});
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Clever",
|
|
},
|
|
secretsword: {
|
|
num: 548,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Special",
|
|
defensiveCategory: "Physical",
|
|
name: "Secret Sword",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Beautiful",
|
|
},
|
|
seedbomb: {
|
|
num: 402,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Seed Bomb",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough",
|
|
},
|
|
seedflare: {
|
|
num: 465,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Seed Flare",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 40,
|
|
boosts: {
|
|
spd: -2,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful",
|
|
},
|
|
seismictoss: {
|
|
num: 69,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damage: 'level',
|
|
category: "Physical",
|
|
name: "Seismic Toss",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
maxMove: {basePower: 75},
|
|
contestType: "Tough",
|
|
},
|
|
selfdestruct: {
|
|
num: 120,
|
|
accuracy: 100,
|
|
basePower: 200,
|
|
category: "Physical",
|
|
name: "Self-Destruct",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
selfdestruct: "always",
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
shadowball: {
|
|
num: 247,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Shadow Ball",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever",
|
|
},
|
|
shadowbone: {
|
|
num: 708,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Shadow Bone",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
shadowclaw: {
|
|
num: 421,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Shadow Claw",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
shadowforce: {
|
|
num: 467,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Shadow Force",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, charge: 1, mirror: 1},
|
|
breaksProtect: true,
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onInvulnerability: false,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
shadowpunch: {
|
|
num: 325,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Shadow Punch",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever",
|
|
},
|
|
shadowsneak: {
|
|
num: 425,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Shadow Sneak",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever",
|
|
},
|
|
shadowstrike: {
|
|
num: 0,
|
|
accuracy: 95,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "CAP",
|
|
name: "Shadow Strike",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever",
|
|
},
|
|
sharpen: {
|
|
num: 159,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Sharpen",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
atk: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
shatteredpsyche: {
|
|
num: 648,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Shattered Psyche",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "psychiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool",
|
|
},
|
|
sheercold: {
|
|
num: 329,
|
|
accuracy: 30,
|
|
basePower: 0,
|
|
category: "Special",
|
|
name: "Sheer Cold",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
ohko: 'Ice',
|
|
target: "normal",
|
|
type: "Ice",
|
|
zMove: {basePower: 180},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Beautiful",
|
|
},
|
|
shellsidearm: {
|
|
num: 801,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Shell Side Arm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyMove(move, pokemon, target) {
|
|
const atk = pokemon.getStat('atk', false, true);
|
|
const spa = pokemon.getStat('spa', false, true);
|
|
const def = target.getStat('def', false, true);
|
|
const spd = target.getStat('spd', false, true);
|
|
const physical = Math.floor(Math.floor(Math.floor(Math.floor(2 * pokemon.level / 5 + 2) * 90 * atk) / def) / 50);
|
|
const special = Math.floor(Math.floor(Math.floor(Math.floor(2 * pokemon.level / 5 + 2) * 90 * spa) / spd) / 50);
|
|
if (physical > special || (physical === special && this.random(2) === 0)) {
|
|
move.category = 'Physical';
|
|
move.flags.contact = 1;
|
|
}
|
|
},
|
|
onHit(target, source, move) {
|
|
this.hint(move.category + " Shell Side Arm");
|
|
},
|
|
onAfterSubDamage(damage, target, source, move) {
|
|
this.hint(move.category + " Shell Side Arm");
|
|
},
|
|
secondary: {
|
|
chance: 20,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
},
|
|
shellsmash: {
|
|
num: 504,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Shell Smash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: -1,
|
|
spd: -1,
|
|
atk: 2,
|
|
spa: 2,
|
|
spe: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Tough",
|
|
},
|
|
shelltrap: {
|
|
num: 704,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Shell Trap",
|
|
pp: 5,
|
|
priority: -3,
|
|
flags: {protect: 1},
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile('shelltrap');
|
|
},
|
|
onTryMove(pokemon) {
|
|
if (!pokemon.volatiles['shelltrap'] || !pokemon.volatiles['shelltrap'].gotHit) {
|
|
this.attrLastMove('[still]');
|
|
this.add('cant', pokemon, 'Shell Trap', 'Shell Trap');
|
|
return null;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add('-singleturn', pokemon, 'move: Shell Trap');
|
|
},
|
|
onHit(pokemon, source, move) {
|
|
if (pokemon.side !== source.side && move.category === 'Physical') {
|
|
pokemon.volatiles['shelltrap'].gotHit = true;
|
|
const action = this.queue.willMove(pokemon);
|
|
if (action) {
|
|
this.queue.prioritizeAction(action);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Tough",
|
|
},
|
|
shiftgear: {
|
|
num: 508,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Shift Gear",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
spe: 2,
|
|
atk: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Steel",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
shockwave: {
|
|
num: 351,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Shock Wave",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
shoreup: {
|
|
num: 659,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Shore Up",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onHit(pokemon) {
|
|
let factor = 0.5;
|
|
if (this.field.isWeather('sandstorm')) {
|
|
factor = 0.667;
|
|
}
|
|
return !!this.heal(this.modify(pokemon.maxhp, factor));
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ground",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
signalbeam: {
|
|
num: 324,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Signal Beam",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Beautiful",
|
|
},
|
|
silverwind: {
|
|
num: 318,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Silver Wind",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Beautiful",
|
|
},
|
|
simplebeam: {
|
|
num: 493,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Simple Beam",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
onTryHit(pokemon) {
|
|
const bannedAbilities = [
|
|
'battlebond', 'comatose', 'disguise', 'multitype', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'simple', 'stancechange', 'truant', 'zenmode',
|
|
];
|
|
if (bannedAbilities.includes(pokemon.ability)) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(pokemon) {
|
|
const oldAbility = pokemon.setAbility('simple');
|
|
if (oldAbility) {
|
|
this.add('-ability', pokemon, 'Simple', '[from] move: Simple Beam');
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
sing: {
|
|
num: 47,
|
|
accuracy: 55,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sing",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, authentic: 1},
|
|
status: 'slp',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
sinisterarrowraid: {
|
|
num: 695,
|
|
accuracy: true,
|
|
basePower: 180,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Sinister Arrow Raid",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "decidiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
sizzlyslide: {
|
|
num: 735,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Sizzly Slide",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, defrost: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Clever",
|
|
},
|
|
sketch: {
|
|
num: 166,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Sketch",
|
|
pp: 1,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {authentic: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
const disallowedMoves = ['chatter', 'sketch', 'struggle'];
|
|
const move = target.lastMove;
|
|
if (source.transformed || !move || source.moves.includes(move.id)) return false;
|
|
if (disallowedMoves.includes(move.id) || move.isZ || move.isMax) return false;
|
|
const sketchIndex = source.moves.indexOf('sketch');
|
|
if (sketchIndex < 0) return false;
|
|
const sketchedMove = {
|
|
move: move.name,
|
|
id: move.id,
|
|
pp: move.pp,
|
|
maxpp: move.pp,
|
|
target: move.target,
|
|
disabled: false,
|
|
used: false,
|
|
};
|
|
source.moveSlots[sketchIndex] = sketchedMove;
|
|
source.baseMoveSlots[sketchIndex] = sketchedMove;
|
|
this.add('-activate', source, 'move: Sketch', move.name);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1, def: 1, spa: 1, spd: 1, spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
skillswap: {
|
|
num: 285,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Skill Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, authentic: 1, mystery: 1},
|
|
onTryHit(target, source) {
|
|
const bannedAbilities = [
|
|
'battlebond', 'comatose', 'disguise', 'gulpmissile', 'hungerswitch', 'iceface', 'illusion', 'multitype', 'neutralizinggas', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'wonderguard', 'zenmode',
|
|
];
|
|
if (
|
|
target.volatiles['dynamax'] || bannedAbilities.includes(target.ability) || bannedAbilities.includes(source.ability)
|
|
) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(target, source, move) {
|
|
const targetAbility = target.getAbility();
|
|
const sourceAbility = source.getAbility();
|
|
if (target.side === source.side) {
|
|
this.add('-activate', source, 'move: Skill Swap', '', '', '[of] ' + target);
|
|
} else {
|
|
this.add('-activate', source, 'move: Skill Swap', targetAbility, sourceAbility, '[of] ' + target);
|
|
}
|
|
this.singleEvent('End', sourceAbility, source.abilityData, source);
|
|
this.singleEvent('End', targetAbility, target.abilityData, target);
|
|
if (targetAbility.id !== sourceAbility.id) {
|
|
source.ability = targetAbility.id;
|
|
target.ability = sourceAbility.id;
|
|
source.abilityData = {id: this.toID(source.ability), target: source};
|
|
target.abilityData = {id: this.toID(target.ability), target: target};
|
|
if (target.side !== source.side) target.volatileStaleness = 'external';
|
|
}
|
|
this.singleEvent('Start', targetAbility, source.abilityData, source);
|
|
this.singleEvent('Start', sourceAbility, target.abilityData, target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
skittersmack: {
|
|
num: 806,
|
|
accuracy: 90,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Skitter Smack",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
},
|
|
skullbash: {
|
|
num: 130,
|
|
accuracy: 100,
|
|
basePower: 130,
|
|
category: "Physical",
|
|
name: "Skull Bash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, charge: 1, protect: 1, mirror: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
this.boost({def: 1}, attacker, attacker, move);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
skyattack: {
|
|
num: 143,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Physical",
|
|
name: "Sky Attack",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {charge: 1, protect: 1, mirror: 1, distance: 1},
|
|
critRatio: 2,
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (!this.runEvent('ChargeMove', attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile('twoturnmove', defender);
|
|
return null;
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
skydrop: {
|
|
num: 507,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Sky Drop",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1},
|
|
onModifyMove(move, source) {
|
|
if (!source.volatiles['skydrop']) {
|
|
move.accuracy = true;
|
|
move.flags.contact = 0;
|
|
}
|
|
},
|
|
onMoveFail(target, source) {
|
|
if (source.volatiles['twoturnmove'] && source.volatiles['twoturnmove'].duration === 1) {
|
|
source.removeVolatile('skydrop');
|
|
source.removeVolatile('twoturnmove');
|
|
this.add('-end', target, 'Sky Drop', '[interrupt]');
|
|
}
|
|
},
|
|
onTryHit(target, source, move) {
|
|
if (target.fainted) return false;
|
|
if (source.removeVolatile(move.id)) {
|
|
if (target !== source.volatiles['twoturnmove'].source) return false;
|
|
|
|
if (target.hasType('Flying')) {
|
|
this.add('-immune', target);
|
|
return null;
|
|
}
|
|
} else {
|
|
if (target.volatiles['substitute'] || target.side === source.side) {
|
|
return false;
|
|
}
|
|
if (target.getWeight() >= 2000) {
|
|
this.add('-fail', target, 'move: Sky Drop', '[heavy]');
|
|
return null;
|
|
}
|
|
|
|
this.add('-prepare', source, move.name, target);
|
|
source.addVolatile('twoturnmove', target);
|
|
return null;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
if (target.hp) this.add('-end', target, 'Sky Drop');
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onAnyDragOut(pokemon) {
|
|
if (pokemon === this.effectData.target || pokemon === this.effectData.source) return false;
|
|
},
|
|
onFoeTrapPokemonPriority: -15,
|
|
onFoeTrapPokemon(defender) {
|
|
if (defender !== this.effectData.source) return;
|
|
defender.trapped = true;
|
|
},
|
|
onFoeBeforeMovePriority: 12,
|
|
onFoeBeforeMove(attacker, defender, move) {
|
|
if (attacker === this.effectData.source) {
|
|
attacker.activeMoveActions--;
|
|
this.debug('Sky drop nullifying.');
|
|
return null;
|
|
}
|
|
},
|
|
onRedirectTargetPriority: 99,
|
|
onRedirectTarget(target, source, source2) {
|
|
if (source !== this.effectData.target) return;
|
|
if (this.effectData.source.fainted) return;
|
|
return this.effectData.source;
|
|
},
|
|
onAnyInvulnerability(target, source, move) {
|
|
if (target !== this.effectData.target && target !== this.effectData.source) {
|
|
return;
|
|
}
|
|
if (source === this.effectData.target && target === this.effectData.source) {
|
|
return;
|
|
}
|
|
if (['gust', 'twister', 'skyuppercut', 'thunder', 'hurricane', 'smackdown', 'thousandarrows'].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onAnyBasePower(basePower, target, source, move) {
|
|
if (target !== this.effectData.target && target !== this.effectData.source) {
|
|
return;
|
|
}
|
|
if (source === this.effectData.target && target === this.effectData.source) {
|
|
return;
|
|
}
|
|
if (move.id === 'gust' || move.id === 'twister') {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
onFaint(target) {
|
|
if (target.volatiles['skydrop'] && target.volatiles['twoturnmove'].source) {
|
|
this.add('-end', target.volatiles['twoturnmove'].source, 'Sky Drop', '[interrupt]');
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Tough",
|
|
},
|
|
skyuppercut: {
|
|
num: 327,
|
|
accuracy: 90,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Sky Uppercut",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
slackoff: {
|
|
num: 303,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Slack Off",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
slam: {
|
|
num: 21,
|
|
accuracy: 75,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Slam",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
slash: {
|
|
num: 163,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Slash",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
sleeppowder: {
|
|
num: 79,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sleep Powder",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {powder: 1, protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'slp',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
sleeptalk: {
|
|
num: 214,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sleep Talk",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
sleepUsable: true,
|
|
onTryHit(pokemon) {
|
|
if (pokemon.status !== 'slp' && !pokemon.hasAbility('comatose')) return false;
|
|
},
|
|
onHit(pokemon) {
|
|
const noSleepTalk = [
|
|
'assist', 'beakblast', 'belch', 'bide', 'celebrate', 'chatter', 'copycat', 'dynamaxcannon', 'focuspunch', 'mefirst', 'metronome', 'mimic', 'mirrormove', 'naturepower', 'shelltrap', 'sketch', 'sleeptalk', 'uproar',
|
|
];
|
|
const moves = [];
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
const moveid = moveSlot.id;
|
|
if (!moveid) continue;
|
|
const move = this.dex.getMove(moveid);
|
|
if (noSleepTalk.includes(moveid) || move.flags['charge'] || (move.isZ && move.basePower !== 1)) {
|
|
continue;
|
|
}
|
|
moves.push(moveid);
|
|
}
|
|
let randomMove = '';
|
|
if (moves.length) randomMove = this.sample(moves);
|
|
if (!randomMove) {
|
|
return false;
|
|
}
|
|
this.useMove(randomMove, pokemon);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'crit2'},
|
|
contestType: "Cute",
|
|
},
|
|
sludge: {
|
|
num: 124,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Sludge",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough",
|
|
},
|
|
sludgebomb: {
|
|
num: 188,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Sludge Bomb",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough",
|
|
},
|
|
sludgewave: {
|
|
num: 482,
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Special",
|
|
name: "Sludge Wave",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'psn',
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Poison",
|
|
contestType: "Tough",
|
|
},
|
|
smackdown: {
|
|
num: 479,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Smack Down",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
volatileStatus: 'smackdown',
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
let applies = false;
|
|
if (pokemon.hasType('Flying') || pokemon.hasAbility('levitate')) applies = true;
|
|
if (pokemon.hasItem('ironball') || pokemon.volatiles['ingrain'] ||
|
|
this.field.getPseudoWeather('gravity')) applies = false;
|
|
if (pokemon.removeVolatile('fly') || pokemon.removeVolatile('bounce')) {
|
|
applies = true;
|
|
this.queue.cancelMove(pokemon);
|
|
pokemon.removeVolatile('twoturnmove');
|
|
}
|
|
if (pokemon.volatiles['magnetrise']) {
|
|
applies = true;
|
|
delete pokemon.volatiles['magnetrise'];
|
|
}
|
|
if (pokemon.volatiles['telekinesis']) {
|
|
applies = true;
|
|
delete pokemon.volatiles['telekinesis'];
|
|
}
|
|
if (!applies) return false;
|
|
this.add('-start', pokemon, 'Smack Down');
|
|
},
|
|
onRestart(pokemon) {
|
|
if (pokemon.removeVolatile('fly') || pokemon.removeVolatile('bounce')) {
|
|
this.queue.cancelMove(pokemon);
|
|
this.add('-start', pokemon, 'Smack Down');
|
|
}
|
|
},
|
|
// groundedness implemented in battle.engine.js:BattlePokemon#isGrounded
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough",
|
|
},
|
|
smartstrike: {
|
|
num: 684,
|
|
accuracy: true,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Smart Strike",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
smellingsalts: {
|
|
num: 265,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.status === 'par') return move.basePower * 2;
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Smelling Salts",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onHit(target) {
|
|
if (target.status === 'par') target.cureStatus();
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
smog: {
|
|
num: 123,
|
|
accuracy: 70,
|
|
basePower: 30,
|
|
category: "Special",
|
|
name: "Smog",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 40,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough",
|
|
},
|
|
smokescreen: {
|
|
num: 108,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Smokescreen",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
accuracy: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {evasion: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
snaptrap: {
|
|
num: 779,
|
|
accuracy: 100,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
name: "Snap Trap",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
volatileStatus: 'partiallytrapped',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
snarl: {
|
|
num: 555,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Special",
|
|
name: "Snarl",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1,
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Dark",
|
|
contestType: "Tough",
|
|
},
|
|
snatch: {
|
|
num: 289,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Snatch",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {authentic: 1},
|
|
volatileStatus: 'snatch',
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add('-singleturn', pokemon, 'Snatch');
|
|
},
|
|
onAnyTryMove(source, target, move) {
|
|
const snatchUser = this.effectData.source;
|
|
if (snatchUser.isSkyDropped()) return;
|
|
if (!move || move.isZ || move.isMax || !move.flags['snatch'] || move.sourceEffect === 'snatch') {
|
|
return;
|
|
}
|
|
snatchUser.removeVolatile('snatch');
|
|
this.add('-activate', snatchUser, 'move: Snatch', '[of] ' + source);
|
|
this.useMove(move.id, snatchUser);
|
|
return null;
|
|
},
|
|
},
|
|
secondary: null,
|
|
pressureTarget: "foeSide",
|
|
target: "self",
|
|
type: "Dark",
|
|
zMove: {boost: {spe: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
snipeshot: {
|
|
num: 745,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Snipe Shot",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
tracksTarget: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
},
|
|
snore: {
|
|
num: 173,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Snore",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
sleepUsable: true,
|
|
onTryHit(target, source) {
|
|
if (source.status !== 'slp' && !source.hasAbility('comatose')) return false;
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
soak: {
|
|
num: 487,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Soak",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
onHit(target) {
|
|
if (target.getTypes().join() === 'Water' || !target.setType('Water')) {
|
|
// Soak should animate even when it fails.
|
|
// Returning false would suppress the animation.
|
|
this.add('-fail', target);
|
|
return null;
|
|
}
|
|
this.add('-start', target, 'typechange', 'Water');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
softboiled: {
|
|
num: 135,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Soft-Boiled",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
solarbeam: {
|
|
num: 76,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Solar Beam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {charge: 1, protect: 1, mirror: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (['sunnyday', 'desolateland'].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;
|
|
},
|
|
onBasePower(basePower, pokemon, target) {
|
|
if (['raindance', 'primordialsea', 'sandstorm', 'hail'].includes(pokemon.effectiveWeather())) {
|
|
this.debug('weakened by weather');
|
|
return this.chainModify(0.5);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
solarblade: {
|
|
num: 669,
|
|
accuracy: 100,
|
|
basePower: 125,
|
|
category: "Physical",
|
|
name: "Solar Blade",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, charge: 1, protect: 1, mirror: 1},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add('-prepare', attacker, move.name);
|
|
if (['sunnyday', 'desolateland'].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;
|
|
},
|
|
onBasePower(basePower, pokemon, target) {
|
|
if (['raindance', 'primordialsea', 'sandstorm', 'hail'].includes(pokemon.effectiveWeather())) {
|
|
this.debug('weakened by weather');
|
|
return this.chainModify(0.5);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
sonicboom: {
|
|
num: 49,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
damage: 20,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Sonic Boom",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
soulstealing7starstrike: {
|
|
num: 699,
|
|
accuracy: true,
|
|
basePower: 195,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Soul-Stealing 7-Star Strike",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {contact: 1},
|
|
isZ: "marshadiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
spacialrend: {
|
|
num: 460,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Spacial Rend",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Beautiful",
|
|
},
|
|
spark: {
|
|
num: 209,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Spark",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
sparklingaria: {
|
|
num: 664,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Sparkling Aria",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
secondary: {
|
|
dustproof: true,
|
|
chance: 100,
|
|
onHit(target) {
|
|
if (target.status === 'brn') target.cureStatus();
|
|
},
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Water",
|
|
contestType: "Tough",
|
|
},
|
|
sparklyswirl: {
|
|
num: 740,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Sparkly Swirl",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
self: {
|
|
onHit(pokemon, source, move) {
|
|
this.add('-activate', source, 'move: Aromatherapy');
|
|
for (const ally of source.side.pokemon) {
|
|
if (ally !== source && (ally.volatiles['substitute'] && !move.infiltrates)) {
|
|
continue;
|
|
}
|
|
ally.cureStatus();
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Clever",
|
|
},
|
|
spectralthief: {
|
|
num: 712,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Spectral Thief",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, authentic: 1},
|
|
stealsBoosts: true,
|
|
// Boost stealing implemented in scripts.js
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool",
|
|
},
|
|
speedswap: {
|
|
num: 683,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Speed Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, authentic: 1, mystery: 1},
|
|
onHit(target, source) {
|
|
const targetSpe = target.storedStats.spe;
|
|
target.storedStats.spe = source.storedStats.spe;
|
|
source.storedStats.spe = targetSpe;
|
|
this.add('-activate', source, 'move: Speed Swap', '[of] ' + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
spiderweb: {
|
|
num: 169,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Spider Web",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
onHit(target, source, move) {
|
|
return target.addVolatile('trapped', source, move, 'trapper');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
spikecannon: {
|
|
num: 131,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Spike Cannon",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
maxMove: {basePower: 120},
|
|
contestType: "Cool",
|
|
},
|
|
spikes: {
|
|
num: 191,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spikes",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {reflectable: 1, nonsky: 1},
|
|
sideCondition: 'spikes',
|
|
condition: {
|
|
// this is a side condition
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'Spikes');
|
|
this.effectData.layers = 1;
|
|
},
|
|
onRestart(side) {
|
|
if (this.effectData.layers >= 3) return false;
|
|
this.add('-sidestart', side, 'Spikes');
|
|
this.effectData.layers++;
|
|
},
|
|
onSwitchIn(pokemon) {
|
|
if (!pokemon.isGrounded()) return;
|
|
if (pokemon.hasItem('heavydutyboots')) return;
|
|
const damageAmounts = [0, 3, 4, 6]; // 1/8, 1/6, 1/4
|
|
this.damage(damageAmounts[this.effectData.layers] * pokemon.maxhp / 24);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Ground",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
spikyshield: {
|
|
num: 596,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spiky Shield",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {},
|
|
stallingMove: true,
|
|
volatileStatus: 'spikyshield',
|
|
onTryHit(target, source, move) {
|
|
return !!this.queue.willAct() && this.runEvent('StallMove', target);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'move: Protect');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags['protect']) {
|
|
if (move.isZ || (move.isMax && !move.breaksProtect)) target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add('-activate', target, 'move: Protect');
|
|
}
|
|
const lockedmove = source.getVolatile('lockedmove');
|
|
if (lockedmove) {
|
|
// Outrage counter is reset
|
|
if (source.volatiles['lockedmove'].duration === 2) {
|
|
delete source.volatiles['lockedmove'];
|
|
}
|
|
}
|
|
if (move.flags['contact']) {
|
|
this.damage(source.baseMaxhp / 8, source, target);
|
|
}
|
|
return this.NOT_FAIL;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZOrMaxPowered && move.flags['contact']) {
|
|
this.damage(source.baseMaxhp / 8, source, target);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
spiritbreak: {
|
|
num: 789,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Spirit Break",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fairy",
|
|
},
|
|
spiritshackle: {
|
|
num: 662,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Spirit Shackle",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target, source, move) {
|
|
if (source.isActive) target.addVolatile('trapped', source, move, 'trapper');
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Tough",
|
|
},
|
|
spitup: {
|
|
num: 255,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
if (!pokemon.volatiles['stockpile'] || !pokemon.volatiles['stockpile'].layers) return false;
|
|
return pokemon.volatiles['stockpile'].layers * 100;
|
|
},
|
|
category: "Special",
|
|
name: "Spit Up",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
onTry(pokemon) {
|
|
if (!pokemon.volatiles['stockpile']) {
|
|
return false;
|
|
}
|
|
},
|
|
onAfterMove(pokemon) {
|
|
pokemon.removeVolatile('stockpile');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
spite: {
|
|
num: 180,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spite",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
onHit(target) {
|
|
const move = target.lastMove;
|
|
if (!move || move.isZ || move.isMax) return false;
|
|
|
|
const ppDeducted = target.deductPP(move.id, 4);
|
|
if (!ppDeducted) return false;
|
|
|
|
this.add("-activate", target, 'move: Spite', move.name, ppDeducted);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Tough",
|
|
},
|
|
splash: {
|
|
num: 150,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Splash",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {gravity: 1},
|
|
onTryHit(target, source) {
|
|
this.add('-nothing');
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 3}},
|
|
contestType: "Cute",
|
|
},
|
|
splinteredstormshards: {
|
|
num: 727,
|
|
accuracy: true,
|
|
basePower: 190,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Splintered Stormshards",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onHit() {
|
|
this.field.clearTerrain();
|
|
},
|
|
isZ: "lycaniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Cool",
|
|
},
|
|
splishysplash: {
|
|
num: 730,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Splishy Splash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
spore: {
|
|
num: 147,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spore",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {powder: 1, protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'slp',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
spotlight: {
|
|
num: 671,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spotlight",
|
|
pp: 15,
|
|
priority: 3,
|
|
flags: {protect: 1, reflectable: 1, mystery: 1},
|
|
volatileStatus: 'spotlight',
|
|
onTryHit(target) {
|
|
if (target.side.active.length < 2) return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add('-singleturn', pokemon, 'move: Spotlight');
|
|
},
|
|
onFoeRedirectTargetPriority: 2,
|
|
onFoeRedirectTarget(target, source, source2, move) {
|
|
if (this.validTarget(this.effectData.target, source, move.target)) {
|
|
this.debug("Spotlight redirected target of move");
|
|
return this.effectData.target;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
stealthrock: {
|
|
num: 446,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Stealth Rock",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {reflectable: 1},
|
|
sideCondition: 'stealthrock',
|
|
condition: {
|
|
// this is a side condition
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'move: Stealth Rock');
|
|
},
|
|
onSwitchIn(pokemon) {
|
|
if (pokemon.hasItem('heavydutyboots')) return;
|
|
const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6);
|
|
this.damage(pokemon.maxhp * Math.pow(2, typeMod) / 8);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Rock",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
steameruption: {
|
|
num: 592,
|
|
accuracy: 95,
|
|
basePower: 110,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Steam Eruption",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, defrost: 1},
|
|
thawsTarget: true,
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
steamroller: {
|
|
num: 537,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Steamroller",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Tough",
|
|
},
|
|
steelbeam: {
|
|
num: 796,
|
|
accuracy: 95,
|
|
basePower: 140,
|
|
category: "Special",
|
|
name: "Steel Beam",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
mindBlownRecoil: true,
|
|
onAfterMove(pokemon, target, move) {
|
|
if (move.mindBlownRecoil && !move.multihit) {
|
|
this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.getEffect('Steel Beam'), true);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
},
|
|
steelroller: {
|
|
num: 798,
|
|
accuracy: 100,
|
|
basePower: 130,
|
|
category: "Physical",
|
|
name: "Steel Roller",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTryHit() {
|
|
if (this.field.isTerrain('')) return false;
|
|
},
|
|
onHit() {
|
|
this.field.clearTerrain();
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
},
|
|
steelwing: {
|
|
num: 211,
|
|
accuracy: 90,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Steel Wing",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
def: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
stickyweb: {
|
|
num: 564,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sticky Web",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {reflectable: 1},
|
|
sideCondition: 'stickyweb',
|
|
condition: {
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'move: Sticky Web');
|
|
},
|
|
onSwitchIn(pokemon) {
|
|
if (!pokemon.isGrounded()) return;
|
|
if (pokemon.hasItem('heavydutyboots')) return;
|
|
this.add('-activate', pokemon, 'move: Sticky Web');
|
|
this.boost({spe: -1}, pokemon, this.effectData.source, this.dex.getActiveMove('stickyweb'));
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Bug",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
stockpile: {
|
|
num: 254,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Stockpile",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onTryHit(pokemon) {
|
|
if (pokemon.volatiles['stockpile'] && pokemon.volatiles['stockpile'].layers >= 3) return false;
|
|
},
|
|
volatileStatus: 'stockpile',
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(target) {
|
|
this.effectData.layers = 1;
|
|
this.effectData.def = 0;
|
|
this.effectData.spd = 0;
|
|
this.add('-start', target, 'stockpile' + this.effectData.layers);
|
|
const [curDef, curSpD] = [target.boosts.def, target.boosts.spd];
|
|
this.boost({def: 1, spd: 1}, target, target);
|
|
if (curDef !== target.boosts.def) this.effectData.def--;
|
|
if (curSpD !== target.boosts.spd) this.effectData.spd--;
|
|
},
|
|
onRestart(target) {
|
|
if (this.effectData.layers >= 3) return false;
|
|
this.effectData.layers++;
|
|
this.add('-start', target, 'stockpile' + this.effectData.layers);
|
|
const curDef = target.boosts.def;
|
|
const curSpD = target.boosts.spd;
|
|
this.boost({def: 1, spd: 1}, target, target);
|
|
if (curDef !== target.boosts.def) this.effectData.def--;
|
|
if (curSpD !== target.boosts.spd) this.effectData.spd--;
|
|
},
|
|
onEnd(target) {
|
|
if (this.effectData.def || this.effectData.spd) {
|
|
const boosts: SparseBoostsTable = {};
|
|
if (this.effectData.def) boosts.def = this.effectData.def;
|
|
if (this.effectData.spd) boosts.spd = this.effectData.spd;
|
|
this.boost(boosts, target, target);
|
|
}
|
|
this.add('-end', target, 'Stockpile');
|
|
if (this.effectData.def !== this.effectData.layers * -1 || this.effectData.spd !== this.effectData.layers * -1) {
|
|
this.hint("In Gen 7, Stockpile keeps track of how many times it successfully altered each stat individually.");
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Tough",
|
|
},
|
|
stokedsparksurfer: {
|
|
num: 700,
|
|
accuracy: true,
|
|
basePower: 175,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Stoked Sparksurfer",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "aloraichiumz",
|
|
secondary: {
|
|
chance: 100,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
stomp: {
|
|
num: 23,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Stomp",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
stompingtantrum: {
|
|
num: 707,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (pokemon.moveLastTurnResult === false) return move.basePower * 2;
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Stomping Tantrum",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough",
|
|
},
|
|
stoneedge: {
|
|
num: 444,
|
|
accuracy: 80,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Stone Edge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough",
|
|
},
|
|
storedpower: {
|
|
num: 500,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return move.basePower + 20 * pokemon.positiveBoosts();
|
|
},
|
|
category: "Special",
|
|
name: "Stored Power",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Clever",
|
|
},
|
|
stormthrow: {
|
|
num: 480,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Storm Throw",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
willCrit: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
strangesteam: {
|
|
num: 790,
|
|
accuracy: 95,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Strange Steam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "normal",
|
|
type: "Fairy",
|
|
},
|
|
strength: {
|
|
num: 70,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Strength",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
strengthsap: {
|
|
num: 668,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Strength Sap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, heal: 1},
|
|
onHit(target, source) {
|
|
if (target.boosts.atk === -6) return false;
|
|
const atk = target.getStat('atk', false, true);
|
|
const success = this.boost({atk: -1}, target, source, null, false, true);
|
|
return !!(this.heal(atk, source, target) || success);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
stringshot: {
|
|
num: 81,
|
|
accuracy: 95,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "String Shot",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
spe: -2,
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Bug",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
struggle: {
|
|
num: 165,
|
|
accuracy: true,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Struggle",
|
|
pp: 1,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1},
|
|
noSketch: true,
|
|
onModifyMove(move, pokemon, target) {
|
|
move.type = '???';
|
|
this.add('-activate', pokemon, 'move: Struggle');
|
|
},
|
|
struggleRecoil: true,
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
strugglebug: {
|
|
num: 522,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Struggle Bug",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1,
|
|
},
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Bug",
|
|
contestType: "Cute",
|
|
},
|
|
stuffcheeks: {
|
|
num: 747,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Stuff Cheeks",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
// Move disabling implemented in Battle#nextTurn in sim/battle.ts
|
|
onTry(source) {
|
|
const item = source.getItem();
|
|
if (item.isBerry && source.eatItem(true)) {
|
|
this.boost({def: 2}, source, null, null, false, true);
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
},
|
|
stunspore: {
|
|
num: 78,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Stun Spore",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {powder: 1, protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'par',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
submission: {
|
|
num: 66,
|
|
accuracy: 80,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Submission",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
recoil: [1, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
substitute: {
|
|
num: 164,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Substitute",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, nonsky: 1},
|
|
volatileStatus: 'substitute',
|
|
onTryHit(target) {
|
|
if (target.volatiles['substitute']) {
|
|
this.add('-fail', target, 'move: Substitute');
|
|
return null;
|
|
}
|
|
if (target.hp <= target.maxhp / 4 || target.maxhp === 1) { // Shedinja clause
|
|
this.add('-fail', target, 'move: Substitute', '[weak]');
|
|
return null;
|
|
}
|
|
},
|
|
onHit(target) {
|
|
this.directDamage(target.maxhp / 4);
|
|
},
|
|
condition: {
|
|
onStart(target) {
|
|
this.add('-start', target, 'Substitute');
|
|
this.effectData.hp = Math.floor(target.maxhp / 4);
|
|
if (target.volatiles['partiallytrapped']) {
|
|
this.add('-end', target, target.volatiles['partiallytrapped'].sourceEffect, '[partiallytrapped]', '[silent]');
|
|
delete target.volatiles['partiallytrapped'];
|
|
}
|
|
},
|
|
onTryPrimaryHitPriority: -1,
|
|
onTryPrimaryHit(target, source, move) {
|
|
if (target === source || move.flags['authentic'] || move.infiltrates) {
|
|
return;
|
|
}
|
|
let damage = this.getDamage(source, target, move);
|
|
if (!damage && damage !== 0) {
|
|
this.add('-fail', source);
|
|
this.attrLastMove('[still]');
|
|
return null;
|
|
}
|
|
damage = this.runEvent('SubDamage', target, source, move, damage);
|
|
if (!damage) {
|
|
return damage;
|
|
}
|
|
if (damage > target.volatiles['substitute'].hp) {
|
|
damage = target.volatiles['substitute'].hp as number;
|
|
}
|
|
target.volatiles['substitute'].hp -= damage;
|
|
source.lastDamage = damage;
|
|
if (target.volatiles['substitute'].hp <= 0) {
|
|
target.removeVolatile('substitute');
|
|
} else {
|
|
this.add('-activate', target, 'move: Substitute', '[damage]');
|
|
}
|
|
if (move.recoil) {
|
|
this.damage(this.calcRecoilDamage(damage, move), source, target, 'recoil');
|
|
}
|
|
if (move.drain) {
|
|
this.heal(Math.ceil(damage * move.drain[0] / move.drain[1]), source, target, 'drain');
|
|
}
|
|
this.singleEvent('AfterSubDamage', move, null, target, source, move, damage);
|
|
this.runEvent('AfterSubDamage', target, source, move, damage);
|
|
return this.HIT_SUBSTITUTE;
|
|
},
|
|
onEnd(target) {
|
|
this.add('-end', target, 'Substitute');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
subzeroslammer: {
|
|
num: 650,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Subzero Slammer",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "iciumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Cool",
|
|
},
|
|
suckerpunch: {
|
|
num: 389,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Sucker Punch",
|
|
pp: 5,
|
|
priority: 1,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTry(source, target) {
|
|
const action = this.queue.willMove(target);
|
|
const move = action?.choice === 'move' ? action.move : null;
|
|
if (!move || (move.category === 'Status' && move.id !== 'mefirst') || target.volatiles['mustrecharge']) {
|
|
this.add('-fail', source);
|
|
this.attrLastMove('[still]');
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
sunnyday: {
|
|
num: 241,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sunny Day",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
weather: 'sunnyday',
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fire",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
sunsteelstrike: {
|
|
num: 713,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Sunsteel Strike",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool",
|
|
},
|
|
superfang: {
|
|
num: 162,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
return this.clampIntRange(target.getUndynamaxedHP() / 2, 1);
|
|
},
|
|
category: "Physical",
|
|
name: "Super Fang",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
superpower: {
|
|
num: 276,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Superpower",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
boosts: {
|
|
atk: -1,
|
|
def: -1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
supersonic: {
|
|
num: 48,
|
|
accuracy: 55,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Supersonic",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, authentic: 1},
|
|
volatileStatus: 'confusion',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
supersonicskystrike: {
|
|
num: 626,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Supersonic Skystrike",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "flyiniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
surf: {
|
|
num: 57,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Surf",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
surgingstrikes: {
|
|
num: 818,
|
|
accuracy: 100,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Surging Strikes",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1},
|
|
willCrit: true,
|
|
multihit: 3,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 130},
|
|
},
|
|
swagger: {
|
|
num: 207,
|
|
accuracy: 85,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Swagger",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
volatileStatus: 'confusion',
|
|
boosts: {
|
|
atk: 2,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Cute",
|
|
},
|
|
swallow: {
|
|
num: 256,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Swallow",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onTryHit(pokemon) {
|
|
if (!pokemon.volatiles['stockpile'] || !pokemon.volatiles['stockpile'].layers) return false;
|
|
},
|
|
onHit(pokemon) {
|
|
const healAmount = [0.25, 0.5, 1];
|
|
const healedBy = this.heal(this.modify(pokemon.maxhp, healAmount[(pokemon.volatiles['stockpile'].layers - 1)]));
|
|
pokemon.removeVolatile('stockpile');
|
|
return !!healedBy;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Tough",
|
|
},
|
|
sweetkiss: {
|
|
num: 186,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sweet Kiss",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
volatileStatus: 'confusion',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
sweetscent: {
|
|
num: 230,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sweet Scent",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
evasion: -2,
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: {boost: {accuracy: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
swift: {
|
|
num: 129,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Swift",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
switcheroo: {
|
|
num: 415,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Switcheroo",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, mystery: 1},
|
|
onTryImmunity(target) {
|
|
return !target.hasAbility('stickyhold');
|
|
},
|
|
onHit(target, source, move) {
|
|
const yourItem = target.takeItem(source);
|
|
const myItem = source.takeItem();
|
|
if (target.item || source.item || (!yourItem && !myItem)) {
|
|
if (yourItem) target.item = yourItem.id;
|
|
if (myItem) source.item = myItem.id;
|
|
return false;
|
|
}
|
|
if (
|
|
(myItem && !this.singleEvent('TakeItem', myItem, source.itemData, target, source, move, myItem)) ||
|
|
(yourItem && !this.singleEvent('TakeItem', yourItem, target.itemData, source, target, move, yourItem))
|
|
) {
|
|
if (yourItem) target.item = yourItem.id;
|
|
if (myItem) source.item = myItem.id;
|
|
return false;
|
|
}
|
|
this.add('-activate', source, 'move: Trick', '[of] ' + target);
|
|
if (myItem) {
|
|
target.setItem(myItem);
|
|
this.add('-item', target, myItem, '[from] move: Switcheroo');
|
|
} else {
|
|
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Switcheroo');
|
|
}
|
|
if (yourItem) {
|
|
source.setItem(yourItem);
|
|
this.add('-item', source, yourItem, '[from] move: Switcheroo');
|
|
} else {
|
|
this.add('-enditem', source, myItem, '[silent]', '[from] move: Switcheroo');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {boost: {spe: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
swordsdance: {
|
|
num: 14,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Swords Dance",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1, dance: 1},
|
|
boosts: {
|
|
atk: 2,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
synchronoise: {
|
|
num: 485,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Synchronoise",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryImmunity(target, source) {
|
|
return target.hasType(source.getTypes());
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
synthesis: {
|
|
num: 235,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Synthesis",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onHit(pokemon) {
|
|
let factor = 0.5;
|
|
switch (pokemon.effectiveWeather()) {
|
|
case 'sunnyday':
|
|
case 'desolateland':
|
|
factor = 0.667;
|
|
break;
|
|
case 'raindance':
|
|
case 'primordialsea':
|
|
case 'sandstorm':
|
|
case 'hail':
|
|
factor = 0.25;
|
|
break;
|
|
}
|
|
return !!this.heal(this.modify(pokemon.maxhp, factor));
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Clever",
|
|
},
|
|
tackle: {
|
|
num: 33,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Tackle",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
tailglow: {
|
|
num: 294,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Tail Glow",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
spa: 3,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: {effect: 'clearnegativeboost'},
|
|
contestType: "Beautiful",
|
|
},
|
|
tailslap: {
|
|
num: 541,
|
|
accuracy: 85,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Tail Slap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 140},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cute",
|
|
},
|
|
tailwhip: {
|
|
num: 39,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tail Whip",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
tailwind: {
|
|
num: 366,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tailwind",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
sideCondition: 'tailwind',
|
|
condition: {
|
|
duration: 4,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasAbility('persistent')) {
|
|
this.add('-activate', source, 'ability: Persistent', effect);
|
|
return 6;
|
|
}
|
|
return 4;
|
|
},
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'move: Tailwind');
|
|
},
|
|
onModifySpe(spe, pokemon) {
|
|
return this.chainModify(2);
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 4,
|
|
onEnd(side) {
|
|
this.add('-sideend', side, 'move: Tailwind');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Flying",
|
|
zMove: {effect: 'crit2'},
|
|
contestType: "Cool",
|
|
},
|
|
takedown: {
|
|
num: 36,
|
|
accuracy: 85,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Take Down",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
recoil: [1, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
tarshot: {
|
|
num: 749,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tar Shot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
volatileStatus: 'tarshot',
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'Tar Shot');
|
|
},
|
|
onEffectivenessPriority: -2,
|
|
onEffectiveness(typeMod, target, type, move) {
|
|
if (move.type !== 'Fire') return;
|
|
if (!target) return;
|
|
if (type !== target.getTypes()[0]) return;
|
|
return typeMod + 1;
|
|
},
|
|
},
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
},
|
|
taunt: {
|
|
num: 269,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Taunt",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
volatileStatus: 'taunt',
|
|
condition: {
|
|
duration: 3,
|
|
onStart(target) {
|
|
if (target.activeTurns && !this.queue.willMove(target)) {
|
|
this.effectData.duration++;
|
|
}
|
|
this.add('-start', target, 'move: Taunt');
|
|
},
|
|
onResidualOrder: 12,
|
|
onEnd(target) {
|
|
this.add('-end', target, 'move: Taunt');
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
const move = this.dex.getMove(moveSlot.id);
|
|
if (move.category === 'Status' && move.id !== 'mefirst') {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
onBeforeMovePriority: 5,
|
|
onBeforeMove(attacker, defender, move) {
|
|
if (!move.isZ && !move.isMax && move.category === 'Status' && move.id !== 'mefirst') {
|
|
this.add('cant', attacker, 'move: Taunt', move);
|
|
return false;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
tearfullook: {
|
|
num: 715,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tearful Look",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {reflectable: 1, mirror: 1},
|
|
boosts: {
|
|
atk: -1,
|
|
spa: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
teatime: {
|
|
num: 752,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Teatime",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {authentic: 1},
|
|
onHitField(target, source, move) {
|
|
let result = false;
|
|
for (const active of this.getAllActive()) {
|
|
if (this.runEvent('Invulnerability', active, source, move) === false) {
|
|
this.add('-miss', source, active);
|
|
result = true;
|
|
} else {
|
|
const item = active.getItem();
|
|
if (active.hp && item.isBerry) {
|
|
// bypasses Unnerve
|
|
active.eatItem(true);
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Normal",
|
|
},
|
|
technoblast: {
|
|
num: 546,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Techno Blast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.ignoringItem()) return;
|
|
move.type = this.runEvent('Drive', pokemon, null, move, 'Normal');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool",
|
|
},
|
|
tectonicrage: {
|
|
num: 630,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Tectonic Rage",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "groundiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Cool",
|
|
},
|
|
teeterdance: {
|
|
num: 298,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Teeter Dance",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, dance: 1},
|
|
volatileStatus: 'confusion',
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Normal",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
telekinesis: {
|
|
num: 477,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Telekinesis",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, gravity: 1, mystery: 1},
|
|
volatileStatus: 'telekinesis',
|
|
condition: {
|
|
duration: 3,
|
|
onStart(target) {
|
|
if (['Diglett', 'Dugtrio', 'Palossand', 'Sandygast'].includes(target.baseSpecies.baseSpecies) ||
|
|
target.baseSpecies.name === 'Gengar-Mega') {
|
|
this.add('-immune', target);
|
|
return null;
|
|
}
|
|
if (target.volatiles['smackdown'] || target.volatiles['ingrain']) return false;
|
|
this.add('-start', target, 'Telekinesis');
|
|
},
|
|
onAccuracyPriority: -1,
|
|
onAccuracy(accuracy, target, source, move) {
|
|
if (move && !move.ohko) return true;
|
|
},
|
|
onImmunity(type) {
|
|
if (type === 'Ground') return false;
|
|
},
|
|
onUpdate(pokemon) {
|
|
if (pokemon.baseSpecies.name === 'Gengar-Mega') {
|
|
delete pokemon.volatiles['telekinesis'];
|
|
this.add('-end', pokemon, 'Telekinesis', '[silent]');
|
|
}
|
|
},
|
|
onResidualOrder: 16,
|
|
onEnd(target) {
|
|
this.add('-end', target, 'Telekinesis');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spa: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
teleport: {
|
|
num: 100,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Teleport",
|
|
pp: 20,
|
|
priority: -6,
|
|
flags: {},
|
|
selfSwitch: true,
|
|
onTryHit: true,
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Cool",
|
|
},
|
|
terrainpulse: {
|
|
num: 805,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Terrain Pulse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, pulse: 1},
|
|
onModifyType(move, pokemon) {
|
|
if (!pokemon.isGrounded()) return;
|
|
switch (this.field.terrain) {
|
|
case 'electricterrain':
|
|
move.type = 'Electric';
|
|
break;
|
|
case 'grassyterrain':
|
|
move.type = 'Grass';
|
|
break;
|
|
case 'mistyterrain':
|
|
move.type = 'Fairy';
|
|
break;
|
|
case 'psychicterrain':
|
|
move.type = 'Psychic';
|
|
break;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
if (this.field.terrain && pokemon.isGrounded()) {
|
|
move.basePower *= 2;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
},
|
|
thief: {
|
|
num: 168,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Thief",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onAfterHit(target, source, move) {
|
|
if (source.item || source.volatiles['gem']) {
|
|
return;
|
|
}
|
|
const yourItem = target.takeItem(source);
|
|
if (!yourItem) {
|
|
return;
|
|
}
|
|
if (!this.singleEvent('TakeItem', yourItem, target.itemData, source, target, move, yourItem) ||
|
|
!source.setItem(yourItem)) {
|
|
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
|
|
return;
|
|
}
|
|
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Thief', '[of] ' + source);
|
|
this.add('-item', source, yourItem, '[from] move: Thief', '[of] ' + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough",
|
|
},
|
|
thousandarrows: {
|
|
num: 614,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Thousand Arrows",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
onEffectiveness(typeMod, target, type, move) {
|
|
if (move.type !== 'Ground') return;
|
|
if (!target) return; // avoid crashing when called from a chat plugin
|
|
// ignore effectiveness if the target is Flying type and immune to Ground
|
|
if (!target.runImmunity('Ground')) {
|
|
if (target.hasType('Flying')) return 0;
|
|
}
|
|
},
|
|
volatileStatus: 'smackdown',
|
|
ignoreImmunity: {'Ground': true},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Ground",
|
|
zMove: {basePower: 180},
|
|
contestType: "Beautiful",
|
|
},
|
|
thousandwaves: {
|
|
num: 615,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Thousand Waves",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
onHit(target, source, move) {
|
|
if (source.isActive) target.addVolatile('trapped', source, move, 'trapper');
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Ground",
|
|
contestType: "Tough",
|
|
},
|
|
thrash: {
|
|
num: 37,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Thrash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
volatileStatus: 'lockedmove',
|
|
},
|
|
onAfterMove(pokemon) {
|
|
if (pokemon.volatiles['lockedmove'] && pokemon.volatiles['lockedmove'].duration === 1) {
|
|
pokemon.removeVolatile('lockedmove');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
throatchop: {
|
|
num: 675,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Throat Chop",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
condition: {
|
|
duration: 2,
|
|
onStart(target) {
|
|
this.add('-start', target, 'Throat Chop', '[silent]');
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (this.dex.getMove(moveSlot.id).flags['sound']) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
onBeforeMovePriority: 6,
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (!move.isZ && !move.isMax && move.flags['sound']) {
|
|
this.add('cant', pokemon, 'move: Throat Chop');
|
|
return false;
|
|
}
|
|
},
|
|
onResidualOrder: 22,
|
|
onEnd(target) {
|
|
this.add('-end', target, 'Throat Chop', '[silent]');
|
|
},
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target) {
|
|
target.addVolatile('throatchop');
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever",
|
|
},
|
|
thunder: {
|
|
num: 87,
|
|
accuracy: 70,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Thunder",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onModifyMove(move, pokemon, target) {
|
|
switch (target.effectiveWeather()) {
|
|
case 'raindance':
|
|
case 'primordialsea':
|
|
move.accuracy = true;
|
|
break;
|
|
case 'sunnyday':
|
|
case 'desolateland':
|
|
move.accuracy = 50;
|
|
break;
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
thunderbolt: {
|
|
num: 85,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Thunderbolt",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
thunderfang: {
|
|
num: 422,
|
|
accuracy: 95,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Thunder Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {bite: 1, contact: 1, protect: 1, mirror: 1},
|
|
secondaries: [
|
|
{
|
|
chance: 10,
|
|
status: 'par',
|
|
}, {
|
|
chance: 10,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
],
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
thunderpunch: {
|
|
num: 9,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Thunder Punch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
thundershock: {
|
|
num: 84,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Thunder Shock",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
thunderwave: {
|
|
num: 86,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Thunder Wave",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'par',
|
|
ignoreImmunity: false,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Cool",
|
|
},
|
|
tickle: {
|
|
num: 321,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tickle",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
boosts: {
|
|
atk: -1,
|
|
def: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
topsyturvy: {
|
|
num: 576,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Topsy-Turvy",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
onHit(target) {
|
|
let success = false;
|
|
let i: BoostName;
|
|
for (i in target.boosts) {
|
|
if (target.boosts[i] === 0) continue;
|
|
target.boosts[i] = -target.boosts[i];
|
|
success = true;
|
|
}
|
|
if (!success) return false;
|
|
this.add('-invertboost', target, '[from] move: Topsy-Turvy');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
torment: {
|
|
num: 259,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Torment",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
volatileStatus: 'torment',
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
if (pokemon.volatiles['dynamax']) {
|
|
delete pokemon.volatiles['torment'];
|
|
return false;
|
|
}
|
|
this.add('-start', pokemon, 'Torment');
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add('-end', pokemon, 'Torment');
|
|
},
|
|
onDisableMove(pokemon) {
|
|
if (pokemon.lastMove && pokemon.lastMove.id !== 'struggle') pokemon.disableMove(pokemon.lastMove.id);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
toxic: {
|
|
num: 92,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Toxic",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
// No Guard-like effect for Poison-type users implemented in Scripts#tryMoveHit
|
|
status: 'tox',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
toxicspikes: {
|
|
num: 390,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Toxic Spikes",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {reflectable: 1, nonsky: 1},
|
|
sideCondition: 'toxicspikes',
|
|
condition: {
|
|
// this is a side condition
|
|
onStart(side) {
|
|
this.add('-sidestart', side, 'move: Toxic Spikes');
|
|
this.effectData.layers = 1;
|
|
},
|
|
onRestart(side) {
|
|
if (this.effectData.layers >= 2) return false;
|
|
this.add('-sidestart', side, 'move: Toxic Spikes');
|
|
this.effectData.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')) {
|
|
return;
|
|
} else if (this.effectData.layers >= 2) {
|
|
pokemon.trySetStatus('tox', pokemon.side.foe.active[0]);
|
|
} else {
|
|
pokemon.trySetStatus('psn', pokemon.side.foe.active[0]);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Poison",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
toxicthread: {
|
|
num: 672,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Toxic Thread",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'psn',
|
|
boosts: {
|
|
spe: -1,
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
transform: {
|
|
num: 144,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Transform",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {mystery: 1},
|
|
onHit(target, pokemon) {
|
|
if (!pokemon.transformInto(target)) {
|
|
return false;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {effect: 'heal'},
|
|
contestType: "Clever",
|
|
},
|
|
triattack: {
|
|
num: 161,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Tri Attack",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
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);
|
|
}
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful",
|
|
},
|
|
trick: {
|
|
num: 271,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Trick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, mystery: 1},
|
|
onTryImmunity(target) {
|
|
return !target.hasAbility('stickyhold');
|
|
},
|
|
onHit(target, source, move) {
|
|
const yourItem = target.takeItem(source);
|
|
const myItem = source.takeItem();
|
|
if (target.item || source.item || (!yourItem && !myItem)) {
|
|
if (yourItem) target.item = yourItem.id;
|
|
if (myItem) source.item = myItem.id;
|
|
return false;
|
|
}
|
|
if (
|
|
(myItem && !this.singleEvent('TakeItem', myItem, source.itemData, target, source, move, myItem)) ||
|
|
(yourItem && !this.singleEvent('TakeItem', yourItem, target.itemData, source, target, move, yourItem))
|
|
) {
|
|
if (yourItem) target.item = yourItem.id;
|
|
if (myItem) source.item = myItem.id;
|
|
return false;
|
|
}
|
|
this.add('-activate', source, 'move: Trick', '[of] ' + target);
|
|
if (myItem) {
|
|
target.setItem(myItem);
|
|
this.add('-item', target, myItem, '[from] move: Trick');
|
|
} else {
|
|
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Trick');
|
|
}
|
|
if (yourItem) {
|
|
source.setItem(yourItem);
|
|
this.add('-item', source, yourItem, '[from] move: Trick');
|
|
} else {
|
|
this.add('-enditem', source, myItem, '[silent]', '[from] move: Trick');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: {boost: {spe: 2}},
|
|
contestType: "Clever",
|
|
},
|
|
trickortreat: {
|
|
num: 567,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Trick-or-Treat",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
onHit(target) {
|
|
if (target.hasType('Ghost')) return false;
|
|
if (!target.addType('Ghost')) return false;
|
|
this.add('-start', target, 'typeadd', 'Ghost', '[from] move: Trick-or-Treat');
|
|
|
|
if (target.side.active.length === 2 && target.position === 1) {
|
|
// Curse Glitch
|
|
const action = this.queue.willMove(target);
|
|
if (action && action.move.id === 'curse') {
|
|
action.targetLoc = -1;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: {boost: {atk: 1, def: 1, spa: 1, spd: 1, spe: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
trickroom: {
|
|
num: 433,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Trick Room",
|
|
pp: 5,
|
|
priority: -7,
|
|
flags: {mirror: 1},
|
|
pseudoWeather: 'trickroom',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasAbility('persistent')) {
|
|
this.add('-activate', source, 'ability: Persistent', effect);
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onStart(target, source) {
|
|
this.add('-fieldstart', 'move: Trick Room', '[of] ' + source);
|
|
},
|
|
onRestart(target, source) {
|
|
this.field.removePseudoWeather('trickroom');
|
|
},
|
|
// Speed modification is changed in Pokemon.getActionSpeed() in sim/pokemon.js
|
|
onResidualOrder: 23,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Trick Room');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: {boost: {accuracy: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
tripleaxel: {
|
|
num: 813,
|
|
accuracy: 90,
|
|
basePower: 20,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return 20 * move.hit;
|
|
},
|
|
category: "Physical",
|
|
name: "Triple Axel",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: 3,
|
|
multiaccuracy: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
zMove: {basePower: 120},
|
|
maxMove: {basePower: 140},
|
|
},
|
|
triplekick: {
|
|
num: 167,
|
|
accuracy: 90,
|
|
basePower: 10,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return 10 * move.hit;
|
|
},
|
|
category: "Physical",
|
|
name: "Triple Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
multihit: 3,
|
|
multiaccuracy: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
zMove: {basePower: 120},
|
|
maxMove: {basePower: 80},
|
|
contestType: "Cool",
|
|
},
|
|
tropkick: {
|
|
num: 688,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Trop Kick",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
atk: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cute",
|
|
},
|
|
trumpcard: {
|
|
num: 376,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
basePowerCallback(source, target, move) {
|
|
const callerMoveId = move.sourceEffect || move.id;
|
|
const moveSlot = callerMoveId === 'instruct' ? source.getMoveData(move.id) : source.getMoveData(callerMoveId);
|
|
if (!moveSlot) return 40;
|
|
switch (moveSlot.pp) {
|
|
case 0:
|
|
return 200;
|
|
case 1:
|
|
return 80;
|
|
case 2:
|
|
return 60;
|
|
case 3:
|
|
return 50;
|
|
default:
|
|
return 40;
|
|
}
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Trump Card",
|
|
pp: 5,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Cool",
|
|
},
|
|
twineedle: {
|
|
num: 41,
|
|
accuracy: 100,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Twineedle",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
multihit: 2,
|
|
secondary: {
|
|
chance: 20,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
maxMove: {basePower: 100},
|
|
contestType: "Cool",
|
|
},
|
|
twinkletackle: {
|
|
num: 656,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Twinkle Tackle",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "fairiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Cool",
|
|
},
|
|
twister: {
|
|
num: 239,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Twister",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon",
|
|
contestType: "Cool",
|
|
},
|
|
uturn: {
|
|
num: 369,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "U-turn",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute",
|
|
},
|
|
uproar: {
|
|
num: 253,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Uproar",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
self: {
|
|
volatileStatus: 'uproar',
|
|
},
|
|
onTryHit(target) {
|
|
for (const [i, allyActive] of target.side.active.entries()) {
|
|
if (allyActive && allyActive.status === 'slp') allyActive.cureStatus();
|
|
const foeActive = target.side.foe.active[i];
|
|
if (foeActive && foeActive.status === 'slp') foeActive.cureStatus();
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 3,
|
|
onStart(target) {
|
|
this.add('-start', target, 'Uproar');
|
|
},
|
|
onResidual(target) {
|
|
if (target.lastMove && target.lastMove.id === 'struggle') {
|
|
// don't lock
|
|
delete target.volatiles['uproar'];
|
|
}
|
|
this.add('-start', target, 'Uproar', '[upkeep]');
|
|
},
|
|
onEnd(target) {
|
|
this.add('-end', target, 'Uproar');
|
|
},
|
|
onLockMove: 'uproar',
|
|
onAnySetStatus(status, pokemon) {
|
|
if (status.id === 'slp') {
|
|
if (pokemon === this.effectData.target) {
|
|
this.add('-fail', pokemon, 'slp', '[from] Uproar', '[msg]');
|
|
} else {
|
|
this.add('-fail', pokemon, 'slp', '[from] Uproar');
|
|
}
|
|
return null;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
vacuumwave: {
|
|
num: 410,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Vacuum Wave",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
vcreate: {
|
|
num: 557,
|
|
accuracy: 95,
|
|
basePower: 180,
|
|
category: "Physical",
|
|
name: "V-create",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
self: {
|
|
boosts: {
|
|
spe: -1,
|
|
def: -1,
|
|
spd: -1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
zMove: {basePower: 220},
|
|
contestType: "Cool",
|
|
},
|
|
veeveevolley: {
|
|
num: 741,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
return Math.floor((pokemon.happiness * 10) / 25) || 1;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Veevee Volley",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute",
|
|
},
|
|
venomdrench: {
|
|
num: 599,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Venom Drench",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
onHit(target, source, move) {
|
|
if (target.status === 'psn' || target.status === 'tox') {
|
|
return !!this.boost({atk: -1, spa: -1, spe: -1}, target, source, move);
|
|
}
|
|
return false;
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Poison",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
venoshock: {
|
|
num: 474,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Venoshock",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onBasePower(basePower, pokemon, target) {
|
|
if (target.status === 'psn' || target.status === 'tox') {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Beautiful",
|
|
},
|
|
vinewhip: {
|
|
num: 22,
|
|
accuracy: 100,
|
|
basePower: 45,
|
|
category: "Physical",
|
|
name: "Vine Whip",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool",
|
|
},
|
|
visegrip: {
|
|
num: 11,
|
|
accuracy: 100,
|
|
basePower: 55,
|
|
category: "Physical",
|
|
name: "Vise Grip",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
vitalthrow: {
|
|
num: 233,
|
|
accuracy: true,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Vital Throw",
|
|
pp: 10,
|
|
priority: -1,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool",
|
|
},
|
|
voltswitch: {
|
|
num: 521,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
name: "Volt Switch",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
volttackle: {
|
|
num: 344,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Volt Tackle",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
recoil: [33, 100],
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
wakeupslap: {
|
|
num: 358,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.status === 'slp' || target.hasAbility('comatose')) return move.basePower * 2;
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Wake-Up Slap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onHit(target) {
|
|
if (target.status === 'slp') target.cureStatus();
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough",
|
|
},
|
|
waterfall: {
|
|
num: 127,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Waterfall",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough",
|
|
},
|
|
watergun: {
|
|
num: 55,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Water Gun",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cute",
|
|
},
|
|
waterpledge: {
|
|
num: 518,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
basePowerCallback(target, source, move) {
|
|
if (['firepledge', 'grasspledge'].includes(move.sourceEffect)) {
|
|
this.add('-combine');
|
|
return 150;
|
|
}
|
|
return 80;
|
|
},
|
|
category: "Special",
|
|
name: "Water Pledge",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, nonsky: 1},
|
|
onPrepareHit(target, source, move) {
|
|
for (const action of this.queue) {
|
|
if (action.choice !== 'move') continue;
|
|
const otherMove = action.move;
|
|
const otherMoveUser = action.pokemon;
|
|
if (
|
|
!otherMove || !action.pokemon || !otherMoveUser.isActive ||
|
|
otherMoveUser.fainted || action.maxMove || action.zmove
|
|
) {
|
|
continue;
|
|
}
|
|
if (otherMoveUser.side === source.side && ['firepledge', 'grasspledge'].includes(otherMove.id)) {
|
|
this.queue.prioritizeAction(action, move);
|
|
this.add('-waiting', source, otherMoveUser);
|
|
return null;
|
|
}
|
|
}
|
|
},
|
|
onModifyMove(move) {
|
|
if (move.sourceEffect === 'grasspledge') {
|
|
move.type = 'Grass';
|
|
move.forceSTAB = true;
|
|
move.sideCondition = 'grasspledge';
|
|
}
|
|
if (move.sourceEffect === 'firepledge') {
|
|
move.type = 'Water';
|
|
move.forceSTAB = true;
|
|
move.self = {sideCondition: 'waterpledge'};
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onStart(targetSide) {
|
|
this.add('-sidestart', targetSide, 'Water Pledge');
|
|
},
|
|
onEnd(targetSide) {
|
|
this.add('-sideend', targetSide, 'Water Pledge');
|
|
},
|
|
onModifyMove(move) {
|
|
if (move.secondaries && move.id !== 'secretpower') {
|
|
this.debug('doubling secondary chance');
|
|
for (const secondary of move.secondaries) {
|
|
if (secondary.chance) secondary.chance *= 2;
|
|
}
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
waterpulse: {
|
|
num: 352,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Water Pulse",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {protect: 1, pulse: 1, mirror: 1, distance: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
target: "any",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
watershuriken: {
|
|
num: 594,
|
|
accuracy: 100,
|
|
basePower: 15,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (pokemon.species.name === 'Greninja-Ash' && pokemon.hasAbility('battlebond')) {
|
|
return move.basePower + 5;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Special",
|
|
name: "Water Shuriken",
|
|
pp: 20,
|
|
priority: 1,
|
|
flags: {protect: 1, mirror: 1},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool",
|
|
},
|
|
watersport: {
|
|
num: 346,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Water Sport",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {nonsky: 1},
|
|
pseudoWeather: 'watersport',
|
|
condition: {
|
|
duration: 5,
|
|
onStart(side, source) {
|
|
this.add('-fieldstart', 'move: Water Sport', '[of] ' + source);
|
|
},
|
|
onBasePowerPriority: 1,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === 'Fire') {
|
|
this.debug('water sport weaken');
|
|
return this.chainModify([0x548, 0x1000]);
|
|
}
|
|
},
|
|
onResidualOrder: 21,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Water Sport');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Water",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
waterspout: {
|
|
num: 323,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return move.basePower * pokemon.hp / pokemon.maxhp;
|
|
},
|
|
category: "Special",
|
|
name: "Water Spout",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
weatherball: {
|
|
num: 311,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Weather Ball",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
onModifyType(move, pokemon) {
|
|
switch (pokemon.effectiveWeather()) {
|
|
case 'sunnyday':
|
|
case 'desolateland':
|
|
move.type = 'Fire';
|
|
break;
|
|
case 'raindance':
|
|
case 'primordialsea':
|
|
move.type = 'Water';
|
|
break;
|
|
case 'sandstorm':
|
|
move.type = 'Rock';
|
|
break;
|
|
case 'hail':
|
|
move.type = 'Ice';
|
|
break;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
switch (pokemon.effectiveWeather()) {
|
|
case 'sunnyday':
|
|
case 'desolateland':
|
|
move.basePower *= 2;
|
|
break;
|
|
case 'raindance':
|
|
case 'primordialsea':
|
|
move.basePower *= 2;
|
|
break;
|
|
case 'sandstorm':
|
|
move.basePower *= 2;
|
|
break;
|
|
case 'hail':
|
|
move.basePower *= 2;
|
|
break;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 160},
|
|
maxMove: {basePower: 130},
|
|
contestType: "Beautiful",
|
|
},
|
|
whirlpool: {
|
|
num: 250,
|
|
accuracy: 85,
|
|
basePower: 35,
|
|
category: "Special",
|
|
name: "Whirlpool",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
volatileStatus: 'partiallytrapped',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful",
|
|
},
|
|
whirlwind: {
|
|
num: 18,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Whirlwind",
|
|
pp: 20,
|
|
priority: -6,
|
|
flags: {reflectable: 1, mirror: 1, authentic: 1, mystery: 1},
|
|
forceSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
wickedblow: {
|
|
num: 817,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Wicked Blow",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1},
|
|
willCrit: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
wideguard: {
|
|
num: 469,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Wide Guard",
|
|
pp: 10,
|
|
priority: 3,
|
|
flags: {snatch: 1},
|
|
sideCondition: 'wideguard',
|
|
onTryHitSide(side, source) {
|
|
return !!this.queue.willAct();
|
|
},
|
|
onHitSide(side, source) {
|
|
source.addVolatile('stall');
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source) {
|
|
this.add('-singleturn', source, 'Wide Guard');
|
|
},
|
|
onTryHitPriority: 4,
|
|
onTryHit(target, source, move) {
|
|
// Wide Guard blocks all spread moves
|
|
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;
|
|
}
|
|
this.add('-activate', target, 'move: Wide Guard');
|
|
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;
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Rock",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
wildcharge: {
|
|
num: 528,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Wild Charge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
recoil: [1, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Tough",
|
|
},
|
|
willowisp: {
|
|
num: 261,
|
|
accuracy: 85,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Will-O-Wisp",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
status: 'brn',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Beautiful",
|
|
},
|
|
wingattack: {
|
|
num: 17,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Wing Attack",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, distance: 1},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool",
|
|
},
|
|
wish: {
|
|
num: 273,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Wish",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
slotCondition: 'Wish',
|
|
condition: {
|
|
duration: 2,
|
|
onStart(pokemon, source) {
|
|
this.effectData.hp = source.maxhp / 2;
|
|
},
|
|
onResidualOrder: 4,
|
|
onEnd(target) {
|
|
if (target && !target.fainted) {
|
|
const damage = this.heal(this.effectData.hp, target, target);
|
|
if (damage) this.add('-heal', target, target.getHealth, '[from] move: Wish', '[wisher] ' + this.effectData.source.name);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
withdraw: {
|
|
num: 110,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Withdraw",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
def: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Water",
|
|
zMove: {boost: {def: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
wonderroom: {
|
|
num: 472,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Wonder Room",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {mirror: 1},
|
|
pseudoWeather: 'wonderroom',
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasAbility('persistent')) {
|
|
this.add('-activate', source, 'ability: Persistent', effect);
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onStart(side, source) {
|
|
this.add('-fieldstart', 'move: Wonder Room', '[of] ' + source);
|
|
},
|
|
onRestart(target, source) {
|
|
this.field.removePseudoWeather('wonderroom');
|
|
},
|
|
// Swapping defenses implemented in sim/pokemon.js:Pokemon#calculateStat and Pokemon#getStat
|
|
onResidualOrder: 24,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Wonder Room');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: {boost: {spd: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
woodhammer: {
|
|
num: 452,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Wood Hammer",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
recoil: [33, 100],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough",
|
|
},
|
|
workup: {
|
|
num: 526,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Work Up",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
boosts: {
|
|
atk: 1,
|
|
spa: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: {boost: {atk: 1}},
|
|
contestType: "Tough",
|
|
},
|
|
worryseed: {
|
|
num: 388,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Worry Seed",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, mystery: 1},
|
|
onTryHit(pokemon) {
|
|
const bannedAbilities = [
|
|
'battlebond', 'comatose', 'disguise', 'insomnia', 'multitype', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'truant', 'zenmode',
|
|
];
|
|
if (bannedAbilities.includes(pokemon.ability)) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(pokemon) {
|
|
const oldAbility = pokemon.setAbility('insomnia');
|
|
if (oldAbility) {
|
|
this.add('-ability', pokemon, 'Insomnia', '[from] move: Worry Seed');
|
|
if (pokemon.status === 'slp') {
|
|
pokemon.cureStatus();
|
|
}
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Clever",
|
|
},
|
|
wrap: {
|
|
num: 35,
|
|
accuracy: 90,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Wrap",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
volatileStatus: 'partiallytrapped',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough",
|
|
},
|
|
wringout: {
|
|
num: 378,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
return Math.floor(Math.floor((120 * (100 * Math.floor(target.hp * 4096 / target.maxhp)) + 2048 - 1) / 4096) / 100) || 1;
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Wring Out",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {basePower: 190},
|
|
maxMove: {basePower: 140},
|
|
contestType: "Tough",
|
|
},
|
|
xscissor: {
|
|
num: 404,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "X-Scissor",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool",
|
|
},
|
|
yawn: {
|
|
num: 281,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Yawn",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
volatileStatus: 'yawn',
|
|
onTryHit(target) {
|
|
if (target.status || !target.runStatusImmunity('slp')) {
|
|
return false;
|
|
}
|
|
},
|
|
condition: {
|
|
noCopy: true, // doesn't get copied by Baton Pass
|
|
duration: 2,
|
|
onStart(target, source) {
|
|
this.add('-start', target, 'move: Yawn', '[of] ' + source);
|
|
},
|
|
onResidualOrder: 19,
|
|
onEnd(target) {
|
|
this.add('-end', target, 'move: Yawn', '[silent]');
|
|
target.trySetStatus('slp', this.effectData.source);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: {boost: {spe: 1}},
|
|
contestType: "Cute",
|
|
},
|
|
zapcannon: {
|
|
num: 192,
|
|
accuracy: 50,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Zap Cannon",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {bullet: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
zenheadbutt: {
|
|
num: 428,
|
|
accuracy: 90,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Zen Headbutt",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever",
|
|
},
|
|
zingzap: {
|
|
num: 716,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Zing Zap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
zippyzap: {
|
|
num: 729,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Zippy Zap",
|
|
pp: 10,
|
|
priority: 2,
|
|
flags: {contact: 1, protect: 1},
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
evasion: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool",
|
|
},
|
|
};
|