mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-05-21 14:59:50 -05:00
4887 lines
154 KiB
JavaScript
4887 lines
154 KiB
JavaScript
'use strict';
|
|
|
|
// Used for Asheviere and Snaquaza's move
|
|
const RandomStaffBrosTeams = require('./random-teams');
|
|
/** @type {typeof import('../../../sim/pokemon').Pokemon} */
|
|
const Pokemon = require(/** @type {any} */ ('../../../.sim-dist/pokemon')).Pokemon;
|
|
|
|
/** @type {{[k: string]: ModdedMoveData}} */
|
|
let BattleMovedex = {
|
|
/*
|
|
// Example
|
|
"moveid": {
|
|
accuracy: 100, // a number or true for always hits
|
|
basePower: 100, // Not used for Status moves, base power of the move, number
|
|
category: "Physical", // "Physical", "Special", or "Status"
|
|
desc: "", // long description
|
|
shortDesc: "", // short description, shows up in /dt
|
|
id: "moveid",
|
|
name: "Move Name",
|
|
pp: 10, // unboosted PP count
|
|
priority: 0, // move priority, -6 -> 6
|
|
flags: {}, // Move flags https://github.com/Zarel/Pokemon-Showdown/blob/master/data/moves.js#L1-L27
|
|
secondary: {
|
|
status: "tox",
|
|
chance: 20,
|
|
}, // secondary, set to null to not use one. Exact usage varies, check data/moves.js for examples
|
|
target: "normal", // What does this move hit?
|
|
// normal = the targeted foe, self = the user, allySide = your side (eg light screen), foeSide = the foe's side (eg spikes), all = the field (eg raindance). More can be found in data/moves.js
|
|
type: "Water", // The move's type
|
|
// Other useful things
|
|
noPPBoosts: true, // add this to not boost the PP of a move, not needed for Z moves, dont include it otherwise
|
|
isZ: "crystalname", // marks a move as a z move, list the crystal name inside
|
|
zMoveEffect: '', // for status moves, what happens when this is used as a Z move? check data/moves.js for examples
|
|
zMoveBoost: {atk: 2}, // for status moves, stat boost given when used as a z move
|
|
critRatio: 2, // The higher the number (above 1) the higher the ratio, lowering it lowers the crit ratio
|
|
drain: [1, 2], // recover first num / second num % of the damage dealt
|
|
heal: [1, 2], // recover first num / second num % of the target's HP
|
|
},
|
|
*/
|
|
// Please keep sets organized alphabetically based on staff member name!
|
|
// 2xTheTap
|
|
noblehowl: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Raises the user's Attack by two stages and cures the user of burns, paralysis, and poison. Removes Reflect, Light Screen, Aurora Veil, Safeguard, and Mist from the opponent's side and removes Spikes, Toxic Spikes, Stealth Rock, and Sticky Web from both sides.",
|
|
shortDesc: "Raises Attack by 2, clears hazards/user status.",
|
|
id: "noblehowl",
|
|
name: "Noble Howl",
|
|
isNonstandard: "Custom",
|
|
pp: 3,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Howl', source);
|
|
this.add('-anim', source, 'Boomburst', source);
|
|
},
|
|
onHit(target, source, move) {
|
|
this.boost({atk: 2}, source, source, this.dex.getActiveMove('Noble Howl'));
|
|
if (!(['', 'slp', 'frz'].includes(source.status))) {
|
|
source.cureStatus();
|
|
}
|
|
let removeTarget = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb'];
|
|
let removeAll = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb'];
|
|
for (const targetCondition of removeTarget) {
|
|
if (target.side.removeSideCondition(targetCondition)) {
|
|
if (!removeAll.includes(targetCondition)) continue;
|
|
this.add('-sideend', target.side, this.dex.getEffect(targetCondition).name, '[from] move: Noble Howl', '[of] ' + target);
|
|
}
|
|
}
|
|
for (const sideCondition of removeAll) {
|
|
if (source.side.removeSideCondition(sideCondition)) {
|
|
this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Noble Howl', '[of] ' + source);
|
|
}
|
|
}
|
|
},
|
|
flags: {mirror: 1, snatch: 1, authentic: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
},
|
|
// 5gen
|
|
toomuchsaws: {
|
|
accuracy: 100,
|
|
basePower: 85,
|
|
basePowerCallback(pokemon, target, move) {
|
|
if (target.newlySwitched) {
|
|
return move.basePower * 2;
|
|
}
|
|
return move.basePower;
|
|
},
|
|
category: "Physical",
|
|
desc: "Base Power doubles if the foe switches out the turn this move is used.",
|
|
shortDesc: "Power doubles if foe switches out.",
|
|
id: "toomuchsaws",
|
|
name: "Too Much Saws",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Headbutt', target);
|
|
},
|
|
flags: {protect: 1, mirror: 1, contact: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
// Aelita
|
|
energyfield: {
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Special",
|
|
desc: "Has a 40% chance to paralyze the target. Lowers the user's Special Attack, Special Defense, and Speed by one stage.",
|
|
shortDesc: "40% to paralyze. Lowers user's SpA, SpD, Spe.",
|
|
id: "energyfield",
|
|
name: "Energy Field",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Electro Ball", target);
|
|
this.add('-anim', source, "Ion Deluge", target);
|
|
},
|
|
self: {boosts: {spa: -1, spd: -1, spe: -1}},
|
|
secondary: {
|
|
chance: 40,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
zMovePower: 200,
|
|
},
|
|
// Aeonic
|
|
shitpost: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
desc: "50% chance to OHKO the user, 50% chance to OHKO the target.",
|
|
shortDesc: "OHKOs user or target (50% chance each).",
|
|
id: "shitpost",
|
|
name: "Shitpost",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Skill Swap", target);
|
|
},
|
|
onHit(target, source) {
|
|
let koed;
|
|
if (Math.round(this.random())) {
|
|
koed = target;
|
|
this.add(`c|%Aeonic|What a buncha jokers`);
|
|
} else {
|
|
koed = source;
|
|
this.add(`c|%Aeonic|haha yeah`);
|
|
}
|
|
|
|
this.add('-anim', koed, "Explosion", koed);
|
|
koed.faint();
|
|
},
|
|
isZ: "noseiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "???",
|
|
},
|
|
// Aethernum
|
|
cataclysm: {
|
|
accuracy: 90,
|
|
basePower: 140,
|
|
category: "Physical",
|
|
desc: "After dealing damage, resets all of the user's boosts to 0, then Attack, Defense, and Speed get lowered by one stage.",
|
|
shortDesc: "Clears user's boosts; lowers Atk, Def and Spe.",
|
|
id: "cataclysm",
|
|
name: "Cataclysm",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Earth Power", target);
|
|
this.add('-anim', source, "Continental Crush", target);
|
|
this.add('-anim', source, "Giga Impact", target);
|
|
},
|
|
onAfterMoveSecondarySelf(pokemon) {
|
|
pokemon.clearBoosts();
|
|
this.add('-clearboost', pokemon);
|
|
this.boost({atk: -1, def: -1, spe: -1}, pokemon, pokemon, this.dex.getActiveMove('Cataclysm'));
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
},
|
|
// Akiamara
|
|
x1: {
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
desc: "This move becomes a physical attack if the user's Attack is greater than its Special Attack, including stat stage changes. This move and its effects ignore the abilities and stat changes of other Pokemon.",
|
|
shortDesc: "Phys if Atk > SpA; ignores boosts, abilities.",
|
|
id: "x1",
|
|
isNonstandard: "Custom",
|
|
name: "x1",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
if (pokemon.getStat('atk', false, true) > pokemon.getStat('spa', false, true)) move.category = 'Physical';
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Focus Punch', target);
|
|
},
|
|
ignoreAbility: true,
|
|
ignoreEvasion: true,
|
|
ignoreDefensive: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
},
|
|
// Akir
|
|
compost: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user recovers half its HP. If any Pokemon fainted the previous turn, this move heals the active Pokemon by 50% of the user's HP on the following turn. Cures the user's party of all status conditions.",
|
|
shortDesc: "Heal 50%, Heal Bell; any fainted: Wish.",
|
|
id: "compost",
|
|
name: "Compost",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Ingrain", target);
|
|
},
|
|
onHit(target, source) {
|
|
let didSomething = false;
|
|
let side = source.side;
|
|
if (side.faintedLastTurn || side.foe.faintedLastTurn) {
|
|
this.add('-anim', source, "Wish", target);
|
|
side.addSlotCondition(source, 'wish', source);
|
|
this.add('-message', `${source.name} made a wish!`);
|
|
didSomething = true;
|
|
}
|
|
for (const ally of side.pokemon) {
|
|
if (ally.cureStatus()) didSomething = true;
|
|
}
|
|
if (this.heal(source.maxhp / 2, source)) didSomething = true;
|
|
return didSomething;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ghost",
|
|
},
|
|
// Alpha
|
|
nekoveil: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user sets up Light Screen, Reflect, and Sunny Day for 5 turns. The effects of Light Screen and reflect are extended to 8 turns if the user is holding Light Clay, and Sunny Day remains for 8 turns if the user is holding a Heat Rock.",
|
|
shortDesc: "Light Screen, Reflect, and Sunny Day for 5 turns.",
|
|
id: "nekoveil",
|
|
name: "Neko Veil",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
flags: {snatch: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Geomancy", source);
|
|
},
|
|
onHit(target, source) {
|
|
source.side.addSideCondition('lightscreen', source);
|
|
source.side.addSideCondition('reflect', source);
|
|
},
|
|
weather: 'sunnyday',
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Psychic",
|
|
},
|
|
// Andrew
|
|
backoffgrrr: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user is protected from most moves made by other Pokemon during this turn, and if targeted with a move, the opposing Pokemon is forced to switch to a random ally. This move has a 1/X chance of being successful, where X starts at 1 and triples each time this move is successfully used. X resets to 1 if this move fails, if the user's last move used is not Baneful Bunker, Detect, Endure, King's Shield, Protect, Quick Guard, Spiky Shield, Wide Guard, or this move, or if it was one of those moves and the user's protection was broken. Fails if the user moves last this turn.",
|
|
shortDesc: "Protects from moves. Targeted: Force switch foe.",
|
|
id: "backoffgrrr",
|
|
name: "Back Off! GRRR!",
|
|
isNonstandard: "Custom",
|
|
pp: 15,
|
|
priority: 4,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Protect", source);
|
|
this.add('-anim', source, "Defense Curl", source);
|
|
},
|
|
stallingMove: true,
|
|
volatileStatus: 'backoffgrrr',
|
|
onTryHit(target, source, move) {
|
|
return !!this.willAct() && this.runEvent('StallMove', target);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
effect: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'move: Protect');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags['protect']) {
|
|
if (move.isZ) target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
this.add('-activate', target, 'move: Protect');
|
|
let lockedmove = source.getVolatile('lockedmove');
|
|
if (lockedmove) {
|
|
// Outrage counter is reset
|
|
if (source.volatiles['lockedmove'].duration === 2) {
|
|
delete source.volatiles['lockedmove'];
|
|
}
|
|
}
|
|
this.add('-anim', target, "Scary Face", source);
|
|
this.add('-anim', target, "Roar", source);
|
|
source.forceSwitchFlag = true;
|
|
this.add('-message', `${source.name} was scared off!`);
|
|
return null;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (target !== source) {
|
|
this.add('-anim', target, "Scary Face", source);
|
|
this.add('-anim', target, "Roar", source);
|
|
source.forceSwitchFlag = true;
|
|
this.add('-message', `${source.name} was scared off!`);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fire",
|
|
},
|
|
// Used for Andrew's ability
|
|
lavaterrain: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "For 5 turns, the terrain becomes Lava Terrain. During the effect, the power of Fire-type attacks made by Pokemon is multiplied by 1.5 and the power of Water-type attacks made by Pokemon is halved. Quilava's defense is doubled under Lava Terrain. Fire-type Pokemon have 1/16 of their maximum HP restored at the end of each turn, and all other Pokemon lose 1/16 of their maximum HP at the end of each turn.",
|
|
shortDesc: "Damages non-Fire-types. +Fire, -Water power.",
|
|
id: "lavaterrain",
|
|
name: "Lava Terrain",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
terrain: 'lavaterrain',
|
|
effect: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source && source.hasItem('terrainextender')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onModifyDefPriority: 1,
|
|
onModifyDef(def, pokemon) {
|
|
if (pokemon.baseTemplate.baseSpecies === 'Quilava') {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
onAnyModifyDamage(basePower, attacker, defender, move) {
|
|
if (move.type === 'Fire') {
|
|
return this.chainModify(1.5);
|
|
}
|
|
if (move.type === 'Water') {
|
|
return this.chainModify(0.5);
|
|
}
|
|
},
|
|
onStart(battle, source, effect) {
|
|
if (effect && effect.effectType === 'Ability') {
|
|
this.add('-fieldstart', 'move: Lava Terrain', '[from] ability: ' + effect, '[of] ' + source);
|
|
} else {
|
|
this.add('-fieldstart', 'move: Lava Terrain');
|
|
}
|
|
this.add('-message', 'The battlefield was covered in Lava!');
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 2,
|
|
onResidual() {
|
|
this.eachEvent('Terrain');
|
|
},
|
|
onTerrain(pokemon) {
|
|
if (pokemon.hasType('Fire')) {
|
|
this.heal(pokemon.maxhp / 16);
|
|
this.add('-message', `${pokemon.illusion ? pokemon.illusion.name : pokemon.name} was healed by the Lava Terrain!`);
|
|
} else {
|
|
this.damage(pokemon.maxhp / 16);
|
|
this.add('-message', `${pokemon.illusion ? pokemon.illusion.name : pokemon.name} was hurt by Lava Terrain!`);
|
|
}
|
|
},
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Lava Terrain');
|
|
this.add('-message', 'The battlefield is no longer covered in Lava.');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fire",
|
|
},
|
|
// Anubis
|
|
hereticsmark: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The target is replaced with a new randomly generated Super Staff Bros Brawl set. The new Pokemon retains the old pokemon's HP percentage, power point percentages, and status condition.",
|
|
shortDesc: "Target is replaced with random SSBB set.",
|
|
id: "hereticsmark",
|
|
name: "Heretic's Mark",
|
|
isNonstandard: "Custom",
|
|
pp: 2,
|
|
noPPBoosts: true,
|
|
priority: -7,
|
|
flags: {authentic: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Shadow Force', target);
|
|
this.add('-anim', target, 'Dark Void', target);
|
|
},
|
|
onHit(target, source, move) {
|
|
let wouldMove = this.cancelMove(target);
|
|
// Generate a new team
|
|
let team = this.teamGenerator.getTeam({name: target.side.name, inBattle: true});
|
|
let set = team.shift();
|
|
if (set.name === target.set.name) set = team.shift(); // Must be a new set
|
|
const oldName = target.name;
|
|
|
|
// Bit of a hack so client doesn't crash when formeChange is called for the new pokemon
|
|
let effect = this.effect;
|
|
this.effect = /** @type {Effect} */ ({id: ''});
|
|
// @ts-ignore
|
|
let pokemon = new Pokemon(set, target.side);
|
|
this.effect = effect;
|
|
|
|
pokemon.hp = Math.floor(pokemon.maxhp * (target.hp / target.maxhp)) || 1;
|
|
pokemon.status = target.status;
|
|
delete target.volatiles[target.name];
|
|
if (target.statusData) pokemon.statusData = target.statusData;
|
|
for (const [j, moveSlot] of pokemon.moveSlots.entries()) {
|
|
moveSlot.pp = Math.floor(moveSlot.maxpp * (target.moveSlots[j] ? (target.moveSlots[j].pp / target.moveSlots[j].maxpp) : 1));
|
|
}
|
|
this.add('faint', target);
|
|
pokemon.position = target.position;
|
|
pokemon.isActive = true;
|
|
target = pokemon;
|
|
target.side.pokemon[0] = pokemon;
|
|
target.side.active[0] = pokemon;
|
|
|
|
this.add('replace', target, pokemon.getDetails, target.hp / target.maxhp); // name change
|
|
target.setAbility(set.ability);
|
|
|
|
const format = this.format;
|
|
if (format && format.onSwitchIn) format.onSwitchIn.call(this, target);
|
|
this.add('-message', `${oldName} was sent to the Distortion World and replaced with somebody else!`);
|
|
for (let stat of Object.keys(target.boosts)) {
|
|
// @ts-ignore Iterate through stat changes to update client
|
|
if (target.boosts[stat] !== 0) {
|
|
// @ts-ignore Iterate through stat changes to update client
|
|
this.add('-setboost', target, stat, target.boosts[stat], '[silent]');
|
|
}
|
|
}
|
|
if (wouldMove) this.hint(`${oldName}'s move was aborted because its moves changed.`);
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
},
|
|
// Used for Anubis's ability
|
|
distortionworld: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Sets Distortion World for 5 turns. The power of Ghost type moves is boosted by 1.5x, and all Pokemon on the field have an effective Speed of 0. This terrain affects floating Pokemon.",
|
|
shortDesc: "5 turns: +Ghost power, all Pokemon Speed tie.",
|
|
id: "distortionworld",
|
|
name: "Distortion World",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {nosky: true},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Dark Void', source);
|
|
this.add('-anim', target, 'Dark Void', target);
|
|
},
|
|
pseudoWeather: 'distortionworld',
|
|
effect: {
|
|
duration: 5,
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === 'Ghost') {
|
|
this.debug('distortion world boost');
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
onStart(battle, source, effect) {
|
|
if (effect && effect.effectType === 'Ability') {
|
|
this.add('-fieldstart', 'move: Distortion World', '[from] ability: ' + effect, '[of] ' + source);
|
|
} else {
|
|
this.add('-fieldstart', 'move: Distortion World');
|
|
}
|
|
this.add('-message', 'Distortion World has caused all speed to become the same!');
|
|
},
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Distortion World');
|
|
this.add('-message', 'Speeds have returned to normal.');
|
|
},
|
|
},
|
|
target: "all",
|
|
type: "Ghost",
|
|
},
|
|
// A Quag to The Past
|
|
murkyambush: {
|
|
accuracy: true,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
desc: "Fails unless the user is hit by a physical move from an opponent this turn before it can execute the move. The foe's move has its secondary effects suppressed and damage halved. If the user was hit and has not fainted, it attacks and the effect ends. This move can affect Flying-type Pokemon.",
|
|
shortDesc: "Prepares for foe's attack, then retaliates.",
|
|
id: "murkyambush",
|
|
name: "Murky Ambush",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: -3,
|
|
flags: {contact: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
if (source.volatiles['murkyambush'] && source.volatiles['murkyambush'].gotHit) {
|
|
this.add('-anim', source, "Dig", target);
|
|
}
|
|
},
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile('murkyambush');
|
|
this.add('-message', `${pokemon.name} anticipates the opposing Pokémon's next move!`);
|
|
this.attrLastMove('[still]');
|
|
this.add('-anim', pokemon, "Work Up", pokemon);
|
|
},
|
|
beforeMoveCallback(pokemon) {
|
|
if (pokemon.volatiles['murkyambush'] && !pokemon.volatiles['murkyambush'].gotHit) {
|
|
this.add('cant', pokemon, 'Murky Ambush', 'Murky Ambush');
|
|
this.add('-message', `${pokemon.name} eases up.`);
|
|
return true;
|
|
}
|
|
this.add('-message', `${pokemon.side.foe.active[0].name} was caught in the ambush!`);
|
|
this.add(`c|+A Quag to The Past|GOTCHA BITCH`);
|
|
},
|
|
effect: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add('-singleturn', pokemon, 'move: Murky Ambush');
|
|
},
|
|
onSourceBasePowerPriority: 7,
|
|
onSourceBasePower(basePower, attacker, defender, move) {
|
|
this.debug('Murky Ambush weaken');
|
|
if (move.category === 'Physical') {
|
|
return this.chainModify(0.5);
|
|
}
|
|
},
|
|
onFoeTryMove(target, source, move) {
|
|
if (move.secondaries && move.category !== 'Status') {
|
|
this.debug('Murky Ambush secondary effects suppression');
|
|
delete move.secondaries;
|
|
}
|
|
},
|
|
onHit(pokemon, source, move) {
|
|
if (pokemon.side !== source.side && move.category === 'Physical') {
|
|
pokemon.volatiles['murkyambush'].gotHit = true;
|
|
}
|
|
},
|
|
},
|
|
ignoreImmunity: {'Ground': true},
|
|
target: "normal",
|
|
type: "Ground",
|
|
},
|
|
// a random duck
|
|
flock: {
|
|
basePower: 100,
|
|
accuracy: 100,
|
|
category: "Special",
|
|
desc: "This move suppresses the foe's ability and has a 70% chance to boost the user's Special Attack and Speed by one stage.",
|
|
shortDesc: "70% SpA & Spe +1. Suppresses foe's ability.",
|
|
id: "flock",
|
|
name: "Flock",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {mirror: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Cosmic Power', source);
|
|
this.add('-anim', source, 'Brave Bird', target);
|
|
this.add('-anim', source, 'Judgment', target);
|
|
},
|
|
onHit(target, source) {
|
|
target.addVolatile('gastroacid', source);
|
|
},
|
|
secondary: {
|
|
chance: 70,
|
|
self: {
|
|
boosts: {
|
|
spa: 1,
|
|
spe: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Flying",
|
|
},
|
|
// Arcticblast
|
|
trashalanche: {
|
|
basePower: 80,
|
|
basePowerCallback(pokemon, target, move) {
|
|
let noitem = 0;
|
|
for (const foes of target.side.pokemon) {
|
|
if (!foes.item) noitem += 20;
|
|
}
|
|
return move.basePower + noitem;
|
|
},
|
|
accuracy: 100,
|
|
category: "Physical",
|
|
desc: "This move's Base Power increases by 20 for every foe that is not holding an item.",
|
|
shortDesc: "+20 Base Power for each itemless foe.",
|
|
id: "trashalanche",
|
|
name: "Trashalanche",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Gunk Shot", target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
},
|
|
// Arsenal
|
|
comeonyougunners: {
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
desc: "This move's type depends on the user's held Plate. If the target has the same type as this move, its Base Power is boosted by 1.5x.",
|
|
shortDesc: "Type = Plate. 1.5x power for same-type targets.",
|
|
id: "comeonyougunners",
|
|
name: "Come on you Gunners",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source, move) {
|
|
this.add('-anim', source, 'Judgment', target);
|
|
this.add('-anim', target, 'Extreme Evoboost', target);
|
|
// Modifying BP here so it happens AFTER ModifyMove
|
|
if (target.types.includes(move.type)) {
|
|
this.debug('Come on you Gunners BP boost');
|
|
move.basePower = move.basePower * 1.5;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
const item = pokemon.getItem();
|
|
if (item.id && item.onPlate && !item.zMove) {
|
|
this.debug(`Come on you Gunners type changed to: ${item.onPlate}`);
|
|
move.type = item.onPlate;
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
},
|
|
// Asheviere
|
|
wondertrade: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Replaces every non-fainted member of the user's team with a Super Staff Bros. Brawl set that is randomly selected from all sets, except those with the move Wonder Trade. Remaining HP and PP percentages, as well as status conditions, are transferred onto the replacement sets. This move fails if it's used by a Pokemon that does not originally know this move. This move fails if the user is not Asheviere.",
|
|
shortDesc: "Replaces user's team with random SSBB sets.",
|
|
id: "wondertrade",
|
|
name: "Wonder Trade",
|
|
isNonstandard: "Custom",
|
|
pp: 2,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Amnesia', source);
|
|
this.add('-anim', source, 'Double Team', source);
|
|
},
|
|
onTryHit(target, source) {
|
|
if (source.name !== 'Asheviere') {
|
|
this.add('-fail', source);
|
|
this.hint("Only Asheviere can use Wonder Trade.");
|
|
return null;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
// Store percent of HP left, percent of PP left, and status for each pokemon on the user's team
|
|
let carryOver = [];
|
|
let currentTeam = source.side.pokemon.slice();
|
|
for (let pokemon of currentTeam) {
|
|
carryOver.push({
|
|
hp: pokemon.hp / pokemon.maxhp,
|
|
status: pokemon.status,
|
|
statusData: pokemon.statusData,
|
|
pp: pokemon.moveSlots.slice().map(m => {
|
|
return m.pp / m.maxpp;
|
|
}),
|
|
});
|
|
// Handle pokemon with less than 4 moves
|
|
while (carryOver[carryOver.length - 1].pp.length < 4) {
|
|
carryOver[carryOver.length - 1].pp.push(1);
|
|
}
|
|
}
|
|
// Generate a new team
|
|
/** @type {Pokemon[]} */
|
|
let team = this.teamGenerator.getTeam({name: source.side.name, inBattle: true});
|
|
// Remove Asheviere from generated teams to not allow duplicates
|
|
team = team.filter(pokemon => !(pokemon.name === 'Asheviere'));
|
|
// Overwrite un-fainted pokemon other than the user
|
|
for (let i = 0; i < currentTeam.length; i++) {
|
|
if (currentTeam[i].fainted || !currentTeam[i].hp || currentTeam[i].position === source.position) continue;
|
|
let set = team.shift();
|
|
if (!set) throw new Error('Not enough pokemon left to wonder trade to.');
|
|
let oldSet = carryOver[i];
|
|
|
|
if (set.name === 'Flare' && currentTeam.filter(p => !p.fainted && p.hp).length <= 2) {
|
|
// Don't select Super Illusion when there are only 2 unfainted pokemon
|
|
set = team.shift();
|
|
if (!set) throw new Error('Not enough pokemon left to wonder trade to.');
|
|
}
|
|
|
|
// Bit of a hack so client doesn't crash when formeChange is called for the new pokemon
|
|
let effect = this.effect;
|
|
this.effect = /** @type {Effect} */ ({id: ''});
|
|
// @ts-ignore
|
|
let pokemon = new Pokemon(set, source.side);
|
|
this.effect = effect;
|
|
|
|
pokemon.hp = Math.floor(pokemon.maxhp * oldSet.hp) || 1;
|
|
pokemon.status = oldSet.status;
|
|
if (oldSet.statusData) pokemon.statusData = oldSet.statusData;
|
|
for (const [j, moveSlot] of pokemon.moveSlots.entries()) {
|
|
moveSlot.pp = Math.floor(moveSlot.maxpp * oldSet.pp[j]);
|
|
}
|
|
pokemon.position = currentTeam[i].position;
|
|
currentTeam[i] = pokemon;
|
|
}
|
|
// Move flare to the front of the team if Super Illusion would not activate
|
|
let newTeam = currentTeam.slice().map(p => (!p.fainted && p.hp) ? p.name : null);
|
|
if (newTeam.filter(n => n).pop() === 'Flare') {
|
|
// Don't swap with the current pokemon or client will softlock
|
|
let newIdx = source.position === 0 ? 1 : 0;
|
|
let idx = newTeam.indexOf('Flare');
|
|
let original = currentTeam[newIdx];
|
|
currentTeam[newIdx] = currentTeam[idx];
|
|
currentTeam[idx] = original;
|
|
// Update pokemon.position flags to prevent errors
|
|
currentTeam[newIdx].position = newIdx;
|
|
currentTeam[idx].position = idx;
|
|
}
|
|
source.side.pokemon = currentTeam;
|
|
this.add('message', `${source.name} wonder traded ${source.side.name}'s team away!`);
|
|
},
|
|
target: "self",
|
|
type: "Psychic",
|
|
},
|
|
// Averardo
|
|
dragonsmash: {
|
|
accuracy: 90,
|
|
basePower: 150,
|
|
category: "Physical",
|
|
desc: "This Pokemon takes 50% of the damage it deals as recoil.",
|
|
shortDesc: "50% recoil.",
|
|
id: "dragonsmash",
|
|
name: "Dragon Smash",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Head Smash', target);
|
|
this.add('-anim', target, 'Blue Flare', target);
|
|
},
|
|
recoil: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
},
|
|
// Beowulf
|
|
buzzingoftheswarm: {
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Physical",
|
|
desc: "Has a 20% chance to cause the target to flinch.",
|
|
shortDesc: "20% chance to flinch.",
|
|
id: "buzzingoftheswarm",
|
|
name: "Buzzing of the Swarm",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Bug Buzz', source);
|
|
},
|
|
secondary: {
|
|
chance: 20,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
target: "normal",
|
|
type: "Bug",
|
|
},
|
|
// biggie
|
|
foodrush: {
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
desc: "If both the user and the target have not fainted, the target is forced to switch out to a random non-fainted ally. This effect fails if the target used Ingrain previously, has the Suction Cups ability, or is behind a Substitute.",
|
|
shortDesc: "Forces the target to switch to a random ally.",
|
|
id: "foodrush",
|
|
name: "Food Rush",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: -6,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Stockpile', source);
|
|
this.add('-anim', source, 'Spit Up', target);
|
|
},
|
|
forceSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
},
|
|
// Birdy~!
|
|
justdance: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Uses a random dance move other than Lunar Dance twice in a row and then restores 1/3 of its max HP.",
|
|
shortDesc: "Uses random dance move twice; heals 1/3 HP.",
|
|
id: 'justdance',
|
|
name: "Just Dance",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {dance: 1, heal: 1},
|
|
onTryMove(pokemon) {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onHit(target, source, effect) {
|
|
this.heal(source.maxhp / 3, source);
|
|
let dancemoves = ['dragondance', 'featherdance', 'fierydance', 'petaldance', 'quiverdance', 'revelationdance', 'swordsdance', 'teeterdance'];
|
|
let randomMove = dancemoves[this.random(dancemoves.length)];
|
|
this.useMove(randomMove, target);
|
|
this.useMove(randomMove, target);
|
|
// Kill getting locked into petal dance
|
|
if (source.getVolatile('lockedmove')) {
|
|
source.removeVolatile('lockedmove');
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
},
|
|
// bobochan
|
|
thousandcircuitoverload: {
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
desc: "If the target is a Ground-type and is immune to Electric due to its typing, this move deals neutral damage regardless of other types, and the target loses its type-based immunity to Electric.",
|
|
shortDesc: "First hit neutral on Ground; removes its immunity.",
|
|
id: "thousandcircuitoverload",
|
|
name: "Thousand Circuit Overload",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Plasma Fists', target);
|
|
},
|
|
onEffectiveness(typeMod, target, type, move) {
|
|
if (move.type !== 'Electric') return;
|
|
if (!target) return; // avoid crashing when called from a chat plugin
|
|
if (!target.runImmunity('Electric')) {
|
|
if (target.hasType('Ground')) return 0;
|
|
}
|
|
},
|
|
volatileStatus: 'thousandcircuitoverload',
|
|
effect: {
|
|
noCopy: true,
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'Thousand Circuit Overload');
|
|
},
|
|
onNegateImmunity(pokemon, type) {
|
|
if (pokemon.hasType('Ground') && type === 'Electric') return false;
|
|
},
|
|
},
|
|
ignoreImmunity: {'Electric': true},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
},
|
|
// Brandon
|
|
blusterywinds: {
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
desc: "Removes Reflect, Light Screen, Aurora Veil, Safeguard, Mist, Spikes, Toxic Spikes, Stealth Rock, and Sticky Web from both sides, and it removes any active weather condition or terrain.",
|
|
shortDesc: "Removes all field conditions and hazards.",
|
|
id: "blusterywinds",
|
|
name: "Blustery Winds",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, authentic: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Defog", target);
|
|
},
|
|
onHit(target, source, move) {
|
|
let removeAll = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb'];
|
|
let silentRemove = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist'];
|
|
for (const sideCondition of removeAll) {
|
|
if (target.side.removeSideCondition(sideCondition)) {
|
|
if (!(silentRemove.includes(sideCondition))) this.add('-sideend', target.side, this.dex.getEffect(sideCondition).name, '[from] move: Blustery Winds', '[of] ' + source);
|
|
}
|
|
if (source.side.removeSideCondition(sideCondition)) {
|
|
if (!(silentRemove.includes(sideCondition))) this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Blustery Winds', '[of] ' + source);
|
|
}
|
|
}
|
|
this.field.clearWeather();
|
|
this.field.clearTerrain();
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
},
|
|
// Cake
|
|
sparcedance: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Boosts the user's Attack, Defense, and Speed by one stage.",
|
|
shortDesc: "+1 Atk, Def, and Spe.",
|
|
id: "sparcedance",
|
|
name: "Sparce Dance",
|
|
isNonstandard: "Custom",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {snatch: 1, mirror: 1, dance: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Quiver Dance", source);
|
|
},
|
|
boosts: {atk: 1, def: 1, spe: 1},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
},
|
|
// c.kilgannon
|
|
insidiousassault: {
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
desc: "This move's category becomes physical if the opponent's Defense stat is lower than its Special Defense stat. This move's Base Power is 1.5x if this move is physical.",
|
|
shortDesc: "Physical and power x1.5 if foe's Def < SpD.",
|
|
id: "insidiousassault",
|
|
name: "Insidious Assault",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Black Hole Eclipse', target);
|
|
},
|
|
onModifyMove(move, pokemon, target) {
|
|
if (target.getStat('def', false, true) < target.getStat('spd', false, true)) move.category = 'Physical';
|
|
},
|
|
onBasePower(basePower, source, target, move) {
|
|
if (move.category === 'Physical') {
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
// cant say
|
|
aesthetislash: {
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Physical",
|
|
desc: "Summons Grassy Terrain. If the user is an Aegislash, it changes to Blade forme, attacks, then goes back to Shield forme.",
|
|
shortDesc: "Summons Grassy Terrain. Aegislash transforms.",
|
|
id: "aesthetislash",
|
|
name: "a e s t h e t i s l a s h",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Geomancy', source);
|
|
this.add('-anim', source, 'Swords Dance', source);
|
|
this.add('-anim', source, 'Bloom Doom', target);
|
|
},
|
|
onAfterMoveSecondarySelf() {
|
|
this.field.setTerrain('grassyterrain');
|
|
},
|
|
onAfterMove(pokemon) {
|
|
if (pokemon.template.baseSpecies !== 'Aegislash' || pokemon.transformed) return;
|
|
if (pokemon.template.species !== 'Aegislash') pokemon.formeChange('Aegislash');
|
|
},
|
|
target: "normal",
|
|
type: "Steel",
|
|
},
|
|
// Catalystic
|
|
birbtotherescue: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Resets the stat stages of all active Pokemon to 0, then lowers target's evasion by one stage and removes hazards.",
|
|
shortDesc: "Resets stats; target's evasion -1; clears hazards.",
|
|
id: "birbtotherescue",
|
|
name: "Birb to the Rescue",
|
|
pp: 15,
|
|
priority: 1,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1, authentic: 1},
|
|
onHit(target, source, move) {
|
|
this.add('-clearallboost');
|
|
for (const pokemon of this.getAllActive()) {
|
|
pokemon.clearBoosts();
|
|
}
|
|
let success = false;
|
|
if (!target.volatiles['substitute'] || move.infiltrates) success = !!this.boost({evasion: -1});
|
|
let removeTarget = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb'];
|
|
let removeAll = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb'];
|
|
for (const targetCondition of removeTarget) {
|
|
if (target.side.removeSideCondition(targetCondition)) {
|
|
if (!removeAll.includes(targetCondition)) continue;
|
|
this.add('-sideend', target.side, this.dex.getEffect(targetCondition).name, '[from] move: Defog', '[of] ' + source);
|
|
success = true;
|
|
}
|
|
}
|
|
for (const sideCondition of removeAll) {
|
|
if (source.side.removeSideCondition(sideCondition)) {
|
|
this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Defog', '[of] ' + source);
|
|
success = true;
|
|
}
|
|
}
|
|
return success;
|
|
},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Haze", target);
|
|
this.add('-anim', source, "Defog", target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ice",
|
|
},
|
|
// Ceteris
|
|
bringerofdarkness: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Has a 50% chance to cause the target to fall asleep. Sets one layer of Spikes on the opponent's side of the field and randomly boosts the user's Speed or Special Attack by one stage.",
|
|
shortDesc: "50% sleep; sets Spikes; Spe or SpA +1.",
|
|
id: "bringerofdarkness",
|
|
name: "Bringer of Darkness",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {reflectable: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Dark Void", target);
|
|
},
|
|
onHit(target, source, move) {
|
|
this.add('-anim', source, "Spikes", target);
|
|
target.side.addSideCondition('spikes');
|
|
if (this.random(2) === 0) {
|
|
this.boost({spa: 1}, source, source);
|
|
} else {
|
|
this.boost({spe: 1}, source, source);
|
|
}
|
|
if (this.random(2) === 0) target.trySetStatus('slp', source);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
// chaos
|
|
forcewin: {
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Confuses the target and subjects it to the effects of Taunt, Torment, Heal Block, and Embargo.",
|
|
shortDesc: "Ensures domination of the opponent.",
|
|
id: "forcewin",
|
|
name: "Forcewin",
|
|
isNonstandard: "Custom",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Entrainment", target);
|
|
this.add('-anim', source, "Lock On", target);
|
|
},
|
|
onHit(target, source) {
|
|
target.addVolatile('taunt', source);
|
|
target.addVolatile('embargo', source);
|
|
target.addVolatile('torment', source);
|
|
target.addVolatile('confusion', source);
|
|
target.addVolatile('healblock', source);
|
|
this.add(`c|~chaos|/forcewin chaos`);
|
|
if (this.random(1000) === 420) {
|
|
// Should almost never happen, but will be hilarious when it does.
|
|
// Basically, roll a 1000 sided die, if it lands on 420 forcibly give the user's trainer the win
|
|
this.add(`c|~chaos|Actually`);
|
|
this.add(`c|~chaos|/forcewin ${source.side.name}`);
|
|
this.win(source.side);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "???",
|
|
},
|
|
// Chloe
|
|
beskyttelsesnet: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user faints, sets Reflect, Light Screen, and Safeguard, and lowers the target's Attack and Special Attack by 2 stages.",
|
|
shortDesc: "Faint; +Screens & Safeguard; foe -2 Atk & SpA.",
|
|
id: "beskyttelsesnet",
|
|
name: "beskyttelsesnet",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {mirror: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Geomancy', source);
|
|
this.add('-anim', source, 'Memento', target);
|
|
},
|
|
onHit(target, source) {
|
|
this.boost({atk: -2, spa: -2}, target, source);
|
|
source.side.addSideCondition('lightscreen', source);
|
|
source.side.addSideCondition('reflect', source);
|
|
source.side.addSideCondition('safeguard', source);
|
|
},
|
|
selfdestruct: "ifHit",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
// Darth
|
|
leechswap: {
|
|
accuracy: 85,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Applies Leech Seed to the foe, then switches out",
|
|
shortDesc: "Leech Seeds foe, then switches out.",
|
|
id: "leechswap",
|
|
name: "Leech Swap",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, reflectable: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Leech Seed", target);
|
|
},
|
|
onHit(target, source) {
|
|
if (target.hasType('Grass') || target.volatiles['leechseed']) {
|
|
this.add('-fail', source);
|
|
return false;
|
|
} else {
|
|
target.addVolatile('leechseed');
|
|
}
|
|
},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
// DaWoblefet
|
|
superegoinflation: {
|
|
accuracy: true,
|
|
category: "Status",
|
|
desc: "User heals 25% HP. The target's Attack and Special Attack increase by two stages, and the target becomes affected by Taunt.",
|
|
shortDesc: "User heals 25% HP; target Atk & SpA +2; Taunt.",
|
|
id: "superegoinflation",
|
|
name: "Super Ego Inflation",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: -7,
|
|
flags: {mirror: 1, authentic: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Follow Me', source);
|
|
this.add('-anim', target, 'Swords Dance', target);
|
|
this.add('-anim', target, 'Nasty Plot', target);
|
|
},
|
|
onHit(target, source, move) {
|
|
this.heal(source.maxhp / 4, source, source, this.dex.getActiveMove('Super Ego Inflation'));
|
|
this.boost({atk: 2, spa: 2}, target, source, this.dex.getActiveMove('Super Ego Inflation'));
|
|
target.addVolatile('taunt', source, this.dex.getActiveMove('Super Ego Inflation'));
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
},
|
|
// Decem
|
|
hitandrun: {
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Special",
|
|
desc: "If this move hits, the Pokemon that was hit is affected with the Gooey status. Gooey causes the affected Pokemon to lose 1/6 of its max HP until it switches out. The user switches out.",
|
|
shortDesc: "Target loses 1/6 of HP per turn, user switches.",
|
|
id: "hitandrun",
|
|
name: "Hit and Run",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Outrage', target);
|
|
},
|
|
onHit(target, source, move) {
|
|
target.addVolatile('Gooey', source, move);
|
|
},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dragon",
|
|
},
|
|
// deetah
|
|
galvanizedstrike: {
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
desc: "Power doubles if the user is burned, paralyzed, or poisoned. The physical damage halving effect from the user's burn is ignored. Has a 30% chance to paralyze the target.",
|
|
shortDesc: "Power x2 if burn/poison/paralyze; 30% paralyze.",
|
|
id: "galvanizedstrike",
|
|
name: "Galvanized Strike",
|
|
isNonstandard: "Custom",
|
|
pp: 20,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Wild Charge', target);
|
|
this.add('-anim', source, 'Bolt Strike', target);
|
|
},
|
|
onBasePower(basePower, pokemon) {
|
|
if (pokemon.status && pokemon.status !== 'slp') {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Electric",
|
|
},
|
|
// DragonWhale
|
|
earthsblessing: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Sets Gravity, raises the user's Attack by 2 stages, and cures the user's burn, paralysis, or poison. Fails if Gravity is already in effect.",
|
|
shortDesc: "Sets Gravity, raises Attack by 2, cures status.",
|
|
id: "earthsblessing",
|
|
name: "Earth's Blessing",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Swords Dance', source);
|
|
this.add('-anim', source, 'Wood Hammer', source);
|
|
},
|
|
onHit(pokemon, move) {
|
|
if (this.field.pseudoWeather.gravity) return false;
|
|
this.boost({atk: 2}, pokemon, pokemon, this.dex.getActiveMove('EarthsBlessing'));
|
|
this.field.addPseudoWeather('gravity');
|
|
if (['', 'slp', 'frz'].includes(pokemon.status)) return;
|
|
pokemon.cureStatus();
|
|
},
|
|
flags: {mirror: 1, snatch: 1},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ground",
|
|
zMoveEffect: 'healhalf',
|
|
},
|
|
// E4 Flint
|
|
fangofthefireking: {
|
|
accuracy: 90,
|
|
basePower: 0,
|
|
damage: 111,
|
|
category: "Physical",
|
|
desc: "Deals 111 HP of damage and burns the target. If the target already has a status ailment, it is replaced with a burn. Fails if the target is a Fire-type or if the user is not a Fire-type.",
|
|
shortDesc: "111 damage & target burned; fails on Fire-type.",
|
|
id: "fangofthefireking",
|
|
name: "Fang of the Fire King",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {mirror: 1, protect: 1, bite: 1},
|
|
onTryMove(pokemon, target, move) {
|
|
this.attrLastMove('[still]');
|
|
if (!pokemon.hasType('Fire') || target.hasType('Fire')) {
|
|
this.add('-fail', pokemon, 'move: Fang of the Fire King');
|
|
return null;
|
|
}
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Crunch', target);
|
|
this.add('-anim', target, 'Searing Shot', target);
|
|
},
|
|
onHit(target, source) {
|
|
target.setStatus('brn', source, null, true);
|
|
// Cringy message
|
|
if (this.random(5) === 1) this.add(`c|@E4 Flint|here's a __taste__ of my __firepower__ XD`);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// Eien
|
|
ancestralpower: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user's Attack and Special Attack are raised by one stage, it transforms into a different Pokemon, and it uses two moves dependent on the Pokemon; Celebi (Future Sight and Recover), Jirachi (Doom Desire and Wish), Manaphy (Tail Glow and Surf), Shaymin (Seed Flare and Leech Seed), or Victini (V-create and Blue Flare). Reverts to Mew and loses the initial raises of one stage to Attack and Special Attack at the end of the turn.",
|
|
shortDesc: "For turn: transforms, boosts, uses linked moves.",
|
|
id: "ancestralpower",
|
|
name: "Ancestral Power",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, authentic: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onHit(target, source, move) {
|
|
let baseForme = source.template.id;
|
|
/** @type {{[forme: string]: string[]}} */
|
|
let formes = {
|
|
celebi: ['Future Sight', 'Recover'],
|
|
jirachi: ['Doom Desire', 'Wish'],
|
|
manaphy: ['Tail Glow', 'Surf'],
|
|
shaymin: ['Seed Flare', 'Leech Seed'],
|
|
victini: ['V-create', 'Blue Flare'],
|
|
};
|
|
let forme = Object.keys(formes)[this.random(5)];
|
|
source.formeChange(forme, this.dex.getAbility('psychicsurge'), true);
|
|
this.boost({atk: 1, spa: 1}, source, source, move);
|
|
this.useMove(formes[forme][0], source, target);
|
|
this.useMove(formes[forme][1], source, target);
|
|
this.boost({atk: -1, spa: -1}, source, source, move);
|
|
source.formeChange(baseForme, this.dex.getAbility('psychicsurge'), true);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
},
|
|
// Elgino
|
|
roughsnuggle: {
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
desc: "Power doubles if the target is not fully evolved.",
|
|
shortDesc: "Power doubles if the target is NFE.",
|
|
id: "roughsnuggle",
|
|
name: "Rough Snuggle",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Let\'s Snuggle Forever', target);
|
|
},
|
|
onBasePower(basePower, pokemon, target) {
|
|
if (target.template.evos.length) {
|
|
return this.chainModify(2);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fighting",
|
|
zMovePower: 175,
|
|
},
|
|
// eternally
|
|
quack: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Boosts the user's Special Attack and accuracy by one stage.",
|
|
shortDesc: "Raises the user's SpA and accuracy by 1.",
|
|
id: "quack",
|
|
name: "Quack",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {mirror: 1, snatch: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Feather Dance', source);
|
|
this.add('-anim', source, 'Aqua Ring', source);
|
|
},
|
|
boosts: {spa: 1, accuracy: 1},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Flying",
|
|
},
|
|
// explodingdaisies
|
|
doom: {
|
|
basePower: 100,
|
|
accuracy: 100,
|
|
category: "Special",
|
|
desc: "Summons Sunny Day after doing damage.",
|
|
shortDesc: "Summons Sunny Day after doing damage.",
|
|
id: "doom",
|
|
name: "DOOM!",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {mirror: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Eruption', target);
|
|
this.add('-anim', source, 'Sunny Day', source);
|
|
},
|
|
onAfterMoveSecondarySelf() {
|
|
this.field.setWeather('sunnyday');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// False
|
|
frck: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
desc: "Does not check accuracy. KOes the foe. User faints afterwards if move hits.",
|
|
shortDesc: "KOes foe. Always hits. User faints on success.",
|
|
id: "frck",
|
|
name: "fr*ck",
|
|
isNonstandard: "Custom",
|
|
pp: 6,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-activate', source, 'move: Celebrate');
|
|
this.add('-anim', source, 'Searing Sunraze Smash', target);
|
|
this.add('-anim', source, 'Explosion', target);
|
|
},
|
|
onHit(target, source) {
|
|
target.faint();
|
|
source.faint();
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "???",
|
|
},
|
|
// fart
|
|
soupstealing7starstrike: {
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
desc: "This move is either a Water-, Fire-, or Grass-type move. The selected type is added to the user of this move.",
|
|
shortDesc: "Changes user/move type to Fire, Water, or Grass.",
|
|
id: "soupstealing7starstrike",
|
|
name: "Soup-Stealing 7-Star Strike",
|
|
isNonstandard: "Custom",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Conversion", source);
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
let types = ['Fire', 'Water', 'Grass'];
|
|
let randomType = this.sample(types);
|
|
move.type = randomType;
|
|
pokemon.addType(randomType);
|
|
this.add('-start', pokemon, 'typeadd', randomType);
|
|
},
|
|
onHit(target, source) {
|
|
this.add('-anim', source, 'Spectral Thief', target);
|
|
if (Math.round(this.random())) {
|
|
this.add(`c|%fart|I hl on soup`);
|
|
} else {
|
|
this.add(`c|%fart|did someone say soup?`);
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
},
|
|
// Felucia
|
|
quickreload: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Physical",
|
|
desc: "Uses Defog and then attempts to use U-Turn.",
|
|
shortDesc: "Uses Defog, then U-Turn.",
|
|
id: "quickreload",
|
|
name: "Quick Reload",
|
|
isNonstandard: "Custom",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {mirror: 1, protect: 1, authentic: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onHit(target, source) {
|
|
this.useMove('Defog', source, target);
|
|
let move = this.dex.getActiveMove('uturn');
|
|
move.basePower = 90;
|
|
this.useMove(move, source, target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Bug",
|
|
},
|
|
// Flare
|
|
distortionblast: {
|
|
accuracy: 100,
|
|
basePower: 100,
|
|
category: "Special",
|
|
desc: "Until they switch out, Pokemon hit by this move will have all status effects and secondary move effects target themselves.",
|
|
shortDesc: "Hit Pokemon have status/secondaries self-target.",
|
|
id: "distortionblast",
|
|
name: "Distortion Blast",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Night Daze', target);
|
|
this.add('-anim', source, 'Magic Room', source);
|
|
},
|
|
volatileStatus: "distortionblast",
|
|
effect: {
|
|
onStart(pokemon) {
|
|
this.add('-start', pokemon, 'Distortion Blast');
|
|
this.add('-message', `${pokemon.illusion ? pokemon.illusion.name : pokemon.name} was distorted!`);
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
if (move.status) {
|
|
if (!move.secondaries) move.secondaries = [];
|
|
move.secondaries.push({chance: 100, status: move.status});
|
|
delete move.status;
|
|
}
|
|
if (move.secondaries) {
|
|
move.secondaries = move.secondaries.map(secondary => {
|
|
return secondary.self || {self: secondary};
|
|
});
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
// FOMG
|
|
rickrollout: {
|
|
accuracy: true,
|
|
basePower: 140,
|
|
category: "Physical",
|
|
desc: "Raises the user's Speed by two stages and has a 30% chance to confuse the target.",
|
|
shortDesc: "Speed +2; 30% chance to confuse target.",
|
|
id: "rickrollout",
|
|
name: "Rickrollout",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Rock Polish', source);
|
|
this.add('-anim', source, 'Let\'s Snuggle Forever', target);
|
|
},
|
|
onHit() {
|
|
let messages = ["SPL players don't want you to know about this secret",
|
|
"North American player reveals the concerning secret how to make money with Pokemon that will crack you up",
|
|
"10 amazing facts about Zarel you have never heard of",
|
|
"Veteran player shared his best team with a beginner - here's what happened after",
|
|
"Use these 3 simple methods to gain 200+ rating in 10 minutes"][this.random(5)];
|
|
|
|
this.add(`raw|<a href="https://www.youtube.com/watch?v=oHg5SJYRHA0"><b>${messages}</b></a>`);
|
|
},
|
|
self: {
|
|
boosts: {
|
|
spe: 2,
|
|
},
|
|
},
|
|
secondary: {
|
|
chance: 30,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
isZ: "astleyiumz",
|
|
target: "normal",
|
|
type: "Rock",
|
|
},
|
|
// Gallant Spear
|
|
stormassaultogs: {
|
|
accuracy: 90,
|
|
basePower: 25,
|
|
multihit: 3,
|
|
category: "Physical",
|
|
desc: "Hits three times. Each hit has a 10% chance to drop the target's Defense and a 10% chance to burn. Each hit is always a critical hit. If one of the hits breaks the target's Substitute, it will take damage for the remaining hits.",
|
|
shortDesc: "Hits thrice; 10% Def -1; 10% burn; always crits.",
|
|
id: "stormassaultogs",
|
|
isNonstandard: "Custom",
|
|
name: "Storm Assault OGs",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
willCrit: true,
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Bullet Seed', target);
|
|
this.add('-anim', source, 'Magma Storm', target);
|
|
},
|
|
secondaries: [
|
|
{
|
|
chance: 10,
|
|
status: 'brn',
|
|
}, {
|
|
chance: 10,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
],
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// Gimm1ck
|
|
"slavsquat": {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Raises the user's Attack, Defense, and Special Defense by one stage. Weather becomes Hail.",
|
|
shortDesc: "Atk, Def, and SpD +1; weather becomes Hail.",
|
|
id: "slavsquat",
|
|
name: "Slav Squat",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Automotize', source);
|
|
this.add('-anim', source, 'Hail', source);
|
|
this.add('-anim', source, 'Gravity', source);
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
def: 1,
|
|
spd: 1,
|
|
},
|
|
weather: 'hail',
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ice",
|
|
},
|
|
// GMars
|
|
tastetherainbow: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Increases this Pokemon's Attack, Special Attack, and Speed by two stages while also decreasing this Pokemon's Defense and Special Defense by one stage. If this Pokemon is a Minior in its Meteor forme, it will permanently transform into one of the Minior colors and have a special effect based on that color. Red burns the foe, orange confuses it, yellow paralyzes it, green applies Leech Seed, blue gives the user Aqua Ring status, indigo poisons the foe, and violet badly poisons it.",
|
|
shortDesc: "+2 Atk, SpA, Spe. -1 Def, SpD. Meteor -> Core.",
|
|
id: "tastetherainbow",
|
|
name: "Taste the Rainbow",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Extreme Evoboost', source);
|
|
},
|
|
onHit(target, source, move) {
|
|
// Set target to the foe, this is a self targeting move so it works even if the foe has a subsitute
|
|
target = source.side.foe.active[0];
|
|
this.boost({atk: 2, spa: 2, spe: 2, def: -1, spd: -1}, source);
|
|
if (source.template.speciesid !== 'miniormeteor' || source.transformed) return;
|
|
|
|
let rainbow = ['', '-Orange', '-Yellow', '-Green', '-Blue', '-Indigo', '-Violet'];
|
|
let color = rainbow[this.random(rainbow.length)];
|
|
source.formeChange(`Minior${color}`, move, true);
|
|
// Display correct color on client
|
|
if (color) {
|
|
this.add('-formechange', source, `Minior${color}`);
|
|
source.m.miniorColor = color;
|
|
}
|
|
|
|
if (target.volatiles['substitute'] && color !== '-Blue') {
|
|
this.add('-fail', source);
|
|
return;
|
|
}
|
|
switch (color) {
|
|
case '':
|
|
if (!target.trySetStatus('brn', source)) this.add('-fail', target);
|
|
break;
|
|
case '-Orange':
|
|
if (!target.addVolatile('confusion', source)) this.add('-fail', target);
|
|
break;
|
|
case '-Yellow':
|
|
if (!target.trySetStatus('par', source)) this.add('-fail', target);
|
|
break;
|
|
case '-Green':
|
|
if (!target.hasType('Grass')) {
|
|
this.add('-anim', source, 'Leech Seed', target);
|
|
target.addVolatile('leechseed');
|
|
} else {
|
|
this.add('-immune', target);
|
|
}
|
|
break;
|
|
case '-Blue':
|
|
if (!source.addVolatile('aquaring', source)) this.add('-fail', source);
|
|
break;
|
|
case '-Indigo':
|
|
if (!target.trySetStatus('psn', source)) this.add('-fail', target);
|
|
break;
|
|
case '-Violet':
|
|
if (!target.trySetStatus('tox', source)) this.add('-fail', target);
|
|
break;
|
|
default:
|
|
throw new Error(`Invalid color for Taste the Rainbow selected: ${color}`);
|
|
}
|
|
},
|
|
target: "self",
|
|
type: "Normal",
|
|
},
|
|
// grimAuxiliatrix
|
|
paintrain: {
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
let targetWeight = target.getWeight();
|
|
let pokemonWeight = pokemon.getWeight();
|
|
if (pokemonWeight > targetWeight * 5) {
|
|
return 120;
|
|
}
|
|
if (pokemonWeight > targetWeight * 4) {
|
|
return 100;
|
|
}
|
|
if (pokemonWeight > targetWeight * 3) {
|
|
return 80;
|
|
}
|
|
if (pokemonWeight > targetWeight * 2) {
|
|
return 60;
|
|
}
|
|
return 40;
|
|
},
|
|
category: "Physical",
|
|
desc: "The power of this move depends on (user's weight / target's weight), rounded down. Power is equal to 120 if the result is 5 or more, 100 if 4, 80 if 3, 60 if 2, and 40 if 1 or less. The user recovers 1/2 the HP lost by the target, rounded half up. If Big Root is held by the user, the HP recovered is 1.3x normal, rounded half down.",
|
|
shortDesc: "Stronger if user is heavier. Heals 50% of damage.",
|
|
id: "paintrain",
|
|
name: "Pain Train",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
flags: {contact: 1, protect: 1, mirror: 1, heal: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Meteor Mash', target);
|
|
},
|
|
drain: [1, 2],
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
},
|
|
// guishark
|
|
dadjoke: {
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
desc: "50% chance to confuse the foe.",
|
|
shortDesc: "50% chance to confuse the foe.",
|
|
id: "dadjoke",
|
|
name: "Dad Joke",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Boomburst", target);
|
|
},
|
|
secondary: {
|
|
chance: 50,
|
|
volatileStatus: "confusion",
|
|
},
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
// Hippopotas
|
|
hazardpass: {
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
pp: 20,
|
|
desc: "The user sets two of Stealth Rock, Spikes (1 layer), Toxic Spikes (1 layer), and Sticky Web on the foe's side of the field and then switches out.",
|
|
shortDesc: "Sets 2 random hazards, then switches out.",
|
|
id: "hazardpass",
|
|
name: "Hazard Pass",
|
|
isNonstandard: "Custom",
|
|
flags: {reflectable: 1, mirror: 1, authentic: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onHitSide(target, source) {
|
|
// All possible hazards, and their maximum possible layer count
|
|
/** @type {{[key: string]: number}} */
|
|
let hazards = {stealthrock: 1, spikes: 3, toxicspikes: 2, stickyweb: 1};
|
|
// Check how many layers of each hazard can still be added to the foe's side
|
|
if (target.getSideCondition('stealthrock')) delete hazards.stealthrock;
|
|
if (target.getSideCondition('spikes')) {
|
|
hazards.spikes -= target.sideConditions['spikes'].layers;
|
|
if (!hazards.spikes) delete hazards.spikes;
|
|
}
|
|
if (target.getSideCondition('toxicspikes')) {
|
|
hazards.toxicspikes -= target.sideConditions['toxicspikes'].layers;
|
|
if (!hazards.toxicspikes) delete hazards.toxicspikes;
|
|
}
|
|
if (target.getSideCondition('stickyweb')) delete hazards.stickyweb;
|
|
// Create a list of hazards not yet at their maximum layer count
|
|
let hazardTypes = Object.keys(hazards);
|
|
// If there are no possible hazards, don't do anything
|
|
if (!hazardTypes.length) return false;
|
|
// Pick a random hazard, and set it
|
|
let hazard1 = this.sample(hazardTypes);
|
|
// Theoretically, this should always work
|
|
this.add('-anim', source, this.dex.getMove(hazard1).name, target);
|
|
target.addSideCondition(hazard1, source, this.effect);
|
|
// If that was the last possible layer of that hazard, remove it from our list of possible hazards
|
|
if (hazards[hazard1] === 1) {
|
|
hazardTypes.splice(hazardTypes.indexOf(hazard1), 1);
|
|
// If there are no more hazards we can set, end early on a success
|
|
if (!hazardTypes.length) return true;
|
|
}
|
|
// Set the last hazard and animate the switch
|
|
let hazard2 = this.sample(hazardTypes);
|
|
this.add('-anim', source, this.dex.getMove(hazard2).name, target);
|
|
target.addSideCondition(hazard2, source, this.effect);
|
|
this.add('-anim', source, "Baton Pass", target);
|
|
},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Normal",
|
|
zMoveBoost: {def: 1},
|
|
},
|
|
// HoeenHero
|
|
scriptedterrain: {
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Sets Scripted Terrain for 5 turns. The power of Bug-type moves is boosted by 1.5, and there is a 5% chance for every move used to become Glitch Out instead. At the end of a turn, every Pokemon has a 5% chance to transform into a Missingno. with 3 random moves and Glitch Out. Switching out will restore the Pokemon to its normal state. This terrain affects floating Pokemon.",
|
|
shortDesc: "5 turns: +Bug power, glitchy effects.",
|
|
id: "scriptedterrain",
|
|
name: "Scripted Terrain",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {nonsky: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Calm Mind', source);
|
|
this.add('-anim', source, 'Geomancy', source);
|
|
},
|
|
terrain: 'scriptedterrain',
|
|
effect: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source && source.hasItem('terrainextender')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === 'Bug') {
|
|
this.debug('scripted terrain boost');
|
|
return this.chainModify(1.5);
|
|
}
|
|
},
|
|
onTryHitPriority: 4,
|
|
onTryHit(target, source, effect) {
|
|
if (!effect || effect.id === 'glitchout' || source.volatiles['glitchout']) return;
|
|
if (this.random(20) === 1) {
|
|
this.add('message', `${source.illusion ? source.illusion.name : source.name}'s move was glitched by the Scripted Terrain!`);
|
|
this.useMove('Glitch Out', source, source.side.foe.active[0]);
|
|
return null;
|
|
}
|
|
},
|
|
onStart(battle, source, effect) {
|
|
if (effect && effect.effectType === 'Ability') {
|
|
this.add('-fieldstart', 'move: Scripted Terrain', '[from] ability: ' + effect, '[of] ' + source);
|
|
} else {
|
|
this.add('-fieldstart', 'move: Scripted Terrain');
|
|
}
|
|
this.add('-message', 'The battlefield got Technical!');
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 2,
|
|
onResidual() {
|
|
this.eachEvent('Terrain');
|
|
},
|
|
onTerrain(pokemon) {
|
|
if (pokemon.template.id === 'missingno') return;
|
|
if (pokemon.fainted || !pokemon.hp) return;
|
|
if (this.random(20) === 1) {
|
|
this.debug('Scripted terrain corrupt');
|
|
this.add('message', `${pokemon.name} was corrupted by a bug in the Scripted Terrain!`);
|
|
// generate a movepool
|
|
let moves = [];
|
|
let pool = this.dex.shuffle(Object.keys(this.dex.data.Movedex));
|
|
let metronome = this.dex.getMove('metronome');
|
|
for (let i of pool) {
|
|
let move = this.dex.getMove(i);
|
|
if (i !== move.id) continue;
|
|
if (move.isZ || move.isNonstandard) continue;
|
|
if (metronome.noMetronome && metronome.noMetronome.includes(move.id)) continue;
|
|
if (this.dex.getMove(i).gen > this.gen) continue;
|
|
moves.push(move);
|
|
if (moves.length >= 3) break;
|
|
}
|
|
moves.push('glitchout');
|
|
if (toID(pokemon.ability).includes('illusion') && pokemon.illusion) this.singleEvent('End', this.dex.getAbility('Illusion'), pokemon.abilityData, pokemon, pokemon);
|
|
pokemon.formeChange('missingno');
|
|
pokemon.moveSlots = [];
|
|
for (let moveid of moves) {
|
|
let move = this.dex.getMove(moveid);
|
|
if (!move.id) continue;
|
|
pokemon.moveSlots.push({
|
|
move: move.name,
|
|
id: move.id,
|
|
pp: 5,
|
|
maxpp: 5,
|
|
target: move.target,
|
|
disabled: false,
|
|
used: false,
|
|
virtual: true,
|
|
});
|
|
}
|
|
}
|
|
},
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Scripted Terrain');
|
|
this.add('-message', 'The battlefield is no longer Technical.');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Psychic",
|
|
},
|
|
// Used by HoeenHero's terrain
|
|
glitchout: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "A random move is selected for use, other than After You, Assist, Baneful Bunker, Beak Blast, Belch, Bestow, Celebrate, Chatter, Copycat, Counter, Covet, Crafty Shield, Destiny Bond, Detect, Diamond Storm, Endure, Feint, Fleur Cannon, Focus Punch, Follow Me, Freeze Shock, Helping Hand, Hold Hands, Hyperspace Hole, Ice Burn, Instruct, King's Shield, Light of Ruin, Mat Block, Me First, Metronome, Mimic, Mind Blown, Mirror Coat, Mirror Move, Nature Power, Photon Geyser, Plasma Fists, Protect, Quash, Quick Guard, Rage Powder, Relic Song, Secret Sword, Shell Trap, Sketch, Sleep Talk, Snarl, Snatch, Snore, Spectral Thief, Spiky Shield, Spotlight, Steam Eruption, Struggle, Switcheroo, Techno Blast, Thief, Thousand Arrows, Thousand Waves, Transform, Trick, Trump Card, V-create, or Wide Guard. The selected move's Base Power is increased by 20.",
|
|
shortDesc: "Uses a random move with Base Power +20.",
|
|
id: "glitchout",
|
|
name: "Glitch Out",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
noMetronome: ['afteryou', 'assist', 'banefulbunker', 'beakblast', 'belch', 'bestow', 'celebrate', 'chatter', 'copycat', 'counter', 'covet', 'craftyshield', 'destinybond', 'detect', 'diamondstorm', 'dragonascent', 'endure', 'feint', 'fleurcannon', 'focuspunch', 'followme', 'freezeshock', 'helpinghand', 'holdhands', 'hyperspacefury', 'hyperspacehole', 'iceburn', 'instruct', 'kingsshield', 'lightofruin', 'matblock', 'mefirst', 'metronome', 'mimic', 'mindblown', 'mirrorcoat', 'mirrormove', 'naturepower', 'originpulse', 'photongeyser', 'plasmafists', 'precipiceblades', 'protect', 'quash', 'quickguard', 'ragepowder', 'relicsong', 'secretsword', 'shelltrap', 'sketch', 'sleeptalk', 'snarl', 'snatch', 'snore', 'spectralthief', 'spikyshield', 'spotlight', 'steameruption', 'struggle', 'switcheroo', 'technoblast', 'thief', 'thousandarrows', 'thousandwaves', 'transform', 'trick', 'trumpcard', 'vcreate', 'wideguard'],
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Bug Buzz', source);
|
|
this.add('-anim', source, 'Metronome', source);
|
|
source.addVolatile('glitchout');
|
|
},
|
|
onHit(target, source, effect) {
|
|
let moves = [];
|
|
for (let i in this.dex.data.Movedex) {
|
|
let move = this.dex.data.Movedex[i];
|
|
if (i !== move.id) continue;
|
|
if (move.isZ || move.isNonstandard) continue;
|
|
if (effect.noMetronome && effect.noMetronome.includes(move.id)) continue;
|
|
if (this.dex.getMove(i).gen > this.gen) continue;
|
|
moves.push(move);
|
|
}
|
|
let randomMove = '';
|
|
if (moves.length) {
|
|
moves.sort((a, b) => a.num - b.num);
|
|
randomMove = this.sample(moves).id;
|
|
}
|
|
if (!randomMove) {
|
|
return false;
|
|
}
|
|
this.useMove(randomMove, target);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Bug",
|
|
},
|
|
// Hubriz
|
|
flowertornado: {
|
|
accuracy: 90,
|
|
basePower: 95,
|
|
category: "Special",
|
|
desc: "Has a 20% chance to either poison the target or cause it to fall asleep.",
|
|
shortDesc: "20% chance to either poison or sleep target.",
|
|
id: "flowertornado",
|
|
name: "Flower Tornado",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Petal Blizzard", target);
|
|
this.add('-anim', source, "Leaf Tornado", target);
|
|
},
|
|
secondary: {
|
|
chance: 20,
|
|
onHit(target, source) {
|
|
let result = this.random(2);
|
|
if (result === 0) {
|
|
target.trySetStatus('psn', source);
|
|
} else {
|
|
target.trySetStatus('slp', source);
|
|
}
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
// inactive
|
|
petrifyinggaze: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Raises the user's Attack by two stages. Traps and paralyzes the foe.",
|
|
shortDesc: "Raises user's Atk by 2; traps and paralyzes foe.",
|
|
id: "petrifyinggaze",
|
|
name: "Petrifying Gaze",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Mean Look", target);
|
|
},
|
|
onHit(target, source, move) {
|
|
this.boost({atk: 2}, source, source);
|
|
target.trySetStatus('par', source);
|
|
return target.addVolatile('trapped', source, move, 'trapper');
|
|
},
|
|
isZ: "dusknoiriumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ghost",
|
|
},
|
|
// irritated
|
|
pureskill: {
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
desc: "Has a 30% chance to paralyze the target and a 10% chance to confuse it.",
|
|
shortDesc: "30% chance to paralyze. 10% chance to confuse.",
|
|
id: "pureskill",
|
|
name: "Pure Skill",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Heart Stamp', target);
|
|
},
|
|
flags: {protect: 1, mirror: 1},
|
|
secondaries: [
|
|
{
|
|
chance: 30,
|
|
status: 'par',
|
|
}, {
|
|
chance: 10,
|
|
volatileStatus: 'confusion',
|
|
},
|
|
],
|
|
target: "normal",
|
|
type: "Psychic",
|
|
},
|
|
// Iyarito
|
|
rosarosa: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Cures the user's party of all status conditions, then poisons the user.",
|
|
shortDesc: "Cures party's statuses, then poisons self.",
|
|
id: "rosarosa",
|
|
name: "Rosa Rosa",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
flags: {mirror: 1, snatch: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Acid Armor', source);
|
|
},
|
|
onHit(pokemon, source, move) {
|
|
//this.add('-activate', source, 'move: Víbora');
|
|
let success = false;
|
|
for (const ally of pokemon.side.pokemon) {
|
|
if (ally.cureStatus()) success = true;
|
|
}
|
|
if (pokemon.trySetStatus('psn', pokemon)) success = true;
|
|
return success;
|
|
},
|
|
secondary: null,
|
|
target: "allyTeam",
|
|
type: "Poison",
|
|
},
|
|
// Jolteonite
|
|
hyperforcestrike: {
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Physical",
|
|
desc: "Damages the target and restores user's HP by 15% of its total health.",
|
|
shortDesc: "Damages the target and heals 15% total HP.",
|
|
id: "hyperforcestrike",
|
|
name: "Hyperforce Strike",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, heal: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Draco Meteor", target);
|
|
},
|
|
onAfterMoveSecondarySelf(pokemon, target, move) {
|
|
this.heal(pokemon.maxhp * 0.15, pokemon, pokemon, move); // 15% health recovered
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
},
|
|
// Kaiju Bunny
|
|
bestialstrike: {
|
|
accuracy: 100,
|
|
basePower: 150,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return move.basePower * pokemon.hp / pokemon.maxhp;
|
|
},
|
|
category: "Physical",
|
|
desc: "Power is equal to (user's current HP * 150 / user's maximum HP), rounded down, but not less than 1.",
|
|
shortDesc: "Less power as user's HP decreases.",
|
|
id: "bestialstrike",
|
|
name: "Bestial Strike",
|
|
isNonstandard: "Custom",
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Outrage', target);
|
|
},
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, contact: 1},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
},
|
|
// kalalokki
|
|
maelstrm: {
|
|
accuracy: 85,
|
|
basePower: 100,
|
|
category: "Special",
|
|
desc: "Prevents the target from switching for four or five turns (seven turns if the user is holding Grip Claw). Causes damage to the target equal to 1/8 of its maximum HP (1/6 if the user is holding Binding Band), rounded down, at the end of each turn during effect. Both of these effects persist for their normal duration even if the user switches out or faints. The target can still switch out if it is holding Shed Shell or uses Baton Pass, Parting Shot, U-turn, or Volt Switch. The effect ends if the target leaves the field or uses Rapid Spin or Substitute successfully. This effect is not stackable or reset by using this or another binding move.",
|
|
shortDesc: "Traps/damages 4-5 turns, even if user switches.",
|
|
id: "maelstrm",
|
|
name: "Maelström",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
volatileStatus: 'maelstrm',
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Dark Void', target);
|
|
this.add('-anim', source, 'Surf', target);
|
|
},
|
|
effect: {
|
|
duration: 5,
|
|
durationCallback(target, source) {
|
|
if (source.hasItem('gripclaw')) {
|
|
this.debug('maelstrm grip claw duration boost');
|
|
return 8;
|
|
}
|
|
return this.random(5, 7);
|
|
},
|
|
onStart() {
|
|
this.add('-message', 'It became trapped in an enormous maelström!');
|
|
},
|
|
onResidualOrder: 11,
|
|
onResidual(pokemon) {
|
|
if (this.effectData.source.hasItem('bindingband')) {
|
|
this.debug('maelstrm binding band damage boost');
|
|
this.damage(pokemon.maxhp / 6);
|
|
} else {
|
|
this.damage(pokemon.maxhp / 8);
|
|
}
|
|
},
|
|
onEnd() {
|
|
this.add('-message', 'The maelström dissipated.');
|
|
},
|
|
onTrapPokemon(pokemon) {
|
|
pokemon.tryTrap();
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
},
|
|
// kaori
|
|
w: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Raises the user's Special Attack, Special Defense, and Speed by one stage. Summons Sunny Day.",
|
|
shortDesc: "User's SpA, SpD, Spe +1. Sets Sunny Day.",
|
|
id: "w",
|
|
name: ">w<",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Petal Dance', source);
|
|
},
|
|
onHit(target, source) {
|
|
this.field.setWeather('sunnyday', source);
|
|
},
|
|
boosts: {
|
|
spa: 1,
|
|
spd: 1,
|
|
spe: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
},
|
|
// Kay
|
|
inkzooka: {
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
desc: "Lowers the user's Defense, Special Defense, and Speed by one stage.",
|
|
shortDesc: "Lowers the user's Def, Sp. Def, and Spe by 1.",
|
|
id: "inkzooka",
|
|
name: "Inkzooka",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Never Ending Nightmare', target);
|
|
},
|
|
self: {
|
|
boosts: {
|
|
def: -1,
|
|
spd: -1,
|
|
spe: -1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
},
|
|
// Kie
|
|
chaotic: {
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
desc: "Before the user attacks, its Attack is increased by one stage. After the user attacks, one of its stats other than accuracy and evasion is boosted by one stage. This move has a 50% chance to confuse the target.",
|
|
shortDesc: "Atk +1, attacks. Random stat +1. 50% confuse.",
|
|
id: "chaotic",
|
|
name: "Chaotic",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.boost({atk: 1}, source);
|
|
this.add('-anim', source, "Dragon Dance", source);
|
|
this.add('-anim', source, "Liquidation", target);
|
|
},
|
|
|
|
onAfterHit(target, source) {
|
|
let boost = {};
|
|
let stat = ['atk', 'def', 'spa', 'spd', 'spe'][this.random(5)];
|
|
// @ts-ignore
|
|
boost[stat] = 1;
|
|
this.boost(boost, source);
|
|
},
|
|
secondary: {
|
|
chance: 50,
|
|
volatileStatus: "confusion",
|
|
},
|
|
target: "normal",
|
|
type: "Water",
|
|
},
|
|
// KingSwordYT
|
|
dragonwarriortouch: {
|
|
accuracy: 100,
|
|
basePower: 70,
|
|
category: "Physical",
|
|
desc: "The user recovers 1/2 the HP lost by the target, rounded half up. Raises the user's Attack by one stage.",
|
|
shortDesc: "User recovers 50% of the damage dealt; Atk +1.",
|
|
id: "dragonwarriortouch",
|
|
name: "Dragon Warrior Touch",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, punch: 1, contact: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Outrage', target);
|
|
this.add('-anim', source, 'Drain Punch', target);
|
|
},
|
|
self: {
|
|
boosts: {
|
|
atk: 1,
|
|
},
|
|
},
|
|
drain: [1, 2],
|
|
target: "normal",
|
|
type: "Fighting",
|
|
},
|
|
// Kipkluif
|
|
"salutethecolonel": {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user is protected from most attacks made by other Pokemon during this turn, and Pokemon trying to make contact with the user have their Attack lowered by 2 stages. Non-damaging moves go through this protection. This move has a 1/X chance of being successful, where X starts at 1 and triples each time this move is successfully used. X resets to 1 if this move fails, if the user's last move used is not Baneful Bunker, Detect, Endure, King's Shield, Protect, Quick Guard, Spiky Shield, or Wide Guard, or if it was one of those moves and the user's protection was broken. The user also swaps its Defense and Special Defense stat stage changes with the target. Fails if the user moves last this turn.",
|
|
shortDesc: "Blocks attacks; contact: Atk -2; Guard Swap.",
|
|
id: "salutethecolonel",
|
|
isNonstandard: "Custom",
|
|
name: "Salute the Colonel",
|
|
pp: 15,
|
|
priority: 4,
|
|
flags: {},
|
|
stallingMove: true,
|
|
volatileStatus: 'kingsshield',
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onTryHit(pokemon) {
|
|
return !!this.willAct() && this.runEvent('StallMove', pokemon);
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "King's Shield", source);
|
|
this.add('-anim', source, "Guard Swap", target);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
this.add(`c|+Kipkluif|o7`);
|
|
let target = pokemon.side.foe.active[0];
|
|
if (!target) return;
|
|
let targetBoosts = {};
|
|
let sourceBoosts = {};
|
|
|
|
for (const stat of ['def', 'spd']) {
|
|
// @ts-ignore
|
|
targetBoosts[stat] = target.boosts[stat];
|
|
// @ts-ignore
|
|
sourceBoosts[stat] = pokemon.boosts[stat];
|
|
}
|
|
|
|
pokemon.setBoost(targetBoosts);
|
|
target.setBoost(sourceBoosts);
|
|
|
|
this.add('-swapboost', pokemon, target, 'def, spd', '[from] move: Guard Swap');
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fighting",
|
|
},
|
|
// Kris
|
|
ectoplasm: {
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Special",
|
|
desc: "This move's type is equal to the user's secondary type. Has a 10% chance to lower the user's Special Defense by 1.",
|
|
shortDesc: "Attack is user's 2nd type. 10% SpD -1.",
|
|
id: "ectoplasm",
|
|
isNonstandard: "Custom",
|
|
name: "Ectoplasm",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onTry(pokemon, target) {
|
|
if (pokemon.types[1] === undefined) {
|
|
this.add('-fail', pokemon);
|
|
return null;
|
|
}
|
|
},
|
|
onModifyMove(move, pokemon) {
|
|
move.type = pokemon.types[1];
|
|
},
|
|
onPrepareHit(target, source) {
|
|
let move = 'Tri Attack';
|
|
switch (source.types[1]) {
|
|
case 'Ghost':
|
|
move = 'Moongeist Beam';
|
|
break;
|
|
case 'Flying':
|
|
move = 'Hurricane';
|
|
break;
|
|
case 'Fire':
|
|
move = 'Blast Burn';
|
|
break;
|
|
case 'Water':
|
|
move = 'Hydro Cannon';
|
|
break;
|
|
case 'Grass':
|
|
move = 'Frenzy Plant';
|
|
break;
|
|
case 'Ice':
|
|
move = 'Sheer Cold';
|
|
break;
|
|
}
|
|
this.add('-anim', source, move, target);
|
|
},
|
|
secondary: {
|
|
chance: 10,
|
|
boosts: {
|
|
spd: -1,
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
},
|
|
// Level 51
|
|
nextlevelstrats: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user gains 5 levels upon using this move, which persist upon switching out.",
|
|
shortDesc: "User gains 5 levels.",
|
|
id: "nextlevelstrats",
|
|
name: "Next Level Strats",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Nasty Plot", target);
|
|
},
|
|
onHit(pokemon) {
|
|
const template = pokemon.template;
|
|
// @ts-ignore
|
|
pokemon.level += 5;
|
|
pokemon.set.level = pokemon.level;
|
|
pokemon.formeChange(template);
|
|
|
|
pokemon.details = template.species + (pokemon.level === 100 ? '' : ', L' + pokemon.level) + (pokemon.gender === '' ? '' : ', ' + pokemon.gender) + (pokemon.set.shiny ? ', shiny' : '');
|
|
this.add('detailschange', pokemon, pokemon.details);
|
|
|
|
const newHP = Math.floor(Math.floor(2 * template.baseStats['hp'] + pokemon.set.ivs['hp'] + Math.floor(pokemon.set.evs['hp'] / 4) + 100) * pokemon.level / 100 + 10);
|
|
pokemon.hp = newHP - (pokemon.maxhp - pokemon.hp);
|
|
pokemon.maxhp = newHP;
|
|
this.add('-heal', pokemon, pokemon.getHealth, '[silent]');
|
|
|
|
this.add('-message', `${pokemon.name} advanced 5 levels! It is now level ${pokemon.level}!`);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
|
|
},
|
|
// LifeisDANK
|
|
barfight: {
|
|
accuracy: 100,
|
|
basePower: 10,
|
|
category: "Physical",
|
|
desc: "Raises both the user's and the target's Attack by three stages, lowers the Defense of both by three stages, confuses both Pokemon, and has a 100% chance to cause the target to flinch. Only works on the user's first turn on the field.",
|
|
shortDesc: "First turn: +3 Atk, -3 Def, flinch, both confused.",
|
|
id: "barfight",
|
|
name: "Bar Fight",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 3,
|
|
flags: {protect: 1, mirror: 1, contact: 1},
|
|
onTry(pokemon, target) {
|
|
if (pokemon.activeTurns > 1) {
|
|
this.attrLastMove('[still]');
|
|
this.add('-fail', pokemon);
|
|
this.hint("Bar Fight only works on your first turn out.");
|
|
return null;
|
|
}
|
|
},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Fake Out", target);
|
|
this.add('-anim', source, "Feather Dance", target);
|
|
},
|
|
onHit(target, source) {
|
|
this.boost({atk: 3, def: -3}, target);
|
|
this.boost({atk: 3, def: -3}, source);
|
|
target.addVolatile('confusion');
|
|
source.addVolatile('confusion');
|
|
target.addVolatile('flinch');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
},
|
|
// Lost Seso
|
|
shuffleramendance: {
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Special",
|
|
desc: "This move's type effectiveness is inverted, meaning that it's super effective on Water-types but not very effective on Grass-types, and so forth. 20% chance to paralyze the target.",
|
|
shortDesc: "Type effectiveness is inverted; 20% paralyze.",
|
|
id: "shuffleramendance",
|
|
name: "Shuffle Ramen Dance",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, dance: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Outrage', target);
|
|
},
|
|
onEffectiveness(typeMod, target) {
|
|
return -typeMod;
|
|
},
|
|
secondary: {
|
|
status: 'par',
|
|
chance: 20,
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
zMovePower: 160,
|
|
},
|
|
// MacChaeger
|
|
naptime: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user falls asleep for the next turn, restoring 50% of its HP and curing itself of any major status condition. If the user falls asleep in this way, all other active Pokemon that are not asleep or frozen also try to use Nap Time. Fails if the user has full HP, if the user is already asleep, or if another effect is preventing sleep.",
|
|
shortDesc: "Active Pokemon sleep 1 turn, restoring HP/status.",
|
|
id: "naptime",
|
|
name: "Nap Time",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onTryMove(pokemon) {
|
|
this.attrLastMove('[still]');
|
|
if (pokemon.hp < pokemon.maxhp && pokemon.status !== 'slp' && !pokemon.hasAbility('comatose')) return;
|
|
this.add('-fail', pokemon);
|
|
this.hint("Nap Time fails if the user has full health, is already asleep, or has Comatose.");
|
|
return null;
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Rest", target);
|
|
this.add('-anim', source, "Aromatic Mist", target);
|
|
},
|
|
onHit(target, source, move) {
|
|
let napWeather = this.field.pseudoWeather['naptime'];
|
|
// Trigger sleep clause if not the original user
|
|
if (target !== napWeather.source) {
|
|
for (const ally of target.side.pokemon) {
|
|
if (ally.status === 'slp') {
|
|
if (!(ally.statusData.source && ally.statusData.source.side === ally.side)) return false;
|
|
}
|
|
}
|
|
}
|
|
if (!target.setStatus('slp', napWeather.source, move)) return false;
|
|
target.statusData.time = 2;
|
|
target.statusData.startTime = 2;
|
|
this.heal(target.maxhp / 2); // Aesthetic only as the healing happens after you fall asleep in-game
|
|
if (napWeather.source === target) {
|
|
for (const curMon of this.getAllActive()) {
|
|
if (curMon === source) continue;
|
|
if (curMon.status !== 'slp' && curMon.status !== 'frz' && !curMon.hasAbility('comatose')) {
|
|
this.add('-anim', source, "Yawn", curMon);
|
|
this.useMove(move, curMon, curMon, move);
|
|
}
|
|
}
|
|
}
|
|
this.field.removePseudoWeather('naptime');
|
|
},
|
|
pseudoWeather: 'naptime',
|
|
effect: {
|
|
duration: 1,
|
|
},
|
|
target: "self",
|
|
type: "Fairy",
|
|
zMoveEffect: 'clearnegativeboosts',
|
|
},
|
|
// Mad Monty ¾°
|
|
"llamacide": {
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
desc: "Has a 40% chance to lower target's Defense by one stage and a 10% chance to freeze it.",
|
|
shortDesc: "40% target's Def -1. 10% chance of freeze.",
|
|
id: "llamacide",
|
|
name: "Llamacide",
|
|
pp: 10,
|
|
flags: {protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Nasty Plot", source);
|
|
this.add('-anim', source, "Plasma Fists", target);
|
|
this.add('-anim', source, "Sheer Cold", target);
|
|
},
|
|
secondaries: [
|
|
{
|
|
status: "frz",
|
|
chance: 10,
|
|
},
|
|
{
|
|
chance: 40,
|
|
boosts: {
|
|
def: -1,
|
|
},
|
|
},
|
|
],
|
|
target: "normal",
|
|
type: "Ice",
|
|
},
|
|
// MajorBowman
|
|
blazeofglory: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
damageCallback(pokemon, target) {
|
|
let damage = pokemon.hp;
|
|
pokemon.faint();
|
|
if (target.volatiles['banefulbunker'] || target.volatiles['kingsshield'] || target.side.sideConditions['matblock'] || target.volatiles['protect'] || target.volatiles['spikyshield'] || target.volatiles['lilypadshield'] || target.volatiles['backoffgrrr']) {
|
|
this.add('-zbroken', target);
|
|
return Math.floor(damage / 4);
|
|
}
|
|
return damage;
|
|
},
|
|
category: "Physical",
|
|
desc: "The user's HP is restored to maximum, and the user then faints. The target then takes damage equal to the amount of HP the user lost. This move does not check accuracy.",
|
|
shortDesc: "Does damage equal to user's max HP. User faints.",
|
|
id: "blazeofglory",
|
|
name: "Blaze of Glory",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Recover", source);
|
|
this.heal(source.maxhp, source, source, this.dex.getActiveMove('Blaze of Glory'));
|
|
this.add('-anim', source, "Final Gambit", target);
|
|
},
|
|
selfdestruct: "ifHit",
|
|
isZ: "victiniumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// Marshmallon
|
|
weatherforecast: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user heals 1/4 of their HP rounded down, is protected from most attacks made by other Pokemon during this turn, and changes the weather. The selected weather depends on the current weather. Rain: Hail, Sun: Rain, Hail: Sun, Other: Randomly pick one of Rain, Sun, and Hail. This move has a 1/X chance of being successful, where X starts at 1 and triples each time this move is successfully used. X resets to 1 if this move fails, if the user's last move used is not Baneful Bunker, Detect, Endure, King's Shield, Protect, Quick Guard, Spiky Shield, or Wide Guard, or if it was one of those moves and the user's protection was broken. Fails if the user moves last this turn.",
|
|
shortDesc: "Protect + Heal 1/4 + change weather.",
|
|
id: "weatherforecast",
|
|
name: "Weather Forecast",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 2,
|
|
flags: {heal: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Protect", source);
|
|
this.add('-anim', source, "Quiver Dance", source);
|
|
let result = !!this.willAct() && this.runEvent('StallMove', source);
|
|
return result;
|
|
},
|
|
onHit(target, source) {
|
|
let didSomething = false;
|
|
switch (this.field.weather) {
|
|
case 'raindance':
|
|
if (this.field.setWeather('hail', source)) didSomething = true;
|
|
break;
|
|
case 'sunnyday':
|
|
if (this.field.setWeather('raindance', source)) didSomething = true;
|
|
break;
|
|
case 'hail':
|
|
if (this.field.setWeather('sunnyday', source)) didSomething = true;
|
|
break;
|
|
default:
|
|
if (this.field.setWeather(['raindance', 'sunnyday', 'hail'][this.random(3)], source)) didSomething = true;
|
|
}
|
|
if (this.heal(source.maxhp / 4, source)) didSomething = true;
|
|
if (source.addVolatile('stall')) didSomething = true;
|
|
if (source.addVolatile('protect')) didSomething = true;
|
|
return didSomething;
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
},
|
|
// martha
|
|
crystalboost: {
|
|
accuracy: 90,
|
|
basePower: 75,
|
|
category: "Special",
|
|
desc: "Has a 50% chance to raise the user's Special Attack by one stage.",
|
|
shortDesc: "50% chance to raise the user's SpA by 1.",
|
|
id: "crystalboost",
|
|
name: "Crystal Boost",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Power Gem", target);
|
|
},
|
|
secondary: {
|
|
chance: 50,
|
|
self: {
|
|
boosts: {
|
|
spa: 1,
|
|
},
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Rock",
|
|
},
|
|
// Marty
|
|
typeanalysis: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "If the user is a Silvally, its item becomes a random Memory whose type matches one of the target's weaknesses, it changes forme, and it uses Multi-Attack. This move and its effects ignore the abilities of other Pokemon. Fails if the target has no weaknesses or if the user's species is not Silvally.",
|
|
shortDesc: "Changes user/move type to target's weakness.",
|
|
id: "typeanalysis",
|
|
name: "Type Analysis",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {authentic: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Conversion", source);
|
|
},
|
|
onHit(target, source) {
|
|
if (source.baseTemplate.baseSpecies !== 'Silvally') return false;
|
|
let targetTypes = target.getTypes(true).filter(type => type !== '???');
|
|
if (!targetTypes.length) {
|
|
if (target.addedType) {
|
|
targetTypes = ['Normal'];
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
let weaknesses = [];
|
|
for (let type in this.dex.data.TypeChart) {
|
|
let typeMod = this.dex.getEffectiveness(type, targetTypes);
|
|
if (typeMod > 0 && this.dex.getImmunity(type, target)) weaknesses.push(type);
|
|
}
|
|
if (!weaknesses.length) {
|
|
return false;
|
|
}
|
|
let randomType = this.sample(weaknesses);
|
|
source.setItem(randomType + 'memory');
|
|
this.add('-item', source, source.getItem(), '[from] move: Type Analysis');
|
|
let template = this.dex.getTemplate('Silvally-' + randomType);
|
|
source.formeChange(template, this.dex.getAbility('rkssystem'), true);
|
|
let move = this.dex.getActiveMove('multiattack');
|
|
move.basePower = 80;
|
|
this.useMove(move, source, target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Normal",
|
|
zMoveEffect: 'heal',
|
|
},
|
|
// Meicoo
|
|
scavengesu: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Lowers the user's Attack and Special Attack by two stages and then swaps all of its stat changes with the target.",
|
|
shortDesc: "Atk/SpA -2, then swaps all stats with foe.",
|
|
id: "scavengesu",
|
|
name: "/scavenges u",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {mirror: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Imprison", source);
|
|
this.add('-anim', source, "Miracle Eye", target);
|
|
},
|
|
onHit(target, source) {
|
|
this.boost({atk: -2, spa: -2}, source, source, this.dex.getActiveMove('/scavenges u'));
|
|
let targetBoosts = {};
|
|
let sourceBoosts = {};
|
|
|
|
for (let i in target.boosts) {
|
|
// @ts-ignore
|
|
targetBoosts[i] = target.boosts[i];
|
|
// @ts-ignore
|
|
sourceBoosts[i] = source.boosts[i];
|
|
}
|
|
|
|
target.setBoost(sourceBoosts);
|
|
source.setBoost(targetBoosts);
|
|
|
|
this.add(`c|%Meicoo|cool quiz`);
|
|
|
|
this.add('-swapboost', source, target, '[from] move: /scavenges u');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
},
|
|
// Megazard
|
|
tippingover: {
|
|
accuracy: 100,
|
|
basePower: 20,
|
|
basePowerCallback(pokemon, target, move) {
|
|
return move.basePower + 20 * pokemon.positiveBoosts();
|
|
},
|
|
category: "Physical",
|
|
desc: "Base Power rises by 20 for each of the user's positive stat stage changes. The user loses any defensive boosts not from Stockpile.",
|
|
shortDesc: "+20 BP per boost. Lose non-Stockpile +Def/SpD.",
|
|
id: "tippingover",
|
|
name: "Tipping Over",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, contact: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Dragon Hammer", target);
|
|
this.add('-anim', target, "Earthquake", target);
|
|
},
|
|
onAfterMoveSecondarySelf(pokemon) {
|
|
let stockpileLayers = 0;
|
|
if (pokemon.volatiles['stockpile']) stockpileLayers = pokemon.volatiles['stockpile'].layers;
|
|
let boosts = {};
|
|
if (pokemon.boosts.def > stockpileLayers) boosts.def = stockpileLayers - pokemon.boosts.def;
|
|
if (pokemon.boosts.spd > stockpileLayers) boosts.spd = stockpileLayers - pokemon.boosts.spd;
|
|
if (boosts.def || boosts.spd) this.boost(boosts, pokemon, pokemon);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "???",
|
|
},
|
|
// Mitsuki
|
|
pythonivy: {
|
|
accuracy: 95,
|
|
basePower: 110,
|
|
category: "Special",
|
|
desc: "Lowers the user's Special Attack, Special Defense, and Speed by one stage.",
|
|
shortDesc: "Lowers the user's SpA, SpD, and Spe by 1.",
|
|
id: "pythonivy",
|
|
name: "Python Ivy",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Leaf Tornado", target);
|
|
this.add('-anim', source, "Leaf Storm", target);
|
|
},
|
|
self: {
|
|
boosts: {
|
|
spa: -1,
|
|
spd: -1,
|
|
spe: -1,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
// Morfent
|
|
e: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "If Trick Room is not already in play, sets Trick Room for 5 turns and raises the user's Attack by one stage.",
|
|
shortDesc: "User Attack +1; sets Trick Room.",
|
|
id: "e",
|
|
name: "E",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: -6,
|
|
onModifyMove(move) {
|
|
if (!this.field.pseudoWeather.trickroom) {
|
|
move.pseudoWeather = 'trickroom';
|
|
}
|
|
},
|
|
flags: {snatch: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Recover", source);
|
|
this.add('-anim', source, "Nasty Plot", source);
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ghost",
|
|
},
|
|
// Used for nui's ability
|
|
prismaticterrain: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "For 5 turns, the terrain becomes Prismatic Terrain. During the effect, the power of Ice-type attacks is multiplied by 0.5, even if the user is not grounded. Hazards and screens are removed and cannot be set while Prismatic Terrain is active. Fails if the current terrain is Prismatic Terrain.",
|
|
shortDesc: "5 turns. No hazards, -Ice power even if floating.",
|
|
id: "prismaticterrain",
|
|
name: "Prismatic Terrain",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
terrain: 'prismaticterrain',
|
|
effect: {
|
|
duration: 5,
|
|
durationCallback(source, effect) {
|
|
if (source && source.hasItem('terrainextender')) {
|
|
return 8;
|
|
}
|
|
return 5;
|
|
},
|
|
onBasePower(basePower, attacker, defender, move) {
|
|
if (move.type === 'Ice') {
|
|
this.debug('prismatic terrain weaken');
|
|
return this.chainModify(0.5);
|
|
}
|
|
},
|
|
onStart(battle, source, effect) {
|
|
if (effect && effect.effectType === 'Ability') {
|
|
this.add('-fieldstart', 'move: Prismatic Terrain', '[from] ability: ' + effect, '[of] ' + source);
|
|
} else {
|
|
this.add('-fieldstart', 'move: Prismatic Terrain');
|
|
}
|
|
this.add('-message', 'The battlefield suddenly got a refractive high poly count!');
|
|
let removeAll = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb'];
|
|
for (const sideCondition of removeAll) {
|
|
if (source.side.foe.removeSideCondition(sideCondition)) {
|
|
this.add('-sideend', source.side.foe, this.dex.getEffect(sideCondition).name, '[from] move: Prismatic Terrain', '[of] ' + source);
|
|
}
|
|
if (source.side.removeSideCondition(sideCondition)) {
|
|
this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Prismatic Terrain', '[of] ' + source);
|
|
}
|
|
}
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 2,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Prismatic Terrain');
|
|
this.add('-message', 'The battlefield no longer has a refractive high poly count!');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Fairy",
|
|
},
|
|
// nui
|
|
pyramidingsong: {
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "If the target has not fainted, both the user and the target are forced to switch out and be replaced with a chosen unfainted ally. The target's replacement has its Speed lowered by 1 stage. Fails if either Pokemon is under the effect of Ingrain or Suction Cups.",
|
|
shortDesc: "Both Pokemon switch. Opp. replacement: Spe -1.",
|
|
id: "pyramidingsong",
|
|
name: "Pyramiding Song",
|
|
isNonstandard: "Custom",
|
|
pp: 20,
|
|
priority: -6,
|
|
flags: {mirror: 1, protect: 1, authentic: 1, sound: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Freeze Dry", target);
|
|
this.add('-anim', source, "Mist", target);
|
|
},
|
|
onTryHit(target, source, move) {
|
|
target.side.addSlotCondition(target, 'pyramidingsong');
|
|
},
|
|
onHit(target, source, move) {
|
|
if (this.runEvent('DragOut', source, target, move)) {
|
|
source.forceSwitchFlag = true;
|
|
}
|
|
},
|
|
effect: {
|
|
duration: 1,
|
|
onSwitchIn(pokemon) {
|
|
this.boost({spe: -1}, pokemon, pokemon.side.foe.active[0], this.dex.getActiveMove('pyramidingsong'));
|
|
},
|
|
},
|
|
forceSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Water",
|
|
zMoveEffect: "boostreplacement",
|
|
},
|
|
// OM
|
|
omboom: {
|
|
accuracy: 95,
|
|
basePower: 110,
|
|
category: "Physical",
|
|
desc: "Has a 50% chance to raise the user's Speed by two stages and a 5% chance to raise the user's Attack by one stage. Only one will ever activate on a single use",
|
|
shortDesc: "50% chance of Spe +2 or 5% chance of Atk +1.",
|
|
id: "omboom",
|
|
name: "OM Boom",
|
|
isNonstandard: "Custom",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {mirror: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Fire Lash", target);
|
|
this.add('-anim', source, "Heat Crash", target);
|
|
},
|
|
onHit() {
|
|
this.add(`c|@OM|Bang Bang`);
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
onHit(target, source) {
|
|
if (this.random(2) === 0) {
|
|
this.boost({spe: 2}, source);
|
|
} else if (this.random(20) === 0) {
|
|
this.boost({atk: 1}, source);
|
|
}
|
|
},
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// Overneat
|
|
ultimateslash: {
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
desc: "If this attack does not miss, the effects of Reflect, Light Screen, and Aurora Veil end for the target's side of the field before damage is calculated. If the user has not fainted, the target loses its held item.",
|
|
shortDesc: "Destroys screens. Removes foe's item.",
|
|
id: "ultimateslash",
|
|
name: "Ultimate Slash",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Night Slash", target);
|
|
},
|
|
onTryHit(pokemon) {
|
|
// will shatter screens through sub, before you hit
|
|
if (pokemon.runImmunity('Dark')) {
|
|
pokemon.side.removeSideCondition('reflect');
|
|
pokemon.side.removeSideCondition('lightscreen');
|
|
pokemon.side.removeSideCondition('auroraveil');
|
|
}
|
|
},
|
|
onAfterHit(target, source) {
|
|
if (source.hp) {
|
|
let item = target.takeItem();
|
|
if (item) {
|
|
this.add('-enditem', target, item.name, '[from] move: Ultimate Slash', '[of] ' + source);
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
// Pablo
|
|
jailshell: {
|
|
accuracy: 90,
|
|
basePower: 90,
|
|
category: "Special",
|
|
desc: "This move has a 50% change to paralyze the target and prevents the target from switching out or using any moves that the user also knows while the user is active.",
|
|
shortDesc: "50% chance to paralyze. Traps and imprisons.",
|
|
id: "jailshell",
|
|
name: "Jail Shell",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Anchor Shot", target);
|
|
},
|
|
onHit(target, source, move) {
|
|
if (source.isActive) target.addVolatile('trapped', source, move, 'trapper');
|
|
source.addVolatile('imprison', source, move);
|
|
},
|
|
secondary: {
|
|
chance: 50,
|
|
status: 'par',
|
|
},
|
|
target: "normal",
|
|
type: "Normal",
|
|
},
|
|
// Paradise
|
|
corrosivetoxic: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Badly poisons the target, even if they are Poison-type or Steel-type. This move does not check accuracy.",
|
|
shortDesc: "Badly poisons the target, regardless of type.",
|
|
id: "corrosivetoxic",
|
|
name: "Corrosive Toxic",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, reflectable: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Toxic", target);
|
|
},
|
|
// Innate corrosive implemented in BattleScripts#setStatus
|
|
status: 'tox',
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
},
|
|
// Pirate Princess
|
|
teabreak: {
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user attempts to use Toxic followed by Venoshock, then Rest and Sleep Talk.",
|
|
shortDesc: "Toxic -> Venoshock -> Rest -> Sleep Talk.",
|
|
id: "teabreak",
|
|
name: "Tea Break",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, authentic: 1},
|
|
sleepUsable: true,
|
|
onTryMove(pokemon) {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onHit(target, source) {
|
|
this.useMove('Toxic', source, target);
|
|
this.useMove('Venoshock', source, target);
|
|
if (source.hp !== source.maxhp) this.useMove('Rest', source, source);
|
|
if (source.status === 'slp' || source.hasAbility('comatose')) this.useMove('Sleep Talk', source, target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
},
|
|
// Used for PiratePrincess's ability
|
|
acidrain: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "For 5 turns, the weather becomes Acid Rain. Pokemon that are not Poison-type take damage every turn. Special Defense of Poison-type pokemon is multiplied by 1.5.",
|
|
shortDesc: "5 turns: +Poison SpD, corrosive damage.",
|
|
id: "acidrain",
|
|
name: "Acid Rain",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
weather: 'acidrain',
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Rain Dance', source);
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Poison",
|
|
},
|
|
// pluviometer
|
|
grammarhammer: {
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
desc: "100% chance to burn the target.",
|
|
shortDesc: "100% chance to burn the target.",
|
|
id: "grammarhammer",
|
|
name: "Grammar Hammer",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {contact: 1, protect: 1, mirror: 1, punch: 1},
|
|
onPrepareHit(target, source) {
|
|
this.attrLastMove('[still]');
|
|
this.add('-anim', source, "Hammer Arm", target);
|
|
},
|
|
onHit(target, source) {
|
|
if (target.name === 'HoeenHero') {
|
|
this.add(`c|@pluviometer|HoennHero*`);
|
|
this.add(`c|~HoeenHero|I can speel`);
|
|
}
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Ghost",
|
|
},
|
|
// Pohjis
|
|
greateqake: {
|
|
accuracy: true,
|
|
basePower: 200,
|
|
category: "Physical",
|
|
desc: "No additional effect.",
|
|
shortDesc: "No additional effect.",
|
|
id: "greateqake",
|
|
name: "Great Eqake",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Tectonic Rage", target);
|
|
},
|
|
isZ: "marowakiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Ground",
|
|
},
|
|
// PokemonDeadChannel
|
|
expressyourself: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
isNonstandard: "Custom",
|
|
desc: "The user is healed for 50% of its HP. All Pokemon in the team's party get healed by 12.5% of their maximum HP.",
|
|
shortDesc: "User heals 50% HP. User's team heals 12.5% HP.",
|
|
id: "expressyourself",
|
|
name: "Express Yourself",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1, heal: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Tail Glow', source);
|
|
this.add('-anim', source, 'Discharge', source);
|
|
},
|
|
onHit(target, source) {
|
|
this.heal(source.maxhp / 2, source);
|
|
if (!this.canSwitch(source.side)) return;
|
|
for (const ally of source.side.pokemon) {
|
|
if (ally === source) continue;
|
|
if (ally.fainted || !ally.hp) continue;
|
|
ally.heal(ally.maxhp / 8, ally);
|
|
}
|
|
this.add('-message', `${source.name} restored everyone's HP.`);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Fairy",
|
|
},
|
|
// pre
|
|
"refactor": {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user swaps all its stat stage changes with the target, then takes 1/4 of its maximum HP, rounded down, and puts it into a substitute to take its place in battle.",
|
|
shortDesc: "Swaps all stat changes with target + Substitute.",
|
|
id: "refactor",
|
|
name: "Refactor",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, authentic: 1, mystery: 1, snatch: 1, nonsky: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Skill Swap', target);
|
|
},
|
|
onTryHit(target, source) {
|
|
if (source.volatiles['substitute']) {
|
|
this.add('-fail', source, 'move: Refactor');
|
|
return null;
|
|
}
|
|
if (source.hp <= source.maxhp / 4) {
|
|
this.add('-fail', source, 'move: Refactor', '[weak]');
|
|
return null;
|
|
}
|
|
},
|
|
onHit(target, source) {
|
|
let targetBoosts = {};
|
|
let sourceBoosts = {};
|
|
|
|
for (let i in target.boosts) {
|
|
// @ts-ignore
|
|
targetBoosts[i] = target.boosts[i];
|
|
// @ts-ignore
|
|
sourceBoosts[i] = source.boosts[i];
|
|
}
|
|
|
|
target.setBoost(sourceBoosts);
|
|
source.setBoost(targetBoosts);
|
|
|
|
this.add('-swapboost', source, target, '[from] move: Refactor');
|
|
this.directDamage(source.maxhp / 4, source);
|
|
},
|
|
self: {
|
|
volatileStatus: 'substitute',
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
},
|
|
// ptoad
|
|
lilypadshield: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user is protected from most moves made by other Pokemon during this turn, and if a Pokemon makes contact with the user, the user restores 1/4 of its maximum HP, rounded half up. This move has a 1/X chance of being successful, where X starts at 1 and doubles each time this move is successfully used. X resets to 1 if this move fails, if the user's last move used is not Baneful Bunker, Detect, Endure, King's Shield, Protect, Quick Guard, Spiky Shield, Wide Guard, or this move, or if it was one of those moves and the user's protection was broken. Fails if the user moves last this turn.",
|
|
shortDesc: "Protects from moves. Contact: restores 25% HP.",
|
|
id: "lilypadshield",
|
|
name: "Lilypad Shield",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 4,
|
|
flags: {heal: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Spiky Shield", source);
|
|
},
|
|
stallingMove: true,
|
|
volatileStatus: 'lilypadshield',
|
|
onTryHit(target, source, move) {
|
|
return !!this.willAct() && this.runEvent('StallMove', target);
|
|
},
|
|
onHit(pokemon) {
|
|
pokemon.addVolatile('stall');
|
|
},
|
|
effect: {
|
|
duration: 1,
|
|
onStart(target) {
|
|
this.add('-singleturn', target, 'move: Protect');
|
|
},
|
|
onTryHitPriority: 3,
|
|
onTryHit(target, source, move) {
|
|
if (!move.flags['protect']) {
|
|
if (move.isZ) target.getMoveHitData(move).zBrokeProtect = true;
|
|
return;
|
|
}
|
|
this.add('-activate', target, 'move: Protect');
|
|
let lockedmove = source.getVolatile('lockedmove');
|
|
if (lockedmove) {
|
|
// Outrage counter is reset
|
|
if (source.volatiles['lockedmove'].duration === 2) {
|
|
delete source.volatiles['lockedmove'];
|
|
}
|
|
}
|
|
if (move.flags['contact']) {
|
|
this.heal(target.maxhp / 4, target, target);
|
|
}
|
|
return null;
|
|
},
|
|
onHit(target, source, move) {
|
|
if (move.isZPowered && move.flags['contact']) {
|
|
this.heal(target.maxhp / 4, target, target);
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Grass",
|
|
},
|
|
// Psynergy
|
|
resolve: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Raises the user's Speed by one stage. Gives Focus Energy.",
|
|
shortDesc: "Raises user's Speed by 1; Focus Energy.",
|
|
id: "resolve",
|
|
name: "Resolve",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Acupressure", source);
|
|
this.add('-anim', source, "Flare Blitz", source);
|
|
},
|
|
onHit(target, source) {
|
|
source.addVolatile('focusenergy', source);
|
|
},
|
|
boosts: {
|
|
spe: 1,
|
|
},
|
|
target: "self",
|
|
type: "Fighting",
|
|
},
|
|
// Quite Quiet
|
|
literallycheating: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "For seven turns, any Pokemon that has one of their stats boosted through any manner loses all PP on the last move they used.",
|
|
shortDesc: "7 turns: boosting stat: lose all PP from last move.",
|
|
id: "literallycheating",
|
|
name: "Literally Cheating",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Genesis Supernova", source);
|
|
},
|
|
pseudoWeather: 'literallycheating',
|
|
effect: {
|
|
duration: 7,
|
|
onBoost(boost, target, source, effect) {
|
|
let positiveBoost = false;
|
|
let values = Object.values(boost);
|
|
for (let i of values) {
|
|
if (i !== undefined && i > 0) {
|
|
positiveBoost = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!positiveBoost || !target.lastMove) return;
|
|
for (const moveSlot of target.moveSlots) {
|
|
if (moveSlot.id === target.lastMove.id) {
|
|
target.deductPP(moveSlot.id, moveSlot.pp);
|
|
}
|
|
}
|
|
this.add('-activate', target, 'move: Literally Cheating', target.lastMove.name, target.lastMove.pp);
|
|
this.add('-message', `${target.name} lost all PP for the move ${target.lastMove.name}!`);
|
|
},
|
|
onStart(battle, source, effect) {
|
|
this.add('-fieldstart', 'move: Literally Cheating');
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 2,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Literally Cheating');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Ghost",
|
|
},
|
|
// Rach
|
|
stunner: {
|
|
accuracy: 85,
|
|
basePower: 95,
|
|
category: "Physical",
|
|
desc: "Has a 50% chance to raise the user's Attack by one stage and a 20% chance to paralyze the foe or cause them to flinch.",
|
|
shortDesc: "50% user's Atk +1. 20% flinch or paralyze foe.",
|
|
id: "stunner",
|
|
name: "Stunner",
|
|
pp: 10,
|
|
priority: 0,
|
|
isNonstandard: "Custom",
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Zen Headbutt", target);
|
|
},
|
|
flags: {protect: 1, mirror: 1, contact: 1},
|
|
secondaries: [
|
|
{
|
|
chance: 50,
|
|
self: {
|
|
boosts: {atk: 1},
|
|
},
|
|
}, {
|
|
chance: 20,
|
|
onHit(target, source) {
|
|
let result = this.random(2);
|
|
if (result === 0) {
|
|
target.trySetStatus('par', source);
|
|
} else {
|
|
target.addVolatile('flinch', source);
|
|
}
|
|
},
|
|
},
|
|
],
|
|
target: "normal",
|
|
type: "Electric",
|
|
},
|
|
// Rage
|
|
rageeeee: {
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
category: "Physical",
|
|
desc: "The user becomes affected with the effects of Rage and Endure. The opponent's next attack will hit 2 to 5 times with a Base Power of 25.",
|
|
shortDesc: "Rage + Endure. Foe: next move 2-5 hits at 25 BP.",
|
|
id: "rageeeee",
|
|
name: "Rageeeee",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, contact: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Rage", target);
|
|
},
|
|
onHit(target, source) {
|
|
source.addVolatile('rage', source);
|
|
if (this.willAct() && this.runEvent('StallMove', source)) {
|
|
this.debug('Rageeeee endure');
|
|
source.addVolatile('endure', source);
|
|
source.addVolatile('stall');
|
|
}
|
|
target.addVolatile('enrageeeeed', source);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Flying",
|
|
},
|
|
// Raid
|
|
firestorm: {
|
|
accuracy: 90,
|
|
basePower: 100,
|
|
category: "Special",
|
|
desc: "100% chance to burn the target.",
|
|
shortDesc: "100% chance to burn the target.",
|
|
id: "firestorm",
|
|
name: "Firestorm",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Fire Spin", target);
|
|
this.add('-anim', source, "Hurricane", target);
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// Ransei
|
|
mashupmotive: {
|
|
accuracy: 100,
|
|
basePower: 80,
|
|
category: "Physical",
|
|
desc: "Raises the user's accuracy by one stage. 50% chance to raise Attack by one stage.",
|
|
shortDesc: "Accuracy +1. 50% chance to raise Atk by 1.",
|
|
id: "mashupmotive",
|
|
name: "Mashup Motive",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Revelation Dance", target);
|
|
},
|
|
secondaries: [
|
|
{
|
|
chance: 50,
|
|
self: {
|
|
boosts: {atk: 1},
|
|
},
|
|
},
|
|
{
|
|
chance: 100,
|
|
self: {
|
|
boosts: {accuracy: 1},
|
|
},
|
|
},
|
|
],
|
|
target: "normal",
|
|
type: "Normal",
|
|
},
|
|
// Rory Mercury
|
|
switchoff: {
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
category: "Physical",
|
|
desc: "Before doing damage, the target's stat boosts are inverted. The user switches out after damaging the target.",
|
|
shortDesc: "Inverts target's boosts, then switches.",
|
|
id: "switchoff",
|
|
name: "Switch Off",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {mirror: 1, protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Topsy-Turvy", target);
|
|
this.add('-anim', source, "Zing Zap", target);
|
|
},
|
|
onTryHit(target, source, move) {
|
|
let success = false;
|
|
for (let i in target.boosts) {
|
|
// @ts-ignore
|
|
if (target.boosts[i] === 0) continue;
|
|
// @ts-ignore
|
|
target.boosts[i] = -target.boosts[i];
|
|
success = true;
|
|
}
|
|
if (!success) return;
|
|
this.add('-invertboost', target, '[from] move: Switch Off');
|
|
},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
},
|
|
// SamJo
|
|
thicc: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Raises the user's Attack and accuracy by one stage.",
|
|
shortDesc: "Raises the user's Attack and accuracy by 1.",
|
|
id: "thicc",
|
|
name: "Thicc",
|
|
isNonstandard: "Custom",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Hone Claws", source);
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
accuracy: 1,
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ice",
|
|
},
|
|
// SamJo Z-Move
|
|
extrathicc: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Raises the user's Attack and accuracy by one stage. Summons Hail and Aurora Veil.",
|
|
shortDesc: "User's Atk and acc +1. Sets Hail and Aurora Veil.",
|
|
id: "extrathicc",
|
|
name: "Extra T h i c c",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Hone Claws", source);
|
|
this.add('-anim', source, "Extreme Evoboost", source);
|
|
this.add('-anim', source, "Blizzard", source);
|
|
},
|
|
onHit(target, source) {
|
|
this.field.setWeather('hail');
|
|
if (this.field.isWeather('hail')) source.side.addSideCondition('auroraveil', source);
|
|
this.add('-message', source.name + ' became extra thicc!');
|
|
},
|
|
boosts: {
|
|
atk: 1,
|
|
accuracy: 1,
|
|
},
|
|
isZ: "thicciniumz",
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Ice",
|
|
},
|
|
// Schiavetto
|
|
plurshift: {
|
|
accuracy: 100,
|
|
basePower: 120,
|
|
category: "Physical",
|
|
desc: "Has a 10% chance, calculated separately per effect, to apply any of Taunt, confusion, flinch, Heal Block, or Focus Energy to the target. Afterwards, the user is switched out for another Pokemon in its party. The selected Pokemon has the user's stat stage changes, confusion, and certain move effects transferred to it. ",
|
|
shortDesc: "Multiple status effects, then uses Baton Pass.",
|
|
id: "plurshift",
|
|
name: "Plurshift",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {contact: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "First Impression", target);
|
|
this.add('-anim', target, "Infestation", target);
|
|
},
|
|
onHit(target, source) {
|
|
source.addVolatile('batonpasshelper');
|
|
},
|
|
secondaries: [
|
|
{
|
|
volatileStatus: "taunt",
|
|
chance: 10,
|
|
},
|
|
{
|
|
volatileStatus: "confusion",
|
|
chance: 10,
|
|
},
|
|
{
|
|
volatileStatus: "flinch",
|
|
chance: 10,
|
|
},
|
|
{
|
|
volatileStatus: "healblock",
|
|
chance: 10,
|
|
},
|
|
{
|
|
volatileStatus: "focusenergy",
|
|
chance: 10,
|
|
},
|
|
],
|
|
selfSwitch: 'copyvolatile',
|
|
isZ: "mariahcariumz",
|
|
target: "normal",
|
|
type: "Poison",
|
|
},
|
|
// Scotteh
|
|
geomagneticstorm: {
|
|
accuracy: 100,
|
|
basePower: 140,
|
|
category: "Special",
|
|
desc: "No additional effect.",
|
|
shortDesc: "No additional effect.",
|
|
id: "geomagneticstorm",
|
|
name: "Geomagnetic Storm",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Discharge", target);
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacent",
|
|
type: "Electric",
|
|
},
|
|
// Shiba
|
|
goinda: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Raises the user's Attack by two stages and Speed by one stage.",
|
|
shortDesc: "Raises the user's Attack by 2 and Speed by 1.",
|
|
id: "goinda",
|
|
name: "GO INDA",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Swords Dance", source);
|
|
this.add('-anim', source, "Sacred Fire", source);
|
|
},
|
|
boosts: {
|
|
atk: 2,
|
|
spe: 1,
|
|
},
|
|
target: "self",
|
|
type: "Flying",
|
|
},
|
|
// Slowbroth
|
|
alienwave: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "For 5 turns, slower Pokemon move first. Psychic-type attacks can hit if the target is a Dark-type.",
|
|
shortDesc: "5 turns: Trick Room; Psychic hits Dark.",
|
|
id: "alienwave",
|
|
name: "Alien Wave",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: -7,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Telekinesis", source);
|
|
this.add('-anim', source, "Trick Room", source);
|
|
},
|
|
pseudoWeather: 'alienwave',
|
|
effect: {
|
|
duration: 5,
|
|
onStart(target, source) {
|
|
this.add('-fieldstart', 'move: Alien Wave');
|
|
this.add('-message', `Psychic-type attacks can hit Dark-type Pokemon!`);
|
|
},
|
|
onNegateImmunity(pokemon, type) {
|
|
if (pokemon.hasType('Dark') && type === 'Psychic') return false;
|
|
},
|
|
// Speed modification is changed in Pokemon.getActionSpeed() in mods/seasonal/scripts.js
|
|
onResidualOrder: 23,
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Alien Wave');
|
|
this.add('-message', `Psychic-type attacks can no longer hit Dark-type Pokemon.`);
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "all",
|
|
type: "Normal",
|
|
},
|
|
// Snaquaza
|
|
fakeclaim: {
|
|
accuracy: true,
|
|
category: "Physical",
|
|
basePower: 1,
|
|
desc: "The user creates a substitute to take its place in battle. This substitute is a Pokemon selected from a broad set of Random Battle-eligible Pokemon able to learn the move chosen as this move's base move. Upon the substitute's creation, this Pokemon's ability is suppressed until it switches out. The substitute Pokemon is generated with a Random Battle moveset with maximum PP that is added (except for duplicates) to the user's moveset; these additions are removed when this substitute is no longer active. The substitute uses its species's base stats, types, Ability, and weight but retains the user's max HP, stat stages, gender, level, status conditions, trapping, binding, and pseudo-statuses such as confusion. Its HP is 100% of the user's maximum HP. When this substitute falls to zero HP, it breaks, and the user reverts to the state in which it used this move. This substitute absorbs indirect damage and authentic moves but does not reset the counter of Toxic poison when broken and cannot be transfered through Baton Pass. Transforming into this substitute will not fail. If the user switches out while the substitute is up, the substitute will be removed and the user will revert to the state in which it used this move. This move's properties are based on the move Fake Claim is inheriting from.",
|
|
shortDesc: "Uses a Random Battle Pokemon as a Substitute.",
|
|
id: "fakeclaim",
|
|
name: "Fake Claim",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onModifyMove(move) {
|
|
// @ts-ignore Hack for Snaquaza's Z move
|
|
move.type = move.baseMove ? move.baseMove.type : move.type;
|
|
// @ts-ignore Hack for Snaquaza's Z move
|
|
move.basePower = move.baseMove ? move.baseMove.basePower : move.basePower;
|
|
// @ts-ignore Hack for Snaquaza's Z move
|
|
move.category = move.baseMove ? move.baseMove.category : move.category;
|
|
// @ts-ignore Hack for Snaquaza's Z move
|
|
this.claimMove = move.baseMove;
|
|
},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source, move) {
|
|
let zmove = this.dex.getMove(this.zMoveTable[move.type]);
|
|
this.add('-anim', source, zmove.name, target);
|
|
this.add('-anim', source, "Transform", source);
|
|
},
|
|
onAfterMoveSecondarySelf(pokemon, move) {
|
|
/** @type {{[move: string]: string[]}} */
|
|
let claims = {
|
|
bravebird: ['Braviary', 'Crobat', 'Decidueye', 'Dodrio', 'Farfetch\'d', 'Golbat', 'Mandibuzz', 'Pidgeot', 'Skarmory', 'Staraptor', 'Swanna', 'Swellow', 'Talonflame', 'Tapu Koko', 'Toucannon'],
|
|
superpower: ['Absol', 'Aggron', 'Armaldo', 'Avalugg', 'Azumarill', 'Barbaracle', 'Basculin', 'Beartic', 'Bewear', 'Bibarel', 'Bouffalant', 'Braviary', 'Breloom', 'Buzzwole', 'Cacturne', 'Carracosta', 'Celesteela', 'Chesnaught', 'Cobalion', 'Conkeldurr', 'Crabominable', 'Crawdaunt', 'Darmanitan', 'Diggersby', 'Donphan', 'Dragonite', 'Drampa', 'Druddigon', 'Durant', 'Eelektross', 'Emboar', 'Exeggutor-Alola', 'Feraligatr', 'Flareon', 'Flygon', 'Gigalith', 'Gogoat', 'Golem', 'Golurk', 'Goodra', 'Granbull', 'Gurdurr', 'Hariyama', 'Hawlucha', 'Haxorus', 'Heatmor', 'Hippowdon', 'Hitmonlee', 'Hydreigon', 'Incineroar', 'Kabutops', 'Keldeo', 'Kingler', 'Komala', 'Kommo-o', 'Krookodile', 'Landorus-Therian', 'Lurantis', 'Luxray', 'Machamp', 'Malamar', 'Mamoswine', 'Mew', 'Mudsdale', 'Nidoking', 'Nidoqueen', 'Pangoro', 'Passimian', 'Piloswine', 'Pinsir', 'Rampardos', 'Regice', 'Regigigas', 'Regirock', 'Registeel', 'Reuniclus', 'Rhydon', 'Rhyperior', 'Samurott', 'Sawk', 'Scizor', 'Scolipede', 'Simipour', 'Simisage', 'Simisear', 'Smeargle', 'Snorlax', 'Spinda', 'Stakataka', 'Stoutland', 'Swampert', 'Tapu Bulu', 'Terrakion', 'Throh', 'Thundurus', 'Torkoal', 'Tornadus', 'Torterra', 'Tyranitar', 'Tyrantrum', 'Ursaring', 'Virizion', 'Zeraora'],
|
|
suckerpunch: ['Absol', 'Arbok', 'Ariados', 'Banette', 'Bisharp', 'Cacturne', 'Celebi', 'Corsola', 'Decidueye', 'Delcatty', 'Drifblim', 'Druddigon', 'Dugtrio', 'Dusknoir', 'Electrode', 'Emboar', 'Froslass', 'Furfrou', 'Furret', 'Galvantula', 'Gengar', 'Girafarig', 'Golem', 'Golisopod', 'Heatmor', 'Hitmonlee', 'Hitmontop', 'Houndoom', 'Huntail', 'Kangaskhan', 'Kecleon', 'Komala', 'Lanturn', 'Latias', 'Liepard', 'Lycanroc', 'Maractus', 'Mawile', 'Meowstic', 'Mew', 'Mightyena', 'Mismagius', 'Nidoking', 'Nidoqueen', 'Purugly', 'Raticate', 'Rotom', 'Sableye', 'Seviper', 'Shiftry', 'Skuntank', 'Slaking', 'Smeargle', 'Spinda', 'Spiritomb', 'Stantler', 'Sudowoodo', 'Toxicroak', 'Umbreon', 'Victreebel', 'Wormadam', 'Xatu'],
|
|
flamethrower: ['Absol', 'Aerodactyl', 'Aggron', 'Altaria', 'Arcanine', 'Audino', 'Azelf', 'Bastiodon', 'Blacephalon', 'Blissey', 'Camerupt', 'Castform', 'Celesteela', 'Chandelure', 'Chansey', 'Charizard', 'Clefable', 'Clefairy', 'Darmanitan', 'Delphox', 'Dragonite', 'Drampa', 'Druddigon', 'Dunsparce', 'Eelektross', 'Electivire', 'Emboar', 'Entei', 'Exeggutor-Alola', 'Exploud', 'Flareon', 'Flygon', 'Furret', 'Garchomp', 'Golem', 'Goodra', 'Gourgeist', 'Granbull', 'Guzzlord', 'Gyarados', 'Heatmor', 'Heatran', 'Houndoom', 'Hydreigon', 'Incineroar', 'Infernape', 'Kangaskhan', 'Kecleon', 'Kommo-o', 'Lickilicky', 'Machamp', 'Magcargo', 'Magmortar', 'Malamar', 'Manectric', 'Marowak', 'Mawile', 'Mew', 'Moltres', 'Muk', 'Nidoking', 'Nidoqueen', 'Ninetales', 'Noivern', 'Octillery', 'Pyroar', 'Rampardos', 'Rapidash', 'Rhydon', 'Rhyperior', 'Salamence', 'Salazzle', 'Seviper', 'Silvally', 'Simisear', 'Skuntank', 'Slaking', 'Slowbro', 'Slowking', 'Slurpuff', 'Smeargle', 'Snorlax', 'Solrock', 'Talonflame', 'Tauros', 'Togekiss', 'Torkoal', 'Turtonator', 'Typhlosion', 'Tyranitar', 'Watchog', 'Weezing', 'Wigglytuff', 'Zangoose'],
|
|
thunderbolt: ['Absol', 'Aggron', 'Ambipom', 'Ampharos', 'Aromatisse', 'Audino', 'Aurorus', 'Azelf', 'Banette', 'Bastiodon', 'Beheeyem', 'Bibarel', 'Blissey', 'Castform', 'Chansey', 'Cinccino', 'Clefable', 'Clefairy', 'Dedenne', 'Delcatty', 'Dragalge', 'Dragonite', 'Drampa', 'Drifblim', 'Dunsparce', 'Eelektross', 'Electivire', 'Electrode', 'Emolga', 'Ferroseed', 'Ferrothorn', 'Froslass', 'Furret', 'Gallade', 'Galvantula', 'Garbodor', 'Gardevoir', 'Gengar', 'Girafarig', 'Golem-Alola', 'Golurk', 'Goodra', 'Gothitelle', 'Granbull', 'Gyarados', 'Heliolisk', 'Illumise', 'Jirachi', 'Jolteon', 'Kangaskhan', 'Kecleon', 'Klinklang', 'Lanturn', 'Lapras', 'Latias', 'Latios', 'Lickilicky', 'Linoone', 'Lopunny', 'Luxray', 'Magearna', 'Magmortar', 'Magneton', 'Magnezone', 'Malamar', 'Manectric', 'Marowak-Alola', 'Marowak-Alola-Totem', 'Meloetta', 'Meowstic', 'Mesprit', 'Mew', 'Miltank', 'Mimikyu', 'Minun', 'Mismagius', 'Mr. Mime', 'Muk', 'Nidoking', 'Nidoqueen', 'Nihilego', 'Oranguru', 'Pachirisu', 'Persian', 'Plusle', 'Porygon-Z', 'Porygon2', 'Primeape', 'Probopass', 'Purugly', 'Raichu', 'Raikou', 'Rampardos', 'Raticate', 'Regice', 'Regigigas', 'Regirock', 'Registeel', 'Rhydon', 'Rhyperior', 'Rotom', 'Silvally', 'Slaking', 'Slurpuff', 'Smeargle', 'Snorlax', 'Stantler', 'Starmie', 'Stoutland', 'Stunfisk', 'Tapu Koko', 'Tapu Lele', 'Tauros', 'Thundurus', 'Togedemaru', 'Tyranitar', 'Uxie', 'Vikavolt', 'Volbeat', 'Watchog', 'Weezing', 'Wigglytuff', 'Xurkitree', 'Zangoose', 'Zapdos', 'Zebstrika', 'Zeraora'],
|
|
icebeam: ['Abomasnow', 'Absol', 'Aggron', 'Alomomola', 'Altaria', 'Araquanid', 'Articuno', 'Audino', 'Aurorus', 'Avalugg', 'Azumarill', 'Barbaracle', 'Basculin', 'Bastiodon', 'Beartic', 'Bibarel', 'Blastoise', 'Blissey', 'Bruxish', 'Carracosta', 'Castform', 'Chansey', 'Clawitzer', 'Claydol', 'Clefable', 'Clefairy', 'Cloyster', 'Corsola', 'Crabominable', 'Crawdaunt', 'Cresselia', 'Cryogonal', 'Delcatty', 'Delibird', 'Dewgong', 'Dragonite', 'Drampa', 'Dunsparce', 'Dusknoir', 'Empoleon', 'Exploud', 'Feraligatr', 'Floatzel', 'Froslass', 'Furret', 'Gastrodon', 'Glaceon', 'Glalie', 'Golduck', 'Golisopod', 'Golurk', 'Goodra', 'Gorebyss', 'Greninja', 'Gyarados', 'Huntail', 'Jellicent', 'Jynx', 'Kabutops', 'Kangaskhan', 'Kecleon', 'Kingdra', 'Kingler', 'Kyurem', 'Lanturn', 'Lapras', 'Latias', 'Latios', 'Lickilicky', 'Linoone', 'Lopunny', 'Ludicolo', 'Lumineon', 'Lunatone', 'Luvdisc', 'Magearna', 'Mamoswine', 'Manaphy', 'Mantine', 'Marowak', 'Masquerain', 'Mawile', 'Mesprit', 'Mew', 'Milotic', 'Miltank', 'Nidoking', 'Nidoqueen', 'Ninetales-Alola', 'Octillery', 'Omastar', 'Pelipper', 'Phione', 'Piloswine', 'Politoed', 'Poliwrath', 'Porygon-Z', 'Porygon2', 'Primarina', 'Quagsire', 'Qwilfish', 'Rampardos', 'Raticate', 'Regice', 'Relicanth', 'Rhydon', 'Rhyperior', 'Samurott', 'Seaking', 'Sharpedo', 'Sigilyph', 'Silvally', 'Simipour', 'Slaking', 'Slowbro', 'Slowking', 'Smeargle', 'Sneasel', 'Snorlax', 'Starmie', 'Suicune', 'Swalot', 'Swampert', 'Swanna', 'Tapu Fini', 'Tauros', 'Tentacruel', 'Toxapex', 'Tyranitar', 'Vanilluxe', 'Vaporeon', 'Wailord', 'Walrein', 'Weavile', 'Whiscash', 'Wigglytuff', 'Wishiwashi', 'Zangoose'],
|
|
};
|
|
// @ts-ignore Hack for Snaquaza's Z move
|
|
const baseMove = this.claimMove ? this.claimMove.id : 'bravebird';
|
|
const pool = claims[baseMove];
|
|
if (!pool) throw new Error(`SSB: Unable to find fake claim movepool for the move: "${baseMove}".`); // Should never happen
|
|
const claim = claims[baseMove][this.random(pool.length)];
|
|
// Generate new set
|
|
const generator = new RandomStaffBrosTeams('gen7randombattle', this.prng);
|
|
let set = generator.randomSet(claim);
|
|
// Suppress Ability now to prevent starting new abilities when transforming
|
|
pokemon.addVolatile('gastroacid', pokemon);
|
|
// Tranform into it
|
|
pokemon.formeChange(set.species);
|
|
for (let newMove of set.moves) {
|
|
let moveTemplate = this.dex.getMove(newMove);
|
|
if (pokemon.moves.includes(moveTemplate.id)) continue;
|
|
pokemon.moveSlots.push({
|
|
move: moveTemplate.name,
|
|
id: moveTemplate.id,
|
|
pp: ((moveTemplate.noPPBoosts || moveTemplate.isZ) ? moveTemplate.pp : moveTemplate.pp * 8 / 5),
|
|
maxpp: ((moveTemplate.noPPBoosts || moveTemplate.isZ) ? moveTemplate.pp : moveTemplate.pp * 8 / 5),
|
|
target: moveTemplate.target,
|
|
disabled: false,
|
|
disabledSource: '',
|
|
used: false,
|
|
});
|
|
}
|
|
// Update HP
|
|
// @ts-ignore Hack for Snaquaza's Z Move
|
|
pokemon.m.claimHP = pokemon.hp;
|
|
pokemon.heal(pokemon.maxhp - pokemon.hp, pokemon);
|
|
this.add('-heal', pokemon, pokemon.getHealth, '[silent]');
|
|
this.add('message', `${pokemon.name} claims to be a ${set.species}!`);
|
|
},
|
|
isZ: "fakeclaimiumz",
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
// sparksblade
|
|
kratosmana: {
|
|
accuracy: 100,
|
|
basePower: 250,
|
|
category: "Physical",
|
|
desc: "The user faints after using this move, even if this move fails for having no target. Has a 10% chance to paralyze the target.",
|
|
shortDesc: "The user faints. 10% chance to paralyze target.",
|
|
id: "kratosmana",
|
|
name: "Kratosmana",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Explosion", target);
|
|
this.add('-anim', source, "Searing Shot", target);
|
|
this.add('-anim', target, "Poison Gas", target);
|
|
},
|
|
selfdestruct: "always",
|
|
secondary: {
|
|
chance: 10,
|
|
status: 'par',
|
|
},
|
|
target: "Normal",
|
|
type: "Fire",
|
|
},
|
|
// Sundar
|
|
leafblaster: {
|
|
accuracy: 100,
|
|
basePower: 90,
|
|
category: "Special",
|
|
desc: "Lowers the user's accuracy by 2 stages.",
|
|
shortDesc: "Lowers the user's accuracy by 2.",
|
|
id: "leafblaster",
|
|
name: "Leaf Blaster",
|
|
isNonstandard: "Custom",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Leaf Storm", target);
|
|
},
|
|
self: {
|
|
boosts: {
|
|
accuracy: -2,
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Grass",
|
|
},
|
|
// Teclis
|
|
absoluteconfiguration: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Puts the foe to sleep. Summons a Nightmare Field with the effects of Nightmare for 4 turns.",
|
|
shortDesc: "Puts foe to sleep. Nightmare for 4 turns.",
|
|
id: "absoluteconfiguration",
|
|
name: "Absolute Configuration",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {reflectable: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Dark Pulse', target);
|
|
this.add('-anim', source, 'Dark Void', target);
|
|
},
|
|
onHit(source) {
|
|
this.field.addPseudoWeather('nightmarefield', source);
|
|
},
|
|
status: 'slp',
|
|
isZ: "darkrainiumz",
|
|
target: "normal",
|
|
type: "Dark",
|
|
},
|
|
// Used for Teclis's z-move
|
|
nightmarefield: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "For 4 turns, Nightmare Field is active. During the effect, sleeping Pokemon suffer from the effects of Nightmare.",
|
|
shortDesc: "4 turns. Sleeping Pokemon suffer Nightmare.",
|
|
id: "nightmarefield",
|
|
name: "Nightmare Field",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {},
|
|
pseudoWeather: 'nightmarefield',
|
|
effect: {
|
|
duration: 4,
|
|
onStart(battle, source, effect) {
|
|
if (effect && effect.effectType === 'Ability') {
|
|
this.add('-fieldstart', 'move: Nightmare Field', '[from] ability: ' + effect, '[of] ' + source);
|
|
} else {
|
|
this.add('-fieldstart', 'move: Nightmare Field');
|
|
}
|
|
},
|
|
onResidualOrder: 21,
|
|
onResidualSubOrder: 2,
|
|
onResidual() {
|
|
for (const curMon of this.getAllActive()) {
|
|
if (curMon.status === 'slp' || curMon.hasAbility('comatose')) {
|
|
this.damage(curMon.maxhp / 4, curMon);
|
|
}
|
|
}
|
|
},
|
|
onEnd() {
|
|
this.add('-fieldend', 'move: Nightmare Field');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Dark",
|
|
},
|
|
// tennisace
|
|
groundsurge: {
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Special",
|
|
desc: "This move's type effectiveness against Ground is changed to be super effective no matter what this move's type is.",
|
|
shortDesc: "Super effective on Ground.",
|
|
id: "groundsurge",
|
|
name: "Ground Surge",
|
|
isNonstandard: "Custom",
|
|
pp: 15,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Thunder", target);
|
|
this.add('-anim', source, "Fissure", target);
|
|
},
|
|
ignoreImmunity: {'Electric': true},
|
|
onEffectiveness(typeMod, target, type) {
|
|
if (type === 'Ground') return 1;
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Electric",
|
|
},
|
|
// Teremiare
|
|
rotate: {
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "The user's replacement will switch out at the end of next turn if the replacement's move is successful.",
|
|
shortDesc: "User's replacement switches after using its move.",
|
|
id: "rotate",
|
|
name: "Rotate",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Celebrate", target);
|
|
},
|
|
sideCondition: "rotate",
|
|
effect: {
|
|
duration: 2,
|
|
onStart(source) {
|
|
this.add('-message', `${source.active[0].name}'s replacement is going to switch out next turn!`);
|
|
},
|
|
onBeforeTurn(pokemon) {
|
|
this.insertQueue({choice: 'event', event: 'SSBRotate', pokemon: pokemon, priority: -69});
|
|
},
|
|
// @ts-ignore unsupported custom event
|
|
onSSBRotate(/** @type {Pokemon} */ pokemon) {
|
|
// @ts-ignore Unsupported custom event, this is refering to a battle
|
|
this.add('-message', `${pokemon.illusion ? pokemon.illusion.name : pokemon.name} is preparing to switch out!`);
|
|
pokemon.switchFlag = true;
|
|
},
|
|
},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
},
|
|
// The Immortal
|
|
ultrasucc: {
|
|
accuracy: true,
|
|
basePower: 140,
|
|
category: "Physical",
|
|
desc: "Has a 100% chance to raise the user's Speed by one stage.",
|
|
shortDesc: "100% chance to raise the user's Speed by 1.",
|
|
id: "ultrasucc",
|
|
name: "Ultra Succ",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Dragon Ascent", target);
|
|
},
|
|
secondary: {
|
|
chance: 100,
|
|
self: {
|
|
boosts: {
|
|
spe: 1,
|
|
},
|
|
},
|
|
},
|
|
isZ: "buzzniumz",
|
|
target: "normal",
|
|
type: "Fighting",
|
|
},
|
|
// The Leprechaun
|
|
gyroballin: {
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
let power = (Math.floor(25 * target.getStat('spe') / pokemon.getStat('spe')) || 1);
|
|
if (power > 150) power = 150;
|
|
this.debug('' + power + ' bp');
|
|
return power;
|
|
},
|
|
category: "Physical",
|
|
desc: "Base Power is equal to (25 * target's current Speed / user's current Speed) + 1, rounded down, but not more than 150. If the user's current Speed is 0, this move's power is 1. Summons Trick Room unless Trick Room is already active.",
|
|
shortDesc: "More power if slower; sets Trick Room.",
|
|
id: "gyroballin",
|
|
name: "Gyro Ballin'",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {bullet: 1, contact: 1, protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Gyro Ball", target);
|
|
},
|
|
onAfterMoveSecondarySelf(pokemon) {
|
|
if (!this.field.pseudoWeather.trickroom) {
|
|
this.field.addPseudoWeather('trickroom', pokemon);
|
|
}
|
|
this.add('-fieldactivate', 'move: Pay Day'); // Coins are scattered on the ground
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Steel",
|
|
zMovePower: 160,
|
|
contestType: "Cool",
|
|
},
|
|
// Tony
|
|
greed: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "If there is no Stealth Rock on the foe's side of the field, sets Stealth Rock and one layer of Spikes. Otherwise, it sets two layers of Spikes.",
|
|
shortDesc: "SR present: Spikes x2; otherwise: SR + Spikes.",
|
|
id: "greed",
|
|
name: "Greed",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {reflectable: 1, nosky: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
if (!target.side.sideConditions['stealthrock']) {
|
|
this.add('-anim', source, "Stealth Rock", target);
|
|
} else {
|
|
this.add('-anim', source, "Spikes", target);
|
|
}
|
|
this.add('-anim', source, "Spikes", target);
|
|
},
|
|
onHitSide(target, source) {
|
|
if (!target.sideConditions['stealthrock']) {
|
|
target.addSideCondition('stealthrock', source);
|
|
} else {
|
|
target.addSideCondition('spikes', source);
|
|
}
|
|
target.addSideCondition('spikes', source);
|
|
},
|
|
secondary: null,
|
|
target: "foeSide",
|
|
type: "Ground",
|
|
},
|
|
// torkool
|
|
smokebomb: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Moves all hazards that are on the user's side of the field to the foe's side of the field. Sets Stealth Rock on the foe's side, after which the user switches out.",
|
|
shortDesc: "Hazards -> foe side. Set SR. User switches out.",
|
|
id: "smokebomb",
|
|
name: "Smoke Bomb",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1, mirror: 1, reflectable: 1, authentic: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Smokescreen", target);
|
|
this.add('-anim', source, "Parting Shot", target);
|
|
},
|
|
onHit(target, source) {
|
|
const sideConditions = {'spikes': 1, 'toxicspikes': 1, 'stealthrock': 1, 'stickyweb': 1};
|
|
for (let i in sideConditions) {
|
|
let layers = source.side.sideConditions[i] ? (source.side.sideConditions[i].layers || 1) : 1;
|
|
if (source.side.removeSideCondition(i)) {
|
|
this.add('-sideend', source.side, this.dex.getEffect(i).name, '[from] move: Smoke Bomb', '[of] ' + source);
|
|
for (layers; layers > 0; layers--) target.side.addSideCondition(i, source);
|
|
}
|
|
}
|
|
target.side.addSideCondition('stealthrock');
|
|
},
|
|
selfSwitch: true,
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// Trickster
|
|
minisingularity: {
|
|
accuracy: 55,
|
|
basePower: 0,
|
|
basePowerCallback(pokemon, target) {
|
|
let targetWeight = target.getWeight();
|
|
if (targetWeight >= 2000) {
|
|
this.debug('120 bp');
|
|
return 120;
|
|
}
|
|
if (targetWeight >= 1000) {
|
|
this.debug('100 bp');
|
|
return 100;
|
|
}
|
|
if (targetWeight >= 500) {
|
|
this.debug('80 bp');
|
|
return 80;
|
|
}
|
|
if (targetWeight >= 250) {
|
|
this.debug('60 bp');
|
|
return 60;
|
|
}
|
|
if (targetWeight >= 100) {
|
|
this.debug('40 bp');
|
|
return 40;
|
|
}
|
|
this.debug('20 bp');
|
|
return 20;
|
|
},
|
|
category: "Special",
|
|
desc: "This move's Base Power is 20 if the target weighs less than 10 kg, 40 if its weight is less than 25 kg, 60 if its weight is less than 50 kg, 80 if its weight is less than 100 kg, 100 if its weight is less than 200 kg, and 120 if its weight is greater than or equal to 200 kg. Before doing damage, the target's item is replaced with an Iron Ball, and the target's weight is doubled.",
|
|
shortDesc: "BP:weight; +foe weight; foe item = Iron Ball.",
|
|
id: "minisingularity",
|
|
name: "Mini Singularity",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Spacial Rend", target);
|
|
this.add('-anim', source, "Flash", target);
|
|
|
|
// Really feel like this could be done better (blocked by protect and alike moves.)
|
|
if (!(target.volatiles['banefulbunker'] || target.volatiles['kingsshield'] || target.side.sideConditions['matblock'] || target.volatiles['protect'] || target.volatiles['spikyshield'] || target.volatiles['lilypadshield'] || target.volatiles['backoffgrrr'])) {
|
|
target.addVolatile('weightdoubler', source);
|
|
let item = target.takeItem();
|
|
if (!target.item) {
|
|
if (item) this.add('-enditem', target, item.name, '[from] move: Mini Singularity', '[of] ' + source);
|
|
target.setItem('ironball');
|
|
this.add('-message', target.name + ' obtained an Iron Ball.');
|
|
}
|
|
}
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Psychic",
|
|
},
|
|
// vivalospride
|
|
ceilingsabsent: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Before the turn starts, this Pokemon uses Taunt against the foe. When this move hits, the user is healed by 50% of its max HP.",
|
|
shortDesc: "Foe is Taunted; user heals 50% of Max HP.",
|
|
id: "ceilingsabsent",
|
|
name: "CEILINGS ABSENT",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {snatch: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Recover", source);
|
|
},
|
|
beforeTurnCallback(pokemon) {
|
|
if (pokemon.status === 'slp' || pokemon.status === 'frz') return;
|
|
this.useMove("taunt", pokemon);
|
|
},
|
|
onHit(source) {
|
|
this.heal(source.maxhp / 2, source);
|
|
},
|
|
secondary: null,
|
|
target: "self",
|
|
type: "Normal",
|
|
},
|
|
// Volco
|
|
explosivedrain: {
|
|
basePower: 90,
|
|
accuracy: 100,
|
|
category: "Special",
|
|
desc: "The user recovers half the HP lost by the target, rounded half up. If Big Root is held, the user recovers 1.3x the normal amount of HP, rounded half down.",
|
|
shortDesc: "User recovers 50% of the damage dealt.",
|
|
id: "explosivedrain",
|
|
name: "Explosive Drain",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, heal: 1},
|
|
drain: [1, 2],
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Fire Blast", target);
|
|
this.add('-anim', source, "Giga Drain", target);
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// Xayah
|
|
feathersnare: {
|
|
accuracy: 100,
|
|
basePower: 95,
|
|
category: "Special",
|
|
desc: "Has a 20% chance to make the target flinch and a 50% chance to paralyze the target.",
|
|
shortDesc: "20% to flinch; 50% to paralyze.",
|
|
id: "feathersnare",
|
|
name: "Feather Snare",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Revelation Dance", source);
|
|
this.add('-anim', source, "Air Slash", target);
|
|
this.add('-anim', source, "Air Slash", target);
|
|
},
|
|
secondaries: [
|
|
{
|
|
chance: 20,
|
|
volatileStatus: 'flinch',
|
|
},
|
|
{
|
|
chance: 50,
|
|
status: 'par',
|
|
},
|
|
],
|
|
zMovePower: 175,
|
|
target: "normal",
|
|
type: "Flying",
|
|
},
|
|
// xfix
|
|
glitzerpopping: {
|
|
accuracy: true,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Uses 2-5 random moves. Does not include Z-Moves that have 1 Base Power or Glitzer Popping.",
|
|
shortDesc: "Uses 2-5 random moves; avoids 1 BP Z-Moves.",
|
|
id: 'glitzerpopping',
|
|
name: "glitzer popping",
|
|
isNonstandard: "Custom",
|
|
pp: 3.14,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {},
|
|
onTryMove(pokemon) {
|
|
this.attrLastMove('[still]');
|
|
const moveData = pokemon.getMoveData('glitzerpopping');
|
|
if (!moveData) return;
|
|
// Lost 1 PP due to move usage, restore 0.9 PP to make it so that only 0.1 PP
|
|
// would be used.
|
|
moveData.pp = (Math.round(moveData.pp * 100) + 90) / 100;
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Metronome", source);
|
|
},
|
|
onHit(target, source, effect) {
|
|
const moves = [];
|
|
for (const i in exports.BattleMovedex) {
|
|
const move = exports.BattleMovedex[i];
|
|
if (i !== move.id || move.id === 'glitzerpopping') continue;
|
|
// Calling 1 BP move is somewhat lame and disappointing. However,
|
|
// signature Z moves are fine, as they actually have a base power.
|
|
if (move.isZ && move.basePower === 1) continue;
|
|
moves.push(move);
|
|
}
|
|
let randomMove;
|
|
if (moves.length) {
|
|
randomMove = this.sample(moves).id;
|
|
}
|
|
if (!randomMove) {
|
|
return false;
|
|
}
|
|
this.useMove(randomMove, target);
|
|
},
|
|
multihit: [2, 5],
|
|
secondary: null,
|
|
target: "self",
|
|
type: "???",
|
|
},
|
|
// xJoelituh
|
|
lavabone: {
|
|
accuracy: 100,
|
|
basePower: 130,
|
|
category: "Physical",
|
|
desc: "Has a 35% chance to burn the target.",
|
|
shortDesc: "35% chance to burn the target.",
|
|
id: "lavabone",
|
|
name: "Lava Bone",
|
|
isNonstandard: "Custom",
|
|
pp: 5,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Shadow Bone", target);
|
|
this.add('-anim', target, "Fire Blast", target);
|
|
},
|
|
secondary: {
|
|
chance: 35,
|
|
status: 'brn',
|
|
},
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// XpRienzo ☑◡☑
|
|
blehflame: {
|
|
accuracy: 100,
|
|
basePower: 130,
|
|
category: "Special",
|
|
desc: "No additional effect.",
|
|
shortDesc: "Usually goes first.",
|
|
id: "blehflame",
|
|
name: "Bleh Flame",
|
|
isNonstandard: "Custom",
|
|
pp: 1,
|
|
priority: 1,
|
|
flags: {},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Focus Energy", source);
|
|
this.add('-anim', source, "Fusion Flare", target);
|
|
},
|
|
secondary: null,
|
|
isZ: "charcoal",
|
|
target: "normal",
|
|
type: "Fire",
|
|
},
|
|
// Yuki
|
|
cutieescape: {
|
|
accuracy: true,
|
|
category: "Status",
|
|
basePower: 0,
|
|
desc: "The user is replaced with another Pokemon in its party. The foe is confused, trapped, and infatuated regardless of the replacement's gender. This move fails unless the user already took damage this turn.",
|
|
shortDesc: "If hit; switches out + confuses, traps, infatuates.",
|
|
id: "cutieescape",
|
|
name: "Cutie Escape",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: -6,
|
|
flags: {mirror: 1},
|
|
beforeTurnCallback(pokemon) {
|
|
pokemon.addVolatile('cutieescape');
|
|
this.add('-message', `${pokemon.name} is preparing to flee!`);
|
|
},
|
|
beforeMoveCallback(pokemon) {
|
|
if (!pokemon.volatiles['cutieescape'] || !pokemon.volatiles['cutieescape'].tookDamage) {
|
|
this.add('-fail', pokemon, 'move: Cutie Escape');
|
|
this.add('-hint', 'Cutie Escape only works when Yuki is hit in the same turn the move is used.');
|
|
return true;
|
|
}
|
|
},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, "Baton Pass", source);
|
|
},
|
|
onHit(target, source) {
|
|
target.addVolatile('confusion');
|
|
target.addVolatile('cutietrap');
|
|
},
|
|
effect: {
|
|
duration: 1,
|
|
onStart(pokemon) {
|
|
this.add('-singleturn', pokemon, 'move: Cutie Escape');
|
|
},
|
|
onHit(pokemon, source, move) {
|
|
if (move.category !== 'Status') {
|
|
pokemon.volatiles['cutieescape'].tookDamage = true;
|
|
}
|
|
},
|
|
},
|
|
secondary: null,
|
|
selfSwitch: true,
|
|
target: "normal",
|
|
type: "Fairy",
|
|
},
|
|
// Zalm
|
|
twinweedle: {
|
|
accuracy: 100,
|
|
basePower: 40,
|
|
multihit: 2,
|
|
category: "Physical",
|
|
desc: "Hits twice. Each hit has a 20% chance to poison the target and heals the user for 30% damage dealt. If one of the hits breaks the target's Substitute, it will take damage for the remaining hits.",
|
|
shortDesc: "2 hits, 20% poison each, heals 30% of damage.",
|
|
id: "twinweedle",
|
|
isNonstandard: "Custom",
|
|
name: "TwinWeedle",
|
|
pp: 25,
|
|
noPPBoosts: true,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, heal: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onPrepareHit(target, source) {
|
|
this.add('-anim', source, 'Poison Sting', target);
|
|
},
|
|
drain: [3, 10],
|
|
secondary: {
|
|
chance: 20,
|
|
status: 'psn',
|
|
},
|
|
target: "normal",
|
|
type: "Poison",
|
|
},
|
|
// Zarel
|
|
relicsongdance: {
|
|
accuracy: 100,
|
|
basePower: 60,
|
|
multihit: 2,
|
|
category: "Special",
|
|
desc: "Hits twice and ignores type immunities. Before the second hit, the user switches to its Pirouette forme, and this move's second hit deals physical Fighting-type damage. After the second hit, the user reverts to its Aria forme. Fails unless the user is Meloetta.",
|
|
shortDesc: "Attacks in Aria forme, then in Pirouette forme.",
|
|
id: "relicsongdance",
|
|
name: "Relic Song Dance",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1, mirror: 1, sound: 1, authentic: 1},
|
|
ignoreImmunity: true,
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onTryHit(target, pokemon) {
|
|
if (pokemon.name !== 'Zarel') {
|
|
this.add('-fail', pokemon);
|
|
this.hint("Only Zarel can use Relic Song Dance.");
|
|
return null;
|
|
}
|
|
this.attrLastMove('[still]');
|
|
let move = pokemon.template.speciesid === 'meloettapirouette' ? 'Brick Break' : 'Relic Song';
|
|
this.add('-anim', pokemon, move, target);
|
|
},
|
|
onHit(target, pokemon, move) {
|
|
if (pokemon.template.speciesid === 'meloettapirouette') {
|
|
pokemon.formeChange('Meloetta');
|
|
} else if (pokemon.formeChange('Meloetta-Pirouette')) {
|
|
move.category = 'Physical';
|
|
move.type = 'Fighting';
|
|
}
|
|
},
|
|
onAfterMove(pokemon) {
|
|
// Ensure Meloetta goes back to standard form after using the move
|
|
if (pokemon.template.speciesid === 'meloettapirouette') {
|
|
pokemon.formeChange('Meloetta');
|
|
}
|
|
this.hint("Zarel still has the Serene Grace ability.");
|
|
},
|
|
effect: {
|
|
duration: 1,
|
|
onAfterMoveSecondarySelf(pokemon, target, move) {
|
|
if (pokemon.template.speciesid === 'meloettapirouette') {
|
|
pokemon.formeChange('Meloetta');
|
|
} else {
|
|
pokemon.formeChange('Meloetta-Pirouette');
|
|
}
|
|
pokemon.removeVolatile('relicsong');
|
|
},
|
|
},
|
|
secondary: null,
|
|
target: "allAdjacentFoes",
|
|
type: "Psychic",
|
|
},
|
|
// Zyg
|
|
thelifeofzyg: {
|
|
accuracy: 100,
|
|
basePower: 0,
|
|
category: "Status",
|
|
desc: "Both the user and target are badly poisoned.",
|
|
shortDesc: "Badly poisons the user and target.",
|
|
id: "thelifeofzyg",
|
|
name: "The Life of Zyg",
|
|
isNonstandard: "Custom",
|
|
pp: 10,
|
|
priority: 0,
|
|
flags: {protect: 1},
|
|
onTryMove() {
|
|
this.attrLastMove('[still]');
|
|
},
|
|
onTryHit(target, source) {
|
|
this.add('-anim', source, "Toxic", source);
|
|
this.add('-anim', source, "Toxic", target);
|
|
},
|
|
onHit(target, source) {
|
|
source.trySetStatus('tox');
|
|
target.trySetStatus('tox');
|
|
},
|
|
secondary: null,
|
|
target: "normal",
|
|
type: "Poison",
|
|
},
|
|
// Modded Sleep Talk for pirate princess
|
|
sleeptalk: {
|
|
inherit: true,
|
|
onHit(pokemon) {
|
|
let moves = [];
|
|
for (const moveSlot of pokemon.moveSlots) {
|
|
const move = moveSlot.id;
|
|
const noSleepTalk = [
|
|
'assist', 'beakblast', 'belch', 'bide', 'celebrate', 'chatter', 'copycat', 'focuspunch', 'mefirst', 'metronome', 'mimic', 'mirrormove', 'naturepower', 'shelltrap', 'sketch', 'sleeptalk', 'uproar',
|
|
'teabreak', 'glitzerpopping', // Modded banlist
|
|
];
|
|
if (move && !(noSleepTalk.includes(move) || this.dex.getMove(move).flags['charge'] || (this.dex.getMove(move).isZ && this.dex.getMove(move).basePower !== 1))) {
|
|
moves.push(move);
|
|
}
|
|
}
|
|
let randomMove = '';
|
|
if (moves.length) randomMove = this.sample(moves);
|
|
if (!randomMove) {
|
|
return false;
|
|
}
|
|
this.useMove(randomMove, pokemon);
|
|
},
|
|
},
|
|
};
|
|
|
|
exports.BattleMovedex = BattleMovedex;
|