22142 lines
519 KiB
JavaScript
22142 lines
519 KiB
JavaScript
"use strict";
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
var moves_exports = {};
|
|
__export(moves_exports, {
|
|
Moves: () => Moves
|
|
});
|
|
module.exports = __toCommonJS(moves_exports);
|
|
const Moves = {
|
|
"10000000voltthunderbolt": {
|
|
num: 719,
|
|
accuracy: true,
|
|
basePower: 195,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "10,000,000 Volt Thunderbolt",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "pikashuniumz",
|
|
critRatio: 3,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
absorb: {
|
|
num: 71,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Special",
|
|
name: "Absorb",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, heal: 1 },
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever"
|
|
},
|
|
accelerock: {
|
|
num: 709,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Accelerock",
|
|
pp: 20,
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Cool"
|
|
},
|
|
acid: {
|
|
num: 51,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Acid",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Poison",
|
|
contestType: "Clever"
|
|
},
|
|
acidarmor: {
|
|
num: 151,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Acid Armor",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Poison",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Tough"
|
|
},
|
|
aciddownpour: {
|
|
num: 628,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Acid Downpour",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "poisoniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Cool"
|
|
},
|
|
acidspray: {
|
|
num: 491,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Acid Spray",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spd: -2
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Beautiful"
|
|
},
|
|
acrobatics: {
|
|
num: 512,
|
|
accuracy: 100,
|
|
basePower: 55,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (!pokemon.item) {
|
|
this.debug("BP doubled for no item");
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Acrobatics",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, distance: 1 },
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
acupressure: {
|
|
num: 367,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Acupressure",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {},
|
|
onHit(target) {
|
|
const stats = [];
|
|
let stat;
|
|
for (stat in target.boosts) {
|
|
if (target.boosts[stat] < 6) {
|
|
stats.push(stat);
|
|
}
|
|
}
|
|
if (stats.length) {
|
|
const randomStat = this.sample(stats);
|
|
const boost = {};
|
|
boost[randomStat] = 2;
|
|
this.boost(boost);
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentAllyOrSelf",
|
|
type: "Normal",
|
|
zMove: { effect: "crit2" },
|
|
contestType: "Tough"
|
|
},
|
|
aerialace: {
|
|
num: 332,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Aerial Ace",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, distance: 1, slicing: 1 },
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
aeroblast: {
|
|
num: 177,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Aeroblast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, distance: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
afteryou: {
|
|
num: 495,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "After You",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bypasssub: 1, allyanim: 1 },
|
|
onHit(target) {
|
|
if (target.side.active.length < 2)
|
|
return false;
|
|
const action = this.queue.willMove(target);
|
|
if (action) {
|
|
this.queue.prioritizeAction(action);
|
|
this.add("-activate", target, "move: After You");
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
agility: {
|
|
num: 97,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Agility",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
spe: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cool"
|
|
},
|
|
aircutter: {
|
|
num: 314,
|
|
accuracy: 95,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Air Cutter",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, slicing: 1, wind: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
airslash: {
|
|
num: 403,
|
|
accuracy: 95,
|
|
basePower: 75,
|
|
category: "Special",
|
|
name: "Air Slash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, distance: 1, slicing: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
alloutpummeling: {
|
|
num: 624,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "All-Out Pummeling",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "fightiniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
allyswitch: {
|
|
num: 502,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Ally Switch",
|
|
pp: 15,
|
|
priority: 2,
|
|
flags: {},
|
|
stallingMove: true,
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onTryHit(source) {
|
|
if (source.side.active.length === 1)
|
|
return false;
|
|
if (source.side.active.length === 3 && source.position === 1)
|
|
return false;
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
const newPosition = pokemon.position === 0 ? pokemon.side.active.length - 1 : 0;
|
|
if (!pokemon.side.active[newPosition])
|
|
return false;
|
|
if (pokemon.side.active[newPosition].fainted)
|
|
return false;
|
|
this.swapPosition(pokemon, newPosition, "[from] move: Ally Switch");
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
amnesia: {
|
|
num: 133,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Amnesia",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
spd: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
anchorshot: {
|
|
num: 677,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Anchor Shot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target, source, move) {
|
|
if (source.isActive)
|
|
target.addVolatile("trapped", source, move, "trapper");
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Tough"
|
|
},
|
|
ancientpower: {
|
|
num: 246,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Ancient Power",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough"
|
|
},
|
|
appleacid: {
|
|
num: 787,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Apple Acid",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Grass"
|
|
},
|
|
aquacutter: {
|
|
num: 895,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Aqua Cutter",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, slicing: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
aquajet: {
|
|
num: 453,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Aqua Jet",
|
|
pp: 20,
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
aquaring: {
|
|
num: 392,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Aqua Ring",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
volatileStatus: "aquaring",
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "Aqua Ring");
|
|
},
|
|
onResidualOrder: 6,
|
|
onResidual(pokemon) {
|
|
this.heal(pokemon.baseMaxhp / 16);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Water",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
aquastep: {
|
|
num: 872,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Aqua Step",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, dance: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
aquatail: {
|
|
num: 401,
|
|
accuracy: 90,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Aqua Tail",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
armorcannon: {
|
|
num: 890,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Armor Cannon",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
def: -1,
|
|
spd: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire"
|
|
},
|
|
armthrust: {
|
|
num: 292,
|
|
accuracy: 100,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Arm Thrust",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
aromatherapy: {
|
|
num: 312,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Aromatherapy",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, distance: 1 },
|
|
onHit(target, source, move) {
|
|
this.add("-activate", source, "move: Aromatherapy");
|
|
let success = false;
|
|
const allies = [...target.side.pokemon, ...target.side.allySide?.pokemon || []];
|
|
for (const ally of allies) {
|
|
if (ally !== source && (ally.hasAbility("sapsipper") || ally.volatiles["substitute"] && !move.infiltrates)) {
|
|
continue;
|
|
}
|
|
if (ally.cureStatus())
|
|
success = true;
|
|
}
|
|
return success;
|
|
},
|
|
target: "allyTeam",
|
|
type: "Grass",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Clever"
|
|
},
|
|
aromaticmist: {
|
|
num: 597,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Aromatic Mist",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { bypasssub: 1 },
|
|
boosts: {
|
|
spd: 1
|
|
},
|
|
secondary: null,
|
|
target: "adjacentAlly",
|
|
type: "Fairy",
|
|
zMove: { boost: { spd: 2 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
assist: {
|
|
num: 274,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Assist",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
onHit(target) {
|
|
const moves = [];
|
|
for (const pokemon of target.side.pokemon) {
|
|
if (pokemon === target)
|
|
continue;
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
const moveid = moveSlot.id;
|
|
const move = this.dex.moves.get(moveid);
|
|
if (move.flags["noassist"] || move.isZ || move.isMax) {
|
|
continue;
|
|
}
|
|
moves.push(moveid);
|
|
}
|
|
}
|
|
let randomMove = "";
|
|
if (moves.length)
|
|
randomMove = this.sample(moves);
|
|
if (!randomMove) {
|
|
return false;
|
|
}
|
|
this.actions.useMove(randomMove, target);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
assurance: {
|
|
num: 372,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.hurtThisTurn) {
|
|
this.debug("BP doubled on damaged target");
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Assurance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
astonish: {
|
|
num: 310,
|
|
accuracy: 100,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Astonish",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cute"
|
|
},
|
|
astralbarrage: {
|
|
num: 825,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Astral Barrage",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Ghost"
|
|
},
|
|
attackorder: {
|
|
num: 454,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Attack Order",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Clever"
|
|
},
|
|
attract: {
|
|
num: 213,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Attract",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
volatileStatus: "attract",
|
|
condition: {
|
|
noCopy: true,
|
|
// doesn't get copied by Baton Pass
|
|
onStart(pokemon, source, effect) {
|
|
if (!(pokemon.gender === "M" && source.gender === "F") && !(pokemon.gender === "F" && source.gender === "M")) {
|
|
this.debug("incompatible gender");
|
|
return false;
|
|
}
|
|
if (!this.runEvent("Attract", pokemon, source)) {
|
|
this.debug("Attract event failed");
|
|
return false;
|
|
}
|
|
if (effect.name === "Cute Charm") {
|
|
this.add("-start", pokemon, "Attract", "[from] ability: Cute Charm", "[of] " + source);
|
|
} else if (effect.name === "Destiny Knot") {
|
|
this.add("-start", pokemon, "Attract", "[from] item: Destiny Knot", "[of] " + source);
|
|
} else {
|
|
this.add("-start", pokemon, "Attract");
|
|
}
|
|
},
|
|
onUpdate(pokemon) {
|
|
if (this.effectState.source && !this.effectState.source.isActive && pokemon.volatiles["attract"]) {
|
|
this.debug("Removing Attract volatile on " + pokemon);
|
|
pokemon.removeVolatile("attract");
|
|
}
|
|
},
|
|
onBeforeMovePriority: 2,
|
|
onBeforeMove(pokemon, target, move) {
|
|
this.add("-activate", pokemon, "move: Attract", "[of] " + this.effectState.source);
|
|
if (this.randomChance(1, 2)) {
|
|
this.add("cant", pokemon, "Attract");
|
|
return false;
|
|
}
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "Attract", "[silent]");
|
|
}
|
|
},
|
|
onTryImmunity(target, source) {
|
|
return target.gender === "M" && source.gender === "F" || target.gender === "F" && source.gender === "M";
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
aurasphere: {
|
|
num: 396,
|
|
accuracy: true,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Aura Sphere",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, pulse: 1, mirror: 1, distance: 1 },
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Fighting",
|
|
contestType: "Beautiful"
|
|
},
|
|
aurawheel: {
|
|
num: 783,
|
|
accuracy: 100,
|
|
basePower: 110,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Aura Wheel",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1
|
|
}
|
|
}
|
|
},
|
|
onTry(source) {
|
|
if (source.species.baseSpecies === "Morpeko") {
|
|
return;
|
|
}
|
|
this.attrLastMove("[still]");
|
|
this.add("-fail", source, "move: Aura Wheel");
|
|
this.hint("Only a Pokemon whose form is Morpeko or Morpeko-Hangry can use this move.");
|
|
return null;
|
|
},
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.species.name === "Morpeko-Hangry") {
|
|
move.type = "Dark";
|
|
} else {
|
|
move.type = "Electric";
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Electric"
|
|
},
|
|
aurorabeam: {
|
|
num: 62,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Aurora Beam",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
atk: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
auroraveil: {
|
|
num: 694,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Aurora Veil",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
sideCondition: "auroraveil",
|
|
onTry() {
|
|
return this.field.isWeather(["hail", "snow"]);
|
|
},
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasItem("lightclay")) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onAnyModifyDamage(damage, source, target, move) {
|
|
if (target !== source && this.effectState.target.hasAlly(target)) {
|
|
if (target.side.getSideCondition("reflect") && this.getCategory(move) === "Physical" || target.side.getSideCondition("lightscreen") && this.getCategory(move) === "Special") {
|
|
return;
|
|
}
|
|
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
|
|
this.debug("Aurora Veil weaken");
|
|
if (this.activePerHalf > 1)
|
|
return this.chainModify([2732, 4096]);
|
|
return this.chainModify(0.5);
|
|
}
|
|
}
|
|
},
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "move: Aurora Veil");
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 10,
|
|
onSideEnd(side) {
|
|
this.add("-sideend", side, "move: Aurora Veil");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Ice",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
autotomize: {
|
|
num: 475,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Autotomize",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onTryHit(pokemon) {
|
|
const hasContrary = pokemon.hasAbility("contrary");
|
|
if (!hasContrary && pokemon.boosts.spe === 6 || hasContrary && pokemon.boosts.spe === -6) {
|
|
return false;
|
|
}
|
|
},
|
|
boosts: {
|
|
spe: 2
|
|
},
|
|
onHit(pokemon) {
|
|
if (pokemon.weighthg > 1) {
|
|
pokemon.weighthg = Math.max(1, pokemon.weighthg - 1e3);
|
|
this.add("-start", pokemon, "Autotomize");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Steel",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
avalanche: {
|
|
num: 419,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const damagedByTarget = pokemon.attackedBy.some(
|
|
(p) => p.source === target && p.damage > 0 && p.thisTurn
|
|
);
|
|
if (damagedByTarget) {
|
|
this.debug("BP doubled for getting hit by " + target);
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Avalanche",
|
|
pp: 10,
|
|
priority: -4,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
axekick: {
|
|
num: 853,
|
|
accuracy: 90,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Axe Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
hasCrashDamage: true,
|
|
onMoveFail(target, source, move) {
|
|
this.damage(source.baseMaxhp / 2, source, source, this.dex.conditions.get("High Jump Kick"));
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "normal",
|
|
type: "Fighting"
|
|
},
|
|
babydolleyes: {
|
|
num: 608,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Baby-Doll Eyes",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
boosts: {
|
|
atk: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
baddybad: {
|
|
num: 737,
|
|
accuracy: 95,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Baddy Bad",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
sideCondition: "reflect"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
banefulbunker: {
|
|
num: 661,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Baneful Bunker",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: { noassist: 1, failcopycat: 1 },
|
|
stallingMove: true,
|
|
volatileStatus: "banefulbunker",
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "move: Protect");
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags["protect"]) {
|
|
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
|
|
return;
|
|
if (move.isZ || move.isMax)
|
|
target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add("-activate", target, "move: Protect");
|
|
}
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
if (this.checkMoveMakesContact(move, source, target)) {
|
|
source.trySetStatus("psn", target);
|
|
}
|
|
return this.NOT_FAIL;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
|
|
source.trySetStatus("psn", target);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Poison",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
barbbarrage: {
|
|
num: 839,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Barb Barrage",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onBasePower(basePower, pokemon, target) {
|
|
if (target.status === "psn" || target.status === "tox") {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 50,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison"
|
|
},
|
|
barrage: {
|
|
num: 140,
|
|
accuracy: 85,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Barrage",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
barrier: {
|
|
num: 112,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Barrier",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cool"
|
|
},
|
|
batonpass: {
|
|
num: 226,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Baton Pass",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryHit(target) {
|
|
if (!this.canSwitch(target.side) || target.volatiles["commanded"]) {
|
|
this.attrLastMove("[still]");
|
|
this.add("-fail", target);
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
self: {
|
|
onHit(source) {
|
|
source.skipBeforeSwitchOutEventFlag = true;
|
|
}
|
|
},
|
|
selfSwitch: "copyvolatile",
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
beakblast: {
|
|
num: 690,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Beak Blast",
|
|
pp: 15,
|
|
priority: -3,
|
|
flags: { bullet: 1, protect: 1, noassist: 1, failmefirst: 1, nosleeptalk: 1, failcopycat: 1, failinstruct: 1 },
|
|
priorityChargeCallback(pokemon) {
|
|
pokemon.addVolatile("beakblast");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add("-singleturn", pokemon, "move: Beak Blast");
|
|
},
|
|
onHit(target, source, move) {
|
|
if (this.checkMoveMakesContact(move, source, target)) {
|
|
source.trySetStatus("brn", target);
|
|
}
|
|
}
|
|
},
|
|
// FIXME: onMoveAborted(pokemon) {pokemon.removeVolatile('beakblast')},
|
|
onAfterMove(pokemon) {
|
|
pokemon.removeVolatile("beakblast");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
contestType: "Tough"
|
|
},
|
|
beatup: {
|
|
num: 251,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const currentSpecies = move.allies.shift().species;
|
|
const bp = 5 + Math.floor(currentSpecies.baseStats.atk / 10);
|
|
this.debug("BP for " + currentSpecies.name + " hit: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Beat Up",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, allyanim: 1 },
|
|
onModifyMove(move, pokemon) {
|
|
move.allies = pokemon.side.pokemon.filter((ally) => ally === pokemon || !ally.fainted && !ally.status);
|
|
move.multihit = move.allies.length;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
behemothbash: {
|
|
num: 782,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Behemoth Bash",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, failcopycat: 1, failmimic: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel"
|
|
},
|
|
behemothblade: {
|
|
num: 781,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Behemoth Blade",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1, failcopycat: 1, failmimic: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel"
|
|
},
|
|
belch: {
|
|
num: 562,
|
|
accuracy: 90,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Belch",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, failmefirst: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
onDisableMove(pokemon) {
|
|
if (!pokemon.ateBerry)
|
|
pokemon.disableMove("belch");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough"
|
|
},
|
|
bellydrum: {
|
|
num: 187,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Belly Drum",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onHit(target) {
|
|
if (target.hp <= target.maxhp / 2 || target.boosts.atk >= 6 || target.maxhp === 1) {
|
|
return false;
|
|
}
|
|
this.directDamage(target.maxhp / 2);
|
|
this.boost({ atk: 12 }, target);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Cute"
|
|
},
|
|
bestow: {
|
|
num: 516,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Bestow",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { mirror: 1, bypasssub: 1, allyanim: 1, noassist: 1, failcopycat: 1 },
|
|
onHit(target, source, move) {
|
|
if (target.item) {
|
|
return false;
|
|
}
|
|
const myItem = source.takeItem();
|
|
if (!myItem)
|
|
return false;
|
|
if (!this.singleEvent("TakeItem", myItem, source.itemState, target, source, move, myItem) || !target.setItem(myItem)) {
|
|
source.item = myItem.id;
|
|
return false;
|
|
}
|
|
this.add("-item", target, myItem.name, "[from] move: Bestow", "[of] " + source);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 2 } },
|
|
contestType: "Cute"
|
|
},
|
|
bide: {
|
|
num: 117,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Bide",
|
|
pp: 10,
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
volatileStatus: "bide",
|
|
ignoreImmunity: true,
|
|
beforeMoveCallback(pokemon) {
|
|
if (pokemon.volatiles["bide"])
|
|
return true;
|
|
},
|
|
condition: {
|
|
duration: 3,
|
|
onLockMove: "bide",
|
|
onStart(pokemon) {
|
|
this.effectState.totalDamage = 0;
|
|
this.add("-start", pokemon, "move: Bide");
|
|
},
|
|
onDamagePriority: -101,
|
|
onDamage(damage, target, source, move) {
|
|
if (!move || move.effectType !== "Move" || !source)
|
|
return;
|
|
this.effectState.totalDamage += damage;
|
|
this.effectState.lastDamageSource = source;
|
|
},
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (this.effectState.duration === 1) {
|
|
this.add("-end", pokemon, "move: Bide");
|
|
target = this.effectState.lastDamageSource;
|
|
if (!target || !this.effectState.totalDamage) {
|
|
this.attrLastMove("[still]");
|
|
this.add("-fail", pokemon);
|
|
return false;
|
|
}
|
|
if (!target.isActive) {
|
|
const possibleTarget = this.getRandomTarget(pokemon, this.dex.moves.get("pound"));
|
|
if (!possibleTarget) {
|
|
this.add("-miss", pokemon);
|
|
return false;
|
|
}
|
|
target = possibleTarget;
|
|
}
|
|
const moveData = {
|
|
id: "bide",
|
|
name: "Bide",
|
|
accuracy: true,
|
|
damage: this.effectState.totalDamage * 2,
|
|
category: "Physical",
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1 },
|
|
effectType: "Move",
|
|
type: "Normal"
|
|
};
|
|
this.actions.tryMoveHit(target, pokemon, moveData);
|
|
pokemon.removeVolatile("bide");
|
|
return false;
|
|
}
|
|
this.add("-activate", pokemon, "move: Bide");
|
|
},
|
|
onMoveAborted(pokemon) {
|
|
pokemon.removeVolatile("bide");
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "move: Bide", "[silent]");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
bind: {
|
|
num: 20,
|
|
accuracy: 85,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Bind",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
bite: {
|
|
num: 44,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Bite",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough"
|
|
},
|
|
bitterblade: {
|
|
num: 891,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Bitter Blade",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire"
|
|
},
|
|
bittermalice: {
|
|
num: 841,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Special",
|
|
name: "Bitter Malice",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
atk: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ghost"
|
|
},
|
|
blackholeeclipse: {
|
|
num: 654,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Black Hole Eclipse",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "darkiniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
blastburn: {
|
|
num: 307,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Blast Burn",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { recharge: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
blazekick: {
|
|
num: 299,
|
|
accuracy: 90,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Blaze Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: {
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
blazingtorque: {
|
|
num: 896,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Blazing Torque",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {
|
|
protect: 1,
|
|
failencore: 1,
|
|
failmefirst: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire"
|
|
},
|
|
bleakwindstorm: {
|
|
num: 846,
|
|
accuracy: 80,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Bleakwind Storm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Flying"
|
|
},
|
|
blizzard: {
|
|
num: 59,
|
|
accuracy: 70,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Blizzard",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
onModifyMove(move) {
|
|
if (this.field.isWeather(["hail", "snow"]))
|
|
move.accuracy = true;
|
|
},
|
|
secondary: {
|
|
chance: 10,
|
|
status: "frz"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
block: {
|
|
num: 335,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Block",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { reflectable: 1, mirror: 1 },
|
|
onHit(target, source, move) {
|
|
return target.addVolatile("trapped", source, move, "trapper");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
bloomdoom: {
|
|
num: 644,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Bloom Doom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "grassiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
blueflare: {
|
|
num: 551,
|
|
accuracy: 85,
|
|
basePower: 130,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Blue Flare",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
bodypress: {
|
|
num: 776,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Body Press",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
overrideOffensiveStat: "def",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting"
|
|
},
|
|
bodyslam: {
|
|
num: 34,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Body Slam",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
boltbeak: {
|
|
num: 754,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.newlySwitched || this.queue.willMove(target)) {
|
|
this.debug("Bolt Beak damage boost");
|
|
return move.basePower * 2;
|
|
}
|
|
this.debug("Bolt Beak NOT boosted");
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Bolt Beak",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric"
|
|
},
|
|
boltstrike: {
|
|
num: 550,
|
|
accuracy: 85,
|
|
basePower: 130,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Bolt Strike",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Beautiful"
|
|
},
|
|
boneclub: {
|
|
num: 125,
|
|
accuracy: 85,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Bone Club",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough"
|
|
},
|
|
bonemerang: {
|
|
num: 155,
|
|
accuracy: 90,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Bonemerang",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Tough"
|
|
},
|
|
bonerush: {
|
|
num: 198,
|
|
accuracy: 90,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Bone Rush",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Tough"
|
|
},
|
|
boomburst: {
|
|
num: 586,
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Special",
|
|
name: "Boomburst",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
bounce: {
|
|
num: 340,
|
|
accuracy: 85,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Bounce",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {
|
|
contact: 1,
|
|
charge: 1,
|
|
protect: 1,
|
|
mirror: 1,
|
|
gravity: 1,
|
|
distance: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failinstruct: 1
|
|
},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onInvulnerability(target, source, move) {
|
|
if (["gust", "twister", "skyuppercut", "thunder", "hurricane", "smackdown", "thousandarrows"].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onSourceBasePower(basePower, target, source, move) {
|
|
if (move.id === "gust" || move.id === "twister") {
|
|
return this.chainModify(2);
|
|
}
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cute"
|
|
},
|
|
bouncybubble: {
|
|
num: 733,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Bouncy Bubble",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, heal: 1 },
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Clever"
|
|
},
|
|
branchpoke: {
|
|
num: 785,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Branch Poke",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass"
|
|
},
|
|
bravebird: {
|
|
num: 413,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Brave Bird",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, distance: 1 },
|
|
recoil: [33, 100],
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
breakingswipe: {
|
|
num: 784,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Breaking Swipe",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
atk: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon"
|
|
},
|
|
breakneckblitz: {
|
|
num: 622,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Breakneck Blitz",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "normaliumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
brickbreak: {
|
|
num: 280,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Brick Break",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onTryHit(pokemon) {
|
|
pokemon.side.removeSideCondition("reflect");
|
|
pokemon.side.removeSideCondition("lightscreen");
|
|
pokemon.side.removeSideCondition("auroraveil");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
brine: {
|
|
num: 362,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Brine",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onBasePower(basePower, pokemon, target) {
|
|
if (target.hp * 2 <= target.maxhp) {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough"
|
|
},
|
|
brutalswing: {
|
|
num: 693,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Brutal Swing",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Dark",
|
|
contestType: "Tough"
|
|
},
|
|
bubble: {
|
|
num: 145,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Bubble",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Cute"
|
|
},
|
|
bubblebeam: {
|
|
num: 61,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Bubble Beam",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
bugbite: {
|
|
num: 450,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Bug Bite",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onHit(target, source) {
|
|
const item = target.getItem();
|
|
if (source.hp && item.isBerry && target.takeItem(source)) {
|
|
this.add("-enditem", target, item.name, "[from] stealeat", "[move] Bug Bite", "[of] " + source);
|
|
if (this.singleEvent("Eat", item, null, source, null, null)) {
|
|
this.runEvent("EatItem", source, null, null, item);
|
|
if (item.id === "leppaberry")
|
|
target.staleness = "external";
|
|
}
|
|
if (item.onEat)
|
|
source.ateBerry = true;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute"
|
|
},
|
|
bugbuzz: {
|
|
num: 405,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Bug Buzz",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Beautiful"
|
|
},
|
|
bulkup: {
|
|
num: 339,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Bulk Up",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fighting",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
bulldoze: {
|
|
num: 523,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Bulldoze",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Ground",
|
|
contestType: "Tough"
|
|
},
|
|
bulletpunch: {
|
|
num: 418,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Bullet Punch",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Tough"
|
|
},
|
|
bulletseed: {
|
|
num: 331,
|
|
accuracy: 100,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Bullet Seed",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cool"
|
|
},
|
|
burningjealousy: {
|
|
num: 807,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
name: "Burning Jealousy",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target, source, move) {
|
|
if (target?.statsRaisedThisTurn) {
|
|
target.trySetStatus("brn", source, move);
|
|
}
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Tough"
|
|
},
|
|
burnup: {
|
|
num: 682,
|
|
accuracy: 100,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Burn Up",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, defrost: 1 },
|
|
onTryMove(pokemon, target, move) {
|
|
if (pokemon.hasType("Fire"))
|
|
return;
|
|
this.add("-fail", pokemon, "move: Burn Up");
|
|
this.attrLastMove("[still]");
|
|
return null;
|
|
},
|
|
self: {
|
|
onHit(pokemon) {
|
|
pokemon.setType(pokemon.getTypes(true).map((type) => type === "Fire" ? "???" : type));
|
|
this.add("-start", pokemon, "typechange", pokemon.getTypes().join("/"), "[from] move: Burn Up");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Clever"
|
|
},
|
|
buzzybuzz: {
|
|
num: 734,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Buzzy Buzz",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Clever"
|
|
},
|
|
calmmind: {
|
|
num: 347,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Calm Mind",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
spa: 1,
|
|
spd: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
camouflage: {
|
|
num: 293,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Camouflage",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onHit(target) {
|
|
let newType = "Normal";
|
|
if (this.field.isTerrain("electricterrain")) {
|
|
newType = "Electric";
|
|
} else if (this.field.isTerrain("grassyterrain")) {
|
|
newType = "Grass";
|
|
} else if (this.field.isTerrain("mistyterrain")) {
|
|
newType = "Fairy";
|
|
} else if (this.field.isTerrain("psychicterrain")) {
|
|
newType = "Psychic";
|
|
}
|
|
if (target.getTypes().join() === newType || !target.setType(newType))
|
|
return false;
|
|
this.add("-start", target, "typechange", newType);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { evasion: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
captivate: {
|
|
num: 445,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Captivate",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
onTryImmunity(pokemon, source) {
|
|
return pokemon.gender === "M" && source.gender === "F" || pokemon.gender === "F" && source.gender === "M";
|
|
},
|
|
boosts: {
|
|
spa: -2
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: { boost: { spd: 2 } },
|
|
contestType: "Cute"
|
|
},
|
|
catastropika: {
|
|
num: 658,
|
|
accuracy: true,
|
|
basePower: 210,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Catastropika",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: { contact: 1 },
|
|
isZ: "pikaniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
ceaselessedge: {
|
|
num: 845,
|
|
accuracy: 90,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Ceaseless Edge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
self: {
|
|
onHit(source) {
|
|
for (const side of source.side.foeSidesWithConditions()) {
|
|
side.addSideCondition("spikes");
|
|
}
|
|
}
|
|
},
|
|
secondary: {},
|
|
// allows sheer force to trigger
|
|
target: "normal",
|
|
type: "Dark"
|
|
},
|
|
celebrate: {
|
|
num: 606,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Celebrate",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
onTryHit(target, source) {
|
|
this.add("-activate", target, "move: Celebrate");
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
charge: {
|
|
num: 268,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Charge",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
volatileStatus: "charge",
|
|
condition: {
|
|
onStart(pokemon, source, effect) {
|
|
if (effect && ["Electromorphosis", "Wind Power"].includes(effect.name)) {
|
|
this.add("-start", pokemon, "Charge", this.activeMove.name, "[from] ability: " + effect.name);
|
|
} else {
|
|
this.add("-start", pokemon, "Charge");
|
|
}
|
|
},
|
|
onRestart(pokemon, source, effect) {
|
|
if (effect && ["Electromorphosis", "Wind Power"].includes(effect.name)) {
|
|
this.add("-start", pokemon, "Charge", this.activeMove.name, "[from] ability: " + effect.name);
|
|
} else {
|
|
this.add("-start", pokemon, "Charge");
|
|
}
|
|
},
|
|
onBasePowerPriority: 9,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === "Electric") {
|
|
this.debug("charge boost");
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
onMoveAborted(pokemon, target, move) {
|
|
if (move.type === "Electric" && move.id !== "charge") {
|
|
pokemon.removeVolatile("charge");
|
|
}
|
|
},
|
|
onAfterMove(pokemon, target, move) {
|
|
if (move.type === "Electric" && move.id !== "charge") {
|
|
pokemon.removeVolatile("charge");
|
|
}
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "Charge", "[silent]");
|
|
}
|
|
},
|
|
boosts: {
|
|
spd: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Electric",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
chargebeam: {
|
|
num: 451,
|
|
accuracy: 90,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Charge Beam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 70,
|
|
self: {
|
|
boosts: {
|
|
spa: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Beautiful"
|
|
},
|
|
charm: {
|
|
num: 204,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Charm",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
boosts: {
|
|
atk: -2
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
chatter: {
|
|
num: 448,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Chatter",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {
|
|
protect: 1,
|
|
mirror: 1,
|
|
sound: 1,
|
|
distance: 1,
|
|
bypasssub: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
noSketch: true,
|
|
secondary: {
|
|
chance: 100,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cute"
|
|
},
|
|
chillingwater: {
|
|
num: 886,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Chilling Water",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
atk: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
chillyreception: {
|
|
num: 881,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Chilly Reception",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
// TODO show prepare message before the "POKEMON used MOVE!" message
|
|
// This happens even before sleep shows its "POKEMON is fast asleep." message
|
|
weather: "snow",
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ice"
|
|
},
|
|
chipaway: {
|
|
num: 498,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Chip Away",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
ignoreDefensive: true,
|
|
ignoreEvasion: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
chloroblast: {
|
|
num: 835,
|
|
accuracy: 95,
|
|
basePower: 150,
|
|
category: "Special",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Chloroblast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
mindBlownRecoil: true,
|
|
onAfterMove(pokemon, target, move) {
|
|
if (move.mindBlownRecoil && !move.multihit) {
|
|
const hpBeforeRecoil = pokemon.hp;
|
|
this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.conditions.get("Chloroblast"), true);
|
|
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
|
|
this.runEvent("EmergencyExit", pokemon, pokemon);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass"
|
|
},
|
|
circlethrow: {
|
|
num: 509,
|
|
accuracy: 90,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Circle Throw",
|
|
pp: 10,
|
|
priority: -6,
|
|
flags: { contact: 1, protect: 1, mirror: 1, noassist: 1, failcopycat: 1 },
|
|
forceSwitch: true,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
clamp: {
|
|
num: 128,
|
|
accuracy: 85,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Clamp",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough"
|
|
},
|
|
clangingscales: {
|
|
num: 691,
|
|
accuracy: 100,
|
|
basePower: 110,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Clanging Scales",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
selfBoost: {
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon",
|
|
contestType: "Tough"
|
|
},
|
|
clangoroussoul: {
|
|
num: 775,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Clangorous Soul",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, sound: 1, dance: 1 },
|
|
onTry(source) {
|
|
if (source.hp <= source.maxhp * 33 / 100 || source.maxhp === 1)
|
|
return false;
|
|
},
|
|
onTryHit(pokemon, target, move) {
|
|
if (!this.boost(move.boosts))
|
|
return null;
|
|
delete move.boosts;
|
|
},
|
|
onHit(pokemon) {
|
|
this.directDamage(pokemon.maxhp * 33 / 100);
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dragon"
|
|
},
|
|
clangoroussoulblaze: {
|
|
num: 728,
|
|
accuracy: true,
|
|
basePower: 185,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Clangorous Soulblaze",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: { sound: 1, bypasssub: 1 },
|
|
selfBoost: {
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1
|
|
}
|
|
},
|
|
isZ: "kommoniumz",
|
|
secondary: {
|
|
// Sheer Force negates the selfBoost even though it is not secondary
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon",
|
|
contestType: "Cool"
|
|
},
|
|
clearsmog: {
|
|
num: 499,
|
|
accuracy: true,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Clear Smog",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onHit(target) {
|
|
target.clearBoosts();
|
|
this.add("-clearboost", target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Beautiful"
|
|
},
|
|
closecombat: {
|
|
num: 370,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Close Combat",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
def: -1,
|
|
spd: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
coaching: {
|
|
num: 811,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Coaching",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bypasssub: 1, allyanim: 1 },
|
|
secondary: null,
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1
|
|
},
|
|
target: "adjacentAlly",
|
|
type: "Fighting"
|
|
},
|
|
coil: {
|
|
num: 489,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Coil",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
accuracy: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Poison",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Tough"
|
|
},
|
|
collisioncourse: {
|
|
num: 878,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Collision Course",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onBasePower(basePower, source, target, move) {
|
|
if (target.runEffectiveness(move) > 0) {
|
|
this.debug(`collision course super effective buff`);
|
|
return this.chainModify([5461, 4096]);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
combattorque: {
|
|
num: 899,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Combat Torque",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {
|
|
protect: 1,
|
|
failencore: 1,
|
|
failmefirst: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Fighting"
|
|
},
|
|
cometpunch: {
|
|
num: 4,
|
|
accuracy: 85,
|
|
basePower: 18,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Comet Punch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
maxMove: { basePower: 100 },
|
|
contestType: "Tough"
|
|
},
|
|
comeuppance: {
|
|
num: 894,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
const lastDamagedBy = pokemon.getLastDamagedBy(true);
|
|
if (lastDamagedBy !== void 0) {
|
|
return lastDamagedBy.damage * 1.5 || 1;
|
|
}
|
|
return 0;
|
|
},
|
|
category: "Physical",
|
|
name: "Comeuppance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, failmefirst: 1 },
|
|
onTry(source) {
|
|
const lastDamagedBy = source.getLastDamagedBy(true);
|
|
if (lastDamagedBy === void 0 || !lastDamagedBy.thisTurn)
|
|
return false;
|
|
},
|
|
onModifyTarget(targetRelayVar, source, target, move) {
|
|
const lastDamagedBy = source.getLastDamagedBy(true);
|
|
if (lastDamagedBy) {
|
|
targetRelayVar.target = this.getAtSlot(lastDamagedBy.slot);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "scripted",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
confide: {
|
|
num: 590,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Confide",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { reflectable: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
boosts: {
|
|
spa: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
confuseray: {
|
|
num: 109,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Confuse Ray",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
volatileStatus: "confusion",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
confusion: {
|
|
num: 93,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Confusion",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
constrict: {
|
|
num: 132,
|
|
accuracy: 100,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Constrict",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
continentalcrush: {
|
|
num: 632,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Continental Crush",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "rockiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Cool"
|
|
},
|
|
conversion: {
|
|
num: 160,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Conversion",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onHit(target) {
|
|
const type = this.dex.moves.get(target.moveSlots[0].id).type;
|
|
if (target.hasType(type) || !target.setType(type))
|
|
return false;
|
|
this.add("-start", target, "typechange", type);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
conversion2: {
|
|
num: 176,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Conversion 2",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { bypasssub: 1 },
|
|
onHit(target, source) {
|
|
if (!target.lastMoveUsed) {
|
|
return false;
|
|
}
|
|
const possibleTypes = [];
|
|
const attackType = target.lastMoveUsed.type;
|
|
for (const type of this.dex.types.names()) {
|
|
if (source.hasType(type))
|
|
continue;
|
|
const typeCheck = this.dex.types.get(type).damageTaken[attackType];
|
|
if (typeCheck === 2 || typeCheck === 3) {
|
|
possibleTypes.push(type);
|
|
}
|
|
}
|
|
if (!possibleTypes.length) {
|
|
return false;
|
|
}
|
|
const randomType = this.sample(possibleTypes);
|
|
if (!source.setType(randomType))
|
|
return false;
|
|
this.add("-start", source, "typechange", randomType);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Beautiful"
|
|
},
|
|
copycat: {
|
|
num: 383,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Copycat",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
onHit(pokemon) {
|
|
let move = this.lastMove;
|
|
if (!move)
|
|
return;
|
|
if (move.isMax && move.baseMove)
|
|
move = this.dex.moves.get(move.baseMove);
|
|
if (move.flags["failcopycat"] || move.isZ || move.isMax) {
|
|
return false;
|
|
}
|
|
this.actions.useMove(move.id, pokemon);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { accuracy: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
coreenforcer: {
|
|
num: 687,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Core Enforcer",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onHit(target) {
|
|
if (target.getAbility().isPermanent)
|
|
return;
|
|
if (target.newlySwitched || this.queue.willMove(target))
|
|
return;
|
|
target.addVolatile("gastroacid");
|
|
},
|
|
onAfterSubDamage(damage, target) {
|
|
if (target.getAbility().isPermanent)
|
|
return;
|
|
if (target.newlySwitched || this.queue.willMove(target))
|
|
return;
|
|
target.addVolatile("gastroacid");
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon",
|
|
zMove: { basePower: 140 },
|
|
contestType: "Tough"
|
|
},
|
|
corkscrewcrash: {
|
|
num: 638,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Corkscrew Crash",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "steeliumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
corrosivegas: {
|
|
num: 810,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Corrosive Gas",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
const item = target.takeItem(source);
|
|
if (item) {
|
|
this.add("-enditem", target, item.name, "[from] move: Corrosive Gas", "[of] " + source);
|
|
} else {
|
|
this.add("-fail", target, "move: Corrosive Gas");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Poison"
|
|
},
|
|
cosmicpower: {
|
|
num: 322,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Cosmic Power",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 1,
|
|
spd: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
cottonguard: {
|
|
num: 538,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Cotton Guard",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 3
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
cottonspore: {
|
|
num: 178,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Cotton Spore",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { powder: 1, protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
spe: -2
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Grass",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
counter: {
|
|
num: 68,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
if (!pokemon.volatiles["counter"])
|
|
return 0;
|
|
return pokemon.volatiles["counter"].damage || 1;
|
|
},
|
|
category: "Physical",
|
|
name: "Counter",
|
|
pp: 20,
|
|
priority: -5,
|
|
flags: { contact: 1, protect: 1, failmefirst: 1, noassist: 1, failcopycat: 1 },
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile("counter");
|
|
},
|
|
onTry(source) {
|
|
if (!source.volatiles["counter"])
|
|
return false;
|
|
if (source.volatiles["counter"].slot === null)
|
|
return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
noCopy: true,
|
|
onStart(target, source, move) {
|
|
this.effectState.slot = null;
|
|
this.effectState.damage = 0;
|
|
},
|
|
onRedirectTargetPriority: -1,
|
|
onRedirectTarget(target, source, source2, move) {
|
|
if (move.id !== "counter")
|
|
return;
|
|
if (source !== this.effectState.target || !this.effectState.slot)
|
|
return;
|
|
return this.getAtSlot(this.effectState.slot);
|
|
},
|
|
onDamagingHit(damage, target, source, move) {
|
|
if (!source.isAlly(target) && this.getCategory(move) === "Physical") {
|
|
this.effectState.slot = source.getSlot();
|
|
this.effectState.damage = 2 * damage;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "scripted",
|
|
type: "Fighting",
|
|
maxMove: { basePower: 75 },
|
|
contestType: "Tough"
|
|
},
|
|
courtchange: {
|
|
num: 756,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Court Change",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { mirror: 1 },
|
|
onHitField(target, source) {
|
|
const sideConditions = [
|
|
"mist",
|
|
"lightscreen",
|
|
"reflect",
|
|
"spikes",
|
|
"safeguard",
|
|
"tailwind",
|
|
"toxicspikes",
|
|
"stealthrock",
|
|
"waterpledge",
|
|
"firepledge",
|
|
"grasspledge",
|
|
"stickyweb",
|
|
"auroraveil",
|
|
"gmaxsteelsurge",
|
|
"gmaxcannonade",
|
|
"gmaxvinelash",
|
|
"gmaxwildfire"
|
|
];
|
|
let success = false;
|
|
if (this.gameType === "freeforall") {
|
|
const offset = this.random(3) + 1;
|
|
const sides = [this.sides[0], this.sides[2], this.sides[1], this.sides[3]];
|
|
const temp = { 0: {}, 1: {}, 2: {}, 3: {} };
|
|
for (const side of sides) {
|
|
for (const id in side.sideConditions) {
|
|
if (!sideConditions.includes(id))
|
|
continue;
|
|
temp[side.n][id] = side.sideConditions[id];
|
|
delete side.sideConditions[id];
|
|
const effectName = this.dex.conditions.get(id).name;
|
|
this.add("-sideend", side, effectName, "[silent]");
|
|
success = true;
|
|
}
|
|
}
|
|
for (let i = 0; i < 4; i++) {
|
|
const sourceSideConditions = temp[sides[i].n];
|
|
const targetSide = sides[(i + offset) % 4];
|
|
for (const id in sourceSideConditions) {
|
|
targetSide.sideConditions[id] = sourceSideConditions[id];
|
|
const effectName = this.dex.conditions.get(id).name;
|
|
let layers = sourceSideConditions[id].layers || 1;
|
|
for (; layers > 0; layers--)
|
|
this.add("-sidestart", targetSide, effectName, "[silent]");
|
|
}
|
|
}
|
|
} else {
|
|
const sourceSideConditions = source.side.sideConditions;
|
|
const targetSideConditions = source.side.foe.sideConditions;
|
|
const sourceTemp = {};
|
|
const targetTemp = {};
|
|
for (const id in sourceSideConditions) {
|
|
if (!sideConditions.includes(id))
|
|
continue;
|
|
sourceTemp[id] = sourceSideConditions[id];
|
|
delete sourceSideConditions[id];
|
|
success = true;
|
|
}
|
|
for (const id in targetSideConditions) {
|
|
if (!sideConditions.includes(id))
|
|
continue;
|
|
targetTemp[id] = targetSideConditions[id];
|
|
delete targetSideConditions[id];
|
|
success = true;
|
|
}
|
|
for (const id in sourceTemp) {
|
|
targetSideConditions[id] = sourceTemp[id];
|
|
}
|
|
for (const id in targetTemp) {
|
|
sourceSideConditions[id] = targetTemp[id];
|
|
}
|
|
this.add("-swapsideconditions");
|
|
}
|
|
if (!success)
|
|
return false;
|
|
this.add("-activate", source, "move: Court Change");
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Normal"
|
|
},
|
|
covet: {
|
|
num: 343,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Covet",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, failmefirst: 1, noassist: 1, failcopycat: 1 },
|
|
onAfterHit(target, source, move) {
|
|
if (source.item || source.volatiles["gem"]) {
|
|
return;
|
|
}
|
|
const yourItem = target.takeItem(source);
|
|
if (!yourItem) {
|
|
return;
|
|
}
|
|
if (!this.singleEvent("TakeItem", yourItem, target.itemState, source, target, move, yourItem) || !source.setItem(yourItem)) {
|
|
target.item = yourItem.id;
|
|
return;
|
|
}
|
|
this.add("-item", source, yourItem, "[from] move: Covet", "[of] " + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
crabhammer: {
|
|
num: 152,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Crabhammer",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough"
|
|
},
|
|
craftyshield: {
|
|
num: 578,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Crafty Shield",
|
|
pp: 10,
|
|
priority: 3,
|
|
flags: {},
|
|
sideCondition: "craftyshield",
|
|
onTry() {
|
|
return !!this.queue.willAct();
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onSideStart(target, source) {
|
|
this.add("-singleturn", source, "Crafty Shield");
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (["self", "all"].includes(move.target) || move.category !== "Status")
|
|
return;
|
|
this.add("-activate", target, "move: Crafty Shield");
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Fairy",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
crosschop: {
|
|
num: 238,
|
|
accuracy: 80,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Cross Chop",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
crosspoison: {
|
|
num: 440,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Cross Poison",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "psn"
|
|
},
|
|
critRatio: 2,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Cool"
|
|
},
|
|
crunch: {
|
|
num: 242,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Crunch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough"
|
|
},
|
|
crushclaw: {
|
|
num: 306,
|
|
accuracy: 95,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Crush Claw",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
crushgrip: {
|
|
num: 462,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const hp = target.hp;
|
|
const maxHP = target.maxhp;
|
|
const bp = Math.floor(Math.floor((120 * (100 * Math.floor(hp * 4096 / maxHP)) + 2048 - 1) / 4096) / 100) || 1;
|
|
this.debug("BP for " + hp + "/" + maxHP + " HP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Crush Grip",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 190 },
|
|
maxMove: { basePower: 140 },
|
|
contestType: "Tough"
|
|
},
|
|
curse: {
|
|
num: 174,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Curse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bypasssub: 1 },
|
|
volatileStatus: "curse",
|
|
onModifyMove(move, source, target) {
|
|
if (!source.hasType("Ghost")) {
|
|
move.target = move.nonGhostTarget;
|
|
} else if (source.isAlly(target)) {
|
|
move.target = "randomNormal";
|
|
}
|
|
},
|
|
onTryHit(target, source, move) {
|
|
if (!source.hasType("Ghost")) {
|
|
delete move.volatileStatus;
|
|
delete move.onHit;
|
|
move.self = { boosts: { spe: -1, atk: 1, def: 1 } };
|
|
} else if (move.volatileStatus && target.volatiles["curse"]) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
this.directDamage(source.maxhp / 2, source, source);
|
|
},
|
|
condition: {
|
|
onStart(pokemon, source) {
|
|
this.add("-start", pokemon, "Curse", "[of] " + source);
|
|
},
|
|
onResidualOrder: 12,
|
|
onResidual(pokemon) {
|
|
this.damage(pokemon.baseMaxhp / 4);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
nonGhostTarget: "self",
|
|
type: "Ghost",
|
|
zMove: { effect: "curse" },
|
|
contestType: "Tough"
|
|
},
|
|
cut: {
|
|
num: 15,
|
|
accuracy: 95,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Cut",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
darkestlariat: {
|
|
num: 663,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Darkest Lariat",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
ignoreEvasion: true,
|
|
ignoreDefensive: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
darkpulse: {
|
|
num: 399,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Dark Pulse",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, pulse: 1, mirror: 1, distance: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "any",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
darkvoid: {
|
|
num: 464,
|
|
accuracy: 50,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Dark Void",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "slp",
|
|
onTry(source, target, move) {
|
|
if (source.species.name === "Darkrai" || move.hasBounced) {
|
|
return;
|
|
}
|
|
this.add("-fail", source, "move: Dark Void");
|
|
this.hint("Only a Pokemon whose form is Darkrai can use this move.");
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Dark",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
dazzlinggleam: {
|
|
num: 605,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Dazzling Gleam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fairy",
|
|
contestType: "Beautiful"
|
|
},
|
|
decorate: {
|
|
num: 777,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Decorate",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { allyanim: 1 },
|
|
secondary: null,
|
|
boosts: {
|
|
atk: 2,
|
|
spa: 2
|
|
},
|
|
target: "normal",
|
|
type: "Fairy"
|
|
},
|
|
defendorder: {
|
|
num: 455,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Defend Order",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 1,
|
|
spd: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
defensecurl: {
|
|
num: 111,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Defense Curl",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 1
|
|
},
|
|
volatileStatus: "defensecurl",
|
|
condition: {
|
|
noCopy: true,
|
|
onRestart: () => null
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { accuracy: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
defog: {
|
|
num: 432,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Defog",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
onHit(target, source, move) {
|
|
let success = false;
|
|
if (!target.volatiles["substitute"] || move.infiltrates)
|
|
success = !!this.boost({ evasion: -1 });
|
|
const removeTarget = [
|
|
"reflect",
|
|
"lightscreen",
|
|
"auroraveil",
|
|
"safeguard",
|
|
"mist",
|
|
"spikes",
|
|
"toxicspikes",
|
|
"stealthrock",
|
|
"stickyweb",
|
|
"gmaxsteelsurge"
|
|
];
|
|
const removeAll = [
|
|
"spikes",
|
|
"toxicspikes",
|
|
"stealthrock",
|
|
"stickyweb",
|
|
"gmaxsteelsurge"
|
|
];
|
|
for (const targetCondition of removeTarget) {
|
|
if (target.side.removeSideCondition(targetCondition)) {
|
|
if (!removeAll.includes(targetCondition))
|
|
continue;
|
|
this.add("-sideend", target.side, this.dex.conditions.get(targetCondition).name, "[from] move: Defog", "[of] " + source);
|
|
success = true;
|
|
}
|
|
}
|
|
for (const sideCondition of removeAll) {
|
|
if (source.side.removeSideCondition(sideCondition)) {
|
|
this.add("-sideend", source.side, this.dex.conditions.get(sideCondition).name, "[from] move: Defog", "[of] " + source);
|
|
success = true;
|
|
}
|
|
}
|
|
this.field.clearTerrain();
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
zMove: { boost: { accuracy: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
destinybond: {
|
|
num: 194,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Destiny Bond",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { bypasssub: 1, noassist: 1, failcopycat: 1 },
|
|
volatileStatus: "destinybond",
|
|
onPrepareHit(pokemon) {
|
|
return !pokemon.removeVolatile("destinybond");
|
|
},
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add("-singlemove", pokemon, "Destiny Bond");
|
|
},
|
|
onFaint(target, source, effect) {
|
|
if (!source || !effect || target.isAlly(source))
|
|
return;
|
|
if (effect.effectType === "Move" && !effect.flags["futuremove"]) {
|
|
if (source.volatiles["dynamax"]) {
|
|
this.add("-hint", "Dynamaxed Pok\xE9mon are immune to Destiny Bond.");
|
|
return;
|
|
}
|
|
this.add("-activate", target, "move: Destiny Bond");
|
|
source.faint();
|
|
}
|
|
},
|
|
onBeforeMovePriority: -1,
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (move.id === "destinybond")
|
|
return;
|
|
this.debug("removing Destiny Bond before attack");
|
|
pokemon.removeVolatile("destinybond");
|
|
},
|
|
onMoveAborted(pokemon, target, move) {
|
|
pokemon.removeVolatile("destinybond");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ghost",
|
|
zMove: { effect: "redirect" },
|
|
contestType: "Clever"
|
|
},
|
|
detect: {
|
|
num: 197,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Detect",
|
|
pp: 5,
|
|
priority: 4,
|
|
flags: { noassist: 1, failcopycat: 1 },
|
|
stallingMove: true,
|
|
volatileStatus: "protect",
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fighting",
|
|
zMove: { boost: { evasion: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
devastatingdrake: {
|
|
num: 652,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Devastating Drake",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "dragoniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Cool"
|
|
},
|
|
diamondstorm: {
|
|
num: 591,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Diamond Storm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
chance: 50,
|
|
boosts: {
|
|
def: 2
|
|
}
|
|
},
|
|
secondary: {
|
|
// Sheer Force negates the self even though it is not secondary
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Rock",
|
|
contestType: "Beautiful"
|
|
},
|
|
dig: {
|
|
num: 91,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Dig",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, charge: 1, protect: 1, mirror: 1, nonsky: 1, nosleeptalk: 1, noassist: 1, failinstruct: 1 },
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onImmunity(type, pokemon) {
|
|
if (type === "sandstorm" || type === "hail")
|
|
return false;
|
|
},
|
|
onInvulnerability(target, source, move) {
|
|
if (["earthquake", "magnitude"].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onSourceModifyDamage(damage, source, target, move) {
|
|
if (move.id === "earthquake" || move.id === "magnitude") {
|
|
return this.chainModify(2);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough"
|
|
},
|
|
disable: {
|
|
num: 50,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Disable",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
volatileStatus: "disable",
|
|
onTryHit(target) {
|
|
if (!target.lastMove || target.lastMove.isZ || target.lastMove.isMax || target.lastMove.id === "struggle") {
|
|
return false;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 5,
|
|
noCopy: true,
|
|
// doesn't get copied by Baton Pass
|
|
onStart(pokemon, source, effect) {
|
|
if (this.queue.willMove(pokemon) || pokemon === this.activePokemon && this.activeMove && !this.activeMove.isExternal) {
|
|
this.effectState.duration--;
|
|
}
|
|
if (!pokemon.lastMove) {
|
|
this.debug(`Pokemon hasn't moved yet`);
|
|
return false;
|
|
}
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (moveSlot.id === pokemon.lastMove.id) {
|
|
if (!moveSlot.pp) {
|
|
this.debug("Move out of PP");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
if (effect.effectType === "Ability") {
|
|
this.add("-start", pokemon, "Disable", pokemon.lastMove.name, "[from] ability: Cursed Body", "[of] " + source);
|
|
} else {
|
|
this.add("-start", pokemon, "Disable", pokemon.lastMove.name);
|
|
}
|
|
this.effectState.move = pokemon.lastMove.id;
|
|
},
|
|
onResidualOrder: 17,
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "Disable");
|
|
},
|
|
onBeforeMovePriority: 7,
|
|
onBeforeMove(attacker, defender, move) {
|
|
if (!move.isZ && move.id === this.effectState.move) {
|
|
this.add("cant", attacker, "Disable", move);
|
|
return false;
|
|
}
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (moveSlot.id === this.effectState.move) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
disarmingvoice: {
|
|
num: 574,
|
|
accuracy: true,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Disarming Voice",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fairy",
|
|
contestType: "Cute"
|
|
},
|
|
discharge: {
|
|
num: 435,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Discharge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Electric",
|
|
contestType: "Beautiful"
|
|
},
|
|
direclaw: {
|
|
num: 827,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Dire Claw",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
onHit(target, source) {
|
|
const result = this.random(3);
|
|
if (result === 0) {
|
|
target.trySetStatus("psn", source);
|
|
} else if (result === 1) {
|
|
target.trySetStatus("par", source);
|
|
} else {
|
|
target.trySetStatus("slp", source);
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Poison"
|
|
},
|
|
dive: {
|
|
num: 291,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Dive",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {
|
|
contact: 1,
|
|
charge: 1,
|
|
protect: 1,
|
|
mirror: 1,
|
|
nonsky: 1,
|
|
allyanim: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failinstruct: 1
|
|
},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
if (attacker.hasAbility("gulpmissile") && attacker.species.name === "Cramorant" && !attacker.transformed) {
|
|
const forme = attacker.hp <= attacker.maxhp / 2 ? "cramorantgorging" : "cramorantgulping";
|
|
attacker.formeChange(forme, move);
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onImmunity(type, pokemon) {
|
|
if (type === "sandstorm" || type === "hail")
|
|
return false;
|
|
},
|
|
onInvulnerability(target, source, move) {
|
|
if (["surf", "whirlpool"].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onSourceModifyDamage(damage, source, target, move) {
|
|
if (move.id === "surf" || move.id === "whirlpool") {
|
|
return this.chainModify(2);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
dizzypunch: {
|
|
num: 146,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Dizzy Punch",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
doodle: {
|
|
num: 867,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Doodle",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
onHit(target, source, move) {
|
|
let success = false;
|
|
for (const pokemon of source.alliesAndSelf()) {
|
|
if (pokemon.ability === target.ability)
|
|
continue;
|
|
const oldAbility = pokemon.setAbility(target.ability);
|
|
if (oldAbility) {
|
|
this.add("-ability", pokemon, target.getAbility().name, "[from] move: Doodle");
|
|
success = true;
|
|
} else if (!success && oldAbility === null) {
|
|
success = null;
|
|
}
|
|
}
|
|
if (!success) {
|
|
if (success === false) {
|
|
this.add("-fail", source);
|
|
}
|
|
this.attrLastMove("[still]");
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Normal"
|
|
},
|
|
doomdesire: {
|
|
num: 353,
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Doom Desire",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { futuremove: 1 },
|
|
onTry(source, target) {
|
|
if (!target.side.addSlotCondition(target, "futuremove"))
|
|
return false;
|
|
Object.assign(target.side.slotConditions[target.position]["futuremove"], {
|
|
move: "doomdesire",
|
|
source,
|
|
moveData: {
|
|
id: "doomdesire",
|
|
name: "Doom Desire",
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Special",
|
|
priority: 0,
|
|
flags: { futuremove: 1 },
|
|
effectType: "Move",
|
|
type: "Steel"
|
|
}
|
|
});
|
|
this.add("-start", source, "Doom Desire");
|
|
return this.NOT_FAIL;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Beautiful"
|
|
},
|
|
doubleedge: {
|
|
num: 38,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Double-Edge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
recoil: [33, 100],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
doublehit: {
|
|
num: 458,
|
|
accuracy: 90,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
name: "Double Hit",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 120 },
|
|
contestType: "Cool"
|
|
},
|
|
doubleironbash: {
|
|
num: 742,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Double Iron Bash",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
multihit: 2,
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: { basePower: 180 },
|
|
maxMove: { basePower: 140 },
|
|
contestType: "Clever"
|
|
},
|
|
doublekick: {
|
|
num: 24,
|
|
accuracy: 100,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Double Kick",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
maxMove: { basePower: 80 },
|
|
contestType: "Cool"
|
|
},
|
|
doubleshock: {
|
|
num: 892,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Double Shock",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onTryMove(pokemon, target, move) {
|
|
if (pokemon.hasType("Electric"))
|
|
return;
|
|
this.add("-fail", pokemon, "move: Double Shock");
|
|
this.attrLastMove("[still]");
|
|
return null;
|
|
},
|
|
self: {
|
|
onHit(pokemon) {
|
|
pokemon.setType(pokemon.getTypes(true).map((type) => type === "Electric" ? "???" : type));
|
|
this.add("-start", pokemon, "typechange", pokemon.getTypes().join("/"), "[from] move: Double Shock");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Clever"
|
|
},
|
|
doubleslap: {
|
|
num: 3,
|
|
accuracy: 85,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Double Slap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
doubleteam: {
|
|
num: 104,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Double Team",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
evasion: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cool"
|
|
},
|
|
dracometeor: {
|
|
num: 434,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Draco Meteor",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
spa: -2
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Beautiful"
|
|
},
|
|
dragonascent: {
|
|
num: 620,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Dragon Ascent",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, distance: 1 },
|
|
self: {
|
|
boosts: {
|
|
def: -1,
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Beautiful"
|
|
},
|
|
dragonbreath: {
|
|
num: 225,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Dragon Breath",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Cool"
|
|
},
|
|
dragonclaw: {
|
|
num: 337,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Dragon Claw",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Cool"
|
|
},
|
|
dragondance: {
|
|
num: 349,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Dragon Dance",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1, dance: 1 },
|
|
boosts: {
|
|
atk: 1,
|
|
spe: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dragon",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cool"
|
|
},
|
|
dragondarts: {
|
|
num: 751,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Dragon Darts",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, noparentalbond: 1 },
|
|
multihit: 2,
|
|
smartTarget: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
maxMove: { basePower: 130 }
|
|
},
|
|
dragonenergy: {
|
|
num: 820,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const bp = move.basePower * pokemon.hp / pokemon.maxhp;
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
name: "Dragon Energy",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon"
|
|
},
|
|
dragonhammer: {
|
|
num: 692,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Dragon Hammer",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Tough"
|
|
},
|
|
dragonpulse: {
|
|
num: 406,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Special",
|
|
name: "Dragon Pulse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, pulse: 1, mirror: 1, distance: 1 },
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Dragon",
|
|
contestType: "Beautiful"
|
|
},
|
|
dragonrage: {
|
|
num: 82,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damage: 40,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Dragon Rage",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Cool"
|
|
},
|
|
dragonrush: {
|
|
num: 407,
|
|
accuracy: 75,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Dragon Rush",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Tough"
|
|
},
|
|
dragontail: {
|
|
num: 525,
|
|
accuracy: 90,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Dragon Tail",
|
|
pp: 10,
|
|
priority: -6,
|
|
flags: { contact: 1, protect: 1, mirror: 1, noassist: 1, failcopycat: 1 },
|
|
forceSwitch: true,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Tough"
|
|
},
|
|
drainingkiss: {
|
|
num: 577,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Draining Kiss",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, heal: 1 },
|
|
drain: [3, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Cute"
|
|
},
|
|
drainpunch: {
|
|
num: 409,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Drain Punch",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1, heal: 1 },
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
dreameater: {
|
|
num: 138,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Dream Eater",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, heal: 1 },
|
|
drain: [1, 2],
|
|
onTryImmunity(target) {
|
|
return target.status === "slp" || target.hasAbility("comatose");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
drillpeck: {
|
|
num: 65,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Drill Peck",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, distance: 1 },
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
drillrun: {
|
|
num: 529,
|
|
accuracy: 95,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Drill Run",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough"
|
|
},
|
|
drumbeating: {
|
|
num: 778,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Drum Beating",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Grass"
|
|
},
|
|
dualchop: {
|
|
num: 530,
|
|
accuracy: 90,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Dual Chop",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Tough"
|
|
},
|
|
dualwingbeat: {
|
|
num: 814,
|
|
accuracy: 90,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Dual Wingbeat",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
maxMove: { basePower: 130 }
|
|
},
|
|
dynamaxcannon: {
|
|
num: 744,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Dynamax Cannon",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, failencore: 1, nosleeptalk: 1, noparentalbond: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon"
|
|
},
|
|
dynamicpunch: {
|
|
num: 223,
|
|
accuracy: 50,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Dynamic Punch",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
earthpower: {
|
|
num: 414,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Earth Power",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Beautiful"
|
|
},
|
|
earthquake: {
|
|
num: 89,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Earthquake",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Ground",
|
|
contestType: "Tough"
|
|
},
|
|
echoedvoice: {
|
|
num: 497,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
basePowerCallback(pokemon, target, move) {
|
|
let bp = move.basePower;
|
|
if (this.field.pseudoWeather.echoedvoice) {
|
|
bp = move.basePower * this.field.pseudoWeather.echoedvoice.multiplier;
|
|
}
|
|
this.debug("BP: " + move.basePower);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
name: "Echoed Voice",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
onTry() {
|
|
this.field.addPseudoWeather("echoedvoice");
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onFieldStart() {
|
|
this.effectState.multiplier = 1;
|
|
},
|
|
onFieldRestart() {
|
|
if (this.effectState.duration !== 2) {
|
|
this.effectState.duration = 2;
|
|
if (this.effectState.multiplier < 5) {
|
|
this.effectState.multiplier++;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
eerieimpulse: {
|
|
num: 598,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Eerie Impulse",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
spa: -2
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
eeriespell: {
|
|
num: 826,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Eerie Spell",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target) {
|
|
if (!target.hp)
|
|
return;
|
|
let move = target.lastMove;
|
|
if (!move || move.isZ)
|
|
return;
|
|
if (move.isMax && move.baseMove)
|
|
move = this.dex.moves.get(move.baseMove);
|
|
const ppDeducted = target.deductPP(move.id, 3);
|
|
if (!ppDeducted)
|
|
return;
|
|
this.add("-activate", target, "move: Eerie Spell", move.name, ppDeducted);
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic"
|
|
},
|
|
eggbomb: {
|
|
num: 121,
|
|
accuracy: 75,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Egg Bomb",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
electricterrain: {
|
|
num: 604,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Electric Terrain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { nonsky: 1 },
|
|
terrain: "electricterrain",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasItem("terrainextender")) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onSetStatus(status, target, source, effect) {
|
|
if (status.id === "slp" && target.isGrounded() && !target.isSemiInvulnerable()) {
|
|
if (effect.id === "yawn" || effect.effectType === "Move" && !effect.secondaries) {
|
|
this.add("-activate", target, "move: Electric Terrain");
|
|
}
|
|
return false;
|
|
}
|
|
},
|
|
onTryAddVolatile(status, target) {
|
|
if (!target.isGrounded() || target.isSemiInvulnerable())
|
|
return;
|
|
if (status.id === "yawn") {
|
|
this.add("-activate", target, "move: Electric Terrain");
|
|
return null;
|
|
}
|
|
},
|
|
onBasePowerPriority: 6,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === "Electric" && attacker.isGrounded() && !attacker.isSemiInvulnerable()) {
|
|
this.debug("electric terrain boost");
|
|
return this.chainModify([5325, 4096]);
|
|
}
|
|
},
|
|
onFieldStart(field, source, effect) {
|
|
if (effect?.effectType === "Ability") {
|
|
this.add("-fieldstart", "move: Electric Terrain", "[from] ability: " + effect.name, "[of] " + source);
|
|
} else {
|
|
this.add("-fieldstart", "move: Electric Terrain");
|
|
}
|
|
},
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 7,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "move: Electric Terrain");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Electric",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
electrify: {
|
|
num: 582,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Electrify",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, allyanim: 1 },
|
|
volatileStatus: "electrify",
|
|
onTryHit(target) {
|
|
if (!this.queue.willMove(target) && target.activeTurns)
|
|
return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "move: Electrify");
|
|
},
|
|
onModifyTypePriority: -2,
|
|
onModifyType(move) {
|
|
if (move.id !== "struggle") {
|
|
this.debug("Electrify making move type electric");
|
|
move.type = "Electric";
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
electroball: {
|
|
num: 486,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
let ratio = Math.floor(pokemon.getStat("spe") / target.getStat("spe"));
|
|
if (!isFinite(ratio))
|
|
ratio = 0;
|
|
const bp = [40, 60, 80, 120, 150][Math.min(ratio, 4)];
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
name: "Electro Ball",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cool"
|
|
},
|
|
electrodrift: {
|
|
num: 879,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Electro Drift",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onBasePower(basePower, source, target, move) {
|
|
if (target.runEffectiveness(move) > 0) {
|
|
this.debug(`electro drift super effective buff`);
|
|
return this.chainModify([5461, 4096]);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
electroweb: {
|
|
num: 527,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Special",
|
|
name: "Electroweb",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Electric",
|
|
contestType: "Beautiful"
|
|
},
|
|
embargo: {
|
|
num: 373,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Embargo",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
volatileStatus: "embargo",
|
|
condition: {
|
|
duration: 5,
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "Embargo");
|
|
this.singleEvent("End", pokemon.getItem(), pokemon.itemState, pokemon);
|
|
},
|
|
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
|
|
onResidualOrder: 21,
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "Embargo");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
ember: {
|
|
num: 52,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Ember",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cute"
|
|
},
|
|
encore: {
|
|
num: 227,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Encore",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1, failencore: 1 },
|
|
volatileStatus: "encore",
|
|
condition: {
|
|
duration: 3,
|
|
noCopy: true,
|
|
// doesn't get copied by Z-Baton Pass
|
|
onStart(target) {
|
|
let move = target.lastMove;
|
|
if (!move || target.volatiles["dynamax"])
|
|
return false;
|
|
if (move.isMax && move.baseMove)
|
|
move = this.dex.moves.get(move.baseMove);
|
|
const moveIndex = target.moves.indexOf(move.id);
|
|
if (move.isZ || move.flags["failencore"] || !target.moveSlots[moveIndex] || target.moveSlots[moveIndex].pp <= 0) {
|
|
return false;
|
|
}
|
|
this.effectState.move = move.id;
|
|
this.add("-start", target, "Encore");
|
|
if (!this.queue.willMove(target)) {
|
|
this.effectState.duration++;
|
|
}
|
|
},
|
|
onOverrideAction(pokemon, target, move) {
|
|
if (move.id !== this.effectState.move)
|
|
return this.effectState.move;
|
|
},
|
|
onResidualOrder: 16,
|
|
onResidual(target) {
|
|
if (target.moves.includes(this.effectState.move) && target.moveSlots[target.moves.indexOf(this.effectState.move)].pp <= 0) {
|
|
target.removeVolatile("encore");
|
|
}
|
|
},
|
|
onEnd(target) {
|
|
this.add("-end", target, "Encore");
|
|
},
|
|
onDisableMove(pokemon) {
|
|
if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) {
|
|
return;
|
|
}
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (moveSlot.id !== this.effectState.move) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
endeavor: {
|
|
num: 283,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
return target.getUndynamaxedHP() - pokemon.hp;
|
|
},
|
|
category: "Physical",
|
|
name: "Endeavor",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, noparentalbond: 1 },
|
|
onTryImmunity(target, pokemon) {
|
|
return pokemon.hp < target.hp;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Tough"
|
|
},
|
|
endure: {
|
|
num: 203,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Endure",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: { noassist: 1, failcopycat: 1 },
|
|
stallingMove: true,
|
|
volatileStatus: "endure",
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "move: Endure");
|
|
},
|
|
onDamagePriority: -10,
|
|
onDamage(damage, target, source, effect) {
|
|
if (effect?.effectType === "Move" && damage >= target.hp) {
|
|
this.add("-activate", target, "move: Endure");
|
|
return target.hp - 1;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Tough"
|
|
},
|
|
energyball: {
|
|
num: 412,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Energy Ball",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful"
|
|
},
|
|
entrainment: {
|
|
num: 494,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Entrainment",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
onTryHit(target, source) {
|
|
if (target === source || target.volatiles["dynamax"])
|
|
return false;
|
|
const additionalBannedSourceAbilities = [
|
|
// Zen Mode included here for compatability with Gen 5-6
|
|
"flowergift",
|
|
"forecast",
|
|
"hungerswitch",
|
|
"illusion",
|
|
"imposter",
|
|
"neutralizinggas",
|
|
"powerofalchemy",
|
|
"receiver",
|
|
"trace",
|
|
"zenmode"
|
|
];
|
|
if (target.ability === source.ability || target.getAbility().isPermanent || target.ability === "truant" || source.getAbility().isPermanent || additionalBannedSourceAbilities.includes(source.ability)) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
const oldAbility = target.setAbility(source.ability);
|
|
if (oldAbility) {
|
|
this.add("-ability", target, target.getAbility().name, "[from] move: Entrainment");
|
|
if (!target.isAlly(source))
|
|
target.volatileStaleness = "external";
|
|
return;
|
|
}
|
|
return oldAbility;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
eruption: {
|
|
num: 284,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const bp = move.basePower * pokemon.hp / pokemon.maxhp;
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
name: "Eruption",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
esperwing: {
|
|
num: 840,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Esper Wing",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic"
|
|
},
|
|
eternabeam: {
|
|
num: 795,
|
|
accuracy: 90,
|
|
basePower: 160,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Eternabeam",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { recharge: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon"
|
|
},
|
|
expandingforce: {
|
|
num: 797,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Expanding Force",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onBasePower(basePower, source) {
|
|
if (this.field.isTerrain("psychicterrain") && source.isGrounded()) {
|
|
this.debug("terrain buff");
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
onModifyMove(move, source, target) {
|
|
if (this.field.isTerrain("psychicterrain") && source.isGrounded()) {
|
|
move.target = "allAdjacentFoes";
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic"
|
|
},
|
|
explosion: {
|
|
num: 153,
|
|
accuracy: 100,
|
|
basePower: 250,
|
|
category: "Physical",
|
|
name: "Explosion",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, noparentalbond: 1 },
|
|
selfdestruct: "always",
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
extrasensory: {
|
|
num: 326,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Extrasensory",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
extremeevoboost: {
|
|
num: 702,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Extreme Evoboost",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "eeviumz",
|
|
boosts: {
|
|
atk: 2,
|
|
def: 2,
|
|
spa: 2,
|
|
spd: 2,
|
|
spe: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
extremespeed: {
|
|
num: 245,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Extreme Speed",
|
|
pp: 5,
|
|
priority: 2,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
facade: {
|
|
num: 263,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Facade",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onBasePower(basePower, pokemon) {
|
|
if (pokemon.status && pokemon.status !== "slp") {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
fairylock: {
|
|
num: 587,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Fairy Lock",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { mirror: 1, bypasssub: 1 },
|
|
pseudoWeather: "fairylock",
|
|
condition: {
|
|
duration: 2,
|
|
onFieldStart(target) {
|
|
this.add("-fieldactivate", "move: Fairy Lock");
|
|
},
|
|
onTrapPokemon(pokemon) {
|
|
pokemon.tryTrap();
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fairy",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
fairywind: {
|
|
num: 584,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Fairy Wind",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Beautiful"
|
|
},
|
|
fakeout: {
|
|
num: 252,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Fake Out",
|
|
pp: 10,
|
|
priority: 3,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onTry(source) {
|
|
if (source.activeMoveActions > 1) {
|
|
this.hint("Fake Out only works on your first turn out.");
|
|
return false;
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
faketears: {
|
|
num: 313,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Fake Tears",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
boosts: {
|
|
spd: -2
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
falsesurrender: {
|
|
num: 793,
|
|
accuracy: true,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "False Surrender",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark"
|
|
},
|
|
falseswipe: {
|
|
num: 206,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "False Swipe",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onDamagePriority: -20,
|
|
onDamage(damage, target, source, effect) {
|
|
if (damage >= target.hp)
|
|
return target.hp - 1;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
featherdance: {
|
|
num: 297,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Feather Dance",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1, dance: 1 },
|
|
boosts: {
|
|
atk: -2
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
feint: {
|
|
num: 364,
|
|
accuracy: 100,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Feint",
|
|
pp: 10,
|
|
priority: 2,
|
|
flags: { mirror: 1, noassist: 1, failcopycat: 1 },
|
|
breaksProtect: true,
|
|
// Breaking protection implemented in scripts.js
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Clever"
|
|
},
|
|
feintattack: {
|
|
num: 185,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Feint Attack",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
fellstinger: {
|
|
num: 565,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Fell Stinger",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onAfterMoveSecondarySelf(pokemon, target, move) {
|
|
if (!target || target.fainted || target.hp <= 0)
|
|
this.boost({ atk: 3 }, pokemon, pokemon, move);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool"
|
|
},
|
|
fierydance: {
|
|
num: 552,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Fiery Dance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, dance: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
self: {
|
|
boosts: {
|
|
spa: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
fierywrath: {
|
|
num: 822,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Fiery Wrath",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Dark"
|
|
},
|
|
filletaway: {
|
|
num: 868,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Fillet Away",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onTry(source) {
|
|
if (source.hp <= source.maxhp / 2 || source.maxhp === 1)
|
|
return false;
|
|
},
|
|
onTryHit(pokemon, target, move) {
|
|
if (!this.boost(move.boosts))
|
|
return null;
|
|
delete move.boosts;
|
|
},
|
|
onHit(pokemon) {
|
|
this.directDamage(pokemon.maxhp / 2);
|
|
},
|
|
boosts: {
|
|
atk: 2,
|
|
spa: 2,
|
|
spe: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal"
|
|
},
|
|
finalgambit: {
|
|
num: 515,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
const damage = pokemon.hp;
|
|
pokemon.faint();
|
|
return damage;
|
|
},
|
|
category: "Special",
|
|
name: "Final Gambit",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, noparentalbond: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
zMove: { basePower: 180 },
|
|
contestType: "Tough"
|
|
},
|
|
fireblast: {
|
|
num: 126,
|
|
accuracy: 85,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Fire Blast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
firefang: {
|
|
num: 424,
|
|
accuracy: 95,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Fire Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
secondaries: [
|
|
{
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
{
|
|
chance: 10,
|
|
volatileStatus: "flinch"
|
|
}
|
|
],
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
firelash: {
|
|
num: 680,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Fire Lash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cute"
|
|
},
|
|
firepledge: {
|
|
num: 519,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
basePowerCallback(target, source, move) {
|
|
if (["grasspledge", "waterpledge"].includes(move.sourceEffect)) {
|
|
this.add("-combine");
|
|
return 150;
|
|
}
|
|
return 80;
|
|
},
|
|
category: "Special",
|
|
name: "Fire Pledge",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1, pledgecombo: 1 },
|
|
onPrepareHit(target, source, move) {
|
|
for (const action of this.queue.list) {
|
|
if (!action.move || !action.pokemon?.isActive || action.pokemon.fainted || action.maxMove || action.zmove) {
|
|
continue;
|
|
}
|
|
if (action.pokemon.isAlly(source) && ["grasspledge", "waterpledge"].includes(action.move.id)) {
|
|
this.queue.prioritizeAction(action, move);
|
|
this.add("-waiting", source, action.pokemon);
|
|
return null;
|
|
}
|
|
}
|
|
},
|
|
onModifyMove(move) {
|
|
if (move.sourceEffect === "waterpledge") {
|
|
move.type = "Water";
|
|
move.forceSTAB = true;
|
|
move.self = { sideCondition: "waterpledge" };
|
|
}
|
|
if (move.sourceEffect === "grasspledge") {
|
|
move.type = "Fire";
|
|
move.forceSTAB = true;
|
|
move.sideCondition = "firepledge";
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onSideStart(targetSide) {
|
|
this.add("-sidestart", targetSide, "Fire Pledge");
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1,
|
|
onResidual(pokemon) {
|
|
if (!pokemon.hasType("Fire"))
|
|
this.damage(pokemon.baseMaxhp / 8, pokemon);
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 8,
|
|
onSideEnd(targetSide) {
|
|
this.add("-sideend", targetSide, "Fire Pledge");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
firepunch: {
|
|
num: 7,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Fire Punch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Tough"
|
|
},
|
|
firespin: {
|
|
num: 83,
|
|
accuracy: 85,
|
|
basePower: 35,
|
|
category: "Special",
|
|
name: "Fire Spin",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
firstimpression: {
|
|
num: 660,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "First Impression",
|
|
pp: 10,
|
|
priority: 2,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onTry(source) {
|
|
if (source.activeMoveActions > 1) {
|
|
this.hint("First Impression only works on your first turn out.");
|
|
return false;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute"
|
|
},
|
|
fishiousrend: {
|
|
num: 755,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.newlySwitched || this.queue.willMove(target)) {
|
|
this.debug("Fishious Rend damage boost");
|
|
return move.basePower * 2;
|
|
}
|
|
this.debug("Fishious Rend NOT boosted");
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Fishious Rend",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water"
|
|
},
|
|
fissure: {
|
|
num: 90,
|
|
accuracy: 30,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Fissure",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
ohko: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
zMove: { basePower: 180 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Tough"
|
|
},
|
|
flail: {
|
|
num: 175,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const ratio = Math.max(Math.floor(pokemon.hp * 48 / pokemon.maxhp), 1);
|
|
let bp;
|
|
if (ratio < 2) {
|
|
bp = 200;
|
|
} else if (ratio < 5) {
|
|
bp = 150;
|
|
} else if (ratio < 10) {
|
|
bp = 100;
|
|
} else if (ratio < 17) {
|
|
bp = 80;
|
|
} else if (ratio < 33) {
|
|
bp = 40;
|
|
} else {
|
|
bp = 20;
|
|
}
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Flail",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cute"
|
|
},
|
|
flameburst: {
|
|
num: 481,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Flame Burst",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onHit(target, source, move) {
|
|
for (const ally of target.adjacentAllies()) {
|
|
this.damage(ally.baseMaxhp / 16, ally, source, this.dex.conditions.get("Flame Burst"));
|
|
}
|
|
},
|
|
onAfterSubDamage(damage, target, source, move) {
|
|
for (const ally of target.adjacentAllies()) {
|
|
this.damage(ally.baseMaxhp / 16, ally, source, this.dex.conditions.get("Flame Burst"));
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
flamecharge: {
|
|
num: 488,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Flame Charge",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
flamewheel: {
|
|
num: 172,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Flame Wheel",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, defrost: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
flamethrower: {
|
|
num: 53,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Flamethrower",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
flareblitz: {
|
|
num: 394,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Flare Blitz",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, defrost: 1 },
|
|
recoil: [33, 100],
|
|
secondary: {
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
flash: {
|
|
num: 148,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Flash",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
accuracy: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { evasion: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
flashcannon: {
|
|
num: 430,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Flash Cannon",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Beautiful"
|
|
},
|
|
flatter: {
|
|
num: 260,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Flatter",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
volatileStatus: "confusion",
|
|
boosts: {
|
|
spa: 1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
fleurcannon: {
|
|
num: 705,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Fleur Cannon",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
spa: -2
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Beautiful"
|
|
},
|
|
fling: {
|
|
num: 374,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Fling",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, allyanim: 1, noparentalbond: 1 },
|
|
onPrepareHit(target, source, move) {
|
|
if (source.ignoringItem())
|
|
return false;
|
|
const item = source.getItem();
|
|
if (!this.singleEvent("TakeItem", item, source.itemState, source, source, move, item))
|
|
return false;
|
|
if (!item.fling)
|
|
return false;
|
|
move.basePower = item.fling.basePower;
|
|
this.debug("BP: " + move.basePower);
|
|
if (item.isBerry) {
|
|
move.onHit = function(foe) {
|
|
if (this.singleEvent("Eat", item, null, foe, null, null)) {
|
|
this.runEvent("EatItem", foe, null, null, item);
|
|
if (item.id === "leppaberry")
|
|
foe.staleness = "external";
|
|
}
|
|
if (item.onEat)
|
|
foe.ateBerry = true;
|
|
};
|
|
} else if (item.fling.effect) {
|
|
move.onHit = item.fling.effect;
|
|
} else {
|
|
if (!move.secondaries)
|
|
move.secondaries = [];
|
|
if (item.fling.status) {
|
|
move.secondaries.push({ status: item.fling.status });
|
|
} else if (item.fling.volatileStatus) {
|
|
move.secondaries.push({ volatileStatus: item.fling.volatileStatus });
|
|
}
|
|
}
|
|
source.addVolatile("fling");
|
|
},
|
|
condition: {
|
|
onUpdate(pokemon) {
|
|
const item = pokemon.getItem();
|
|
pokemon.setItem("");
|
|
pokemon.lastItem = item.id;
|
|
pokemon.usedItemThisTurn = true;
|
|
this.add("-enditem", pokemon, item.name, "[from] move: Fling");
|
|
this.runEvent("AfterUseItem", pokemon, null, null, item);
|
|
pokemon.removeVolatile("fling");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cute"
|
|
},
|
|
flipturn: {
|
|
num: 812,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Flip Turn",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water"
|
|
},
|
|
floatyfall: {
|
|
num: 731,
|
|
accuracy: 95,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Floaty Fall",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, gravity: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
floralhealing: {
|
|
num: 666,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Floral Healing",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, heal: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
let success = false;
|
|
if (this.field.isTerrain("grassyterrain")) {
|
|
success = !!this.heal(this.modify(target.baseMaxhp, 0.667));
|
|
} else {
|
|
success = !!this.heal(Math.ceil(target.baseMaxhp * 0.5));
|
|
}
|
|
if (success && !target.isAlly(source)) {
|
|
target.staleness = "external";
|
|
}
|
|
if (!success) {
|
|
this.add("-fail", target, "heal");
|
|
return this.NOT_FAIL;
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
flowershield: {
|
|
num: 579,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Flower Shield",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { distance: 1 },
|
|
onHitField(t, source, move) {
|
|
const targets = [];
|
|
for (const pokemon of this.getAllActive()) {
|
|
if (pokemon.hasType("Grass") && (!pokemon.volatiles["maxguard"] || this.runEvent("TryHit", pokemon, source, move))) {
|
|
targets.push(pokemon);
|
|
}
|
|
}
|
|
let success = false;
|
|
for (const target of targets) {
|
|
success = this.boost({ def: 1 }, target, source, move) || success;
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fairy",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
flowertrick: {
|
|
num: 870,
|
|
accuracy: true,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Flower Trick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
willCrit: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass"
|
|
},
|
|
fly: {
|
|
num: 19,
|
|
accuracy: 95,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Fly",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {
|
|
contact: 1,
|
|
charge: 1,
|
|
protect: 1,
|
|
mirror: 1,
|
|
gravity: 1,
|
|
distance: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failinstruct: 1
|
|
},
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onInvulnerability(target, source, move) {
|
|
if (["gust", "twister", "skyuppercut", "thunder", "hurricane", "smackdown", "thousandarrows"].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onSourceModifyDamage(damage, source, target, move) {
|
|
if (move.id === "gust" || move.id === "twister") {
|
|
return this.chainModify(2);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Clever"
|
|
},
|
|
flyingpress: {
|
|
num: 560,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Flying Press",
|
|
pp: 10,
|
|
flags: { contact: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, nonsky: 1 },
|
|
onEffectiveness(typeMod, target, type, move) {
|
|
return typeMod + this.dex.getEffectiveness("Flying", type);
|
|
},
|
|
priority: 0,
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Fighting",
|
|
zMove: { basePower: 170 },
|
|
contestType: "Tough"
|
|
},
|
|
focusblast: {
|
|
num: 411,
|
|
accuracy: 70,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Focus Blast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
focusenergy: {
|
|
num: 116,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Focus Energy",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
volatileStatus: "focusenergy",
|
|
condition: {
|
|
onStart(target, source, effect) {
|
|
if (effect?.id === "zpower") {
|
|
this.add("-start", target, "move: Focus Energy", "[zeffect]");
|
|
} else if (effect && ["costar", "imposter", "psychup", "transform"].includes(effect.id)) {
|
|
this.add("-start", target, "move: Focus Energy", "[silent]");
|
|
} else {
|
|
this.add("-start", target, "move: Focus Energy");
|
|
}
|
|
},
|
|
onModifyCritRatio(critRatio) {
|
|
return critRatio + 2;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { accuracy: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
focuspunch: {
|
|
num: 264,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
name: "Focus Punch",
|
|
pp: 20,
|
|
priority: -3,
|
|
flags: { contact: 1, protect: 1, punch: 1, failmefirst: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
|
|
priorityChargeCallback(pokemon) {
|
|
pokemon.addVolatile("focuspunch");
|
|
},
|
|
beforeMoveCallback(pokemon) {
|
|
if (pokemon.volatiles["focuspunch"]?.lostFocus) {
|
|
this.add("cant", pokemon, "Focus Punch", "Focus Punch");
|
|
return true;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add("-singleturn", pokemon, "move: Focus Punch");
|
|
},
|
|
onHit(pokemon, source, move) {
|
|
if (move.category !== "Status") {
|
|
this.effectState.lostFocus = true;
|
|
}
|
|
},
|
|
onTryAddVolatile(status, pokemon) {
|
|
if (status.id === "flinch")
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
followme: {
|
|
num: 266,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Follow Me",
|
|
pp: 20,
|
|
priority: 2,
|
|
flags: { noassist: 1, failcopycat: 1 },
|
|
volatileStatus: "followme",
|
|
onTry(source) {
|
|
return this.activePerHalf > 1;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source, effect) {
|
|
if (effect?.id === "zpower") {
|
|
this.add("-singleturn", target, "move: Follow Me", "[zeffect]");
|
|
} else {
|
|
this.add("-singleturn", target, "move: Follow Me");
|
|
}
|
|
},
|
|
onFoeRedirectTargetPriority: 1,
|
|
onFoeRedirectTarget(target, source, source2, move) {
|
|
if (!this.effectState.target.isSkyDropped() && this.validTarget(this.effectState.target, source, move.target)) {
|
|
if (move.smartTarget)
|
|
move.smartTarget = false;
|
|
this.debug("Follow Me redirected target of move");
|
|
return this.effectState.target;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
forcepalm: {
|
|
num: 395,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Force Palm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
foresight: {
|
|
num: 193,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Foresight",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
volatileStatus: "foresight",
|
|
onTryHit(target) {
|
|
if (target.volatiles["miracleeye"])
|
|
return false;
|
|
},
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "Foresight");
|
|
},
|
|
onNegateImmunity(pokemon, type) {
|
|
if (pokemon.hasType("Ghost") && ["Normal", "Fighting"].includes(type))
|
|
return false;
|
|
},
|
|
onModifyBoost(boosts) {
|
|
if (boosts.evasion && boosts.evasion > 0) {
|
|
boosts.evasion = 0;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { effect: "crit2" },
|
|
contestType: "Clever"
|
|
},
|
|
forestscurse: {
|
|
num: 571,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Forest's Curse",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
onHit(target) {
|
|
if (target.hasType("Grass"))
|
|
return false;
|
|
if (!target.addType("Grass"))
|
|
return false;
|
|
this.add("-start", target, "typeadd", "Grass", "[from] move: Forest's Curse");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
foulplay: {
|
|
num: 492,
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Physical",
|
|
name: "Foul Play",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
overrideOffensivePokemon: "target",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
freezedry: {
|
|
num: 573,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
name: "Freeze-Dry",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onEffectiveness(typeMod, target, type) {
|
|
if (type === "Water")
|
|
return 1;
|
|
},
|
|
secondary: {
|
|
chance: 10,
|
|
status: "frz"
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
freezeshock: {
|
|
num: 553,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Freeze Shock",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { charge: 1, protect: 1, mirror: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
freezingglare: {
|
|
num: 821,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Freezing Glare",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "frz"
|
|
},
|
|
target: "normal",
|
|
type: "Psychic"
|
|
},
|
|
freezyfrost: {
|
|
num: 739,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Freezy Frost",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onHit() {
|
|
this.add("-clearallboost");
|
|
for (const pokemon of this.getAllActive()) {
|
|
pokemon.clearBoosts();
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Clever"
|
|
},
|
|
frenzyplant: {
|
|
num: 338,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Frenzy Plant",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { recharge: 1, protect: 1, mirror: 1, nonsky: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
frostbreath: {
|
|
num: 524,
|
|
accuracy: 90,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Frost Breath",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
willCrit: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
frustration: {
|
|
num: 218,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
return Math.floor((255 - pokemon.happiness) * 10 / 25) || 1;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Frustration",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cute"
|
|
},
|
|
furyattack: {
|
|
num: 31,
|
|
accuracy: 85,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Fury Attack",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
furycutter: {
|
|
num: 210,
|
|
accuracy: 95,
|
|
basePower: 40,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (!pokemon.volatiles["furycutter"] || move.hit === 1) {
|
|
pokemon.addVolatile("furycutter");
|
|
}
|
|
const bp = this.clampIntRange(move.basePower * pokemon.volatiles["furycutter"].multiplier, 1, 160);
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Fury Cutter",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
condition: {
|
|
duration: 2,
|
|
onStart() {
|
|
this.effectState.multiplier = 1;
|
|
},
|
|
onRestart() {
|
|
if (this.effectState.multiplier < 4) {
|
|
this.effectState.multiplier <<= 1;
|
|
}
|
|
this.effectState.duration = 2;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool"
|
|
},
|
|
furyswipes: {
|
|
num: 154,
|
|
accuracy: 80,
|
|
basePower: 18,
|
|
category: "Physical",
|
|
name: "Fury Swipes",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
maxMove: { basePower: 100 },
|
|
contestType: "Tough"
|
|
},
|
|
fusionbolt: {
|
|
num: 559,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Fusion Bolt",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onBasePower(basePower, pokemon) {
|
|
if (this.lastSuccessfulMoveThisTurn === "fusionflare") {
|
|
this.debug("double power");
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
fusionflare: {
|
|
num: 558,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Fusion Flare",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, defrost: 1 },
|
|
onBasePower(basePower, pokemon) {
|
|
if (this.lastSuccessfulMoveThisTurn === "fusionbolt") {
|
|
this.debug("double power");
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
futuresight: {
|
|
num: 248,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Future Sight",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { allyanim: 1, futuremove: 1 },
|
|
ignoreImmunity: true,
|
|
onTry(source, target) {
|
|
if (!target.side.addSlotCondition(target, "futuremove"))
|
|
return false;
|
|
Object.assign(target.side.slotConditions[target.position]["futuremove"], {
|
|
duration: 3,
|
|
move: "futuresight",
|
|
source,
|
|
moveData: {
|
|
id: "futuresight",
|
|
name: "Future Sight",
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
priority: 0,
|
|
flags: { allyanim: 1, futuremove: 1 },
|
|
ignoreImmunity: false,
|
|
effectType: "Move",
|
|
type: "Psychic"
|
|
}
|
|
});
|
|
this.add("-start", source, "move: Future Sight");
|
|
return this.NOT_FAIL;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
gastroacid: {
|
|
num: 380,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Gastro Acid",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
volatileStatus: "gastroacid",
|
|
onTryHit(target) {
|
|
if (target.getAbility().isPermanent) {
|
|
return false;
|
|
}
|
|
if (target.hasItem("Ability Shield")) {
|
|
this.add("-block", target, "item: Ability Shield");
|
|
return null;
|
|
}
|
|
},
|
|
condition: {
|
|
// Ability suppression implemented in Pokemon.ignoringAbility() within sim/pokemon.ts
|
|
onStart(pokemon) {
|
|
if (pokemon.hasItem("Ability Shield"))
|
|
return false;
|
|
this.add("-endability", pokemon);
|
|
this.singleEvent("End", pokemon.getAbility(), pokemon.abilityState, pokemon, pokemon, "gastroacid");
|
|
},
|
|
onCopy(pokemon) {
|
|
if (pokemon.getAbility().isPermanent)
|
|
pokemon.removeVolatile("gastroacid");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
geargrind: {
|
|
num: 544,
|
|
accuracy: 85,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Gear Grind",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: { basePower: 180 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Clever"
|
|
},
|
|
gearup: {
|
|
num: 674,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Gear Up",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1, bypasssub: 1 },
|
|
onHitSide(side, source, move) {
|
|
const targets = side.allies().filter((target) => target.hasAbility(["plus", "minus"]) && (!target.volatiles["maxguard"] || this.runEvent("TryHit", target, source, move)));
|
|
if (!targets.length)
|
|
return false;
|
|
let didSomething = false;
|
|
for (const target of targets) {
|
|
didSomething = this.boost({ atk: 1, spa: 1 }, target, source, move, false, true) || didSomething;
|
|
}
|
|
return didSomething;
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Steel",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
genesissupernova: {
|
|
num: 703,
|
|
accuracy: true,
|
|
basePower: 185,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Genesis Supernova",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "mewniumz",
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
onHit() {
|
|
this.field.setTerrain("psychicterrain");
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
geomancy: {
|
|
num: 601,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Geomancy",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { charge: 1, nonsky: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
boosts: {
|
|
spa: 2,
|
|
spd: 2,
|
|
spe: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fairy",
|
|
zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
gigadrain: {
|
|
num: 202,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Special",
|
|
name: "Giga Drain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, heal: 1 },
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever"
|
|
},
|
|
gigaimpact: {
|
|
num: 416,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
name: "Giga Impact",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, recharge: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
gigatonhammer: {
|
|
num: 893,
|
|
accuracy: 100,
|
|
basePower: 160,
|
|
category: "Physical",
|
|
name: "Gigaton Hammer",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onDisableMove(pokemon) {
|
|
if (pokemon.lastMove?.id === "gigatonhammer")
|
|
pokemon.disableMove("gigatonhammer");
|
|
},
|
|
beforeMoveCallback(pokemon) {
|
|
if (pokemon.lastMove?.id === "gigatonhammer")
|
|
pokemon.addVolatile("gigatonhammer");
|
|
},
|
|
onAfterMove(pokemon) {
|
|
if (pokemon.removeVolatile("gigatonhammer")) {
|
|
this.add("-hint", "Some effects can force a Pokemon to use Gigaton Hammer again in a row.");
|
|
}
|
|
},
|
|
condition: {},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel"
|
|
},
|
|
gigavolthavoc: {
|
|
num: 646,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Gigavolt Havoc",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "electriumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
glaciallance: {
|
|
num: 824,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Glacial Lance",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Ice"
|
|
},
|
|
glaciate: {
|
|
num: 549,
|
|
accuracy: 95,
|
|
basePower: 65,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Glaciate",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
glaiverush: {
|
|
num: 862,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Glaive Rush",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "glaiverush"
|
|
},
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
this.add("-singlemove", pokemon, "Glaive Rush", "[silent]");
|
|
},
|
|
onAccuracy() {
|
|
return true;
|
|
},
|
|
onSourceModifyDamage() {
|
|
return this.chainModify(2);
|
|
},
|
|
onBeforeMovePriority: 100,
|
|
onBeforeMove(pokemon) {
|
|
this.debug("removing Glaive Rush drawback before attack");
|
|
pokemon.removeVolatile("glaiverush");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon"
|
|
},
|
|
glare: {
|
|
num: 137,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Glare",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "par",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
glitzyglow: {
|
|
num: 736,
|
|
accuracy: 95,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Glitzy Glow",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
sideCondition: "lightscreen"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
gmaxbefuddle: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Befuddle",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Butterfree",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
const result = this.random(3);
|
|
if (result === 0) {
|
|
pokemon.trySetStatus("slp", source);
|
|
} else if (result === 1) {
|
|
pokemon.trySetStatus("par", source);
|
|
} else {
|
|
pokemon.trySetStatus("psn", source);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Bug",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxcannonade: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Cannonade",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Blastoise",
|
|
self: {
|
|
onHit(source) {
|
|
for (const side of source.side.foeSidesWithConditions()) {
|
|
side.addSideCondition("gmaxcannonade");
|
|
}
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onSideStart(targetSide) {
|
|
this.add("-sidestart", targetSide, "G-Max Cannonade");
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1,
|
|
onResidual(target) {
|
|
if (!target.hasType("Water"))
|
|
this.damage(target.baseMaxhp / 6, target);
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 11,
|
|
onSideEnd(targetSide) {
|
|
this.add("-sideend", targetSide, "G-Max Cannonade");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxcentiferno: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Centiferno",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Centiskorch",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
pokemon.addVolatile("partiallytrapped", source, this.dex.getActiveMove("G-Max Centiferno"));
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxchistrike: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Chi Strike",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Machamp",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.alliesAndSelf()) {
|
|
pokemon.addVolatile("gmaxchistrike");
|
|
}
|
|
}
|
|
},
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(target, source, effect) {
|
|
this.effectState.layers = 1;
|
|
if (!["costar", "imposter", "psychup", "transform"].includes(effect?.id)) {
|
|
this.add("-start", target, "move: G-Max Chi Strike");
|
|
}
|
|
},
|
|
onRestart(target, source, effect) {
|
|
if (this.effectState.layers >= 3)
|
|
return false;
|
|
this.effectState.layers++;
|
|
if (!["costar", "imposter", "psychup", "transform"].includes(effect?.id)) {
|
|
this.add("-start", target, "move: G-Max Chi Strike");
|
|
}
|
|
},
|
|
onModifyCritRatio(critRatio) {
|
|
return critRatio + this.effectState.layers;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxcuddle: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Cuddle",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Eevee",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
pokemon.addVolatile("attract");
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxdepletion: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Depletion",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Duraludon",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
let move = pokemon.lastMove;
|
|
if (!move || move.isZ)
|
|
continue;
|
|
if (move.isMax && move.baseMove)
|
|
move = this.dex.moves.get(move.baseMove);
|
|
const ppDeducted = pokemon.deductPP(move.id, 2);
|
|
if (ppDeducted) {
|
|
this.add("-activate", pokemon, "move: G-Max Depletion", move.name, ppDeducted);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Dragon",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxdrumsolo: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 160,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Drum Solo",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Rillaboom",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxfinale: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Finale",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Alcremie",
|
|
self: {
|
|
onHit(target, source, move) {
|
|
for (const pokemon of source.alliesAndSelf()) {
|
|
this.heal(pokemon.maxhp / 6, pokemon, source, move);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fairy",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxfireball: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 160,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Fireball",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Cinderace",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxfoamburst: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Foam Burst",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Kingler",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
this.boost({ spe: -2 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxgoldrush: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Gold Rush",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Meowth",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
pokemon.addVolatile("confusion");
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxgravitas: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Gravitas",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Orbeetle",
|
|
self: {
|
|
pseudoWeather: "gravity"
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxhydrosnipe: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 160,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Hydrosnipe",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Inteleon",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxmalodor: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Malodor",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Garbodor",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
pokemon.trySetStatus("psn", source);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Poison",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxmeltdown: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Meltdown",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Melmetal",
|
|
self: {
|
|
onHit(source, target, effect) {
|
|
for (const pokemon of source.foes()) {
|
|
if (!pokemon.volatiles["dynamax"])
|
|
pokemon.addVolatile("torment", source, effect);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxoneblow: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max One Blow",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Urshifu",
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxrapidflow: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Rapid Flow",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Urshifu-Rapid-Strike",
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxreplenish: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Replenish",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Snorlax",
|
|
self: {
|
|
onHit(source) {
|
|
if (this.random(2) === 0)
|
|
return;
|
|
for (const pokemon of source.alliesAndSelf()) {
|
|
if (pokemon.item)
|
|
continue;
|
|
if (pokemon.lastItem && this.dex.items.get(pokemon.lastItem).isBerry) {
|
|
const item = pokemon.lastItem;
|
|
pokemon.lastItem = "";
|
|
this.add("-item", pokemon, this.dex.items.get(item), "[from] move: G-Max Replenish");
|
|
pokemon.setItem(item);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxresonance: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Resonance",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Lapras",
|
|
self: {
|
|
sideCondition: "auroraveil"
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Ice",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxsandblast: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Sandblast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Sandaconda",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
pokemon.addVolatile("partiallytrapped", source, this.dex.getActiveMove("G-Max Sandblast"));
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Ground",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxsmite: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Smite",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Hatterene",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
pokemon.addVolatile("confusion", source);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fairy",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxsnooze: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Snooze",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Grimmsnarl",
|
|
onHit(target) {
|
|
if (target.status || !target.runStatusImmunity("slp"))
|
|
return;
|
|
if (this.random(2) === 0)
|
|
return;
|
|
target.addVolatile("yawn");
|
|
},
|
|
onAfterSubDamage(damage, target) {
|
|
if (target.status || !target.runStatusImmunity("slp"))
|
|
return;
|
|
if (this.random(2) === 0)
|
|
return;
|
|
target.addVolatile("yawn");
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxsteelsurge: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Steelsurge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Copperajah",
|
|
self: {
|
|
onHit(source) {
|
|
for (const side of source.side.foeSidesWithConditions()) {
|
|
side.addSideCondition("gmaxsteelsurge");
|
|
}
|
|
}
|
|
},
|
|
condition: {
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "move: G-Max Steelsurge");
|
|
},
|
|
onEntryHazard(pokemon) {
|
|
if (pokemon.hasItem("heavydutyboots"))
|
|
return;
|
|
const steelHazard = this.dex.getActiveMove("Stealth Rock");
|
|
steelHazard.type = "Steel";
|
|
const typeMod = this.clampIntRange(pokemon.runEffectiveness(steelHazard), -6, 6);
|
|
this.damage(pokemon.maxhp * Math.pow(2, typeMod) / 8);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxstonesurge: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Stonesurge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Drednaw",
|
|
self: {
|
|
onHit(source) {
|
|
for (const side of source.side.foeSidesWithConditions()) {
|
|
side.addSideCondition("stealthrock");
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxstunshock: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Stun Shock",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Toxtricity",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
const result = this.random(2);
|
|
if (result === 0) {
|
|
pokemon.trySetStatus("par", source);
|
|
} else {
|
|
pokemon.trySetStatus("psn", source);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxsweetness: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Sweetness",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Appletun",
|
|
self: {
|
|
onHit(source) {
|
|
for (const ally of source.side.pokemon) {
|
|
ally.cureStatus();
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxtartness: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Tartness",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Flapple",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
this.boost({ evasion: -1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxterror: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Terror",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Gengar",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
pokemon.addVolatile("trapped", source, null, "trapper");
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxvinelash: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Vine Lash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Venusaur",
|
|
self: {
|
|
onHit(source) {
|
|
for (const side of source.side.foeSidesWithConditions()) {
|
|
side.addSideCondition("gmaxvinelash");
|
|
}
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onSideStart(targetSide) {
|
|
this.add("-sidestart", targetSide, "G-Max Vine Lash");
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1,
|
|
onResidual(target) {
|
|
if (!target.hasType("Grass"))
|
|
this.damage(target.baseMaxhp / 6, target);
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 11,
|
|
onSideEnd(targetSide) {
|
|
this.add("-sideend", targetSide, "G-Max Vine Lash");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxvolcalith: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Volcalith",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Coalossal",
|
|
self: {
|
|
onHit(source) {
|
|
for (const side of source.side.foeSidesWithConditions()) {
|
|
side.addSideCondition("gmaxvolcalith");
|
|
}
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onSideStart(targetSide) {
|
|
this.add("-sidestart", targetSide, "G-Max Volcalith");
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1,
|
|
onResidual(target) {
|
|
if (!target.hasType("Rock"))
|
|
this.damage(target.baseMaxhp / 6, target);
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 11,
|
|
onSideEnd(targetSide) {
|
|
this.add("-sideend", targetSide, "G-Max Volcalith");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Rock",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxvoltcrash: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Volt Crash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Pikachu",
|
|
self: {
|
|
onHit(source) {
|
|
for (const pokemon of source.foes()) {
|
|
pokemon.trySetStatus("par", source);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxwildfire: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Wildfire",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Charizard",
|
|
self: {
|
|
onHit(source) {
|
|
for (const side of source.side.foeSidesWithConditions()) {
|
|
side.addSideCondition("gmaxwildfire");
|
|
}
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onSideStart(targetSide) {
|
|
this.add("-sidestart", targetSide, "G-Max Wildfire");
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 1,
|
|
onResidual(target) {
|
|
if (!target.hasType("Fire"))
|
|
this.damage(target.baseMaxhp / 6, target);
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 11,
|
|
onSideEnd(targetSide) {
|
|
this.add("-sideend", targetSide, "G-Max Wildfire");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
gmaxwindrage: {
|
|
num: 1e3,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Gigantamax",
|
|
name: "G-Max Wind Rage",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: "Corviknight",
|
|
self: {
|
|
onHit(source) {
|
|
let success = false;
|
|
const removeTarget = [
|
|
"reflect",
|
|
"lightscreen",
|
|
"auroraveil",
|
|
"safeguard",
|
|
"mist",
|
|
"spikes",
|
|
"toxicspikes",
|
|
"stealthrock",
|
|
"stickyweb"
|
|
];
|
|
const removeAll = ["spikes", "toxicspikes", "stealthrock", "stickyweb", "gmaxsteelsurge"];
|
|
for (const targetCondition of removeTarget) {
|
|
if (source.side.foe.removeSideCondition(targetCondition)) {
|
|
if (!removeAll.includes(targetCondition))
|
|
continue;
|
|
this.add("-sideend", source.side.foe, this.dex.conditions.get(targetCondition).name, "[from] move: G-Max Wind Rage", "[of] " + source);
|
|
success = true;
|
|
}
|
|
}
|
|
for (const sideCondition of removeAll) {
|
|
if (source.side.removeSideCondition(sideCondition)) {
|
|
this.add("-sideend", source.side, this.dex.conditions.get(sideCondition).name, "[from] move: G-Max Wind Rage", "[of] " + source);
|
|
success = true;
|
|
}
|
|
}
|
|
this.field.clearTerrain();
|
|
return success;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
grassknot: {
|
|
num: 447,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const targetWeight = target.getWeight();
|
|
let bp;
|
|
if (targetWeight >= 2e3) {
|
|
bp = 120;
|
|
} else if (targetWeight >= 1e3) {
|
|
bp = 100;
|
|
} else if (targetWeight >= 500) {
|
|
bp = 80;
|
|
} else if (targetWeight >= 250) {
|
|
bp = 60;
|
|
} else if (targetWeight >= 100) {
|
|
bp = 40;
|
|
} else {
|
|
bp = 20;
|
|
}
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
name: "Grass Knot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1 },
|
|
onTryHit(target, source, move) {
|
|
if (target.volatiles["dynamax"]) {
|
|
this.add("-fail", source, "move: Grass Knot", "[from] Dynamax");
|
|
this.attrLastMove("[still]");
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cute"
|
|
},
|
|
grasspledge: {
|
|
num: 520,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
basePowerCallback(target, source, move) {
|
|
if (["waterpledge", "firepledge"].includes(move.sourceEffect)) {
|
|
this.add("-combine");
|
|
return 150;
|
|
}
|
|
return 80;
|
|
},
|
|
category: "Special",
|
|
name: "Grass Pledge",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1, pledgecombo: 1 },
|
|
onPrepareHit(target, source, move) {
|
|
for (const action of this.queue.list) {
|
|
if (!action.move || !action.pokemon?.isActive || action.pokemon.fainted || action.maxMove || action.zmove) {
|
|
continue;
|
|
}
|
|
if (action.pokemon.isAlly(source) && ["waterpledge", "firepledge"].includes(action.move.id)) {
|
|
this.queue.prioritizeAction(action, move);
|
|
this.add("-waiting", source, action.pokemon);
|
|
return null;
|
|
}
|
|
}
|
|
},
|
|
onModifyMove(move) {
|
|
if (move.sourceEffect === "waterpledge") {
|
|
move.type = "Grass";
|
|
move.forceSTAB = true;
|
|
move.sideCondition = "grasspledge";
|
|
}
|
|
if (move.sourceEffect === "firepledge") {
|
|
move.type = "Fire";
|
|
move.forceSTAB = true;
|
|
move.sideCondition = "firepledge";
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onSideStart(targetSide) {
|
|
this.add("-sidestart", targetSide, "Grass Pledge");
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 9,
|
|
onSideEnd(targetSide) {
|
|
this.add("-sideend", targetSide, "Grass Pledge");
|
|
},
|
|
onModifySpe(spe, pokemon) {
|
|
return this.chainModify(0.25);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful"
|
|
},
|
|
grasswhistle: {
|
|
num: 320,
|
|
accuracy: 55,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Grass Whistle",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
status: "slp",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
grassyglide: {
|
|
num: 803,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Grassy Glide",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onModifyPriority(priority, source, target, move) {
|
|
if (this.field.isTerrain("grassyterrain") && source.isGrounded()) {
|
|
return priority + 1;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
grassyterrain: {
|
|
num: 580,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Grassy Terrain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { nonsky: 1 },
|
|
terrain: "grassyterrain",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasItem("terrainextender")) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onBasePowerPriority: 6,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
const weakenedMoves = ["earthquake", "bulldoze", "magnitude"];
|
|
if (weakenedMoves.includes(move.id) && defender.isGrounded() && !defender.isSemiInvulnerable()) {
|
|
this.debug("move weakened by grassy terrain");
|
|
return this.chainModify(0.5);
|
|
}
|
|
if (move.type === "Grass" && attacker.isGrounded()) {
|
|
this.debug("grassy terrain boost");
|
|
return this.chainModify([5325, 4096]);
|
|
}
|
|
},
|
|
onFieldStart(field, source, effect) {
|
|
if (effect?.effectType === "Ability") {
|
|
this.add("-fieldstart", "move: Grassy Terrain", "[from] ability: " + effect.name, "[of] " + source);
|
|
} else {
|
|
this.add("-fieldstart", "move: Grassy Terrain");
|
|
}
|
|
},
|
|
onResidualOrder: 5,
|
|
onResidualSubOrder: 2,
|
|
onResidual(pokemon) {
|
|
if (pokemon.isGrounded() && !pokemon.isSemiInvulnerable()) {
|
|
this.heal(pokemon.baseMaxhp / 16, pokemon, pokemon);
|
|
} else {
|
|
this.debug(`Pokemon semi-invuln or not grounded; Grassy Terrain skipped`);
|
|
}
|
|
},
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 7,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "move: Grassy Terrain");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Grass",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
gravapple: {
|
|
num: 788,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Grav Apple",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onBasePower(basePower) {
|
|
if (this.field.getPseudoWeather("gravity")) {
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Grass"
|
|
},
|
|
gravity: {
|
|
num: 356,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Gravity",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { nonsky: 1 },
|
|
pseudoWeather: "gravity",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-activate", source, "ability: Persistent", "[move] Gravity");
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onFieldStart(target, source) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-fieldstart", "move: Gravity", "[persistent]");
|
|
} else {
|
|
this.add("-fieldstart", "move: Gravity");
|
|
}
|
|
for (const pokemon of this.getAllActive()) {
|
|
let applies = false;
|
|
if (pokemon.removeVolatile("bounce") || pokemon.removeVolatile("fly")) {
|
|
applies = true;
|
|
this.queue.cancelMove(pokemon);
|
|
pokemon.removeVolatile("twoturnmove");
|
|
}
|
|
if (pokemon.volatiles["skydrop"]) {
|
|
applies = true;
|
|
this.queue.cancelMove(pokemon);
|
|
if (pokemon.volatiles["skydrop"].source) {
|
|
this.add("-end", pokemon.volatiles["twoturnmove"].source, "Sky Drop", "[interrupt]");
|
|
}
|
|
pokemon.removeVolatile("skydrop");
|
|
pokemon.removeVolatile("twoturnmove");
|
|
}
|
|
if (pokemon.volatiles["magnetrise"]) {
|
|
applies = true;
|
|
delete pokemon.volatiles["magnetrise"];
|
|
}
|
|
if (pokemon.volatiles["telekinesis"]) {
|
|
applies = true;
|
|
delete pokemon.volatiles["telekinesis"];
|
|
}
|
|
if (applies)
|
|
this.add("-activate", pokemon, "move: Gravity");
|
|
}
|
|
},
|
|
onModifyAccuracy(accuracy) {
|
|
if (typeof accuracy !== "number")
|
|
return;
|
|
return this.chainModify([6840, 4096]);
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (this.dex.moves.get(moveSlot.id).flags["gravity"]) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
// groundedness implemented in battle.engine.js:BattlePokemon#isGrounded
|
|
onBeforeMovePriority: 6,
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (move.flags["gravity"] && !move.isZ) {
|
|
this.add("cant", pokemon, "move: Gravity", move);
|
|
return false;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon, target) {
|
|
if (move.flags["gravity"] && !move.isZ) {
|
|
this.add("cant", pokemon, "move: Gravity", move);
|
|
return false;
|
|
}
|
|
},
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 2,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "move: Gravity");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
growl: {
|
|
num: 45,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Growl",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
boosts: {
|
|
atk: -1
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
growth: {
|
|
num: 74,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Growth",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onModifyMove(move, pokemon) {
|
|
if (["sunnyday", "desolateland"].includes(pokemon.effectiveWeather()))
|
|
move.boosts = { atk: 2, spa: 2 };
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
spa: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
grudge: {
|
|
num: 288,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Grudge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { bypasssub: 1 },
|
|
volatileStatus: "grudge",
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add("-singlemove", pokemon, "Grudge");
|
|
},
|
|
onFaint(target, source, effect) {
|
|
if (!source || source.fainted || !effect)
|
|
return;
|
|
if (effect.effectType === "Move" && !effect.flags["futuremove"] && source.lastMove) {
|
|
let move = source.lastMove;
|
|
if (move.isMax && move.baseMove)
|
|
move = this.dex.moves.get(move.baseMove);
|
|
for (const moveSlot of source.moveSlots) {
|
|
if (moveSlot.id === move.id) {
|
|
moveSlot.pp = 0;
|
|
this.add("-activate", source, "move: Grudge", move.name);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
onBeforeMovePriority: 100,
|
|
onBeforeMove(pokemon) {
|
|
this.debug("removing Grudge before attack");
|
|
pokemon.removeVolatile("grudge");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ghost",
|
|
zMove: { effect: "redirect" },
|
|
contestType: "Tough"
|
|
},
|
|
guardianofalola: {
|
|
num: 698,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
const hp75 = Math.floor(target.getUndynamaxedHP() * 3 / 4);
|
|
if (target.volatiles["protect"] || target.volatiles["banefulbunker"] || target.volatiles["kingsshield"] || target.volatiles["spikyshield"] || target.side.getSideCondition("matblock")) {
|
|
this.add("-zbroken", target);
|
|
return this.clampIntRange(Math.ceil(hp75 / 4 - 0.5), 1);
|
|
}
|
|
return this.clampIntRange(hp75, 1);
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Guardian of Alola",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "tapuniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Tough"
|
|
},
|
|
guardsplit: {
|
|
num: 470,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Guard Split",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
const newdef = Math.floor((target.storedStats.def + source.storedStats.def) / 2);
|
|
target.storedStats.def = newdef;
|
|
source.storedStats.def = newdef;
|
|
const newspd = Math.floor((target.storedStats.spd + source.storedStats.spd) / 2);
|
|
target.storedStats.spd = newspd;
|
|
source.storedStats.spd = newspd;
|
|
this.add("-activate", source, "move: Guard Split", "[of] " + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
guardswap: {
|
|
num: 385,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Guard Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, bypasssub: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
const targetBoosts = {};
|
|
const sourceBoosts = {};
|
|
const defSpd = ["def", "spd"];
|
|
for (const stat of defSpd) {
|
|
targetBoosts[stat] = target.boosts[stat];
|
|
sourceBoosts[stat] = source.boosts[stat];
|
|
}
|
|
source.setBoost(targetBoosts);
|
|
target.setBoost(sourceBoosts);
|
|
this.add("-swapboost", source, target, "def, spd", "[from] move: Guard Swap");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
guillotine: {
|
|
num: 12,
|
|
accuracy: 30,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Guillotine",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
ohko: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 180 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cool"
|
|
},
|
|
gunkshot: {
|
|
num: 441,
|
|
accuracy: 80,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Gunk Shot",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough"
|
|
},
|
|
gust: {
|
|
num: 16,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Gust",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, distance: 1, wind: 1 },
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Clever"
|
|
},
|
|
gyroball: {
|
|
num: 360,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
let power = Math.floor(25 * target.getStat("spe") / pokemon.getStat("spe")) + 1;
|
|
if (!isFinite(power))
|
|
power = 1;
|
|
if (power > 150)
|
|
power = 150;
|
|
this.debug("BP: " + power);
|
|
return power;
|
|
},
|
|
category: "Physical",
|
|
name: "Gyro Ball",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { bullet: 1, contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cool"
|
|
},
|
|
hail: {
|
|
num: 258,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Hail",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
weather: "hail",
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ice",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
hammerarm: {
|
|
num: 359,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Hammer Arm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
self: {
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
happyhour: {
|
|
num: 603,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Happy Hour",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryHit(target, source) {
|
|
this.add("-activate", target, "move: Happy Hour");
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
harden: {
|
|
num: 106,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Harden",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
haze: {
|
|
num: 114,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Haze",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { bypasssub: 1 },
|
|
onHitField() {
|
|
this.add("-clearallboost");
|
|
for (const pokemon of this.getAllActive()) {
|
|
pokemon.clearBoosts();
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ice",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Beautiful"
|
|
},
|
|
headbutt: {
|
|
num: 29,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Headbutt",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
headcharge: {
|
|
num: 543,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Head Charge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
recoil: [1, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
headlongrush: {
|
|
num: 838,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Headlong Rush",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
self: {
|
|
boosts: {
|
|
def: -1,
|
|
spd: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground"
|
|
},
|
|
headsmash: {
|
|
num: 457,
|
|
accuracy: 80,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
name: "Head Smash",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
recoil: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough"
|
|
},
|
|
healbell: {
|
|
num: 215,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Heal Bell",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, sound: 1, distance: 1, bypasssub: 1 },
|
|
onHit(target, source) {
|
|
this.add("-activate", source, "move: Heal Bell");
|
|
let success = false;
|
|
const allies = [...target.side.pokemon, ...target.side.allySide?.pokemon || []];
|
|
for (const ally of allies) {
|
|
if (ally !== source && ally.hasAbility("soundproof"))
|
|
continue;
|
|
if (ally.cureStatus())
|
|
success = true;
|
|
}
|
|
return success;
|
|
},
|
|
target: "allyTeam",
|
|
type: "Normal",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Beautiful"
|
|
},
|
|
healblock: {
|
|
num: 377,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Heal Block",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
volatileStatus: "healblock",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-activate", source, "ability: Persistent", "[move] Heal Block");
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onStart(pokemon, source) {
|
|
this.add("-start", pokemon, "move: Heal Block");
|
|
source.moveThisTurnResult = true;
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (this.dex.moves.get(moveSlot.id).flags["heal"]) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
onBeforeMovePriority: 6,
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (move.flags["heal"] && !move.isZ && !move.isMax) {
|
|
this.add("cant", pokemon, "move: Heal Block", move);
|
|
return false;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon, target) {
|
|
if (move.flags["heal"] && !move.isZ && !move.isMax) {
|
|
this.add("cant", pokemon, "move: Heal Block", move);
|
|
return false;
|
|
}
|
|
},
|
|
onResidualOrder: 20,
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "move: Heal Block");
|
|
},
|
|
onTryHeal(damage, target, source, effect) {
|
|
if (effect?.id === "zpower" || this.effectState.isZ)
|
|
return damage;
|
|
return false;
|
|
},
|
|
onRestart(target, source) {
|
|
this.add("-fail", target, "move: Heal Block");
|
|
if (!source.moveThisTurnResult) {
|
|
source.moveThisTurnResult = false;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Psychic",
|
|
zMove: { boost: { spa: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
healingwish: {
|
|
num: 361,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Healing Wish",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
onTryHit(source) {
|
|
if (!this.canSwitch(source.side)) {
|
|
this.attrLastMove("[still]");
|
|
this.add("-fail", source);
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
selfdestruct: "ifHit",
|
|
slotCondition: "healingwish",
|
|
condition: {
|
|
onSwap(target) {
|
|
if (!target.fainted && (target.hp < target.maxhp || target.status)) {
|
|
target.heal(target.maxhp);
|
|
target.clearStatus();
|
|
this.add("-heal", target, target.getHealth, "[from] move: Healing Wish");
|
|
target.side.removeSlotCondition(target, "healingwish");
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
contestType: "Beautiful"
|
|
},
|
|
healorder: {
|
|
num: 456,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Heal Order",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
healpulse: {
|
|
num: 505,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Heal Pulse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, pulse: 1, reflectable: 1, distance: 1, heal: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
let success = false;
|
|
if (source.hasAbility("megalauncher")) {
|
|
success = !!this.heal(this.modify(target.baseMaxhp, 0.75));
|
|
} else {
|
|
success = !!this.heal(Math.ceil(target.baseMaxhp * 0.5));
|
|
}
|
|
if (success && !target.isAlly(source)) {
|
|
target.staleness = "external";
|
|
}
|
|
if (!success) {
|
|
this.add("-fail", target, "heal");
|
|
return this.NOT_FAIL;
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Psychic",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
heartstamp: {
|
|
num: 531,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Heart Stamp",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cute"
|
|
},
|
|
heartswap: {
|
|
num: 391,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Heart Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, bypasssub: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
const targetBoosts = {};
|
|
const sourceBoosts = {};
|
|
let i;
|
|
for (i in target.boosts) {
|
|
targetBoosts[i] = target.boosts[i];
|
|
sourceBoosts[i] = source.boosts[i];
|
|
}
|
|
target.setBoost(sourceBoosts);
|
|
source.setBoost(targetBoosts);
|
|
this.add("-swapboost", source, target, "[from] move: Heart Swap");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { effect: "crit2" },
|
|
contestType: "Clever"
|
|
},
|
|
heatcrash: {
|
|
num: 535,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const targetWeight = target.getWeight();
|
|
const pokemonWeight = pokemon.getWeight();
|
|
let bp;
|
|
if (pokemonWeight >= targetWeight * 5) {
|
|
bp = 120;
|
|
} else if (pokemonWeight >= targetWeight * 4) {
|
|
bp = 100;
|
|
} else if (pokemonWeight >= targetWeight * 3) {
|
|
bp = 80;
|
|
} else if (pokemonWeight >= targetWeight * 2) {
|
|
bp = 60;
|
|
} else {
|
|
bp = 40;
|
|
}
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Heat Crash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1 },
|
|
onTryHit(target, pokemon, move) {
|
|
if (target.volatiles["dynamax"]) {
|
|
this.add("-fail", pokemon, "Dynamax");
|
|
this.attrLastMove("[still]");
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Tough"
|
|
},
|
|
heatwave: {
|
|
num: 257,
|
|
accuracy: 90,
|
|
basePower: 95,
|
|
category: "Special",
|
|
name: "Heat Wave",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
heavyslam: {
|
|
num: 484,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const targetWeight = target.getWeight();
|
|
const pokemonWeight = pokemon.getWeight();
|
|
let bp;
|
|
if (pokemonWeight >= targetWeight * 5) {
|
|
bp = 120;
|
|
} else if (pokemonWeight >= targetWeight * 4) {
|
|
bp = 100;
|
|
} else if (pokemonWeight >= targetWeight * 3) {
|
|
bp = 80;
|
|
} else if (pokemonWeight >= targetWeight * 2) {
|
|
bp = 60;
|
|
} else {
|
|
bp = 40;
|
|
}
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Heavy Slam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1 },
|
|
onTryHit(target, pokemon, move) {
|
|
if (target.volatiles["dynamax"]) {
|
|
this.add("-fail", pokemon, "Dynamax");
|
|
this.attrLastMove("[still]");
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Tough"
|
|
},
|
|
helpinghand: {
|
|
num: 270,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Helping Hand",
|
|
pp: 20,
|
|
priority: 5,
|
|
flags: { bypasssub: 1, noassist: 1, failcopycat: 1 },
|
|
volatileStatus: "helpinghand",
|
|
onTryHit(target) {
|
|
if (!target.newlySwitched && !this.queue.willMove(target))
|
|
return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source) {
|
|
this.effectState.multiplier = 1.5;
|
|
this.add("-singleturn", target, "Helping Hand", "[of] " + source);
|
|
},
|
|
onRestart(target, source) {
|
|
this.effectState.multiplier *= 1.5;
|
|
this.add("-singleturn", target, "Helping Hand", "[of] " + source);
|
|
},
|
|
onBasePowerPriority: 10,
|
|
onBasePower(basePower) {
|
|
this.debug("Boosting from Helping Hand: " + this.effectState.multiplier);
|
|
return this.chainModify(this.effectState.multiplier);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentAlly",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
hex: {
|
|
num: 506,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.status || target.hasAbility("comatose")) {
|
|
this.debug("BP doubled from status condition");
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Special",
|
|
name: "Hex",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: { basePower: 160 },
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpower: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onModifyType(move, pokemon) {
|
|
move.type = pokemon.hpType || "Dark";
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerbug: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Bug",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerdark: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Dark",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerdragon: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Dragon",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerelectric: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Electric",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerfighting: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Fighting",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerfire: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Fire",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerflying: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Flying",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerghost: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Ghost",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowergrass: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Grass",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerground: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Ground",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerice: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Ice",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerpoison: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Poison",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerpsychic: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Psychic",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerrock: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Rock",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowersteel: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Steel",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Clever"
|
|
},
|
|
hiddenpowerwater: {
|
|
num: 237,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
realMove: "Hidden Power",
|
|
isNonstandard: "Past",
|
|
name: "Hidden Power Water",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Clever"
|
|
},
|
|
highhorsepower: {
|
|
num: 667,
|
|
accuracy: 95,
|
|
basePower: 95,
|
|
category: "Physical",
|
|
name: "High Horsepower",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough"
|
|
},
|
|
highjumpkick: {
|
|
num: 136,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Physical",
|
|
name: "High Jump Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, gravity: 1 },
|
|
hasCrashDamage: true,
|
|
onMoveFail(target, source, move) {
|
|
this.damage(source.baseMaxhp / 2, source, source, this.dex.conditions.get("High Jump Kick"));
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
holdback: {
|
|
num: 610,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Hold Back",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onDamagePriority: -20,
|
|
onDamage(damage, target, source, effect) {
|
|
if (damage >= target.hp)
|
|
return target.hp - 1;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
holdhands: {
|
|
num: 607,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Hold Hands",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { bypasssub: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
secondary: null,
|
|
target: "adjacentAlly",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
honeclaws: {
|
|
num: 468,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Hone Claws",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
atk: 1,
|
|
accuracy: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dark",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
hornattack: {
|
|
num: 30,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Horn Attack",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
horndrill: {
|
|
num: 32,
|
|
accuracy: 30,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Horn Drill",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
ohko: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 180 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cool"
|
|
},
|
|
hornleech: {
|
|
num: 532,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Horn Leech",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, heal: 1 },
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough"
|
|
},
|
|
howl: {
|
|
num: 336,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Howl",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { snatch: 1, sound: 1 },
|
|
boosts: {
|
|
atk: 1
|
|
},
|
|
secondary: null,
|
|
target: "allies",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
hurricane: {
|
|
num: 542,
|
|
accuracy: 70,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Hurricane",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, distance: 1, wind: 1 },
|
|
onModifyMove(move, pokemon, target) {
|
|
switch (target?.effectiveWeather()) {
|
|
case "raindance":
|
|
case "primordialsea":
|
|
move.accuracy = true;
|
|
break;
|
|
case "sunnyday":
|
|
case "desolateland":
|
|
move.accuracy = 50;
|
|
break;
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Tough"
|
|
},
|
|
hydrocannon: {
|
|
num: 308,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Hydro Cannon",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { recharge: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
hydropump: {
|
|
num: 56,
|
|
accuracy: 80,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Hydro Pump",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
hydrosteam: {
|
|
num: 876,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Hydro Steam",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, defrost: 1 },
|
|
// Damage boost in Sun applied in conditions.ts
|
|
thawsTarget: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water"
|
|
},
|
|
hydrovortex: {
|
|
num: 642,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Hydro Vortex",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "wateriumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
hyperbeam: {
|
|
num: 63,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Hyper Beam",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { recharge: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
hyperdrill: {
|
|
num: 887,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Hyper Drill",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Clever"
|
|
},
|
|
hyperfang: {
|
|
num: 158,
|
|
accuracy: 90,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Hyper Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
hyperspacefury: {
|
|
num: 621,
|
|
accuracy: true,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Hyperspace Fury",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { mirror: 1, bypasssub: 1 },
|
|
breaksProtect: true,
|
|
onTry(source) {
|
|
if (source.species.name === "Hoopa-Unbound") {
|
|
return;
|
|
}
|
|
this.hint("Only a Pokemon whose form is Hoopa Unbound can use this move.");
|
|
if (source.species.name === "Hoopa") {
|
|
this.attrLastMove("[still]");
|
|
this.add("-fail", source, "move: Hyperspace Fury", "[forme]");
|
|
return null;
|
|
}
|
|
this.attrLastMove("[still]");
|
|
this.add("-fail", source, "move: Hyperspace Fury");
|
|
return null;
|
|
},
|
|
self: {
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough"
|
|
},
|
|
hyperspacehole: {
|
|
num: 593,
|
|
accuracy: true,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Hyperspace Hole",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { mirror: 1, bypasssub: 1 },
|
|
breaksProtect: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
hypervoice: {
|
|
num: 304,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Hyper Voice",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
hypnosis: {
|
|
num: 95,
|
|
accuracy: 60,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Hypnosis",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "slp",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
iceball: {
|
|
num: 301,
|
|
accuracy: 90,
|
|
basePower: 30,
|
|
basePowerCallback(pokemon, target, move) {
|
|
let bp = move.basePower;
|
|
const iceballData = pokemon.volatiles["iceball"];
|
|
if (iceballData?.hitCount) {
|
|
bp *= Math.pow(2, iceballData.contactHitCount);
|
|
}
|
|
if (iceballData && pokemon.status !== "slp") {
|
|
iceballData.hitCount++;
|
|
iceballData.contactHitCount++;
|
|
if (iceballData.hitCount < 5) {
|
|
iceballData.duration = 2;
|
|
}
|
|
}
|
|
if (pokemon.volatiles["defensecurl"]) {
|
|
bp *= 2;
|
|
}
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Ice Ball",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { bullet: 1, contact: 1, protect: 1, mirror: 1, noparentalbond: 1, failinstruct: 1 },
|
|
onModifyMove(move, pokemon, target) {
|
|
if (pokemon.volatiles["iceball"] || pokemon.status === "slp" || !target)
|
|
return;
|
|
pokemon.addVolatile("iceball");
|
|
pokemon.volatiles["iceball"].targetSlot = move.sourceEffect ? pokemon.lastMoveTargetLoc : pokemon.getLocOf(target);
|
|
},
|
|
onAfterMove(source, target, move) {
|
|
const iceballData = source.volatiles["iceball"];
|
|
if (iceballData && iceballData.hitCount === 5 && iceballData.contactHitCount < 5) {
|
|
source.addVolatile("rolloutstorage");
|
|
source.volatiles["rolloutstorage"].contactHitCount = iceballData.contactHitCount;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onLockMove: "iceball",
|
|
onStart() {
|
|
this.effectState.hitCount = 0;
|
|
this.effectState.contactHitCount = 0;
|
|
},
|
|
onResidual(target) {
|
|
if (target.lastMove && target.lastMove.id === "struggle") {
|
|
delete target.volatiles["iceball"];
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
icebeam: {
|
|
num: 58,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Ice Beam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "frz"
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
iceburn: {
|
|
num: 554,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Ice Burn",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { charge: 1, protect: 1, mirror: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
icefang: {
|
|
num: 423,
|
|
accuracy: 95,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Ice Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
secondaries: [
|
|
{
|
|
chance: 10,
|
|
status: "frz"
|
|
},
|
|
{
|
|
chance: 10,
|
|
volatileStatus: "flinch"
|
|
}
|
|
],
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Cool"
|
|
},
|
|
icehammer: {
|
|
num: 665,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Ice Hammer",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
self: {
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Tough"
|
|
},
|
|
icepunch: {
|
|
num: 8,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Ice Punch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "frz"
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
iceshard: {
|
|
num: 420,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Ice Shard",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
icespinner: {
|
|
num: 861,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Ice Spinner",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onHit() {
|
|
this.field.clearTerrain();
|
|
},
|
|
onAfterSubDamage() {
|
|
this.field.clearTerrain();
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice"
|
|
},
|
|
iciclecrash: {
|
|
num: 556,
|
|
accuracy: 90,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Icicle Crash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
iciclespear: {
|
|
num: 333,
|
|
accuracy: 100,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Icicle Spear",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Beautiful"
|
|
},
|
|
icywind: {
|
|
num: 196,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Special",
|
|
name: "Icy Wind",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
imprison: {
|
|
num: 286,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Imprison",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, bypasssub: 1, mustpressure: 1 },
|
|
volatileStatus: "imprison",
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(target) {
|
|
this.add("-start", target, "move: Imprison");
|
|
},
|
|
onFoeDisableMove(pokemon) {
|
|
for (const moveSlot of this.effectState.source.moveSlots) {
|
|
if (moveSlot.id === "struggle")
|
|
continue;
|
|
pokemon.disableMove(moveSlot.id, "hidden");
|
|
}
|
|
pokemon.maybeDisabled = true;
|
|
},
|
|
onFoeBeforeMovePriority: 4,
|
|
onFoeBeforeMove(attacker, defender, move) {
|
|
if (move.id !== "struggle" && this.effectState.source.hasMove(move.id) && !move.isZ && !move.isMax) {
|
|
this.add("cant", attacker, "move: Imprison", move);
|
|
return false;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { boost: { spd: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
incinerate: {
|
|
num: 510,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Incinerate",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onHit(pokemon, source) {
|
|
const item = pokemon.getItem();
|
|
if ((item.isBerry || item.isGem) && pokemon.takeItem(source)) {
|
|
this.add("-enditem", pokemon, item.name, "[from] move: Incinerate");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Tough"
|
|
},
|
|
infernalparade: {
|
|
num: 844,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.status || target.hasAbility("comatose"))
|
|
return move.basePower * 2;
|
|
return move.basePower;
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Infernal Parade",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Ghost"
|
|
},
|
|
inferno: {
|
|
num: 517,
|
|
accuracy: 50,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Inferno",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
infernooverdrive: {
|
|
num: 640,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Inferno Overdrive",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "firiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
infestation: {
|
|
num: 611,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Special",
|
|
name: "Infestation",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute"
|
|
},
|
|
ingrain: {
|
|
num: 275,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Ingrain",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1, nonsky: 1 },
|
|
volatileStatus: "ingrain",
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "move: Ingrain");
|
|
},
|
|
onResidualOrder: 7,
|
|
onResidual(pokemon) {
|
|
this.heal(pokemon.baseMaxhp / 16);
|
|
},
|
|
onTrapPokemon(pokemon) {
|
|
pokemon.tryTrap();
|
|
},
|
|
// groundedness implemented in battle.engine.js:BattlePokemon#isGrounded
|
|
onDragOut(pokemon) {
|
|
this.add("-activate", pokemon, "move: Ingrain");
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
instruct: {
|
|
num: 689,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Instruct",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, bypasssub: 1, allyanim: 1, failinstruct: 1 },
|
|
onHit(target, source) {
|
|
if (!target.lastMove || target.volatiles["dynamax"])
|
|
return false;
|
|
const lastMove = target.lastMove;
|
|
const moveIndex = target.moves.indexOf(lastMove.id);
|
|
if (lastMove.flags["failinstruct"] || lastMove.isZ || lastMove.isMax || lastMove.flags["charge"] || lastMove.flags["recharge"] || target.volatiles["beakblast"] || target.volatiles["focuspunch"] || target.volatiles["shelltrap"] || target.moveSlots[moveIndex] && target.moveSlots[moveIndex].pp <= 0) {
|
|
return false;
|
|
}
|
|
this.add("-singleturn", target, "move: Instruct", "[of] " + source);
|
|
this.queue.prioritizeAction(this.queue.resolveAction({
|
|
choice: "move",
|
|
pokemon: target,
|
|
moveid: target.lastMove.id,
|
|
targetLoc: target.lastMoveTargetLoc
|
|
})[0]);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
iondeluge: {
|
|
num: 569,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Ion Deluge",
|
|
pp: 25,
|
|
priority: 1,
|
|
flags: {},
|
|
pseudoWeather: "iondeluge",
|
|
condition: {
|
|
duration: 1,
|
|
onFieldStart(target, source, sourceEffect) {
|
|
this.add("-fieldactivate", "move: Ion Deluge");
|
|
this.hint(`Normal-type moves become Electric-type after using ${sourceEffect}.`);
|
|
},
|
|
onModifyTypePriority: -2,
|
|
onModifyType(move) {
|
|
if (move.type === "Normal") {
|
|
move.type = "Electric";
|
|
this.debug(move.name + "'s type changed to Electric");
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Electric",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
irondefense: {
|
|
num: 334,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Iron Defense",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Steel",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Tough"
|
|
},
|
|
ironhead: {
|
|
num: 442,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Iron Head",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Tough"
|
|
},
|
|
irontail: {
|
|
num: 231,
|
|
accuracy: 75,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Iron Tail",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
jawlock: {
|
|
num: 746,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Jaw Lock",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
onHit(target, source, move) {
|
|
source.addVolatile("trapped", target, move, "trapper");
|
|
target.addVolatile("trapped", source, move, "trapper");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark"
|
|
},
|
|
jetpunch: {
|
|
num: 857,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Jet Punch",
|
|
pp: 15,
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: null,
|
|
hasSheerForce: true,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
judgment: {
|
|
num: 449,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Judgment",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.ignoringItem())
|
|
return;
|
|
const item = pokemon.getItem();
|
|
if (item.id && item.onPlate && !item.zMove) {
|
|
move.type = item.onPlate;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
jumpkick: {
|
|
num: 26,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Jump Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, gravity: 1 },
|
|
hasCrashDamage: true,
|
|
onMoveFail(target, source, move) {
|
|
this.damage(source.baseMaxhp / 2, source, source, this.dex.conditions.get("Jump Kick"));
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
junglehealing: {
|
|
num: 816,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Jungle Healing",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { heal: 1, bypasssub: 1, allyanim: 1 },
|
|
onHit(pokemon) {
|
|
const success = !!this.heal(this.modify(pokemon.maxhp, 0.25));
|
|
return pokemon.cureStatus() || success;
|
|
},
|
|
secondary: null,
|
|
target: "allies",
|
|
type: "Grass"
|
|
},
|
|
karatechop: {
|
|
num: 2,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Karate Chop",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
kinesis: {
|
|
num: 134,
|
|
accuracy: 80,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Kinesis",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
accuracy: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { evasion: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
kingsshield: {
|
|
num: 588,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "King's Shield",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: { noassist: 1, failcopycat: 1, failinstruct: 1 },
|
|
stallingMove: true,
|
|
volatileStatus: "kingsshield",
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "Protect");
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags["protect"] || move.category === "Status") {
|
|
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
|
|
return;
|
|
if (move.isZ || move.isMax)
|
|
target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add("-activate", target, "move: Protect");
|
|
}
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
if (this.checkMoveMakesContact(move, source, target)) {
|
|
this.boost({ atk: -1 }, source, target, this.dex.getActiveMove("King's Shield"));
|
|
}
|
|
return this.NOT_FAIL;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
|
|
this.boost({ atk: -1 }, source, target, this.dex.getActiveMove("King's Shield"));
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Steel",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cool"
|
|
},
|
|
knockoff: {
|
|
num: 282,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Knock Off",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onBasePower(basePower, source, target, move) {
|
|
const item = target.getItem();
|
|
if (!this.singleEvent("TakeItem", item, target.itemState, target, target, move, item))
|
|
return;
|
|
if (item.id) {
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
onAfterHit(target, source) {
|
|
if (source.hp) {
|
|
const item = target.takeItem();
|
|
if (item) {
|
|
this.add("-enditem", target, item.name, "[from] move: Knock Off", "[of] " + source);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
kowtowcleave: {
|
|
num: 869,
|
|
accuracy: true,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Kowtow Cleave",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark"
|
|
},
|
|
landswrath: {
|
|
num: 616,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Land's Wrath",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Ground",
|
|
zMove: { basePower: 185 },
|
|
contestType: "Beautiful"
|
|
},
|
|
laserfocus: {
|
|
num: 673,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Laser Focus",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
volatileStatus: "laserfocus",
|
|
condition: {
|
|
duration: 2,
|
|
onStart(pokemon, source, effect) {
|
|
if (effect && ["costar", "imposter", "psychup", "transform"].includes(effect.id)) {
|
|
this.add("-start", pokemon, "move: Laser Focus", "[silent]");
|
|
} else {
|
|
this.add("-start", pokemon, "move: Laser Focus");
|
|
}
|
|
},
|
|
onRestart(pokemon) {
|
|
this.effectState.duration = 2;
|
|
this.add("-start", pokemon, "move: Laser Focus");
|
|
},
|
|
onModifyCritRatio(critRatio) {
|
|
return 5;
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "move: Laser Focus", "[silent]");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
lashout: {
|
|
num: 808,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Lash Out",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onBasePower(basePower, source) {
|
|
if (source.statsLoweredThisTurn) {
|
|
this.debug("lashout buff");
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark"
|
|
},
|
|
lastresort: {
|
|
num: 387,
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Physical",
|
|
name: "Last Resort",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onTry(source) {
|
|
if (source.moveSlots.length < 2)
|
|
return false;
|
|
let hasLastResort = false;
|
|
for (const moveSlot of source.moveSlots) {
|
|
if (moveSlot.id === "lastresort") {
|
|
hasLastResort = true;
|
|
continue;
|
|
}
|
|
if (!moveSlot.used)
|
|
return false;
|
|
}
|
|
return hasLastResort;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
lastrespects: {
|
|
num: 854,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return 50 + 50 * pokemon.side.totalFainted;
|
|
},
|
|
category: "Physical",
|
|
name: "Last Respects",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost"
|
|
},
|
|
lavaplume: {
|
|
num: 436,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Lava Plume",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "brn"
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Fire",
|
|
contestType: "Tough"
|
|
},
|
|
leafage: {
|
|
num: 670,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Leafage",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough"
|
|
},
|
|
leafblade: {
|
|
num: 348,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Leaf Blade",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
leafstorm: {
|
|
num: 437,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Leaf Storm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
spa: -2
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful"
|
|
},
|
|
leaftornado: {
|
|
num: 536,
|
|
accuracy: 90,
|
|
basePower: 65,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Leaf Tornado",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
accuracy: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
leechlife: {
|
|
num: 141,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Leech Life",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, heal: 1 },
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Clever"
|
|
},
|
|
leechseed: {
|
|
num: 73,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Leech Seed",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
volatileStatus: "leechseed",
|
|
condition: {
|
|
onStart(target) {
|
|
this.add("-start", target, "move: Leech Seed");
|
|
},
|
|
onResidualOrder: 8,
|
|
onResidual(pokemon) {
|
|
const target = this.getAtSlot(pokemon.volatiles["leechseed"].sourceSlot);
|
|
if (!target || target.fainted || target.hp <= 0) {
|
|
this.debug("Nothing to leech into");
|
|
return;
|
|
}
|
|
const damage = this.damage(pokemon.baseMaxhp / 8, pokemon, target);
|
|
if (damage) {
|
|
this.heal(damage, target, pokemon);
|
|
}
|
|
}
|
|
},
|
|
onTryImmunity(target) {
|
|
return !target.hasType("Grass");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
leer: {
|
|
num: 43,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Leer",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
def: -1
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
letssnuggleforever: {
|
|
num: 726,
|
|
accuracy: true,
|
|
basePower: 190,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Let's Snuggle Forever",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: { contact: 1 },
|
|
isZ: "mimikiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Cool"
|
|
},
|
|
lick: {
|
|
num: 122,
|
|
accuracy: 100,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Lick",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cute"
|
|
},
|
|
lifedew: {
|
|
num: 791,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Life Dew",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1, bypasssub: 1 },
|
|
heal: [1, 4],
|
|
secondary: null,
|
|
target: "allies",
|
|
type: "Water"
|
|
},
|
|
lightofruin: {
|
|
num: 617,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Light of Ruin",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
recoil: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Beautiful"
|
|
},
|
|
lightscreen: {
|
|
num: 113,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Light Screen",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
sideCondition: "lightscreen",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasItem("lightclay")) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onAnyModifyDamage(damage, source, target, move) {
|
|
if (target !== source && this.effectState.target.hasAlly(target) && this.getCategory(move) === "Special") {
|
|
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
|
|
this.debug("Light Screen weaken");
|
|
if (this.activePerHalf > 1)
|
|
return this.chainModify([2732, 4096]);
|
|
return this.chainModify(0.5);
|
|
}
|
|
}
|
|
},
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "move: Light Screen");
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 2,
|
|
onSideEnd(side) {
|
|
this.add("-sideend", side, "move: Light Screen");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Psychic",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
lightthatburnsthesky: {
|
|
num: 723,
|
|
accuracy: true,
|
|
basePower: 200,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Light That Burns the Sky",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onModifyMove(move, pokemon) {
|
|
if (pokemon.getStat("atk", false, true) > pokemon.getStat("spa", false, true))
|
|
move.category = "Physical";
|
|
},
|
|
ignoreAbility: true,
|
|
isZ: "ultranecroziumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
liquidation: {
|
|
num: 710,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Liquidation",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
lockon: {
|
|
num: 199,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Lock-On",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onTryHit(target, source) {
|
|
if (source.volatiles["lockon"])
|
|
return false;
|
|
},
|
|
onHit(target, source) {
|
|
source.addVolatile("lockon", target);
|
|
this.add("-activate", source, "move: Lock-On", "[of] " + target);
|
|
},
|
|
condition: {
|
|
noCopy: true,
|
|
// doesn't get copied by Baton Pass
|
|
duration: 2,
|
|
onSourceInvulnerabilityPriority: 1,
|
|
onSourceInvulnerability(target, source, move) {
|
|
if (move && source === this.effectState.target && target === this.effectState.source)
|
|
return 0;
|
|
},
|
|
onSourceAccuracy(accuracy, target, source, move) {
|
|
if (move && source === this.effectState.target && target === this.effectState.source)
|
|
return true;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
lovelykiss: {
|
|
num: 142,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Lovely Kiss",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "slp",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
lowkick: {
|
|
num: 67,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const targetWeight = target.getWeight();
|
|
let bp;
|
|
if (targetWeight >= 2e3) {
|
|
bp = 120;
|
|
} else if (targetWeight >= 1e3) {
|
|
bp = 100;
|
|
} else if (targetWeight >= 500) {
|
|
bp = 80;
|
|
} else if (targetWeight >= 250) {
|
|
bp = 60;
|
|
} else if (targetWeight >= 100) {
|
|
bp = 40;
|
|
} else {
|
|
bp = 20;
|
|
}
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Low Kick",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onTryHit(target, pokemon, move) {
|
|
if (target.volatiles["dynamax"]) {
|
|
this.add("-fail", pokemon, "Dynamax");
|
|
this.attrLastMove("[still]");
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
zMove: { basePower: 160 },
|
|
contestType: "Tough"
|
|
},
|
|
lowsweep: {
|
|
num: 490,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Low Sweep",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Clever"
|
|
},
|
|
luckychant: {
|
|
num: 381,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Lucky Chant",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
sideCondition: "luckychant",
|
|
condition: {
|
|
duration: 5,
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "move: Lucky Chant");
|
|
},
|
|
onCriticalHit: false,
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 6,
|
|
onSideEnd(side) {
|
|
this.add("-sideend", side, "move: Lucky Chant");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Normal",
|
|
zMove: { boost: { evasion: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
luminacrash: {
|
|
num: 855,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Lumina Crash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spd: -2
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic"
|
|
},
|
|
lunarblessing: {
|
|
num: 849,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Lunar Blessing",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
onHit(pokemon) {
|
|
const success = !!this.heal(this.modify(pokemon.maxhp, 0.25));
|
|
return pokemon.cureStatus() || success;
|
|
},
|
|
secondary: null,
|
|
target: "allies",
|
|
type: "Psychic"
|
|
},
|
|
lunardance: {
|
|
num: 461,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Lunar Dance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1, dance: 1 },
|
|
onTryHit(source) {
|
|
if (!this.canSwitch(source.side)) {
|
|
this.attrLastMove("[still]");
|
|
this.add("-fail", source);
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
selfdestruct: "ifHit",
|
|
slotCondition: "lunardance",
|
|
condition: {
|
|
onSwap(target) {
|
|
if (!target.fainted && (target.hp < target.maxhp || target.status || target.moveSlots.some((moveSlot) => moveSlot.pp < moveSlot.maxpp))) {
|
|
target.heal(target.maxhp);
|
|
target.clearStatus();
|
|
for (const moveSlot of target.moveSlots) {
|
|
moveSlot.pp = moveSlot.maxpp;
|
|
}
|
|
this.add("-heal", target, target.getHealth, "[from] move: Lunar Dance");
|
|
target.side.removeSlotCondition(target, "lunardance");
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
contestType: "Beautiful"
|
|
},
|
|
lunge: {
|
|
num: 679,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Lunge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
atk: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute"
|
|
},
|
|
lusterpurge: {
|
|
num: 295,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Luster Purge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
machpunch: {
|
|
num: 183,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Mach Punch",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
magicalleaf: {
|
|
num: 345,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Magical Leaf",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful"
|
|
},
|
|
magicaltorque: {
|
|
num: 900,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Magical Torque",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {
|
|
protect: 1,
|
|
failencore: 1,
|
|
failmefirst: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "normal",
|
|
type: "Fairy"
|
|
},
|
|
magiccoat: {
|
|
num: 277,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Magic Coat",
|
|
pp: 15,
|
|
priority: 4,
|
|
flags: {},
|
|
volatileStatus: "magiccoat",
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target, source, effect) {
|
|
this.add("-singleturn", target, "move: Magic Coat");
|
|
if (effect?.effectType === "Move") {
|
|
this.effectState.pranksterBoosted = effect.pranksterBoosted;
|
|
}
|
|
},
|
|
onTryHitPriority: 2,
|
|
onTryHit(target, source, move) {
|
|
if (target === source || move.hasBounced || !move.flags["reflectable"]) {
|
|
return;
|
|
}
|
|
const newMove = this.dex.getActiveMove(move.id);
|
|
newMove.hasBounced = true;
|
|
newMove.pranksterBoosted = this.effectState.pranksterBoosted;
|
|
this.actions.useMove(newMove, target, source);
|
|
return null;
|
|
},
|
|
onAllyTryHitSide(target, source, move) {
|
|
if (target.isAlly(source) || move.hasBounced || !move.flags["reflectable"]) {
|
|
return;
|
|
}
|
|
const newMove = this.dex.getActiveMove(move.id);
|
|
newMove.hasBounced = true;
|
|
newMove.pranksterBoosted = false;
|
|
this.actions.useMove(newMove, this.effectState.target, source);
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { boost: { spd: 2 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
magicpowder: {
|
|
num: 750,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Magic Powder",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { powder: 1, protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
onHit(target) {
|
|
if (target.getTypes().join() === "Psychic" || !target.setType("Psychic"))
|
|
return false;
|
|
this.add("-start", target, "typechange", "Psychic");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic"
|
|
},
|
|
magicroom: {
|
|
num: 478,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Magic Room",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { mirror: 1 },
|
|
pseudoWeather: "magicroom",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-activate", source, "ability: Persistent", "[move] Magic Room");
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onFieldStart(target, source) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-fieldstart", "move: Magic Room", "[of] " + source, "[persistent]");
|
|
} else {
|
|
this.add("-fieldstart", "move: Magic Room", "[of] " + source);
|
|
}
|
|
for (const mon of this.getAllActive()) {
|
|
this.singleEvent("End", mon.getItem(), mon.itemState, mon);
|
|
}
|
|
},
|
|
onFieldRestart(target, source) {
|
|
this.field.removePseudoWeather("magicroom");
|
|
},
|
|
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 6,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "move: Magic Room", "[of] " + this.effectState.source);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
magmastorm: {
|
|
num: 463,
|
|
accuracy: 75,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Magma Storm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Tough"
|
|
},
|
|
magnetbomb: {
|
|
num: 443,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Magnet Bomb",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
magneticflux: {
|
|
num: 602,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Magnetic Flux",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1, distance: 1, bypasssub: 1 },
|
|
onHitSide(side, source, move) {
|
|
const targets = side.allies().filter((ally) => ally.hasAbility(["plus", "minus"]) && (!ally.volatiles["maxguard"] || this.runEvent("TryHit", ally, source, move)));
|
|
if (!targets.length)
|
|
return false;
|
|
let didSomething = false;
|
|
for (const target of targets) {
|
|
didSomething = this.boost({ def: 1, spd: 1 }, target, source, move, false, true) || didSomething;
|
|
}
|
|
return didSomething;
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Electric",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
magnetrise: {
|
|
num: 393,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Magnet Rise",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, gravity: 1 },
|
|
volatileStatus: "magnetrise",
|
|
onTry(source, target, move) {
|
|
if (target.volatiles["smackdown"] || target.volatiles["ingrain"])
|
|
return false;
|
|
if (this.field.getPseudoWeather("Gravity")) {
|
|
this.add("cant", source, "move: Gravity", move);
|
|
return null;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 5,
|
|
onStart(target) {
|
|
this.add("-start", target, "Magnet Rise");
|
|
},
|
|
onImmunity(type) {
|
|
if (type === "Ground")
|
|
return false;
|
|
},
|
|
onResidualOrder: 18,
|
|
onEnd(target) {
|
|
this.add("-end", target, "Magnet Rise");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Electric",
|
|
zMove: { boost: { evasion: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
magnitude: {
|
|
num: 222,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Magnitude",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
onModifyMove(move, pokemon) {
|
|
const i = this.random(100);
|
|
if (i < 5) {
|
|
move.magnitude = 4;
|
|
move.basePower = 10;
|
|
} else if (i < 15) {
|
|
move.magnitude = 5;
|
|
move.basePower = 30;
|
|
} else if (i < 35) {
|
|
move.magnitude = 6;
|
|
move.basePower = 50;
|
|
} else if (i < 65) {
|
|
move.magnitude = 7;
|
|
move.basePower = 70;
|
|
} else if (i < 85) {
|
|
move.magnitude = 8;
|
|
move.basePower = 90;
|
|
} else if (i < 95) {
|
|
move.magnitude = 9;
|
|
move.basePower = 110;
|
|
} else {
|
|
move.magnitude = 10;
|
|
move.basePower = 150;
|
|
}
|
|
},
|
|
onUseMoveMessage(pokemon, target, move) {
|
|
this.add("-activate", pokemon, "move: Magnitude", move.magnitude);
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Ground",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 140 },
|
|
contestType: "Tough"
|
|
},
|
|
makeitrain: {
|
|
num: 874,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Make It Rain",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
spa: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Steel",
|
|
contestType: "Beautiful"
|
|
},
|
|
maliciousmoonsault: {
|
|
num: 696,
|
|
accuracy: true,
|
|
basePower: 180,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Malicious Moonsault",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: { contact: 1 },
|
|
isZ: "inciniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
matblock: {
|
|
num: 561,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Mat Block",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, nonsky: 1, noassist: 1, failcopycat: 1 },
|
|
stallingMove: true,
|
|
sideCondition: "matblock",
|
|
onTry(source) {
|
|
if (source.activeMoveActions > 1) {
|
|
this.hint("Mat Block only works on your first turn out.");
|
|
return false;
|
|
}
|
|
return !!this.queue.willAct();
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onSideStart(target, source) {
|
|
this.add("-singleturn", source, "Mat Block");
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags["protect"]) {
|
|
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
|
|
return;
|
|
if (move.isZ || move.isMax)
|
|
target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move && (move.target === "self" || move.category === "Status"))
|
|
return;
|
|
this.add("-activate", target, "move: Mat Block", move.name);
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Fighting",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
maxairstream: {
|
|
num: 766,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Airstream",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.alliesAndSelf()) {
|
|
this.boost({ spe: 1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
maxdarkness: {
|
|
num: 772,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Darkness",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.foes()) {
|
|
this.boost({ spd: -1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
maxflare: {
|
|
num: 757,
|
|
accuracy: true,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Flare",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
this.field.setWeather("sunnyday");
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
maxflutterby: {
|
|
num: 758,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Flutterby",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.foes()) {
|
|
this.boost({ spa: -1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Bug",
|
|
contestType: "Cool"
|
|
},
|
|
maxgeyser: {
|
|
num: 765,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Geyser",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
this.field.setWeather("raindance");
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
maxguard: {
|
|
num: 743,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Max Guard",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {},
|
|
isMax: true,
|
|
stallingMove: true,
|
|
volatileStatus: "maxguard",
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "Max Guard");
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
const bypassesMaxGuard = [
|
|
"acupressure",
|
|
"afteryou",
|
|
"allyswitch",
|
|
"aromatherapy",
|
|
"aromaticmist",
|
|
"coaching",
|
|
"confide",
|
|
"copycat",
|
|
"curse",
|
|
"decorate",
|
|
"doomdesire",
|
|
"feint",
|
|
"futuresight",
|
|
"gmaxoneblow",
|
|
"gmaxrapidflow",
|
|
"healbell",
|
|
"holdhands",
|
|
"howl",
|
|
"junglehealing",
|
|
"lifedew",
|
|
"meanlook",
|
|
"perishsong",
|
|
"playnice",
|
|
"powertrick",
|
|
"roar",
|
|
"roleplay",
|
|
"tearfullook"
|
|
];
|
|
if (bypassesMaxGuard.includes(move.id))
|
|
return;
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add("-activate", target, "move: Max Guard");
|
|
}
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
maxhailstorm: {
|
|
num: 763,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Hailstorm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
this.field.setWeather("hail");
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Ice",
|
|
contestType: "Cool"
|
|
},
|
|
maxknuckle: {
|
|
num: 761,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Knuckle",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.alliesAndSelf()) {
|
|
this.boost({ atk: 1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
maxlightning: {
|
|
num: 759,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Lightning",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
this.field.setTerrain("electricterrain");
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
maxmindstorm: {
|
|
num: 769,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Mindstorm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
this.field.setTerrain("psychicterrain");
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
maxooze: {
|
|
num: 764,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Ooze",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.alliesAndSelf()) {
|
|
this.boost({ spa: 1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Poison",
|
|
contestType: "Cool"
|
|
},
|
|
maxovergrowth: {
|
|
num: 773,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Overgrowth",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
this.field.setTerrain("grassyterrain");
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
maxphantasm: {
|
|
num: 762,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Phantasm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.foes()) {
|
|
this.boost({ def: -1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
maxquake: {
|
|
num: 771,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Quake",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.alliesAndSelf()) {
|
|
this.boost({ spd: 1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Ground",
|
|
contestType: "Cool"
|
|
},
|
|
maxrockfall: {
|
|
num: 770,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Rockfall",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
this.field.setWeather("sandstorm");
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Rock",
|
|
contestType: "Cool"
|
|
},
|
|
maxstarfall: {
|
|
num: 767,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Starfall",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
this.field.setTerrain("mistyterrain");
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Fairy",
|
|
contestType: "Cool"
|
|
},
|
|
maxsteelspike: {
|
|
num: 774,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Steelspike",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.alliesAndSelf()) {
|
|
this.boost({ def: 1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
maxstrike: {
|
|
num: 760,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Strike",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.foes()) {
|
|
this.boost({ spe: -1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
maxwyrmwind: {
|
|
num: 768,
|
|
accuracy: true,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Max Wyrmwind",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
isMax: true,
|
|
self: {
|
|
onHit(source) {
|
|
if (!source.volatiles["dynamax"])
|
|
return;
|
|
for (const pokemon of source.foes()) {
|
|
this.boost({ atk: -1 }, pokemon);
|
|
}
|
|
}
|
|
},
|
|
target: "adjacentFoe",
|
|
type: "Dragon",
|
|
contestType: "Cool"
|
|
},
|
|
meanlook: {
|
|
num: 212,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Mean Look",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { reflectable: 1, mirror: 1 },
|
|
onHit(target, source, move) {
|
|
return target.addVolatile("trapped", source, move, "trapper");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
meditate: {
|
|
num: 96,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Meditate",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
atk: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
mefirst: {
|
|
num: 382,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Me First",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {
|
|
protect: 1,
|
|
bypasssub: 1,
|
|
failencore: 1,
|
|
failmefirst: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
onTryHit(target, pokemon) {
|
|
const action = this.queue.willMove(target);
|
|
if (!action)
|
|
return false;
|
|
const move = this.dex.getActiveMove(action.move.id);
|
|
if (action.zmove || move.isZ || move.isMax)
|
|
return false;
|
|
if (target.volatiles["mustrecharge"])
|
|
return false;
|
|
if (move.category === "Status" || move.flags["failmefirst"])
|
|
return false;
|
|
pokemon.addVolatile("mefirst");
|
|
this.actions.useMove(move, pokemon, target);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onBasePowerPriority: 12,
|
|
onBasePower(basePower) {
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "adjacentFoe",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
megadrain: {
|
|
num: 72,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Mega Drain",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, heal: 1 },
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { basePower: 120 },
|
|
contestType: "Clever"
|
|
},
|
|
megahorn: {
|
|
num: 224,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Megahorn",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool"
|
|
},
|
|
megakick: {
|
|
num: 25,
|
|
accuracy: 75,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Mega Kick",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
megapunch: {
|
|
num: 5,
|
|
accuracy: 85,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Mega Punch",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
memento: {
|
|
num: 262,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Memento",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
boosts: {
|
|
atk: -2,
|
|
spa: -2
|
|
},
|
|
selfdestruct: "ifHit",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { effect: "healreplacement" },
|
|
contestType: "Tough"
|
|
},
|
|
menacingmoonrazemaelstrom: {
|
|
num: 725,
|
|
accuracy: true,
|
|
basePower: 200,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Menacing Moonraze Maelstrom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "lunaliumz",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
metalburst: {
|
|
num: 368,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
const lastDamagedBy = pokemon.getLastDamagedBy(true);
|
|
if (lastDamagedBy !== void 0) {
|
|
return lastDamagedBy.damage * 1.5 || 1;
|
|
}
|
|
return 0;
|
|
},
|
|
category: "Physical",
|
|
name: "Metal Burst",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, failmefirst: 1 },
|
|
onTry(source) {
|
|
const lastDamagedBy = source.getLastDamagedBy(true);
|
|
if (lastDamagedBy === void 0 || !lastDamagedBy.thisTurn)
|
|
return false;
|
|
},
|
|
onModifyTarget(targetRelayVar, source, target, move) {
|
|
const lastDamagedBy = source.getLastDamagedBy(true);
|
|
if (lastDamagedBy) {
|
|
targetRelayVar.target = this.getAtSlot(lastDamagedBy.slot);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "scripted",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
metalclaw: {
|
|
num: 232,
|
|
accuracy: 95,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Metal Claw",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
atk: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
metalsound: {
|
|
num: 319,
|
|
accuracy: 85,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Metal Sound",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1, allyanim: 1 },
|
|
boosts: {
|
|
spd: -2
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
meteorassault: {
|
|
num: 794,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Meteor Assault",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, recharge: 1, mirror: 1, failinstruct: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting"
|
|
},
|
|
meteorbeam: {
|
|
num: 800,
|
|
accuracy: 90,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Meteor Beam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { charge: 1, protect: 1, mirror: 1 },
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
this.boost({ spa: 1 }, attacker, attacker, move);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock"
|
|
},
|
|
meteormash: {
|
|
num: 309,
|
|
accuracy: 90,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Meteor Mash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
self: {
|
|
boosts: {
|
|
atk: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
metronome: {
|
|
num: 118,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Metronome",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
noMetronome: [
|
|
"After You",
|
|
"Apple Acid",
|
|
"Armor Cannon",
|
|
"Assist",
|
|
"Astral Barrage",
|
|
"Aura Wheel",
|
|
"Baneful Bunker",
|
|
"Beak Blast",
|
|
"Behemoth Bash",
|
|
"Behemoth Blade",
|
|
"Belch",
|
|
"Bestow",
|
|
"Blazing Torque",
|
|
"Body Press",
|
|
"Branch Poke",
|
|
"Breaking Swipe",
|
|
"Celebrate",
|
|
"Chatter",
|
|
"Chilling Water",
|
|
"Chilly Reception",
|
|
"Clangorous Soul",
|
|
"Collision Course",
|
|
"Combat Torque",
|
|
"Comeuppance",
|
|
"Copycat",
|
|
"Counter",
|
|
"Covet",
|
|
"Crafty Shield",
|
|
"Decorate",
|
|
"Destiny Bond",
|
|
"Detect",
|
|
"Diamond Storm",
|
|
"Doodle",
|
|
"Double Iron Bash",
|
|
"Double Shock",
|
|
"Dragon Ascent",
|
|
"Dragon Energy",
|
|
"Drum Beating",
|
|
"Dynamax Cannon",
|
|
"Electro Drift",
|
|
"Endure",
|
|
"Eternabeam",
|
|
"False Surrender",
|
|
"Feint",
|
|
"Fiery Wrath",
|
|
"Fillet Away",
|
|
"Fleur Cannon",
|
|
"Focus Punch",
|
|
"Follow Me",
|
|
"Freeze Shock",
|
|
"Freezing Glare",
|
|
"Glacial Lance",
|
|
"Grav Apple",
|
|
"Helping Hand",
|
|
"Hold Hands",
|
|
"Hyper Drill",
|
|
"Hyperspace Fury",
|
|
"Hyperspace Hole",
|
|
"Ice Burn",
|
|
"Instruct",
|
|
"Jet Punch",
|
|
"Jungle Healing",
|
|
"King's Shield",
|
|
"Life Dew",
|
|
"Light of Ruin",
|
|
"Magical Torque",
|
|
"Make It Rain",
|
|
"Mat Block",
|
|
"Me First",
|
|
"Meteor Assault",
|
|
"Metronome",
|
|
"Mimic",
|
|
"Mind Blown",
|
|
"Mirror Coat",
|
|
"Mirror Move",
|
|
"Moongeist Beam",
|
|
"Nature Power",
|
|
"Nature's Madness",
|
|
"Noxious Torque",
|
|
"Obstruct",
|
|
"Order Up",
|
|
"Origin Pulse",
|
|
"Overdrive",
|
|
"Photon Geyser",
|
|
"Plasma Fists",
|
|
"Population Bomb",
|
|
"Pounce",
|
|
"Power Shift",
|
|
"Precipice Blades",
|
|
"Protect",
|
|
"Pyro Ball",
|
|
"Quash",
|
|
"Quick Guard",
|
|
"Rage Fist",
|
|
"Rage Powder",
|
|
"Raging Bull",
|
|
"Raging Fury",
|
|
"Relic Song",
|
|
"Revival Blessing",
|
|
"Ruination",
|
|
"Salt Cure",
|
|
"Secret Sword",
|
|
"Shed Tail",
|
|
"Shell Trap",
|
|
"Silk Trap",
|
|
"Sketch",
|
|
"Sleep Talk",
|
|
"Snap Trap",
|
|
"Snarl",
|
|
"Snatch",
|
|
"Snore",
|
|
"Snowscape",
|
|
"Spectral Thief",
|
|
"Spicy Extract",
|
|
"Spiky Shield",
|
|
"Spirit Break",
|
|
"Spotlight",
|
|
"Springtide Storm",
|
|
"Steam Eruption",
|
|
"Steel Beam",
|
|
"Strange Steam",
|
|
"Struggle",
|
|
"Sunsteel Strike",
|
|
"Surging Strikes",
|
|
"Switcheroo",
|
|
"Techno Blast",
|
|
"Thief",
|
|
"Thousand Arrows",
|
|
"Thousand Waves",
|
|
"Thunder Cage",
|
|
"Thunderous Kick",
|
|
"Tidy Up",
|
|
"Trailblaze",
|
|
"Transform",
|
|
"Trick",
|
|
"Twin Beam",
|
|
"V-create",
|
|
"Wicked Blow",
|
|
"Wicked Torque",
|
|
"Wide Guard"
|
|
],
|
|
onHit(target, source, effect) {
|
|
const moves = this.dex.moves.all().filter((move) => (![2, 4].includes(this.gen) || !source.moves.includes(move.id)) && !move.realMove && !move.isZ && !move.isMax && (!move.isNonstandard || move.isNonstandard === "Unobtainable") && !effect.noMetronome.includes(move.name));
|
|
let randomMove = "";
|
|
if (moves.length) {
|
|
moves.sort((a, b) => a.num - b.num);
|
|
randomMove = this.sample(moves).id;
|
|
}
|
|
if (!randomMove)
|
|
return false;
|
|
source.side.lastSelectedMove = this.toID(randomMove);
|
|
this.actions.useMove(randomMove, target);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
milkdrink: {
|
|
num: 208,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Milk Drink",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
mimic: {
|
|
num: 102,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Mimic",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {
|
|
protect: 1,
|
|
bypasssub: 1,
|
|
allyanim: 1,
|
|
failencore: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
onHit(target, source) {
|
|
const move = target.lastMove;
|
|
if (source.transformed || !move || move.flags["failmimic"] || source.moves.includes(move.id)) {
|
|
return false;
|
|
}
|
|
if (move.isZ || move.isMax)
|
|
return false;
|
|
const mimicIndex = source.moves.indexOf("mimic");
|
|
if (mimicIndex < 0)
|
|
return false;
|
|
source.moveSlots[mimicIndex] = {
|
|
move: move.name,
|
|
id: move.id,
|
|
pp: move.pp,
|
|
maxpp: move.pp,
|
|
target: move.target,
|
|
disabled: false,
|
|
used: false,
|
|
virtual: true
|
|
};
|
|
this.add("-start", source, "Mimic", move.name);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { accuracy: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
mindblown: {
|
|
num: 720,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Mind Blown",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
mindBlownRecoil: true,
|
|
onAfterMove(pokemon, target, move) {
|
|
if (move.mindBlownRecoil && !move.multihit) {
|
|
const hpBeforeRecoil = pokemon.hp;
|
|
this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.conditions.get("Mind Blown"), true);
|
|
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
|
|
this.runEvent("EmergencyExit", pokemon, pokemon);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
mindreader: {
|
|
num: 170,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Mind Reader",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onTryHit(target, source) {
|
|
if (source.volatiles["lockon"])
|
|
return false;
|
|
},
|
|
onHit(target, source) {
|
|
source.addVolatile("lockon", target);
|
|
this.add("-activate", source, "move: Mind Reader", "[of] " + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
minimize: {
|
|
num: 107,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Minimize",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
volatileStatus: "minimize",
|
|
condition: {
|
|
noCopy: true,
|
|
onRestart: () => null,
|
|
onSourceModifyDamage(damage, source, target, move) {
|
|
const boostedMoves = [
|
|
"stomp",
|
|
"steamroller",
|
|
"bodyslam",
|
|
"flyingpress",
|
|
"dragonrush",
|
|
"heatcrash",
|
|
"heavyslam",
|
|
"maliciousmoonsault"
|
|
];
|
|
if (boostedMoves.includes(move.id)) {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
onAccuracy(accuracy, target, source, move) {
|
|
const boostedMoves = [
|
|
"stomp",
|
|
"steamroller",
|
|
"bodyslam",
|
|
"flyingpress",
|
|
"dragonrush",
|
|
"heatcrash",
|
|
"heavyslam",
|
|
"maliciousmoonsault"
|
|
];
|
|
if (boostedMoves.includes(move.id)) {
|
|
return true;
|
|
}
|
|
return accuracy;
|
|
}
|
|
},
|
|
boosts: {
|
|
evasion: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
miracleeye: {
|
|
num: 357,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Miracle Eye",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
volatileStatus: "miracleeye",
|
|
onTryHit(target) {
|
|
if (target.volatiles["foresight"])
|
|
return false;
|
|
},
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "Miracle Eye");
|
|
},
|
|
onNegateImmunity(pokemon, type) {
|
|
if (pokemon.hasType("Dark") && type === "Psychic")
|
|
return false;
|
|
},
|
|
onModifyBoost(boosts) {
|
|
if (boosts.evasion && boosts.evasion > 0) {
|
|
boosts.evasion = 0;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
mirrorcoat: {
|
|
num: 243,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
if (!pokemon.volatiles["mirrorcoat"])
|
|
return 0;
|
|
return pokemon.volatiles["mirrorcoat"].damage || 1;
|
|
},
|
|
category: "Special",
|
|
name: "Mirror Coat",
|
|
pp: 20,
|
|
priority: -5,
|
|
flags: { protect: 1, failmefirst: 1, noassist: 1 },
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile("mirrorcoat");
|
|
},
|
|
onTry(source) {
|
|
if (!source.volatiles["mirrorcoat"])
|
|
return false;
|
|
if (source.volatiles["mirrorcoat"].slot === null)
|
|
return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
noCopy: true,
|
|
onStart(target, source, move) {
|
|
this.effectState.slot = null;
|
|
this.effectState.damage = 0;
|
|
},
|
|
onRedirectTargetPriority: -1,
|
|
onRedirectTarget(target, source, source2, move) {
|
|
if (move.id !== "mirrorcoat")
|
|
return;
|
|
if (source !== this.effectState.target || !this.effectState.slot)
|
|
return;
|
|
return this.getAtSlot(this.effectState.slot);
|
|
},
|
|
onDamagingHit(damage, target, source, move) {
|
|
if (!source.isAlly(target) && this.getCategory(move) === "Special") {
|
|
this.effectState.slot = source.getSlot();
|
|
this.effectState.damage = 2 * damage;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "scripted",
|
|
type: "Psychic",
|
|
contestType: "Beautiful"
|
|
},
|
|
mirrormove: {
|
|
num: 119,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Mirror Move",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
onTryHit(target, pokemon) {
|
|
const move = target.lastMove;
|
|
if (!move?.flags["mirror"] || move.isZ || move.isMax) {
|
|
return false;
|
|
}
|
|
this.actions.useMove(move.id, pokemon, target);
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
zMove: { boost: { atk: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
mirrorshot: {
|
|
num: 429,
|
|
accuracy: 85,
|
|
basePower: 65,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Mirror Shot",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
accuracy: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Beautiful"
|
|
},
|
|
mist: {
|
|
num: 54,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Mist",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
sideCondition: "mist",
|
|
condition: {
|
|
duration: 5,
|
|
onTryBoost(boost, target, source, effect) {
|
|
if (effect.effectType === "Move" && effect.infiltrates && !target.isAlly(source))
|
|
return;
|
|
if (source && target !== source) {
|
|
let showMsg = false;
|
|
let i;
|
|
for (i in boost) {
|
|
if (boost[i] < 0) {
|
|
delete boost[i];
|
|
showMsg = true;
|
|
}
|
|
}
|
|
if (showMsg && !effect.secondaries) {
|
|
this.add("-activate", target, "move: Mist");
|
|
}
|
|
}
|
|
},
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "Mist");
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 4,
|
|
onSideEnd(side) {
|
|
this.add("-sideend", side, "Mist");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Ice",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Beautiful"
|
|
},
|
|
mistball: {
|
|
num: 296,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Mist Ball",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
spa: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
mistyexplosion: {
|
|
num: 802,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Misty Explosion",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
selfdestruct: "always",
|
|
onBasePower(basePower, source) {
|
|
if (this.field.isTerrain("mistyterrain") && source.isGrounded()) {
|
|
this.debug("misty terrain boost");
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Fairy"
|
|
},
|
|
mistyterrain: {
|
|
num: 581,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Misty Terrain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { nonsky: 1 },
|
|
terrain: "mistyterrain",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasItem("terrainextender")) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onSetStatus(status, target, source, effect) {
|
|
if (!target.isGrounded() || target.isSemiInvulnerable())
|
|
return;
|
|
if (effect && (effect.status || effect.id === "yawn")) {
|
|
this.add("-activate", target, "move: Misty Terrain");
|
|
}
|
|
return false;
|
|
},
|
|
onTryAddVolatile(status, target, source, effect) {
|
|
if (!target.isGrounded() || target.isSemiInvulnerable())
|
|
return;
|
|
if (status.id === "confusion") {
|
|
if (effect.effectType === "Move" && !effect.secondaries)
|
|
this.add("-activate", target, "move: Misty Terrain");
|
|
return null;
|
|
}
|
|
},
|
|
onBasePowerPriority: 6,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === "Dragon" && defender.isGrounded() && !defender.isSemiInvulnerable()) {
|
|
this.debug("misty terrain weaken");
|
|
return this.chainModify(0.5);
|
|
}
|
|
},
|
|
onFieldStart(field, source, effect) {
|
|
if (effect?.effectType === "Ability") {
|
|
this.add("-fieldstart", "move: Misty Terrain", "[from] ability: " + effect.name, "[of] " + source);
|
|
} else {
|
|
this.add("-fieldstart", "move: Misty Terrain");
|
|
}
|
|
},
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 7,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "Misty Terrain");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fairy",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
moonblast: {
|
|
num: 585,
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Special",
|
|
name: "Moonblast",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
spa: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Beautiful"
|
|
},
|
|
moongeistbeam: {
|
|
num: 714,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Moongeist Beam",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
moonlight: {
|
|
num: 236,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Moonlight",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
onHit(pokemon) {
|
|
let factor = 0.5;
|
|
switch (pokemon.effectiveWeather()) {
|
|
case "sunnyday":
|
|
case "desolateland":
|
|
factor = 0.667;
|
|
break;
|
|
case "raindance":
|
|
case "primordialsea":
|
|
case "sandstorm":
|
|
case "hail":
|
|
case "snow":
|
|
factor = 0.25;
|
|
break;
|
|
}
|
|
const success = !!this.heal(this.modify(pokemon.maxhp, factor));
|
|
if (!success) {
|
|
this.add("-fail", pokemon, "heal");
|
|
return this.NOT_FAIL;
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fairy",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
morningsun: {
|
|
num: 234,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Morning Sun",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
onHit(pokemon) {
|
|
let factor = 0.5;
|
|
switch (pokemon.effectiveWeather()) {
|
|
case "sunnyday":
|
|
case "desolateland":
|
|
factor = 0.667;
|
|
break;
|
|
case "raindance":
|
|
case "primordialsea":
|
|
case "sandstorm":
|
|
case "hail":
|
|
case "snow":
|
|
factor = 0.25;
|
|
break;
|
|
}
|
|
const success = !!this.heal(this.modify(pokemon.maxhp, factor));
|
|
if (!success) {
|
|
this.add("-fail", pokemon, "heal");
|
|
return this.NOT_FAIL;
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
mortalspin: {
|
|
num: 866,
|
|
accuracy: 100,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Mortal Spin",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onAfterHit(target, pokemon) {
|
|
if (pokemon.hp && pokemon.removeVolatile("leechseed")) {
|
|
this.add("-end", pokemon, "Leech Seed", "[from] move: Mortal Spin", "[of] " + pokemon);
|
|
}
|
|
const sideConditions = ["spikes", "toxicspikes", "stealthrock", "stickyweb", "gmaxsteelsurge"];
|
|
for (const condition of sideConditions) {
|
|
if (pokemon.hp && pokemon.side.removeSideCondition(condition)) {
|
|
this.add("-sideend", pokemon.side, this.dex.conditions.get(condition).name, "[from] move: Mortal Spin", "[of] " + pokemon);
|
|
}
|
|
}
|
|
if (pokemon.hp && pokemon.volatiles["partiallytrapped"]) {
|
|
pokemon.removeVolatile("partiallytrapped");
|
|
}
|
|
},
|
|
onAfterSubDamage(damage, target, pokemon) {
|
|
if (pokemon.hp && pokemon.removeVolatile("leechseed")) {
|
|
this.add("-end", pokemon, "Leech Seed", "[from] move: Mortal Spin", "[of] " + pokemon);
|
|
}
|
|
const sideConditions = ["spikes", "toxicspikes", "stealthrock", "stickyweb", "gmaxsteelsurge"];
|
|
for (const condition of sideConditions) {
|
|
if (pokemon.hp && pokemon.side.removeSideCondition(condition)) {
|
|
this.add("-sideend", pokemon.side, this.dex.conditions.get(condition).name, "[from] move: Mortal Spin", "[of] " + pokemon);
|
|
}
|
|
}
|
|
if (pokemon.hp && pokemon.volatiles["partiallytrapped"]) {
|
|
pokemon.removeVolatile("partiallytrapped");
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
status: "psn"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Poison"
|
|
},
|
|
mountaingale: {
|
|
num: 836,
|
|
accuracy: 85,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Mountain Gale",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Ice"
|
|
},
|
|
mudbomb: {
|
|
num: 426,
|
|
accuracy: 85,
|
|
basePower: 65,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Mud Bomb",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
accuracy: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Cute"
|
|
},
|
|
mudshot: {
|
|
num: 341,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Special",
|
|
name: "Mud Shot",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough"
|
|
},
|
|
mudslap: {
|
|
num: 189,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Special",
|
|
name: "Mud-Slap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
accuracy: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Cute"
|
|
},
|
|
mudsport: {
|
|
num: 300,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Mud Sport",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { nonsky: 1 },
|
|
pseudoWeather: "mudsport",
|
|
condition: {
|
|
duration: 5,
|
|
onFieldStart(field, source) {
|
|
this.add("-fieldstart", "move: Mud Sport", "[of] " + source);
|
|
},
|
|
onBasePowerPriority: 1,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === "Electric") {
|
|
this.debug("mud sport weaken");
|
|
return this.chainModify([1352, 4096]);
|
|
}
|
|
},
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 4,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "move: Mud Sport");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ground",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
muddywater: {
|
|
num: 330,
|
|
accuracy: 85,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Muddy Water",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
accuracy: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Tough"
|
|
},
|
|
multiattack: {
|
|
num: 718,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Multi-Attack",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.ignoringItem())
|
|
return;
|
|
move.type = this.runEvent("Memory", pokemon, null, move, "Normal");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 185 },
|
|
maxMove: { basePower: 95 },
|
|
contestType: "Tough"
|
|
},
|
|
mysticalfire: {
|
|
num: 595,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Special",
|
|
name: "Mystical Fire",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
mysticalpower: {
|
|
num: 832,
|
|
accuracy: 90,
|
|
basePower: 70,
|
|
category: "Special",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Mystical Power",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spa: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic"
|
|
},
|
|
nastyplot: {
|
|
num: 417,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Nasty Plot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
spa: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dark",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
naturalgift: {
|
|
num: 363,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Natural Gift",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.ignoringItem())
|
|
return;
|
|
const item = pokemon.getItem();
|
|
if (!item.naturalGift)
|
|
return;
|
|
move.type = item.naturalGift.type;
|
|
},
|
|
onPrepareHit(target, pokemon, move) {
|
|
if (pokemon.ignoringItem())
|
|
return false;
|
|
const item = pokemon.getItem();
|
|
if (!item.naturalGift)
|
|
return false;
|
|
move.basePower = item.naturalGift.basePower;
|
|
this.debug("BP: " + move.basePower);
|
|
pokemon.setItem("");
|
|
pokemon.lastItem = item.id;
|
|
pokemon.usedItemThisTurn = true;
|
|
this.runEvent("AfterUseItem", pokemon, null, null, item);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Clever"
|
|
},
|
|
naturepower: {
|
|
num: 267,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Nature Power",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
onTryHit(target, pokemon) {
|
|
let move = "triattack";
|
|
if (this.field.isTerrain("electricterrain")) {
|
|
move = "thunderbolt";
|
|
} else if (this.field.isTerrain("grassyterrain")) {
|
|
move = "energyball";
|
|
} else if (this.field.isTerrain("mistyterrain")) {
|
|
move = "moonblast";
|
|
} else if (this.field.isTerrain("psychicterrain")) {
|
|
move = "psychic";
|
|
}
|
|
this.actions.useMove(move, pokemon, target);
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
naturesmadness: {
|
|
num: 717,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
return this.clampIntRange(Math.floor(target.getUndynamaxedHP() / 2), 1);
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Nature's Madness",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Tough"
|
|
},
|
|
needlearm: {
|
|
num: 302,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Needle Arm",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever"
|
|
},
|
|
neverendingnightmare: {
|
|
num: 636,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Never-Ending Nightmare",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "ghostiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
nightdaze: {
|
|
num: 539,
|
|
accuracy: 95,
|
|
basePower: 85,
|
|
category: "Special",
|
|
name: "Night Daze",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 40,
|
|
boosts: {
|
|
accuracy: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
nightmare: {
|
|
num: 171,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Nightmare",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
volatileStatus: "nightmare",
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
if (pokemon.status !== "slp" && !pokemon.hasAbility("comatose")) {
|
|
return false;
|
|
}
|
|
this.add("-start", pokemon, "Nightmare");
|
|
},
|
|
onResidualOrder: 11,
|
|
onResidual(pokemon) {
|
|
this.damage(pokemon.baseMaxhp / 4);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
nightshade: {
|
|
num: 101,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damage: "level",
|
|
category: "Special",
|
|
name: "Night Shade",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever"
|
|
},
|
|
nightslash: {
|
|
num: 400,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Night Slash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Cool"
|
|
},
|
|
nobleroar: {
|
|
num: 568,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Noble Roar",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
boosts: {
|
|
atk: -1,
|
|
spa: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
noretreat: {
|
|
num: 748,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "No Retreat",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
volatileStatus: "noretreat",
|
|
onTry(source, target, move) {
|
|
if (source.volatiles["noretreat"])
|
|
return false;
|
|
if (source.volatiles["trapped"]) {
|
|
delete move.volatileStatus;
|
|
}
|
|
},
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "move: No Retreat");
|
|
},
|
|
onTrapPokemon(pokemon) {
|
|
pokemon.tryTrap();
|
|
}
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fighting"
|
|
},
|
|
noxioustorque: {
|
|
num: 898,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Noxious Torque",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {
|
|
protect: 1,
|
|
failencore: 1,
|
|
failmefirst: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison"
|
|
},
|
|
nuzzle: {
|
|
num: 609,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Physical",
|
|
name: "Nuzzle",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cute"
|
|
},
|
|
oblivionwing: {
|
|
num: 613,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Oblivion Wing",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, distance: 1, heal: 1 },
|
|
drain: [3, 4],
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
obstruct: {
|
|
num: 792,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Obstruct",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: { failinstruct: 1 },
|
|
stallingMove: true,
|
|
volatileStatus: "obstruct",
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "Protect");
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags["protect"] || move.category === "Status") {
|
|
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
|
|
return;
|
|
if (move.isZ || move.isMax)
|
|
target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add("-activate", target, "move: Protect");
|
|
}
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
if (this.checkMoveMakesContact(move, source, target)) {
|
|
this.boost({ def: -2 }, source, target, this.dex.getActiveMove("Obstruct"));
|
|
}
|
|
return this.NOT_FAIL;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
|
|
this.boost({ def: -2 }, source, target, this.dex.getActiveMove("Obstruct"));
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dark"
|
|
},
|
|
oceanicoperetta: {
|
|
num: 697,
|
|
accuracy: true,
|
|
basePower: 195,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Oceanic Operetta",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "primariumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
octazooka: {
|
|
num: 190,
|
|
accuracy: 85,
|
|
basePower: 65,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Octazooka",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
accuracy: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough"
|
|
},
|
|
octolock: {
|
|
num: 753,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Octolock",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onTryImmunity(target) {
|
|
return this.dex.getImmunity("trapped", target);
|
|
},
|
|
volatileStatus: "octolock",
|
|
condition: {
|
|
onStart(pokemon, source) {
|
|
this.add("-start", pokemon, "move: Octolock", "[of] " + source);
|
|
},
|
|
onResidualOrder: 14,
|
|
onResidual(pokemon) {
|
|
const source = this.effectState.source;
|
|
if (source && (!source.isActive || source.hp <= 0 || !source.activeTurns)) {
|
|
delete pokemon.volatiles["octolock"];
|
|
this.add("-end", pokemon, "Octolock", "[partiallytrapped]", "[silent]");
|
|
return;
|
|
}
|
|
this.boost({ def: -1, spd: -1 }, pokemon, source, this.dex.getActiveMove("octolock"));
|
|
},
|
|
onTrapPokemon(pokemon) {
|
|
if (this.effectState.source && this.effectState.source.isActive)
|
|
pokemon.tryTrap();
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting"
|
|
},
|
|
odorsleuth: {
|
|
num: 316,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Odor Sleuth",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1, allyanim: 1 },
|
|
volatileStatus: "foresight",
|
|
onTryHit(target) {
|
|
if (target.volatiles["miracleeye"])
|
|
return false;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
ominouswind: {
|
|
num: 466,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Ominous Wind",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Beautiful"
|
|
},
|
|
orderup: {
|
|
num: 856,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Order Up",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1 },
|
|
onAfterMoveSecondarySelf(pokemon, target, move) {
|
|
if (!pokemon.volatiles["commanded"])
|
|
return;
|
|
const tatsugiri = pokemon.volatiles["commanded"].source;
|
|
if (tatsugiri.baseSpecies.baseSpecies !== "Tatsugiri")
|
|
return;
|
|
switch (tatsugiri.baseSpecies.forme) {
|
|
case "Droopy":
|
|
this.boost({ def: 1 }, pokemon, pokemon);
|
|
break;
|
|
case "Stretchy":
|
|
this.boost({ spe: 1 }, pokemon, pokemon);
|
|
break;
|
|
default:
|
|
this.boost({ atk: 1 }, pokemon, pokemon);
|
|
break;
|
|
}
|
|
},
|
|
secondary: null,
|
|
hasSheerForce: true,
|
|
target: "normal",
|
|
type: "Dragon"
|
|
},
|
|
originpulse: {
|
|
num: 618,
|
|
accuracy: 85,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Origin Pulse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, pulse: 1, mirror: 1 },
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
outrage: {
|
|
num: 200,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Outrage",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, failinstruct: 1 },
|
|
self: {
|
|
volatileStatus: "lockedmove"
|
|
},
|
|
onAfterMove(pokemon) {
|
|
if (pokemon.volatiles["lockedmove"] && pokemon.volatiles["lockedmove"].duration === 1) {
|
|
pokemon.removeVolatile("lockedmove");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Dragon",
|
|
contestType: "Cool"
|
|
},
|
|
overdrive: {
|
|
num: 786,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Overdrive",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Electric"
|
|
},
|
|
overheat: {
|
|
num: 315,
|
|
accuracy: 90,
|
|
basePower: 130,
|
|
category: "Special",
|
|
name: "Overheat",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
spa: -2
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
painsplit: {
|
|
num: 220,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Pain Split",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, allyanim: 1 },
|
|
onHit(target, pokemon) {
|
|
const targetHP = target.getUndynamaxedHP();
|
|
const averagehp = Math.floor((targetHP + pokemon.hp) / 2) || 1;
|
|
const targetChange = targetHP - averagehp;
|
|
target.sethp(target.hp - targetChange);
|
|
this.add("-sethp", target, target.getHealth, "[from] move: Pain Split", "[silent]");
|
|
pokemon.sethp(averagehp);
|
|
this.add("-sethp", pokemon, pokemon.getHealth, "[from] move: Pain Split");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
paleowave: {
|
|
num: 0,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Special",
|
|
isNonstandard: "CAP",
|
|
name: "Paleo Wave",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
atk: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Beautiful"
|
|
},
|
|
paraboliccharge: {
|
|
num: 570,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Parabolic Charge",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, heal: 1 },
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Electric",
|
|
contestType: "Clever"
|
|
},
|
|
partingshot: {
|
|
num: 575,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Parting Shot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
onHit(target, source, move) {
|
|
const success = this.boost({ atk: -1, spa: -1 }, target, source);
|
|
if (!success && !target.hasAbility("mirrorarmor")) {
|
|
delete move.selfSwitch;
|
|
}
|
|
},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { effect: "healreplacement" },
|
|
contestType: "Cool"
|
|
},
|
|
payback: {
|
|
num: 371,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.newlySwitched || this.queue.willMove(target)) {
|
|
this.debug("Payback NOT boosted");
|
|
return move.basePower;
|
|
}
|
|
this.debug("Payback damage boost");
|
|
return move.basePower * 2;
|
|
},
|
|
category: "Physical",
|
|
name: "Payback",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough"
|
|
},
|
|
payday: {
|
|
num: 6,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Pay Day",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Clever"
|
|
},
|
|
peck: {
|
|
num: 64,
|
|
accuracy: 100,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
name: "Peck",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, distance: 1 },
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
perishsong: {
|
|
num: 195,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Perish Song",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { sound: 1, distance: 1, bypasssub: 1 },
|
|
onHitField(target, source, move) {
|
|
let result = false;
|
|
let message = false;
|
|
for (const pokemon of this.getAllActive()) {
|
|
if (this.runEvent("Invulnerability", pokemon, source, move) === false) {
|
|
this.add("-miss", source, pokemon);
|
|
result = true;
|
|
} else if (this.runEvent("TryHit", pokemon, source, move) === null) {
|
|
result = true;
|
|
} else if (!pokemon.volatiles["perishsong"]) {
|
|
pokemon.addVolatile("perishsong");
|
|
this.add("-start", pokemon, "perish3", "[silent]");
|
|
result = true;
|
|
message = true;
|
|
}
|
|
}
|
|
if (!result)
|
|
return false;
|
|
if (message)
|
|
this.add("-fieldactivate", "move: Perish Song");
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onEnd(target) {
|
|
this.add("-start", target, "perish0");
|
|
target.faint();
|
|
},
|
|
onResidualOrder: 24,
|
|
onResidual(pokemon) {
|
|
const duration = pokemon.volatiles["perishsong"].duration;
|
|
this.add("-start", pokemon, "perish" + duration);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
petalblizzard: {
|
|
num: 572,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Petal Blizzard",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Grass",
|
|
contestType: "Beautiful"
|
|
},
|
|
petaldance: {
|
|
num: 80,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Petal Dance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, dance: 1, failinstruct: 1 },
|
|
self: {
|
|
volatileStatus: "lockedmove"
|
|
},
|
|
onAfterMove(pokemon) {
|
|
if (pokemon.volatiles["lockedmove"] && pokemon.volatiles["lockedmove"].duration === 1) {
|
|
pokemon.removeVolatile("lockedmove");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Grass",
|
|
contestType: "Beautiful"
|
|
},
|
|
phantomforce: {
|
|
num: 566,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Phantom Force",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, charge: 1, mirror: 1, nosleeptalk: 1, noassist: 1, failinstruct: 1 },
|
|
breaksProtect: true,
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onInvulnerability: false
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
photongeyser: {
|
|
num: 722,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Photon Geyser",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onModifyMove(move, pokemon) {
|
|
if (pokemon.getStat("atk", false, true) > pokemon.getStat("spa", false, true))
|
|
move.category = "Physical";
|
|
},
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
pikapapow: {
|
|
num: 732,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
const bp = Math.floor(pokemon.happiness * 10 / 25) || 1;
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Pika Papow",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cute"
|
|
},
|
|
pinmissile: {
|
|
num: 42,
|
|
accuracy: 95,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Pin Missile",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cool"
|
|
},
|
|
plasmafists: {
|
|
num: 721,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Plasma Fists",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
pseudoWeather: "iondeluge",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
playnice: {
|
|
num: 589,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Play Nice",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
boosts: {
|
|
atk: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
playrough: {
|
|
num: 583,
|
|
accuracy: 90,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Play Rough",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
atk: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Cute"
|
|
},
|
|
pluck: {
|
|
num: 365,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Pluck",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, distance: 1 },
|
|
onHit(target, source) {
|
|
const item = target.getItem();
|
|
if (source.hp && item.isBerry && target.takeItem(source)) {
|
|
this.add("-enditem", target, item.name, "[from] stealeat", "[move] Pluck", "[of] " + source);
|
|
if (this.singleEvent("Eat", item, null, source, null, null)) {
|
|
this.runEvent("EatItem", source, null, null, item);
|
|
if (item.id === "leppaberry")
|
|
target.staleness = "external";
|
|
}
|
|
if (item.onEat)
|
|
source.ateBerry = true;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cute"
|
|
},
|
|
poisonfang: {
|
|
num: 305,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Poison Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
status: "tox"
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Clever"
|
|
},
|
|
poisongas: {
|
|
num: 139,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Poison Gas",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "psn",
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Poison",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
poisonjab: {
|
|
num: 398,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Poison Jab",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough"
|
|
},
|
|
poisonpowder: {
|
|
num: 77,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Poison Powder",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { powder: 1, protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "psn",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
poisonsting: {
|
|
num: 40,
|
|
accuracy: 100,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Poison Sting",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Clever"
|
|
},
|
|
poisontail: {
|
|
num: 342,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Poison Tail",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: {
|
|
chance: 10,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Clever"
|
|
},
|
|
pollenpuff: {
|
|
num: 676,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Pollen Puff",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1, allyanim: 1 },
|
|
onTryHit(target, source, move) {
|
|
if (source.isAlly(target)) {
|
|
move.basePower = 0;
|
|
move.infiltrates = true;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
if (source.isAlly(target)) {
|
|
if (!this.heal(Math.floor(target.baseMaxhp * 0.5))) {
|
|
this.add("-immune", target);
|
|
return this.NOT_FAIL;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute"
|
|
},
|
|
poltergeist: {
|
|
num: 809,
|
|
accuracy: 90,
|
|
basePower: 110,
|
|
category: "Physical",
|
|
name: "Poltergeist",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onTry(source, target) {
|
|
return !!target.item;
|
|
},
|
|
onTryHit(target, source, move) {
|
|
this.add("-activate", target, "move: Poltergeist", this.dex.items.get(target.item).name);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost"
|
|
},
|
|
populationbomb: {
|
|
num: 860,
|
|
accuracy: 90,
|
|
basePower: 20,
|
|
category: "Physical",
|
|
name: "Population Bomb",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
multihit: 10,
|
|
multiaccuracy: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal"
|
|
},
|
|
pounce: {
|
|
num: 884,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Pounce",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute"
|
|
},
|
|
pound: {
|
|
num: 1,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Pound",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
powder: {
|
|
num: 600,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Powder",
|
|
pp: 20,
|
|
priority: 1,
|
|
flags: { powder: 1, protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
volatileStatus: "powder",
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "Powder");
|
|
},
|
|
onTryMovePriority: -1,
|
|
onTryMove(pokemon, target, move) {
|
|
if (move.type === "Fire") {
|
|
this.add("-activate", pokemon, "move: Powder");
|
|
this.damage(this.clampIntRange(Math.round(pokemon.maxhp / 4), 1));
|
|
this.attrLastMove("[still]");
|
|
return false;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
zMove: { boost: { spd: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
powdersnow: {
|
|
num: 181,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Powder Snow",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "frz"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Ice",
|
|
contestType: "Beautiful"
|
|
},
|
|
powergem: {
|
|
num: 408,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Power Gem",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Beautiful"
|
|
},
|
|
powershift: {
|
|
num: 829,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Power Shift",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
volatileStatus: "powershift",
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "Power Shift");
|
|
[
|
|
pokemon.storedStats.atk,
|
|
pokemon.storedStats.spa,
|
|
pokemon.storedStats.def,
|
|
pokemon.storedStats.spd
|
|
] = [
|
|
pokemon.storedStats.def,
|
|
pokemon.storedStats.spd,
|
|
pokemon.storedStats.atk,
|
|
pokemon.storedStats.spa
|
|
];
|
|
},
|
|
onCopy(pokemon) {
|
|
[
|
|
pokemon.storedStats.atk,
|
|
pokemon.storedStats.spa,
|
|
pokemon.storedStats.def,
|
|
pokemon.storedStats.spd
|
|
] = [
|
|
pokemon.storedStats.def,
|
|
pokemon.storedStats.spd,
|
|
pokemon.storedStats.atk,
|
|
pokemon.storedStats.spa
|
|
];
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "Power Shift");
|
|
[
|
|
pokemon.storedStats.atk,
|
|
pokemon.storedStats.spa,
|
|
pokemon.storedStats.def,
|
|
pokemon.storedStats.spd
|
|
] = [
|
|
pokemon.storedStats.def,
|
|
pokemon.storedStats.spd,
|
|
pokemon.storedStats.atk,
|
|
pokemon.storedStats.spa
|
|
];
|
|
},
|
|
onRestart(pokemon) {
|
|
pokemon.removeVolatile("Power Shift");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal"
|
|
},
|
|
powersplit: {
|
|
num: 471,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Power Split",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
const newatk = Math.floor((target.storedStats.atk + source.storedStats.atk) / 2);
|
|
target.storedStats.atk = newatk;
|
|
source.storedStats.atk = newatk;
|
|
const newspa = Math.floor((target.storedStats.spa + source.storedStats.spa) / 2);
|
|
target.storedStats.spa = newspa;
|
|
source.storedStats.spa = newspa;
|
|
this.add("-activate", source, "move: Power Split", "[of] " + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
powerswap: {
|
|
num: 384,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Power Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, bypasssub: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
const targetBoosts = {};
|
|
const sourceBoosts = {};
|
|
const atkSpa = ["atk", "spa"];
|
|
for (const stat of atkSpa) {
|
|
targetBoosts[stat] = target.boosts[stat];
|
|
sourceBoosts[stat] = source.boosts[stat];
|
|
}
|
|
source.setBoost(targetBoosts);
|
|
target.setBoost(sourceBoosts);
|
|
this.add("-swapboost", source, target, "atk, spa", "[from] move: Power Swap");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
powertrick: {
|
|
num: 379,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Power Trick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
volatileStatus: "powertrick",
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "Power Trick");
|
|
const newatk = pokemon.storedStats.def;
|
|
const newdef = pokemon.storedStats.atk;
|
|
pokemon.storedStats.atk = newatk;
|
|
pokemon.storedStats.def = newdef;
|
|
},
|
|
onCopy(pokemon) {
|
|
const newatk = pokemon.storedStats.def;
|
|
const newdef = pokemon.storedStats.atk;
|
|
pokemon.storedStats.atk = newatk;
|
|
pokemon.storedStats.def = newdef;
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "Power Trick");
|
|
const newatk = pokemon.storedStats.def;
|
|
const newdef = pokemon.storedStats.atk;
|
|
pokemon.storedStats.atk = newatk;
|
|
pokemon.storedStats.def = newdef;
|
|
},
|
|
onRestart(pokemon) {
|
|
pokemon.removeVolatile("Power Trick");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
powertrip: {
|
|
num: 681,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const bp = move.basePower + 20 * pokemon.positiveBoosts();
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Power Trip",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Clever"
|
|
},
|
|
poweruppunch: {
|
|
num: 612,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Power-Up Punch",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
atk: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
powerwhip: {
|
|
num: 438,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Power Whip",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough"
|
|
},
|
|
precipiceblades: {
|
|
num: 619,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Precipice Blades",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
target: "allAdjacentFoes",
|
|
type: "Ground",
|
|
contestType: "Cool"
|
|
},
|
|
present: {
|
|
num: 217,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
name: "Present",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onModifyMove(move, pokemon, target) {
|
|
const rand = this.random(10);
|
|
if (rand < 2) {
|
|
move.heal = [1, 4];
|
|
move.infiltrates = true;
|
|
} else if (rand < 6) {
|
|
move.basePower = 40;
|
|
} else if (rand < 9) {
|
|
move.basePower = 80;
|
|
} else {
|
|
move.basePower = 120;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
prismaticlaser: {
|
|
num: 711,
|
|
accuracy: 100,
|
|
basePower: 160,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Prismatic Laser",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { recharge: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
protect: {
|
|
num: 182,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Protect",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: { noassist: 1, failcopycat: 1 },
|
|
stallingMove: true,
|
|
volatileStatus: "protect",
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "Protect");
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags["protect"]) {
|
|
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
|
|
return;
|
|
if (move.isZ || move.isMax)
|
|
target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add("-activate", target, "move: Protect");
|
|
}
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
psybeam: {
|
|
num: 60,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Psybeam",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Beautiful"
|
|
},
|
|
psyblade: {
|
|
num: 875,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Psyblade",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
secondary: null,
|
|
onBasePower(basePower, source) {
|
|
if (this.field.isTerrain("electricterrain")) {
|
|
this.debug("psyblade electric terrain boost");
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic"
|
|
},
|
|
psychup: {
|
|
num: 244,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Psych Up",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bypasssub: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
let i;
|
|
for (i in target.boosts) {
|
|
source.boosts[i] = target.boosts[i];
|
|
}
|
|
const volatilesToCopy = ["focusenergy", "gmaxchistrike", "laserfocus"];
|
|
for (const volatile of volatilesToCopy) {
|
|
if (target.volatiles[volatile]) {
|
|
source.addVolatile(volatile);
|
|
if (volatile === "gmaxchistrike")
|
|
source.volatiles[volatile].layers = target.volatiles[volatile].layers;
|
|
} else {
|
|
source.removeVolatile(volatile);
|
|
}
|
|
}
|
|
this.add("-copyboost", source, target, "[from] move: Psych Up");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Clever"
|
|
},
|
|
psychic: {
|
|
num: 94,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Psychic",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
psychicfangs: {
|
|
num: 706,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
name: "Psychic Fangs",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
onTryHit(pokemon) {
|
|
pokemon.side.removeSideCondition("reflect");
|
|
pokemon.side.removeSideCondition("lightscreen");
|
|
pokemon.side.removeSideCondition("auroraveil");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
psychicterrain: {
|
|
num: 678,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Psychic Terrain",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { nonsky: 1 },
|
|
terrain: "psychicterrain",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasItem("terrainextender")) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onTryHitPriority: 4,
|
|
onTryHit(target, source, effect) {
|
|
if (effect && (effect.priority <= 0.1 || effect.target === "self")) {
|
|
return;
|
|
}
|
|
if (target.isSemiInvulnerable() || target.isAlly(source))
|
|
return;
|
|
if (!target.isGrounded()) {
|
|
const baseMove = this.dex.moves.get(effect.id);
|
|
if (baseMove.priority > 0) {
|
|
this.hint("Psychic Terrain doesn't affect Pok\xE9mon immune to Ground.");
|
|
}
|
|
return;
|
|
}
|
|
this.add("-activate", target, "move: Psychic Terrain");
|
|
return null;
|
|
},
|
|
onBasePowerPriority: 6,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === "Psychic" && attacker.isGrounded() && !attacker.isSemiInvulnerable()) {
|
|
this.debug("psychic terrain boost");
|
|
return this.chainModify([5325, 4096]);
|
|
}
|
|
},
|
|
onFieldStart(field, source, effect) {
|
|
if (effect?.effectType === "Ability") {
|
|
this.add("-fieldstart", "move: Psychic Terrain", "[from] ability: " + effect.name, "[of] " + source);
|
|
} else {
|
|
this.add("-fieldstart", "move: Psychic Terrain");
|
|
}
|
|
},
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 7,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "move: Psychic Terrain");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
psychoboost: {
|
|
num: 354,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Psycho Boost",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
spa: -2
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
psychocut: {
|
|
num: 427,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Psycho Cut",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, slicing: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
psychoshift: {
|
|
num: 375,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Psycho Shift",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onTryHit(target, source, move) {
|
|
if (!source.status)
|
|
return false;
|
|
move.status = source.status;
|
|
},
|
|
self: {
|
|
onHit(pokemon) {
|
|
pokemon.cureStatus();
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spa: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
psyshieldbash: {
|
|
num: 828,
|
|
accuracy: 90,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Psyshield Bash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
def: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Psychic"
|
|
},
|
|
psyshock: {
|
|
num: 473,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
overrideDefensiveStat: "def",
|
|
name: "Psyshock",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Beautiful"
|
|
},
|
|
psystrike: {
|
|
num: 540,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
overrideDefensiveStat: "def",
|
|
name: "Psystrike",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
psywave: {
|
|
num: 149,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damageCallback(pokemon) {
|
|
return this.random(50, 151) * pokemon.level / 100;
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Psywave",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
pulverizingpancake: {
|
|
num: 701,
|
|
accuracy: true,
|
|
basePower: 210,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Pulverizing Pancake",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: { contact: 1 },
|
|
isZ: "snorliumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
punishment: {
|
|
num: 386,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
let power = 60 + 20 * target.positiveBoosts();
|
|
if (power > 200)
|
|
power = 200;
|
|
this.debug("BP: " + power);
|
|
return power;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Punishment",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cool"
|
|
},
|
|
purify: {
|
|
num: 685,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Purify",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, heal: 1 },
|
|
onHit(target, source) {
|
|
if (!target.cureStatus()) {
|
|
this.add("-fail", source);
|
|
this.attrLastMove("[still]");
|
|
return this.NOT_FAIL;
|
|
}
|
|
this.heal(Math.ceil(source.maxhp * 0.5), source);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
pursuit: {
|
|
num: 228,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.beingCalledBack || target.switchFlag) {
|
|
this.debug("Pursuit damage boost");
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Pursuit",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
beforeTurnCallback(pokemon) {
|
|
for (const side of this.sides) {
|
|
if (side.hasAlly(pokemon))
|
|
continue;
|
|
side.addSideCondition("pursuit", pokemon);
|
|
const data = side.getSideConditionData("pursuit");
|
|
if (!data.sources) {
|
|
data.sources = [];
|
|
}
|
|
data.sources.push(pokemon);
|
|
}
|
|
},
|
|
onModifyMove(move, source, target) {
|
|
if (target?.beingCalledBack || target?.switchFlag)
|
|
move.accuracy = true;
|
|
},
|
|
onTryHit(target, pokemon) {
|
|
target.side.removeSideCondition("pursuit");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onBeforeSwitchOut(pokemon) {
|
|
this.debug("Pursuit start");
|
|
let alreadyAdded = false;
|
|
pokemon.removeVolatile("destinybond");
|
|
for (const source of this.effectState.sources) {
|
|
if (!source.isAdjacent(pokemon) || !this.queue.cancelMove(source) || !source.hp)
|
|
continue;
|
|
if (!alreadyAdded) {
|
|
this.add("-activate", pokemon, "move: Pursuit");
|
|
alreadyAdded = true;
|
|
}
|
|
if (source.canMegaEvo || source.canUltraBurst) {
|
|
for (const [actionIndex, action] of this.queue.entries()) {
|
|
if (action.pokemon === source && action.choice === "megaEvo") {
|
|
this.actions.runMegaEvo(source);
|
|
this.queue.list.splice(actionIndex, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
this.actions.runMove("pursuit", source, source.getLocOf(pokemon));
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
pyroball: {
|
|
num: 780,
|
|
accuracy: 90,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Pyro Ball",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, defrost: 1, bullet: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire"
|
|
},
|
|
quash: {
|
|
num: 511,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Quash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onHit(target) {
|
|
if (this.activePerHalf === 1)
|
|
return false;
|
|
const action = this.queue.willMove(target);
|
|
if (!action)
|
|
return false;
|
|
action.order = 201;
|
|
this.add("-activate", target, "move: Quash");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
quickattack: {
|
|
num: 98,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Quick Attack",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
quickguard: {
|
|
num: 501,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Quick Guard",
|
|
pp: 15,
|
|
priority: 3,
|
|
flags: { snatch: 1 },
|
|
sideCondition: "quickguard",
|
|
onTry() {
|
|
return !!this.queue.willAct();
|
|
},
|
|
onHitSide(side, source) {
|
|
source.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onSideStart(target, source) {
|
|
this.add("-singleturn", source, "Quick Guard");
|
|
},
|
|
onTryHitPriority: 4,
|
|
onTryHit(target, source, move) {
|
|
if (move.priority <= 0.1)
|
|
return;
|
|
if (!move.flags["protect"]) {
|
|
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
|
|
return;
|
|
if (move.isZ || move.isMax)
|
|
target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
this.add("-activate", target, "move: Quick Guard");
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Fighting",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
quiverdance: {
|
|
num: 483,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Quiver Dance",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1, dance: 1 },
|
|
boosts: {
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
rage: {
|
|
num: 99,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Rage",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "rage"
|
|
},
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add("-singlemove", pokemon, "Rage");
|
|
},
|
|
onHit(target, source, move) {
|
|
if (target !== source && move.category !== "Status") {
|
|
this.boost({ atk: 1 });
|
|
}
|
|
},
|
|
onBeforeMovePriority: 100,
|
|
onBeforeMove(pokemon) {
|
|
this.debug("removing Rage before attack");
|
|
pokemon.removeVolatile("rage");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
ragefist: {
|
|
num: 889,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
basePowerCallback(pokemon) {
|
|
return Math.min(350, 50 + 50 * pokemon.timesAttacked);
|
|
},
|
|
category: "Physical",
|
|
name: "Rage Fist",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost"
|
|
},
|
|
ragepowder: {
|
|
num: 476,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Rage Powder",
|
|
pp: 20,
|
|
priority: 2,
|
|
flags: { powder: 1, noassist: 1, failcopycat: 1 },
|
|
volatileStatus: "ragepowder",
|
|
onTry(source) {
|
|
return this.activePerHalf > 1;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add("-singleturn", pokemon, "move: Rage Powder");
|
|
},
|
|
onFoeRedirectTargetPriority: 1,
|
|
onFoeRedirectTarget(target, source, source2, move) {
|
|
const ragePowderUser = this.effectState.target;
|
|
if (ragePowderUser.isSkyDropped())
|
|
return;
|
|
if (source.runStatusImmunity("powder") && this.validTarget(ragePowderUser, source, move.target)) {
|
|
if (move.smartTarget)
|
|
move.smartTarget = false;
|
|
this.debug("Rage Powder redirected target of move");
|
|
return ragePowderUser;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
ragingbull: {
|
|
num: 873,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Raging Bull",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onTryHit(pokemon) {
|
|
pokemon.side.removeSideCondition("reflect");
|
|
pokemon.side.removeSideCondition("lightscreen");
|
|
pokemon.side.removeSideCondition("auroraveil");
|
|
},
|
|
onModifyType(move, pokemon) {
|
|
switch (pokemon.species.name) {
|
|
case "Tauros-Paldea-Combat":
|
|
move.type = "Fighting";
|
|
break;
|
|
case "Tauros-Paldea-Blaze":
|
|
move.type = "Fire";
|
|
break;
|
|
case "Tauros-Paldea-Aqua":
|
|
move.type = "Water";
|
|
break;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal"
|
|
},
|
|
ragingfury: {
|
|
num: 833,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Raging Fury",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "lockedmove"
|
|
},
|
|
onAfterMove(pokemon) {
|
|
if (pokemon.volatiles["lockedmove"]?.duration === 1) {
|
|
pokemon.removeVolatile("lockedmove");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Fire"
|
|
},
|
|
raindance: {
|
|
num: 240,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Rain Dance",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
weather: "RainDance",
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Water",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
rapidspin: {
|
|
num: 229,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Rapid Spin",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onAfterHit(target, pokemon) {
|
|
if (pokemon.hp && pokemon.removeVolatile("leechseed")) {
|
|
this.add("-end", pokemon, "Leech Seed", "[from] move: Rapid Spin", "[of] " + pokemon);
|
|
}
|
|
const sideConditions = ["spikes", "toxicspikes", "stealthrock", "stickyweb", "gmaxsteelsurge"];
|
|
for (const condition of sideConditions) {
|
|
if (pokemon.hp && pokemon.side.removeSideCondition(condition)) {
|
|
this.add("-sideend", pokemon.side, this.dex.conditions.get(condition).name, "[from] move: Rapid Spin", "[of] " + pokemon);
|
|
}
|
|
}
|
|
if (pokemon.hp && pokemon.volatiles["partiallytrapped"]) {
|
|
pokemon.removeVolatile("partiallytrapped");
|
|
}
|
|
},
|
|
onAfterSubDamage(damage, target, pokemon) {
|
|
if (pokemon.hp && pokemon.removeVolatile("leechseed")) {
|
|
this.add("-end", pokemon, "Leech Seed", "[from] move: Rapid Spin", "[of] " + pokemon);
|
|
}
|
|
const sideConditions = ["spikes", "toxicspikes", "stealthrock", "stickyweb", "gmaxsteelsurge"];
|
|
for (const condition of sideConditions) {
|
|
if (pokemon.hp && pokemon.side.removeSideCondition(condition)) {
|
|
this.add("-sideend", pokemon.side, this.dex.conditions.get(condition).name, "[from] move: Rapid Spin", "[of] " + pokemon);
|
|
}
|
|
}
|
|
if (pokemon.hp && pokemon.volatiles["partiallytrapped"]) {
|
|
pokemon.removeVolatile("partiallytrapped");
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
razorleaf: {
|
|
num: 75,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Physical",
|
|
name: "Razor Leaf",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, slicing: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
razorshell: {
|
|
num: 534,
|
|
accuracy: 95,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Razor Shell",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
razorwind: {
|
|
num: 13,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Razor Wind",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { charge: 1, protect: 1, mirror: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
recover: {
|
|
num: 105,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Recover",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
recycle: {
|
|
num: 278,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Recycle",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onHit(pokemon) {
|
|
if (pokemon.item || !pokemon.lastItem)
|
|
return false;
|
|
const item = pokemon.lastItem;
|
|
pokemon.lastItem = "";
|
|
this.add("-item", pokemon, this.dex.items.get(item), "[from] move: Recycle");
|
|
pokemon.setItem(item);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
reflect: {
|
|
num: 115,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Reflect",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
sideCondition: "reflect",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasItem("lightclay")) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onAnyModifyDamage(damage, source, target, move) {
|
|
if (target !== source && this.effectState.target.hasAlly(target) && this.getCategory(move) === "Physical") {
|
|
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
|
|
this.debug("Reflect weaken");
|
|
if (this.activePerHalf > 1)
|
|
return this.chainModify([2732, 4096]);
|
|
return this.chainModify(0.5);
|
|
}
|
|
}
|
|
},
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "Reflect");
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 1,
|
|
onSideEnd(side) {
|
|
this.add("-sideend", side, "Reflect");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Psychic",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
reflecttype: {
|
|
num: 513,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Reflect Type",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, bypasssub: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
if (source.species && (source.species.num === 493 || source.species.num === 773))
|
|
return false;
|
|
if (source.terastallized)
|
|
return false;
|
|
const oldApparentType = source.apparentType;
|
|
let newBaseTypes = target.getTypes(true).filter((type) => type !== "???");
|
|
if (!newBaseTypes.length) {
|
|
if (target.addedType) {
|
|
newBaseTypes = ["Normal"];
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
this.add("-start", source, "typechange", "[from] move: Reflect Type", "[of] " + target);
|
|
source.setType(newBaseTypes);
|
|
source.addedType = target.addedType;
|
|
source.knownType = target.isAlly(source) && target.knownType;
|
|
if (!source.knownType)
|
|
source.apparentType = oldApparentType;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
refresh: {
|
|
num: 287,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Refresh",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onHit(pokemon) {
|
|
if (["", "slp", "frz"].includes(pokemon.status))
|
|
return false;
|
|
pokemon.cureStatus();
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Cute"
|
|
},
|
|
relicsong: {
|
|
num: 547,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Special",
|
|
name: "Relic Song",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "slp"
|
|
},
|
|
onHit(target, pokemon, move) {
|
|
if (pokemon.baseSpecies.baseSpecies === "Meloetta" && !pokemon.transformed) {
|
|
move.willChangeForme = true;
|
|
}
|
|
},
|
|
onAfterMoveSecondarySelf(pokemon, target, move) {
|
|
if (move.willChangeForme) {
|
|
const meloettaForme = pokemon.species.id === "meloettapirouette" ? "" : "-Pirouette";
|
|
pokemon.formeChange("Meloetta" + meloettaForme, this.effect, false, "[msg]");
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
rest: {
|
|
num: 156,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Rest",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
onTry(source) {
|
|
if (source.status === "slp" || source.hasAbility("comatose"))
|
|
return false;
|
|
if (source.hp === source.maxhp) {
|
|
this.add("-fail", source, "heal");
|
|
return null;
|
|
}
|
|
if (source.hasAbility(["insomnia", "vitalspirit"])) {
|
|
this.add("-fail", source, "[from] ability: " + source.getAbility().name, "[of] " + source);
|
|
return null;
|
|
}
|
|
},
|
|
onHit(target, source, move) {
|
|
const result = target.setStatus("slp", source, move);
|
|
if (!result)
|
|
return result;
|
|
target.statusState.time = 3;
|
|
target.statusState.startTime = 3;
|
|
this.heal(target.maxhp);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
retaliate: {
|
|
num: 514,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Retaliate",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onBasePower(basePower, pokemon) {
|
|
if (pokemon.side.faintedLastTurn) {
|
|
this.debug("Boosted for a faint last turn");
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
return: {
|
|
num: 216,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
return Math.floor(pokemon.happiness * 10 / 25) || 1;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Return",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cute"
|
|
},
|
|
revelationdance: {
|
|
num: 686,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Revelation Dance",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, dance: 1 },
|
|
onModifyType(move, pokemon) {
|
|
let type = pokemon.getTypes()[0];
|
|
if (type === "Bird")
|
|
type = "???";
|
|
move.type = type;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
revenge: {
|
|
num: 279,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const damagedByTarget = pokemon.attackedBy.some(
|
|
(p) => p.source === target && p.damage > 0 && p.thisTurn
|
|
);
|
|
if (damagedByTarget) {
|
|
this.debug("BP doubled for getting hit by " + target);
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Revenge",
|
|
pp: 10,
|
|
priority: -4,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
reversal: {
|
|
num: 179,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
const ratio = Math.max(Math.floor(pokemon.hp * 48 / pokemon.maxhp), 1);
|
|
let bp;
|
|
if (ratio < 2) {
|
|
bp = 200;
|
|
} else if (ratio < 5) {
|
|
bp = 150;
|
|
} else if (ratio < 10) {
|
|
bp = 100;
|
|
} else if (ratio < 17) {
|
|
bp = 80;
|
|
} else if (ratio < 33) {
|
|
bp = 40;
|
|
} else {
|
|
bp = 20;
|
|
}
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Reversal",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
zMove: { basePower: 160 },
|
|
contestType: "Cool"
|
|
},
|
|
revivalblessing: {
|
|
num: 863,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Revival Blessing",
|
|
pp: 1,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryHit(source) {
|
|
if (!source.side.pokemon.filter((ally) => ally.fainted).length) {
|
|
return false;
|
|
}
|
|
},
|
|
slotCondition: "revivalblessing",
|
|
// No this not a real switchout move
|
|
// This is needed to trigger a switch protocol to choose a fainted party member
|
|
// Feel free to refactor
|
|
selfSwitch: true,
|
|
condition: {
|
|
duration: 1
|
|
// reviving implemented in side.ts, kind of
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal"
|
|
},
|
|
risingvoltage: {
|
|
num: 804,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
basePowerCallback(source, target, move) {
|
|
if (this.field.isTerrain("electricterrain") && target.isGrounded()) {
|
|
if (!source.isAlly(target))
|
|
this.hint(`${move.name}'s BP doubled on grounded target.`);
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Special",
|
|
name: "Rising Voltage",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
maxMove: { basePower: 140 }
|
|
},
|
|
roar: {
|
|
num: 46,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Roar",
|
|
pp: 20,
|
|
priority: -6,
|
|
flags: { reflectable: 1, mirror: 1, sound: 1, bypasssub: 1, allyanim: 1, noassist: 1, failcopycat: 1 },
|
|
forceSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
roaroftime: {
|
|
num: 459,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Special",
|
|
name: "Roar of Time",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { recharge: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Beautiful"
|
|
},
|
|
rockblast: {
|
|
num: 350,
|
|
accuracy: 90,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Rock Blast",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Tough"
|
|
},
|
|
rockclimb: {
|
|
num: 431,
|
|
accuracy: 85,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Rock Climb",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
rockpolish: {
|
|
num: 397,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Rock Polish",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
spe: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Rock",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Tough"
|
|
},
|
|
rockslide: {
|
|
num: 157,
|
|
accuracy: 90,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Rock Slide",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Rock",
|
|
contestType: "Tough"
|
|
},
|
|
rocksmash: {
|
|
num: 249,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Rock Smash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
rockthrow: {
|
|
num: 88,
|
|
accuracy: 90,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Rock Throw",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough"
|
|
},
|
|
rocktomb: {
|
|
num: 317,
|
|
accuracy: 95,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Rock Tomb",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Clever"
|
|
},
|
|
rockwrecker: {
|
|
num: 439,
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Rock Wrecker",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { bullet: 1, recharge: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
volatileStatus: "mustrecharge"
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough"
|
|
},
|
|
roleplay: {
|
|
num: 272,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Role Play",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bypasssub: 1, allyanim: 1 },
|
|
onTryHit(target, source) {
|
|
if (target.ability === source.ability)
|
|
return false;
|
|
const additionalBannedTargetAbilities = [
|
|
// Zen Mode included here for compatability with Gen 5-6
|
|
"flowergift",
|
|
"forecast",
|
|
"hungerswitch",
|
|
"illusion",
|
|
"imposter",
|
|
"neutralizinggas",
|
|
"powerofalchemy",
|
|
"receiver",
|
|
"trace",
|
|
"wonderguard",
|
|
"zenmode"
|
|
];
|
|
if (target.getAbility().isPermanent || additionalBannedTargetAbilities.includes(target.ability) || source.getAbility().isPermanent) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
const oldAbility = source.setAbility(target.ability);
|
|
if (oldAbility) {
|
|
this.add("-ability", source, source.getAbility().name, "[from] move: Role Play", "[of] " + target);
|
|
return;
|
|
}
|
|
return oldAbility;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
rollingkick: {
|
|
num: 27,
|
|
accuracy: 85,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Rolling Kick",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
rollout: {
|
|
num: 205,
|
|
accuracy: 90,
|
|
basePower: 30,
|
|
basePowerCallback(pokemon, target, move) {
|
|
let bp = move.basePower;
|
|
const rolloutData = pokemon.volatiles["rollout"];
|
|
if (rolloutData?.hitCount) {
|
|
bp *= Math.pow(2, rolloutData.contactHitCount);
|
|
}
|
|
if (rolloutData && pokemon.status !== "slp") {
|
|
rolloutData.hitCount++;
|
|
rolloutData.contactHitCount++;
|
|
if (rolloutData.hitCount < 5) {
|
|
rolloutData.duration = 2;
|
|
}
|
|
}
|
|
if (pokemon.volatiles["defensecurl"]) {
|
|
bp *= 2;
|
|
}
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
name: "Rollout",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, noparentalbond: 1, failinstruct: 1 },
|
|
onModifyMove(move, pokemon, target) {
|
|
if (pokemon.volatiles["rollout"] || pokemon.status === "slp" || !target)
|
|
return;
|
|
pokemon.addVolatile("rollout");
|
|
pokemon.volatiles["rollout"].targetSlot = move.sourceEffect ? pokemon.lastMoveTargetLoc : pokemon.getLocOf(target);
|
|
},
|
|
onAfterMove(source, target, move) {
|
|
const rolloutData = source.volatiles["rollout"];
|
|
if (rolloutData && rolloutData.hitCount === 5 && rolloutData.contactHitCount < 5) {
|
|
source.addVolatile("rolloutstorage");
|
|
source.volatiles["rolloutstorage"].contactHitCount = rolloutData.contactHitCount;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onLockMove: "rollout",
|
|
onStart() {
|
|
this.effectState.hitCount = 0;
|
|
this.effectState.contactHitCount = 0;
|
|
},
|
|
onResidual(target) {
|
|
if (target.lastMove && target.lastMove.id === "struggle") {
|
|
delete target.volatiles["rollout"];
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Cute"
|
|
},
|
|
roost: {
|
|
num: 355,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Roost",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
heal: [1, 2],
|
|
self: {
|
|
volatileStatus: "roost"
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onResidualOrder: 25,
|
|
onStart(target) {
|
|
if (!target.terastallized) {
|
|
this.add("-singleturn", target, "move: Roost");
|
|
} else if (target.terastallized === "Flying") {
|
|
this.add("-hint", "If a Flying Terastallized Pokemon uses Roost, it remains Flying-type.");
|
|
}
|
|
},
|
|
onTypePriority: -1,
|
|
onType(types, pokemon) {
|
|
this.effectState.typeWas = types;
|
|
return types.filter((type) => type !== "Flying");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Flying",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
rototiller: {
|
|
num: 563,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Rototiller",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { distance: 1, nonsky: 1 },
|
|
onHitField(target, source) {
|
|
const targets = [];
|
|
let anyAirborne = false;
|
|
for (const pokemon of this.getAllActive()) {
|
|
if (!pokemon.runImmunity("Ground")) {
|
|
this.add("-immune", pokemon);
|
|
anyAirborne = true;
|
|
continue;
|
|
}
|
|
if (pokemon.hasType("Grass")) {
|
|
targets.push(pokemon);
|
|
}
|
|
}
|
|
if (!targets.length && !anyAirborne)
|
|
return false;
|
|
for (const pokemon of targets) {
|
|
this.boost({ atk: 1, spa: 1 }, pokemon, source);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ground",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
round: {
|
|
num: 496,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
basePowerCallback(target, source, move) {
|
|
if (move.sourceEffect === "round") {
|
|
this.debug("BP doubled");
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Special",
|
|
name: "Round",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
onTry(source, target, move) {
|
|
for (const action of this.queue.list) {
|
|
if (!action.pokemon || !action.move || action.maxMove || action.zmove)
|
|
continue;
|
|
if (action.move.id === "round") {
|
|
this.queue.prioritizeAction(action, move);
|
|
return;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
ruination: {
|
|
num: 877,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
return this.clampIntRange(Math.floor(target.getUndynamaxedHP() / 2), 1);
|
|
},
|
|
category: "Special",
|
|
name: "Ruination",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough"
|
|
},
|
|
sacredfire: {
|
|
num: 221,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Sacred Fire",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, defrost: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
sacredsword: {
|
|
num: 533,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Sacred Sword",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
ignoreEvasion: true,
|
|
ignoreDefensive: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
safeguard: {
|
|
num: 219,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Safeguard",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
sideCondition: "safeguard",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-activate", source, "ability: Persistent", "[move] Safeguard");
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onSetStatus(status, target, source, effect) {
|
|
if (!effect || !source)
|
|
return;
|
|
if (effect.id === "yawn")
|
|
return;
|
|
if (effect.effectType === "Move" && effect.infiltrates && !target.isAlly(source))
|
|
return;
|
|
if (target !== source) {
|
|
this.debug("interrupting setStatus");
|
|
if (effect.name === "Synchronize" || effect.effectType === "Move" && !effect.secondaries) {
|
|
this.add("-activate", target, "move: Safeguard");
|
|
}
|
|
return null;
|
|
}
|
|
},
|
|
onTryAddVolatile(status, target, source, effect) {
|
|
if (!effect || !source)
|
|
return;
|
|
if (effect.effectType === "Move" && effect.infiltrates && !target.isAlly(source))
|
|
return;
|
|
if ((status.id === "confusion" || status.id === "yawn") && target !== source) {
|
|
if (effect.effectType === "Move" && !effect.secondaries)
|
|
this.add("-activate", target, "move: Safeguard");
|
|
return null;
|
|
}
|
|
},
|
|
onSideStart(side, source) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-sidestart", side, "Safeguard", "[persistent]");
|
|
} else {
|
|
this.add("-sidestart", side, "Safeguard");
|
|
}
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 3,
|
|
onSideEnd(side) {
|
|
this.add("-sideend", side, "Safeguard");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
saltcure: {
|
|
num: 864,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Salt Cure",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "Salt Cure");
|
|
},
|
|
onResidualOrder: 13,
|
|
onResidual(pokemon) {
|
|
this.damage(pokemon.baseMaxhp / (pokemon.hasType(["Water", "Steel"]) ? 4 : 8));
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "Salt Cure");
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
volatileStatus: "saltcure"
|
|
},
|
|
target: "normal",
|
|
type: "Rock"
|
|
},
|
|
sandattack: {
|
|
num: 28,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sand Attack",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
accuracy: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
zMove: { boost: { evasion: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
sandsearstorm: {
|
|
num: 848,
|
|
accuracy: 80,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Sandsear Storm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
status: "brn"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Ground"
|
|
},
|
|
sandstorm: {
|
|
num: 201,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sandstorm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { wind: 1 },
|
|
weather: "Sandstorm",
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Rock",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
sandtomb: {
|
|
num: 328,
|
|
accuracy: 85,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
name: "Sand Tomb",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Clever"
|
|
},
|
|
sappyseed: {
|
|
num: 738,
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Sappy Seed",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
onHit(target, source) {
|
|
if (target.hasType("Grass"))
|
|
return null;
|
|
target.addVolatile("leechseed", source);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Clever"
|
|
},
|
|
savagespinout: {
|
|
num: 634,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Savage Spin-Out",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "buginiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool"
|
|
},
|
|
scald: {
|
|
num: 503,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Scald",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, defrost: 1 },
|
|
thawsTarget: true,
|
|
secondary: {
|
|
chance: 30,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough"
|
|
},
|
|
scaleshot: {
|
|
num: 799,
|
|
accuracy: 90,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Scale Shot",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
selfBoost: {
|
|
boosts: {
|
|
def: -1,
|
|
spe: 1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 130 }
|
|
},
|
|
scaryface: {
|
|
num: 184,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Scary Face",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
boosts: {
|
|
spe: -2
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
scorchingsands: {
|
|
num: 815,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
name: "Scorching Sands",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, defrost: 1 },
|
|
thawsTarget: true,
|
|
secondary: {
|
|
chance: 30,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Ground"
|
|
},
|
|
scratch: {
|
|
num: 10,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Scratch",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
screech: {
|
|
num: 103,
|
|
accuracy: 85,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Screech",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1, allyanim: 1 },
|
|
boosts: {
|
|
def: -2
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
searingshot: {
|
|
num: 545,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Searing Shot",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "brn"
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Fire",
|
|
contestType: "Cool"
|
|
},
|
|
searingsunrazesmash: {
|
|
num: 724,
|
|
accuracy: true,
|
|
basePower: 200,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Searing Sunraze Smash",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: { contact: 1 },
|
|
isZ: "solganiumz",
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
secretpower: {
|
|
num: 290,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Secret Power",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onModifyMove(move, pokemon) {
|
|
if (this.field.isTerrain(""))
|
|
return;
|
|
move.secondaries = [];
|
|
if (this.field.isTerrain("electricterrain")) {
|
|
move.secondaries.push({
|
|
chance: 30,
|
|
status: "par"
|
|
});
|
|
} else if (this.field.isTerrain("grassyterrain")) {
|
|
move.secondaries.push({
|
|
chance: 30,
|
|
status: "slp"
|
|
});
|
|
} else if (this.field.isTerrain("mistyterrain")) {
|
|
move.secondaries.push({
|
|
chance: 30,
|
|
boosts: {
|
|
spa: -1
|
|
}
|
|
});
|
|
} else if (this.field.isTerrain("psychicterrain")) {
|
|
move.secondaries.push({
|
|
chance: 30,
|
|
boosts: {
|
|
spe: -1
|
|
}
|
|
});
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Clever"
|
|
},
|
|
secretsword: {
|
|
num: 548,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
overrideDefensiveStat: "def",
|
|
name: "Secret Sword",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Beautiful"
|
|
},
|
|
seedbomb: {
|
|
num: 402,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Seed Bomb",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough"
|
|
},
|
|
seedflare: {
|
|
num: 465,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Seed Flare",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 40,
|
|
boosts: {
|
|
spd: -2
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Beautiful"
|
|
},
|
|
seismictoss: {
|
|
num: 69,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
damage: "level",
|
|
category: "Physical",
|
|
name: "Seismic Toss",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
maxMove: { basePower: 75 },
|
|
contestType: "Tough"
|
|
},
|
|
selfdestruct: {
|
|
num: 120,
|
|
accuracy: 100,
|
|
basePower: 200,
|
|
category: "Physical",
|
|
name: "Self-Destruct",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, noparentalbond: 1 },
|
|
selfdestruct: "always",
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
shadowball: {
|
|
num: 247,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Shadow Ball",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
spd: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever"
|
|
},
|
|
shadowbone: {
|
|
num: 708,
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Shadow Bone",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
shadowclaw: {
|
|
num: 421,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Shadow Claw",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
shadowforce: {
|
|
num: 467,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Shadow Force",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, charge: 1, mirror: 1, nosleeptalk: 1, noassist: 1, failinstruct: 1 },
|
|
breaksProtect: true,
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onInvulnerability: false
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
shadowpunch: {
|
|
num: 325,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Shadow Punch",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever"
|
|
},
|
|
shadowsneak: {
|
|
num: 425,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Shadow Sneak",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever"
|
|
},
|
|
shadowstrike: {
|
|
num: 0,
|
|
accuracy: 95,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "CAP",
|
|
name: "Shadow Strike",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 50,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Clever"
|
|
},
|
|
sharpen: {
|
|
num: 159,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Sharpen",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
atk: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
shatteredpsyche: {
|
|
num: 648,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Shattered Psyche",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "psychiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
shedtail: {
|
|
num: 880,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Shed Tail",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
volatileStatus: "substitute",
|
|
onTryHit(source) {
|
|
if (!this.canSwitch(source.side)) {
|
|
this.add("-fail", source);
|
|
return this.NOT_FAIL;
|
|
}
|
|
if (source.volatiles["substitute"]) {
|
|
this.add("-fail", source, "move: Shed Tail");
|
|
return this.NOT_FAIL;
|
|
}
|
|
if (source.hp <= Math.ceil(source.maxhp / 2)) {
|
|
this.add("-fail", source, "move: Shed Tail", "[weak]");
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
onHit(target) {
|
|
this.directDamage(Math.ceil(target.maxhp / 2));
|
|
},
|
|
self: {
|
|
onHit(source) {
|
|
source.skipBeforeSwitchOutEventFlag = true;
|
|
}
|
|
},
|
|
selfSwitch: "shedtail",
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" }
|
|
},
|
|
sheercold: {
|
|
num: 329,
|
|
accuracy: 30,
|
|
basePower: 0,
|
|
category: "Special",
|
|
name: "Sheer Cold",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
ohko: "Ice",
|
|
target: "normal",
|
|
type: "Ice",
|
|
zMove: { basePower: 180 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Beautiful"
|
|
},
|
|
shellsidearm: {
|
|
num: 801,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Shell Side Arm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onPrepareHit(target, source, move) {
|
|
if (!source.isAlly(target)) {
|
|
this.attrLastMove("[anim] Shell Side Arm " + move.category);
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon, target) {
|
|
if (!target)
|
|
return;
|
|
const atk = pokemon.getStat("atk", false, true);
|
|
const spa = pokemon.getStat("spa", false, true);
|
|
const def = target.getStat("def", false, true);
|
|
const spd = target.getStat("spd", false, true);
|
|
const physical = Math.floor(Math.floor(Math.floor(Math.floor(2 * pokemon.level / 5 + 2) * 90 * atk) / def) / 50);
|
|
const special = Math.floor(Math.floor(Math.floor(Math.floor(2 * pokemon.level / 5 + 2) * 90 * spa) / spd) / 50);
|
|
if (physical > special || physical === special && this.random(2) === 0) {
|
|
move.category = "Physical";
|
|
move.flags.contact = 1;
|
|
}
|
|
},
|
|
onHit(target, source, move) {
|
|
if (!source.isAlly(target))
|
|
this.hint(move.category + " Shell Side Arm");
|
|
},
|
|
onAfterSubDamage(damage, target, source, move) {
|
|
if (!source.isAlly(target))
|
|
this.hint(move.category + " Shell Side Arm");
|
|
},
|
|
secondary: {
|
|
chance: 20,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison"
|
|
},
|
|
shellsmash: {
|
|
num: 504,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Shell Smash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: -1,
|
|
spd: -1,
|
|
atk: 2,
|
|
spa: 2,
|
|
spe: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Tough"
|
|
},
|
|
shelltrap: {
|
|
num: 704,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Shell Trap",
|
|
pp: 5,
|
|
priority: -3,
|
|
flags: { protect: 1, failmefirst: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
|
|
priorityChargeCallback(pokemon) {
|
|
pokemon.addVolatile("shelltrap");
|
|
},
|
|
onTryMove(pokemon) {
|
|
if (!pokemon.volatiles["shelltrap"]?.gotHit) {
|
|
this.attrLastMove("[still]");
|
|
this.add("cant", pokemon, "Shell Trap", "Shell Trap");
|
|
return null;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add("-singleturn", pokemon, "move: Shell Trap");
|
|
},
|
|
onHit(pokemon, source, move) {
|
|
if (!pokemon.isAlly(source) && move.category === "Physical") {
|
|
this.effectState.gotHit = true;
|
|
const action = this.queue.willMove(pokemon);
|
|
if (action) {
|
|
this.queue.prioritizeAction(action);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Fire",
|
|
contestType: "Tough"
|
|
},
|
|
shelter: {
|
|
num: 842,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Shelter",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Steel"
|
|
},
|
|
shiftgear: {
|
|
num: 508,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Shift Gear",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
spe: 2,
|
|
atk: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Steel",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
shockwave: {
|
|
num: 351,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Shock Wave",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
shoreup: {
|
|
num: 659,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Shore Up",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
onHit(pokemon) {
|
|
let factor = 0.5;
|
|
if (this.field.isWeather("sandstorm")) {
|
|
factor = 0.667;
|
|
}
|
|
const success = !!this.heal(this.modify(pokemon.maxhp, factor));
|
|
if (!success) {
|
|
this.add("-fail", pokemon, "heal");
|
|
return this.NOT_FAIL;
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ground",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
signalbeam: {
|
|
num: 324,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Signal Beam",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Beautiful"
|
|
},
|
|
silktrap: {
|
|
num: 852,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Silk Trap",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {},
|
|
stallingMove: true,
|
|
volatileStatus: "silktrap",
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "Protect");
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags["protect"] || move.category === "Status") {
|
|
if (move.isZ || move.isMax)
|
|
target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add("-activate", target, "move: Protect");
|
|
}
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
if (this.checkMoveMakesContact(move, source, target)) {
|
|
this.boost({ spe: -1 }, source, target, this.dex.getActiveMove("Silk Trap"));
|
|
}
|
|
return this.NOT_FAIL;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
|
|
this.boost({ spe: -1 }, source, target, this.dex.getActiveMove("Silk Trap"));
|
|
}
|
|
}
|
|
},
|
|
target: "self",
|
|
type: "Bug"
|
|
},
|
|
silverwind: {
|
|
num: 318,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Silver Wind",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Beautiful"
|
|
},
|
|
simplebeam: {
|
|
num: 493,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Simple Beam",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
onTryHit(target) {
|
|
if (target.getAbility().isPermanent || target.ability === "simple" || target.ability === "truant") {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(pokemon) {
|
|
const oldAbility = pokemon.setAbility("simple");
|
|
if (oldAbility) {
|
|
this.add("-ability", pokemon, "Simple", "[from] move: Simple Beam");
|
|
return;
|
|
}
|
|
return oldAbility;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
sing: {
|
|
num: 47,
|
|
accuracy: 55,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sing",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
status: "slp",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
sinisterarrowraid: {
|
|
num: 695,
|
|
accuracy: true,
|
|
basePower: 180,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Sinister Arrow Raid",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "decidiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
sizzlyslide: {
|
|
num: 735,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Sizzly Slide",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, defrost: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Clever"
|
|
},
|
|
sketch: {
|
|
num: 166,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Sketch",
|
|
pp: 1,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {
|
|
bypasssub: 1,
|
|
allyanim: 1,
|
|
failencore: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
onHit(target, source) {
|
|
const disallowedMoves = ["chatter", "sketch", "struggle"];
|
|
const move = target.lastMove;
|
|
if (source.transformed || !move || source.moves.includes(move.id))
|
|
return false;
|
|
if (disallowedMoves.includes(move.id) || move.isZ || move.isMax)
|
|
return false;
|
|
const sketchIndex = source.moves.indexOf("sketch");
|
|
if (sketchIndex < 0)
|
|
return false;
|
|
const sketchedMove = {
|
|
move: move.name,
|
|
id: move.id,
|
|
pp: move.pp,
|
|
maxpp: move.pp,
|
|
target: move.target,
|
|
disabled: false,
|
|
used: false
|
|
};
|
|
source.moveSlots[sketchIndex] = sketchedMove;
|
|
source.baseMoveSlots[sketchIndex] = sketchedMove;
|
|
this.add("-activate", source, "move: Sketch", move.name);
|
|
},
|
|
noSketch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
skillswap: {
|
|
num: 285,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Skill Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, bypasssub: 1, allyanim: 1 },
|
|
onTryHit(target, source) {
|
|
const additionalBannedAbilities = ["hungerswitch", "illusion", "neutralizinggas", "wonderguard"];
|
|
const targetAbility = target.getAbility();
|
|
const sourceAbility = source.getAbility();
|
|
if (target.volatiles["dynamax"] || targetAbility.isPermanent || sourceAbility.isPermanent || additionalBannedAbilities.includes(target.ability) || additionalBannedAbilities.includes(source.ability)) {
|
|
return false;
|
|
}
|
|
const sourceCanBeSet = this.runEvent("SetAbility", source, source, this.effect, targetAbility);
|
|
if (!sourceCanBeSet)
|
|
return sourceCanBeSet;
|
|
const targetCanBeSet = this.runEvent("SetAbility", target, source, this.effect, sourceAbility);
|
|
if (!targetCanBeSet)
|
|
return targetCanBeSet;
|
|
},
|
|
onHit(target, source, move) {
|
|
const targetAbility = target.getAbility();
|
|
const sourceAbility = source.getAbility();
|
|
if (target.isAlly(source)) {
|
|
this.add("-activate", source, "move: Skill Swap", "", "", "[of] " + target);
|
|
} else {
|
|
this.add("-activate", source, "move: Skill Swap", targetAbility, sourceAbility, "[of] " + target);
|
|
}
|
|
this.singleEvent("End", sourceAbility, source.abilityState, source);
|
|
this.singleEvent("End", targetAbility, target.abilityState, target);
|
|
source.ability = targetAbility.id;
|
|
target.ability = sourceAbility.id;
|
|
source.abilityState = { id: this.toID(source.ability), target: source };
|
|
target.abilityState = { id: this.toID(target.ability), target };
|
|
if (!target.isAlly(source))
|
|
target.volatileStaleness = "external";
|
|
this.singleEvent("Start", targetAbility, source.abilityState, source);
|
|
this.singleEvent("Start", sourceAbility, target.abilityState, target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
skittersmack: {
|
|
num: 806,
|
|
accuracy: 90,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Skitter Smack",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Bug"
|
|
},
|
|
skullbash: {
|
|
num: 130,
|
|
accuracy: 100,
|
|
basePower: 130,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Skull Bash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, charge: 1, protect: 1, mirror: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
this.boost({ def: 1 }, attacker, attacker, move);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
skyattack: {
|
|
num: 143,
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Physical",
|
|
name: "Sky Attack",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { charge: 1, protect: 1, mirror: 1, distance: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
critRatio: 2,
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
skydrop: {
|
|
num: 507,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Sky Drop",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {
|
|
contact: 1,
|
|
charge: 1,
|
|
protect: 1,
|
|
mirror: 1,
|
|
gravity: 1,
|
|
distance: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failinstruct: 1
|
|
},
|
|
onModifyMove(move, source) {
|
|
if (!source.volatiles["skydrop"]) {
|
|
move.accuracy = true;
|
|
delete move.flags["contact"];
|
|
}
|
|
},
|
|
onMoveFail(target, source) {
|
|
if (source.volatiles["twoturnmove"] && source.volatiles["twoturnmove"].duration === 1) {
|
|
source.removeVolatile("skydrop");
|
|
source.removeVolatile("twoturnmove");
|
|
if (target === this.effectState.target) {
|
|
this.add("-end", target, "Sky Drop", "[interrupt]");
|
|
}
|
|
}
|
|
},
|
|
onTry(source, target) {
|
|
return !target.fainted;
|
|
},
|
|
onTryHit(target, source, move) {
|
|
if (source.removeVolatile(move.id)) {
|
|
if (target !== source.volatiles["twoturnmove"].source)
|
|
return false;
|
|
if (target.hasType("Flying")) {
|
|
this.add("-immune", target);
|
|
return null;
|
|
}
|
|
} else {
|
|
if (target.volatiles["substitute"] || target.isAlly(source)) {
|
|
return false;
|
|
}
|
|
if (target.getWeight() >= 2e3) {
|
|
this.add("-fail", target, "move: Sky Drop", "[heavy]");
|
|
return null;
|
|
}
|
|
this.add("-prepare", source, move.name, target);
|
|
source.addVolatile("twoturnmove", target);
|
|
return null;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
if (target.hp)
|
|
this.add("-end", target, "Sky Drop");
|
|
},
|
|
condition: {
|
|
duration: 2,
|
|
onAnyDragOut(pokemon) {
|
|
if (pokemon === this.effectState.target || pokemon === this.effectState.source)
|
|
return false;
|
|
},
|
|
onFoeTrapPokemonPriority: -15,
|
|
onFoeTrapPokemon(defender) {
|
|
if (defender !== this.effectState.source)
|
|
return;
|
|
defender.trapped = true;
|
|
},
|
|
onFoeBeforeMovePriority: 12,
|
|
onFoeBeforeMove(attacker, defender, move) {
|
|
if (attacker === this.effectState.source) {
|
|
attacker.activeMoveActions--;
|
|
this.debug("Sky drop nullifying.");
|
|
return null;
|
|
}
|
|
},
|
|
onRedirectTargetPriority: 99,
|
|
onRedirectTarget(target, source, source2) {
|
|
if (source !== this.effectState.target)
|
|
return;
|
|
if (this.effectState.source.fainted)
|
|
return;
|
|
return this.effectState.source;
|
|
},
|
|
onAnyInvulnerability(target, source, move) {
|
|
if (target !== this.effectState.target && target !== this.effectState.source) {
|
|
return;
|
|
}
|
|
if (source === this.effectState.target && target === this.effectState.source) {
|
|
return;
|
|
}
|
|
if (["gust", "twister", "skyuppercut", "thunder", "hurricane", "smackdown", "thousandarrows"].includes(move.id)) {
|
|
return;
|
|
}
|
|
return false;
|
|
},
|
|
onAnyBasePower(basePower, target, source, move) {
|
|
if (target !== this.effectState.target && target !== this.effectState.source) {
|
|
return;
|
|
}
|
|
if (source === this.effectState.target && target === this.effectState.source) {
|
|
return;
|
|
}
|
|
if (move.id === "gust" || move.id === "twister") {
|
|
this.debug("BP doubled on midair target");
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
onFaint(target) {
|
|
if (target.volatiles["skydrop"] && target.volatiles["twoturnmove"].source) {
|
|
this.add("-end", target.volatiles["twoturnmove"].source, "Sky Drop", "[interrupt]");
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Tough"
|
|
},
|
|
skyuppercut: {
|
|
num: 327,
|
|
accuracy: 90,
|
|
basePower: 85,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Sky Uppercut",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
slackoff: {
|
|
num: 303,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Slack Off",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
slam: {
|
|
num: 21,
|
|
accuracy: 75,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Slam",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
slash: {
|
|
num: 163,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Slash",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
sleeppowder: {
|
|
num: 79,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sleep Powder",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { powder: 1, protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "slp",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
sleeptalk: {
|
|
num: 214,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sleep Talk",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
sleepUsable: true,
|
|
onTry(source) {
|
|
return source.status === "slp" || source.hasAbility("comatose");
|
|
},
|
|
onHit(pokemon) {
|
|
const moves = [];
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
const moveid = moveSlot.id;
|
|
if (!moveid)
|
|
continue;
|
|
const move = this.dex.moves.get(moveid);
|
|
if (move.flags["nosleeptalk"] || move.flags["charge"] || move.isZ && move.basePower !== 1 || move.isMax) {
|
|
continue;
|
|
}
|
|
moves.push(moveid);
|
|
}
|
|
let randomMove = "";
|
|
if (moves.length)
|
|
randomMove = this.sample(moves);
|
|
if (!randomMove) {
|
|
return false;
|
|
}
|
|
this.actions.useMove(randomMove, pokemon);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "crit2" },
|
|
contestType: "Cute"
|
|
},
|
|
sludge: {
|
|
num: 124,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Sludge",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough"
|
|
},
|
|
sludgebomb: {
|
|
num: 188,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Sludge Bomb",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough"
|
|
},
|
|
sludgewave: {
|
|
num: 482,
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Special",
|
|
name: "Sludge Wave",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "psn"
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Poison",
|
|
contestType: "Tough"
|
|
},
|
|
smackdown: {
|
|
num: 479,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Smack Down",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
volatileStatus: "smackdown",
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
let applies = false;
|
|
if (pokemon.hasType("Flying") || pokemon.hasAbility("levitate"))
|
|
applies = true;
|
|
if (pokemon.hasItem("ironball") || pokemon.volatiles["ingrain"] || this.field.getPseudoWeather("gravity"))
|
|
applies = false;
|
|
if (pokemon.removeVolatile("fly") || pokemon.removeVolatile("bounce")) {
|
|
applies = true;
|
|
this.queue.cancelMove(pokemon);
|
|
pokemon.removeVolatile("twoturnmove");
|
|
}
|
|
if (pokemon.volatiles["magnetrise"]) {
|
|
applies = true;
|
|
delete pokemon.volatiles["magnetrise"];
|
|
}
|
|
if (pokemon.volatiles["telekinesis"]) {
|
|
applies = true;
|
|
delete pokemon.volatiles["telekinesis"];
|
|
}
|
|
if (!applies)
|
|
return false;
|
|
this.add("-start", pokemon, "Smack Down");
|
|
},
|
|
onRestart(pokemon) {
|
|
if (pokemon.removeVolatile("fly") || pokemon.removeVolatile("bounce")) {
|
|
this.queue.cancelMove(pokemon);
|
|
pokemon.removeVolatile("twoturnmove");
|
|
this.add("-start", pokemon, "Smack Down");
|
|
}
|
|
}
|
|
// groundedness implemented in battle.engine.js:BattlePokemon#isGrounded
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough"
|
|
},
|
|
smartstrike: {
|
|
num: 684,
|
|
accuracy: true,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Smart Strike",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
smellingsalts: {
|
|
num: 265,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.status === "par") {
|
|
this.debug("BP doubled on paralyzed target");
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Smelling Salts",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onHit(target) {
|
|
if (target.status === "par")
|
|
target.cureStatus();
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
smog: {
|
|
num: 123,
|
|
accuracy: 70,
|
|
basePower: 30,
|
|
category: "Special",
|
|
name: "Smog",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 40,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Tough"
|
|
},
|
|
smokescreen: {
|
|
num: 108,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Smokescreen",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
accuracy: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { evasion: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
snaptrap: {
|
|
num: 779,
|
|
accuracy: 100,
|
|
basePower: 35,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Snap Trap",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass"
|
|
},
|
|
snarl: {
|
|
num: 555,
|
|
accuracy: 95,
|
|
basePower: 55,
|
|
category: "Special",
|
|
name: "Snarl",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Dark",
|
|
contestType: "Tough"
|
|
},
|
|
snatch: {
|
|
num: 289,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Snatch",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: { bypasssub: 1, mustpressure: 1, noassist: 1, failcopycat: 1 },
|
|
volatileStatus: "snatch",
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add("-singleturn", pokemon, "Snatch");
|
|
},
|
|
onAnyPrepareHitPriority: -1,
|
|
onAnyPrepareHit(source, target, move) {
|
|
const snatchUser = this.effectState.source;
|
|
if (snatchUser.isSkyDropped())
|
|
return;
|
|
if (!move || move.isZ || move.isMax || !move.flags["snatch"] || move.sourceEffect === "snatch") {
|
|
return;
|
|
}
|
|
snatchUser.removeVolatile("snatch");
|
|
this.add("-activate", snatchUser, "move: Snatch", "[of] " + source);
|
|
this.actions.useMove(move.id, snatchUser);
|
|
return null;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dark",
|
|
zMove: { boost: { spe: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
snipeshot: {
|
|
num: 745,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Snipe Shot",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
tracksTarget: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water"
|
|
},
|
|
snore: {
|
|
num: 173,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Snore",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
sleepUsable: true,
|
|
onTry(source) {
|
|
return source.status === "slp" || source.hasAbility("comatose");
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
snowscape: {
|
|
num: 883,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Snowscape",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
weather: "snow",
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ice"
|
|
},
|
|
soak: {
|
|
num: 487,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Soak",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
onHit(target) {
|
|
if (target.getTypes().join() === "Water" || !target.setType("Water")) {
|
|
this.add("-fail", target);
|
|
return null;
|
|
}
|
|
this.add("-start", target, "typechange", "Water");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
softboiled: {
|
|
num: 135,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Soft-Boiled",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
heal: [1, 2],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
solarbeam: {
|
|
num: 76,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Solar Beam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { charge: 1, protect: 1, mirror: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (["sunnyday", "desolateland"].includes(attacker.effectiveWeather())) {
|
|
this.attrLastMove("[still]");
|
|
this.addMove("-anim", attacker, move.name, defender);
|
|
return;
|
|
}
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
onBasePower(basePower, pokemon, target) {
|
|
const weakWeathers = ["raindance", "primordialsea", "sandstorm", "hail", "snow"];
|
|
if (weakWeathers.includes(pokemon.effectiveWeather())) {
|
|
this.debug("weakened by weather");
|
|
return this.chainModify(0.5);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
solarblade: {
|
|
num: 669,
|
|
accuracy: 100,
|
|
basePower: 125,
|
|
category: "Physical",
|
|
name: "Solar Blade",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, charge: 1, protect: 1, mirror: 1, slicing: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
onTryMove(attacker, defender, move) {
|
|
if (attacker.removeVolatile(move.id)) {
|
|
return;
|
|
}
|
|
this.add("-prepare", attacker, move.name);
|
|
if (["sunnyday", "desolateland"].includes(attacker.effectiveWeather())) {
|
|
this.attrLastMove("[still]");
|
|
this.addMove("-anim", attacker, move.name, defender);
|
|
return;
|
|
}
|
|
if (!this.runEvent("ChargeMove", attacker, defender, move)) {
|
|
return;
|
|
}
|
|
attacker.addVolatile("twoturnmove", defender);
|
|
return null;
|
|
},
|
|
onBasePower(basePower, pokemon, target) {
|
|
const weakWeathers = ["raindance", "primordialsea", "sandstorm", "hail", "snow"];
|
|
if (weakWeathers.includes(pokemon.effectiveWeather())) {
|
|
this.debug("weakened by weather");
|
|
return this.chainModify(0.5);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
sonicboom: {
|
|
num: 49,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
damage: 20,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Sonic Boom",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
soulstealing7starstrike: {
|
|
num: 699,
|
|
accuracy: true,
|
|
basePower: 195,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Soul-Stealing 7-Star Strike",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: { contact: 1 },
|
|
isZ: "marshadiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
spacialrend: {
|
|
num: 460,
|
|
accuracy: 95,
|
|
basePower: 100,
|
|
category: "Special",
|
|
name: "Spacial Rend",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
contestType: "Beautiful"
|
|
},
|
|
spark: {
|
|
num: 209,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Spark",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
sparklingaria: {
|
|
num: 664,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Sparkling Aria",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: {
|
|
dustproof: true,
|
|
chance: 100,
|
|
volatileStatus: "sparklingaria"
|
|
},
|
|
onAfterMove(source, target, move) {
|
|
for (const pokemon of this.getAllActive()) {
|
|
if (pokemon !== source && pokemon.removeVolatile("sparklingaria") && pokemon.status === "brn" && !source.fainted) {
|
|
pokemon.cureStatus();
|
|
}
|
|
}
|
|
},
|
|
target: "allAdjacent",
|
|
type: "Water",
|
|
contestType: "Tough"
|
|
},
|
|
sparklyswirl: {
|
|
num: 740,
|
|
accuracy: 85,
|
|
basePower: 120,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Sparkly Swirl",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
self: {
|
|
onHit(pokemon, source, move) {
|
|
this.add("-activate", source, "move: Aromatherapy");
|
|
for (const ally of source.side.pokemon) {
|
|
if (ally !== source && (ally.volatiles["substitute"] && !move.infiltrates)) {
|
|
continue;
|
|
}
|
|
ally.cureStatus();
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Clever"
|
|
},
|
|
spectralthief: {
|
|
num: 712,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Spectral Thief",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, bypasssub: 1 },
|
|
stealsBoosts: true,
|
|
// Boost stealing implemented in scripts.js
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Cool"
|
|
},
|
|
speedswap: {
|
|
num: 683,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Speed Swap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, bypasssub: 1, allyanim: 1 },
|
|
onHit(target, source) {
|
|
const targetSpe = target.storedStats.spe;
|
|
target.storedStats.spe = source.storedStats.spe;
|
|
source.storedStats.spe = targetSpe;
|
|
this.add("-activate", source, "move: Speed Swap", "[of] " + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
spicyextract: {
|
|
num: 858,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spicy Extract",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
atk: 2,
|
|
def: -2
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass"
|
|
},
|
|
spiderweb: {
|
|
num: 169,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Spider Web",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
onHit(target, source, move) {
|
|
return target.addVolatile("trapped", source, move, "trapper");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
spikecannon: {
|
|
num: 131,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Spike Cannon",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
maxMove: { basePower: 120 },
|
|
contestType: "Cool"
|
|
},
|
|
spikes: {
|
|
num: 191,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spikes",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { reflectable: 1, nonsky: 1, mustpressure: 1 },
|
|
sideCondition: "spikes",
|
|
condition: {
|
|
// this is a side condition
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "Spikes");
|
|
this.effectState.layers = 1;
|
|
},
|
|
onSideRestart(side) {
|
|
if (this.effectState.layers >= 3)
|
|
return false;
|
|
this.add("-sidestart", side, "Spikes");
|
|
this.effectState.layers++;
|
|
},
|
|
onEntryHazard(pokemon) {
|
|
if (!pokemon.isGrounded() || pokemon.hasItem("heavydutyboots"))
|
|
return;
|
|
const damageAmounts = [0, 3, 4, 6];
|
|
this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Ground",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
spikyshield: {
|
|
num: 596,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spiky Shield",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: { noassist: 1, failcopycat: 1 },
|
|
stallingMove: true,
|
|
volatileStatus: "spikyshield",
|
|
onPrepareHit(pokemon) {
|
|
return !!this.queue.willAct() && this.runEvent("StallMove", pokemon);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add("-singleturn", target, "move: Protect");
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags["protect"]) {
|
|
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
|
|
return;
|
|
if (move.isZ || move.isMax)
|
|
target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
if (move.smartTarget) {
|
|
move.smartTarget = false;
|
|
} else {
|
|
this.add("-activate", target, "move: Protect");
|
|
}
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
if (this.checkMoveMakesContact(move, source, target)) {
|
|
this.damage(source.baseMaxhp / 8, source, target);
|
|
}
|
|
return this.NOT_FAIL;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
|
|
this.damage(source.baseMaxhp / 8, source, target);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
spinout: {
|
|
num: 859,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Spin Out",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
spe: -2
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel"
|
|
},
|
|
spiritbreak: {
|
|
num: 789,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Spirit Break",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fairy"
|
|
},
|
|
spiritshackle: {
|
|
num: 662,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Spirit Shackle",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target, source, move) {
|
|
if (source.isActive)
|
|
target.addVolatile("trapped", source, move, "trapper");
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
contestType: "Tough"
|
|
},
|
|
spitup: {
|
|
num: 255,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
if (!pokemon.volatiles["stockpile"]?.layers)
|
|
return false;
|
|
return pokemon.volatiles["stockpile"].layers * 100;
|
|
},
|
|
category: "Special",
|
|
name: "Spit Up",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1 },
|
|
onTry(source) {
|
|
return !!source.volatiles["stockpile"];
|
|
},
|
|
onAfterMove(pokemon) {
|
|
pokemon.removeVolatile("stockpile");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
spite: {
|
|
num: 180,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spite",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
onHit(target) {
|
|
let move = target.lastMove;
|
|
if (!move || move.isZ)
|
|
return false;
|
|
if (move.isMax && move.baseMove)
|
|
move = this.dex.moves.get(move.baseMove);
|
|
const ppDeducted = target.deductPP(move.id, 4);
|
|
if (!ppDeducted)
|
|
return false;
|
|
this.add("-activate", target, "move: Spite", move.name, ppDeducted);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Tough"
|
|
},
|
|
splash: {
|
|
num: 150,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Splash",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { gravity: 1 },
|
|
onTry(source, target, move) {
|
|
if (this.field.getPseudoWeather("Gravity")) {
|
|
this.add("cant", source, "move: Gravity", move);
|
|
return null;
|
|
}
|
|
},
|
|
onTryHit(target, source) {
|
|
this.add("-nothing");
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 3 } },
|
|
contestType: "Cute"
|
|
},
|
|
splinteredstormshards: {
|
|
num: 727,
|
|
accuracy: true,
|
|
basePower: 190,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Splintered Stormshards",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onHit() {
|
|
this.field.clearTerrain();
|
|
},
|
|
onAfterSubDamage() {
|
|
this.field.clearTerrain();
|
|
},
|
|
isZ: "lycaniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Cool"
|
|
},
|
|
splishysplash: {
|
|
num: 730,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
isNonstandard: "LGPE",
|
|
name: "Splishy Splash",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
spore: {
|
|
num: 147,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Spore",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { powder: 1, protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "slp",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
spotlight: {
|
|
num: 671,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Spotlight",
|
|
pp: 15,
|
|
priority: 3,
|
|
flags: { protect: 1, reflectable: 1, allyanim: 1, noassist: 1, failcopycat: 1 },
|
|
volatileStatus: "spotlight",
|
|
onTryHit(target) {
|
|
if (this.activePerHalf === 1)
|
|
return false;
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add("-singleturn", pokemon, "move: Spotlight");
|
|
},
|
|
onFoeRedirectTargetPriority: 2,
|
|
onFoeRedirectTarget(target, source, source2, move) {
|
|
if (this.validTarget(this.effectState.target, source, move.target)) {
|
|
this.debug("Spotlight redirected target of move");
|
|
return this.effectState.target;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
springtidestorm: {
|
|
num: 831,
|
|
accuracy: 80,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Springtide Storm",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
boosts: {
|
|
atk: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Fairy"
|
|
},
|
|
stealthrock: {
|
|
num: 446,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Stealth Rock",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { reflectable: 1, mustpressure: 1 },
|
|
sideCondition: "stealthrock",
|
|
condition: {
|
|
// this is a side condition
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "move: Stealth Rock");
|
|
},
|
|
onEntryHazard(pokemon) {
|
|
if (pokemon.hasItem("heavydutyboots"))
|
|
return;
|
|
const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove("stealthrock")), -6, 6);
|
|
this.damage(pokemon.maxhp * Math.pow(2, typeMod) / 8);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Rock",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
steameruption: {
|
|
num: 592,
|
|
accuracy: 95,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Steam Eruption",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, defrost: 1 },
|
|
thawsTarget: true,
|
|
secondary: {
|
|
chance: 30,
|
|
status: "brn"
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
steamroller: {
|
|
num: 537,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Steamroller",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Tough"
|
|
},
|
|
steelbeam: {
|
|
num: 796,
|
|
accuracy: 95,
|
|
basePower: 140,
|
|
category: "Special",
|
|
name: "Steel Beam",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
mindBlownRecoil: true,
|
|
onAfterMove(pokemon, target, move) {
|
|
if (move.mindBlownRecoil && !move.multihit) {
|
|
const hpBeforeRecoil = pokemon.hp;
|
|
this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.conditions.get("Steel Beam"), true);
|
|
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
|
|
this.runEvent("EmergencyExit", pokemon, pokemon);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel"
|
|
},
|
|
steelroller: {
|
|
num: 798,
|
|
accuracy: 100,
|
|
basePower: 130,
|
|
category: "Physical",
|
|
name: "Steel Roller",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onTry() {
|
|
return !this.field.isTerrain("");
|
|
},
|
|
onHit() {
|
|
this.field.clearTerrain();
|
|
},
|
|
onAfterSubDamage() {
|
|
this.field.clearTerrain();
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel"
|
|
},
|
|
steelwing: {
|
|
num: 211,
|
|
accuracy: 90,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Steel Wing",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
self: {
|
|
boosts: {
|
|
def: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
stickyweb: {
|
|
num: 564,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sticky Web",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { reflectable: 1 },
|
|
sideCondition: "stickyweb",
|
|
condition: {
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "move: Sticky Web");
|
|
},
|
|
onEntryHazard(pokemon) {
|
|
if (!pokemon.isGrounded() || pokemon.hasItem("heavydutyboots"))
|
|
return;
|
|
this.add("-activate", pokemon, "move: Sticky Web");
|
|
this.boost({ spe: -1 }, pokemon, this.effectState.source, this.dex.getActiveMove("stickyweb"));
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Bug",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
stockpile: {
|
|
num: 254,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Stockpile",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onTry(source) {
|
|
if (source.volatiles["stockpile"] && source.volatiles["stockpile"].layers >= 3)
|
|
return false;
|
|
},
|
|
volatileStatus: "stockpile",
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(target) {
|
|
this.effectState.layers = 1;
|
|
this.effectState.def = 0;
|
|
this.effectState.spd = 0;
|
|
this.add("-start", target, "stockpile" + this.effectState.layers);
|
|
const [curDef, curSpD] = [target.boosts.def, target.boosts.spd];
|
|
this.boost({ def: 1, spd: 1 }, target, target);
|
|
if (curDef !== target.boosts.def)
|
|
this.effectState.def--;
|
|
if (curSpD !== target.boosts.spd)
|
|
this.effectState.spd--;
|
|
},
|
|
onRestart(target) {
|
|
if (this.effectState.layers >= 3)
|
|
return false;
|
|
this.effectState.layers++;
|
|
this.add("-start", target, "stockpile" + this.effectState.layers);
|
|
const curDef = target.boosts.def;
|
|
const curSpD = target.boosts.spd;
|
|
this.boost({ def: 1, spd: 1 }, target, target);
|
|
if (curDef !== target.boosts.def)
|
|
this.effectState.def--;
|
|
if (curSpD !== target.boosts.spd)
|
|
this.effectState.spd--;
|
|
},
|
|
onEnd(target) {
|
|
if (this.effectState.def || this.effectState.spd) {
|
|
const boosts = {};
|
|
if (this.effectState.def)
|
|
boosts.def = this.effectState.def;
|
|
if (this.effectState.spd)
|
|
boosts.spd = this.effectState.spd;
|
|
this.boost(boosts, target, target);
|
|
}
|
|
this.add("-end", target, "Stockpile");
|
|
if (this.effectState.def !== this.effectState.layers * -1 || this.effectState.spd !== this.effectState.layers * -1) {
|
|
this.hint("In Gen 7, Stockpile keeps track of how many times it successfully altered each stat individually.");
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Tough"
|
|
},
|
|
stokedsparksurfer: {
|
|
num: 700,
|
|
accuracy: true,
|
|
basePower: 175,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Stoked Sparksurfer",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "aloraichiumz",
|
|
secondary: {
|
|
chance: 100,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
stomp: {
|
|
num: 23,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Stomp",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
stompingtantrum: {
|
|
num: 707,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (pokemon.moveLastTurnResult === false) {
|
|
this.debug("doubling Stomping Tantrum BP due to previous move failure");
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
name: "Stomping Tantrum",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Tough"
|
|
},
|
|
stoneaxe: {
|
|
num: 830,
|
|
accuracy: 90,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Stone Axe",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
self: {
|
|
onHit(source) {
|
|
for (const side of source.side.foeSidesWithConditions()) {
|
|
side.addSideCondition("stealthrock");
|
|
}
|
|
}
|
|
},
|
|
secondary: {},
|
|
// allows sheer force to trigger
|
|
target: "normal",
|
|
type: "Rock"
|
|
},
|
|
stoneedge: {
|
|
num: 444,
|
|
accuracy: 80,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
name: "Stone Edge",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock",
|
|
contestType: "Tough"
|
|
},
|
|
storedpower: {
|
|
num: 500,
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const bp = move.basePower + 20 * pokemon.positiveBoosts();
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
name: "Stored Power",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Clever"
|
|
},
|
|
stormthrow: {
|
|
num: 480,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Storm Throw",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
willCrit: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
strangesteam: {
|
|
num: 790,
|
|
accuracy: 95,
|
|
basePower: 90,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Strange Steam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "normal",
|
|
type: "Fairy"
|
|
},
|
|
strength: {
|
|
num: 70,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Strength",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
strengthsap: {
|
|
num: 668,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Strength Sap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, heal: 1 },
|
|
onHit(target, source) {
|
|
if (target.boosts.atk === -6)
|
|
return false;
|
|
const atk = target.getStat("atk", false, true);
|
|
const success = this.boost({ atk: -1 }, target, source, null, false, true);
|
|
return !!(this.heal(atk, source, target) || success);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
stringshot: {
|
|
num: 81,
|
|
accuracy: 95,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "String Shot",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
spe: -2
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Bug",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
struggle: {
|
|
num: 165,
|
|
accuracy: true,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Struggle",
|
|
pp: 1,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {
|
|
contact: 1,
|
|
protect: 1,
|
|
failencore: 1,
|
|
failmefirst: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
noSketch: true,
|
|
onModifyMove(move, pokemon, target) {
|
|
move.type = "???";
|
|
this.add("-activate", pokemon, "move: Struggle");
|
|
},
|
|
struggleRecoil: true,
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
strugglebug: {
|
|
num: 522,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Struggle Bug",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
spa: -1
|
|
}
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Bug",
|
|
contestType: "Cute"
|
|
},
|
|
stuffcheeks: {
|
|
num: 747,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Stuff Cheeks",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onDisableMove(pokemon) {
|
|
if (!pokemon.getItem().isBerry)
|
|
pokemon.disableMove("stuffcheeks");
|
|
},
|
|
onTry(source) {
|
|
return source.getItem().isBerry;
|
|
},
|
|
onHit(pokemon) {
|
|
if (!this.boost({ def: 2 }))
|
|
return null;
|
|
pokemon.eatItem(true);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal"
|
|
},
|
|
stunspore: {
|
|
num: 78,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Stun Spore",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { powder: 1, protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "par",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
submission: {
|
|
num: 66,
|
|
accuracy: 80,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Submission",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
recoil: [1, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
substitute: {
|
|
num: 164,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Substitute",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, nonsky: 1 },
|
|
volatileStatus: "substitute",
|
|
onTryHit(source) {
|
|
if (source.volatiles["substitute"]) {
|
|
this.add("-fail", source, "move: Substitute");
|
|
return this.NOT_FAIL;
|
|
}
|
|
if (source.hp <= source.maxhp / 4 || source.maxhp === 1) {
|
|
this.add("-fail", source, "move: Substitute", "[weak]");
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
onHit(target) {
|
|
this.directDamage(target.maxhp / 4);
|
|
},
|
|
condition: {
|
|
onStart(target, source, effect) {
|
|
if (effect?.id === "shedtail") {
|
|
this.add("-start", target, "Substitute", "[from] move: Shed Tail");
|
|
} else {
|
|
this.add("-start", target, "Substitute");
|
|
}
|
|
this.effectState.hp = Math.floor(target.maxhp / 4);
|
|
if (target.volatiles["partiallytrapped"]) {
|
|
this.add("-end", target, target.volatiles["partiallytrapped"].sourceEffect, "[partiallytrapped]", "[silent]");
|
|
delete target.volatiles["partiallytrapped"];
|
|
}
|
|
},
|
|
onTryPrimaryHitPriority: -1,
|
|
onTryPrimaryHit(target, source, move) {
|
|
if (target === source || move.flags["bypasssub"] || move.infiltrates) {
|
|
return;
|
|
}
|
|
let damage = this.actions.getDamage(source, target, move);
|
|
if (!damage && damage !== 0) {
|
|
this.add("-fail", source);
|
|
this.attrLastMove("[still]");
|
|
return null;
|
|
}
|
|
damage = this.runEvent("SubDamage", target, source, move, damage);
|
|
if (!damage) {
|
|
return damage;
|
|
}
|
|
if (damage > target.volatiles["substitute"].hp) {
|
|
damage = target.volatiles["substitute"].hp;
|
|
}
|
|
target.volatiles["substitute"].hp -= damage;
|
|
source.lastDamage = damage;
|
|
if (target.volatiles["substitute"].hp <= 0) {
|
|
if (move.ohko)
|
|
this.add("-ohko");
|
|
target.removeVolatile("substitute");
|
|
} else {
|
|
this.add("-activate", target, "move: Substitute", "[damage]");
|
|
}
|
|
if (move.recoil) {
|
|
this.damage(this.actions.calcRecoilDamage(damage, move), source, target, "recoil");
|
|
}
|
|
if (move.drain) {
|
|
this.heal(Math.ceil(damage * move.drain[0] / move.drain[1]), source, target, "drain");
|
|
}
|
|
this.singleEvent("AfterSubDamage", move, null, target, source, move, damage);
|
|
this.runEvent("AfterSubDamage", target, source, move, damage);
|
|
return this.HIT_SUBSTITUTE;
|
|
},
|
|
onEnd(target) {
|
|
this.add("-end", target, "Substitute");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
subzeroslammer: {
|
|
num: 650,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Subzero Slammer",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "iciumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
contestType: "Cool"
|
|
},
|
|
suckerpunch: {
|
|
num: 389,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Sucker Punch",
|
|
pp: 5,
|
|
priority: 1,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onTry(source, target) {
|
|
const action = this.queue.willMove(target);
|
|
const move = action?.choice === "move" ? action.move : null;
|
|
if (!move || move.category === "Status" && move.id !== "mefirst" || target.volatiles["mustrecharge"]) {
|
|
return false;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
sunnyday: {
|
|
num: 241,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sunny Day",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
weather: "sunnyday",
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fire",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
sunsteelstrike: {
|
|
num: 713,
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Sunsteel Strike",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
ignoreAbility: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
contestType: "Cool"
|
|
},
|
|
superfang: {
|
|
num: 162,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
return this.clampIntRange(target.getUndynamaxedHP() / 2, 1);
|
|
},
|
|
category: "Physical",
|
|
name: "Super Fang",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
superpower: {
|
|
num: 276,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Superpower",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
atk: -1,
|
|
def: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
supersonic: {
|
|
num: 48,
|
|
accuracy: 55,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Supersonic",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
volatileStatus: "confusion",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
supersonicskystrike: {
|
|
num: 626,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Supersonic Skystrike",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "flyiniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
surf: {
|
|
num: 57,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Surf",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
surgingstrikes: {
|
|
num: 818,
|
|
accuracy: 100,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Surging Strikes",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, punch: 1, mirror: 1 },
|
|
willCrit: true,
|
|
multihit: 3,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 130 }
|
|
},
|
|
swagger: {
|
|
num: 207,
|
|
accuracy: 85,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Swagger",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
volatileStatus: "confusion",
|
|
boosts: {
|
|
atk: 2
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Cute"
|
|
},
|
|
swallow: {
|
|
num: 256,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Swallow",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
onTry(source) {
|
|
return !!source.volatiles["stockpile"];
|
|
},
|
|
onHit(pokemon) {
|
|
const healAmount = [0.25, 0.5, 1];
|
|
const success = !!this.heal(this.modify(pokemon.maxhp, healAmount[pokemon.volatiles["stockpile"].layers - 1]));
|
|
if (!success)
|
|
this.add("-fail", pokemon, "heal");
|
|
pokemon.removeVolatile("stockpile");
|
|
return success || this.NOT_FAIL;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Tough"
|
|
},
|
|
sweetkiss: {
|
|
num: 186,
|
|
accuracy: 75,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sweet Kiss",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
volatileStatus: "confusion",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
sweetscent: {
|
|
num: 230,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Sweet Scent",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
evasion: -2
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: { boost: { accuracy: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
swift: {
|
|
num: 129,
|
|
accuracy: true,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Swift",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
switcheroo: {
|
|
num: 415,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Switcheroo",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, allyanim: 1, noassist: 1, failcopycat: 1 },
|
|
onTryImmunity(target) {
|
|
return !target.hasAbility("stickyhold");
|
|
},
|
|
onHit(target, source, move) {
|
|
const yourItem = target.takeItem(source);
|
|
const myItem = source.takeItem();
|
|
if (target.item || source.item || !yourItem && !myItem) {
|
|
if (yourItem)
|
|
target.item = yourItem.id;
|
|
if (myItem)
|
|
source.item = myItem.id;
|
|
return false;
|
|
}
|
|
if (myItem && !this.singleEvent("TakeItem", myItem, source.itemState, target, source, move, myItem) || yourItem && !this.singleEvent("TakeItem", yourItem, target.itemState, source, target, move, yourItem)) {
|
|
if (yourItem)
|
|
target.item = yourItem.id;
|
|
if (myItem)
|
|
source.item = myItem.id;
|
|
return false;
|
|
}
|
|
this.add("-activate", source, "move: Trick", "[of] " + target);
|
|
if (myItem) {
|
|
target.setItem(myItem);
|
|
this.add("-item", target, myItem, "[from] move: Switcheroo");
|
|
} else {
|
|
this.add("-enditem", target, yourItem, "[silent]", "[from] move: Switcheroo");
|
|
}
|
|
if (yourItem) {
|
|
source.setItem(yourItem);
|
|
this.add("-item", source, yourItem, "[from] move: Switcheroo");
|
|
} else {
|
|
this.add("-enditem", source, myItem, "[silent]", "[from] move: Switcheroo");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { boost: { spe: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
swordsdance: {
|
|
num: 14,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Swords Dance",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1, dance: 1 },
|
|
boosts: {
|
|
atk: 2
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
synchronoise: {
|
|
num: 485,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Synchronoise",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onTryImmunity(target, source) {
|
|
return target.hasType(source.getTypes());
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
synthesis: {
|
|
num: 235,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Synthesis",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
onHit(pokemon) {
|
|
let factor = 0.5;
|
|
switch (pokemon.effectiveWeather()) {
|
|
case "sunnyday":
|
|
case "desolateland":
|
|
factor = 0.667;
|
|
break;
|
|
case "raindance":
|
|
case "primordialsea":
|
|
case "sandstorm":
|
|
case "hail":
|
|
case "snow":
|
|
factor = 0.25;
|
|
break;
|
|
}
|
|
const success = !!this.heal(this.modify(pokemon.maxhp, factor));
|
|
if (!success) {
|
|
this.add("-fail", pokemon, "heal");
|
|
return this.NOT_FAIL;
|
|
}
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Clever"
|
|
},
|
|
tackle: {
|
|
num: 33,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
name: "Tackle",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
tailglow: {
|
|
num: 294,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Tail Glow",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
spa: 3
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
zMove: { effect: "clearnegativeboost" },
|
|
contestType: "Beautiful"
|
|
},
|
|
tailslap: {
|
|
num: 541,
|
|
accuracy: 85,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
name: "Tail Slap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 140 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cute"
|
|
},
|
|
tailwhip: {
|
|
num: 39,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tail Whip",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
def: -1
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
tailwind: {
|
|
num: 366,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tailwind",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { snatch: 1, wind: 1 },
|
|
sideCondition: "tailwind",
|
|
condition: {
|
|
duration: 4,
|
|
durationCallback(target, source, effect) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-activate", source, "ability: Persistent", "[move] Tailwind");
|
|
return 6;
|
|
}
|
|
return 4;
|
|
},
|
|
onSideStart(side, source) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-sidestart", side, "move: Tailwind", "[persistent]");
|
|
} else {
|
|
this.add("-sidestart", side, "move: Tailwind");
|
|
}
|
|
},
|
|
onModifySpe(spe, pokemon) {
|
|
return this.chainModify(2);
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 5,
|
|
onSideEnd(side) {
|
|
this.add("-sideend", side, "move: Tailwind");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Flying",
|
|
zMove: { effect: "crit2" },
|
|
contestType: "Cool"
|
|
},
|
|
takedown: {
|
|
num: 36,
|
|
accuracy: 85,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Take Down",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
recoil: [1, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
takeheart: {
|
|
num: 850,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Take Heart",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
onHit(pokemon) {
|
|
const success = !!this.boost({ spa: 1, spd: 1 });
|
|
return pokemon.cureStatus() || success;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic"
|
|
},
|
|
tarshot: {
|
|
num: 749,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tar Shot",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
volatileStatus: "tarshot",
|
|
condition: {
|
|
onStart(pokemon) {
|
|
this.add("-start", pokemon, "Tar Shot");
|
|
},
|
|
onEffectivenessPriority: -2,
|
|
onEffectiveness(typeMod, target, type, move) {
|
|
if (move.type !== "Fire")
|
|
return;
|
|
if (!target)
|
|
return;
|
|
if (type !== target.getTypes()[0])
|
|
return;
|
|
return typeMod + 1;
|
|
}
|
|
},
|
|
boosts: {
|
|
spe: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Rock"
|
|
},
|
|
taunt: {
|
|
num: 269,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Taunt",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
volatileStatus: "taunt",
|
|
condition: {
|
|
duration: 3,
|
|
onStart(target) {
|
|
if (target.activeTurns && !this.queue.willMove(target)) {
|
|
this.effectState.duration++;
|
|
}
|
|
this.add("-start", target, "move: Taunt");
|
|
},
|
|
onResidualOrder: 15,
|
|
onEnd(target) {
|
|
this.add("-end", target, "move: Taunt");
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
const move = this.dex.moves.get(moveSlot.id);
|
|
if (move.category === "Status" && move.id !== "mefirst") {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
onBeforeMovePriority: 5,
|
|
onBeforeMove(attacker, defender, move) {
|
|
if (!move.isZ && !move.isMax && move.category === "Status" && move.id !== "mefirst") {
|
|
this.add("cant", attacker, "move: Taunt", move);
|
|
return false;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
tearfullook: {
|
|
num: 715,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tearful Look",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { reflectable: 1, mirror: 1 },
|
|
boosts: {
|
|
atk: -1,
|
|
spa: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
teatime: {
|
|
num: 752,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Teatime",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bypasssub: 1 },
|
|
onHitField(target, source, move) {
|
|
const targets = [];
|
|
for (const pokemon of this.getAllActive()) {
|
|
if (this.runEvent("Invulnerability", pokemon, source, move) === false) {
|
|
this.add("-miss", source, pokemon);
|
|
} else if (this.runEvent("TryHit", pokemon, source, move) && pokemon.getItem().isBerry) {
|
|
targets.push(pokemon);
|
|
}
|
|
}
|
|
this.add("-fieldactivate", "move: Teatime");
|
|
if (!targets.length) {
|
|
this.add("-fail", source, "move: Teatime");
|
|
this.attrLastMove("[still]");
|
|
return this.NOT_FAIL;
|
|
}
|
|
for (const pokemon of targets) {
|
|
pokemon.eatItem(true);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Normal"
|
|
},
|
|
technoblast: {
|
|
num: 546,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Techno Blast",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onModifyType(move, pokemon) {
|
|
if (pokemon.ignoringItem())
|
|
return;
|
|
move.type = this.runEvent("Drive", pokemon, null, move, "Normal");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cool"
|
|
},
|
|
tectonicrage: {
|
|
num: 630,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Tectonic Rage",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "groundiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
contestType: "Cool"
|
|
},
|
|
teeterdance: {
|
|
num: 298,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Teeter Dance",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, dance: 1 },
|
|
volatileStatus: "confusion",
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Normal",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
telekinesis: {
|
|
num: 477,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Telekinesis",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, gravity: 1, allyanim: 1 },
|
|
volatileStatus: "telekinesis",
|
|
onTry(source, target, move) {
|
|
if (this.field.getPseudoWeather("Gravity")) {
|
|
this.attrLastMove("[still]");
|
|
this.add("cant", source, "move: Gravity", move);
|
|
return null;
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 3,
|
|
onStart(target) {
|
|
if (["Diglett", "Dugtrio", "Palossand", "Sandygast"].includes(target.baseSpecies.baseSpecies) || target.baseSpecies.name === "Gengar-Mega") {
|
|
this.add("-immune", target);
|
|
return null;
|
|
}
|
|
if (target.volatiles["smackdown"] || target.volatiles["ingrain"])
|
|
return false;
|
|
this.add("-start", target, "Telekinesis");
|
|
},
|
|
onAccuracyPriority: -1,
|
|
onAccuracy(accuracy, target, source, move) {
|
|
if (move && !move.ohko)
|
|
return true;
|
|
},
|
|
onImmunity(type) {
|
|
if (type === "Ground")
|
|
return false;
|
|
},
|
|
onUpdate(pokemon) {
|
|
if (pokemon.baseSpecies.name === "Gengar-Mega") {
|
|
delete pokemon.volatiles["telekinesis"];
|
|
this.add("-end", pokemon, "Telekinesis", "[silent]");
|
|
}
|
|
},
|
|
onResidualOrder: 19,
|
|
onEnd(target) {
|
|
this.add("-end", target, "Telekinesis");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spa: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
teleport: {
|
|
num: 100,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Teleport",
|
|
pp: 20,
|
|
priority: -6,
|
|
flags: {},
|
|
onTry(source) {
|
|
return !!this.canSwitch(source.side);
|
|
},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Cool"
|
|
},
|
|
terablast: {
|
|
num: 851,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Tera Blast",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, mustpressure: 1 },
|
|
onModifyType(move, pokemon, target) {
|
|
if (pokemon.terastallized) {
|
|
move.type = pokemon.teraType;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
if (pokemon.terastallized && pokemon.getStat("atk", false, true) > pokemon.getStat("spa", false, true)) {
|
|
move.category = "Physical";
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal"
|
|
},
|
|
terrainpulse: {
|
|
num: 805,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Terrain Pulse",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, pulse: 1 },
|
|
onModifyType(move, pokemon) {
|
|
if (!pokemon.isGrounded())
|
|
return;
|
|
switch (this.field.terrain) {
|
|
case "electricterrain":
|
|
move.type = "Electric";
|
|
break;
|
|
case "grassyterrain":
|
|
move.type = "Grass";
|
|
break;
|
|
case "mistyterrain":
|
|
move.type = "Fairy";
|
|
break;
|
|
case "psychicterrain":
|
|
move.type = "Psychic";
|
|
break;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
if (this.field.terrain && pokemon.isGrounded()) {
|
|
move.basePower *= 2;
|
|
this.debug("BP doubled in Terrain");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 }
|
|
},
|
|
thief: {
|
|
num: 168,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Thief",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, failmefirst: 1, noassist: 1, failcopycat: 1 },
|
|
onAfterHit(target, source, move) {
|
|
if (source.item || source.volatiles["gem"]) {
|
|
return;
|
|
}
|
|
const yourItem = target.takeItem(source);
|
|
if (!yourItem) {
|
|
return;
|
|
}
|
|
if (!this.singleEvent("TakeItem", yourItem, target.itemState, source, target, move, yourItem) || !source.setItem(yourItem)) {
|
|
target.item = yourItem.id;
|
|
return;
|
|
}
|
|
this.add("-enditem", target, yourItem, "[silent]", "[from] move: Thief", "[of] " + source);
|
|
this.add("-item", source, yourItem, "[from] move: Thief", "[of] " + target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Tough"
|
|
},
|
|
thousandarrows: {
|
|
num: 614,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Thousand Arrows",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
onEffectiveness(typeMod, target, type, move) {
|
|
if (move.type !== "Ground")
|
|
return;
|
|
if (!target)
|
|
return;
|
|
if (!target.runImmunity("Ground")) {
|
|
if (target.hasType("Flying"))
|
|
return 0;
|
|
}
|
|
},
|
|
volatileStatus: "smackdown",
|
|
ignoreImmunity: { "Ground": true },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Ground",
|
|
zMove: { basePower: 180 },
|
|
contestType: "Beautiful"
|
|
},
|
|
thousandwaves: {
|
|
num: 615,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Thousand Waves",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1 },
|
|
onHit(target, source, move) {
|
|
if (source.isActive)
|
|
target.addVolatile("trapped", source, move, "trapper");
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Ground",
|
|
contestType: "Tough"
|
|
},
|
|
thrash: {
|
|
num: 37,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Thrash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, failinstruct: 1 },
|
|
self: {
|
|
volatileStatus: "lockedmove"
|
|
},
|
|
onAfterMove(pokemon) {
|
|
if (pokemon.volatiles["lockedmove"] && pokemon.volatiles["lockedmove"].duration === 1) {
|
|
pokemon.removeVolatile("lockedmove");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
throatchop: {
|
|
num: 675,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Throat Chop",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
condition: {
|
|
duration: 2,
|
|
onStart(target) {
|
|
this.add("-start", target, "Throat Chop", "[silent]");
|
|
},
|
|
onDisableMove(pokemon) {
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
if (this.dex.moves.get(moveSlot.id).flags["sound"]) {
|
|
pokemon.disableMove(moveSlot.id);
|
|
}
|
|
}
|
|
},
|
|
onBeforeMovePriority: 6,
|
|
onBeforeMove(pokemon, target, move) {
|
|
if (!move.isZ && !move.isMax && move.flags["sound"]) {
|
|
this.add("cant", pokemon, "move: Throat Chop");
|
|
return false;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon, target) {
|
|
if (!move.isZ && !move.isMax && move.flags["sound"]) {
|
|
this.add("cant", pokemon, "move: Throat Chop");
|
|
return false;
|
|
}
|
|
},
|
|
onResidualOrder: 22,
|
|
onEnd(target) {
|
|
this.add("-end", target, "Throat Chop", "[silent]");
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target) {
|
|
target.addVolatile("throatchop");
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
contestType: "Clever"
|
|
},
|
|
thunder: {
|
|
num: 87,
|
|
accuracy: 70,
|
|
basePower: 110,
|
|
category: "Special",
|
|
name: "Thunder",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onModifyMove(move, pokemon, target) {
|
|
switch (target?.effectiveWeather()) {
|
|
case "raindance":
|
|
case "primordialsea":
|
|
move.accuracy = true;
|
|
break;
|
|
case "sunnyday":
|
|
case "desolateland":
|
|
move.accuracy = 50;
|
|
break;
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
thunderbolt: {
|
|
num: 85,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Thunderbolt",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
thundercage: {
|
|
num: 819,
|
|
accuracy: 90,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Thunder Cage",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric"
|
|
},
|
|
thunderfang: {
|
|
num: 422,
|
|
accuracy: 95,
|
|
basePower: 65,
|
|
category: "Physical",
|
|
name: "Thunder Fang",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { bite: 1, contact: 1, protect: 1, mirror: 1 },
|
|
secondaries: [
|
|
{
|
|
chance: 10,
|
|
status: "par"
|
|
},
|
|
{
|
|
chance: 10,
|
|
volatileStatus: "flinch"
|
|
}
|
|
],
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
thunderouskick: {
|
|
num: 823,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Thunderous Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fighting"
|
|
},
|
|
thunderpunch: {
|
|
num: 9,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Thunder Punch",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, punch: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
thundershock: {
|
|
num: 84,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Thunder Shock",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 10,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
thunderwave: {
|
|
num: 86,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Thunder Wave",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "par",
|
|
ignoreImmunity: false,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Cool"
|
|
},
|
|
tickle: {
|
|
num: 321,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tickle",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
boosts: {
|
|
atk: -1,
|
|
def: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
tidyup: {
|
|
num: 882,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Tidy Up",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
onHit(pokemon) {
|
|
let success = false;
|
|
for (const active of this.getAllActive()) {
|
|
if (active.removeVolatile("substitute"))
|
|
success = true;
|
|
}
|
|
const removeAll = ["spikes", "toxicspikes", "stealthrock", "stickyweb", "gmaxsteelsurge"];
|
|
const sides = [pokemon.side, ...pokemon.side.foeSidesWithConditions()];
|
|
for (const side of sides) {
|
|
for (const sideCondition of removeAll) {
|
|
if (side.removeSideCondition(sideCondition)) {
|
|
this.add("-sideend", side, this.dex.conditions.get(sideCondition).name);
|
|
success = true;
|
|
}
|
|
}
|
|
}
|
|
if (success)
|
|
this.add("-activate", pokemon, "move: Tidy Up");
|
|
return !!this.boost({ atk: 1, spe: 1 }, pokemon, pokemon, null, false, true) || success;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal"
|
|
},
|
|
topsyturvy: {
|
|
num: 576,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Topsy-Turvy",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
onHit(target) {
|
|
let success = false;
|
|
let i;
|
|
for (i in target.boosts) {
|
|
if (target.boosts[i] === 0)
|
|
continue;
|
|
target.boosts[i] = -target.boosts[i];
|
|
success = true;
|
|
}
|
|
if (!success)
|
|
return false;
|
|
this.add("-invertboost", target, "[from] move: Topsy-Turvy");
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
torchsong: {
|
|
num: 871,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Torch Song",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spa: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
contestType: "Beautiful"
|
|
},
|
|
torment: {
|
|
num: 259,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Torment",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1 },
|
|
volatileStatus: "torment",
|
|
condition: {
|
|
noCopy: true,
|
|
onStart(pokemon, source, effect) {
|
|
if (pokemon.volatiles["dynamax"]) {
|
|
delete pokemon.volatiles["torment"];
|
|
return false;
|
|
}
|
|
if (effect?.id === "gmaxmeltdown")
|
|
this.effectState.duration = 3;
|
|
this.add("-start", pokemon, "Torment");
|
|
},
|
|
onEnd(pokemon) {
|
|
this.add("-end", pokemon, "Torment");
|
|
},
|
|
onDisableMove(pokemon) {
|
|
if (pokemon.lastMove && pokemon.lastMove.id !== "struggle")
|
|
pokemon.disableMove(pokemon.lastMove.id);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
toxic: {
|
|
num: 92,
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Toxic",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
// No Guard-like effect for Poison-type users implemented in Scripts#tryMoveHit
|
|
status: "tox",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
toxicspikes: {
|
|
num: 390,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Toxic Spikes",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { reflectable: 1, nonsky: 1, mustpressure: 1 },
|
|
sideCondition: "toxicspikes",
|
|
condition: {
|
|
// this is a side condition
|
|
onSideStart(side) {
|
|
this.add("-sidestart", side, "move: Toxic Spikes");
|
|
this.effectState.layers = 1;
|
|
},
|
|
onSideRestart(side) {
|
|
if (this.effectState.layers >= 2)
|
|
return false;
|
|
this.add("-sidestart", side, "move: Toxic Spikes");
|
|
this.effectState.layers++;
|
|
},
|
|
onEntryHazard(pokemon) {
|
|
if (!pokemon.isGrounded())
|
|
return;
|
|
if (pokemon.hasType("Poison")) {
|
|
this.add("-sideend", pokemon.side, "move: Toxic Spikes", "[of] " + pokemon);
|
|
pokemon.side.removeSideCondition("toxicspikes");
|
|
} else if (pokemon.hasType("Steel") || pokemon.hasItem("heavydutyboots")) {
|
|
return;
|
|
} else if (this.effectState.layers >= 2) {
|
|
pokemon.trySetStatus("tox", pokemon.side.foe.active[0]);
|
|
} else {
|
|
pokemon.trySetStatus("psn", pokemon.side.foe.active[0]);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Poison",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
toxicthread: {
|
|
num: 672,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Toxic Thread",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "psn",
|
|
boosts: {
|
|
spe: -1
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
trailblaze: {
|
|
num: 885,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Physical",
|
|
name: "Trailblaze",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
transform: {
|
|
num: 144,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Transform",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { allyanim: 1, failencore: 1, noassist: 1, failcopycat: 1, failinstruct: 1, failmimic: 1 },
|
|
onHit(target, pokemon) {
|
|
if (!pokemon.transformInto(target)) {
|
|
return false;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { effect: "heal" },
|
|
contestType: "Clever"
|
|
},
|
|
triattack: {
|
|
num: 161,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
name: "Tri Attack",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
onHit(target, source) {
|
|
const result = this.random(3);
|
|
if (result === 0) {
|
|
target.trySetStatus("brn", source);
|
|
} else if (result === 1) {
|
|
target.trySetStatus("par", source);
|
|
} else {
|
|
target.trySetStatus("frz", source);
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Beautiful"
|
|
},
|
|
trick: {
|
|
num: 271,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Trick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, allyanim: 1, noassist: 1, failcopycat: 1 },
|
|
onTryImmunity(target) {
|
|
return !target.hasAbility("stickyhold");
|
|
},
|
|
onHit(target, source, move) {
|
|
const yourItem = target.takeItem(source);
|
|
const myItem = source.takeItem();
|
|
if (target.item || source.item || !yourItem && !myItem) {
|
|
if (yourItem)
|
|
target.item = yourItem.id;
|
|
if (myItem)
|
|
source.item = myItem.id;
|
|
return false;
|
|
}
|
|
if (myItem && !this.singleEvent("TakeItem", myItem, source.itemState, target, source, move, myItem) || yourItem && !this.singleEvent("TakeItem", yourItem, target.itemState, source, target, move, yourItem)) {
|
|
if (yourItem)
|
|
target.item = yourItem.id;
|
|
if (myItem)
|
|
source.item = myItem.id;
|
|
return false;
|
|
}
|
|
this.add("-activate", source, "move: Trick", "[of] " + target);
|
|
if (myItem) {
|
|
target.setItem(myItem);
|
|
this.add("-item", target, myItem, "[from] move: Trick");
|
|
} else {
|
|
this.add("-enditem", target, yourItem, "[silent]", "[from] move: Trick");
|
|
}
|
|
if (yourItem) {
|
|
source.setItem(yourItem);
|
|
this.add("-item", source, yourItem, "[from] move: Trick");
|
|
} else {
|
|
this.add("-enditem", source, myItem, "[silent]", "[from] move: Trick");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
zMove: { boost: { spe: 2 } },
|
|
contestType: "Clever"
|
|
},
|
|
trickortreat: {
|
|
num: 567,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Trick-or-Treat",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
onHit(target) {
|
|
if (target.hasType("Ghost"))
|
|
return false;
|
|
if (!target.addType("Ghost"))
|
|
return false;
|
|
this.add("-start", target, "typeadd", "Ghost", "[from] move: Trick-or-Treat");
|
|
if (target.side.active.length === 2 && target.position === 1) {
|
|
const action = this.queue.willMove(target);
|
|
if (action && action.move.id === "curse") {
|
|
action.targetLoc = -1;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
zMove: { boost: { atk: 1, def: 1, spa: 1, spd: 1, spe: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
trickroom: {
|
|
num: 433,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Trick Room",
|
|
pp: 5,
|
|
priority: -7,
|
|
flags: { mirror: 1 },
|
|
pseudoWeather: "trickroom",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-activate", source, "ability: Persistent", "[move] Trick Room");
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onFieldStart(target, source) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-fieldstart", "move: Trick Room", "[of] " + source, "[persistent]");
|
|
} else {
|
|
this.add("-fieldstart", "move: Trick Room", "[of] " + source);
|
|
}
|
|
},
|
|
onFieldRestart(target, source) {
|
|
this.field.removePseudoWeather("trickroom");
|
|
},
|
|
// Speed modification is changed in Pokemon.getActionSpeed() in sim/pokemon.js
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 1,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "move: Trick Room");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: { boost: { accuracy: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
triplearrows: {
|
|
num: 843,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Triple Arrows",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
critRatio: 2,
|
|
secondaries: [
|
|
{
|
|
chance: 50,
|
|
boosts: {
|
|
def: -1
|
|
}
|
|
},
|
|
{
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
}
|
|
],
|
|
target: "normal",
|
|
type: "Fighting"
|
|
},
|
|
tripleaxel: {
|
|
num: 813,
|
|
accuracy: 90,
|
|
basePower: 20,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return 20 * move.hit;
|
|
},
|
|
category: "Physical",
|
|
name: "Triple Axel",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: 3,
|
|
multiaccuracy: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
zMove: { basePower: 120 },
|
|
maxMove: { basePower: 140 }
|
|
},
|
|
tripledive: {
|
|
num: 865,
|
|
accuracy: 95,
|
|
basePower: 30,
|
|
category: "Physical",
|
|
name: "Triple Dive",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: 3,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water"
|
|
},
|
|
triplekick: {
|
|
num: 167,
|
|
accuracy: 90,
|
|
basePower: 10,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return 10 * move.hit;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Triple Kick",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
multihit: 3,
|
|
multiaccuracy: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
zMove: { basePower: 120 },
|
|
maxMove: { basePower: 80 },
|
|
contestType: "Cool"
|
|
},
|
|
tropkick: {
|
|
num: 688,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "Trop Kick",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
boosts: {
|
|
atk: -1
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cute"
|
|
},
|
|
trumpcard: {
|
|
num: 376,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
basePowerCallback(source, target, move) {
|
|
const callerMoveId = move.sourceEffect || move.id;
|
|
const moveSlot = callerMoveId === "instruct" ? source.getMoveData(move.id) : source.getMoveData(callerMoveId);
|
|
let bp;
|
|
if (!moveSlot) {
|
|
bp = 40;
|
|
} else {
|
|
switch (moveSlot.pp) {
|
|
case 0:
|
|
bp = 200;
|
|
break;
|
|
case 1:
|
|
bp = 80;
|
|
break;
|
|
case 2:
|
|
bp = 60;
|
|
break;
|
|
case 3:
|
|
bp = 50;
|
|
break;
|
|
default:
|
|
bp = 40;
|
|
break;
|
|
}
|
|
}
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Trump Card",
|
|
pp: 5,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Cool"
|
|
},
|
|
twinbeam: {
|
|
num: 888,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Twin Beam",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
multihit: 2,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Cool"
|
|
},
|
|
twineedle: {
|
|
num: 41,
|
|
accuracy: 100,
|
|
basePower: 25,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Twineedle",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
multihit: 2,
|
|
secondary: {
|
|
chance: 20,
|
|
status: "psn"
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
maxMove: { basePower: 100 },
|
|
contestType: "Cool"
|
|
},
|
|
twinkletackle: {
|
|
num: 656,
|
|
accuracy: true,
|
|
basePower: 1,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Twinkle Tackle",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
isZ: "fairiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
contestType: "Cool"
|
|
},
|
|
twister: {
|
|
num: 239,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Twister",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Dragon",
|
|
contestType: "Cool"
|
|
},
|
|
uturn: {
|
|
num: 369,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
name: "U-turn",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cute"
|
|
},
|
|
uproar: {
|
|
num: 253,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
name: "Uproar",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1, nosleeptalk: 1, failinstruct: 1 },
|
|
self: {
|
|
volatileStatus: "uproar"
|
|
},
|
|
onTryHit(target) {
|
|
const activeTeam = target.side.activeTeam();
|
|
const foeActiveTeam = target.side.foe.activeTeam();
|
|
for (const [i, allyActive] of activeTeam.entries()) {
|
|
if (allyActive && allyActive.status === "slp")
|
|
allyActive.cureStatus();
|
|
const foeActive = foeActiveTeam[i];
|
|
if (foeActive && foeActive.status === "slp")
|
|
foeActive.cureStatus();
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 3,
|
|
onStart(target) {
|
|
this.add("-start", target, "Uproar");
|
|
},
|
|
onResidual(target) {
|
|
if (target.volatiles["throatchop"]) {
|
|
target.removeVolatile("uproar");
|
|
return;
|
|
}
|
|
if (target.lastMove && target.lastMove.id === "struggle") {
|
|
delete target.volatiles["uproar"];
|
|
}
|
|
this.add("-start", target, "Uproar", "[upkeep]");
|
|
},
|
|
onResidualOrder: 28,
|
|
onResidualSubOrder: 1,
|
|
onEnd(target) {
|
|
this.add("-end", target, "Uproar");
|
|
},
|
|
onLockMove: "uproar",
|
|
onAnySetStatus(status, pokemon) {
|
|
if (status.id === "slp") {
|
|
if (pokemon === this.effectState.target) {
|
|
this.add("-fail", pokemon, "slp", "[from] Uproar", "[msg]");
|
|
} else {
|
|
this.add("-fail", pokemon, "slp", "[from] Uproar");
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "randomNormal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
vacuumwave: {
|
|
num: 410,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Vacuum Wave",
|
|
pp: 30,
|
|
priority: 1,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
vcreate: {
|
|
num: 557,
|
|
accuracy: 95,
|
|
basePower: 180,
|
|
category: "Physical",
|
|
name: "V-create",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
self: {
|
|
boosts: {
|
|
spe: -1,
|
|
def: -1,
|
|
spd: -1
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
zMove: { basePower: 220 },
|
|
contestType: "Cool"
|
|
},
|
|
veeveevolley: {
|
|
num: 741,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon) {
|
|
const bp = Math.floor(pokemon.happiness * 10 / 25) || 1;
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Veevee Volley",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Cute"
|
|
},
|
|
venomdrench: {
|
|
num: 599,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Venom Drench",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
onHit(target, source, move) {
|
|
if (target.status === "psn" || target.status === "tox") {
|
|
return !!this.boost({ atk: -1, spa: -1, spe: -1 }, target, source, move);
|
|
}
|
|
return false;
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Poison",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
venoshock: {
|
|
num: 474,
|
|
accuracy: 100,
|
|
basePower: 65,
|
|
category: "Special",
|
|
name: "Venoshock",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
onBasePower(basePower, pokemon, target) {
|
|
if (target.status === "psn" || target.status === "tox") {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
contestType: "Beautiful"
|
|
},
|
|
victorydance: {
|
|
num: 837,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Victory Dance",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, dance: 1 },
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spe: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fighting"
|
|
},
|
|
vinewhip: {
|
|
num: 22,
|
|
accuracy: 100,
|
|
basePower: 45,
|
|
category: "Physical",
|
|
name: "Vine Whip",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Cool"
|
|
},
|
|
visegrip: {
|
|
num: 11,
|
|
accuracy: 100,
|
|
basePower: 55,
|
|
category: "Physical",
|
|
name: "Vise Grip",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
vitalthrow: {
|
|
num: 233,
|
|
accuracy: true,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Vital Throw",
|
|
pp: 10,
|
|
priority: -1,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Cool"
|
|
},
|
|
voltswitch: {
|
|
num: 521,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
name: "Volt Switch",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
volttackle: {
|
|
num: 344,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Volt Tackle",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
recoil: [33, 100],
|
|
secondary: {
|
|
chance: 10,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
wakeupslap: {
|
|
num: 358,
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.status === "slp" || target.hasAbility("comatose")) {
|
|
this.debug("BP doubled on sleeping target");
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
isNonstandard: "Past",
|
|
name: "Wake-Up Slap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
onHit(target) {
|
|
if (target.status === "slp")
|
|
target.cureStatus();
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
contestType: "Tough"
|
|
},
|
|
waterfall: {
|
|
num: 127,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Waterfall",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Tough"
|
|
},
|
|
watergun: {
|
|
num: 55,
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Special",
|
|
name: "Water Gun",
|
|
pp: 25,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cute"
|
|
},
|
|
waterpledge: {
|
|
num: 518,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
basePowerCallback(target, source, move) {
|
|
if (["firepledge", "grasspledge"].includes(move.sourceEffect)) {
|
|
this.add("-combine");
|
|
return 150;
|
|
}
|
|
return 80;
|
|
},
|
|
category: "Special",
|
|
name: "Water Pledge",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, nonsky: 1, pledgecombo: 1 },
|
|
onPrepareHit(target, source, move) {
|
|
for (const action of this.queue) {
|
|
if (action.choice !== "move")
|
|
continue;
|
|
const otherMove = action.move;
|
|
const otherMoveUser = action.pokemon;
|
|
if (!otherMove || !action.pokemon || !otherMoveUser.isActive || otherMoveUser.fainted || action.maxMove || action.zmove) {
|
|
continue;
|
|
}
|
|
if (otherMoveUser.isAlly(source) && ["firepledge", "grasspledge"].includes(otherMove.id)) {
|
|
this.queue.prioritizeAction(action, move);
|
|
this.add("-waiting", source, otherMoveUser);
|
|
return null;
|
|
}
|
|
}
|
|
},
|
|
onModifyMove(move) {
|
|
if (move.sourceEffect === "grasspledge") {
|
|
move.type = "Grass";
|
|
move.forceSTAB = true;
|
|
move.sideCondition = "grasspledge";
|
|
}
|
|
if (move.sourceEffect === "firepledge") {
|
|
move.type = "Water";
|
|
move.forceSTAB = true;
|
|
move.self = { sideCondition: "waterpledge" };
|
|
}
|
|
},
|
|
condition: {
|
|
duration: 4,
|
|
onSideStart(targetSide) {
|
|
this.add("-sidestart", targetSide, "Water Pledge");
|
|
},
|
|
onSideResidualOrder: 26,
|
|
onSideResidualSubOrder: 7,
|
|
onSideEnd(targetSide) {
|
|
this.add("-sideend", targetSide, "Water Pledge");
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
if (move.secondaries && move.id !== "secretpower") {
|
|
this.debug("doubling secondary chance");
|
|
for (const secondary of move.secondaries) {
|
|
if (pokemon.hasAbility("serenegrace") && secondary.volatileStatus === "flinch")
|
|
continue;
|
|
if (secondary.chance)
|
|
secondary.chance *= 2;
|
|
}
|
|
if (move.self?.chance)
|
|
move.self.chance *= 2;
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
waterpulse: {
|
|
num: 352,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Special",
|
|
name: "Water Pulse",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { protect: 1, pulse: 1, mirror: 1, distance: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "confusion"
|
|
},
|
|
target: "any",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
watershuriken: {
|
|
num: 594,
|
|
accuracy: 100,
|
|
basePower: 15,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (pokemon.species.name === "Greninja-Ash" && pokemon.hasAbility("battlebond") && !pokemon.transformed) {
|
|
return move.basePower + 5;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Special",
|
|
name: "Water Shuriken",
|
|
pp: 20,
|
|
priority: 1,
|
|
flags: { protect: 1, mirror: 1 },
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Cool"
|
|
},
|
|
watersport: {
|
|
num: 346,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Past",
|
|
name: "Water Sport",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { nonsky: 1 },
|
|
pseudoWeather: "watersport",
|
|
condition: {
|
|
duration: 5,
|
|
onFieldStart(field, source) {
|
|
this.add("-fieldstart", "move: Water Sport", "[of] " + source);
|
|
},
|
|
onBasePowerPriority: 1,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === "Fire") {
|
|
this.debug("water sport weaken");
|
|
return this.chainModify([1352, 4096]);
|
|
}
|
|
},
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 3,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "move: Water Sport");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Water",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
waterspout: {
|
|
num: 323,
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const bp = move.basePower * pokemon.hp / pokemon.maxhp;
|
|
this.debug("BP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
name: "Water Spout",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
wavecrash: {
|
|
num: 834,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Wave Crash",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
recoil: [33, 100],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water"
|
|
},
|
|
weatherball: {
|
|
num: 311,
|
|
accuracy: 100,
|
|
basePower: 50,
|
|
category: "Special",
|
|
name: "Weather Ball",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
onModifyType(move, pokemon) {
|
|
switch (pokemon.effectiveWeather()) {
|
|
case "sunnyday":
|
|
case "desolateland":
|
|
move.type = "Fire";
|
|
break;
|
|
case "raindance":
|
|
case "primordialsea":
|
|
move.type = "Water";
|
|
break;
|
|
case "sandstorm":
|
|
move.type = "Rock";
|
|
break;
|
|
case "hail":
|
|
case "snow":
|
|
move.type = "Ice";
|
|
break;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
switch (pokemon.effectiveWeather()) {
|
|
case "sunnyday":
|
|
case "desolateland":
|
|
move.basePower *= 2;
|
|
break;
|
|
case "raindance":
|
|
case "primordialsea":
|
|
move.basePower *= 2;
|
|
break;
|
|
case "sandstorm":
|
|
move.basePower *= 2;
|
|
break;
|
|
case "hail":
|
|
case "snow":
|
|
move.basePower *= 2;
|
|
break;
|
|
}
|
|
this.debug("BP: " + move.basePower);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 160 },
|
|
maxMove: { basePower: 130 },
|
|
contestType: "Beautiful"
|
|
},
|
|
whirlpool: {
|
|
num: 250,
|
|
accuracy: 85,
|
|
basePower: 35,
|
|
category: "Special",
|
|
name: "Whirlpool",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
contestType: "Beautiful"
|
|
},
|
|
whirlwind: {
|
|
num: 18,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Whirlwind",
|
|
pp: 20,
|
|
priority: -6,
|
|
flags: { reflectable: 1, mirror: 1, bypasssub: 1, allyanim: 1, wind: 1, noassist: 1, failcopycat: 1 },
|
|
forceSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
wickedblow: {
|
|
num: 817,
|
|
accuracy: 100,
|
|
basePower: 75,
|
|
category: "Physical",
|
|
name: "Wicked Blow",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, punch: 1, mirror: 1 },
|
|
willCrit: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark"
|
|
},
|
|
wickedtorque: {
|
|
num: 897,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Wicked Torque",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {
|
|
protect: 1,
|
|
failencore: 1,
|
|
failmefirst: 1,
|
|
nosleeptalk: 1,
|
|
noassist: 1,
|
|
failcopycat: 1,
|
|
failinstruct: 1,
|
|
failmimic: 1
|
|
},
|
|
secondary: {
|
|
chance: 10,
|
|
status: "slp"
|
|
},
|
|
target: "normal",
|
|
type: "Dark"
|
|
},
|
|
wideguard: {
|
|
num: 469,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Wide Guard",
|
|
pp: 10,
|
|
priority: 3,
|
|
flags: { snatch: 1 },
|
|
sideCondition: "wideguard",
|
|
onTry() {
|
|
return !!this.queue.willAct();
|
|
},
|
|
onHitSide(side, source) {
|
|
source.addVolatile("stall");
|
|
},
|
|
condition: {
|
|
duration: 1,
|
|
onSideStart(target, source) {
|
|
this.add("-singleturn", source, "Wide Guard");
|
|
},
|
|
onTryHitPriority: 4,
|
|
onTryHit(target, source, move) {
|
|
if (move?.target !== "allAdjacent" && move.target !== "allAdjacentFoes") {
|
|
return;
|
|
}
|
|
if (move.isZ || move.isMax) {
|
|
if (["gmaxoneblow", "gmaxrapidflow"].includes(move.id))
|
|
return;
|
|
target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
this.add("-activate", target, "move: Wide Guard");
|
|
const lockedmove = source.getVolatile("lockedmove");
|
|
if (lockedmove) {
|
|
if (source.volatiles["lockedmove"].duration === 2) {
|
|
delete source.volatiles["lockedmove"];
|
|
}
|
|
}
|
|
return this.NOT_FAIL;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "allySide",
|
|
type: "Rock",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
wildboltstorm: {
|
|
num: 847,
|
|
accuracy: 80,
|
|
basePower: 100,
|
|
category: "Special",
|
|
isNonstandard: "Unobtainable",
|
|
name: "Wildbolt Storm",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, mirror: 1, wind: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
status: "par"
|
|
},
|
|
target: "allAdjacentFoes",
|
|
type: "Electric"
|
|
},
|
|
wildcharge: {
|
|
num: 528,
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
name: "Wild Charge",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
recoil: [1, 4],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Tough"
|
|
},
|
|
willowisp: {
|
|
num: 261,
|
|
accuracy: 85,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Will-O-Wisp",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
status: "brn",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Beautiful"
|
|
},
|
|
wingattack: {
|
|
num: 17,
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
name: "Wing Attack",
|
|
pp: 35,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, distance: 1 },
|
|
secondary: null,
|
|
target: "any",
|
|
type: "Flying",
|
|
contestType: "Cool"
|
|
},
|
|
wish: {
|
|
num: 273,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Wish",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { snatch: 1, heal: 1 },
|
|
slotCondition: "Wish",
|
|
condition: {
|
|
duration: 2,
|
|
onStart(pokemon, source) {
|
|
this.effectState.hp = source.maxhp / 2;
|
|
},
|
|
onResidualOrder: 4,
|
|
onEnd(target) {
|
|
if (target && !target.fainted) {
|
|
const damage = this.heal(this.effectState.hp, target, target);
|
|
if (damage) {
|
|
this.add("-heal", target, target.getHealth, "[from] move: Wish", "[wisher] " + this.effectState.source.name);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
withdraw: {
|
|
num: 110,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Withdraw",
|
|
pp: 40,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
def: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Water",
|
|
zMove: { boost: { def: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
wonderroom: {
|
|
num: 472,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Wonder Room",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { mirror: 1 },
|
|
pseudoWeather: "wonderroom",
|
|
condition: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-activate", source, "ability: Persistent", "[move] Wonder Room");
|
|
return 7;
|
|
}
|
|
return 5;
|
|
},
|
|
onModifyMove(move, source, target) {
|
|
if (!move.overrideOffensiveStat)
|
|
return;
|
|
const statAndBoosts = move.overrideOffensiveStat;
|
|
if (!["def", "spd"].includes(statAndBoosts))
|
|
return;
|
|
move.overrideOffensiveStat = statAndBoosts === "def" ? "spd" : "def";
|
|
this.hint(`${move.name} uses ${statAndBoosts === "def" ? "" : "Sp. "}Def boosts when Wonder Room is active.`);
|
|
},
|
|
onFieldStart(field, source) {
|
|
if (source?.hasAbility("persistent")) {
|
|
this.add("-fieldstart", "move: Wonder Room", "[of] " + source, "[persistent]");
|
|
} else {
|
|
this.add("-fieldstart", "move: Wonder Room", "[of] " + source);
|
|
}
|
|
},
|
|
onFieldRestart(target, source) {
|
|
this.field.removePseudoWeather("wonderroom");
|
|
},
|
|
// Swapping defenses partially implemented in sim/pokemon.js:Pokemon#calculateStat and Pokemon#getStat
|
|
onFieldResidualOrder: 27,
|
|
onFieldResidualSubOrder: 5,
|
|
onFieldEnd() {
|
|
this.add("-fieldend", "move: Wonder Room");
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
zMove: { boost: { spd: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
woodhammer: {
|
|
num: 452,
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
name: "Wood Hammer",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
recoil: [33, 100],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
contestType: "Tough"
|
|
},
|
|
workup: {
|
|
num: 526,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Work Up",
|
|
pp: 30,
|
|
priority: 0,
|
|
flags: { snatch: 1 },
|
|
boosts: {
|
|
atk: 1,
|
|
spa: 1
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
zMove: { boost: { atk: 1 } },
|
|
contestType: "Tough"
|
|
},
|
|
worryseed: {
|
|
num: 388,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Worry Seed",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1, allyanim: 1 },
|
|
onTryImmunity(target) {
|
|
if (target.ability === "truant" || target.ability === "insomnia") {
|
|
return false;
|
|
}
|
|
},
|
|
onTryHit(target) {
|
|
if (target.getAbility().isPermanent) {
|
|
return false;
|
|
}
|
|
},
|
|
onHit(pokemon) {
|
|
const oldAbility = pokemon.setAbility("insomnia");
|
|
if (oldAbility) {
|
|
this.add("-ability", pokemon, "Insomnia", "[from] move: Worry Seed");
|
|
if (pokemon.status === "slp") {
|
|
pokemon.cureStatus();
|
|
}
|
|
return;
|
|
}
|
|
return oldAbility;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Clever"
|
|
},
|
|
wrap: {
|
|
num: 35,
|
|
accuracy: 90,
|
|
basePower: 15,
|
|
category: "Physical",
|
|
name: "Wrap",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
volatileStatus: "partiallytrapped",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
contestType: "Tough"
|
|
},
|
|
wringout: {
|
|
num: 378,
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target, move) {
|
|
const hp = target.hp;
|
|
const maxHP = target.maxhp;
|
|
const bp = Math.floor(Math.floor((120 * (100 * Math.floor(hp * 4096 / maxHP)) + 2048 - 1) / 4096) / 100) || 1;
|
|
this.debug("BP for " + hp + "/" + maxHP + " HP: " + bp);
|
|
return bp;
|
|
},
|
|
category: "Special",
|
|
isNonstandard: "Past",
|
|
name: "Wring Out",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { basePower: 190 },
|
|
maxMove: { basePower: 140 },
|
|
contestType: "Tough"
|
|
},
|
|
xscissor: {
|
|
num: 404,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "X-Scissor",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1, slicing: 1 },
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
contestType: "Cool"
|
|
},
|
|
yawn: {
|
|
num: 281,
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
name: "Yawn",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { protect: 1, reflectable: 1, mirror: 1 },
|
|
volatileStatus: "yawn",
|
|
onTryHit(target) {
|
|
if (target.status || !target.runStatusImmunity("slp")) {
|
|
return false;
|
|
}
|
|
},
|
|
condition: {
|
|
noCopy: true,
|
|
// doesn't get copied by Baton Pass
|
|
duration: 2,
|
|
onStart(target, source) {
|
|
this.add("-start", target, "move: Yawn", "[of] " + source);
|
|
},
|
|
onResidualOrder: 23,
|
|
onEnd(target) {
|
|
this.add("-end", target, "move: Yawn", "[silent]");
|
|
target.trySetStatus("slp", this.effectState.source);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMove: { boost: { spe: 1 } },
|
|
contestType: "Cute"
|
|
},
|
|
zapcannon: {
|
|
num: 192,
|
|
accuracy: 50,
|
|
basePower: 120,
|
|
category: "Special",
|
|
name: "Zap Cannon",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: { bullet: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
status: "par"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
zenheadbutt: {
|
|
num: 428,
|
|
accuracy: 90,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Zen Headbutt",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Psychic",
|
|
contestType: "Clever"
|
|
},
|
|
zingzap: {
|
|
num: 716,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
name: "Zing Zap",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: "flinch"
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
},
|
|
zippyzap: {
|
|
num: 729,
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
isNonstandard: "LGPE",
|
|
name: "Zippy Zap",
|
|
pp: 10,
|
|
priority: 2,
|
|
flags: { contact: 1, protect: 1, mirror: 1 },
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
evasion: 1
|
|
}
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
contestType: "Cool"
|
|
}
|
|
};
|
|
//# sourceMappingURL=moves.js.map
|