Fix random typos (#11020)
Some checks are pending
Node.js CI / build (18.x) (push) Waiting to run

This commit is contained in:
Sergio Garcia 2025-04-14 08:59:36 +02:00 committed by GitHub
parent 789456572d
commit fc23103de1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 69 additions and 69 deletions

View File

@ -144,7 +144,7 @@ represented by a space), and the rest of the string being their username.
`|uhtml|NAME|HTML` `|uhtml|NAME|HTML`
> We recieved an HTML message (NAME) that can change what it's displaying, > We received an HTML message (NAME) that can change what it's displaying,
> this is used in things like our Polls system, for example. > this is used in things like our Polls system, for example.
`|uhtmlchange|NAME|HTML` `|uhtmlchange|NAME|HTML`
@ -305,7 +305,7 @@ represented by a space), and the rest of the string being their username.
`|tournament|update|JSON` `|tournament|update|JSON`
> `JSON` is a JSON object representing the changes in the tournament > `JSON` is a JSON object representing the changes in the tournament
> since the last update you recieved or the start of the tournament. > since the last update you received or the start of the tournament.
> These include: > These include:
> >
format: the tournament's custom name or the format being used format: the tournament's custom name or the format being used

View File

@ -2783,7 +2783,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
if (this.dex.species.get(name).exists || this.dex.moves.get(name).exists || if (this.dex.species.get(name).exists || this.dex.moves.get(name).exists ||
this.dex.abilities.get(name).exists || name === 'blitz') { this.dex.abilities.get(name).exists || name === 'blitz') {
// Certain pokemon have volatiles named after their id // Certain pokemon have volatiles named after their id
// To prevent overwriting those, and to prevent accidentaly leaking // To prevent overwriting those, and to prevent accidentally leaking
// that a pokemon is on a team through the onStart even triggering // that a pokemon is on a team through the onStart even triggering
// at the start of a match, users with pokemon names will need their // at the start of a match, users with pokemon names will need their
// statuses to end in "user". // statuses to end in "user".

View File

@ -10,7 +10,7 @@ There were only 151 Pokémon plus MissingNo, just a handful of moves, no abiliti
EVd to the max and we had some kind of different IVs, which maxed at 15 and every point gave 2 to the stat, so in EVd to the max and we had some kind of different IVs, which maxed at 15 and every point gave 2 to the stat, so in
a similar fashion, Pokes used to have 30 IVs on each stat. a similar fashion, Pokes used to have 30 IVs on each stat.
The following sources have been used and extremly useful when developing this mod: The following sources have been used and extremely useful when developing this mod:
https://raw.github.com/po-devs/pokemon-online/master/bin/database/rby-stuff.txt https://raw.github.com/po-devs/pokemon-online/master/bin/database/rby-stuff.txt
https://www.smogon.com/rb/articles/differences https://www.smogon.com/rb/articles/differences
https://www.smogon.com/forums/threads/past-gens-research-thread.3506992/#post-5878612 https://www.smogon.com/forums/threads/past-gens-research-thread.3506992/#post-5878612

View File

@ -2,7 +2,7 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
standard: { standard: {
effectType: 'ValidatorRule', effectType: 'ValidatorRule',
name: 'Standard', name: 'Standard',
desc: "The standard ruleset for all offical Smogon singles tiers (Ubers, OU, etc.)", desc: "The standard ruleset for all official Smogon singles tiers (Ubers, OU, etc.)",
ruleset: ['Obtainable', 'Sleep Clause Mod', 'Switch Priority Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod'], ruleset: ['Obtainable', 'Sleep Clause Mod', 'Switch Priority Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
}, },
}; };

View File

@ -14,7 +14,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (this.field.isWeather('sunnyday')) { if (this.field.isWeather('sunnyday')) {
pokemon.addVolatile('protosynthesis'); pokemon.addVolatile('protosynthesis');
} else if (!pokemon.volatiles['protosynthesis']?.fromBooster && this.field.weather !== 'sunnyday') { } else if (!pokemon.volatiles['protosynthesis']?.fromBooster && this.field.weather !== 'sunnyday') {
// Protosynthesis will not deactivite if Sun is suppressed, hence the direct ID check (isWeather respects supression) // Protosynthesis will not deactivite if Sun is suppressed, hence the direct ID check (isWeather respects suppression)
pokemon.removeVolatile('protosynthesis'); pokemon.removeVolatile('protosynthesis');
} }
}, },

View File

@ -19,7 +19,7 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
standard: { standard: {
effectType: 'ValidatorRule', effectType: 'ValidatorRule',
name: 'Standard', name: 'Standard',
desc: "The standard ruleset for all offical Smogon singles tiers (Ubers, OU, etc.)", desc: "The standard ruleset for all official Smogon singles tiers (Ubers, OU, etc.)",
ruleset: [ ruleset: [
'Standard AG', 'Standard AG',
'Sleep Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause', 'Sleep Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause',

View File

@ -97,7 +97,7 @@ export const Repl = new class {
/** /**
* Starts a REPL server, using a UNIX socket for IPC. The eval function * Starts a REPL server, using a UNIX socket for IPC. The eval function
* parametre is passed in because there is no other way to access a file's * parameter is passed in because there is no other way to access a file's
* non-global context. * non-global context.
*/ */
start(filename: string, evalFunction: (input: string) => any) { start(filename: string, evalFunction: (input: string) => any) {

View File

@ -145,7 +145,7 @@ export const crqHandlers: { [k: string]: Chat.CRQHandler } = {
return targetRoom.battle.format; return targetRoom.battle.format;
}, },
cmdsearch(target, user, trustable) { cmdsearch(target, user, trustable) {
// in no world should ths be a thing. our longest command name is 37 chars // in no world should this be a thing. our longest command name is 37 chars
if (target.length > 40) return null; if (target.length > 40) return null;
const cmdPrefix = target.charAt(0); const cmdPrefix = target.charAt(0);
if (!['/', '!'].includes(cmdPrefix)) return null; if (!['/', '!'].includes(cmdPrefix)) return null;

View File

@ -87,7 +87,7 @@ As an example:
Plines Plines
------------------------------------------------------------------------ ------------------------------------------------------------------------
A lot of the functions refering "plines". A pline is a protocol line, A lot of the functions referring "plines". A pline is a protocol line,
documented in [PROTOCOL.md][https://github.com/smogon/pokemon-showdown/blob/master/PROTOCOL.md] documented in [PROTOCOL.md][https://github.com/smogon/pokemon-showdown/blob/master/PROTOCOL.md]
Plines are the ones that usually start with `|MESSAGETYPE|`, but a pline Plines are the ones that usually start with `|MESSAGETYPE|`, but a pline

View File

@ -752,9 +752,9 @@ function runDexsearch(target: string, cmd: string, message: string, isTest: bool
if (g === undefined) continue; if (g === undefined) continue;
if (tierTraits.includes(cat) && tierInequalitySearch) continue; if (tierTraits.includes(cat) && tierInequalitySearch) continue;
if (cat === 'stats') { if (cat === 'stats') {
const ineqality = param.split(','); const inequality = param.split(',');
const result = validStatInequality(group['stats'], ineqality[0], const result = validStatInequality(group['stats'], inequality[0],
ineqality[1] as Direction, ineqality[2], +ineqality[3], input); inequality[1] as Direction, inequality[2], +inequality[3], input);
if (!result) continue; if (!result) continue;
return result; return result;
} }
@ -789,7 +789,7 @@ function runDexsearch(target: string, cmd: string, message: string, isTest: bool
// Skip over combined inequality operations because they present separately. // Skip over combined inequality operations because they present separately.
if (gEquality && !(input.search(/([><]{1}=)/) >= 0 || gInclusiveIneq)) { if (gEquality && !(input.search(/([><]{1}=)/) >= 0 || gInclusiveIneq)) {
return `The search already included '${input}' or another inequality which makes it redunant.`; return `The search already included '${input}' or another inequality which makes it redundant.`;
} else if (compareTo === 'numeric') { } else if (compareTo === 'numeric') {
if ((greater && ((inclusiveGreater && value < +greater) || (!inclusiveGreater && value <= +greater))) || if ((greater && ((inclusiveGreater && value < +greater) || (!inclusiveGreater && value <= +greater))) ||
(less && ((inclusiveLess && value > +less) || (!inclusiveLess && value >= +less)))) { (less && ((inclusiveLess && value > +less) || (!inclusiveLess && value >= +less)))) {
@ -807,7 +807,7 @@ function runDexsearch(target: string, cmd: string, message: string, isTest: bool
const checkEquality = input.includes('=') && gEquality; const checkEquality = input.includes('=') && gEquality;
if (gValue || inverseSwapValue) { if (gValue || inverseSwapValue) {
return `The search already included '${input}' or another inequality which makes it redunant.`; return `The search already included '${input}' or another inequality which makes it redundant.`;
} else if (compareTo === 'numeric' && (inverseValue || gEquality)) { } else if (compareTo === 'numeric' && (inverseValue || gEquality)) {
const result = value - Number(inverseValue || gEquality); const result = value - Number(inverseValue || gEquality);
if ((direction === 'greater' && ((checkEquality && result > 0) || (!checkEquality && result >= 0))) || if ((direction === 'greater' && ((checkEquality && result > 0) || (!checkEquality && result >= 0))) ||
@ -874,8 +874,8 @@ function runDexsearch(target: string, cmd: string, message: string, isTest: bool
tierSearch = tierSearch || !isNotSearch; tierSearch = tierSearch || !isNotSearch;
if (isTierInequalityParam) { if (isTierInequalityParam) {
const tierValue = singlesTiersValues[target]; const tierValue = singlesTiersValues[target];
const entires = Object.entries(singlesTiersValues); const entries = Object.entries(singlesTiersValues);
for (const [key, value] of entires) { for (const [key, value] of entries) {
const useTier = (value > tierValue && tierInequality[0]) || (value < tierValue && !tierInequality[0]); const useTier = (value > tierValue && tierInequality[0]) || (value < tierValue && !tierInequality[0]);
if (useTier && (!key.startsWith('CAP') || capSearch)) { if (useTier && (!key.startsWith('CAP') || capSearch)) {
orGroup.tiers[key] = true; orGroup.tiers[key] = true;
@ -896,8 +896,8 @@ function runDexsearch(target: string, cmd: string, message: string, isTest: bool
tierSearch = tierSearch || !isNotSearch; tierSearch = tierSearch || !isNotSearch;
if (isTierInequalityParam) { if (isTierInequalityParam) {
const tierValue = doublesTiersValues[target]; const tierValue = doublesTiersValues[target];
const entires = Object.entries(doublesTiersValues); const entries = Object.entries(doublesTiersValues);
for (const [key, value] of entires) { for (const [key, value] of entries) {
if ((value > tierValue && tierInequality[0]) || (value < tierValue && !tierInequality[0])) { if ((value > tierValue && tierInequality[0]) || (value < tierValue && !tierInequality[0])) {
orGroup.doublesTiers[key] = true; orGroup.doublesTiers[key] = true;
} else if (tierValue === value && tierInequality[1]) { } else if (tierValue === value && tierInequality[1]) {

View File

@ -165,7 +165,7 @@ async function convertRoomPunishments() {
} }
export function writeStats(line: string) { export function writeStats(line: string) {
// ticketType\ttotalTime\ttimeToFirstClaim\tinactiveTime\tresolution\tresult\tstaff,userids,seperated,with,commas // ticketType\ttotalTime\ttimeToFirstClaim\tinactiveTime\tresolution\tresult\tstaff,userids,separated,with,commas
const date = new Date(); const date = new Date();
const month = Chat.toTimestamp(date).split(' ')[0].split('-', 2).join('-'); const month = Chat.toTimestamp(date).split(' ')[0].split('-', 2).join('-');
try { try {
@ -442,7 +442,7 @@ export class HelpTicket extends Rooms.SimpleRoomGame {
involvedStaff = Array.from(this.involvedStaff.entries()).map(s => s[0]).join(','); involvedStaff = Array.from(this.involvedStaff.entries()).map(s => s[0]).join(',');
} }
// Write to TSV // Write to TSV
// ticketType\ttotalTime\ttimeToFirstClaim\tinactiveTime\tresolution\tresult\tstaff,userids,seperated,with,commas // ticketType\ttotalTime\ttimeToFirstClaim\tinactiveTime\tresolution\tresult\tstaff,userids,separated,with,commas
const line = `${this.ticket.type}\t${(this.closeTime - this.createTime)}\t${firstClaimWait}\t${this.unclaimedTime}\t${this.resolution}\t${this.result}\t${involvedStaff}`; const line = `${this.ticket.type}\t${(this.closeTime - this.createTime)}\t${firstClaimWait}\t${this.unclaimedTime}\t${this.resolution}\t${this.result}\t${involvedStaff}`;
writeStats(line); writeStats(line);
} }
@ -2523,7 +2523,7 @@ export const commands: Chat.ChatCommands = {
if (tarUser) { if (tarUser) {
HelpTicket.notifyResolved(tarUser, ticket, ticketId); HelpTicket.notifyResolved(tarUser, ticket, ticketId);
} }
// ticketType\ttotalTime\ttimeToFirstClaim\tinactiveTime\tresolution\tresult\tstaff,userids,seperated,with,commas // ticketType\ttotalTime\ttimeToFirstClaim\tinactiveTime\tresolution\tresult\tstaff,userids,separated,with,commas
writeStats(`${ticket.type}\t${Date.now() - ticket.created}\t0\t0\tresolved\tvalid\t${user.id}`); writeStats(`${ticket.type}\t${Date.now() - ticket.created}\t0\t0\tresolved\tvalid\t${user.id}`);
this.popupReply(`You resolved ${ticketId}'s ticket.`); this.popupReply(`You resolved ${ticketId}'s ticket.`);
await HelpTicket.modlog({ await HelpTicket.modlog({

View File

@ -405,7 +405,7 @@ class Mafia extends Rooms.RoomGame<MafiaPlayer> {
this.roles.push(player.role); this.roles.push(player.role);
this.played.push(player.id); this.played.push(player.id);
} else { } else {
// TODO improve reseting roles // TODO improve resetting roles
this.originalRoles = []; this.originalRoles = [];
this.originalRoleString = ''; this.originalRoleString = '';
this.roles = []; this.roles = [];
@ -1854,7 +1854,7 @@ class Mafia extends Rooms.RoomGame<MafiaPlayer> {
this.sendHTML(this.roomWindow()); this.sendHTML(this.roomWindow());
this.updatePlayers(); this.updatePlayers();
if (this.room.roomid === 'mafia' && this.started) { if (this.room.roomid === 'mafia' && this.started) {
// Intead of using this.played, which shows players who have subbed out as well // Instead of using this.played, which shows players who have subbed out as well
// We check who played through to the end when recording playlogs // We check who played through to the end when recording playlogs
const played = this.players.map(p => p.id); const played = this.players.map(p => p.id);
const month = new Date().toLocaleString("en-us", { month: "numeric", year: "numeric" }); const month = new Date().toLocaleString("en-us", { month: "numeric", year: "numeric" });
@ -2111,12 +2111,12 @@ export const pages: Chat.PageTable = {
} }
buf += `<p><details><summary class="button" style="text-align:left; display:inline-block">How to setup roles</summary>`; buf += `<p><details><summary class="button" style="text-align:left; display:inline-block">How to setup roles</summary>`;
buf += `<h3>Setting the roles</h3>`; buf += `<h3>Setting the roles</h3>`;
buf += `<p>To set the roles, use /mafia setroles [comma seperated list of roles] OR /mafia setroles [theme] in ${room.title}.</p>`; buf += `<p>To set the roles, use /mafia setroles [comma separated list of roles] OR /mafia setroles [theme] in ${room.title}.</p>`;
buf += `<p>If you set the roles from a theme, the role parser will get all the correct roles for you. (Not all themes are supported).</p>`; buf += `<p>If you set the roles from a theme, the role parser will get all the correct roles for you. (Not all themes are supported).</p>`;
buf += `<p>The following key words determine a role's alignment (If none are found, the default alignment is town):</p>`; buf += `<p>The following key words determine a role's alignment (If none are found, the default alignment is town):</p>`;
buf += `<p style="font-weight:bold">${Object.values(MafiaData.alignments).map(a => `<span style="color:${a.color || '#FFF'}">${a.name}</span>`).join(', ')}</p>`; buf += `<p style="font-weight:bold">${Object.values(MafiaData.alignments).map(a => `<span style="color:${a.color || '#FFF'}">${a.name}</span>`).join(', ')}</p>`;
buf += `<p>Please note that anything inside (parentheses) is ignored by the role parser.</p>`; buf += `<p>Please note that anything inside (parentheses) is ignored by the role parser.</p>`;
buf += `<p>If you have roles that have conflicting alignments or base roles, you can use /mafia forcesetroles [comma seperated list of roles] to forcibly set the roles.</p>`; buf += `<p>If you have roles that have conflicting alignments or base roles, you can use /mafia forcesetroles [comma separated list of roles] to forcibly set the roles.</p>`;
buf += `<p>Please note that you will have to PM all the players their alignment, partners (if any), and other information about their role because the server will not provide it.</p>`; buf += `<p>Please note that you will have to PM all the players their alignment, partners (if any), and other information about their role because the server will not provide it.</p>`;
buf += `<hr/></details></p>`; buf += `<hr/></details></p>`;
buf += `<p style="font-weight:bold;">Players who will be subbed unless they talk: ${game.hostRequestedSub.join(', ')}</p>`; buf += `<p style="font-weight:bold;">Players who will be subbed unless they talk: ${game.hostRequestedSub.join(', ')}</p>`;
@ -3461,7 +3461,7 @@ export const commands: Chat.ChatCommands = {
this.modlog('MAFIASUBHOST', targetUser, `replacing ${oldHostid}`, { noalts: true, noip: true }); this.modlog('MAFIASUBHOST', targetUser, `replacing ${oldHostid}`, { noalts: true, noip: true });
} }
}, },
subhosthelp: [`/mafia subhost [user] - Substitues the user as the new game host.`], subhosthelp: [`/mafia subhost [user] - Substitutes the user as the new game host.`],
cohosthelp: [ cohosthelp: [
`/mafia cohost [user] - Adds the user as a cohost. Cohosts can talk during the game, as well as perform host actions.`, `/mafia cohost [user] - Adds the user as a cohost. Cohosts can talk during the game, as well as perform host actions.`,
], ],
@ -4113,7 +4113,7 @@ export const commands: Chat.ChatCommands = {
`/mafia players - Display the current list of players, will highlight players.`, `/mafia players - Display the current list of players, will highlight players.`,
`/mafia [rl|orl] - Display the role list or the original role list for the current game.`, `/mafia [rl|orl] - Display the role list or the original role list for the current game.`,
`/mafia data [alignment|role|modifier|theme|term] - Get information on a mafia alignment, role, modifier, theme, or term.`, `/mafia data [alignment|role|modifier|theme|term] - Get information on a mafia alignment, role, modifier, theme, or term.`,
`/mafia subhost [user] - Substitues the user as the new game host. Requires % @ # ~`, `/mafia subhost [user] - Substitutes the user as the new game host. Requires % @ # ~`,
`/mafia (un)cohost [user] - Adds/removes the user as a cohost. Cohosts can talk during the game, as well as perform host actions. Requires % @ # ~`, `/mafia (un)cohost [user] - Adds/removes the user as a cohost. Cohosts can talk during the game, as well as perform host actions. Requires % @ # ~`,
`/mafia [enable|disable] - Enables/disables mafia in this room. Requires # ~`, `/mafia [enable|disable] - Enables/disables mafia in this room. Requires # ~`,
].join('<br/>'); ].join('<br/>');
@ -4143,8 +4143,8 @@ export const commands: Chat.ChatCommands = {
`/mafia votelock [on|off] - Allows or disallows players to change their vote. Requires host % @ # ~`, `/mafia votelock [on|off] - Allows or disallows players to change their vote. Requires host % @ # ~`,
`/mafia voting [on|off] - Allows or disallows voting. Requires host % @ # ~`, `/mafia voting [on|off] - Allows or disallows voting. Requires host % @ # ~`,
`/mafia forcevote [yes/no] - Forces players' votes onto themselves, and prevents unvoting. Requires host % @ # ~`, `/mafia forcevote [yes/no] - Forces players' votes onto themselves, and prevents unvoting. Requires host % @ # ~`,
`/mafia setroles [comma seperated roles] - Set the roles for a game of mafia. You need to provide one role per player. Requires host % @ # ~`, `/mafia setroles [comma separated roles] - Set the roles for a game of mafia. You need to provide one role per player. Requires host % @ # ~`,
`/mafia forcesetroles [comma seperated roles] - Forcibly set the roles for a game of mafia. No role PM information or alignment will be set. Requires host % @ # ~`, `/mafia forcesetroles [comma separated roles] - Forcibly set the roles for a game of mafia. No role PM information or alignment will be set. Requires host % @ # ~`,
`/mafia start - Start the game of mafia. Signups must be closed. Requires host % @ # ~`, `/mafia start - Start the game of mafia. Signups must be closed. Requires host % @ # ~`,
`/mafia [day|night] - Move to the next game day or night. Requires host % @ # ~`, `/mafia [day|night] - Move to the next game day or night. Requires host % @ # ~`,
`/mafia extend (minutes) - Return to the previous game day. If (minutes) is provided, set the deadline for (minutes) minutes. Requires host % @ # ~`, `/mafia extend (minutes) - Return to the previous game day. If (minutes) is provided, set the deadline for (minutes) minutes. Requires host % @ # ~`,
@ -4162,7 +4162,7 @@ export const commands: Chat.ChatCommands = {
`/mafia (un)[priest|actor] [player] - Makes [player] a priest (can't hammer) or actor (can only hammer). Requires host % @ # ~`, `/mafia (un)[priest|actor] [player] - Makes [player] a priest (can't hammer) or actor (can only hammer). Requires host % @ # ~`,
`/mafia deadline [minutes|off] - Sets or removes the deadline for the game. Cannot be more than 20 minutes.`, `/mafia deadline [minutes|off] - Sets or removes the deadline for the game. Cannot be more than 20 minutes.`,
`/mafia sub next, [player] - Forcibly sub [player] out of the game. Requires host % @ # ~`, `/mafia sub next, [player] - Forcibly sub [player] out of the game. Requires host % @ # ~`,
`/mafia sub remove, [user] - Forcibly remove [user] from the sublist. Requres host % @ # ~`, `/mafia sub remove, [user] - Forcibly remove [user] from the sublist. Requires host % @ # ~`,
`/mafia sub unrequest, [player] - Remove's a player's request to sub out of the game. Requires host % @ # ~`, `/mafia sub unrequest, [player] - Remove's a player's request to sub out of the game. Requires host % @ # ~`,
`/mafia sub [player], [user] - Forcibly sub [player] for [user]. Requires host % @ # ~`, `/mafia sub [player], [user] - Forcibly sub [player] for [user]. Requires host % @ # ~`,
`/mafia autosub [yes|no] - Sets if players will automatically sub out if a user is on the sublist. Defaults to yes. Requires host % @ # ~`, `/mafia autosub [yes|no] - Sets if players will automatically sub out if a user is on the sublist. Defaults to yes. Requires host % @ # ~`,

View File

@ -276,7 +276,7 @@ export const commands: Chat.ChatCommands = {
`<code>/suspects</code>: displays currently running suspect tests.<br />` + `<code>/suspects</code>: displays currently running suspect tests.<br />` +
`<code>/suspects add [tier], [suspect], [date], [...reqs]</code>: adds a suspect test. Date in the format MM/DD. ` + `<code>/suspects add [tier], [suspect], [date], [...reqs]</code>: adds a suspect test. Date in the format MM/DD. ` +
`Reqs in the format [key]=[value], where valid keys are 'coil', 'elo', and 'gxe', delimited by commas. At least one is required. <br />` + `Reqs in the format [key]=[value], where valid keys are 'coil', 'elo', and 'gxe', delimited by commas. At least one is required. <br />` +
`(note that if you are using COIL, you must set a B value indepedently with <code>/suspects setcoil</code>). Requires: ~<br />` + `(note that if you are using COIL, you must set a B value independently with <code>/suspects setcoil</code>). Requires: ~<br />` +
`<code>/suspects remove [tier]</code>: deletes a suspect test. Requires: ~<br />` + `<code>/suspects remove [tier]</code>: deletes a suspect test. Requires: ~<br />` +
`<code>/suspects whitelist [username]</code>: allows [username] to add suspect tests. Requires: ~<br />` + `<code>/suspects whitelist [username]</code>: allows [username] to add suspect tests. Requires: ~<br />` +
`<code>/suspects unwhitelist [username]</code>: disallows [username] from adding suspect tests. Requires: ~<br />` + `<code>/suspects unwhitelist [username]</code>: disallows [username] from adding suspect tests. Requires: ~<br />` +

View File

@ -156,7 +156,7 @@ The beginning of a battle will look something like this:
`|t:|TIMESTAMP` `|t:|TIMESTAMP`
> The current UNIX timestamp (the number of seconds since 1970) - useful for determining > The current UNIX timestamp (the number of seconds since 1970) - useful for determining
> when events occured in real time. > when events occurred in real time.
### Identifying Pokémon ### Identifying Pokémon
@ -316,7 +316,7 @@ stat boosts are minor actions.
`|-fail|POKEMON|ACTION` `|-fail|POKEMON|ACTION`
> The specified `ACTION` has failed against the `POKEMON` targetted. The > The specified `ACTION` has failed against the `POKEMON` targeted. The
> `ACTION` in question should be a move that fails due to its own mechanics. > `ACTION` in question should be a move that fails due to its own mechanics.
> Moves (or effect activations) that fail because they're blocked by another > Moves (or effect activations) that fail because they're blocked by another
> effect should use `-block` instead. > effect should use `-block` instead.

View File

@ -619,7 +619,7 @@ export class Side {
if (maxMove) targetType = this.battle.dex.moves.get(maxMove).target; if (maxMove) targetType = this.battle.dex.moves.get(maxMove).target;
// Validate targetting // Validate targeting
if (autoChoose) { if (autoChoose) {
targetLoc = 0; targetLoc = 0;

View File

@ -154,7 +154,7 @@ export const State = new class {
return battle; return battle;
} }
// Direct comparsions of serialized state will be flakey as the timestamp // Direct comparisons of serialized state will be flakey as the timestamp
// protocol message |t:| can diverge between two different runs over the same state. // protocol message |t:| can diverge between two different runs over the same state.
// State must first be normalized before it is comparable. // State must first be normalized before it is comparable.
normalize(state: AnyObject) { normalize(state: AnyObject) {
@ -256,7 +256,7 @@ export const State = new class {
// Simply looking for a 'hit' field to determine if an object is an ActiveMove or not seems // Simply looking for a 'hit' field to determine if an object is an ActiveMove or not seems
// pretty fragile, but its no different than what the simulator is doing. We go further and // pretty fragile, but its no different than what the simulator is doing. We go further and
// also check if the object has an 'id', as that's what we will intrepret as the Move. // also check if the object has an 'id', as that's what we will interpret as the Move.
isActiveMove(obj: AnyObject): obj is ActiveMove { isActiveMove(obj: AnyObject): obj is ActiveMove {
return obj.hasOwnProperty('hit') && (obj.hasOwnProperty('id') || obj.hasOwnProperty('move')); return obj.hasOwnProperty('hit') && (obj.hasOwnProperty('id') || obj.hasOwnProperty('move'));
} }

View File

@ -559,7 +559,7 @@ export class TeamValidator {
let species = dex.species.get(set.species); let species = dex.species.get(set.species);
set.species = species.name; set.species = species.name;
// Backwards compatability with old Gmax format // Backwards compatibility with old Gmax format
if (set.species.toLowerCase().endsWith('-gmax') && this.format.id !== 'gen8megamax') { if (set.species.toLowerCase().endsWith('-gmax') && this.format.id !== 'gen8megamax') {
set.species = set.species.slice(0, -5); set.species = set.species.slice(0, -5);
species = dex.species.get(set.species); species = dex.species.get(set.species);
@ -2311,7 +2311,7 @@ export class TeamValidator {
return problems; return problems;
} }
/** /**
* Returns a list of problems regarding a Pokemon's avilability in Pokemon GO (empty list if no problems) * Returns a list of problems regarding a Pokemon's availability in Pokemon GO (empty list if no problems)
* If the Pokemon cannot be obtained from Pokemon GO, returns null * If the Pokemon cannot be obtained from Pokemon GO, returns null
*/ */
validatePokemonGo( validatePokemonGo(
@ -2594,7 +2594,7 @@ export class TeamValidator {
const ability = dex.abilities.get(set.ability); const ability = dex.abilities.get(set.ability);
if (dex.gen < 6 && ability.gen > learnedGen && !checkingPrevo) { if (dex.gen < 6 && ability.gen > learnedGen && !checkingPrevo) {
// You can evolve a transfered mon to reroll for its new Ability. // You can evolve a transferred mon to reroll for its new Ability.
cantLearnReason = `is learned in gen ${learnedGen}, but the Ability ${ability.name} did not exist then.`; cantLearnReason = `is learned in gen ${learnedGen}, but the Ability ${ability.name} did not exist then.`;
continue; continue;
} }

View File

@ -180,7 +180,7 @@ export class ExhaustiveRunner {
// validation). Coordinates with the CoordinatedPlayerAI below through Pools to ensure as // validation). Coordinates with the CoordinatedPlayerAI below through Pools to ensure as
// many different options as possible get exercised in battle. // many different options as possible get exercised in battle.
class TeamGenerator { class TeamGenerator {
// By default, the TeamGenerator generates sets completely at random which unforunately means // By default, the TeamGenerator generates sets completely at random which unfortunately means
// certain signature combinations (eg. Mega Stone/Z Moves which only work for specific Pokemon) // certain signature combinations (eg. Mega Stone/Z Moves which only work for specific Pokemon)
// are unlikely to be chosen. To combat this, we keep a mapping of these combinations and some // are unlikely to be chosen. To combat this, we keep a mapping of these combinations and some
// fraction of the time when we are generating sets for these particular Pokemon we give them // fraction of the time when we are generating sets for these particular Pokemon we give them

View File

@ -124,13 +124,13 @@ describe('broader, more integrated Punishments tests', function () {
const initialLogLength = this.room.log.log.length; const initialLogLength = this.room.log.log.length;
await this.parse("Hi! I'm a locked user!"); await this.parse("Hi! I'm a locked user!");
assert.equal(this.room.log.log.length, initialLogLength, `user should be unable to sucessfully chat while locked`); assert.equal(this.room.log.log.length, initialLogLength, `user should be unable to successfully chat while locked`);
Punishments.unlock(this.user.id); Punishments.unlock(this.user.id);
await this.parse("/msgroom lobby,Hi! I'm no longer locked!"); await this.parse("/msgroom lobby,Hi! I'm no longer locked!");
// we can't just check the roomlog length because unlocking adds a |n| message to // we can't just check the roomlog length because unlocking adds a |n| message to
const lastMessage = this.room.log.log.pop(); const lastMessage = this.room.log.log.pop();
assert(lastMessage.endsWith(` Lock Me Please|Hi! I'm no longer locked!`), `user should have sucessfuly sent a message after being locked`); assert(lastMessage.endsWith(` Lock Me Please|Hi! I'm no longer locked!`), `user should have successfully sent a message after being locked`);
}); });
// This test relies on Chat#parse returning `false` when permission is denied. // This test relies on Chat#parse returning `false` when permission is denied.
@ -138,13 +138,13 @@ describe('broader, more integrated Punishments tests', function () {
// an `ErrorMessage` is the only time `false` will be returned by Chat#parse (unless a chat command returns it, which /msg does not). // an `ErrorMessage` is the only time `false` will be returned by Chat#parse (unless a chat command returns it, which /msg does not).
// If you are here because this test is failing, check if the above assumptions are still valid. // If you are here because this test is failing, check if the above assumptions are still valid.
// If they are not, the test should either be refactored to use another way of // If they are not, the test should either be refactored to use another way of
// determining whether a PM was sucessful (such as modifying Chat.sendPM), or skipped entirely. // determining whether a PM was successful (such as modifying Chat.sendPM), or skipped entirely.
it('should prevent users from sending PMs other than to staff while they are locked', async () => { it('should prevent users from sending PMs other than to staff while they are locked', async () => {
makeUser("Some Random Reg", '127.0.0.4'); makeUser("Some Random Reg", '127.0.0.4');
makeUser("Annika", '127.0.0.5').tempGroup = '~'; makeUser("Annika", '127.0.0.5').tempGroup = '~';
let result = await this.parse("/msg Some Random Reg, Hi! I'm a locked user!"); let result = await this.parse("/msg Some Random Reg, Hi! I'm a locked user!");
assert.equal(result, false, `user should be unable to sucessfully send PMs while locked`); assert.equal(result, false, `user should be unable to successfully send PMs while locked`);
result = await this.parse("/msg Annika, Hi! I'm a locked user!"); result = await this.parse("/msg Annika, Hi! I'm a locked user!");
assert.notEqual(result, false, `user should be able to send PMs to global staff while locked`); assert.notEqual(result, false, `user should be able to send PMs to global staff while locked`);

View File

@ -49,7 +49,7 @@ describe('Neutralizing Gas', () => {
assert.statStage(battle.p2.active[0], 'atk', -1); assert.statStage(battle.p2.active[0], 'atk', -1);
}); });
it(`should negate abilites that activate on switch-out`, () => { it(`should negate abilities that activate on switch-out`, () => {
battle = common.createBattle([ battle = common.createBattle([
[{ species: "Weezing", ability: 'neutralizinggas', moves: ['toxic'] }, [{ species: "Weezing", ability: 'neutralizinggas', moves: ['toxic'] },
{ species: "Type: Null", ability: 'battlearmor', moves: ['facade'] }], { species: "Type: Null", ability: 'battlearmor', moves: ['facade'] }],

View File

@ -608,7 +608,7 @@ describe('Choices', () => {
assert(logText.includes(subString), `${logText} does not include ${subString}`); assert(logText.includes(subString), `${logText} does not include ${subString}`);
}); });
it('should privately log the target of targetted chosen moves', () => { it('should privately log the target of targeted chosen moves', () => {
battle = common.createBattle({ gameType: 'doubles' }, [[ battle = common.createBattle({ gameType: 'doubles' }, [[
{ species: "Bulbasaur", ability: 'overgrow', moves: ['tackle'] }, { species: "Bulbasaur", ability: 'overgrow', moves: ['tackle'] },
{ species: "Ivysaur", ability: 'overgrow', moves: ['tackle'] }, { species: "Ivysaur", ability: 'overgrow', moves: ['tackle'] },

View File

@ -22,7 +22,7 @@ describe('Hazards', () => {
assert.false(battle.field.isTerrain('electricterrain')); assert.false(battle.field.isTerrain('electricterrain'));
}); });
it(`should damage multiple Pokemon switching in simulatenously by Speed order`, () => { it(`should damage multiple Pokemon switching in simultaneously by Speed order`, () => {
battle = common.createBattle([[ battle = common.createBattle([[
{ species: 'wynaut', moves: ['stealthrock', 'sleeptalk'] }, { species: 'wynaut', moves: ['stealthrock', 'sleeptalk'] },
{ species: 'kyogre', ability: 'drizzle', item: 'choicescarf', moves: ['sleeptalk'] }, { species: 'kyogre', ability: 'drizzle', item: 'choicescarf', moves: ['sleeptalk'] },

View File

@ -7,7 +7,7 @@ let battle;
describe(`[Hackmons] Ogerpon`, () => { describe(`[Hackmons] Ogerpon`, () => {
// https://www.smogon.com/forums/threads/scarlet-violet-battle-mechanics-research.3709545/post-9838633 // https://www.smogon.com/forums/threads/scarlet-violet-battle-mechanics-research.3709545/post-9838633
it(`should keep permanent abilites after Terastallizing until it switches out`, () => { it(`should keep permanent abilities after Terastallizing until it switches out`, () => {
battle = common.gen(9).createBattle([[ battle = common.gen(9).createBattle([[
{ species: 'ogerpon', ability: 'multitype', moves: ['sleeptalk'] }, { species: 'ogerpon', ability: 'multitype', moves: ['sleeptalk'] },
{ species: 'shedinja', moves: ['splash'] }, { species: 'shedinja', moves: ['splash'] },

View File

@ -121,28 +121,28 @@ describe(`PRNG`, () => {
}); });
it(`should return items with equal probability for a five-item array`, () => { it(`should return items with equal probability for a five-item array`, () => {
const items = ['a', 'b', 'c', 'd', 'e']; const items = ['a', 'b', 'c', 'd', 'e'];
const occurences = { a: 0, b: 0, c: 0, d: 0, e: 0 }; const occurrences = { a: 0, b: 0, c: 0, d: 0, e: 0 };
const prng = new PRNG(testSeed); const prng = new PRNG(testSeed);
for (let i = 0; i < 1000; ++i) { for (let i = 0; i < 1000; ++i) {
const sample = prng.sample(items); const sample = prng.sample(items);
occurences[sample] += 1; occurrences[sample] += 1;
} }
assert.bounded(occurences.a, [170, 230]); assert.bounded(occurrences.a, [170, 230]);
assert.bounded(occurences.b, [170, 230]); assert.bounded(occurrences.b, [170, 230]);
assert.bounded(occurences.c, [170, 230]); assert.bounded(occurrences.c, [170, 230]);
assert.bounded(occurences.d, [170, 230]); assert.bounded(occurrences.d, [170, 230]);
assert.bounded(occurences.e, [170, 230]); assert.bounded(occurrences.e, [170, 230]);
}); });
it(`should return items with weighted probability for a three-item array with duplicates`, () => { it(`should return items with weighted probability for a three-item array with duplicates`, () => {
const items = ['x', 'x', 'y']; const items = ['x', 'x', 'y'];
const occurences = { x: 0, y: 0 }; const occurrences = { x: 0, y: 0 };
const prng = new PRNG(testSeed); const prng = new PRNG(testSeed);
for (let i = 0; i < 100; ++i) { for (let i = 0; i < 100; ++i) {
const sample = prng.sample(items); const sample = prng.sample(items);
occurences[sample] += 1; occurrences[sample] += 1;
} }
assert.bounded(occurences.x, [63, 71]); assert.bounded(occurrences.x, [63, 71]);
assert.bounded(occurences.y, [29, 37]); assert.bounded(occurrences.y, [29, 37]);
}); });
it(`should be identical to array[random(array.length)]`, () => { it(`should be identical to array[random(array.length)]`, () => {
// This invariant is important for battle logs. // This invariant is important for battle logs.

View File

@ -39,7 +39,7 @@ describe('Acupressure', () => {
}); });
// https://www.smogon.com/forums/threads/acupressure-targeting.3733779/post-9920405 // https://www.smogon.com/forums/threads/acupressure-targeting.3733779/post-9920405
it(`should redirect to the user if a targetted ally faints`, () => { it(`should redirect to the user if a targeted ally faints`, () => {
battle = common.createBattle({ gameType: 'doubles' }, [[ battle = common.createBattle({ gameType: 'doubles' }, [[
{ species: 'Pincurchin', moves: ['acupressure'] }, { species: 'Pincurchin', moves: ['acupressure'] },
{ species: 'Flutter Mane', moves: ['memento'] }, { species: 'Flutter Mane', moves: ['memento'] },
@ -54,7 +54,7 @@ describe('Acupressure', () => {
assert(Object.values(battle.p1.active[0].boosts).some(n => n === 2)); assert(Object.values(battle.p1.active[0].boosts).some(n => n === 2));
}); });
it(`in Gen 5, should not redirect to the uesr if a targetted ally faints`, () => { it(`in Gen 5, should not redirect to the uesr if a targeted ally faints`, () => {
battle = common.gen(5).createBattle({ gameType: 'doubles' }, [[ battle = common.gen(5).createBattle({ gameType: 'doubles' }, [[
{ species: 'Shuckle', moves: ['acupressure'] }, { species: 'Shuckle', moves: ['acupressure'] },
{ species: 'Dugtrio', moves: ['memento'] }, { species: 'Dugtrio', moves: ['memento'] },

View File

@ -131,7 +131,7 @@ describe('Curse', () => {
}); });
}); });
describe('XY/ORAS Curse targetting when becoming Ghost the same turn', () => { describe('XY/ORAS Curse targeting when becoming Ghost the same turn', () => {
afterEach(() => { afterEach(() => {
battle.destroy(); battle.destroy();
}); });

View File

@ -34,7 +34,7 @@ describe('Follow Me', () => {
assert.equal(hitCount, 2); assert.equal(hitCount, 2);
}); });
it('should not redirect self-targetting moves', () => { it('should not redirect self-targeting moves', () => {
battle = common.createBattle({ gameType: 'doubles' }); battle = common.createBattle({ gameType: 'doubles' });
battle.setPlayer('p1', { team: [ battle.setPlayer('p1', { team: [
{ species: 'Clefable', ability: 'unaware', moves: ['followme'] }, { species: 'Clefable', ability: 'unaware', moves: ['followme'] },

View File

@ -216,7 +216,7 @@ describe('Heal Block [Gen 4]', () => {
assert.notEqual(battle.p1.active[0].hp, battle.p1.active[0].maxhp); assert.notEqual(battle.p1.active[0].hp, battle.p1.active[0].maxhp);
}); });
it('should fail indepedently on each target', () => { it('should fail independently on each target', () => {
battle = common.createBattle({ gameType: 'doubles' }, [[ battle = common.createBattle({ gameType: 'doubles' }, [[
{ species: 'porygon2', moves: ['sleeptalk'] }, { species: 'porygon2', moves: ['sleeptalk'] },
{ species: 'marshadow', moves: ['sleeptalk'] }, { species: 'marshadow', moves: ['sleeptalk'] },

View File

@ -19,7 +19,7 @@ describe('Substitute', () => {
assert.equal(pokemon.maxhp - pokemon.hp, Math.floor(pokemon.maxhp / 4)); assert.equal(pokemon.maxhp - pokemon.hp, Math.floor(pokemon.maxhp / 4));
}); });
it('should not block the user\'s own moves from targetting itself', () => { it('should not block the user\'s own moves from targeting itself', () => {
battle = common.createBattle(); battle = common.createBattle();
battle.setPlayer('p1', { team: [{ species: 'Mewtwo', ability: 'pressure', moves: ['substitute', 'calmmind'] }] }); battle.setPlayer('p1', { team: [{ species: 'Mewtwo', ability: 'pressure', moves: ['substitute', 'calmmind'] }] });
battle.setPlayer('p2', { team: [{ species: 'Mewtwo', ability: 'pressure', moves: ['recover'] }] }); battle.setPlayer('p2', { team: [{ species: 'Mewtwo', ability: 'pressure', moves: ['recover'] }] });
@ -107,7 +107,7 @@ describe('Substitute', () => {
assert.equal(battle.p2.active[0].hp - hp, Math.ceil(Math.floor(battle.p1.active[0].maxhp / 4) / 2)); assert.equal(battle.p2.active[0].hp - hp, Math.ceil(Math.floor(battle.p1.active[0].maxhp / 4) / 2));
}); });
it('should block most status moves targetting the user', () => { it('should block most status moves targeting the user', () => {
battle = common.createBattle(); battle = common.createBattle();
battle.setPlayer('p1', { team: [{ species: 'Mewtwo', ability: 'noguard', moves: ['substitute'] }] }); battle.setPlayer('p1', { team: [{ species: 'Mewtwo', ability: 'noguard', moves: ['substitute'] }] });
battle.setPlayer('p2', { team: [{ species: 'Mewtwo', ability: 'pressure', item: 'laggingtail', moves: ['hypnosis', 'toxic', 'poisongas', 'thunderwave', 'willowisp'] }] }); battle.setPlayer('p2', { team: [{ species: 'Mewtwo', ability: 'pressure', item: 'laggingtail', moves: ['hypnosis', 'toxic', 'poisongas', 'thunderwave', 'willowisp'] }] });

View File

@ -49,7 +49,7 @@ games asynchronously.
large performance benefits over the default sequential mode and may require large performance benefits over the default sequential mode and may require
additional memory. additional memory.
**TODO**: Add support for running battles in `--parallel` on muliple cores with **TODO**: Add support for running battles in `--parallel` on multiple cores with
[`worker_threads`](https://nodejs.org/api/worker_threads.html). [`worker_threads`](https://nodejs.org/api/worker_threads.html).
## exhaustive ## exhaustive
@ -74,4 +74,4 @@ likely to catch fire.
- **`--forever`**: continue iterating through formats infinitely, exhausting - **`--forever`**: continue iterating through formats infinitely, exhausting
each `--cycles` times. each `--cycles` times.
- **`--seed`**: PRNG seed to use (eg. `'1234,5678,9012,3456'`). - **`--seed`**: PRNG seed to use (eg. `'1234,5678,9012,3456'`).
- **`--maxFailures`**: exit early if this many failures have occured. - **`--maxFailures`**: exit early if this many failures have occurred.