"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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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: { metronome: 1 }, 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, metronome: 1, slicing: 1 }, secondary: null, target: "any", type: "Flying", contestType: "Cool" }, aeroblast: { num: 177, accuracy: 95, basePower: 100, category: "Special", name: "Aeroblast", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, distance: 1, metronome: 1, wind: 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 (this.activePerHalf === 1) 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, metronome: 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, metronome: 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, metronome: 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" }, alluringvoice: { num: 914, accuracy: 100, basePower: 80, category: "Special", name: "Alluring Voice", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 1 }, secondary: { chance: 100, onHit(target, source, move) { if (target?.statsRaisedThisTurn) { target.addVolatile("confusion", source, move); } } }, target: "normal", type: "Fairy" }, allyswitch: { num: 502, accuracy: true, basePower: 0, category: "Status", name: "Ally Switch", pp: 15, priority: 2, flags: { metronome: 1 }, onPrepareHit(pokemon) { return pokemon.addVolatile("allyswitch"); }, onHit(pokemon) { let success = true; if (this.format.gameType !== "doubles" && this.format.gameType !== "triples") success = false; if (pokemon.side.active.length === 3 && pokemon.position === 1) success = false; const newPosition = pokemon.position === 0 ? pokemon.side.active.length - 1 : 0; if (!pokemon.side.active[newPosition]) success = false; if (pokemon.side.active[newPosition].fainted) success = false; if (!success) { this.add("-fail", pokemon, "move: Ally Switch"); this.attrLastMove("[still]"); return this.NOT_FAIL; } this.swapPosition(pokemon, newPosition, "[from] move: Ally Switch"); }, condition: { duration: 2, counterMax: 729, onStart() { this.effectState.counter = 3; }, onRestart(pokemon) { const counter = this.effectState.counter || 1; this.debug(`Ally Switch success chance: ${Math.round(100 / counter)}%`); const success = this.randomChance(1, counter); if (!success) { delete pokemon.volatiles["allyswitch"]; return false; } if (this.effectState.counter < this.effect.counterMax) { this.effectState.counter *= 3; } this.effectState.duration = 2; } }, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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) { if (ally.hasAbility("sapsipper")) { this.add("-immune", ally, "[from] ability: Sap Sipper"); continue; } if (ally.hasAbility("goodasgold")) { this.add("-immune", ally, "[from] ability: Good as Gold"); continue; } if (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, metronome: 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, failmimic: 1, failinstruct: 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); }, callsMove: true, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, distance: 1, metronome: 1, bullet: 1, pulse: 1 }, secondary: null, target: "any", type: "Fighting", contestType: "Beautiful" }, aurawheel: { num: 783, accuracy: 100, basePower: 110, category: "Physical", name: "Aura Wheel", pp: 10, priority: 0, flags: { protect: 1, mirror: 1 }, secondary: { chance: 100, self: { boosts: { spe: 1 } } }, onTry(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, metronome: 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, metronome: 1 }, sideCondition: "auroraveil", onTry() { return this.field.isWeather(["hail", "snowscape"]); }, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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", name: "Barb Barrage", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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: { metronome: 1 }, onHit(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", name: "Beak Blast", pp: 15, priority: -3, flags: { protect: 1, failmefirst: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, bullet: 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, metronome: 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, failcopycat: 1, failmimic: 1, slicing: 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, failmimic: 1, failinstruct: 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, metronome: 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, metronome: 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, metronome: 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 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, heal: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, failmimic: 1, failinstruct: 1, nosketch: 1 }, secondary: { chance: 30, status: "brn" }, target: "normal", type: "Fire" }, bleakwindstorm: { num: 846, accuracy: 80, basePower: 100, category: "Special", name: "Bleakwind Storm", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1, wind: 1 }, onModifyMove(move, pokemon, target) { if (target && ["raindance", "primordialsea"].includes(target.effectiveWeather())) { move.accuracy = true; } }, 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, metronome: 1, wind: 1 }, onModifyMove(move) { if (this.field.isWeather(["hail", "snowscape"])) 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, metronome: 1 }, onHit(target, source, move) { return target.addVolatile("trapped", source, move, "trapper"); }, secondary: null, target: "normal", type: "Normal", zMove: { boost: { def: 1 } }, contestType: "Cute" }, bloodmoon: { num: 901, accuracy: 100, basePower: 140, category: "Special", name: "Blood Moon", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1, cantusetwice: 1 }, secondary: null, target: "normal", type: "Normal" }, bloomdoom: { num: 644, accuracy: true, basePower: 1, category: "Physical", isNonstandard: "Past", name: "Bloom Doom", pp: 1, priority: 0, flags: {}, isZ: "grassiumz", secondary: null, target: "normal", type: "Grass", contestType: "Cool" }, blueflare: { num: 551, accuracy: 85, basePower: 130, category: "Special", name: "Blue Flare", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 1 }, secondary: null, target: "normal", type: "Electric" }, boltstrike: { num: 550, accuracy: 85, basePower: 130, category: "Physical", name: "Bolt Strike", pp: 5, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 1 }, multihit: [2, 5], secondary: null, target: "normal", type: "Grass", zMove: { basePower: 140 }, maxMove: { basePower: 130 }, contestType: "Cool" }, burningbulwark: { num: 908, accuracy: true, basePower: 0, category: "Status", name: "Burning Bulwark", pp: 10, priority: 4, flags: { metronome: 1, noassist: 1, failcopycat: 1 }, stallingMove: true, volatileStatus: "burningbulwark", 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"] || 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)) { source.trySetStatus("brn", target); } return this.NOT_FAIL; }, onHit(target, source, move) { if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) { source.trySetStatus("brn", target); } } }, secondary: null, target: "self", type: "Fire" }, burningjealousy: { num: 807, accuracy: 100, basePower: 70, category: "Special", name: "Burning Jealousy", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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", isNonstandard: "Unobtainable", name: "Burn Up", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, defrost: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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", name: "Ceaseless Edge", pp: 15, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, slicing: 1 }, onAfterHit(target, source, move) { if (!move.hasSheerForce && source.hp) { for (const side of source.side.foeSidesWithConditions()) { side.addSideCondition("spikes"); } } }, onAfterSubDamage(damage, target, source, move) { if (!move.hasSheerForce && source.hp) { for (const side of source.side.foeSidesWithConditions()) { side.addSideCondition("spikes"); } } }, secondary: {}, // Sheer Force-boosted 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, failmimic: 1, failinstruct: 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, metronome: 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, metronome: 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, metronome: 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, failmimic: 1, failinstruct: 1 }, 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: "snowscape", 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, metronome: 1 }, ignoreDefensive: true, ignoreEvasion: true, secondary: null, target: "normal", type: "Normal", contestType: "Tough" }, chloroblast: { num: 835, accuracy: 95, basePower: 150, category: "Special", name: "Chloroblast", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1 }, // Recoil implemented in battle-actions.ts 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, metronome: 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, metronome: 1 }, volatileStatus: "partiallytrapped", secondary: null, target: "normal", type: "Water", contestType: "Tough" }, clangingscales: { num: 691, accuracy: 100, basePower: 110, category: "Special", name: "Clanging Scales", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 1 }, selfBoost: { boosts: { def: -1 } }, secondary: null, target: "allAdjacentFoes", type: "Dragon", contestType: "Tough" }, clangoroussoul: { num: 775, accuracy: 100, basePower: 0, category: "Status", 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, failmimic: 1, failinstruct: 1, nosketch: 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, metronome: 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?.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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: { chance: 10, boosts: { spe: -1 } }, target: "normal", type: "Normal", contestType: "Tough" }, continentalcrush: { num: 632, accuracy: true, basePower: 1, category: "Physical", isNonstandard: "Past", name: "Continental Crush", pp: 1, priority: 0, flags: {}, isZ: "rockiumz", secondary: null, target: "normal", type: "Rock", contestType: "Cool" }, conversion: { num: 160, accuracy: true, basePower: 0, category: "Status", name: "Conversion", pp: 30, priority: 0, flags: { snatch: 1, metronome: 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", name: "Conversion 2", pp: 30, priority: 0, flags: { bypasssub: 1, metronome: 1 }, onHit(target, source) { if (!target.lastMoveUsed) { return false; } const possibleTypes = []; const attackType = target.lastMoveUsed.type; for (const typeName of this.dex.types.names()) { if (source.hasType(typeName)) continue; const typeCheck = this.dex.types.get(typeName).damageTaken[attackType]; if (typeCheck === 2 || typeCheck === 3) { possibleTypes.push(typeName); } } 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, failmimic: 1, failinstruct: 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); }, callsMove: true, 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, metronome: 1 }, onHit(target) { if (target.getAbility().flags["cantsuppress"]) return; if (target.newlySwitched || this.queue.willMove(target)) return; target.addVolatile("gastroacid"); }, onAfterSubDamage(damage, target) { if (target.getAbility().flags["cantsuppress"]) 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", isNonstandard: "Unobtainable", name: "Corrosive Gas", pp: 40, priority: 0, flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1, metronome: 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", name: "Cosmic Power", pp: 20, priority: 0, flags: { snatch: 1, metronome: 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, metronome: 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: { protect: 1, reflectable: 1, mirror: 1, metronome: 1, powder: 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, metronome: 1 }, onHitField(target, source) { const sideConditions = [ "mist", "lightscreen", "reflect", "spikes", "safeguard", "tailwind", "toxicspikes", "stealthrock", "waterpledge", "firepledge", "grasspledge", "stickyweb", "auroraveil", "luckychant", "gmaxsteelsurge", "gmaxcannonade", "gmaxvinelash", "gmaxwildfire", "gmaxvolcalith" ]; 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, metronome: 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, metronome: 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, metronome: 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 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, metronome: 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", name: "Crush Grip", pp: 5, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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", isNonstandard: "Unobtainable", name: "Cut", pp: 30, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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, mirror: 1, distance: 1, metronome: 1, pulse: 1 }, secondary: { chance: 20, volatileStatus: "flinch" }, target: "any", type: "Dark", contestType: "Cool" }, darkvoid: { num: 464, accuracy: 50, basePower: 0, category: "Status", name: "Dark Void", pp: 10, priority: 0, flags: { protect: 1, reflectable: 1, mirror: 1, metronome: 1, nosketch: 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, metronome: 1 }, secondary: null, target: "allAdjacentFoes", type: "Fairy", contestType: "Beautiful" }, decorate: { num: 777, accuracy: true, basePower: 0, category: "Status", name: "Decorate", pp: 15, priority: 0, flags: { 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: " + effect.name, `[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, metronome: 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, metronome: 1 }, secondary: { chance: 30, status: "par" }, target: "allAdjacent", type: "Electric", contestType: "Beautiful" }, direclaw: { num: 827, accuracy: 100, basePower: 80, category: "Physical", name: "Dire Claw", pp: 15, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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; if (!target.getAbility().flags["failroleplay"]) { for (const pokemon of source.alliesAndSelf()) { if (pokemon.ability === target.ability || pokemon.getAbility().flags["cantsuppress"]) 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", name: "Doom Desire", pp: 5, priority: 0, flags: { metronome: 1, 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: { metronome: 1, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: { chance: 30, status: "par" }, target: "normal", type: "Dragon", contestType: "Cool" }, dragoncheer: { num: 913, accuracy: true, basePower: 0, category: "Status", name: "Dragon Cheer", pp: 15, priority: 0, flags: { bypasssub: 1, allyanim: 1, metronome: 1 }, volatileStatus: "dragoncheer", condition: { onStart(target, source, effect) { if (target.volatiles["focusenergy"]) return false; if (effect && ["costar", "imposter", "psychup", "transform"].includes(effect.id)) { this.add("-start", target, "move: Dragon Cheer", "[silent]"); } else { this.add("-start", target, "move: Dragon Cheer"); } this.effectState.hasDragonType = target.hasType("Dragon"); }, onModifyCritRatio(critRatio, source) { return critRatio + (this.effectState.hasDragonType ? 2 : 1); } }, secondary: null, target: "adjacentAlly", type: "Dragon" }, dragonclaw: { num: 337, accuracy: 100, basePower: 80, category: "Physical", name: "Dragon Claw", pp: 15, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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", name: "Dragon Hammer", pp: 15, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, mirror: 1, distance: 1, metronome: 1, pulse: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, failcopycat: 1, failmimic: 1, failinstruct: 1, noparentalbond: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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" }, electroshot: { num: 905, accuracy: 100, basePower: 130, category: "Special", name: "Electro Shot", pp: 10, priority: 0, flags: { charge: 1, protect: 1, mirror: 1, metronome: 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 (["raindance", "primordialsea"].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; }, secondary: null, hasSheerForce: true, target: "normal", type: "Electric" }, electroweb: { num: 527, accuracy: 95, basePower: 55, category: "Special", name: "Electroweb", pp: 15, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 1 }, onTryHit(target, source) { if (target === source || target.volatiles["dynamax"]) return false; if (target.ability === source.ability || target.getAbility().flags["cantsuppress"] || target.ability === "truant" || source.getAbility().flags["noentrain"]) { 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, metronome: 1 }, secondary: null, target: "allAdjacentFoes", type: "Fire", contestType: "Beautiful" }, esperwing: { num: 840, accuracy: 100, basePower: 80, category: "Special", name: "Esper Wing", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, dance: 1, allyanim: 1, metronome: 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, metronome: 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, metronome: 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" }, ficklebeam: { num: 907, accuracy: 100, basePower: 80, category: "Special", name: "Fickle Beam", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1 }, onBasePower(basePower, pokemon) { if (this.randomChance(3, 10)) { this.attrLastMove("[anim] Fickle Beam All Out"); this.add("-activate", pokemon, "move: Fickle Beam"); return this.chainModify(2); } }, secondary: null, target: "normal", type: "Dragon" }, fierydance: { num: 552, accuracy: 100, basePower: 80, category: "Special", name: "Fiery Dance", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, dance: 1, metronome: 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; }, selfdestruct: "ifHit", category: "Special", name: "Final Gambit", pp: 5, priority: 0, flags: { protect: 1, metronome: 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, metronome: 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 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, metronome: 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 move.basePower; }, category: "Special", name: "Fire Pledge", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, nonsky: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 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, metronome: 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) { 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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", name: "Floral Healing", pp: 10, priority: 0, flags: { protect: 1, reflectable: 1, heal: 1, allyanim: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 1 }, volatileStatus: "focusenergy", condition: { onStart(target, source, effect) { if (target.volatiles["dragoncheer"]) return false; 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, metronome: 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, metronome: 1 }, volatileStatus: "foresight", onTryHit(target) { if (target.volatiles["miracleeye"]) return false; }, condition: { noCopy: true, onStart(pokemon) { this.add("-start", pokemon, "Foresight"); }, onNegateImmunity(pokemon, type) { if (pokemon.hasType("Ghost") && ["Normal", "Fighting"].includes(type)) return false; }, onModifyBoost(boosts) { if (boosts.evasion && boosts.evasion > 0) { boosts.evasion = 0; } } }, secondary: null, target: "normal", type: "Normal", zMove: { effect: "crit2" }, contestType: "Clever" }, forestscurse: { num: 571, accuracy: 100, basePower: 0, category: "Status", name: "Forest's Curse", pp: 20, priority: 0, flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1, metronome: 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, metronome: 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, metronome: 1 }, onEffectiveness(typeMod, target, type) { if (type === "Water") return 1; }, secondary: { chance: 10, status: "frz" }, target: "normal", type: "Ice", contestType: "Beautiful" }, freezeshock: { num: 553, accuracy: 90, basePower: 140, category: "Physical", name: "Freeze Shock", pp: 5, priority: 0, flags: { charge: 1, protect: 1, mirror: 1, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, multihit: [2, 5], secondary: null, target: "normal", type: "Normal", maxMove: { basePower: 100 }, contestType: "Tough" }, fusionbolt: { num: 559, accuracy: 100, basePower: 100, category: "Physical", name: "Fusion Bolt", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1 }, onBasePower(basePower, pokemon) { if (this.lastSuccessfulMoveThisTurn === "fusionflare") { this.debug("double power"); return this.chainModify(2); } }, secondary: null, target: "normal", type: "Electric", contestType: "Cool" }, fusionflare: { num: 558, accuracy: 100, basePower: 100, category: "Special", name: "Fusion Flare", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, defrost: 1, metronome: 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, metronome: 1, futuremove: 1 }, ignoreImmunity: true, onTry(source, target) { if (!target.side.addSlotCondition(target, "futuremove")) return false; Object.assign(target.side.slotConditions[target.position]["futuremove"], { move: "futuresight", source, moveData: { id: "futuresight", name: "Future Sight", accuracy: 100, basePower: 120, category: "Special", priority: 0, flags: { allyanim: 1, metronome: 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, metronome: 1 }, volatileStatus: "gastroacid", onTryHit(target) { if (target.getAbility().flags["cantsuppress"]) { 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().flags["cantsuppress"]) 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1, cantusetwice: 1 }, 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", name: "Glaciate", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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.randomChance(1, 2)) 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.randomChance(1, 2)) return; target.addVolatile("yawn"); }, onAfterSubDamage(damage, target) { if (target.status || !target.runStatusImmunity("slp")) return; if (this.randomChance(1, 2)) 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"); }, onSwitchIn(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 * 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, metronome: 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 move.basePower; }, category: "Special", name: "Grass Pledge", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, nonsky: 1, metronome: 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, metronome: 1 }, status: "slp", secondary: null, target: "normal", type: "Grass", zMove: { boost: { spe: 1 } }, contestType: "Clever" }, grassyglide: { num: 803, accuracy: 100, basePower: 55, category: "Physical", name: "Grassy Glide", pp: 20, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, bullet: 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: { metronome: 1 }, 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, metronome: 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: { metronome: 1 }, 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, metronome: 1 }, boosts: { def: 1 }, secondary: null, target: "self", type: "Normal", zMove: { boost: { def: 1 } }, contestType: "Tough" }, hardpress: { num: 912, accuracy: 100, basePower: 0, basePowerCallback(pokemon, target) { const hp = target.hp; const maxHP = target.maxhp; const bp = Math.floor(Math.floor((100 * (100 * Math.floor(hp * 4096 / maxHP)) + 2048 - 1) / 4096) / 100) || 1; this.debug(`BP for ${hp}/${maxHP} HP: ${bp}`); return bp; }, category: "Physical", name: "Hard Press", pp: 10, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 }, secondary: null, target: "normal", type: "Steel" }, haze: { num: 114, accuracy: true, basePower: 0, category: "Status", name: "Haze", pp: 30, priority: 0, flags: { bypasssub: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, recoil: [1, 2], secondary: null, target: "normal", type: "Rock", contestType: "Tough" }, healbell: { num: 215, accuracy: true, basePower: 0, category: "Status", name: "Heal Bell", pp: 5, priority: 0, flags: { snatch: 1, sound: 1, distance: 1, bypasssub: 1, metronome: 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) { if (ally.hasAbility("soundproof")) { this.add("-immune", ally, "[from] ability: Soundproof"); continue; } if (ally.hasAbility("goodasgold")) { this.add("-immune", ally, "[from] ability: Good as Gold"); 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, metronome: 1 }, volatileStatus: "healblock", condition: { duration: 5, durationCallback(target, source, effect) { if (effect?.name === "Psychic Noise") { return 2; } 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, effect) { if (effect?.name === "Psychic Noise") return; 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, metronome: 1 }, onTryHit(source) { if (!this.canSwitch(source.side)) { this.attrLastMove("[still]"); this.add("-fail", source); return this.NOT_FAIL; } }, selfdestruct: "ifHit", slotCondition: "healingwish", condition: { onSwitchIn(target) { this.singleEvent("Swap", this.effect, this.effectState, target); }, 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, metronome: 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, reflectable: 1, distance: 1, heal: 1, allyanim: 1, metronome: 1, pulse: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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", isNonstandard: "Unobtainable", name: "Hold Back", pp: 40, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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", isNonstandard: "Unobtainable", name: "Hold Hands", pp: 40, priority: 0, flags: { bypasssub: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failmimic: 1, failinstruct: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 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, nosketch: 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, metronome: 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, metronome: 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 *= 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, failinstruct: 1, bullet: 1, noparentalbond: 1 }, onModifyMove(move, pokemon, target) { if (pokemon.volatiles["iceball"] || pokemon.status === "slp" || !target) return; pokemon.addVolatile("iceball"); if (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, metronome: 1 }, secondary: { chance: 10, status: "frz" }, target: "normal", type: "Ice", contestType: "Beautiful" }, iceburn: { num: 554, accuracy: 90, basePower: 140, category: "Special", name: "Ice Burn", pp: 5, priority: 0, flags: { charge: 1, protect: 1, mirror: 1, 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, onAfterHit(target, source) { if (source.hp) { this.field.clearTerrain(); } }, onAfterSubDamage(damage, target, source) { if (source.hp) { 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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", name: "Infernal Parade", pp: 15, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { metronome: 1 }, 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: { chance: 30, boosts: { def: -1 } }, target: "normal", type: "Steel", contestType: "Cool" }, ivycudgel: { num: 904, accuracy: 100, basePower: 100, category: "Physical", name: "Ivy Cudgel", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1 }, critRatio: 2, onPrepareHit(target, source, move) { if (move.type !== "Grass") { this.attrLastMove("[anim] Ivy Cudgel " + move.type); } }, onModifyType(move, pokemon) { switch (pokemon.species.name) { case "Ogerpon-Wellspring": case "Ogerpon-Wellspring-Tera": move.type = "Water"; break; case "Ogerpon-Hearthflame": case "Ogerpon-Hearthflame-Tera": move.type = "Fire"; break; case "Ogerpon-Cornerstone": case "Ogerpon-Cornerstone-Tera": move.type = "Rock"; break; } }, secondary: null, target: "normal", type: "Grass" }, jawlock: { num: 746, accuracy: 100, basePower: 80, category: "Physical", name: "Jaw Lock", pp: 10, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 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, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: { chance: 100, boosts: { spd: -2 } }, target: "normal", type: "Psychic" }, lunarblessing: { num: 849, accuracy: true, basePower: 0, category: "Status", name: "Lunar Blessing", pp: 5, priority: 0, flags: { snatch: 1, heal: 1, metronome: 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, dance: 1, heal: 1, metronome: 1 }, onTryHit(source) { if (!this.canSwitch(source.side)) { this.attrLastMove("[still]"); this.add("-fail", source); return this.NOT_FAIL; } }, selfdestruct: "ifHit", slotCondition: "lunardance", condition: { onSwitchIn(target) { this.singleEvent("Swap", this.effect, this.effectState, target); }, 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, metronome: 1 }, secondary: { chance: 100, boosts: { atk: -1 } }, target: "normal", type: "Bug", contestType: "Cute" }, lusterpurge: { num: 295, accuracy: 100, basePower: 95, category: "Special", name: "Luster Purge", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, failmimic: 1, failinstruct: 1, nosketch: 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: { metronome: 1 }, 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"] || target.isSemiInvulnerable()) { return; } const newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = this.effectState.pranksterBoosted; this.actions.useMove(newMove, target, { target: source }); return null; }, onAllyTryHitSide(target, source, move) { if (target.isAlly(source) || move.hasBounced || !move.flags["reflectable"] || target.isSemiInvulnerable()) { return; } const newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = false; this.actions.useMove(newMove, this.effectState.target, { 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: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1, metronome: 1, powder: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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, metronome: 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, metronome: 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" }, malignantchain: { num: 919, accuracy: 100, basePower: 100, category: "Special", name: "Malignant Chain", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1 }, secondary: { chance: 50, status: "tox" }, target: "normal", type: "Poison" }, 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" }, matchagotcha: { num: 902, accuracy: 90, basePower: 80, category: "Special", name: "Matcha Gotcha", pp: 15, priority: 0, flags: { protect: 1, mirror: 1, defrost: 1, heal: 1, metronome: 1 }, drain: [1, 2], thawsTarget: true, secondary: { chance: 20, status: "brn" }, target: "allAdjacentFoes", type: "Grass" }, 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, metronome: 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, metronome: 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, failmimic: 1, failinstruct: 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); } }, callsMove: true, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1, failmefirst: 1 }, onTry(source) { const lastDamagedBy = source.getLastDamagedBy(true); if (!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, metronome: 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, metronome: 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: { recharge: 1, protect: 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, metronome: 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, metronome: 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, failmimic: 1, failinstruct: 1 }, onHit(pokemon) { const moves = this.dex.moves.all().filter((move) => (!move.isNonstandard || move.isNonstandard === "Unobtainable") && move.flags["metronome"]); let randomMove = ""; if (moves.length) { moves.sort((a, b) => a.num - b.num); randomMove = this.sample(moves).id; } if (!randomMove) return false; this.actions.useMove(randomMove, pokemon); }, callsMove: true, secondary: null, target: "self", type: "Normal", contestType: "Cute" }, mightycleave: { num: 910, accuracy: 100, basePower: 95, category: "Physical", name: "Mighty Cleave", pp: 5, priority: 0, flags: { contact: 1, mirror: 1, metronome: 1, slicing: 1 }, secondary: null, target: "normal", type: "Rock" }, milkdrink: { num: 208, accuracy: true, basePower: 0, category: "Status", name: "Milk Drink", pp: 5, priority: 0, flags: { snatch: 1, heal: 1, metronome: 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, failmimic: 1, failinstruct: 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, metronome: 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, metronome: 1 }, volatileStatus: "minimize", condition: { noCopy: true, onRestart: () => null, onSourceModifyDamage(damage, source, target, move) { const boostedMoves = [ "stomp", "steamroller", "bodyslam", "flyingpress", "dragonrush", "heatcrash", "heavyslam", "maliciousmoonsault", "supercellslam" ]; if (boostedMoves.includes(move.id)) { return this.chainModify(2); } }, onAccuracy(accuracy, target, source, move) { const boostedMoves = [ "stomp", "steamroller", "bodyslam", "flyingpress", "dragonrush", "heatcrash", "heavyslam", "maliciousmoonsault", "supercellslam" ]; 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, metronome: 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, failmimic: 1, failinstruct: 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; }, callsMove: true, 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, metronome: 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, metronome: 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: 95, category: "Special", name: "Mist Ball", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: { chance: 30, boosts: { spa: -1 } }, target: "normal", type: "Fairy", contestType: "Beautiful" }, moongeistbeam: { num: 714, accuracy: 100, basePower: 100, category: "Special", name: "Moongeist Beam", pp: 5, priority: 0, flags: { protect: 1, mirror: 1 }, ignoreAbility: true, secondary: null, target: "normal", type: "Ghost", contestType: "Cool" }, moonlight: { num: 236, accuracy: true, basePower: 0, category: "Status", name: "Moonlight", pp: 5, priority: 0, flags: { snatch: 1, heal: 1, metronome: 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 "snowscape": 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, metronome: 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 "snowscape": 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, metronome: 1 }, onAfterHit(target, pokemon, move) { if (!move.hasSheerForce) { 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, move) { if (!move.hasSheerForce) { 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", name: "Mountain Gale", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: { chance: 100, boosts: { spa: -1 } }, target: "normal", type: "Fire", contestType: "Beautiful" }, mysticalpower: { num: 832, accuracy: 90, basePower: 70, category: "Special", name: "Mystical Power", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, failmimic: 1, failinstruct: 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; }, callsMove: true, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, failmimic: 1, failinstruct: 1, nosketch: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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?.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, metronome: 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, metronome: 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, mirror: 1, pulse: 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, metronome: 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, metronome: 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, metronome: 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" }, paraboliccharge: { num: 570, accuracy: 100, basePower: 65, category: "Special", name: "Parabolic Charge", pp: 20, priority: 0, flags: { protect: 1, mirror: 1, heal: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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", 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 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, metronome: 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, metronome: 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: { protect: 1, reflectable: 1, mirror: 1, metronome: 1, powder: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, allyanim: 1, metronome: 1, bullet: 1 }, onTryHit(target, source, move) { if (source.isAlly(target)) { move.basePower = 0; move.infiltrates = true; } }, onTryMove(source, target, move) { if (source.isAlly(target) && source.volatiles["healblock"]) { this.attrLastMove("[still]"); this.add("cant", source, "move: Heal Block", move); return false; } }, onHit(target, source, move) { if (source.isAlly(target)) { if (!this.heal(Math.floor(target.baseMaxhp * 0.5))) { if (target.volatiles["healblock"] && target.hp !== target.maxhp) { this.attrLastMove("[still]"); this.add("cant", source, "move: Heal Block", move); } else { 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, metronome: 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, metronome: 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: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1, metronome: 1, powder: 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, metronome: 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, metronome: 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"); 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 Shift"); const newatk = pokemon.storedStats.def; const newdef = pokemon.storedStats.atk; pokemon.storedStats.atk = newatk; pokemon.storedStats.def = newdef; }, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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", name: "Prismatic Laser", pp: 10, priority: 0, flags: { recharge: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, onHit(target, source) { let i; for (i in target.boosts) { source.boosts[i] = target.boosts[i]; } const volatilesToCopy = ["dragoncheer", "focusenergy", "gmaxchistrike", "laserfocus"]; for (const volatile of volatilesToCopy) source.removeVolatile(volatile); for (const volatile of volatilesToCopy) { if (target.volatiles[volatile]) { source.addVolatile(volatile); if (volatile === "gmaxchistrike") source.volatiles[volatile].layers = target.volatiles[volatile].layers; if (volatile === "dragoncheer") source.volatiles[volatile].hasDragonType = target.volatiles[volatile].hasDragonType; } } 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, metronome: 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: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 1 }, onTryHit(pokemon) { pokemon.side.removeSideCondition("reflect"); pokemon.side.removeSideCondition("lightscreen"); pokemon.side.removeSideCondition("auroraveil"); }, secondary: null, target: "normal", type: "Psychic", contestType: "Clever" }, psychicnoise: { num: 917, accuracy: 100, basePower: 75, category: "Special", name: "Psychic Noise", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 1 }, secondary: { chance: 100, volatileStatus: "healblock" }, target: "normal", type: "Psychic" }, psychicterrain: { num: 678, accuracy: true, basePower: 0, category: "Status", name: "Psychic Terrain", pp: 10, priority: 0, flags: { nonsky: 1, metronome: 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", name: "Psycho Boost", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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", name: "Psyshield Bash", pp: 10, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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 || source.canTerastallize) { for (const [actionIndex, action] of this.queue.entries()) { if (action.pokemon === source) { if (action.choice === "megaEvo") { this.actions.runMegaEvo(source); } else if (action.choice === "terastallize") { this.actions.terastallize(source); } else { continue; } 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, metronome: 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, metronome: 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, metronome: 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: { noassist: 1, failcopycat: 1, powder: 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", 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: { metronome: 1 }, 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, metronome: 1 }, onAfterHit(target, pokemon, move) { if (!move.hasSheerForce) { 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, move) { if (!move.hasSheerForce) { 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, "0", "[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, metronome: 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")) { this.add("-fail", source, "[from] ability: Insomnia", `[of] ${source}`); return null; } if (source.hasAbility("vitalspirit")) { this.add("-fail", source, "[from] ability: Vital Spirit", `[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, metronome: 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, metronome: 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, metronome: 1 }, onModifyType(move, pokemon) { const types = pokemon.getTypes(); let type = types[0]; if (type === "Bird") type = "???"; if (type === "???" && types[1]) type = types[1]; 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, metronome: 1 }, secondary: null, target: "normal", type: "Fighting", contestType: "Tough" }, reversal: { num: 179, accuracy: 100, basePower: 0, basePowerCallback(pokemon) { 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, metronome: 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: { heal: 1, nosketch: 1 }, 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: { chance: 100, boosts: { spe: -1 } }, target: "normal", type: "Rock", contestType: "Clever" }, rockwrecker: { num: 439, accuracy: 90, basePower: 150, category: "Physical", name: "Rock Wrecker", pp: 5, priority: 0, flags: { recharge: 1, protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 1 }, onTryHit(target, source) { if (target.ability === source.ability) return false; if (target.getAbility().flags["failroleplay"] || source.getAbility().flags["cantsuppress"]) 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, metronome: 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 *= 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, metronome: 1, failinstruct: 1, noparentalbond: 1 }, onModifyMove(move, pokemon, target) { if (pokemon.volatiles["rollout"] || pokemon.status === "slp" || !target) return; pokemon.addVolatile("rollout"); if (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, metronome: 1 }, heal: [1, 2], self: { volatileStatus: "roost" }, condition: { duration: 1, onResidualOrder: 25, onStart(target) { if (target.terastallized) { if (target.hasType("Flying")) { this.add("-hint", "If a Terastallized Pokemon uses Roost, it remains Flying-type."); } return false; } this.add("-singleturn", target, "move: Roost"); }, 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, metronome: 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, metronome: 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", name: "Sacred Fire", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, defrost: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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", name: "Sandsear Storm", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1, wind: 1 }, onModifyMove(move, pokemon, target) { if (target && ["raindance", "primordialsea"].includes(target.effectiveWeather())) { move.accuracy = true; } }, 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: { metronome: 1, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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", overrideDefensiveStat: "def", name: "Secret Sword", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, slicing: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 1 }, secondary: null, target: "normal", type: "Grass", contestType: "Tough" }, seedflare: { num: 465, accuracy: 85, basePower: 120, category: "Special", name: "Seed Flare", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: null, 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, metronome: 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) || source.volatiles["commanded"]) { 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, metronome: 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, metronome: 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.randomChance(1, 2)) { 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, metronome: 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", name: "Shelter", pp: 10, priority: 0, flags: { snatch: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: { chance: 10, self: { boosts: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } } }, target: "normal", type: "Bug", contestType: "Beautiful" }, simplebeam: { num: 493, accuracy: 100, basePower: 0, category: "Status", name: "Simple Beam", pp: 15, priority: 0, flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1, metronome: 1 }, onTryHit(target) { if (target.getAbility().flags["cantsuppress"] || 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, metronome: 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", name: "Sketch", pp: 1, noPPBoosts: true, priority: 0, flags: { bypasssub: 1, allyanim: 1, failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failmimic: 1, failinstruct: 1, nosketch: 1 }, onHit(target, source) { const move = target.lastMove; if (source.transformed || !move || source.moves.includes(move.id)) return false; if (move.flags["nosketch"] || move.isZ || move.isMax) return false; const sketchIndex = source.moves.indexOf("sketch"); if (sketchIndex < 0) return false; const sketchedMove = { move: move.name, id: move.id, pp: move.pp, maxpp: move.pp, target: move.target, disabled: false, used: false }; source.moveSlots[sketchIndex] = sketchedMove; source.baseMoveSlots[sketchIndex] = sketchedMove; this.add("-activate", source, "move: Sketch", move.name); }, secondary: null, target: "normal", type: "Normal", zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } }, contestType: "Clever" }, skillswap: { num: 285, accuracy: true, basePower: 0, category: "Status", name: "Skill Swap", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, bypasssub: 1, allyanim: 1, metronome: 1 }, onTryHit(target, source) { const targetAbility = target.getAbility(); const sourceAbility = source.getAbility(); if (sourceAbility.flags["failskillswap"] || targetAbility.flags["failskillswap"] || target.volatiles["dynamax"]) { return false; } const sourceCanBeSet = this.runEvent("SetAbility", source, source, this.effect, targetAbility); if (!sourceCanBeSet) return sourceCanBeSet; const targetCanBeSet = this.runEvent("SetAbility", target, source, this.effect, sourceAbility); if (!targetCanBeSet) return targetCanBeSet; }, onHit(target, source, move) { const targetAbility = target.getAbility(); const sourceAbility = source.getAbility(); if (target.isAlly(source)) { this.add("-activate", source, "move: Skill Swap", "", "", `[of] ${target}`); } else { this.add("-activate", source, "move: Skill Swap", targetAbility, sourceAbility, `[of] ${target}`); } this.singleEvent("End", sourceAbility, source.abilityState, source); this.singleEvent("End", targetAbility, target.abilityState, target); source.ability = targetAbility.id; target.ability = sourceAbility.id; source.abilityState = this.initEffectState({ id: this.toID(source.ability), target: source }); target.abilityState = this.initEffectState({ id: this.toID(target.ability), target }); source.volatileStaleness = void 0; 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, reflectable: 1, mirror: 1, metronome: 1, powder: 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, failmimic: 1, failinstruct: 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); }, callsMove: true, 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: "snowscape", 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, metronome: 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, metronome: 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, metronome: 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", "snowscape"]; 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, metronome: 1, nosleeptalk: 1, failinstruct: 1, slicing: 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", "snowscape"]; 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: { chance: 30, status: "par" }, target: "normal", type: "Electric", contestType: "Cool" }, sparklingaria: { num: 664, accuracy: 100, basePower: 90, category: "Special", name: "Sparkling Aria", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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++; }, onSwitchIn(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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, reflectable: 1, mirror: 1, metronome: 1, powder: 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, noCopy: true, // doesn't get copied by Baton Pass 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", 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, metronome: 1, mustpressure: 1 }, sideCondition: "stealthrock", condition: { // this is a side condition onSideStart(side) { this.add("-sidestart", side, "move: Stealth Rock"); }, onSwitchIn(pokemon) { if (pokemon.hasItem("heavydutyboots")) return; const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove("stealthrock")), -6, 6); this.damage(pokemon.maxhp * 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, sideCondition: "stickyweb", condition: { onSideStart(side) { this.add("-sidestart", side, "move: Sticky Web"); }, onSwitchIn(pokemon) { if (!pokemon.isGrounded() || pokemon.hasItem("heavydutyboots")) return; this.add("-activate", pokemon, "move: Sticky Web"); this.boost({ spe: -1 }, pokemon, pokemon.side.foe.active[0], 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, metronome: 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, metronome: 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, metronome: 1 }, secondary: null, target: "normal", type: "Ground", contestType: "Tough" }, stoneaxe: { num: 830, accuracy: 90, basePower: 65, category: "Physical", name: "Stone Axe", pp: 15, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, slicing: 1 }, onAfterHit(target, source, move) { if (!move.hasSheerForce && source.hp) { for (const side of source.side.foeSidesWithConditions()) { side.addSideCondition("stealthrock"); } } }, onAfterSubDamage(damage, target, source, move) { if (!move.hasSheerForce && source.hp) { for (const side of source.side.foeSidesWithConditions()) { side.addSideCondition("stealthrock"); } } }, secondary: {}, // Sheer Force-boosted 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, metronome: 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, metronome: 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, metronome: 1 }, willCrit: true, secondary: null, target: "normal", type: "Fighting", contestType: "Cool" }, strangesteam: { num: 790, accuracy: 95, basePower: 90, category: "Special", name: "Strange Steam", pp: 10, priority: 0, flags: { protect: 1, mirror: 1 }, secondary: { chance: 20, volatileStatus: "confusion" }, target: "normal", type: "Fairy" }, strength: { num: 70, accuracy: 100, basePower: 80, category: "Physical", name: "Strength", pp: 15, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, failmimic: 1, failinstruct: 1, nosketch: 1 }, 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, metronome: 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, metronome: 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: { protect: 1, reflectable: 1, mirror: 1, metronome: 1, powder: 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, metronome: 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, metronome: 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 || move.id === "chloroblast") { this.damage(this.actions.calcRecoilDamage(damage, move, source), 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, metronome: 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: { metronome: 1 }, weather: "sunnyday", secondary: null, target: "all", type: "Fire", zMove: { boost: { spe: 1 } }, contestType: "Beautiful" }, sunsteelstrike: { num: 713, accuracy: 100, basePower: 100, category: "Physical", name: "Sunsteel Strike", pp: 5, priority: 0, flags: { contact: 1, protect: 1, mirror: 1 }, ignoreAbility: true, secondary: null, target: "normal", type: "Steel", contestType: "Cool" }, supercellslam: { num: 916, accuracy: 95, basePower: 100, category: "Physical", name: "Supercell Slam", pp: 15, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 }, hasCrashDamage: true, onMoveFail(target, source, move) { this.damage(source.baseMaxhp / 2, source, source, this.dex.conditions.get("Supercell Slam")); }, secondary: null, target: "normal", type: "Electric" }, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, mirror: 1, punch: 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, metronome: 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, metronome: 1 }, onTry(source, target, move) { if (move.sourceEffect === "snatch") return; return !!source.volatiles["stockpile"]; }, onHit(pokemon) { const layers = pokemon.volatiles["stockpile"]?.layers || 1; const healAmount = [0.25, 0.5, 1]; const success = !!this.heal(this.modify(pokemon.maxhp, healAmount[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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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 "snowscape": 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" }, syrupbomb: { num: 903, accuracy: 85, basePower: 60, category: "Special", name: "Syrup Bomb", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1, bullet: 1 }, condition: { noCopy: true, duration: 4, onStart(pokemon) { this.add("-start", pokemon, "Syrup Bomb"); }, onUpdate(pokemon) { if (this.effectState.source && !this.effectState.source.isActive) { pokemon.removeVolatile("syrupbomb"); } }, onResidualOrder: 14, onResidual(pokemon) { this.boost({ spe: -1 }, pokemon, this.effectState.source); }, onEnd(pokemon) { this.add("-end", pokemon, "Syrup Bomb", "[silent]"); } }, secondary: { chance: 100, volatileStatus: "syrupbomb" }, target: "normal", type: "Grass" }, tachyoncutter: { num: 911, accuracy: true, basePower: 50, category: "Special", name: "Tachyon Cutter", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1, slicing: 1 }, multihit: 2, secondary: null, target: "normal", type: "Steel", zMove: { basePower: 180 }, maxMove: { basePower: 140 }, contestType: "Clever" }, tackle: { num: 33, accuracy: 100, basePower: 40, category: "Physical", name: "Tackle", pp: 35, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 }, secondary: null, target: "normal", type: "Normal", contestType: "Tough" }, tailglow: { num: 294, accuracy: true, basePower: 0, category: "Status", name: "Tail Glow", pp: 20, priority: 0, flags: { snatch: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, recoil: [1, 4], secondary: null, target: "normal", type: "Normal", contestType: "Tough" }, takeheart: { num: 850, accuracy: true, basePower: 0, category: "Status", name: "Take Heart", pp: 15, priority: 0, flags: { snatch: 1, metronome: 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, metronome: 1 }, volatileStatus: "tarshot", condition: { onStart(pokemon) { if (pokemon.terastallized) return false; 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { metronome: 1 }, onTry(source) { return !!this.canSwitch(source.side); }, selfSwitch: true, secondary: null, target: "self", type: "Psychic", zMove: { effect: "heal" }, contestType: "Cool" }, temperflare: { num: 915, accuracy: 100, basePower: 75, basePowerCallback(pokemon, target, move) { if (pokemon.moveLastTurnResult === false) { this.debug("doubling Temper Flare BP due to previous move failure"); return move.basePower * 2; } return move.basePower; }, category: "Physical", name: "Temper Flare", pp: 10, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 }, secondary: null, target: "normal", type: "Fire" }, terablast: { num: 851, accuracy: 100, basePower: 80, basePowerCallback(pokemon, target, move) { if (pokemon.terastallized === "Stellar") { return 100; } return move.basePower; }, category: "Special", name: "Tera Blast", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1, mustpressure: 1 }, onPrepareHit(target, source, move) { if (source.terastallized) { this.attrLastMove("[anim] Tera Blast " + source.teraType); } }, 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"; } if (pokemon.terastallized === "Stellar") { move.self = { boosts: { atk: -1, spa: -1 } }; } }, secondary: null, target: "normal", type: "Normal" }, terastarstorm: { num: 906, accuracy: 100, basePower: 120, category: "Special", name: "Tera Starstorm", pp: 5, priority: 0, flags: { protect: 1, mirror: 1, noassist: 1, failcopycat: 1, failmimic: 1, nosketch: 1 }, onModifyType(move, pokemon) { if (pokemon.species.name === "Terapagos-Stellar") { move.type = "Stellar"; if (pokemon.terastallized && pokemon.getStat("atk", false, true) > pokemon.getStat("spa", false, true)) { move.category = "Physical"; } } }, onModifyMove(move, pokemon) { if (pokemon.species.name === "Terapagos-Stellar") { move.target = "allAdjacentFoes"; } }, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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" }, thunderclap: { num: 909, accuracy: 100, basePower: 70, category: "Special", name: "Thunderclap", pp: 5, priority: 1, flags: { protect: 1, mirror: 1, metronome: 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: "Electric", contestType: "Clever" }, thunderfang: { num: 422, accuracy: 95, basePower: 65, category: "Physical", name: "Thunder Fang", pp: 15, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, bite: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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", name: "Topsy-Turvy", pp: 20, priority: 0, flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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++; }, onSwitchIn(pokemon) { if (!pokemon.isGrounded()) return; if (pokemon.hasType("Poison")) { this.add("-sideend", pokemon.side, "move: Toxic Spikes", `[of] ${pokemon}`); pokemon.side.removeSideCondition("toxicspikes"); } else if (pokemon.hasType("Steel") || pokemon.hasItem("heavydutyboots")) { } 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", name: "Toxic Thread", pp: 20, priority: 0, flags: { protect: 1, reflectable: 1, mirror: 1, metronome: 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, failmimic: 1, failinstruct: 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, metronome: 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, metronome: 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, metronome: 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", name: "Triple Arrows", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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", name: "Triple Kick", pp: 10, priority: 0, flags: { contact: 1, protect: 1, mirror: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, selfSwitch: true, secondary: null, target: "normal", type: "Bug", contestType: "Cute" }, upperhand: { num: 918, accuracy: 100, basePower: 65, category: "Physical", name: "Upper Hand", pp: 15, priority: 3, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 }, onTry(source, target) { const action = this.queue.willMove(target); const move = action?.choice === "move" ? action.move : null; if (!move || move.priority <= 0.1 || move.category === "Status") { return false; } }, secondary: { chance: 100, volatileStatus: "flinch" }, target: "normal", type: "Fighting" }, uproar: { num: 253, accuracy: 100, basePower: 90, category: "Special", name: "Uproar", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 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, metronome: 1 }, secondary: null, target: "normal", type: "Fighting", contestType: "Cool" }, vcreate: { num: 557, accuracy: 95, basePower: 180, category: "Physical", isNonstandard: "Unobtainable", 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, metronome: 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, metronome: 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", name: "Victory Dance", pp: 10, priority: 0, flags: { snatch: 1, dance: 1, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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 move.basePower; }, category: "Special", name: "Water Pledge", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, nonsky: 1, metronome: 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, mirror: 1, distance: 1, metronome: 1, pulse: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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 "snowscape": 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 "snowscape": 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, metronome: 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, metronome: 1, noassist: 1, failcopycat: 1, wind: 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, mirror: 1, punch: 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, failmimic: 1, failinstruct: 1, nosketch: 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", name: "Wildbolt Storm", pp: 10, priority: 0, flags: { protect: 1, mirror: 1, metronome: 1, wind: 1 }, onModifyMove(move, pokemon, target) { if (target && ["raindance", "primordialsea"].includes(target.effectiveWeather())) { move.accuracy = true; } }, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, slotCondition: "Wish", condition: { onStart(pokemon, source) { this.effectState.hp = source.maxhp / 2; this.effectState.startingTurn = this.getOverflowedTurnCount(); if (this.effectState.startingTurn === 255) { this.hint(`In Gen 8+, Wish will never resolve when used on the ${this.turn}th turn.`); } }, onResidualOrder: 4, onResidual(target) { if (this.getOverflowedTurnCount() <= this.effectState.startingTurn) return; target.side.removeSlotCondition(this.getAtSlot(this.effectState.sourceSlot), "wish"); }, 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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, metronome: 1 }, onTryImmunity(target) { if (target.ability === "truant" || target.ability === "insomnia") { return false; } }, onTryHit(target) { if (target.getAbility().flags["cantsuppress"]) { 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, metronome: 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, metronome: 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, metronome: 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, metronome: 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: { protect: 1, mirror: 1, metronome: 1, bullet: 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, metronome: 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, metronome: 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" }, // CAP moves 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" }, 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" } }; //# sourceMappingURL=moves.js.map