Minecraft-STC-Modpack/showdown/data/moves.js
2023-08-14 21:45:09 -04:00

22142 lines
519 KiB
JavaScript

"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var moves_exports = {};
__export(moves_exports, {
Moves: () => Moves
});
module.exports = __toCommonJS(moves_exports);
const Moves = {
"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("BP 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 = [];
let stat;
for (stat in target.boosts) {
if (target.boosts[stat] < 6) {
stats.push(stat);
}
}
if (stats.length) {
const randomStat = this.sample(stats);
const boost = {};
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, slicing: 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: { bypasssub: 1, allyanim: 1 },
onHit(target) {
if (target.side.active.length < 2)
return false;
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, slicing: 1, wind: 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, slicing: 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: {},
stallingMove: true,
onPrepareHit(pokemon) {
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
},
onTryHit(source) {
if (source.side.active.length === 1)
return false;
if (source.side.active.length === 3 && source.position === 1)
return false;
},
onHit(pokemon) {
pokemon.addVolatile("stall");
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",
isNonstandard: "Past",
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"
},
aquacutter: {
num: 895,
accuracy: 100,
basePower: 70,
category: "Physical",
name: "Aqua Cutter",
pp: 20,
priority: 0,
flags: { protect: 1, mirror: 1, slicing: 1 },
critRatio: 2,
secondary: null,
target: "normal",
type: "Water",
contestType: "Cool"
},
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"
},
aquastep: {
num: 872,
accuracy: 100,
basePower: 80,
category: "Physical",
name: "Aqua Step",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, dance: 1 },
secondary: {
chance: 100,
self: {
boosts: {
spe: 1
}
}
},
target: "normal",
type: "Water",
contestType: "Cool"
},
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"
},
armorcannon: {
num: 890,
accuracy: 100,
basePower: 120,
category: "Special",
name: "Armor Cannon",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
self: {
boosts: {
def: -1,
spd: -1
}
},
secondary: null,
target: "normal",
type: "Fire"
},
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",
isNonstandard: "Past",
name: "Aromatherapy",
pp: 5,
priority: 0,
flags: { snatch: 1, distance: 1 },
onHit(target, source, move) {
this.add("-activate", source, "move: Aromatherapy");
let success = false;
const allies = [...target.side.pokemon, ...target.side.allySide?.pokemon || []];
for (const ally of allies) {
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: { bypasssub: 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: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
onHit(target) {
const moves = [];
for (const pokemon of target.side.pokemon) {
if (pokemon === target)
continue;
for (const moveSlot of pokemon.moveSlots) {
const moveid = moveSlot.id;
const move = this.dex.moves.get(moveid);
if (move.flags["noassist"] || move.isZ || move.isMax) {
continue;
}
moves.push(moveid);
}
}
let randomMove = "";
if (moves.length)
randomMove = this.sample(moves);
if (!randomMove) {
return false;
}
this.actions.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("BP doubled on damaged target");
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"
},
astralbarrage: {
num: 825,
accuracy: 100,
basePower: 120,
category: "Special",
name: "Astral Barrage",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: null,
target: "allAdjacentFoes",
type: "Ghost"
},
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, bypasssub: 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.name === "Cute Charm") {
this.add("-start", pokemon, "Attract", "[from] ability: Cute Charm", "[of] " + source);
} else if (effect.name === "Destiny Knot") {
this.add("-start", pokemon, "Attract", "[from] item: Destiny Knot", "[of] " + source);
} else {
this.add("-start", pokemon, "Attract");
}
},
onUpdate(pokemon) {
if (this.effectState.source && !this.effectState.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.effectState.source);
if (this.randomChance(1, 2)) {
this.add("cant", pokemon, "Attract");
return false;
}
},
onEnd(pokemon) {
this.add("-end", pokemon, "Attract", "[silent]");
}
},
onTryImmunity(target, source) {
return target.gender === "M" && source.gender === "F" || target.gender === "F" && source.gender === "M";
},
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",
isNonstandard: "Past",
name: "Aura Wheel",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 100,
self: {
boosts: {
spe: 1
}
}
},
onTry(source) {
if (source.species.baseSpecies === "Morpeko") {
return;
}
this.attrLastMove("[still]");
this.add("-fail", source, "move: Aura Wheel");
this.hint("Only a Pokemon whose form is Morpeko or Morpeko-Hangry can use this move.");
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",
onTry() {
return this.field.isWeather(["hail", "snow"]);
},
condition: {
duration: 5,
durationCallback(target, source, effect) {
if (source?.hasItem("lightclay")) {
return 8;
}
return 5;
},
onAnyModifyDamage(damage, source, target, move) {
if (target !== source && this.effectState.target.hasAlly(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 (this.activePerHalf > 1)
return this.chainModify([2732, 4096]);
return this.chainModify(0.5);
}
}
},
onSideStart(side) {
this.add("-sidestart", side, "move: Aurora Veil");
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 10,
onSideEnd(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",
isNonstandard: "Past",
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 - 1e3);
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("BP doubled 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"
},
axekick: {
num: 853,
accuracy: 90,
basePower: 120,
category: "Physical",
name: "Axe Kick",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
hasCrashDamage: true,
onMoveFail(target, source, move) {
this.damage(source.baseMaxhp / 2, source, source, this.dex.conditions.get("High Jump Kick"));
},
secondary: {
chance: 30,
volatileStatus: "confusion"
},
target: "normal",
type: "Fighting"
},
babydolleyes: {
num: 608,
accuracy: 100,
basePower: 0,
category: "Status",
name: "Baby-Doll Eyes",
pp: 30,
priority: 1,
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 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, mirror: 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: { noassist: 1, failcopycat: 1 },
stallingMove: true,
volatileStatus: "banefulbunker",
onPrepareHit(pokemon) {
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
},
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 (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
return;
if (move.isZ || move.isMax)
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) {
if (source.volatiles["lockedmove"].duration === 2) {
delete source.volatiles["lockedmove"];
}
}
if (this.checkMoveMakesContact(move, source, target)) {
source.trySetStatus("psn", target);
}
return this.NOT_FAIL;
},
onHit(target, source, move) {
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
source.trySetStatus("psn", target);
}
}
},
secondary: null,
target: "self",
type: "Poison",
zMove: { boost: { def: 1 } },
contestType: "Tough"
},
barbbarrage: {
num: 839,
accuracy: 100,
basePower: 60,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Barb Barrage",
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: {
chance: 50,
status: "psn"
},
target: "normal",
type: "Poison"
},
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: {},
onTryHit(target) {
if (!this.canSwitch(target.side) || target.volatiles["commanded"]) {
this.attrLastMove("[still]");
this.add("-fail", target);
return this.NOT_FAIL;
}
},
self: {
onHit(source) {
source.skipBeforeSwitchOutEventFlag = true;
}
},
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, noassist: 1, failmefirst: 1, nosleeptalk: 1, failcopycat: 1, failinstruct: 1 },
priorityChargeCallback(pokemon) {
pokemon.addVolatile("beakblast");
},
condition: {
duration: 1,
onStart(pokemon) {
this.add("-singleturn", pokemon, "move: Beak Blast");
},
onHit(target, source, move) {
if (this.checkMoveMakesContact(move, source, target)) {
source.trySetStatus("brn", target);
}
}
},
// 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) {
const currentSpecies = move.allies.shift().species;
const bp = 5 + Math.floor(currentSpecies.baseStats.atk / 10);
this.debug("BP for " + currentSpecies.name + " hit: " + bp);
return bp;
},
category: "Physical",
name: "Beat Up",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, allyanim: 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, failcopycat: 1, failmimic: 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, slicing: 1, failcopycat: 1, failmimic: 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, failmefirst: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
onDisableMove(pokemon) {
if (!pokemon.ateBerry)
pokemon.disableMove("belch");
},
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) {
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, bypasssub: 1, allyanim: 1, noassist: 1, failcopycat: 1 },
onHit(target, source, move) {
if (target.item) {
return false;
}
const myItem = source.takeItem();
if (!myItem)
return false;
if (!this.singleEvent("TakeItem", myItem, source.itemState, 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, nosleeptalk: 1, failinstruct: 1 },
volatileStatus: "bide",
ignoreImmunity: true,
beforeMoveCallback(pokemon) {
if (pokemon.volatiles["bide"])
return true;
},
condition: {
duration: 3,
onLockMove: "bide",
onStart(pokemon) {
this.effectState.totalDamage = 0;
this.add("-start", pokemon, "move: Bide");
},
onDamagePriority: -101,
onDamage(damage, target, source, move) {
if (!move || move.effectType !== "Move" || !source)
return;
this.effectState.totalDamage += damage;
this.effectState.lastDamageSource = source;
},
onBeforeMove(pokemon, target, move) {
if (this.effectState.duration === 1) {
this.add("-end", pokemon, "move: Bide");
target = this.effectState.lastDamageSource;
if (!target || !this.effectState.totalDamage) {
this.attrLastMove("[still]");
this.add("-fail", pokemon);
return false;
}
if (!target.isActive) {
const possibleTarget = this.getRandomTarget(pokemon, this.dex.moves.get("pound"));
if (!possibleTarget) {
this.add("-miss", pokemon);
return false;
}
target = possibleTarget;
}
const moveData = {
id: "bide",
name: "Bide",
accuracy: true,
damage: this.effectState.totalDamage * 2,
category: "Physical",
priority: 1,
flags: { contact: 1, protect: 1 },
effectType: "Move",
type: "Normal"
};
this.actions.tryMoveHit(target, pokemon, moveData);
pokemon.removeVolatile("bide");
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"
},
bitterblade: {
num: 891,
accuracy: 100,
basePower: 90,
category: "Physical",
name: "Bitter Blade",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
drain: [1, 2],
secondary: null,
target: "normal",
type: "Fire"
},
bittermalice: {
num: 841,
accuracy: 100,
basePower: 75,
category: "Special",
name: "Bitter Malice",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 100,
boosts: {
atk: -1
}
},
target: "normal",
type: "Ghost"
},
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"
},
blazingtorque: {
num: 896,
accuracy: 100,
basePower: 80,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Blazing Torque",
pp: 10,
priority: 0,
flags: {
protect: 1,
failencore: 1,
failmefirst: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 1
},
secondary: {
chance: 30,
status: "brn"
},
target: "normal",
type: "Fire"
},
bleakwindstorm: {
num: 846,
accuracy: 80,
basePower: 100,
category: "Special",
isNonstandard: "Unobtainable",
name: "Bleakwind Storm",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, wind: 1 },
secondary: {
chance: 30,
boosts: {
spe: -1
}
},
target: "allAdjacentFoes",
type: "Flying"
},
blizzard: {
num: 59,
accuracy: 70,
basePower: 110,
category: "Special",
name: "Blizzard",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1, wind: 1 },
onModifyMove(move) {
if (this.field.isWeather(["hail", "snow"]))
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",
isNonstandard: "Past",
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 },
overrideOffensiveStat: "def",
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",
isNonstandard: "Past",
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",
isNonstandard: "Past",
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",
isNonstandard: "Past",
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, bypasssub: 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,
nosleeptalk: 1,
noassist: 1,
failinstruct: 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, mirror: 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) {
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, bypasssub: 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.getTypes().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, mirror: 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"
},
ceaselessedge: {
num: 845,
accuracy: 90,
basePower: 65,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Ceaseless Edge",
pp: 15,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
self: {
onHit(source) {
for (const side of source.side.foeSidesWithConditions()) {
side.addSideCondition("spikes");
}
}
},
secondary: {},
// allows sheer force to trigger
target: "normal",
type: "Dark"
},
celebrate: {
num: 606,
accuracy: true,
basePower: 0,
category: "Status",
name: "Celebrate",
pp: 40,
priority: 0,
flags: { nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
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",
condition: {
onStart(pokemon, source, effect) {
if (effect && ["Electromorphosis", "Wind Power"].includes(effect.name)) {
this.add("-start", pokemon, "Charge", this.activeMove.name, "[from] ability: " + effect.name);
} else {
this.add("-start", pokemon, "Charge");
}
},
onRestart(pokemon, source, effect) {
if (effect && ["Electromorphosis", "Wind Power"].includes(effect.name)) {
this.add("-start", pokemon, "Charge", this.activeMove.name, "[from] ability: " + effect.name);
} else {
this.add("-start", pokemon, "Charge");
}
},
onBasePowerPriority: 9,
onBasePower(basePower, attacker, defender, move) {
if (move.type === "Electric") {
this.debug("charge boost");
return this.chainModify(2);
}
},
onMoveAborted(pokemon, target, move) {
if (move.type === "Electric" && move.id !== "charge") {
pokemon.removeVolatile("charge");
}
},
onAfterMove(pokemon, target, move) {
if (move.type === "Electric" && move.id !== "charge") {
pokemon.removeVolatile("charge");
}
},
onEnd(pokemon) {
this.add("-end", pokemon, "Charge", "[silent]");
}
},
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, allyanim: 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,
bypasssub: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 1
},
noSketch: true,
secondary: {
chance: 100,
volatileStatus: "confusion"
},
target: "any",
type: "Flying",
contestType: "Cute"
},
chillingwater: {
num: 886,
accuracy: 100,
basePower: 50,
category: "Special",
name: "Chilling Water",
pp: 20,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 100,
boosts: {
atk: -1
}
},
target: "normal",
type: "Water",
contestType: "Beautiful"
},
chillyreception: {
num: 881,
accuracy: true,
basePower: 0,
category: "Status",
name: "Chilly Reception",
pp: 10,
priority: 0,
flags: {},
// TODO show prepare message before the "POKEMON used MOVE!" message
// This happens even before sleep shows its "POKEMON is fast asleep." message
weather: "snow",
selfSwitch: true,
secondary: null,
target: "all",
type: "Ice"
},
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"
},
chloroblast: {
num: 835,
accuracy: 95,
basePower: 150,
category: "Special",
isNonstandard: "Unobtainable",
name: "Chloroblast",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
mindBlownRecoil: true,
onAfterMove(pokemon, target, move) {
if (move.mindBlownRecoil && !move.multihit) {
const hpBeforeRecoil = pokemon.hp;
this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.conditions.get("Chloroblast"), true);
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
this.runEvent("EmergencyExit", pokemon, pokemon);
}
}
},
secondary: null,
target: "normal",
type: "Grass"
},
circlethrow: {
num: 509,
accuracy: 90,
basePower: 60,
category: "Physical",
name: "Circle Throw",
pp: 10,
priority: -6,
flags: { contact: 1, protect: 1, mirror: 1, noassist: 1, failcopycat: 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",
isNonstandard: "Past",
name: "Clanging Scales",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
selfBoost: {
boosts: {
def: -1
}
},
secondary: null,
target: "allAdjacentFoes",
type: "Dragon",
contestType: "Tough"
},
clangoroussoul: {
num: 775,
accuracy: 100,
basePower: 0,
category: "Status",
isNonstandard: "Past",
name: "Clangorous Soul",
pp: 5,
priority: 0,
flags: { snatch: 1, sound: 1, dance: 1 },
onTry(source) {
if (source.hp <= source.maxhp * 33 / 100 || source.maxhp === 1)
return false;
},
onTryHit(pokemon, target, move) {
if (!this.boost(move.boosts))
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, bypasssub: 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: { bypasssub: 1, allyanim: 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"
},
collisioncourse: {
num: 878,
accuracy: 100,
basePower: 100,
category: "Physical",
name: "Collision Course",
pp: 5,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
onBasePower(basePower, source, target, move) {
if (target.runEffectiveness(move) > 0) {
this.debug(`collision course super effective buff`);
return this.chainModify([5461, 4096]);
}
},
secondary: null,
target: "normal",
type: "Fighting",
contestType: "Tough"
},
combattorque: {
num: 899,
accuracy: 100,
basePower: 100,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Combat Torque",
pp: 10,
priority: 0,
flags: {
protect: 1,
failencore: 1,
failmefirst: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 1
},
secondary: {
chance: 30,
status: "par"
},
target: "normal",
type: "Fighting"
},
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"
},
comeuppance: {
num: 894,
accuracy: 100,
basePower: 0,
damageCallback(pokemon) {
const lastDamagedBy = pokemon.getLastDamagedBy(true);
if (lastDamagedBy !== void 0) {
return lastDamagedBy.damage * 1.5 || 1;
}
return 0;
},
category: "Physical",
name: "Comeuppance",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, failmefirst: 1 },
onTry(source) {
const lastDamagedBy = source.getLastDamagedBy(true);
if (lastDamagedBy === void 0 || !lastDamagedBy.thisTurn)
return false;
},
onModifyTarget(targetRelayVar, source, target, move) {
const lastDamagedBy = source.getLastDamagedBy(true);
if (lastDamagedBy) {
targetRelayVar.target = this.getAtSlot(lastDamagedBy.slot);
}
},
secondary: null,
target: "scripted",
type: "Dark",
contestType: "Cool"
},
confide: {
num: 590,
accuracy: true,
basePower: 0,
category: "Status",
name: "Confide",
pp: 20,
priority: 0,
flags: { reflectable: 1, mirror: 1, sound: 1, bypasssub: 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",
isNonstandard: "Past",
name: "Conversion",
pp: 30,
priority: 0,
flags: { snatch: 1 },
onHit(target) {
const type = this.dex.moves.get(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",
isNonstandard: "Past",
name: "Conversion 2",
pp: 30,
priority: 0,
flags: { bypasssub: 1 },
onHit(target, source) {
if (!target.lastMoveUsed) {
return false;
}
const possibleTypes = [];
const attackType = target.lastMoveUsed.type;
for (const type of this.dex.types.names()) {
if (source.hasType(type))
continue;
const typeCheck = this.dex.types.get(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: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
onHit(pokemon) {
let move = this.lastMove;
if (!move)
return;
if (move.isMax && move.baseMove)
move = this.dex.moves.get(move.baseMove);
if (move.flags["failcopycat"] || move.isZ || move.isMax) {
return false;
}
this.actions.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) {
if (target.getAbility().isPermanent)
return;
if (target.newlySwitched || this.queue.willMove(target))
return;
target.addVolatile("gastroacid");
},
onAfterSubDamage(damage, target) {
if (target.getAbility().isPermanent)
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, allyanim: 1 },
onHit(target, source) {
const item = target.takeItem(source);
if (item) {
this.add("-enditem", target, item.name, "[from] move: Corrosive Gas", "[of] " + source);
} else {
this.add("-fail", target, "move: Corrosive Gas");
}
},
secondary: null,
target: "allAdjacent",
type: "Poison"
},
cosmicpower: {
num: 322,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Unobtainable",
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, failmefirst: 1, noassist: 1, failcopycat: 1 },
beforeTurnCallback(pokemon) {
pokemon.addVolatile("counter");
},
onTry(source) {
if (!source.volatiles["counter"])
return false;
if (source.volatiles["counter"].slot === null)
return false;
},
condition: {
duration: 1,
noCopy: true,
onStart(target, source, move) {
this.effectState.slot = null;
this.effectState.damage = 0;
},
onRedirectTargetPriority: -1,
onRedirectTarget(target, source, source2, move) {
if (move.id !== "counter")
return;
if (source !== this.effectState.target || !this.effectState.slot)
return;
return this.getAtSlot(this.effectState.slot);
},
onDamagingHit(damage, target, source, move) {
if (!source.isAlly(target) && this.getCategory(move) === "Physical") {
this.effectState.slot = source.getSlot();
this.effectState.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 sideConditions = [
"mist",
"lightscreen",
"reflect",
"spikes",
"safeguard",
"tailwind",
"toxicspikes",
"stealthrock",
"waterpledge",
"firepledge",
"grasspledge",
"stickyweb",
"auroraveil",
"gmaxsteelsurge",
"gmaxcannonade",
"gmaxvinelash",
"gmaxwildfire"
];
let success = false;
if (this.gameType === "freeforall") {
const offset = this.random(3) + 1;
const sides = [this.sides[0], this.sides[2], this.sides[1], this.sides[3]];
const temp = { 0: {}, 1: {}, 2: {}, 3: {} };
for (const side of sides) {
for (const id in side.sideConditions) {
if (!sideConditions.includes(id))
continue;
temp[side.n][id] = side.sideConditions[id];
delete side.sideConditions[id];
const effectName = this.dex.conditions.get(id).name;
this.add("-sideend", side, effectName, "[silent]");
success = true;
}
}
for (let i = 0; i < 4; i++) {
const sourceSideConditions = temp[sides[i].n];
const targetSide = sides[(i + offset) % 4];
for (const id in sourceSideConditions) {
targetSide.sideConditions[id] = sourceSideConditions[id];
const effectName = this.dex.conditions.get(id).name;
let layers = sourceSideConditions[id].layers || 1;
for (; layers > 0; layers--)
this.add("-sidestart", targetSide, effectName, "[silent]");
}
}
} else {
const sourceSideConditions = source.side.sideConditions;
const targetSideConditions = source.side.foe.sideConditions;
const sourceTemp = {};
const targetTemp = {};
for (const id in sourceSideConditions) {
if (!sideConditions.includes(id))
continue;
sourceTemp[id] = sourceSideConditions[id];
delete sourceSideConditions[id];
success = true;
}
for (const id in targetSideConditions) {
if (!sideConditions.includes(id))
continue;
targetTemp[id] = targetSideConditions[id];
delete targetSideConditions[id];
success = true;
}
for (const id in sourceTemp) {
targetSideConditions[id] = sourceTemp[id];
}
for (const id in targetTemp) {
sourceSideConditions[id] = targetTemp[id];
}
this.add("-swapsideconditions");
}
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, failmefirst: 1, noassist: 1, failcopycat: 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.itemState, source, target, move, yourItem) || !source.setItem(yourItem)) {
target.item = yourItem.id;
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",
isNonstandard: "Past",
name: "Crafty Shield",
pp: 10,
priority: 3,
flags: {},
sideCondition: "craftyshield",
onTry() {
return !!this.queue.willAct();
},
condition: {
duration: 1,
onSideStart(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, slicing: 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) {
const hp = target.hp;
const maxHP = target.maxhp;
const bp = Math.floor(Math.floor((120 * (100 * Math.floor(hp * 4096 / maxHP)) + 2048 - 1) / 4096) / 100) || 1;
this.debug("BP for " + hp + "/" + maxHP + " HP: " + bp);
return bp;
},
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: { bypasssub: 1 },
volatileStatus: "curse",
onModifyMove(move, source, target) {
if (!source.hasType("Ghost")) {
move.target = move.nonGhostTarget;
} else if (source.isAlly(target)) {
move.target = "randomNormal";
}
},
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: 12,
onResidual(pokemon) {
this.damage(pokemon.baseMaxhp / 4);
}
},
secondary: null,
target: "normal",
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, slicing: 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",
onTry(source, target, move) {
if (source.species.name === "Darkrai" || move.hasBounced) {
return;
}
this.add("-fail", source, "move: Dark Void");
this.hint("Only a Pokemon whose form is Darkrai can use this move.");
return null;
},
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",
isNonstandard: "Past",
name: "Decorate",
pp: 15,
priority: 0,
flags: { allyanim: 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,
onRestart: () => null
},
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, bypasssub: 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.conditions.get(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.conditions.get(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: { bypasssub: 1, noassist: 1, failcopycat: 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.isAlly(source))
return;
if (effect.effectType === "Move" && !effect.flags["futuremove"]) {
if (source.volatiles["dynamax"]) {
this.add("-hint", "Dynamaxed Pok\xE9mon 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: { noassist: 1, failcopycat: 1 },
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",
name: "Diamond Storm",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
self: {
chance: 50,
boosts: {
def: 2
}
},
secondary: {
// Sheer Force negates the self even though it is not secondary
},
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, nosleeptalk: 1, noassist: 1, failinstruct: 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, bypasssub: 1 },
volatileStatus: "disable",
onTryHit(target) {
if (!target.lastMove || target.lastMove.isZ || target.lastMove.isMax || target.lastMove.id === "struggle") {
return false;
}
},
condition: {
duration: 5,
noCopy: true,
// doesn't get copied by Baton Pass
onStart(pokemon, source, effect) {
if (this.queue.willMove(pokemon) || pokemon === this.activePokemon && this.activeMove && !this.activeMove.isExternal) {
this.effectState.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;
}
}
}
if (effect.effectType === "Ability") {
this.add("-start", pokemon, "Disable", pokemon.lastMove.name, "[from] ability: Cursed Body", "[of] " + source);
} else {
this.add("-start", pokemon, "Disable", pokemon.lastMove.name);
}
this.effectState.move = pokemon.lastMove.id;
},
onResidualOrder: 17,
onEnd(pokemon) {
this.add("-end", pokemon, "Disable");
},
onBeforeMovePriority: 7,
onBeforeMove(attacker, defender, move) {
if (!move.isZ && move.id === this.effectState.move) {
this.add("cant", attacker, "Disable", move);
return false;
}
},
onDisableMove(pokemon) {
for (const moveSlot of pokemon.moveSlots) {
if (moveSlot.id === this.effectState.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, bypasssub: 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"
},
direclaw: {
num: 827,
accuracy: 100,
basePower: 80,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Dire Claw",
pp: 15,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
secondary: {
chance: 50,
onHit(target, source) {
const result = this.random(3);
if (result === 0) {
target.trySetStatus("psn", source);
} else if (result === 1) {
target.trySetStatus("par", source);
} else {
target.trySetStatus("slp", source);
}
}
},
target: "normal",
type: "Poison"
},
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,
allyanim: 1,
nosleeptalk: 1,
noassist: 1,
failinstruct: 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"
},
doodle: {
num: 867,
accuracy: 100,
basePower: 0,
category: "Status",
name: "Doodle",
pp: 10,
priority: 0,
flags: {},
onHit(target, source, move) {
let success = false;
for (const pokemon of source.alliesAndSelf()) {
if (pokemon.ability === target.ability)
continue;
const oldAbility = pokemon.setAbility(target.ability);
if (oldAbility) {
this.add("-ability", pokemon, target.getAbility().name, "[from] move: Doodle");
success = true;
} else if (!success && oldAbility === null) {
success = null;
}
}
if (!success) {
if (success === false) {
this.add("-fail", source);
}
this.attrLastMove("[still]");
return this.NOT_FAIL;
}
},
secondary: null,
target: "adjacentFoe",
type: "Normal"
},
doomdesire: {
num: 353,
accuracy: 100,
basePower: 140,
category: "Special",
isNonstandard: "Past",
name: "Doom Desire",
pp: 5,
priority: 0,
flags: { futuremove: 1 },
onTry(source, target) {
if (!target.side.addSlotCondition(target, "futuremove"))
return false;
Object.assign(target.side.slotConditions[target.position]["futuremove"], {
move: "doomdesire",
source,
moveData: {
id: "doomdesire",
name: "Doom Desire",
accuracy: 100,
basePower: 140,
category: "Special",
priority: 0,
flags: { futuremove: 1 },
effectType: "Move",
type: "Steel"
}
});
this.add("-start", source, "Doom Desire");
return this.NOT_FAIL;
},
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",
isNonstandard: "Past",
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"
},
doubleshock: {
num: 892,
accuracy: 100,
basePower: 120,
category: "Physical",
name: "Double Shock",
pp: 5,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
onTryMove(pokemon, target, move) {
if (pokemon.hasType("Electric"))
return;
this.add("-fail", pokemon, "move: Double Shock");
this.attrLastMove("[still]");
return null;
},
self: {
onHit(pokemon) {
pokemon.setType(pokemon.getTypes(true).map((type) => type === "Electric" ? "???" : type));
this.add("-start", pokemon, "typechange", pokemon.getTypes().join("/"), "[from] move: Double Shock");
}
},
secondary: null,
target: "normal",
type: "Electric",
contestType: "Clever"
},
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",
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, noparentalbond: 1 },
multihit: 2,
smartTarget: true,
secondary: null,
target: "normal",
type: "Dragon",
maxMove: { basePower: 130 }
},
dragonenergy: {
num: 820,
accuracy: 100,
basePower: 150,
basePowerCallback(pokemon, target, move) {
const bp = move.basePower * pokemon.hp / pokemon.maxhp;
this.debug("BP: " + bp);
return bp;
},
category: "Special",
name: "Dragon Energy",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: null,
target: "allAdjacentFoes",
type: "Dragon"
},
dragonhammer: {
num: 692,
accuracy: 100,
basePower: 90,
category: "Physical",
isNonstandard: "Past",
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, noassist: 1, failcopycat: 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",
isNonstandard: "Past",
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, failencore: 1, nosleeptalk: 1, noparentalbond: 1, failcopycat: 1, failinstruct: 1, failmimic: 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(pokemon, target, move) {
let bp = move.basePower;
if (this.field.pseudoWeather.echoedvoice) {
bp = move.basePower * this.field.pseudoWeather.echoedvoice.multiplier;
}
this.debug("BP: " + move.basePower);
return bp;
},
category: "Special",
name: "Echoed Voice",
pp: 15,
priority: 0,
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
onTry() {
this.field.addPseudoWeather("echoedvoice");
},
condition: {
duration: 2,
onFieldStart() {
this.effectState.multiplier = 1;
},
onFieldRestart() {
if (this.effectState.duration !== 2) {
this.effectState.duration = 2;
if (this.effectState.multiplier < 5) {
this.effectState.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"
},
eeriespell: {
num: 826,
accuracy: 100,
basePower: 80,
category: "Special",
name: "Eerie Spell",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
secondary: {
chance: 100,
onHit(target) {
if (!target.hp)
return;
let move = target.lastMove;
if (!move || move.isZ)
return;
if (move.isMax && move.baseMove)
move = this.dex.moves.get(move.baseMove);
const ppDeducted = target.deductPP(move.id, 3);
if (!ppDeducted)
return;
this.add("-activate", target, "move: Eerie Spell", move.name, ppDeducted);
}
},
target: "normal",
type: "Psychic"
},
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([5325, 4096]);
}
},
onFieldStart(field, source, effect) {
if (effect?.effectType === "Ability") {
this.add("-fieldstart", "move: Electric Terrain", "[from] ability: " + effect.name, "[of] " + source);
} else {
this.add("-fieldstart", "move: Electric Terrain");
}
},
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 7,
onFieldEnd() {
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",
isNonstandard: "Past",
name: "Electrify",
pp: 20,
priority: 0,
flags: { protect: 1, mirror: 1, allyanim: 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"
},
electrodrift: {
num: 879,
accuracy: 100,
basePower: 100,
category: "Special",
name: "Electro Drift",
pp: 5,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
onBasePower(basePower, source, target, move) {
if (target.runEffectiveness(move) > 0) {
this.debug(`electro drift super effective buff`);
return this.chainModify([5461, 4096]);
}
},
secondary: null,
target: "normal",
type: "Electric",
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");
this.singleEvent("End", pokemon.getItem(), pokemon.itemState, pokemon);
},
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
onResidualOrder: 21,
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, bypasssub: 1, failencore: 1 },
volatileStatus: "encore",
condition: {
duration: 3,
noCopy: true,
// doesn't get copied by Z-Baton Pass
onStart(target) {
let move = target.lastMove;
if (!move || target.volatiles["dynamax"])
return false;
if (move.isMax && move.baseMove)
move = this.dex.moves.get(move.baseMove);
const moveIndex = target.moves.indexOf(move.id);
if (move.isZ || move.flags["failencore"] || !target.moveSlots[moveIndex] || target.moveSlots[moveIndex].pp <= 0) {
return false;
}
this.effectState.move = move.id;
this.add("-start", target, "Encore");
if (!this.queue.willMove(target)) {
this.effectState.duration++;
}
},
onOverrideAction(pokemon, target, move) {
if (move.id !== this.effectState.move)
return this.effectState.move;
},
onResidualOrder: 16,
onResidual(target) {
if (target.moves.includes(this.effectState.move) && target.moveSlots[target.moves.indexOf(this.effectState.move)].pp <= 0) {
target.removeVolatile("encore");
}
},
onEnd(target) {
this.add("-end", target, "Encore");
},
onDisableMove(pokemon) {
if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) {
return;
}
for (const moveSlot of pokemon.moveSlots) {
if (moveSlot.id !== this.effectState.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, noparentalbond: 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: { noassist: 1, failcopycat: 1 },
stallingMove: true,
volatileStatus: "endure",
onPrepareHit(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, allyanim: 1 },
onTryHit(target, source) {
if (target === source || target.volatiles["dynamax"])
return false;
const additionalBannedSourceAbilities = [
// Zen Mode included here for compatability with Gen 5-6
"flowergift",
"forecast",
"hungerswitch",
"illusion",
"imposter",
"neutralizinggas",
"powerofalchemy",
"receiver",
"trace",
"zenmode"
];
if (target.ability === source.ability || target.getAbility().isPermanent || target.ability === "truant" || source.getAbility().isPermanent || additionalBannedSourceAbilities.includes(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.isAlly(source))
target.volatileStaleness = "external";
return;
}
return oldAbility;
},
secondary: null,
target: "normal",
type: "Normal",
zMove: { boost: { spd: 1 } },
contestType: "Cute"
},
eruption: {
num: 284,
accuracy: 100,
basePower: 150,
basePowerCallback(pokemon, target, move) {
const bp = move.basePower * pokemon.hp / pokemon.maxhp;
this.debug("BP: " + bp);
return bp;
},
category: "Special",
name: "Eruption",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: null,
target: "allAdjacentFoes",
type: "Fire",
contestType: "Beautiful"
},
esperwing: {
num: 840,
accuracy: 100,
basePower: 80,
category: "Special",
isNonstandard: "Unobtainable",
name: "Esper Wing",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
critRatio: 2,
secondary: {
chance: 100,
self: {
boosts: {
spe: 1
}
}
},
target: "normal",
type: "Psychic"
},
eternabeam: {
num: 795,
accuracy: 90,
basePower: 160,
category: "Special",
isNonstandard: "Past",
name: "Eternabeam",
pp: 5,
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, noparentalbond: 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, bypasssub: 1 },
pseudoWeather: "fairylock",
condition: {
duration: 2,
onFieldStart(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, wind: 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(source) {
if (source.activeMoveActions > 1) {
this.hint("Fake Out only works on your first turn out.");
return false;
}
},
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, allyanim: 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 },
onDamagePriority: -20,
onDamage(damage, target, source, effect) {
if (damage >= target.hp)
return target.hp - 1;
},
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, allyanim: 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, noassist: 1, failcopycat: 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"
},
fierywrath: {
num: 822,
accuracy: 100,
basePower: 90,
category: "Special",
name: "Fiery Wrath",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 20,
volatileStatus: "flinch"
},
target: "allAdjacentFoes",
type: "Dark"
},
filletaway: {
num: 868,
accuracy: true,
basePower: 0,
category: "Status",
name: "Fillet Away",
pp: 10,
priority: 0,
flags: { snatch: 1 },
onTry(source) {
if (source.hp <= source.maxhp / 2 || source.maxhp === 1)
return false;
},
onTryHit(pokemon, target, move) {
if (!this.boost(move.boosts))
return null;
delete move.boosts;
},
onHit(pokemon) {
this.directDamage(pokemon.maxhp / 2);
},
boosts: {
atk: 2,
spa: 2,
spe: 2
},
secondary: null,
target: "self",
type: "Normal"
},
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, noparentalbond: 1 },
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, pledgecombo: 1 },
onPrepareHit(target, source, move) {
for (const action of this.queue.list) {
if (!action.move || !action.pokemon?.isActive || action.pokemon.fainted || action.maxMove || action.zmove) {
continue;
}
if (action.pokemon.isAlly(source) && ["grasspledge", "waterpledge"].includes(action.move.id)) {
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,
onSideStart(targetSide) {
this.add("-sidestart", targetSide, "Fire Pledge");
},
onResidualOrder: 5,
onResidualSubOrder: 1,
onResidual(pokemon) {
if (!pokemon.hasType("Fire"))
this.damage(pokemon.baseMaxhp / 8, pokemon);
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 8,
onSideEnd(targetSide) {
this.add("-sideend", targetSide, "Fire Pledge");
}
},
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(source) {
if (source.activeMoveActions > 1) {
this.hint("First Impression only works on your first turn out.");
return false;
}
},
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",
isNonstandard: "Past",
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 = Math.max(Math.floor(pokemon.hp * 48 / pokemon.maxhp), 1);
let bp;
if (ratio < 2) {
bp = 200;
} else if (ratio < 5) {
bp = 150;
} else if (ratio < 10) {
bp = 100;
} else if (ratio < 17) {
bp = 80;
} else if (ratio < 33) {
bp = 40;
} else {
bp = 20;
}
this.debug("BP: " + bp);
return bp;
},
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) {
for (const ally of target.adjacentAllies()) {
this.damage(ally.baseMaxhp / 16, ally, source, this.dex.conditions.get("Flame Burst"));
}
},
onAfterSubDamage(damage, target, source, move) {
for (const ally of target.adjacentAllies()) {
this.damage(ally.baseMaxhp / 16, ally, source, this.dex.conditions.get("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, allyanim: 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, allyanim: 1, noparentalbond: 1 },
onPrepareHit(target, source, move) {
if (source.ignoringItem())
return false;
const item = source.getItem();
if (!this.singleEvent("TakeItem", item, source.itemState, source, source, move, item))
return false;
if (!item.fling)
return false;
move.basePower = item.fling.basePower;
this.debug("BP: " + move.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.addVolatile("fling");
},
condition: {
onUpdate(pokemon) {
const item = pokemon.getItem();
pokemon.setItem("");
pokemon.lastItem = item.id;
pokemon.usedItemThisTurn = true;
this.add("-enditem", pokemon, item.name, "[from] move: Fling");
this.runEvent("AfterUseItem", pokemon, null, null, item);
pokemon.removeVolatile("fling");
}
},
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, mirror: 1, gravity: 1 },
secondary: {
chance: 30,
volatileStatus: "flinch"
},
target: "normal",
type: "Flying",
contestType: "Cool"
},
floralhealing: {
num: 666,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Past",
name: "Floral Healing",
pp: 10,
priority: 0,
flags: { protect: 1, reflectable: 1, heal: 1, allyanim: 1 },
onHit(target, source) {
let success = false;
if (this.field.isTerrain("grassyterrain")) {
success = !!this.heal(this.modify(target.baseMaxhp, 0.667));
} else {
success = !!this.heal(Math.ceil(target.baseMaxhp * 0.5));
}
if (success && !target.isAlly(source)) {
target.staleness = "external";
}
if (!success) {
this.add("-fail", target, "heal");
return this.NOT_FAIL;
}
return success;
},
secondary: null,
target: "normal",
type: "Fairy",
zMove: { effect: "clearnegativeboost" },
contestType: "Beautiful"
},
flowershield: {
num: 579,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Past",
name: "Flower Shield",
pp: 10,
priority: 0,
flags: { distance: 1 },
onHitField(t, source, move) {
const targets = [];
for (const pokemon of this.getAllActive()) {
if (pokemon.hasType("Grass") && (!pokemon.volatiles["maxguard"] || this.runEvent("TryHit", pokemon, source, move))) {
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"
},
flowertrick: {
num: 870,
accuracy: true,
basePower: 70,
category: "Physical",
name: "Flower Trick",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
willCrit: true,
secondary: null,
target: "normal",
type: "Grass"
},
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,
nosleeptalk: 1,
noassist: 1,
failinstruct: 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 && ["costar", "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, failmefirst: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
priorityChargeCallback(pokemon) {
pokemon.addVolatile("focuspunch");
},
beforeMoveCallback(pokemon) {
if (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") {
this.effectState.lostFocus = true;
}
},
onTryAddVolatile(status, pokemon) {
if (status.id === "flinch")
return null;
}
},
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: { noassist: 1, failcopycat: 1 },
volatileStatus: "followme",
onTry(source) {
return this.activePerHalf > 1;
},
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.effectState.target.isSkyDropped() && this.validTarget(this.effectState.target, source, move.target)) {
if (move.smartTarget)
move.smartTarget = false;
this.debug("Follow Me redirected target of move");
return this.effectState.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, bypasssub: 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",
isNonstandard: "Past",
name: "Forest's Curse",
pp: 20,
priority: 0,
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 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 },
overrideOffensivePokemon: "target",
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",
isNonstandard: "Past",
name: "Freeze Shock",
pp: 5,
priority: 0,
flags: { charge: 1, protect: 1, mirror: 1, nosleeptalk: 1, failinstruct: 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"
},
freezingglare: {
num: 821,
accuracy: 100,
basePower: 90,
category: "Special",
name: "Freezing Glare",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 10,
status: "frz"
},
target: "normal",
type: "Psychic"
},
freezyfrost: {
num: 739,
accuracy: 90,
basePower: 100,
category: "Special",
isNonstandard: "LGPE",
name: "Freezy Frost",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 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");
}
const bp = this.clampIntRange(move.basePower * pokemon.volatiles["furycutter"].multiplier, 1, 160);
this.debug("BP: " + bp);
return bp;
},
category: "Physical",
name: "Fury Cutter",
pp: 20,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
condition: {
duration: 2,
onStart() {
this.effectState.multiplier = 1;
},
onRestart() {
if (this.effectState.multiplier < 4) {
this.effectState.multiplier <<= 1;
}
this.effectState.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",
isNonstandard: "Past",
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",
isNonstandard: "Past",
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: { allyanim: 1, futuremove: 1 },
ignoreImmunity: 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,
moveData: {
id: "futuresight",
name: "Future Sight",
accuracy: 100,
basePower: 120,
category: "Special",
priority: 0,
flags: { allyanim: 1, futuremove: 1 },
ignoreImmunity: false,
effectType: "Move",
type: "Psychic"
}
});
this.add("-start", source, "move: Future Sight");
return this.NOT_FAIL;
},
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, allyanim: 1 },
volatileStatus: "gastroacid",
onTryHit(target) {
if (target.getAbility().isPermanent) {
return false;
}
if (target.hasItem("Ability Shield")) {
this.add("-block", target, "item: Ability Shield");
return null;
}
},
condition: {
// Ability suppression implemented in Pokemon.ignoringAbility() within sim/pokemon.ts
onStart(pokemon) {
if (pokemon.hasItem("Ability Shield"))
return false;
this.add("-endability", pokemon);
this.singleEvent("End", pokemon.getAbility(), pokemon.abilityState, pokemon, pokemon, "gastroacid");
},
onCopy(pokemon) {
if (pokemon.getAbility().isPermanent)
pokemon.removeVolatile("gastroacid");
}
},
secondary: null,
target: "normal",
type: "Poison",
zMove: { boost: { spe: 1 } },
contestType: "Tough"
},
geargrind: {
num: 544,
accuracy: 85,
basePower: 50,
category: "Physical",
isNonstandard: "Past",
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",
isNonstandard: "Past",
name: "Gear Up",
pp: 20,
priority: 0,
flags: { snatch: 1, bypasssub: 1 },
onHitSide(side, source, move) {
const targets = side.allies().filter((target) => target.hasAbility(["plus", "minus"]) && (!target.volatiles["maxguard"] || this.runEvent("TryHit", target, source, move)));
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, nosleeptalk: 1, failinstruct: 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"
},
gigatonhammer: {
num: 893,
accuracy: 100,
basePower: 160,
category: "Physical",
name: "Gigaton Hammer",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
onDisableMove(pokemon) {
if (pokemon.lastMove?.id === "gigatonhammer")
pokemon.disableMove("gigatonhammer");
},
beforeMoveCallback(pokemon) {
if (pokemon.lastMove?.id === "gigatonhammer")
pokemon.addVolatile("gigatonhammer");
},
onAfterMove(pokemon) {
if (pokemon.removeVolatile("gigatonhammer")) {
this.add("-hint", "Some effects can force a Pokemon to use Gigaton Hammer again in a row.");
}
},
condition: {},
secondary: null,
target: "normal",
type: "Steel"
},
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"
},
glaciallance: {
num: 824,
accuracy: 100,
basePower: 120,
category: "Physical",
name: "Glacial Lance",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: null,
target: "allAdjacentFoes",
type: "Ice"
},
glaciate: {
num: 549,
accuracy: 95,
basePower: 65,
category: "Special",
isNonstandard: "Past",
name: "Glaciate",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 100,
boosts: {
spe: -1
}
},
target: "allAdjacentFoes",
type: "Ice",
contestType: "Beautiful"
},
glaiverush: {
num: 862,
accuracy: 100,
basePower: 120,
category: "Physical",
name: "Glaive Rush",
pp: 5,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
self: {
volatileStatus: "glaiverush"
},
condition: {
noCopy: true,
onStart(pokemon) {
this.add("-singlemove", pokemon, "Glaive Rush", "[silent]");
},
onAccuracy() {
return true;
},
onSourceModifyDamage() {
return this.chainModify(2);
},
onBeforeMovePriority: 100,
onBeforeMove(pokemon) {
this.debug("removing Glaive Rush drawback before attack");
pokemon.removeVolatile("glaiverush");
}
},
secondary: null,
target: "normal",
type: "Dragon"
},
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, mirror: 1 },
self: {
sideCondition: "lightscreen"
},
secondary: null,
target: "normal",
type: "Psychic",
contestType: "Clever"
},
gmaxbefuddle: {
num: 1e3,
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.foes()) {
const result = this.random(3);
if (result === 0) {
pokemon.trySetStatus("slp", source);
} else if (result === 1) {
pokemon.trySetStatus("par", source);
} else {
pokemon.trySetStatus("psn", source);
}
}
}
},
target: "adjacentFoe",
type: "Bug",
contestType: "Cool"
},
gmaxcannonade: {
num: 1e3,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Gigantamax",
name: "G-Max Cannonade",
pp: 10,
priority: 0,
flags: {},
isMax: "Blastoise",
self: {
onHit(source) {
for (const side of source.side.foeSidesWithConditions()) {
side.addSideCondition("gmaxcannonade");
}
}
},
condition: {
duration: 4,
onSideStart(targetSide) {
this.add("-sidestart", targetSide, "G-Max Cannonade");
},
onResidualOrder: 5,
onResidualSubOrder: 1,
onResidual(target) {
if (!target.hasType("Water"))
this.damage(target.baseMaxhp / 6, target);
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 11,
onSideEnd(targetSide) {
this.add("-sideend", targetSide, "G-Max Cannonade");
}
},
secondary: null,
target: "adjacentFoe",
type: "Water",
contestType: "Cool"
},
gmaxcentiferno: {
num: 1e3,
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.foes()) {
pokemon.addVolatile("partiallytrapped", source, this.dex.getActiveMove("G-Max Centiferno"));
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Fire",
contestType: "Cool"
},
gmaxchistrike: {
num: 1e3,
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.alliesAndSelf()) {
pokemon.addVolatile("gmaxchistrike");
}
}
},
condition: {
noCopy: true,
onStart(target, source, effect) {
this.effectState.layers = 1;
if (!["costar", "imposter", "psychup", "transform"].includes(effect?.id)) {
this.add("-start", target, "move: G-Max Chi Strike");
}
},
onRestart(target, source, effect) {
if (this.effectState.layers >= 3)
return false;
this.effectState.layers++;
if (!["costar", "imposter", "psychup", "transform"].includes(effect?.id)) {
this.add("-start", target, "move: G-Max Chi Strike");
}
},
onModifyCritRatio(critRatio) {
return critRatio + this.effectState.layers;
}
},
secondary: null,
target: "adjacentFoe",
type: "Fighting",
contestType: "Cool"
},
gmaxcuddle: {
num: 1e3,
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.foes()) {
pokemon.addVolatile("attract");
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Normal",
contestType: "Cool"
},
gmaxdepletion: {
num: 1e3,
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.foes()) {
let move = pokemon.lastMove;
if (!move || move.isZ)
continue;
if (move.isMax && move.baseMove)
move = this.dex.moves.get(move.baseMove);
const ppDeducted = pokemon.deductPP(move.id, 2);
if (ppDeducted) {
this.add("-activate", pokemon, "move: G-Max Depletion", move.name, ppDeducted);
}
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Dragon",
contestType: "Cool"
},
gmaxdrumsolo: {
num: 1e3,
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: 1e3,
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.alliesAndSelf()) {
this.heal(pokemon.maxhp / 6, pokemon, source, move);
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Fairy",
contestType: "Cool"
},
gmaxfireball: {
num: 1e3,
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: 1e3,
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.foes()) {
this.boost({ spe: -2 }, pokemon);
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Water",
contestType: "Cool"
},
gmaxgoldrush: {
num: 1e3,
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.foes()) {
pokemon.addVolatile("confusion");
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Normal",
contestType: "Cool"
},
gmaxgravitas: {
num: 1e3,
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: 1e3,
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: 1e3,
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.foes()) {
pokemon.trySetStatus("psn", source);
}
}
},
target: "adjacentFoe",
type: "Poison",
contestType: "Cool"
},
gmaxmeltdown: {
num: 1e3,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Gigantamax",
name: "G-Max Meltdown",
pp: 5,
priority: 0,
flags: {},
isMax: "Melmetal",
self: {
onHit(source, target, effect) {
for (const pokemon of source.foes()) {
if (!pokemon.volatiles["dynamax"])
pokemon.addVolatile("torment", source, effect);
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Steel",
contestType: "Cool"
},
gmaxoneblow: {
num: 1e3,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Gigantamax",
name: "G-Max One Blow",
pp: 5,
priority: 0,
flags: {},
isMax: "Urshifu",
secondary: null,
target: "adjacentFoe",
type: "Dark",
contestType: "Cool"
},
gmaxrapidflow: {
num: 1e3,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Gigantamax",
name: "G-Max Rapid Flow",
pp: 5,
priority: 0,
flags: {},
isMax: "Urshifu-Rapid-Strike",
secondary: null,
target: "adjacentFoe",
type: "Water",
contestType: "Cool"
},
gmaxreplenish: {
num: 1e3,
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.alliesAndSelf()) {
if (pokemon.item)
continue;
if (pokemon.lastItem && this.dex.items.get(pokemon.lastItem).isBerry) {
const item = pokemon.lastItem;
pokemon.lastItem = "";
this.add("-item", pokemon, this.dex.items.get(item), "[from] move: G-Max Replenish");
pokemon.setItem(item);
}
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Normal",
contestType: "Cool"
},
gmaxresonance: {
num: 1e3,
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: 1e3,
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.foes()) {
pokemon.addVolatile("partiallytrapped", source, this.dex.getActiveMove("G-Max Sandblast"));
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Ground",
contestType: "Cool"
},
gmaxsmite: {
num: 1e3,
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.foes()) {
pokemon.addVolatile("confusion", source);
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Fairy",
contestType: "Cool"
},
gmaxsnooze: {
num: 1e3,
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: 1e3,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Gigantamax",
name: "G-Max Steelsurge",
pp: 5,
priority: 0,
flags: {},
isMax: "Copperajah",
self: {
onHit(source) {
for (const side of source.side.foeSidesWithConditions()) {
side.addSideCondition("gmaxsteelsurge");
}
}
},
condition: {
onSideStart(side) {
this.add("-sidestart", side, "move: G-Max Steelsurge");
},
onEntryHazard(pokemon) {
if (pokemon.hasItem("heavydutyboots"))
return;
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: 1e3,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Gigantamax",
name: "G-Max Stonesurge",
pp: 5,
priority: 0,
flags: {},
isMax: "Drednaw",
self: {
onHit(source) {
for (const side of source.side.foeSidesWithConditions()) {
side.addSideCondition("stealthrock");
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Water",
contestType: "Cool"
},
gmaxstunshock: {
num: 1e3,
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.foes()) {
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: 1e3,
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: 1e3,
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.foes()) {
this.boost({ evasion: -1 }, pokemon);
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Grass",
contestType: "Cool"
},
gmaxterror: {
num: 1e3,
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.foes()) {
pokemon.addVolatile("trapped", source, null, "trapper");
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Ghost",
contestType: "Cool"
},
gmaxvinelash: {
num: 1e3,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Gigantamax",
name: "G-Max Vine Lash",
pp: 10,
priority: 0,
flags: {},
isMax: "Venusaur",
self: {
onHit(source) {
for (const side of source.side.foeSidesWithConditions()) {
side.addSideCondition("gmaxvinelash");
}
}
},
condition: {
duration: 4,
onSideStart(targetSide) {
this.add("-sidestart", targetSide, "G-Max Vine Lash");
},
onResidualOrder: 5,
onResidualSubOrder: 1,
onResidual(target) {
if (!target.hasType("Grass"))
this.damage(target.baseMaxhp / 6, target);
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 11,
onSideEnd(targetSide) {
this.add("-sideend", targetSide, "G-Max Vine Lash");
}
},
secondary: null,
target: "adjacentFoe",
type: "Grass",
contestType: "Cool"
},
gmaxvolcalith: {
num: 1e3,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Gigantamax",
name: "G-Max Volcalith",
pp: 10,
priority: 0,
flags: {},
isMax: "Coalossal",
self: {
onHit(source) {
for (const side of source.side.foeSidesWithConditions()) {
side.addSideCondition("gmaxvolcalith");
}
}
},
condition: {
duration: 4,
onSideStart(targetSide) {
this.add("-sidestart", targetSide, "G-Max Volcalith");
},
onResidualOrder: 5,
onResidualSubOrder: 1,
onResidual(target) {
if (!target.hasType("Rock"))
this.damage(target.baseMaxhp / 6, target);
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 11,
onSideEnd(targetSide) {
this.add("-sideend", targetSide, "G-Max Volcalith");
}
},
secondary: null,
target: "adjacentFoe",
type: "Rock",
contestType: "Cool"
},
gmaxvoltcrash: {
num: 1e3,
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.foes()) {
pokemon.trySetStatus("par", source);
}
}
},
secondary: null,
target: "adjacentFoe",
type: "Electric",
contestType: "Cool"
},
gmaxwildfire: {
num: 1e3,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Gigantamax",
name: "G-Max Wildfire",
pp: 10,
priority: 0,
flags: {},
isMax: "Charizard",
self: {
onHit(source) {
for (const side of source.side.foeSidesWithConditions()) {
side.addSideCondition("gmaxwildfire");
}
}
},
condition: {
duration: 4,
onSideStart(targetSide) {
this.add("-sidestart", targetSide, "G-Max Wildfire");
},
onResidualOrder: 5,
onResidualSubOrder: 1,
onResidual(target) {
if (!target.hasType("Fire"))
this.damage(target.baseMaxhp / 6, target);
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 11,
onSideEnd(targetSide) {
this.add("-sideend", targetSide, "G-Max Wildfire");
}
},
secondary: null,
target: "adjacentFoe",
type: "Fire",
contestType: "Cool"
},
gmaxwindrage: {
num: 1e3,
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.conditions.get(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.conditions.get(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();
let bp;
if (targetWeight >= 2e3) {
bp = 120;
} else if (targetWeight >= 1e3) {
bp = 100;
} else if (targetWeight >= 500) {
bp = 80;
} else if (targetWeight >= 250) {
bp = 60;
} else if (targetWeight >= 100) {
bp = 40;
} else {
bp = 20;
}
this.debug("BP: " + bp);
return bp;
},
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, pledgecombo: 1 },
onPrepareHit(target, source, move) {
for (const action of this.queue.list) {
if (!action.move || !action.pokemon?.isActive || action.pokemon.fainted || action.maxMove || action.zmove) {
continue;
}
if (action.pokemon.isAlly(source) && ["waterpledge", "firepledge"].includes(action.move.id)) {
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,
onSideStart(targetSide) {
this.add("-sidestart", targetSide, "Grass Pledge");
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 9,
onSideEnd(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, bypasssub: 1 },
status: "slp",
secondary: null,
target: "normal",
type: "Grass",
zMove: { boost: { spe: 1 } },
contestType: "Clever"
},
grassyglide: {
num: 803,
accuracy: 100,
basePower: 60,
category: "Physical",
name: "Grassy Glide",
pp: 20,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 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) && defender.isGrounded() && !defender.isSemiInvulnerable()) {
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([5325, 4096]);
}
},
onFieldStart(field, source, effect) {
if (effect?.effectType === "Ability") {
this.add("-fieldstart", "move: Grassy Terrain", "[from] ability: " + effect.name, "[of] " + source);
} else {
this.add("-fieldstart", "move: Grassy Terrain");
}
},
onResidualOrder: 5,
onResidualSubOrder: 2,
onResidual(pokemon) {
if (pokemon.isGrounded() && !pokemon.isSemiInvulnerable()) {
this.heal(pokemon.baseMaxhp / 16, pokemon, pokemon);
} else {
this.debug(`Pokemon semi-invuln or not grounded; Grassy Terrain skipped`);
}
},
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 7,
onFieldEnd() {
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", "[move] Gravity");
return 7;
}
return 5;
},
onFieldStart(target, source) {
if (source?.hasAbility("persistent")) {
this.add("-fieldstart", "move: Gravity", "[persistent]");
} else {
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 this.chainModify([6840, 4096]);
},
onDisableMove(pokemon) {
for (const moveSlot of pokemon.moveSlots) {
if (this.dex.moves.get(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"] && !move.isZ) {
this.add("cant", pokemon, "move: Gravity", move);
return false;
}
},
onModifyMove(move, pokemon, target) {
if (move.flags["gravity"] && !move.isZ) {
this.add("cant", pokemon, "move: Gravity", move);
return false;
}
},
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 2,
onFieldEnd() {
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, bypasssub: 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",
isNonstandard: "Past",
name: "Grudge",
pp: 5,
priority: 0,
flags: { bypasssub: 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.flags["futuremove"] && source.lastMove) {
let move = source.lastMove;
if (move.isMax && move.baseMove)
move = this.dex.moves.get(move.baseMove);
for (const moveSlot of source.moveSlots) {
if (moveSlot.id === move.id) {
moveSlot.pp = 0;
this.add("-activate", source, "move: Grudge", move.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, allyanim: 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, bypasssub: 1, allyanim: 1 },
onHit(target, source) {
const targetBoosts = {};
const sourceBoosts = {};
const defSpd = ["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, wind: 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("BP: " + power);
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",
isNonstandard: "Past",
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: { bypasssub: 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",
isNonstandard: "Past",
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"
},
headlongrush: {
num: 838,
accuracy: 100,
basePower: 120,
category: "Physical",
name: "Headlong Rush",
pp: 5,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
self: {
boosts: {
def: -1,
spd: -1
}
},
secondary: null,
target: "normal",
type: "Ground"
},
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",
isNonstandard: "Unobtainable",
name: "Heal Bell",
pp: 5,
priority: 0,
flags: { snatch: 1, sound: 1, distance: 1, bypasssub: 1 },
onHit(target, source) {
this.add("-activate", source, "move: Heal Bell");
let success = false;
const allies = [...target.side.pokemon, ...target.side.allySide?.pokemon || []];
for (const ally of allies) {
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", "[move] Heal Block");
return 7;
}
return 5;
},
onStart(pokemon, source) {
this.add("-start", pokemon, "move: Heal Block");
source.moveThisTurnResult = true;
},
onDisableMove(pokemon) {
for (const moveSlot of pokemon.moveSlots) {
if (this.dex.moves.get(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;
}
},
onModifyMove(move, pokemon, target) {
if (move.flags["heal"] && !move.isZ && !move.isMax) {
this.add("cant", pokemon, "move: Heal Block", move);
return false;
}
},
onResidualOrder: 20,
onEnd(pokemon) {
this.add("-end", pokemon, "move: Heal Block");
},
onTryHeal(damage, target, source, effect) {
if (effect?.id === "zpower" || this.effectState.isZ)
return damage;
return false;
},
onRestart(target, source) {
this.add("-fail", target, "move: Heal Block");
if (!source.moveThisTurnResult) {
source.moveThisTurnResult = 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(source) {
if (!this.canSwitch(source.side)) {
this.attrLastMove("[still]");
this.add("-fail", source);
return this.NOT_FAIL;
}
},
selfdestruct: "ifHit",
slotCondition: "healingwish",
condition: {
onSwap(target) {
if (!target.fainted && (target.hp < target.maxhp || target.status)) {
target.heal(target.maxhp);
target.clearStatus();
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, allyanim: 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.isAlly(source)) {
target.staleness = "external";
}
if (!success) {
this.add("-fail", target, "heal");
return this.NOT_FAIL;
}
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",
name: "Heart Swap",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, bypasssub: 1, allyanim: 1 },
onHit(target, source) {
const targetBoosts = {};
const sourceBoosts = {};
let i;
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();
let bp;
if (pokemonWeight >= targetWeight * 5) {
bp = 120;
} else if (pokemonWeight >= targetWeight * 4) {
bp = 100;
} else if (pokemonWeight >= targetWeight * 3) {
bp = 80;
} else if (pokemonWeight >= targetWeight * 2) {
bp = 60;
} else {
bp = 40;
}
this.debug("BP: " + bp);
return bp;
},
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, wind: 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();
let bp;
if (pokemonWeight >= targetWeight * 5) {
bp = 120;
} else if (pokemonWeight >= targetWeight * 4) {
bp = 100;
} else if (pokemonWeight >= targetWeight * 3) {
bp = 80;
} else if (pokemonWeight >= targetWeight * 2) {
bp = 60;
} else {
bp = 40;
}
this.debug("BP: " + bp);
return bp;
},
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: { bypasssub: 1, noassist: 1, failcopycat: 1 },
volatileStatus: "helpinghand",
onTryHit(target) {
if (!target.newlySwitched && !this.queue.willMove(target))
return false;
},
condition: {
duration: 1,
onStart(target, source) {
this.effectState.multiplier = 1.5;
this.add("-singleturn", target, "Helping Hand", "[of] " + source);
},
onRestart(target, source) {
this.effectState.multiplier *= 1.5;
this.add("-singleturn", target, "Helping Hand", "[of] " + source);
},
onBasePowerPriority: 10,
onBasePower(basePower) {
this.debug("Boosting from Helping Hand: " + this.effectState.multiplier);
return this.chainModify(this.effectState.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")) {
this.debug("BP doubled from status condition");
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.conditions.get("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 },
onDamagePriority: -20,
onDamage(damage, target, source, effect) {
if (damage >= target.hp)
return target.hp - 1;
},
secondary: null,
target: "normal",
type: "Normal",
contestType: "Cool"
},
holdhands: {
num: 607,
accuracy: true,
basePower: 0,
category: "Status",
name: "Hold Hands",
pp: 40,
priority: 0,
flags: { bypasssub: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 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, wind: 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"
},
hydrosteam: {
num: 876,
accuracy: 100,
basePower: 80,
category: "Special",
name: "Hydro Steam",
pp: 15,
priority: 0,
flags: { protect: 1, mirror: 1, defrost: 1 },
// Damage boost in Sun applied in conditions.ts
thawsTarget: true,
secondary: null,
target: "normal",
type: "Water"
},
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"
},
hyperdrill: {
num: 887,
accuracy: 100,
basePower: 100,
category: "Physical",
name: "Hyper Drill",
pp: 5,
priority: 0,
flags: { contact: 1, mirror: 1 },
secondary: null,
target: "normal",
type: "Normal",
contestType: "Clever"
},
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",
name: "Hyperspace Fury",
pp: 5,
priority: 0,
flags: { mirror: 1, bypasssub: 1 },
breaksProtect: true,
onTry(source) {
if (source.species.name === "Hoopa-Unbound") {
return;
}
this.hint("Only a Pokemon whose form is Hoopa Unbound can use this move.");
if (source.species.name === "Hoopa") {
this.attrLastMove("[still]");
this.add("-fail", source, "move: Hyperspace Fury", "[forme]");
return null;
}
this.attrLastMove("[still]");
this.add("-fail", source, "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",
name: "Hyperspace Hole",
pp: 5,
priority: 0,
flags: { mirror: 1, bypasssub: 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, bypasssub: 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;
const iceballData = pokemon.volatiles["iceball"];
if (iceballData?.hitCount) {
bp *= Math.pow(2, iceballData.contactHitCount);
}
if (iceballData && pokemon.status !== "slp") {
iceballData.hitCount++;
iceballData.contactHitCount++;
if (iceballData.hitCount < 5) {
iceballData.duration = 2;
}
}
if (pokemon.volatiles["defensecurl"]) {
bp *= 2;
}
this.debug("BP: " + bp);
return bp;
},
category: "Physical",
isNonstandard: "Past",
name: "Ice Ball",
pp: 20,
priority: 0,
flags: { bullet: 1, contact: 1, protect: 1, mirror: 1, noparentalbond: 1, failinstruct: 1 },
onModifyMove(move, pokemon, target) {
if (pokemon.volatiles["iceball"] || pokemon.status === "slp" || !target)
return;
pokemon.addVolatile("iceball");
pokemon.volatiles["iceball"].targetSlot = move.sourceEffect ? pokemon.lastMoveTargetLoc : pokemon.getLocOf(target);
},
onAfterMove(source, target, move) {
const iceballData = source.volatiles["iceball"];
if (iceballData && iceballData.hitCount === 5 && iceballData.contactHitCount < 5) {
source.addVolatile("rolloutstorage");
source.volatiles["rolloutstorage"].contactHitCount = iceballData.contactHitCount;
}
},
condition: {
duration: 1,
onLockMove: "iceball",
onStart() {
this.effectState.hitCount = 0;
this.effectState.contactHitCount = 0;
},
onResidual(target) {
if (target.lastMove && target.lastMove.id === "struggle") {
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",
isNonstandard: "Past",
name: "Ice Burn",
pp: 5,
priority: 0,
flags: { charge: 1, protect: 1, mirror: 1, nosleeptalk: 1, failinstruct: 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",
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"
},
icespinner: {
num: 861,
accuracy: 100,
basePower: 80,
category: "Physical",
name: "Ice Spinner",
pp: 15,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
onHit() {
this.field.clearTerrain();
},
onAfterSubDamage() {
this.field.clearTerrain();
},
secondary: null,
target: "normal",
type: "Ice"
},
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, wind: 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, bypasssub: 1, mustpressure: 1 },
volatileStatus: "imprison",
condition: {
noCopy: true,
onStart(target) {
this.add("-start", target, "move: Imprison");
},
onFoeDisableMove(pokemon) {
for (const moveSlot of this.effectState.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.effectState.source.hasMove(move.id) && !move.isZ && !move.isMax) {
this.add("cant", attacker, "move: Imprison", move);
return false;
}
}
},
secondary: null,
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"
},
infernalparade: {
num: 844,
accuracy: 100,
basePower: 60,
basePowerCallback(pokemon, target, move) {
if (target.status || target.hasAbility("comatose"))
return move.basePower * 2;
return move.basePower;
},
category: "Special",
isNonstandard: "Unobtainable",
name: "Infernal Parade",
pp: 15,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 30,
status: "brn"
},
target: "normal",
type: "Ghost"
},
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, bypasssub: 1, allyanim: 1, failinstruct: 1 },
onHit(target, source) {
if (!target.lastMove || target.volatiles["dynamax"])
return false;
const lastMove = target.lastMove;
const moveIndex = target.moves.indexOf(lastMove.id);
if (lastMove.flags["failinstruct"] || lastMove.isZ || lastMove.isMax || lastMove.flags["charge"] || lastMove.flags["recharge"] || target.volatiles["beakblast"] || target.volatiles["focuspunch"] || target.volatiles["shelltrap"] || target.moveSlots[moveIndex] && target.moveSlots[moveIndex].pp <= 0) {
return false;
}
this.add("-singleturn", target, "move: Instruct", "[of] " + source);
this.queue.prioritizeAction(this.queue.resolveAction({
choice: "move",
pokemon: target,
moveid: target.lastMove.id,
targetLoc: target.lastMoveTargetLoc
})[0]);
},
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,
onFieldStart(target, source, sourceEffect) {
this.add("-fieldactivate", "move: Ion Deluge");
this.hint(`Normal-type moves become Electric-type after using ${sourceEffect}.`);
},
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: 10,
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"
},
jetpunch: {
num: 857,
accuracy: 100,
basePower: 60,
category: "Physical",
name: "Jet Punch",
pp: 15,
priority: 1,
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
secondary: null,
hasSheerForce: true,
target: "normal",
type: "Water",
contestType: "Cool"
},
judgment: {
num: 449,
accuracy: 100,
basePower: 100,
category: "Special",
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.conditions.get("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: { heal: 1, bypasssub: 1, allyanim: 1 },
onHit(pokemon) {
const success = !!this.heal(this.modify(pokemon.maxhp, 0.25));
return pokemon.cureStatus() || success;
},
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",
isNonstandard: "Past",
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",
isNonstandard: "Past",
name: "King's Shield",
pp: 10,
priority: 4,
flags: { noassist: 1, failcopycat: 1, failinstruct: 1 },
stallingMove: true,
volatileStatus: "kingsshield",
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"] || move.category === "Status") {
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
return;
if (move.isZ || move.isMax)
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) {
if (source.volatiles["lockedmove"].duration === 2) {
delete source.volatiles["lockedmove"];
}
}
if (this.checkMoveMakesContact(move, source, target)) {
this.boost({ atk: -1 }, source, target, this.dex.getActiveMove("King's Shield"));
}
return this.NOT_FAIL;
},
onHit(target, source, move) {
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
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.itemState, 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"
},
kowtowcleave: {
num: 869,
accuracy: true,
basePower: 85,
category: "Physical",
name: "Kowtow Cleave",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
secondary: null,
target: "normal",
type: "Dark"
},
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",
isNonstandard: "Past",
name: "Laser Focus",
pp: 30,
priority: 0,
flags: { snatch: 1 },
volatileStatus: "laserfocus",
condition: {
duration: 2,
onStart(pokemon, source, effect) {
if (effect && ["costar", "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.effectState.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(source) {
if (source.moveSlots.length < 2)
return false;
let hasLastResort = false;
for (const moveSlot of source.moveSlots) {
if (moveSlot.id === "lastresort") {
hasLastResort = true;
continue;
}
if (!moveSlot.used)
return false;
}
return hasLastResort;
},
secondary: null,
target: "normal",
type: "Normal",
contestType: "Cute"
},
lastrespects: {
num: 854,
accuracy: 100,
basePower: 50,
basePowerCallback(pokemon, target, move) {
return 50 + 50 * pokemon.side.totalFainted;
},
category: "Physical",
name: "Last Respects",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: null,
target: "normal",
type: "Ghost"
},
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, slicing: 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",
isNonstandard: "Past",
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.getAtSlot(pokemon.volatiles["leechseed"].sourceSlot);
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, bypasssub: 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 && this.effectState.target.hasAlly(target) && this.getCategory(move) === "Special") {
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
this.debug("Light Screen weaken");
if (this.activePerHalf > 1)
return this.chainModify([2732, 4096]);
return this.chainModify(0.5);
}
}
},
onSideStart(side) {
this.add("-sidestart", side, "move: Light Screen");
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 2,
onSideEnd(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.effectState.target && target === this.effectState.source)
return 0;
},
onSourceAccuracy(accuracy, target, source, move) {
if (move && source === this.effectState.target && target === this.effectState.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();
let bp;
if (targetWeight >= 2e3) {
bp = 120;
} else if (targetWeight >= 1e3) {
bp = 100;
} else if (targetWeight >= 500) {
bp = 80;
} else if (targetWeight >= 250) {
bp = 60;
} else if (targetWeight >= 100) {
bp = 40;
} else {
bp = 20;
}
this.debug("BP: " + bp);
return bp;
},
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,
onSideStart(side) {
this.add("-sidestart", side, "move: Lucky Chant");
},
onCriticalHit: false,
onSideResidualOrder: 26,
onSideResidualSubOrder: 6,
onSideEnd(side) {
this.add("-sideend", side, "move: Lucky Chant");
}
},
secondary: null,
target: "allySide",
type: "Normal",
zMove: { boost: { evasion: 1 } },
contestType: "Cute"
},
luminacrash: {
num: 855,
accuracy: 100,
basePower: 80,
category: "Special",
name: "Lumina Crash",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 100,
boosts: {
spd: -2
}
},
target: "normal",
type: "Psychic"
},
lunarblessing: {
num: 849,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Unobtainable",
name: "Lunar Blessing",
pp: 5,
priority: 0,
flags: { snatch: 1, heal: 1 },
onHit(pokemon) {
const success = !!this.heal(this.modify(pokemon.maxhp, 0.25));
return pokemon.cureStatus() || success;
},
secondary: null,
target: "allies",
type: "Psychic"
},
lunardance: {
num: 461,
accuracy: true,
basePower: 0,
category: "Status",
name: "Lunar Dance",
pp: 10,
priority: 0,
flags: { snatch: 1, heal: 1, dance: 1 },
onTryHit(source) {
if (!this.canSwitch(source.side)) {
this.attrLastMove("[still]");
this.add("-fail", source);
return this.NOT_FAIL;
}
},
selfdestruct: "ifHit",
slotCondition: "lunardance",
condition: {
onSwap(target) {
if (!target.fainted && (target.hp < target.maxhp || target.status || target.moveSlots.some((moveSlot) => moveSlot.pp < moveSlot.maxpp))) {
target.heal(target.maxhp);
target.clearStatus();
for (const moveSlot of target.moveSlots) {
moveSlot.pp = moveSlot.maxpp;
}
this.add("-heal", target, target.getHealth, "[from] move: Lunar Dance");
target.side.removeSlotCondition(target, "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"
},
magicaltorque: {
num: 900,
accuracy: 100,
basePower: 100,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Magical Torque",
pp: 10,
priority: 0,
flags: {
protect: 1,
failencore: 1,
failmefirst: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 1
},
secondary: {
chance: 30,
volatileStatus: "confusion"
},
target: "normal",
type: "Fairy"
},
magiccoat: {
num: 277,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Past",
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.effectState.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.effectState.pranksterBoosted;
this.actions.useMove(newMove, target, source);
return null;
},
onAllyTryHitSide(target, source, move) {
if (target.isAlly(source) || move.hasBounced || !move.flags["reflectable"]) {
return;
}
const newMove = this.dex.getActiveMove(move.id);
newMove.hasBounced = true;
newMove.pranksterBoosted = false;
this.actions.useMove(newMove, this.effectState.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, allyanim: 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", "[move] Magic Room");
return 7;
}
return 5;
},
onFieldStart(target, source) {
if (source?.hasAbility("persistent")) {
this.add("-fieldstart", "move: Magic Room", "[of] " + source, "[persistent]");
} else {
this.add("-fieldstart", "move: Magic Room", "[of] " + source);
}
for (const mon of this.getAllActive()) {
this.singleEvent("End", mon.getItem(), mon.itemState, mon);
}
},
onFieldRestart(target, source) {
this.field.removePseudoWeather("magicroom");
},
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 6,
onFieldEnd() {
this.add("-fieldend", "move: Magic Room", "[of] " + this.effectState.source);
}
},
secondary: null,
target: "all",
type: "Psychic",
zMove: { boost: { spd: 1 } },
contestType: "Clever"
},
magmastorm: {
num: 463,
accuracy: 75,
basePower: 100,
category: "Special",
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, bypasssub: 1 },
onHitSide(side, source, move) {
const targets = side.allies().filter((ally) => ally.hasAbility(["plus", "minus"]) && (!ally.volatiles["maxguard"] || this.runEvent("TryHit", ally, source, move)));
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",
onTry(source, target, move) {
if (target.volatiles["smackdown"] || target.volatiles["ingrain"])
return false;
if (this.field.getPseudoWeather("Gravity")) {
this.add("cant", source, "move: Gravity", move);
return null;
}
},
condition: {
duration: 5,
onStart(target) {
this.add("-start", target, "Magnet Rise");
},
onImmunity(type) {
if (type === "Ground")
return false;
},
onResidualOrder: 18,
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"
},
makeitrain: {
num: 874,
accuracy: 100,
basePower: 120,
category: "Special",
name: "Make It Rain",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
self: {
boosts: {
spa: -1
}
},
secondary: null,
target: "allAdjacentFoes",
type: "Steel",
contestType: "Beautiful"
},
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",
isNonstandard: "Past",
name: "Mat Block",
pp: 10,
priority: 0,
flags: { snatch: 1, nonsky: 1, noassist: 1, failcopycat: 1 },
stallingMove: true,
sideCondition: "matblock",
onTry(source) {
if (source.activeMoveActions > 1) {
this.hint("Mat Block only works on your first turn out.");
return false;
}
return !!this.queue.willAct();
},
condition: {
duration: 1,
onSideStart(target, source) {
this.add("-singleturn", source, "Mat Block");
},
onTryHitPriority: 3,
onTryHit(target, source, move) {
if (!move.flags["protect"]) {
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
return;
if (move.isZ || move.isMax)
target.getMoveHitData(move).zBrokeProtect = true;
return;
}
if (move && (move.target === "self" || move.category === "Status"))
return;
this.add("-activate", target, "move: Mat Block", move.name);
const lockedmove = source.getVolatile("lockedmove");
if (lockedmove) {
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",
isNonstandard: "Past",
name: "Max Airstream",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.alliesAndSelf()) {
this.boost({ spe: 1 }, pokemon);
}
}
},
target: "adjacentFoe",
type: "Flying",
contestType: "Cool"
},
maxdarkness: {
num: 772,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Past",
name: "Max Darkness",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.foes()) {
this.boost({ spd: -1 }, pokemon);
}
}
},
target: "adjacentFoe",
type: "Dark",
contestType: "Cool"
},
maxflare: {
num: 757,
accuracy: true,
basePower: 100,
category: "Physical",
isNonstandard: "Past",
name: "Max Flare",
pp: 10,
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",
isNonstandard: "Past",
name: "Max Flutterby",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.foes()) {
this.boost({ spa: -1 }, pokemon);
}
}
},
target: "adjacentFoe",
type: "Bug",
contestType: "Cool"
},
maxgeyser: {
num: 765,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Past",
name: "Max Geyser",
pp: 10,
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",
isNonstandard: "Past",
name: "Max Guard",
pp: 10,
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) {
const bypassesMaxGuard = [
"acupressure",
"afteryou",
"allyswitch",
"aromatherapy",
"aromaticmist",
"coaching",
"confide",
"copycat",
"curse",
"decorate",
"doomdesire",
"feint",
"futuresight",
"gmaxoneblow",
"gmaxrapidflow",
"healbell",
"holdhands",
"howl",
"junglehealing",
"lifedew",
"meanlook",
"perishsong",
"playnice",
"powertrick",
"roar",
"roleplay",
"tearfullook"
];
if (bypassesMaxGuard.includes(move.id))
return;
if (move.smartTarget) {
move.smartTarget = false;
} else {
this.add("-activate", target, "move: Max Guard");
}
const lockedmove = source.getVolatile("lockedmove");
if (lockedmove) {
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",
isNonstandard: "Past",
name: "Max Hailstorm",
pp: 10,
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",
isNonstandard: "Past",
name: "Max Knuckle",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.alliesAndSelf()) {
this.boost({ atk: 1 }, pokemon);
}
}
},
target: "adjacentFoe",
type: "Fighting",
contestType: "Cool"
},
maxlightning: {
num: 759,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Past",
name: "Max Lightning",
pp: 10,
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",
isNonstandard: "Past",
name: "Max Mindstorm",
pp: 10,
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",
isNonstandard: "Past",
name: "Max Ooze",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.alliesAndSelf()) {
this.boost({ spa: 1 }, pokemon);
}
}
},
target: "adjacentFoe",
type: "Poison",
contestType: "Cool"
},
maxovergrowth: {
num: 773,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Past",
name: "Max Overgrowth",
pp: 10,
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",
isNonstandard: "Past",
name: "Max Phantasm",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.foes()) {
this.boost({ def: -1 }, pokemon);
}
}
},
target: "adjacentFoe",
type: "Ghost",
contestType: "Cool"
},
maxquake: {
num: 771,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Past",
name: "Max Quake",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.alliesAndSelf()) {
this.boost({ spd: 1 }, pokemon);
}
}
},
target: "adjacentFoe",
type: "Ground",
contestType: "Cool"
},
maxrockfall: {
num: 770,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Past",
name: "Max Rockfall",
pp: 10,
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",
isNonstandard: "Past",
name: "Max Starfall",
pp: 10,
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",
isNonstandard: "Past",
name: "Max Steelspike",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.alliesAndSelf()) {
this.boost({ def: 1 }, pokemon);
}
}
},
target: "adjacentFoe",
type: "Steel",
contestType: "Cool"
},
maxstrike: {
num: 760,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Past",
name: "Max Strike",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.foes()) {
this.boost({ spe: -1 }, pokemon);
}
}
},
target: "adjacentFoe",
type: "Normal",
contestType: "Cool"
},
maxwyrmwind: {
num: 768,
accuracy: true,
basePower: 10,
category: "Physical",
isNonstandard: "Past",
name: "Max Wyrmwind",
pp: 10,
priority: 0,
flags: {},
isMax: true,
self: {
onHit(source) {
if (!source.volatiles["dynamax"])
return;
for (const pokemon of source.foes()) {
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,
bypasssub: 1,
failencore: 1,
failmefirst: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 1
},
onTryHit(target, pokemon) {
const action = this.queue.willMove(target);
if (!action)
return false;
const move = this.dex.getActiveMove(action.move.id);
if (action.zmove || move.isZ || move.isMax)
return false;
if (target.volatiles["mustrecharge"])
return false;
if (move.category === "Status" || move.flags["failmefirst"])
return false;
pokemon.addVolatile("mefirst");
this.actions.useMove(move, pokemon, target);
return null;
},
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) {
const lastDamagedBy = pokemon.getLastDamagedBy(true);
if (lastDamagedBy !== void 0) {
return lastDamagedBy.damage * 1.5 || 1;
}
return 0;
},
category: "Physical",
name: "Metal Burst",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, failmefirst: 1 },
onTry(source) {
const lastDamagedBy = source.getLastDamagedBy(true);
if (lastDamagedBy === void 0 || !lastDamagedBy.thisTurn)
return false;
},
onModifyTarget(targetRelayVar, source, target, move) {
const lastDamagedBy = source.getLastDamagedBy(true);
if (lastDamagedBy) {
targetRelayVar.target = this.getAtSlot(lastDamagedBy.slot);
}
},
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, bypasssub: 1, allyanim: 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",
isNonstandard: "Past",
name: "Meteor Assault",
pp: 5,
priority: 0,
flags: { protect: 1, recharge: 1, mirror: 1, failinstruct: 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: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
noMetronome: [
"After You",
"Apple Acid",
"Armor Cannon",
"Assist",
"Astral Barrage",
"Aura Wheel",
"Baneful Bunker",
"Beak Blast",
"Behemoth Bash",
"Behemoth Blade",
"Belch",
"Bestow",
"Blazing Torque",
"Body Press",
"Branch Poke",
"Breaking Swipe",
"Celebrate",
"Chatter",
"Chilling Water",
"Chilly Reception",
"Clangorous Soul",
"Collision Course",
"Combat Torque",
"Comeuppance",
"Copycat",
"Counter",
"Covet",
"Crafty Shield",
"Decorate",
"Destiny Bond",
"Detect",
"Diamond Storm",
"Doodle",
"Double Iron Bash",
"Double Shock",
"Dragon Ascent",
"Dragon Energy",
"Drum Beating",
"Dynamax Cannon",
"Electro Drift",
"Endure",
"Eternabeam",
"False Surrender",
"Feint",
"Fiery Wrath",
"Fillet Away",
"Fleur Cannon",
"Focus Punch",
"Follow Me",
"Freeze Shock",
"Freezing Glare",
"Glacial Lance",
"Grav Apple",
"Helping Hand",
"Hold Hands",
"Hyper Drill",
"Hyperspace Fury",
"Hyperspace Hole",
"Ice Burn",
"Instruct",
"Jet Punch",
"Jungle Healing",
"King's Shield",
"Life Dew",
"Light of Ruin",
"Magical Torque",
"Make It Rain",
"Mat Block",
"Me First",
"Meteor Assault",
"Metronome",
"Mimic",
"Mind Blown",
"Mirror Coat",
"Mirror Move",
"Moongeist Beam",
"Nature Power",
"Nature's Madness",
"Noxious Torque",
"Obstruct",
"Order Up",
"Origin Pulse",
"Overdrive",
"Photon Geyser",
"Plasma Fists",
"Population Bomb",
"Pounce",
"Power Shift",
"Precipice Blades",
"Protect",
"Pyro Ball",
"Quash",
"Quick Guard",
"Rage Fist",
"Rage Powder",
"Raging Bull",
"Raging Fury",
"Relic Song",
"Revival Blessing",
"Ruination",
"Salt Cure",
"Secret Sword",
"Shed Tail",
"Shell Trap",
"Silk Trap",
"Sketch",
"Sleep Talk",
"Snap Trap",
"Snarl",
"Snatch",
"Snore",
"Snowscape",
"Spectral Thief",
"Spicy Extract",
"Spiky Shield",
"Spirit Break",
"Spotlight",
"Springtide Storm",
"Steam Eruption",
"Steel Beam",
"Strange Steam",
"Struggle",
"Sunsteel Strike",
"Surging Strikes",
"Switcheroo",
"Techno Blast",
"Thief",
"Thousand Arrows",
"Thousand Waves",
"Thunder Cage",
"Thunderous Kick",
"Tidy Up",
"Trailblaze",
"Transform",
"Trick",
"Twin Beam",
"V-create",
"Wicked Blow",
"Wicked Torque",
"Wide Guard"
],
onHit(target, source, effect) {
const moves = this.dex.moves.all().filter((move) => (![2, 4].includes(this.gen) || !source.moves.includes(move.id)) && !move.realMove && !move.isZ && !move.isMax && (!move.isNonstandard || move.isNonstandard === "Unobtainable") && !effect.noMetronome.includes(move.name));
let randomMove = "";
if (moves.length) {
moves.sort((a, b) => a.num - b.num);
randomMove = this.sample(moves).id;
}
if (!randomMove)
return false;
source.side.lastSelectedMove = this.toID(randomMove);
this.actions.useMove(randomMove, target);
},
secondary: null,
target: "self",
type: "Normal",
contestType: "Cute"
},
milkdrink: {
num: 208,
accuracy: true,
basePower: 0,
category: "Status",
name: "Milk Drink",
pp: 5,
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,
bypasssub: 1,
allyanim: 1,
failencore: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 1
},
onHit(target, source) {
const move = target.lastMove;
if (source.transformed || !move || move.flags["failmimic"] || source.moves.includes(move.id)) {
return false;
}
if (move.isZ || move.isMax)
return false;
const mimicIndex = source.moves.indexOf("mimic");
if (mimicIndex < 0)
return false;
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) {
const hpBeforeRecoil = pokemon.hp;
this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.conditions.get("Mind Blown"), true);
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
this.runEvent("EmergencyExit", pokemon, pokemon);
}
}
},
secondary: null,
target: "allAdjacent",
type: "Fire",
contestType: "Cool"
},
mindreader: {
num: 170,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Past",
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,
onRestart: () => null,
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, bypasssub: 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, failmefirst: 1, noassist: 1 },
beforeTurnCallback(pokemon) {
pokemon.addVolatile("mirrorcoat");
},
onTry(source) {
if (!source.volatiles["mirrorcoat"])
return false;
if (source.volatiles["mirrorcoat"].slot === null)
return false;
},
condition: {
duration: 1,
noCopy: true,
onStart(target, source, move) {
this.effectState.slot = null;
this.effectState.damage = 0;
},
onRedirectTargetPriority: -1,
onRedirectTarget(target, source, source2, move) {
if (move.id !== "mirrorcoat")
return;
if (source !== this.effectState.target || !this.effectState.slot)
return;
return this.getAtSlot(this.effectState.slot);
},
onDamagingHit(damage, target, source, move) {
if (!source.isAlly(target) && this.getCategory(move) === "Special") {
this.effectState.slot = source.getSlot();
this.effectState.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: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
onTryHit(target, pokemon) {
const move = target.lastMove;
if (!move?.flags["mirror"] || move.isZ || move.isMax) {
return false;
}
this.actions.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,
onTryBoost(boost, target, source, effect) {
if (effect.effectType === "Move" && effect.infiltrates && !target.isAlly(source))
return;
if (source && target !== source) {
let showMsg = false;
let i;
for (i in boost) {
if (boost[i] < 0) {
delete boost[i];
showMsg = true;
}
}
if (showMsg && !effect.secondaries) {
this.add("-activate", target, "move: Mist");
}
}
},
onSideStart(side) {
this.add("-sidestart", side, "Mist");
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 4,
onSideEnd(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.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);
}
},
onFieldStart(field, source, effect) {
if (effect?.effectType === "Ability") {
this.add("-fieldstart", "move: Misty Terrain", "[from] ability: " + effect.name, "[of] " + source);
} else {
this.add("-fieldstart", "move: Misty Terrain");
}
},
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 7,
onFieldEnd() {
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",
isNonstandard: "Past",
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":
case "snow":
factor = 0.25;
break;
}
const success = !!this.heal(this.modify(pokemon.maxhp, factor));
if (!success) {
this.add("-fail", pokemon, "heal");
return this.NOT_FAIL;
}
return success;
},
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":
case "snow":
factor = 0.25;
break;
}
const success = !!this.heal(this.modify(pokemon.maxhp, factor));
if (!success) {
this.add("-fail", pokemon, "heal");
return this.NOT_FAIL;
}
return success;
},
secondary: null,
target: "self",
type: "Normal",
zMove: { effect: "clearnegativeboost" },
contestType: "Beautiful"
},
mortalspin: {
num: 866,
accuracy: 100,
basePower: 30,
category: "Physical",
name: "Mortal Spin",
pp: 15,
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: Mortal 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.conditions.get(condition).name, "[from] move: Mortal 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: Mortal 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.conditions.get(condition).name, "[from] move: Mortal Spin", "[of] " + pokemon);
}
}
if (pokemon.hp && pokemon.volatiles["partiallytrapped"]) {
pokemon.removeVolatile("partiallytrapped");
}
},
secondary: {
chance: 100,
status: "psn"
},
target: "allAdjacentFoes",
type: "Poison"
},
mountaingale: {
num: 836,
accuracy: 85,
basePower: 100,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Mountain Gale",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 30,
volatileStatus: "flinch"
},
target: "normal",
type: "Ice"
},
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,
onFieldStart(field, 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([1352, 4096]);
}
},
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 4,
onFieldEnd() {
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",
isNonstandard: "Past",
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"
},
mysticalpower: {
num: 832,
accuracy: 90,
basePower: 70,
category: "Special",
isNonstandard: "Unobtainable",
name: "Mystical Power",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: {
chance: 100,
self: {
boosts: {
spa: 1
}
}
},
target: "normal",
type: "Psychic"
},
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;
this.debug("BP: " + move.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",
isNonstandard: "Past",
name: "Nature Power",
pp: 20,
priority: 0,
flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
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.actions.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: 11,
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, slicing: 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, bypasssub: 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",
onTry(source, target, move) {
if (source.volatiles["noretreat"])
return false;
if (source.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"
},
noxioustorque: {
num: 898,
accuracy: 100,
basePower: 100,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Noxious Torque",
pp: 10,
priority: 0,
flags: {
protect: 1,
failencore: 1,
failmefirst: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 1
},
secondary: {
chance: 30,
status: "psn"
},
target: "normal",
type: "Poison"
},
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: 100,
basePower: 0,
category: "Status",
isNonstandard: "Past",
name: "Obstruct",
pp: 10,
priority: 4,
flags: { failinstruct: 1 },
stallingMove: true,
volatileStatus: "obstruct",
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"] || move.category === "Status") {
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
return;
if (move.isZ || move.isMax)
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) {
if (source.volatiles["lockedmove"].duration === 2) {
delete source.volatiles["lockedmove"];
}
}
if (this.checkMoveMakesContact(move, source, target)) {
this.boost({ def: -2 }, source, target, this.dex.getActiveMove("Obstruct"));
}
return this.NOT_FAIL;
},
onHit(target, source, move) {
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
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",
isNonstandard: "Past",
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",
isNonstandard: "Past",
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: 14,
onResidual(pokemon) {
const source = this.effectState.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.effectState.source && this.effectState.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, bypasssub: 1, allyanim: 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"
},
orderup: {
num: 856,
accuracy: 100,
basePower: 80,
category: "Physical",
name: "Order Up",
pp: 10,
priority: 0,
flags: { protect: 1 },
onAfterMoveSecondarySelf(pokemon, target, move) {
if (!pokemon.volatiles["commanded"])
return;
const tatsugiri = pokemon.volatiles["commanded"].source;
if (tatsugiri.baseSpecies.baseSpecies !== "Tatsugiri")
return;
switch (tatsugiri.baseSpecies.forme) {
case "Droopy":
this.boost({ def: 1 }, pokemon, pokemon);
break;
case "Stretchy":
this.boost({ spe: 1 }, pokemon, pokemon);
break;
default:
this.boost({ atk: 1 }, pokemon, pokemon);
break;
}
},
secondary: null,
hasSheerForce: true,
target: "normal",
type: "Dragon"
},
originpulse: {
num: 618,
accuracy: 85,
basePower: 110,
category: "Special",
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, failinstruct: 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, bypasssub: 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, allyanim: 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, bypasssub: 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 },
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, bypasssub: 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: 24,
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, wind: 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, failinstruct: 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, nosleeptalk: 1, noassist: 1, failinstruct: 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",
isNonstandard: "Past",
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) {
const bp = Math.floor(pokemon.happiness * 10 / 25) || 1;
this.debug("BP: " + bp);
return bp;
},
category: "Special",
isNonstandard: "LGPE",
name: "Pika Papow",
pp: 20,
priority: 0,
flags: { protect: 1, mirror: 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",
isNonstandard: "Past",
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, bypasssub: 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, allyanim: 1 },
onTryHit(target, source, move) {
if (source.isAlly(target)) {
move.basePower = 0;
move.infiltrates = true;
}
},
onHit(target, source) {
if (source.isAlly(target)) {
if (!this.heal(Math.floor(target.baseMaxhp * 0.5))) {
this.add("-immune", target);
return this.NOT_FAIL;
}
}
},
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(source, target) {
return !!target.item;
},
onTryHit(target, source, move) {
this.add("-activate", target, "move: Poltergeist", this.dex.items.get(target.item).name);
},
secondary: null,
target: "normal",
type: "Ghost"
},
populationbomb: {
num: 860,
accuracy: 90,
basePower: 20,
category: "Physical",
name: "Population Bomb",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
multihit: 10,
multiaccuracy: true,
secondary: null,
target: "normal",
type: "Normal"
},
pounce: {
num: 884,
accuracy: 100,
basePower: 50,
category: "Physical",
name: "Pounce",
pp: 20,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
secondary: {
chance: 100,
boosts: {
spe: -1
}
},
target: "normal",
type: "Bug",
contestType: "Cute"
},
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, bypasssub: 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));
this.attrLastMove("[still]");
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"
},
powershift: {
num: 829,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Unobtainable",
name: "Power Shift",
pp: 10,
priority: 0,
flags: { snatch: 1 },
volatileStatus: "powershift",
condition: {
onStart(pokemon) {
this.add("-start", pokemon, "Power Shift");
[
pokemon.storedStats.atk,
pokemon.storedStats.spa,
pokemon.storedStats.def,
pokemon.storedStats.spd
] = [
pokemon.storedStats.def,
pokemon.storedStats.spd,
pokemon.storedStats.atk,
pokemon.storedStats.spa
];
},
onCopy(pokemon) {
[
pokemon.storedStats.atk,
pokemon.storedStats.spa,
pokemon.storedStats.def,
pokemon.storedStats.spd
] = [
pokemon.storedStats.def,
pokemon.storedStats.spd,
pokemon.storedStats.atk,
pokemon.storedStats.spa
];
},
onEnd(pokemon) {
this.add("-end", pokemon, "Power Shift");
[
pokemon.storedStats.atk,
pokemon.storedStats.spa,
pokemon.storedStats.def,
pokemon.storedStats.spd
] = [
pokemon.storedStats.def,
pokemon.storedStats.spd,
pokemon.storedStats.atk,
pokemon.storedStats.spa
];
},
onRestart(pokemon) {
pokemon.removeVolatile("Power Shift");
}
},
secondary: null,
target: "self",
type: "Normal"
},
powersplit: {
num: 471,
accuracy: true,
basePower: 0,
category: "Status",
name: "Power Split",
pp: 10,
priority: 0,
flags: { protect: 1, allyanim: 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, bypasssub: 1, allyanim: 1 },
onHit(target, source) {
const targetBoosts = {};
const sourceBoosts = {};
const atkSpa = ["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) {
const bp = move.basePower + 20 * pokemon.positiveBoosts();
this.debug("BP: " + bp);
return bp;
},
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",
isNonstandard: "Past",
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",
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];
move.infiltrates = true;
} 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",
isNonstandard: "Past",
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: { noassist: 1, failcopycat: 1 },
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 (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
return;
if (move.isZ || move.isMax)
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) {
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"
},
psyblade: {
num: 875,
accuracy: 100,
basePower: 80,
category: "Physical",
name: "Psyblade",
pp: 15,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
secondary: null,
onBasePower(basePower, source) {
if (this.field.isTerrain("electricterrain")) {
this.debug("psyblade electric terrain boost");
return this.chainModify(1.5);
}
},
target: "normal",
type: "Psychic"
},
psychup: {
num: 244,
accuracy: true,
basePower: 0,
category: "Status",
name: "Psych Up",
pp: 10,
priority: 0,
flags: { bypasssub: 1, allyanim: 1 },
onHit(target, source) {
let i;
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) {
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.isAlly(source))
return;
if (!target.isGrounded()) {
const baseMove = this.dex.moves.get(effect.id);
if (baseMove.priority > 0) {
this.hint("Psychic Terrain doesn't affect Pok\xE9mon 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([5325, 4096]);
}
},
onFieldStart(field, source, effect) {
if (effect?.effectType === "Ability") {
this.add("-fieldstart", "move: Psychic Terrain", "[from] ability: " + effect.name, "[of] " + source);
} else {
this.add("-fieldstart", "move: Psychic Terrain");
}
},
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 7,
onFieldEnd() {
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, slicing: 1 },
critRatio: 2,
secondary: null,
target: "normal",
type: "Psychic",
contestType: "Cool"
},
psychoshift: {
num: 375,
accuracy: 100,
basePower: 0,
category: "Status",
isNonstandard: "Past",
name: "Psycho Shift",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
onTryHit(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"
},
psyshieldbash: {
num: 828,
accuracy: 90,
basePower: 70,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Psyshield Bash",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
secondary: {
chance: 100,
self: {
boosts: {
def: 1
}
}
},
target: "normal",
type: "Psychic"
},
psyshock: {
num: 473,
accuracy: 100,
basePower: 80,
category: "Special",
overrideDefensiveStat: "def",
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",
overrideDefensiveStat: "def",
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;
this.debug("BP: " + power);
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",
isNonstandard: "Past",
name: "Purify",
pp: 20,
priority: 0,
flags: { protect: 1, reflectable: 1, heal: 1 },
onHit(target, source) {
if (!target.cureStatus()) {
this.add("-fail", source);
this.attrLastMove("[still]");
return this.NOT_FAIL;
}
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) {
if (target.beingCalledBack || target.switchFlag) {
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.hasAlly(pokemon))
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 || target?.switchFlag)
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.effectState.sources) {
if (!source.isAdjacent(pokemon) || !this.queue.cancelMove(source) || !source.hp)
continue;
if (!alreadyAdded) {
this.add("-activate", pokemon, "move: Pursuit");
alreadyAdded = true;
}
if (source.canMegaEvo || source.canUltraBurst) {
for (const [actionIndex, action] of this.queue.entries()) {
if (action.pokemon === source && action.choice === "megaEvo") {
this.actions.runMegaEvo(source);
this.queue.list.splice(actionIndex, 1);
break;
}
}
}
this.actions.runMove("pursuit", source, source.getLocOf(pokemon));
}
}
},
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 (this.activePerHalf === 1)
return false;
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",
onTry() {
return !!this.queue.willAct();
},
onHitSide(side, source) {
source.addVolatile("stall");
},
condition: {
duration: 1,
onSideStart(target, source) {
this.add("-singleturn", source, "Quick Guard");
},
onTryHitPriority: 4,
onTryHit(target, source, move) {
if (move.priority <= 0.1)
return;
if (!move.flags["protect"]) {
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
return;
if (move.isZ || move.isMax)
target.getMoveHitData(move).zBrokeProtect = true;
return;
}
this.add("-activate", target, "move: Quick Guard");
const lockedmove = source.getVolatile("lockedmove");
if (lockedmove) {
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"
},
ragefist: {
num: 889,
accuracy: 100,
basePower: 50,
basePowerCallback(pokemon) {
return Math.min(350, 50 + 50 * pokemon.timesAttacked);
},
category: "Physical",
name: "Rage Fist",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
secondary: null,
target: "normal",
type: "Ghost"
},
ragepowder: {
num: 476,
accuracy: true,
basePower: 0,
category: "Status",
name: "Rage Powder",
pp: 20,
priority: 2,
flags: { powder: 1, noassist: 1, failcopycat: 1 },
volatileStatus: "ragepowder",
onTry(source) {
return this.activePerHalf > 1;
},
condition: {
duration: 1,
onStart(pokemon) {
this.add("-singleturn", pokemon, "move: Rage Powder");
},
onFoeRedirectTargetPriority: 1,
onFoeRedirectTarget(target, source, source2, move) {
const ragePowderUser = this.effectState.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"
},
ragingbull: {
num: 873,
accuracy: 100,
basePower: 90,
category: "Physical",
name: "Raging Bull",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
onTryHit(pokemon) {
pokemon.side.removeSideCondition("reflect");
pokemon.side.removeSideCondition("lightscreen");
pokemon.side.removeSideCondition("auroraveil");
},
onModifyType(move, pokemon) {
switch (pokemon.species.name) {
case "Tauros-Paldea-Combat":
move.type = "Fighting";
break;
case "Tauros-Paldea-Blaze":
move.type = "Fire";
break;
case "Tauros-Paldea-Aqua":
move.type = "Water";
break;
}
},
secondary: null,
target: "normal",
type: "Normal"
},
ragingfury: {
num: 833,
accuracy: 100,
basePower: 120,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Raging Fury",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
self: {
volatileStatus: "lockedmove"
},
onAfterMove(pokemon) {
if (pokemon.volatiles["lockedmove"]?.duration === 1) {
pokemon.removeVolatile("lockedmove");
}
},
secondary: null,
target: "randomNormal",
type: "Fire"
},
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.conditions.get(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.conditions.get(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, slicing: 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, slicing: 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, nosleeptalk: 1, failinstruct: 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: 5,
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.items.get(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 && this.effectState.target.hasAlly(target) && this.getCategory(move) === "Physical") {
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
this.debug("Reflect weaken");
if (this.activePerHalf > 1)
return this.chainModify([2732, 4096]);
return this.chainModify(0.5);
}
}
},
onSideStart(side) {
this.add("-sidestart", side, "Reflect");
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 1,
onSideEnd(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, bypasssub: 1, allyanim: 1 },
onHit(target, source) {
if (source.species && (source.species.num === 493 || source.species.num === 773))
return false;
if (source.terastallized)
return false;
const oldApparentType = source.apparentType;
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.isAlly(source) && target.knownType;
if (!source.knownType)
source.apparentType = oldApparentType;
},
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",
name: "Relic Song",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 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: 5,
priority: 0,
flags: { snatch: 1, heal: 1 },
onTry(source) {
if (source.status === "slp" || source.hasAbility("comatose"))
return false;
if (source.hp === source.maxhp) {
this.add("-fail", source, "heal");
return null;
}
if (source.hasAbility(["insomnia", "vitalspirit"])) {
this.add("-fail", source, "[from] ability: " + source.getAbility().name, "[of] " + source);
return null;
}
},
onHit(target, source, move) {
const result = target.setStatus("slp", source, move);
if (!result)
return result;
target.statusState.time = 3;
target.statusState.startTime = 3;
this.heal(target.maxhp);
},
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",
name: "Revelation Dance",
pp: 15,
priority: 0,
flags: { protect: 1, mirror: 1, dance: 1 },
onModifyType(move, pokemon) {
let type = pokemon.getTypes()[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("BP doubled for getting hit by " + target);
return move.basePower * 2;
}
return move.basePower;
},
category: "Physical",
isNonstandard: "Past",
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 = Math.max(Math.floor(pokemon.hp * 48 / pokemon.maxhp), 1);
let bp;
if (ratio < 2) {
bp = 200;
} else if (ratio < 5) {
bp = 150;
} else if (ratio < 10) {
bp = 100;
} else if (ratio < 17) {
bp = 80;
} else if (ratio < 33) {
bp = 40;
} else {
bp = 20;
}
this.debug("BP: " + bp);
return bp;
},
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"
},
revivalblessing: {
num: 863,
accuracy: true,
basePower: 0,
category: "Status",
name: "Revival Blessing",
pp: 1,
noPPBoosts: true,
priority: 0,
flags: {},
onTryHit(source) {
if (!source.side.pokemon.filter((ally) => ally.fainted).length) {
return false;
}
},
slotCondition: "revivalblessing",
// No this not a real switchout move
// This is needed to trigger a switch protocol to choose a fainted party member
// Feel free to refactor
selfSwitch: true,
condition: {
duration: 1
// reviving implemented in side.ts, kind of
},
secondary: null,
target: "self",
type: "Normal"
},
risingvoltage: {
num: 804,
accuracy: 100,
basePower: 70,
basePowerCallback(source, target, move) {
if (this.field.isTerrain("electricterrain") && target.isGrounded()) {
if (!source.isAlly(target))
this.hint(`${move.name}'s BP doubled on grounded target.`);
return move.basePower * 2;
}
return move.basePower;
},
category: "Special",
name: "Rising Voltage",
pp: 20,
priority: 0,
flags: { protect: 1, mirror: 1 },
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, bypasssub: 1, allyanim: 1, noassist: 1, failcopycat: 1 },
forceSwitch: true,
secondary: null,
target: "normal",
type: "Normal",
zMove: { boost: { def: 1 } },
contestType: "Cool"
},
roaroftime: {
num: 459,
accuracy: 90,
basePower: 150,
category: "Special",
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",
isNonstandard: "Past",
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: { bypasssub: 1, allyanim: 1 },
onTryHit(target, source) {
if (target.ability === source.ability)
return false;
const additionalBannedTargetAbilities = [
// Zen Mode included here for compatability with Gen 5-6
"flowergift",
"forecast",
"hungerswitch",
"illusion",
"imposter",
"neutralizinggas",
"powerofalchemy",
"receiver",
"trace",
"wonderguard",
"zenmode"
];
if (target.getAbility().isPermanent || additionalBannedTargetAbilities.includes(target.ability) || source.getAbility().isPermanent) {
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 oldAbility;
},
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;
const rolloutData = pokemon.volatiles["rollout"];
if (rolloutData?.hitCount) {
bp *= Math.pow(2, rolloutData.contactHitCount);
}
if (rolloutData && pokemon.status !== "slp") {
rolloutData.hitCount++;
rolloutData.contactHitCount++;
if (rolloutData.hitCount < 5) {
rolloutData.duration = 2;
}
}
if (pokemon.volatiles["defensecurl"]) {
bp *= 2;
}
this.debug("BP: " + bp);
return bp;
},
category: "Physical",
name: "Rollout",
pp: 20,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, noparentalbond: 1, failinstruct: 1 },
onModifyMove(move, pokemon, target) {
if (pokemon.volatiles["rollout"] || pokemon.status === "slp" || !target)
return;
pokemon.addVolatile("rollout");
pokemon.volatiles["rollout"].targetSlot = move.sourceEffect ? pokemon.lastMoveTargetLoc : pokemon.getLocOf(target);
},
onAfterMove(source, target, move) {
const rolloutData = source.volatiles["rollout"];
if (rolloutData && rolloutData.hitCount === 5 && rolloutData.contactHitCount < 5) {
source.addVolatile("rolloutstorage");
source.volatiles["rolloutstorage"].contactHitCount = rolloutData.contactHitCount;
}
},
condition: {
duration: 1,
onLockMove: "rollout",
onStart() {
this.effectState.hitCount = 0;
this.effectState.contactHitCount = 0;
},
onResidual(target) {
if (target.lastMove && target.lastMove.id === "struggle") {
delete target.volatiles["rollout"];
}
}
},
secondary: null,
target: "normal",
type: "Rock",
contestType: "Cute"
},
roost: {
num: 355,
accuracy: true,
basePower: 0,
category: "Status",
name: "Roost",
pp: 5,
priority: 0,
flags: { snatch: 1, heal: 1 },
heal: [1, 2],
self: {
volatileStatus: "roost"
},
condition: {
duration: 1,
onResidualOrder: 25,
onStart(target) {
if (!target.terastallized) {
this.add("-singleturn", target, "move: Roost");
} else if (target.terastallized === "Flying") {
this.add("-hint", "If a Flying Terastallized Pokemon uses Roost, it remains Flying-type.");
}
},
onTypePriority: -1,
onType(types, pokemon) {
this.effectState.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 = [];
let anyAirborne = false;
for (const pokemon of this.getAllActive()) {
if (!pokemon.runImmunity("Ground")) {
this.add("-immune", pokemon);
anyAirborne = true;
continue;
}
if (pokemon.hasType("Grass")) {
targets.push(pokemon);
}
}
if (!targets.length && !anyAirborne)
return false;
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") {
this.debug("BP doubled");
return move.basePower * 2;
}
return move.basePower;
},
category: "Special",
name: "Round",
pp: 15,
priority: 0,
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
onTry(source, target, move) {
for (const action of this.queue.list) {
if (!action.pokemon || !action.move || action.maxMove || action.zmove)
continue;
if (action.move.id === "round") {
this.queue.prioritizeAction(action, move);
return;
}
}
},
secondary: null,
target: "normal",
type: "Normal",
contestType: "Beautiful"
},
ruination: {
num: 877,
accuracy: 90,
basePower: 0,
damageCallback(pokemon, target) {
return this.clampIntRange(Math.floor(target.getUndynamaxedHP() / 2), 1);
},
category: "Special",
name: "Ruination",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: null,
target: "normal",
type: "Dark",
contestType: "Tough"
},
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, slicing: 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", "[move] Safeguard");
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.isAlly(source))
return;
if (target !== source) {
this.debug("interrupting setStatus");
if (effect.name === "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.isAlly(source))
return;
if ((status.id === "confusion" || status.id === "yawn") && target !== source) {
if (effect.effectType === "Move" && !effect.secondaries)
this.add("-activate", target, "move: Safeguard");
return null;
}
},
onSideStart(side, source) {
if (source?.hasAbility("persistent")) {
this.add("-sidestart", side, "Safeguard", "[persistent]");
} else {
this.add("-sidestart", side, "Safeguard");
}
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 3,
onSideEnd(side) {
this.add("-sideend", side, "Safeguard");
}
},
secondary: null,
target: "allySide",
type: "Normal",
zMove: { boost: { spe: 1 } },
contestType: "Beautiful"
},
saltcure: {
num: 864,
accuracy: 100,
basePower: 40,
category: "Physical",
name: "Salt Cure",
pp: 15,
priority: 0,
flags: { protect: 1, mirror: 1 },
condition: {
noCopy: true,
onStart(pokemon) {
this.add("-start", pokemon, "Salt Cure");
},
onResidualOrder: 13,
onResidual(pokemon) {
this.damage(pokemon.baseMaxhp / (pokemon.hasType(["Water", "Steel"]) ? 4 : 8));
},
onEnd(pokemon) {
this.add("-end", pokemon, "Salt Cure");
}
},
secondary: {
chance: 100,
volatileStatus: "saltcure"
},
target: "normal",
type: "Rock"
},
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"
},
sandsearstorm: {
num: 848,
accuracy: 80,
basePower: 100,
category: "Special",
isNonstandard: "Unobtainable",
name: "Sandsear Storm",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, wind: 1 },
secondary: {
chance: 20,
status: "brn"
},
target: "allAdjacentFoes",
type: "Ground"
},
sandstorm: {
num: 201,
accuracy: true,
basePower: 0,
category: "Status",
name: "Sandstorm",
pp: 10,
priority: 0,
flags: { wind: 1 },
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, mirror: 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, allyanim: 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, bypasssub: 1, allyanim: 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",
isNonstandard: "Past",
overrideDefensiveStat: "def",
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, noparentalbond: 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",
isNonstandard: "Past",
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",
name: "Shadow Force",
pp: 5,
priority: 0,
flags: { contact: 1, charge: 1, mirror: 1, nosleeptalk: 1, noassist: 1, failinstruct: 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"
},
shedtail: {
num: 880,
accuracy: true,
basePower: 0,
category: "Status",
name: "Shed Tail",
pp: 10,
priority: 0,
flags: {},
volatileStatus: "substitute",
onTryHit(source) {
if (!this.canSwitch(source.side)) {
this.add("-fail", source);
return this.NOT_FAIL;
}
if (source.volatiles["substitute"]) {
this.add("-fail", source, "move: Shed Tail");
return this.NOT_FAIL;
}
if (source.hp <= Math.ceil(source.maxhp / 2)) {
this.add("-fail", source, "move: Shed Tail", "[weak]");
return this.NOT_FAIL;
}
},
onHit(target) {
this.directDamage(Math.ceil(target.maxhp / 2));
},
self: {
onHit(source) {
source.skipBeforeSwitchOutEventFlag = true;
}
},
selfSwitch: "shedtail",
secondary: null,
target: "self",
type: "Normal",
zMove: { effect: "clearnegativeboost" }
},
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 },
onPrepareHit(target, source, move) {
if (!source.isAlly(target)) {
this.attrLastMove("[anim] Shell Side Arm " + move.category);
}
},
onModifyMove(move, pokemon, target) {
if (!target)
return;
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) {
if (!source.isAlly(target))
this.hint(move.category + " Shell Side Arm");
},
onAfterSubDamage(damage, target, source, move) {
if (!source.isAlly(target))
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",
isNonstandard: "Past",
name: "Shell Trap",
pp: 5,
priority: -3,
flags: { protect: 1, failmefirst: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
priorityChargeCallback(pokemon) {
pokemon.addVolatile("shelltrap");
},
onTryMove(pokemon) {
if (!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.isAlly(source) && move.category === "Physical") {
this.effectState.gotHit = true;
const action = this.queue.willMove(pokemon);
if (action) {
this.queue.prioritizeAction(action);
}
}
}
},
secondary: null,
target: "allAdjacentFoes",
type: "Fire",
contestType: "Tough"
},
shelter: {
num: 842,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Unobtainable",
name: "Shelter",
pp: 10,
priority: 0,
flags: { snatch: 1 },
boosts: {
def: 2
},
secondary: null,
target: "self",
type: "Steel"
},
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: 5,
priority: 0,
flags: { snatch: 1, heal: 1 },
onHit(pokemon) {
let factor = 0.5;
if (this.field.isWeather("sandstorm")) {
factor = 0.667;
}
const success = !!this.heal(this.modify(pokemon.maxhp, factor));
if (!success) {
this.add("-fail", pokemon, "heal");
return this.NOT_FAIL;
}
return success;
},
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"
},
silktrap: {
num: 852,
accuracy: true,
basePower: 0,
category: "Status",
name: "Silk Trap",
pp: 10,
priority: 4,
flags: {},
stallingMove: true,
volatileStatus: "silktrap",
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"] || move.category === "Status") {
if (move.isZ || move.isMax)
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) {
if (source.volatiles["lockedmove"].duration === 2) {
delete source.volatiles["lockedmove"];
}
}
if (this.checkMoveMakesContact(move, source, target)) {
this.boost({ spe: -1 }, source, target, this.dex.getActiveMove("Silk Trap"));
}
return this.NOT_FAIL;
},
onHit(target, source, move) {
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
this.boost({ spe: -1 }, source, target, this.dex.getActiveMove("Silk Trap"));
}
}
},
target: "self",
type: "Bug"
},
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",
isNonstandard: "Unobtainable",
name: "Simple Beam",
pp: 15,
priority: 0,
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
onTryHit(target) {
if (target.getAbility().isPermanent || target.ability === "simple" || target.ability === "truant") {
return false;
}
},
onHit(pokemon) {
const oldAbility = pokemon.setAbility("simple");
if (oldAbility) {
this.add("-ability", pokemon, "Simple", "[from] move: Simple Beam");
return;
}
return oldAbility;
},
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, bypasssub: 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, mirror: 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: {
bypasssub: 1,
allyanim: 1,
failencore: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 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);
},
noSketch: true,
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, bypasssub: 1, allyanim: 1 },
onTryHit(target, source) {
const additionalBannedAbilities = ["hungerswitch", "illusion", "neutralizinggas", "wonderguard"];
const targetAbility = target.getAbility();
const sourceAbility = source.getAbility();
if (target.volatiles["dynamax"] || targetAbility.isPermanent || sourceAbility.isPermanent || additionalBannedAbilities.includes(target.ability) || additionalBannedAbilities.includes(source.ability)) {
return false;
}
const sourceCanBeSet = this.runEvent("SetAbility", source, source, this.effect, targetAbility);
if (!sourceCanBeSet)
return sourceCanBeSet;
const targetCanBeSet = this.runEvent("SetAbility", target, source, this.effect, sourceAbility);
if (!targetCanBeSet)
return targetCanBeSet;
},
onHit(target, source, move) {
const targetAbility = target.getAbility();
const sourceAbility = source.getAbility();
if (target.isAlly(source)) {
this.add("-activate", source, "move: Skill Swap", "", "", "[of] " + target);
} else {
this.add("-activate", source, "move: Skill Swap", targetAbility, sourceAbility, "[of] " + target);
}
this.singleEvent("End", sourceAbility, source.abilityState, source);
this.singleEvent("End", targetAbility, target.abilityState, target);
source.ability = targetAbility.id;
target.ability = sourceAbility.id;
source.abilityState = { id: this.toID(source.ability), target: source };
target.abilityState = { id: this.toID(target.ability), target };
if (!target.isAlly(source))
target.volatileStaleness = "external";
this.singleEvent("Start", targetAbility, source.abilityState, source);
this.singleEvent("Start", sourceAbility, target.abilityState, 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",
isNonstandard: "Past",
name: "Skull Bash",
pp: 10,
priority: 0,
flags: { contact: 1, charge: 1, protect: 1, mirror: 1, nosleeptalk: 1, failinstruct: 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, nosleeptalk: 1, failinstruct: 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,
nosleeptalk: 1,
noassist: 1,
failinstruct: 1
},
onModifyMove(move, source) {
if (!source.volatiles["skydrop"]) {
move.accuracy = true;
delete move.flags["contact"];
}
},
onMoveFail(target, source) {
if (source.volatiles["twoturnmove"] && source.volatiles["twoturnmove"].duration === 1) {
source.removeVolatile("skydrop");
source.removeVolatile("twoturnmove");
if (target === this.effectState.target) {
this.add("-end", target, "Sky Drop", "[interrupt]");
}
}
},
onTry(source, target) {
return !target.fainted;
},
onTryHit(target, source, move) {
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.isAlly(source)) {
return false;
}
if (target.getWeight() >= 2e3) {
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.effectState.target || pokemon === this.effectState.source)
return false;
},
onFoeTrapPokemonPriority: -15,
onFoeTrapPokemon(defender) {
if (defender !== this.effectState.source)
return;
defender.trapped = true;
},
onFoeBeforeMovePriority: 12,
onFoeBeforeMove(attacker, defender, move) {
if (attacker === this.effectState.source) {
attacker.activeMoveActions--;
this.debug("Sky drop nullifying.");
return null;
}
},
onRedirectTargetPriority: 99,
onRedirectTarget(target, source, source2) {
if (source !== this.effectState.target)
return;
if (this.effectState.source.fainted)
return;
return this.effectState.source;
},
onAnyInvulnerability(target, source, move) {
if (target !== this.effectState.target && target !== this.effectState.source) {
return;
}
if (source === this.effectState.target && target === this.effectState.source) {
return;
}
if (["gust", "twister", "skyuppercut", "thunder", "hurricane", "smackdown", "thousandarrows"].includes(move.id)) {
return;
}
return false;
},
onAnyBasePower(basePower, target, source, move) {
if (target !== this.effectState.target && target !== this.effectState.source) {
return;
}
if (source === this.effectState.target && target === this.effectState.source) {
return;
}
if (move.id === "gust" || move.id === "twister") {
this.debug("BP doubled on midair target");
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: 5,
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, slicing: 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: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
sleepUsable: true,
onTry(source) {
return source.status === "slp" || source.hasAbility("comatose");
},
onHit(pokemon) {
const moves = [];
for (const moveSlot of pokemon.moveSlots) {
const moveid = moveSlot.id;
if (!moveid)
continue;
const move = this.dex.moves.get(moveid);
if (move.flags["nosleeptalk"] || move.flags["charge"] || move.isZ && move.basePower !== 1 || move.isMax) {
continue;
}
moves.push(moveid);
}
let randomMove = "";
if (moves.length)
randomMove = this.sample(moves);
if (!randomMove) {
return false;
}
this.actions.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);
pokemon.removeVolatile("twoturnmove");
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") {
this.debug("BP doubled on paralyzed target");
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",
isNonstandard: "Past",
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, bypasssub: 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: { bypasssub: 1, mustpressure: 1, noassist: 1, failcopycat: 1 },
volatileStatus: "snatch",
condition: {
duration: 1,
onStart(pokemon) {
this.add("-singleturn", pokemon, "Snatch");
},
onAnyPrepareHitPriority: -1,
onAnyPrepareHit(source, target, move) {
const snatchUser = this.effectState.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.actions.useMove(move.id, snatchUser);
return null;
}
},
secondary: null,
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, bypasssub: 1 },
sleepUsable: true,
onTry(source) {
return source.status === "slp" || source.hasAbility("comatose");
},
secondary: {
chance: 30,
volatileStatus: "flinch"
},
target: "normal",
type: "Normal",
contestType: "Cute"
},
snowscape: {
num: 883,
accuracy: true,
basePower: 0,
category: "Status",
name: "Snowscape",
pp: 10,
priority: 0,
flags: {},
weather: "snow",
secondary: null,
target: "all",
type: "Ice"
},
soak: {
num: 487,
accuracy: 100,
basePower: 0,
category: "Status",
name: "Soak",
pp: 20,
priority: 0,
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
onHit(target) {
if (target.getTypes().join() === "Water" || !target.setType("Water")) {
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: 5,
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, nosleeptalk: 1, failinstruct: 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) {
const weakWeathers = ["raindance", "primordialsea", "sandstorm", "hail", "snow"];
if (weakWeathers.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, slicing: 1, nosleeptalk: 1, failinstruct: 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) {
const weakWeathers = ["raindance", "primordialsea", "sandstorm", "hail", "snow"];
if (weakWeathers.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",
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",
isNonstandard: "Past",
name: "Sparkling Aria",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
secondary: {
dustproof: true,
chance: 100,
volatileStatus: "sparklingaria"
},
onAfterMove(source, target, move) {
for (const pokemon of this.getAllActive()) {
if (pokemon !== source && pokemon.removeVolatile("sparklingaria") && pokemon.status === "brn" && !source.fainted) {
pokemon.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, mirror: 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",
isNonstandard: "Past",
name: "Spectral Thief",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, bypasssub: 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, bypasssub: 1, allyanim: 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"
},
spicyextract: {
num: 858,
accuracy: true,
basePower: 0,
category: "Status",
name: "Spicy Extract",
pp: 15,
priority: 0,
flags: { protect: 1, reflectable: 1, mirror: 1 },
boosts: {
atk: 2,
def: -2
},
secondary: null,
target: "normal",
type: "Grass"
},
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, mustpressure: 1 },
sideCondition: "spikes",
condition: {
// this is a side condition
onSideStart(side) {
this.add("-sidestart", side, "Spikes");
this.effectState.layers = 1;
},
onSideRestart(side) {
if (this.effectState.layers >= 3)
return false;
this.add("-sidestart", side, "Spikes");
this.effectState.layers++;
},
onEntryHazard(pokemon) {
if (!pokemon.isGrounded() || pokemon.hasItem("heavydutyboots"))
return;
const damageAmounts = [0, 3, 4, 6];
this.damage(damageAmounts[this.effectState.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: { noassist: 1, failcopycat: 1 },
stallingMove: true,
volatileStatus: "spikyshield",
onPrepareHit(pokemon) {
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
},
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 (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
return;
if (move.isZ || move.isMax)
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) {
if (source.volatiles["lockedmove"].duration === 2) {
delete source.volatiles["lockedmove"];
}
}
if (this.checkMoveMakesContact(move, source, target)) {
this.damage(source.baseMaxhp / 8, source, target);
}
return this.NOT_FAIL;
},
onHit(target, source, move) {
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
this.damage(source.baseMaxhp / 8, source, target);
}
}
},
secondary: null,
target: "self",
type: "Grass",
zMove: { boost: { def: 1 } },
contestType: "Tough"
},
spinout: {
num: 859,
accuracy: 100,
basePower: 100,
category: "Physical",
name: "Spin Out",
pp: 5,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
self: {
boosts: {
spe: -2
}
},
secondary: null,
target: "normal",
type: "Steel"
},
spiritbreak: {
num: 789,
accuracy: 100,
basePower: 75,
category: "Physical",
name: "Spirit Break",
pp: 15,
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"]?.layers)
return false;
return pokemon.volatiles["stockpile"].layers * 100;
},
category: "Special",
name: "Spit Up",
pp: 10,
priority: 0,
flags: { protect: 1 },
onTry(source) {
return !!source.volatiles["stockpile"];
},
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, bypasssub: 1 },
onHit(target) {
let move = target.lastMove;
if (!move || move.isZ)
return false;
if (move.isMax && move.baseMove)
move = this.dex.moves.get(move.baseMove);
const ppDeducted = target.deductPP(move.id, 4);
if (!ppDeducted)
return false;
this.add("-activate", target, "move: Spite", 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 },
onTry(source, target, move) {
if (this.field.getPseudoWeather("Gravity")) {
this.add("cant", source, "move: Gravity", move);
return null;
}
},
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();
},
onAfterSubDamage() {
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, mirror: 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",
isNonstandard: "Past",
name: "Spotlight",
pp: 15,
priority: 3,
flags: { protect: 1, reflectable: 1, allyanim: 1, noassist: 1, failcopycat: 1 },
volatileStatus: "spotlight",
onTryHit(target) {
if (this.activePerHalf === 1)
return false;
},
condition: {
duration: 1,
onStart(pokemon) {
this.add("-singleturn", pokemon, "move: Spotlight");
},
onFoeRedirectTargetPriority: 2,
onFoeRedirectTarget(target, source, source2, move) {
if (this.validTarget(this.effectState.target, source, move.target)) {
this.debug("Spotlight redirected target of move");
return this.effectState.target;
}
}
},
secondary: null,
target: "normal",
type: "Normal",
zMove: { boost: { spd: 1 } },
contestType: "Cute"
},
springtidestorm: {
num: 831,
accuracy: 80,
basePower: 100,
category: "Special",
isNonstandard: "Unobtainable",
name: "Springtide Storm",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1, wind: 1 },
secondary: {
chance: 30,
boosts: {
atk: -1
}
},
target: "allAdjacentFoes",
type: "Fairy"
},
stealthrock: {
num: 446,
accuracy: true,
basePower: 0,
category: "Status",
name: "Stealth Rock",
pp: 20,
priority: 0,
flags: { reflectable: 1, mustpressure: 1 },
sideCondition: "stealthrock",
condition: {
// this is a side condition
onSideStart(side) {
this.add("-sidestart", side, "move: Stealth Rock");
},
onEntryHazard(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",
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) {
const hpBeforeRecoil = pokemon.hp;
this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.conditions.get("Steel Beam"), true);
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
this.runEvent("EmergencyExit", pokemon, pokemon);
}
}
},
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 },
onTry() {
return !this.field.isTerrain("");
},
onHit() {
this.field.clearTerrain();
},
onAfterSubDamage() {
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: {
onSideStart(side) {
this.add("-sidestart", side, "move: Sticky Web");
},
onEntryHazard(pokemon) {
if (!pokemon.isGrounded() || pokemon.hasItem("heavydutyboots"))
return;
this.add("-activate", pokemon, "move: Sticky Web");
this.boost({ spe: -1 }, pokemon, this.effectState.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 },
onTry(source) {
if (source.volatiles["stockpile"] && source.volatiles["stockpile"].layers >= 3)
return false;
},
volatileStatus: "stockpile",
condition: {
noCopy: true,
onStart(target) {
this.effectState.layers = 1;
this.effectState.def = 0;
this.effectState.spd = 0;
this.add("-start", target, "stockpile" + this.effectState.layers);
const [curDef, curSpD] = [target.boosts.def, target.boosts.spd];
this.boost({ def: 1, spd: 1 }, target, target);
if (curDef !== target.boosts.def)
this.effectState.def--;
if (curSpD !== target.boosts.spd)
this.effectState.spd--;
},
onRestart(target) {
if (this.effectState.layers >= 3)
return false;
this.effectState.layers++;
this.add("-start", target, "stockpile" + this.effectState.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.effectState.def--;
if (curSpD !== target.boosts.spd)
this.effectState.spd--;
},
onEnd(target) {
if (this.effectState.def || this.effectState.spd) {
const boosts = {};
if (this.effectState.def)
boosts.def = this.effectState.def;
if (this.effectState.spd)
boosts.spd = this.effectState.spd;
this.boost(boosts, target, target);
}
this.add("-end", target, "Stockpile");
if (this.effectState.def !== this.effectState.layers * -1 || this.effectState.spd !== this.effectState.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) {
this.debug("doubling Stomping Tantrum BP due to previous move failure");
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"
},
stoneaxe: {
num: 830,
accuracy: 90,
basePower: 65,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Stone Axe",
pp: 15,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
self: {
onHit(source) {
for (const side of source.side.foeSidesWithConditions()) {
side.addSideCondition("stealthrock");
}
}
},
secondary: {},
// allows sheer force to trigger
target: "normal",
type: "Rock"
},
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) {
const bp = move.basePower + 20 * pokemon.positiveBoosts();
this.debug("BP: " + bp);
return bp;
},
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",
isNonstandard: "Past",
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",
isNonstandard: "Past",
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,
failencore: 1,
failmefirst: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 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 },
onDisableMove(pokemon) {
if (!pokemon.getItem().isBerry)
pokemon.disableMove("stuffcheeks");
},
onTry(source) {
return source.getItem().isBerry;
},
onHit(pokemon) {
if (!this.boost({ def: 2 }))
return null;
pokemon.eatItem(true);
},
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",
isNonstandard: "Past",
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(source) {
if (source.volatiles["substitute"]) {
this.add("-fail", source, "move: Substitute");
return this.NOT_FAIL;
}
if (source.hp <= source.maxhp / 4 || source.maxhp === 1) {
this.add("-fail", source, "move: Substitute", "[weak]");
return this.NOT_FAIL;
}
},
onHit(target) {
this.directDamage(target.maxhp / 4);
},
condition: {
onStart(target, source, effect) {
if (effect?.id === "shedtail") {
this.add("-start", target, "Substitute", "[from] move: Shed Tail");
} else {
this.add("-start", target, "Substitute");
}
this.effectState.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["bypasssub"] || move.infiltrates) {
return;
}
let damage = this.actions.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;
}
target.volatiles["substitute"].hp -= damage;
source.lastDamage = damage;
if (target.volatiles["substitute"].hp <= 0) {
if (move.ohko)
this.add("-ohko");
target.removeVolatile("substitute");
} else {
this.add("-activate", target, "move: Substitute", "[damage]");
}
if (move.recoil) {
this.damage(this.actions.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"]) {
return false;
}
},
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",
isNonstandard: "Past",
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, bypasssub: 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, punch: 1, mirror: 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, allyanim: 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 },
onTry(source) {
return !!source.volatiles["stockpile"];
},
onHit(pokemon) {
const healAmount = [0.25, 0.5, 1];
const success = !!this.heal(this.modify(pokemon.maxhp, healAmount[pokemon.volatiles["stockpile"].layers - 1]));
if (!success)
this.add("-fail", pokemon, "heal");
pokemon.removeVolatile("stockpile");
return success || this.NOT_FAIL;
},
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, allyanim: 1, noassist: 1, failcopycat: 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.itemState, target, source, move, myItem) || yourItem && !this.singleEvent("TakeItem", yourItem, target.itemState, 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":
case "snow":
factor = 0.25;
break;
}
const success = !!this.heal(this.modify(pokemon.maxhp, factor));
if (!success) {
this.add("-fail", pokemon, "heal");
return this.NOT_FAIL;
}
return success;
},
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, wind: 1 },
sideCondition: "tailwind",
condition: {
duration: 4,
durationCallback(target, source, effect) {
if (source?.hasAbility("persistent")) {
this.add("-activate", source, "ability: Persistent", "[move] Tailwind");
return 6;
}
return 4;
},
onSideStart(side, source) {
if (source?.hasAbility("persistent")) {
this.add("-sidestart", side, "move: Tailwind", "[persistent]");
} else {
this.add("-sidestart", side, "move: Tailwind");
}
},
onModifySpe(spe, pokemon) {
return this.chainModify(2);
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 5,
onSideEnd(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"
},
takeheart: {
num: 850,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Past",
name: "Take Heart",
pp: 15,
priority: 0,
flags: { snatch: 1 },
onHit(pokemon) {
const success = !!this.boost({ spa: 1, spd: 1 });
return pokemon.cureStatus() || success;
},
secondary: null,
target: "self",
type: "Psychic"
},
tarshot: {
num: 749,
accuracy: 100,
basePower: 0,
category: "Status",
name: "Tar Shot",
pp: 15,
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, bypasssub: 1 },
volatileStatus: "taunt",
condition: {
duration: 3,
onStart(target) {
if (target.activeTurns && !this.queue.willMove(target)) {
this.effectState.duration++;
}
this.add("-start", target, "move: Taunt");
},
onResidualOrder: 15,
onEnd(target) {
this.add("-end", target, "move: Taunt");
},
onDisableMove(pokemon) {
for (const moveSlot of pokemon.moveSlots) {
const move = this.dex.moves.get(moveSlot.id);
if (move.category === "Status" && move.id !== "mefirst") {
pokemon.disableMove(moveSlot.id);
}
}
},
onBeforeMovePriority: 5,
onBeforeMove(attacker, defender, move) {
if (!move.isZ && !move.isMax && move.category === "Status" && move.id !== "mefirst") {
this.add("cant", attacker, "move: Taunt", move);
return false;
}
}
},
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: { bypasssub: 1 },
onHitField(target, source, move) {
const targets = [];
for (const pokemon of this.getAllActive()) {
if (this.runEvent("Invulnerability", pokemon, source, move) === false) {
this.add("-miss", source, pokemon);
} else if (this.runEvent("TryHit", pokemon, source, move) && pokemon.getItem().isBerry) {
targets.push(pokemon);
}
}
this.add("-fieldactivate", "move: Teatime");
if (!targets.length) {
this.add("-fail", source, "move: Teatime");
this.attrLastMove("[still]");
return this.NOT_FAIL;
}
for (const pokemon of targets) {
pokemon.eatItem(true);
}
},
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, allyanim: 1 },
volatileStatus: "telekinesis",
onTry(source, target, move) {
if (this.field.getPseudoWeather("Gravity")) {
this.attrLastMove("[still]");
this.add("cant", source, "move: Gravity", move);
return null;
}
},
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: 19,
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: {},
onTry(source) {
return !!this.canSwitch(source.side);
},
selfSwitch: true,
secondary: null,
target: "self",
type: "Psychic",
zMove: { effect: "heal" },
contestType: "Cool"
},
terablast: {
num: 851,
accuracy: 100,
basePower: 80,
category: "Special",
name: "Tera Blast",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, mustpressure: 1 },
onModifyType(move, pokemon, target) {
if (pokemon.terastallized) {
move.type = pokemon.teraType;
}
},
onModifyMove(move, pokemon) {
if (pokemon.terastallized && pokemon.getStat("atk", false, true) > pokemon.getStat("spa", false, true)) {
move.category = "Physical";
}
},
secondary: null,
target: "normal",
type: "Normal"
},
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;
this.debug("BP doubled in Terrain");
}
},
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, failmefirst: 1, noassist: 1, failcopycat: 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.itemState, source, target, move, yourItem) || !source.setItem(yourItem)) {
target.item = yourItem.id;
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;
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, failinstruct: 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.moves.get(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;
}
},
onModifyMove(move, pokemon, target) {
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"
},
thundercage: {
num: 819,
accuracy: 90,
basePower: 80,
category: "Special",
name: "Thunder Cage",
pp: 15,
priority: 0,
flags: { protect: 1, mirror: 1 },
volatileStatus: "partiallytrapped",
secondary: null,
target: "normal",
type: "Electric"
},
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"
},
thunderouskick: {
num: 823,
accuracy: 100,
basePower: 90,
category: "Physical",
name: "Thunderous Kick",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
secondary: {
chance: 100,
boosts: {
def: -1
}
},
target: "normal",
type: "Fighting"
},
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, allyanim: 1 },
boosts: {
atk: -1,
def: -1
},
secondary: null,
target: "normal",
type: "Normal",
zMove: { boost: { def: 1 } },
contestType: "Cute"
},
tidyup: {
num: 882,
accuracy: true,
basePower: 0,
category: "Status",
name: "Tidy Up",
pp: 10,
priority: 0,
flags: {},
onHit(pokemon) {
let success = false;
for (const active of this.getAllActive()) {
if (active.removeVolatile("substitute"))
success = true;
}
const removeAll = ["spikes", "toxicspikes", "stealthrock", "stickyweb", "gmaxsteelsurge"];
const sides = [pokemon.side, ...pokemon.side.foeSidesWithConditions()];
for (const side of sides) {
for (const sideCondition of removeAll) {
if (side.removeSideCondition(sideCondition)) {
this.add("-sideend", side, this.dex.conditions.get(sideCondition).name);
success = true;
}
}
}
if (success)
this.add("-activate", pokemon, "move: Tidy Up");
return !!this.boost({ atk: 1, spe: 1 }, pokemon, pokemon, null, false, true) || success;
},
secondary: null,
target: "self",
type: "Normal"
},
topsyturvy: {
num: 576,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Past",
name: "Topsy-Turvy",
pp: 20,
priority: 0,
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
onHit(target) {
let success = false;
let i;
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"
},
torchsong: {
num: 871,
accuracy: 100,
basePower: 80,
category: "Special",
name: "Torch Song",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
secondary: {
chance: 100,
self: {
boosts: {
spa: 1
}
}
},
target: "normal",
type: "Fire",
contestType: "Beautiful"
},
torment: {
num: 259,
accuracy: 100,
basePower: 0,
category: "Status",
name: "Torment",
pp: 15,
priority: 0,
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
volatileStatus: "torment",
condition: {
noCopy: true,
onStart(pokemon, source, effect) {
if (pokemon.volatiles["dynamax"]) {
delete pokemon.volatiles["torment"];
return false;
}
if (effect?.id === "gmaxmeltdown")
this.effectState.duration = 3;
this.add("-start", pokemon, "Torment");
},
onEnd(pokemon) {
this.add("-end", pokemon, "Torment");
},
onDisableMove(pokemon) {
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, mustpressure: 1 },
sideCondition: "toxicspikes",
condition: {
// this is a side condition
onSideStart(side) {
this.add("-sidestart", side, "move: Toxic Spikes");
this.effectState.layers = 1;
},
onSideRestart(side) {
if (this.effectState.layers >= 2)
return false;
this.add("-sidestart", side, "move: Toxic Spikes");
this.effectState.layers++;
},
onEntryHazard(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.effectState.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"
},
trailblaze: {
num: 885,
accuracy: 100,
basePower: 50,
category: "Physical",
name: "Trailblaze",
pp: 20,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
secondary: {
chance: 100,
self: {
boosts: {
spe: 1
}
}
},
target: "normal",
type: "Grass",
contestType: "Cool"
},
transform: {
num: 144,
accuracy: true,
basePower: 0,
category: "Status",
name: "Transform",
pp: 10,
priority: 0,
flags: { allyanim: 1, failencore: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 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, allyanim: 1, noassist: 1, failcopycat: 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.itemState, target, source, move, myItem) || yourItem && !this.singleEvent("TakeItem", yourItem, target.itemState, 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",
isNonstandard: "Past",
name: "Trick-or-Treat",
pp: 20,
priority: 0,
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 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) {
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", "[move] Trick Room");
return 7;
}
return 5;
},
onFieldStart(target, source) {
if (source?.hasAbility("persistent")) {
this.add("-fieldstart", "move: Trick Room", "[of] " + source, "[persistent]");
} else {
this.add("-fieldstart", "move: Trick Room", "[of] " + source);
}
},
onFieldRestart(target, source) {
this.field.removePseudoWeather("trickroom");
},
// Speed modification is changed in Pokemon.getActionSpeed() in sim/pokemon.js
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 1,
onFieldEnd() {
this.add("-fieldend", "move: Trick Room");
}
},
secondary: null,
target: "all",
type: "Psychic",
zMove: { boost: { accuracy: 1 } },
contestType: "Clever"
},
triplearrows: {
num: 843,
accuracy: 100,
basePower: 90,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Triple Arrows",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
critRatio: 2,
secondaries: [
{
chance: 50,
boosts: {
def: -1
}
},
{
chance: 30,
volatileStatus: "flinch"
}
],
target: "normal",
type: "Fighting"
},
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 }
},
tripledive: {
num: 865,
accuracy: 95,
basePower: 30,
category: "Physical",
name: "Triple Dive",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
multihit: 3,
secondary: null,
target: "normal",
type: "Water"
},
triplekick: {
num: 167,
accuracy: 90,
basePower: 10,
basePowerCallback(pokemon, target, move) {
return 10 * move.hit;
},
category: "Physical",
isNonstandard: "Past",
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);
let bp;
if (!moveSlot) {
bp = 40;
} else {
switch (moveSlot.pp) {
case 0:
bp = 200;
break;
case 1:
bp = 80;
break;
case 2:
bp = 60;
break;
case 3:
bp = 50;
break;
default:
bp = 40;
break;
}
}
this.debug("BP: " + bp);
return bp;
},
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"
},
twinbeam: {
num: 888,
accuracy: 100,
basePower: 40,
category: "Special",
name: "Twin Beam",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1 },
multihit: 2,
secondary: null,
target: "normal",
type: "Psychic",
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, wind: 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, bypasssub: 1, nosleeptalk: 1, failinstruct: 1 },
self: {
volatileStatus: "uproar"
},
onTryHit(target) {
const activeTeam = target.side.activeTeam();
const foeActiveTeam = target.side.foe.activeTeam();
for (const [i, allyActive] of activeTeam.entries()) {
if (allyActive && allyActive.status === "slp")
allyActive.cureStatus();
const foeActive = foeActiveTeam[i];
if (foeActive && foeActive.status === "slp")
foeActive.cureStatus();
}
},
condition: {
duration: 3,
onStart(target) {
this.add("-start", target, "Uproar");
},
onResidual(target) {
if (target.volatiles["throatchop"]) {
target.removeVolatile("uproar");
return;
}
if (target.lastMove && target.lastMove.id === "struggle") {
delete target.volatiles["uproar"];
}
this.add("-start", target, "Uproar", "[upkeep]");
},
onResidualOrder: 28,
onResidualSubOrder: 1,
onEnd(target) {
this.add("-end", target, "Uproar");
},
onLockMove: "uproar",
onAnySetStatus(status, pokemon) {
if (status.id === "slp") {
if (pokemon === this.effectState.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) {
const bp = Math.floor(pokemon.happiness * 10 / 25) || 1;
this.debug("BP: " + bp);
return bp;
},
category: "Physical",
isNonstandard: "LGPE",
name: "Veevee Volley",
pp: 20,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
secondary: null,
target: "normal",
type: "Normal",
contestType: "Cute"
},
venomdrench: {
num: 599,
accuracy: 100,
basePower: 0,
category: "Status",
isNonstandard: "Past",
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"
},
victorydance: {
num: 837,
accuracy: true,
basePower: 0,
category: "Status",
isNonstandard: "Unobtainable",
name: "Victory Dance",
pp: 10,
priority: 0,
flags: { snatch: 1, dance: 1 },
boosts: {
atk: 1,
def: 1,
spe: 1
},
secondary: null,
target: "self",
type: "Fighting"
},
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",
isNonstandard: "Past",
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")) {
this.debug("BP doubled on sleeping target");
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, pledgecombo: 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.isAlly(source) && ["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,
onSideStart(targetSide) {
this.add("-sidestart", targetSide, "Water Pledge");
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 7,
onSideEnd(targetSide) {
this.add("-sideend", targetSide, "Water Pledge");
},
onModifyMove(move, pokemon) {
if (move.secondaries && move.id !== "secretpower") {
this.debug("doubling secondary chance");
for (const secondary of move.secondaries) {
if (pokemon.hasAbility("serenegrace") && secondary.volatileStatus === "flinch")
continue;
if (secondary.chance)
secondary.chance *= 2;
}
if (move.self?.chance)
move.self.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") && !pokemon.transformed) {
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,
onFieldStart(field, 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([1352, 4096]);
}
},
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 3,
onFieldEnd() {
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) {
const bp = move.basePower * pokemon.hp / pokemon.maxhp;
this.debug("BP: " + bp);
return bp;
},
category: "Special",
name: "Water Spout",
pp: 5,
priority: 0,
flags: { protect: 1, mirror: 1 },
secondary: null,
target: "allAdjacentFoes",
type: "Water",
contestType: "Beautiful"
},
wavecrash: {
num: 834,
accuracy: 100,
basePower: 120,
category: "Physical",
name: "Wave Crash",
pp: 10,
priority: 0,
flags: { contact: 1, protect: 1, mirror: 1 },
recoil: [33, 100],
secondary: null,
target: "normal",
type: "Water"
},
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":
case "snow":
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":
case "snow":
move.basePower *= 2;
break;
}
this.debug("BP: " + move.basePower);
},
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, bypasssub: 1, allyanim: 1, wind: 1, noassist: 1, failcopycat: 1 },
forceSwitch: true,
secondary: null,
target: "normal",
type: "Normal",
zMove: { boost: { spd: 1 } },
contestType: "Clever"
},
wickedblow: {
num: 817,
accuracy: 100,
basePower: 75,
category: "Physical",
name: "Wicked Blow",
pp: 5,
priority: 0,
flags: { contact: 1, protect: 1, punch: 1, mirror: 1 },
willCrit: true,
secondary: null,
target: "normal",
type: "Dark"
},
wickedtorque: {
num: 897,
accuracy: 100,
basePower: 80,
category: "Physical",
isNonstandard: "Unobtainable",
name: "Wicked Torque",
pp: 10,
priority: 0,
flags: {
protect: 1,
failencore: 1,
failmefirst: 1,
nosleeptalk: 1,
noassist: 1,
failcopycat: 1,
failinstruct: 1,
failmimic: 1
},
secondary: {
chance: 10,
status: "slp"
},
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",
onTry() {
return !!this.queue.willAct();
},
onHitSide(side, source) {
source.addVolatile("stall");
},
condition: {
duration: 1,
onSideStart(target, source) {
this.add("-singleturn", source, "Wide Guard");
},
onTryHitPriority: 4,
onTryHit(target, source, move) {
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) {
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"
},
wildboltstorm: {
num: 847,
accuracy: 80,
basePower: 100,
category: "Special",
isNonstandard: "Unobtainable",
name: "Wildbolt Storm",
pp: 10,
priority: 0,
flags: { protect: 1, mirror: 1, wind: 1 },
secondary: {
chance: 20,
status: "par"
},
target: "allAdjacentFoes",
type: "Electric"
},
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.effectState.hp = source.maxhp / 2;
},
onResidualOrder: 4,
onEnd(target) {
if (target && !target.fainted) {
const damage = this.heal(this.effectState.hp, target, target);
if (damage) {
this.add("-heal", target, target.getHealth, "[from] move: Wish", "[wisher] " + this.effectState.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", "[move] Wonder Room");
return 7;
}
return 5;
},
onModifyMove(move, source, target) {
if (!move.overrideOffensiveStat)
return;
const statAndBoosts = move.overrideOffensiveStat;
if (!["def", "spd"].includes(statAndBoosts))
return;
move.overrideOffensiveStat = statAndBoosts === "def" ? "spd" : "def";
this.hint(`${move.name} uses ${statAndBoosts === "def" ? "" : "Sp. "}Def boosts when Wonder Room is active.`);
},
onFieldStart(field, source) {
if (source?.hasAbility("persistent")) {
this.add("-fieldstart", "move: Wonder Room", "[of] " + source, "[persistent]");
} else {
this.add("-fieldstart", "move: Wonder Room", "[of] " + source);
}
},
onFieldRestart(target, source) {
this.field.removePseudoWeather("wonderroom");
},
// Swapping defenses partially implemented in sim/pokemon.js:Pokemon#calculateStat and Pokemon#getStat
onFieldResidualOrder: 27,
onFieldResidualSubOrder: 5,
onFieldEnd() {
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, allyanim: 1 },
onTryImmunity(target) {
if (target.ability === "truant" || target.ability === "insomnia") {
return false;
}
},
onTryHit(target) {
if (target.getAbility().isPermanent) {
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 oldAbility;
},
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, move) {
const hp = target.hp;
const maxHP = target.maxhp;
const bp = Math.floor(Math.floor((120 * (100 * Math.floor(hp * 4096 / maxHP)) + 2048 - 1) / 4096) / 100) || 1;
this.debug("BP for " + hp + "/" + maxHP + " HP: " + bp);
return bp;
},
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, slicing: 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: 23,
onEnd(target) {
this.add("-end", target, "move: Yawn", "[silent]");
target.trySetStatus("slp", this.effectState.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, mirror: 1 },
secondary: {
chance: 100,
self: {
boosts: {
evasion: 1
}
}
},
target: "normal",
type: "Electric",
contestType: "Cool"
}
};
//# sourceMappingURL=moves.js.map