mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-09-14 12:15:44 -05:00
Modernize the coding style of the OM chat plugin (#7643)
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
// Other Metas plugin by Spandan
|
||||
/**
|
||||
* Other Metagames chat plugin
|
||||
* Lets users see elements of Pokemon in various Other Metagames.
|
||||
* Originally by Spandan.
|
||||
* @author Kris
|
||||
*/
|
||||
|
||||
import {Utils} from '../../lib/utils';
|
||||
|
||||
@@ -42,12 +47,12 @@ function getMegaStone(stone: string, mod = 'gen8'): Item | null {
|
||||
export const commands: ChatCommands = {
|
||||
om: 'othermetas',
|
||||
othermetas(target, room, user) {
|
||||
if (!this.runBroadcast()) return;
|
||||
this.runBroadcast();
|
||||
target = toID(target);
|
||||
let buffer = ``;
|
||||
|
||||
if (target === 'all' && this.broadcasting) {
|
||||
return this.sendReplyBox(`You cannot broadcast information about all Other Metagames at once.`);
|
||||
throw new Chat.ErrorMessage(`You cannot broadcast information about all Other Metagames at once.`);
|
||||
}
|
||||
|
||||
if (!target || target === 'all') {
|
||||
@@ -78,30 +83,28 @@ export const commands: ChatCommands = {
|
||||
|
||||
mnm: 'mixandmega',
|
||||
mixandmega(target, room, user) {
|
||||
if (!this.runBroadcast()) return;
|
||||
if (!toID(target) || !target.includes('@')) return this.parse('/help mixandmega');
|
||||
this.runBroadcast();
|
||||
let dex = Dex;
|
||||
const sep = target.split('@');
|
||||
const stoneName = sep.slice(1).join('@').trim().split(',');
|
||||
const mod = stoneName[1];
|
||||
if (mod && toID(mod) in Dex.dexes) dex = Dex.mod(toID(mod));
|
||||
if (mod) {
|
||||
if (toID(mod) in Dex.dexes) {
|
||||
dex = Dex.mod(toID(mod));
|
||||
} else {
|
||||
throw new Chat.ErrorMessage(`A mod by the name of '${mod.trim()}' does not exist.`);
|
||||
}
|
||||
if (dex === Dex.dexes['ssb']) {
|
||||
throw new Chat.ErrorMessage(`The SSB mod supports custom elements for Mega Stones that have the capability of crashing the server.`);
|
||||
}
|
||||
}
|
||||
const stone = getMegaStone(stoneName[0], mod);
|
||||
const species = dex.getSpecies(sep[0]);
|
||||
if (!stone || (dex.gen >= 8 && ['redorb', 'blueorb'].includes(stone.id))) {
|
||||
return this.errorReply(`Error: Mega Stone not found.`);
|
||||
}
|
||||
if (!species.exists) return this.errorReply(`Error: Pokemon not found.`);
|
||||
const banlist = Dex.getFormat('gen8mixandmega').banlist;
|
||||
if (banlist.includes(stone.name)) {
|
||||
this.errorReply(`Warning: ${stone.name} is banned from Mix and Mega.`);
|
||||
}
|
||||
// Fake Pokemon and Mega Stones
|
||||
if (species.isNonstandard === "CAP") {
|
||||
this.errorReply(`Warning: ${species.name} is not a real Pokemon and is therefore not usable in Mix and Mega.`);
|
||||
}
|
||||
if (stone.isNonstandard === "CAP") {
|
||||
this.errorReply(`Warning: ${stone.name} is a fake mega stone created by the CAP Project and is restricted to the CAP ${stone.megaEvolves}.`);
|
||||
throw new Chat.ErrorMessage(`Error: Mega Stone not found.`);
|
||||
}
|
||||
if (!species.exists) throw new Chat.ErrorMessage(`Error: Pok\u00e9mon not found.`);
|
||||
let baseSpecies = dex.getSpecies(stone.megaEvolves);
|
||||
let megaSpecies = dex.getSpecies(stone.megaStone);
|
||||
if (stone.id === 'redorb') { // Orbs do not have 'Item.megaStone' or 'Item.megaEvolves' properties.
|
||||
@@ -174,27 +177,36 @@ export const commands: ChatCommands = {
|
||||
}).join(" |  ") + '</font>');
|
||||
},
|
||||
mixandmegahelp: [
|
||||
`/mnm <pokemon> @ <mega stone>[, generation] - Shows the Mix and Mega evolved Pokemon's type and stats.`,
|
||||
`/mnm <pokemon> @ <mega stone>[, generation] - Shows the Mix and Mega evolved Pok\u00e9mon's type and stats.`,
|
||||
],
|
||||
|
||||
orb: 'stone',
|
||||
megastone: 'stone',
|
||||
stone(target) {
|
||||
if (!this.runBroadcast()) return;
|
||||
const sep = target.split(',');
|
||||
let dex = Dex;
|
||||
if (sep[1] && toID(sep[1]) in Dex.dexes) dex = Dex.mod(toID(sep[1]));
|
||||
if (sep[1]) {
|
||||
if (toID(sep[1]) in Dex.dexes) {
|
||||
dex = Dex.mod(toID(sep[1]));
|
||||
} else {
|
||||
throw new Chat.ErrorMessage(`A mod by the name of '${sep[1].trim()}' does not exist.`);
|
||||
}
|
||||
if (dex === Dex.dexes['ssb']) {
|
||||
throw new Chat.ErrorMessage(`The SSB mod supports custom elements for Mega Stones that have the capability of crashing the server.`);
|
||||
}
|
||||
}
|
||||
const targetid = toID(sep[0]);
|
||||
if (!targetid) return this.parse('/help stone');
|
||||
this.runBroadcast();
|
||||
const stone = getMegaStone(targetid, sep[1]);
|
||||
if (stone && dex.gen >= 8 && ['redorb', 'blueorb'].includes(stone.id)) {
|
||||
return this.errorReply("The Orbs do not exist in Gen 8 and later.");
|
||||
throw new Chat.ErrorMessage("The Orbs do not exist in Gen 8 and later.");
|
||||
}
|
||||
const stones = [];
|
||||
if (!stone) {
|
||||
const species = dex.getSpecies(targetid.replace(/(?:mega[xy]?|primal)$/, ''));
|
||||
if (!species.exists) return this.errorReply(`Error: Mega Stone not found.`);
|
||||
if (!species.otherFormes) return this.errorReply(`Error: Mega Evolution not found.`);
|
||||
if (!species.exists) throw new Chat.ErrorMessage(`Error: Mega Stone not found.`);
|
||||
if (!species.otherFormes) throw new Chat.ErrorMessage(`Error: Mega Evolution not found.`);
|
||||
for (const poke of species.otherFormes) {
|
||||
if (!/(?:-Primal|-Mega(?:-[XY])?)$/.test(poke)) continue;
|
||||
const megaPoke = dex.getSpecies(poke);
|
||||
@@ -203,26 +215,15 @@ export const commands: ChatCommands = {
|
||||
if (!flag) continue;
|
||||
stones.push(getMegaStone(flag, sep[1]));
|
||||
}
|
||||
if (!stones.length) return this.errorReply(`Error: Mega Evolution not found.`);
|
||||
if (!stones.length) throw new Chat.ErrorMessage(`Error: Mega Evolution not found.`);
|
||||
}
|
||||
const toDisplay = (stones.length ? stones : [stone]);
|
||||
const ruleTable = Dex.getRuleTable(Dex.getFormat('gen8mixandmega'));
|
||||
for (const aStone of toDisplay) {
|
||||
if (!aStone) return;
|
||||
if (ruleTable.isBanned(`${aStone.name === 'Dragon Ascent' ? 'move' : 'item'}:${aStone.name}`)) {
|
||||
this.errorReply(`Warning: ${aStone.name} is banned from Mix and Mega.`);
|
||||
}
|
||||
if (aStone.name === 'Dragon Ascent') {
|
||||
this.errorReply(`Warning: Only Pokemon with access to Dragon Ascent can mega evolve with Mega Rayquaza's traits.`);
|
||||
}
|
||||
// Fake Mega Stones
|
||||
if (aStone.isNonstandard === 'CAP') {
|
||||
this.errorReply(`Warning: ${aStone.name} is a fake mega stone created by the CAP Project and is restricted to the CAP ${aStone.megaEvolves}.`);
|
||||
}
|
||||
let baseSpecies = dex.getSpecies(aStone.megaEvolves);
|
||||
let megaSpecies = dex.getSpecies(aStone.megaStone);
|
||||
if (dex.gen >= 8 && ['redorb', 'blueorb'].includes(aStone.id)) {
|
||||
return this.errorReply("The Orbs do not exist in Gen 8 and later.");
|
||||
throw new Chat.ErrorMessage("The Orbs do not exist in Gen 8 and later.");
|
||||
}
|
||||
if (aStone.id === 'redorb') { // Orbs do not have 'Item.megaStone' or 'Item.megaEvolves' properties.
|
||||
megaSpecies = dex.getSpecies("Groudon-Primal");
|
||||
@@ -294,13 +295,13 @@ export const commands: ChatCommands = {
|
||||
this.sendReply(`|raw|<font size="1"><font color="#686868">Gen:</font> ${details["Gen"]} |  <font color="#686868">Weight:</font> ${details["Weight"]}</font>`);
|
||||
}
|
||||
},
|
||||
stonehelp: [`/stone <mega stone>[, generation] - Shows the changes that a mega stone/orb applies to a Pokemon.`],
|
||||
stonehelp: [`/stone <mega stone>[, generation] - Shows the changes that a mega stone/orb applies to a Pok\u00e9mon.`],
|
||||
|
||||
350: '350cup',
|
||||
'350cup'(target, room, user) {
|
||||
if (!this.runBroadcast()) return;
|
||||
const args = target.split(',');
|
||||
if (!toID(args[0])) return this.parse('/help 350cup');
|
||||
this.runBroadcast();
|
||||
let dex = Dex;
|
||||
if (args[1] && toID(args[1]) in Dex.dexes) {
|
||||
dex = Dex.dexes[toID(args[1])];
|
||||
@@ -312,7 +313,7 @@ export const commands: ChatCommands = {
|
||||
if (!species.exists || species.gen > dex.gen) {
|
||||
const monName = species.gen > dex.gen ? species.name : args[0].trim();
|
||||
const additionalReason = species.gen > dex.gen ? ` in Generation ${dex.gen}` : ``;
|
||||
return this.errorReply(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
throw new Chat.ErrorMessage(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
}
|
||||
const bst = species.bst;
|
||||
species.bst = 0;
|
||||
@@ -337,9 +338,9 @@ export const commands: ChatCommands = {
|
||||
ts7: 'tiershift',
|
||||
ts8: 'tiershift',
|
||||
tiershift(target, room, user, connection, cmd) {
|
||||
if (!this.runBroadcast()) return;
|
||||
const args = target.split(',');
|
||||
if (!toID(args[0])) return this.parse('/help tiershift');
|
||||
this.runBroadcast();
|
||||
const targetGen = parseInt(cmd[cmd.length - 1]);
|
||||
if (targetGen && !args[1]) args[1] = `gen${targetGen}`;
|
||||
let dex = Dex;
|
||||
@@ -353,7 +354,7 @@ export const commands: ChatCommands = {
|
||||
if (!species.exists || species.gen > dex.gen) {
|
||||
const monName = species.gen > dex.gen ? species.name : args[0].trim();
|
||||
const additionalReason = species.gen > dex.gen ? ` in Generation ${dex.gen}` : ``;
|
||||
return this.errorReply(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
throw new Chat.ErrorMessage(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
}
|
||||
const boosts: {[tier in TierShiftTiers]: number} = {
|
||||
UU: 10,
|
||||
@@ -382,7 +383,7 @@ export const commands: ChatCommands = {
|
||||
},
|
||||
tiershifthelp: [
|
||||
`/ts OR /tiershift <pokemon>[, generation] - Shows the base stats that a Pok\u00e9mon would have in Tier Shift.`,
|
||||
`Alternatively, you can use /ts[gen number] to see a Pokemon's stats in that generation.`,
|
||||
`Alternatively, you can use /ts[gen number] to see a Pok\u00e9mon's stats in that generation.`,
|
||||
],
|
||||
|
||||
scale: 'scalemons',
|
||||
@@ -395,9 +396,9 @@ export const commands: ChatCommands = {
|
||||
scale7: 'scalemons',
|
||||
scale8: 'scalemons',
|
||||
scalemons(target, room, user, connection, cmd) {
|
||||
if (!this.runBroadcast()) return;
|
||||
const args = target.split(',');
|
||||
if (!args.length || !toID(args[0])) return this.parse(`/help scalemons`);
|
||||
this.runBroadcast();
|
||||
const targetGen = parseInt(cmd[cmd.length - 1]);
|
||||
if (targetGen && !args[1]) args[1] = `gen${targetGen}`;
|
||||
let dex = Dex;
|
||||
@@ -411,7 +412,7 @@ export const commands: ChatCommands = {
|
||||
if (!species.exists || species.gen > dex.gen) {
|
||||
const monName = species.gen > dex.gen ? species.name : args[0].trim();
|
||||
const additionalReason = species.gen > dex.gen ? ` in Generation ${dex.gen}` : ``;
|
||||
return this.errorReply(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
throw new Chat.ErrorMessage(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
}
|
||||
const bstNoHP = species.bst - species.baseStats.hp;
|
||||
const scale = (dex.gen !== 1 ? 600 : 500) - species.baseStats['hp'];
|
||||
@@ -427,7 +428,7 @@ export const commands: ChatCommands = {
|
||||
},
|
||||
scalemonshelp: [
|
||||
`/scale OR /scalemons <pokemon>[, gen] - Shows the base stats that a Pok\u00e9mon would have in Scalemons.`,
|
||||
`Alternatively, you can use /scale[gen number] to see a Pokemon's scaled stats in that generation.`,
|
||||
`Alternatively, you can use /scale[gen number] to see a Pok\u00e9mon's scaled stats in that generation.`,
|
||||
],
|
||||
|
||||
flip: 'flipped',
|
||||
@@ -440,9 +441,9 @@ export const commands: ChatCommands = {
|
||||
flip7: 'flipped',
|
||||
flip8: 'flipped',
|
||||
flipped(target, room, user, connection, cmd) {
|
||||
if (!this.runBroadcast()) return;
|
||||
const args = target.split(',');
|
||||
if (!args[0]) return this.parse(`/help flipped`);
|
||||
this.runBroadcast();
|
||||
const mon = args[0];
|
||||
let mod = args[1];
|
||||
const targetGen = parseInt(cmd[cmd.length - 1]);
|
||||
@@ -457,7 +458,7 @@ export const commands: ChatCommands = {
|
||||
if (!species.exists || species.gen > dex.gen) {
|
||||
const monName = species.gen > dex.gen ? species.name : mon.trim();
|
||||
const additionalReason = species.gen > dex.gen ? ` in Generation ${dex.gen}` : ``;
|
||||
return this.errorReply(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
throw new Chat.ErrorMessage(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
}
|
||||
if (dex.gen === 1) {
|
||||
const flippedStats: {[k: string]: number} = {
|
||||
@@ -481,8 +482,8 @@ export const commands: ChatCommands = {
|
||||
this.sendReply(`|raw|${Chat.getDataPokemonHTML(species, dex.gen)}`);
|
||||
},
|
||||
flippedhelp: [
|
||||
`/flip OR /flipped <pokemon>[, gen] - Shows the base stats that a Pokemon would have in Flipped.`,
|
||||
`Alternatively, you can use /flip[gen number] to see a Pokemon's stats in that generation.`,
|
||||
`/flip OR /flipped <pokemon>[, gen] - Shows the base stats that a Pok\u00e9mon would have in Flipped.`,
|
||||
`Alternatively, you can use /flip[gen number] to see a Pok\u00e9mon's stats in that generation.`,
|
||||
],
|
||||
|
||||
ns: 'natureswap',
|
||||
@@ -493,7 +494,6 @@ export const commands: ChatCommands = {
|
||||
ns7: 'natureswap',
|
||||
ns8: 'natureswap',
|
||||
natureswap(target, room, user, connection, cmd) {
|
||||
if (!this.runBroadcast()) return;
|
||||
const args = target.split(',');
|
||||
const nature = args[0];
|
||||
const pokemon = args[1];
|
||||
@@ -507,14 +507,15 @@ export const commands: ChatCommands = {
|
||||
dex = Dex.mod(format.mod);
|
||||
}
|
||||
if (!toID(nature) || !toID(pokemon)) return this.parse(`/help natureswap`);
|
||||
this.runBroadcast();
|
||||
const natureObj = dex.getNature(nature);
|
||||
if (dex.gen < 3) return this.errorReply(`Error: Natures don't exist prior to Generation 3.`);
|
||||
if (!natureObj.exists) return this.errorReply(`Error: Nature ${nature} not found.`);
|
||||
if (dex.gen < 3) throw new Chat.ErrorMessage(`Error: Natures don't exist prior to Generation 3.`);
|
||||
if (!natureObj.exists) throw new Chat.ErrorMessage(`Error: Nature ${nature} not found.`);
|
||||
const species = Utils.deepClone(dex.getSpecies(pokemon));
|
||||
if (!species.exists || species.gen > dex.gen) {
|
||||
const monName = species.gen > dex.gen ? species.name : args[0].trim();
|
||||
const additionalReason = species.gen > dex.gen ? ` in Generation ${dex.gen}` : ``;
|
||||
return this.errorReply(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
throw new Chat.ErrorMessage(`Error: Pok\u00e9mon '${monName}' not found${additionalReason}.`);
|
||||
}
|
||||
if (natureObj.minus && natureObj.plus) {
|
||||
const swap = species.baseStats[natureObj.minus];
|
||||
@@ -525,8 +526,8 @@ export const commands: ChatCommands = {
|
||||
this.sendReply(`|raw|${Chat.getDataPokemonHTML(species, dex.gen)}`);
|
||||
},
|
||||
natureswaphelp: [
|
||||
`/ns OR /natureswap <nature>, <pokemon>[, gen] - Shows the base stats that a Pokemon would have in Nature Swap.`,
|
||||
`Alternatively, you can use /ns[gen number] to see a Pokemon's stats in that generation.`,
|
||||
`/ns OR /natureswap <nature>, <pokemon>[, gen] - Shows the base stats that a Pok\u00e9mon would have in Nature Swap.`,
|
||||
`Alternatively, you can use /ns[gen number] to see a Pok\u00e9mon's stats in that generation.`,
|
||||
],
|
||||
|
||||
ce: 'crossevolve',
|
||||
@@ -539,11 +540,11 @@ export const commands: ChatCommands = {
|
||||
const species = Dex.getSpecies(pokes[0]);
|
||||
const crossSpecies = Dex.getSpecies(pokes[1]);
|
||||
|
||||
if (!species.exists) return this.errorReply(`Error: Pokemon '${pokes[0]}' not found.`);
|
||||
if (!crossSpecies.exists) return this.errorReply(`Error: Pokemon '${pokes[1]}' not found.`);
|
||||
if (!species.exists) throw new Chat.ErrorMessage(`Error: Pok\u00e9mon '${pokes[0]}' not found.`);
|
||||
if (!crossSpecies.exists) throw new Chat.ErrorMessage(`Error: Pok\u00e9mon '${pokes[1]}' not found.`);
|
||||
|
||||
if (!species.evos.length) return this.errorReply(`Error: ${species.name} does not evolve.`);
|
||||
if (!crossSpecies.prevo) return this.errorReply(`Error: ${crossSpecies.name} does not have a prevolution.`);
|
||||
if (!species.evos.length) throw new Chat.ErrorMessage(`Error: ${species.name} does not evolve.`);
|
||||
if (!crossSpecies.prevo) throw new Chat.ErrorMessage(`Error: ${crossSpecies.name} does not have a prevolution.`);
|
||||
|
||||
let setStage = 1;
|
||||
let crossStage = 1;
|
||||
@@ -561,7 +562,7 @@ export const commands: ChatCommands = {
|
||||
}
|
||||
}
|
||||
if (setStage + 1 !== crossStage) {
|
||||
return this.errorReply(`Error: Cross evolution must follow evolutionary stages. (${species.name} is Stage ${setStage} and can only cross evolve to Stage ${setStage + 1})`);
|
||||
throw new Chat.ErrorMessage(`Error: Cross evolution must follow evolutionary stages. (${species.name} is Stage ${setStage} and can only cross evolve to Stage ${setStage + 1})`);
|
||||
}
|
||||
const mixedSpecies = Utils.deepClone(species);
|
||||
mixedSpecies.abilities = Utils.deepClone(crossSpecies.abilities);
|
||||
@@ -613,7 +614,7 @@ export const commands: ChatCommands = {
|
||||
}).join(" |  ") + '</font>');
|
||||
},
|
||||
crossevolvehelp: [
|
||||
"/crossevo <base pokemon>, <evolved pokemon> - Shows the type and stats for the Cross Evolved Pokemon.",
|
||||
"/crossevo <base pokemon>, <evolved pokemon> - Shows the type and stats for the Cross Evolved Pok\u00e9mon.",
|
||||
],
|
||||
|
||||
showevo(target, user, room) {
|
||||
@@ -622,14 +623,10 @@ export const commands: ChatCommands = {
|
||||
if (!targetid) return this.parse('/help showevo');
|
||||
const evo = Dex.getSpecies(target);
|
||||
if (!evo.exists) {
|
||||
return this.errorReply(`Error: Pok\u00e9mon ${target} not found.`);
|
||||
throw new Chat.ErrorMessage(`Error: Pok\u00e9mon ${target} not found.`);
|
||||
}
|
||||
if (!evo.prevo) {
|
||||
return this.errorReply(`Error: ${evo.name} is not an evolution.`);
|
||||
}
|
||||
// Fake Pokemon
|
||||
if (evo.isNonstandard === 'CAP') {
|
||||
this.errorReply(`Warning: ${evo.name} is a fake Pok\u00e9mon created by the CAP Project and is restricted to CAP.`);
|
||||
throw new Chat.ErrorMessage(`Error: ${evo.name} is not an evolution.`);
|
||||
}
|
||||
const prevoSpecies = Dex.getSpecies(evo.prevo);
|
||||
const deltas = Utils.deepClone(evo);
|
||||
|
||||
@@ -492,9 +492,11 @@ export class CommandContext extends MessageContext {
|
||||
} catch (err) {
|
||||
if (err.name?.endsWith('ErrorMessage')) {
|
||||
this.errorReply(err.message);
|
||||
this.update();
|
||||
return false;
|
||||
}
|
||||
if (err.name.endsWith('Interruption')) {
|
||||
this.update();
|
||||
return;
|
||||
}
|
||||
Monitor.crashlog(err, 'A chat command', {
|
||||
|
||||
Reference in New Issue
Block a user