From 89128dee97060b57d4d4b9d265cf377a255b579a Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Thu, 6 Jun 2024 17:16:59 -0600 Subject: [PATCH] Utils#Multiset: Redefine `get` to remove `undefined` return (#10329) --- config/formats.ts | 20 ++++++++++---------- data/random-battles/gen8/teams.ts | 4 ---- data/random-battles/gen9/teams.ts | 4 ---- data/random-battles/gen9baby/teams.ts | 10 +++++----- data/rulesets.ts | 11 +++++------ lib/utils.ts | 7 +++++-- server/chat-plugins/chat-monitor.ts | 2 +- server/chat-plugins/modlog-viewer.ts | 4 ++-- server/chat-plugins/wifi.tsx | 4 ++-- sim/dex.ts | 1 + 10 files changed, 31 insertions(+), 36 deletions(-) diff --git a/config/formats.ts b/config/formats.ts index 7464f1253daa..9426bd9a28c9 100644 --- a/config/formats.ts +++ b/config/formats.ts @@ -834,7 +834,7 @@ export const Formats: FormatList = [ }, onValidateTeam(team, f, teamHas) { if (this.ruleTable.has('abilityclause')) { - const abilityTable = new Map(); + const abilityTable = new this.dex.Multiset(); const base: {[k: string]: string} = { airlock: 'cloudnine', armortail: 'queenlymajesty', @@ -860,13 +860,13 @@ export const Formats: FormatList = [ let ability = this.toID(set.ability.split('0')[0]); if (!ability) continue; if (ability in base) ability = base[ability] as ID; - if ((abilityTable.get(ability) || 0) >= num) { + if (abilityTable.get(ability) >= num) { return [ `You are limited to ${num} of each ability by ${num} Ability Clause.`, `(You have more than ${num} ${this.dex.abilities.get(ability).name} variants)`, ]; } - abilityTable.set(ability, (abilityTable.get(ability) || 0) + 1); + abilityTable.add(ability); } } @@ -2158,9 +2158,9 @@ export const Formats: FormatList = [ ], onValidateTeam(team, format, teamHas) { const problems = []; - for (const trademark in teamHas.trademarks) { - if (teamHas.trademarks[trademark] > 1) { - problems.push(`You are limited to 1 of each Trademark.`, `(You have ${teamHas.trademarks[trademark]} Pok\u00e9mon with ${trademark} as a Trademark.)`); + for (const trademark of teamHas.trademarks.keys()) { + if (teamHas.trademarks.get(trademark) > 1) { + problems.push(`You are limited to 1 of each Trademark.`, `(You have ${teamHas.trademarks.get(trademark)} Pok\u00e9mon with ${trademark} as a Trademark.)`); } } return problems; @@ -2199,8 +2199,8 @@ export const Formats: FormatList = [ set.ability = 'No Ability'; problems = problems.concat(validator.validateSet(set, teamHas) || []); set.ability = ability.id; - if (!teamHas.trademarks) teamHas.trademarks = {}; - teamHas.trademarks[ability.name] = (teamHas.trademarks[ability.name] || 0) + 1; + if (!teamHas.trademarks) teamHas.trademarks = new this.dex.Multiset(); + teamHas.trademarks.add(ability.name); return problems.length ? problems : null; }, }, @@ -2424,11 +2424,11 @@ export const Formats: FormatList = [ restricted: ['Arceus'], onValidateTeam(team, format) { // baseSpecies:count - const restrictedPokemonCount = new Map(); + const restrictedPokemonCount = new this.dex.Multiset(); for (const set of team) { const species = this.dex.species.get(set.species); if (!this.ruleTable.isRestrictedSpecies(species)) continue; - restrictedPokemonCount.set(species.baseSpecies, (restrictedPokemonCount.get(species.baseSpecies) || 0) + 1); + restrictedPokemonCount.add(species.baseSpecies); } for (const [baseSpecies, count] of restrictedPokemonCount) { if (count > 1) { diff --git a/data/random-battles/gen8/teams.ts b/data/random-battles/gen8/teams.ts index 1cec6b38ed3e..7a20cf2c2a77 100644 --- a/data/random-battles/gen8/teams.ts +++ b/data/random-battles/gen8/teams.ts @@ -47,10 +47,6 @@ export class MoveCounter extends Utils.Multiset { this.damagingMoves = new Set(); this.setupType = ''; } - - get(key: string): number { - return super.get(key) || 0; - } } type MoveEnforcementChecker = ( diff --git a/data/random-battles/gen9/teams.ts b/data/random-battles/gen9/teams.ts index f9993273db9d..13f94c7f538c 100644 --- a/data/random-battles/gen9/teams.ts +++ b/data/random-battles/gen9/teams.ts @@ -54,10 +54,6 @@ export class MoveCounter extends Utils.Multiset { this.damagingMoves = new Set(); this.ironFist = 0; } - - get(key: string): number { - return super.get(key) || 0; - } } type MoveEnforcementChecker = ( diff --git a/data/random-battles/gen9baby/teams.ts b/data/random-battles/gen9baby/teams.ts index 89cd6bc7ae00..6d7723495669 100644 --- a/data/random-battles/gen9baby/teams.ts +++ b/data/random-battles/gen9baby/teams.ts @@ -770,7 +770,7 @@ export class RandomBabyTeams extends RandomTeams { // Limit two of any type for (const typeName of types) { - if ((typeCount.get(typeName) || 0) >= 2 * limitFactor) { + if (typeCount.get(typeName) >= 2 * limitFactor) { skip = true; break; } @@ -781,13 +781,13 @@ export class RandomBabyTeams extends RandomTeams { for (const typeName of this.dex.types.names()) { // it's weak to the type if (this.dex.getEffectiveness(typeName, species) > 0) { - if ((typeWeaknesses.get(typeName) || 0) >= 3 * limitFactor) { + if (typeWeaknesses.get(typeName) >= 3 * limitFactor) { skip = true; break; } } if (this.dex.getEffectiveness(typeName, species) > 1) { - if ((typeDoubleWeaknesses.get(typeName) || 0) >= 1 * limitFactor) { + if (typeDoubleWeaknesses.get(typeName) >= 1 * limitFactor) { skip = true; break; } @@ -797,12 +797,12 @@ export class RandomBabyTeams extends RandomTeams { // Limit four weak to Freeze-Dry if (weakToFreezeDry) { - if ((typeWeaknesses.get('Freeze-Dry') || 0) >= 4 * limitFactor) continue; + if (typeWeaknesses.get('Freeze-Dry') >= 4 * limitFactor) continue; } } // Limit three of any type combination in Monotype - if (!this.forceMonotype && isMonotype && ((typeComboCount.get(typeCombo) || 0) >= 3 * limitFactor)) continue; + if (!this.forceMonotype && isMonotype && typeComboCount.get(typeCombo) >= 3 * limitFactor) continue; const set: RandomTeamsTypes.RandomSet = this.randomSet(species, teamDetails, false, false); pokemon.push(set); diff --git a/data/rulesets.ts b/data/rulesets.ts index 9eac725b2414..b9171a543bbd 100644 --- a/data/rulesets.ts +++ b/data/rulesets.ts @@ -1,6 +1,5 @@ // Note: These are the rules that formats use -import {Utils} from "../lib"; import type {Learnset} from "../sim/dex-species"; import {Pokemon} from "../sim/pokemon"; @@ -812,7 +811,7 @@ export const Rulesets: {[k: string]: FormatData} = { }, onValidateTeam(team) { if (this.format.id === 'gen8multibility') return; - const abilityTable = new Map(); + const abilityTable = new this.dex.Multiset(); const base: {[k: string]: string} = { airlock: 'cloudnine', armortail: 'queenlymajesty', @@ -838,13 +837,13 @@ export const Rulesets: {[k: string]: FormatData} = { let ability = this.toID(set.ability); if (!ability) continue; if (ability in base) ability = base[ability] as ID; - if ((abilityTable.get(ability) || 0) >= num) { + if (abilityTable.get(ability) >= num) { return [ `You are limited to ${num} of each ability by Ability Clause.`, `(You have more than ${num} ${this.dex.abilities.get(ability).name} variant${num === 1 ? '' : 's'})`, ]; } - abilityTable.set(ability, (abilityTable.get(ability) || 0) + 1); + abilityTable.add(ability); } }, }, @@ -1590,7 +1589,7 @@ export const Rulesets: {[k: string]: FormatData} = { return null; }, onValidateTeam(team) { - const sketches = new Utils.Multiset(); + const sketches = new this.dex.Multiset(); for (const set of team) { if ((set as any).sketchMove) { sketches.add((set as any).sketchMove); @@ -2697,7 +2696,7 @@ export const Rulesets: {[k: string]: FormatData} = { } }, onValidateTeam(team, format) { - const donors = new Utils.Multiset(); + const donors = new this.dex.Multiset(); for (const set of team) { const species = this.dex.species.get(set.species); const fusion = this.dex.species.get(set.name); diff --git a/lib/utils.ts b/lib/utils.ts index beeb3f6be3bb..b121d6738c51 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -414,12 +414,15 @@ export function formatSQLArray(arr: unknown[], args?: unknown[]) { } export class Multiset extends Map { + get(key: T) { + return super.get(key) ?? 0; + } add(key: T) { - this.set(key, (this.get(key) ?? 0) + 1); + this.set(key, this.get(key) + 1); return this; } remove(key: T) { - const newValue = (this.get(key) ?? 0) - 1; + const newValue = this.get(key) - 1; if (newValue <= 0) return this.delete(key); this.set(key, newValue); return true; diff --git a/server/chat-plugins/chat-monitor.ts b/server/chat-plugins/chat-monitor.ts index e22135150c82..42a74907de15 100644 --- a/server/chat-plugins/chat-monitor.ts +++ b/server/chat-plugins/chat-monitor.ts @@ -428,7 +428,7 @@ export const namefilter: Chat.NameFilter = (name, user) => { if (Punishments.namefilterwhitelist.has(id)) return name; if (Monitor.forceRenames.has(id)) { if (typeof Monitor.forceRenames.get(id) === 'number') { - // we check this for hotpatching reasons, since on the initial chat patch this will still be a Utils.MultiSet + // we check this for hotpatching reasons, since on the initial chat patch this will still be a Utils.Multiset // we're gonna assume no one has seen it since that covers people who _haven't_ actually, and those who have // likely will not be attempting to log into it Monitor.forceRenames.set(id, false); diff --git a/server/chat-plugins/modlog-viewer.ts b/server/chat-plugins/modlog-viewer.ts index cef81f7ea48a..3afcdbef1a8b 100644 --- a/server/chat-plugins/modlog-viewer.ts +++ b/server/chat-plugins/modlog-viewer.ts @@ -389,7 +389,7 @@ export const pages: Chat.PageTable = { if (entry.ip) { let ipTable = punishmentsByIp.get(entry.ip); if (!ipTable) { - ipTable = new Utils.Multiset(); + ipTable = new Utils.Multiset(); punishmentsByIp.set(entry.ip, ipTable); } ipTable.add(entry.action); @@ -448,7 +448,7 @@ export const pages: Chat.PageTable = { for (const [ip, table] of punishmentsByIp) { buf += `${ip}`; for (const key of keys) { - buf += `${table.get(key) || 0}`; + buf += `${table.get(key)}`; } buf += ``; } diff --git a/server/chat-plugins/wifi.tsx b/server/chat-plugins/wifi.tsx index cba8b948c9e4..40d6fd63431b 100644 --- a/server/chat-plugins/wifi.tsx +++ b/server/chat-plugins/wifi.tsx @@ -449,7 +449,7 @@ export class QuestionGiveaway extends Giveaway { if (Giveaway.checkBanned(this.room, user)) return user.sendTo(this.room, "You are banned from entering giveaways."); if (this.checkExcluded(user)) return user.sendTo(this.room, "You are disallowed from entering the giveaway."); - if ((this.answered.get(user.id) ?? 0) >= 3) { + if (this.answered.get(user.id) >= 3) { return user.sendTo( this.room, "You have already guessed three times. You cannot guess anymore in this.giveaway." @@ -468,7 +468,7 @@ export class QuestionGiveaway extends Giveaway { this.joined.set(user.latestIp, user.id); this.answered.add(user.id); - if ((this.answered.get(user.id) ?? 0) >= 3) { + if (this.answered.get(user.id) >= 3) { user.sendTo( this.room, `Your guess '${guess}' is wrong. You have used up all of your guesses. Better luck next time!` diff --git a/sim/dex.ts b/sim/dex.ts index 9f2dd4255717..0afa9ee67bd0 100644 --- a/sim/dex.ts +++ b/sim/dex.ts @@ -123,6 +123,7 @@ export class ModdedDex { deepClone = Utils.deepClone; deepFreeze = Utils.deepFreeze; + Multiset = Utils.Multiset; readonly formats: DexFormats; readonly abilities: DexAbilities;