Pokemon_server / dist /sim /battle.js.map
Jofthomas's picture
Jofthomas HF staff
Upload 4781 files
5c2ed06 verified
{
"version": 3,
"sources": ["../../sim/battle.ts"],
"sourcesContent": ["/**\n * Simulator Battle\n * Pokemon Showdown - http://pokemonshowdown.com/\n *\n * This file is where the battle simulation itself happens.\n *\n * The most important part of the simulation is the event system:\n * see the `runEvent` function definition for details.\n *\n * General battle mechanics are in `battle-actions`; move-specific,\n * item-specific, etc mechanics are in the corresponding file in\n * `data`.\n *\n * @license MIT\n */\n\nimport { Dex, toID } from './dex';\nimport { Teams } from './teams';\nimport { Field } from './field';\nimport { Pokemon, type EffectState, RESTORATIVE_BERRIES } from './pokemon';\nimport { PRNG, type PRNGSeed } from './prng';\nimport { type MoveRequest, type ChoiceRequest, Side } from './side';\nimport { State } from './state';\nimport { BattleQueue, type Action } from './battle-queue';\nimport { BattleActions } from './battle-actions';\nimport { Utils } from '../lib/utils';\ndeclare const __version: any;\n\nexport type ChannelID = 0 | 1 | 2 | 3 | 4;\n\nexport type ChannelMessages<T extends ChannelID | -1> = Record<T, string[]>;\n\nconst splitRegex = /^\\|split\\|p([1234])\\n(.*)\\n(.*)|.+/gm;\n\nexport function extractChannelMessages<T extends ChannelID | -1>(message: string, channelIds: T[]): ChannelMessages<T> {\n\tconst channelIdSet = new Set(channelIds);\n\tconst channelMessages: ChannelMessages<ChannelID | -1> = {\n\t\t[-1]: [],\n\t\t0: [],\n\t\t1: [],\n\t\t2: [],\n\t\t3: [],\n\t\t4: [],\n\t};\n\n\tfor (const [lineMatch, playerMatch, secretMessage, sharedMessage] of message.matchAll(splitRegex)) {\n\t\tconst player = playerMatch ? parseInt(playerMatch) : 0;\n\t\tfor (const channelId of channelIdSet) {\n\t\t\tlet line = lineMatch;\n\t\t\tif (player) {\n\t\t\t\tline = channelId === -1 || player === channelId ? secretMessage : sharedMessage;\n\t\t\t\tif (!line) continue;\n\t\t\t}\n\t\t\tchannelMessages[channelId].push(line);\n\t\t}\n\t}\n\n\treturn channelMessages;\n}\n\ninterface BattleOptions {\n\tformat?: Format;\n\tformatid: ID;\n\t/** Output callback */\n\tsend?: (type: string, data: string | string[]) => void;\n\tprng?: PRNG; // PRNG override (you usually don't need this, just pass a seed)\n\tseed?: PRNGSeed; // PRNG seed\n\trated?: boolean | string; // Rated string\n\tp1?: PlayerOptions; // Player 1 data\n\tp2?: PlayerOptions; // Player 2 data\n\tp3?: PlayerOptions; // Player 3 data\n\tp4?: PlayerOptions; // Player 4 data\n\tdebug?: boolean; // show debug mode option\n\tforceRandomChance?: boolean; // force Battle#randomChance to always return true or false (used in some tests)\n\tdeserialized?: boolean;\n\tstrictChoices?: boolean; // whether invalid choices should throw\n}\n\ninterface EventListenerWithoutPriority {\n\teffect: Effect;\n\ttarget?: Pokemon;\n\tindex?: number;\n\tcallback?: Function;\n\tstate: EffectState | null;\n\tend: Function | null;\n\tendCallArgs?: any[];\n\teffectHolder: Pokemon | Side | Field | Battle;\n}\ninterface EventListener extends EventListenerWithoutPriority {\n\torder: number | false;\n\tpriority: number;\n\tsubOrder: number;\n\teffectOrder?: number;\n\tspeed?: number;\n}\n\ntype Part = string | number | boolean | Pokemon | Side | Effect | Move | null | undefined;\n\n// The current request state of the Battle:\n//\n// - 'teampreview': beginning of BW/XY/SM battle (Team Preview)\n// - 'move': beginning of each turn\n// - 'switch': end of turn if fainted (or mid turn with switching effects)\n// - '': no request. Used between turns, or when the battle is over.\n//\n// An individual Side's request state is encapsulated in its `activeRequest` field.\nexport type RequestState = 'teampreview' | 'move' | 'switch' | '';\n\nexport class Battle {\n\treadonly id: ID;\n\treadonly debugMode: boolean;\n\treadonly forceRandomChance: boolean | null;\n\treadonly deserialized: boolean;\n\treadonly strictChoices: boolean;\n\treadonly format: Format;\n\treadonly formatData: EffectState;\n\treadonly gameType: GameType;\n\t/**\n\t * The number of active pokemon per half-field.\n\t * See header comment in side.ts for details.\n\t */\n\treadonly activePerHalf: 1 | 2 | 3;\n\treadonly field: Field;\n\treadonly sides: [Side, Side] | [Side, Side, Side, Side];\n\treadonly prngSeed: PRNGSeed;\n\tdex: ModdedDex;\n\tgen: number;\n\truleTable: Dex.RuleTable;\n\tprng: PRNG;\n\trated: boolean | string;\n\treportExactHP: boolean;\n\treportPercentages: boolean;\n\tsupportCancel: boolean;\n\n\tactions: BattleActions;\n\tqueue: BattleQueue;\n\treadonly faintQueue: {\n\t\ttarget: Pokemon,\n\t\tsource: Pokemon | null,\n\t\teffect: Effect | null,\n\t}[];\n\n\treadonly log: string[];\n\treadonly inputLog: string[];\n\treadonly messageLog: string[];\n\tsentLogPos: number;\n\tsentEnd: boolean;\n\n\trequestState: RequestState;\n\tturn: number;\n\tmidTurn: boolean;\n\tstarted: boolean;\n\tended: boolean;\n\twinner?: string;\n\n\teffect: Effect;\n\teffectState: EffectState;\n\n\tevent: AnyObject;\n\tevents: AnyObject | null;\n\teventDepth: number;\n\n\tactiveMove: ActiveMove | null;\n\tactivePokemon: Pokemon | null;\n\tactiveTarget: Pokemon | null;\n\n\tlastMove: ActiveMove | null;\n\tlastSuccessfulMoveThisTurn: ID | null;\n\tlastMoveLine: number;\n\t/** The last damage dealt by a move in the battle - only used by Gen 1 Counter. */\n\tlastDamage: number;\n\teffectOrder: number;\n\tquickClawRoll: boolean;\n\tspeedOrder: number[];\n\n\tteamGenerator: ReturnType<typeof Teams.getGenerator> | null;\n\n\treadonly hints: Set<string>;\n\n\treadonly NOT_FAIL: '';\n\treadonly HIT_SUBSTITUTE: 0;\n\treadonly FAIL: false;\n\treadonly SILENT_FAIL: null;\n\n\treadonly send: (type: string, data: string | string[]) => void;\n\n\ttrunc: (num: number, bits?: number) => number;\n\tclampIntRange: (num: any, min?: number, max?: number) => number;\n\ttoID = toID;\n\tconstructor(options: BattleOptions) {\n\t\tthis.log = [];\n\t\tthis.add('t:', Math.floor(Date.now() / 1000));\n\n\t\tconst format = options.format || Dex.formats.get(options.formatid, true);\n\t\tthis.format = format;\n\t\tthis.dex = Dex.forFormat(format);\n\t\tthis.gen = this.dex.gen;\n\t\tthis.ruleTable = this.dex.formats.getRuleTable(format);\n\n\t\tthis.trunc = this.dex.trunc;\n\t\tthis.clampIntRange = Utils.clampIntRange;\n\t\t// Object.assign(this, this.dex.data.Scripts);\n\t\tfor (const i in this.dex.data.Scripts) {\n\t\t\tconst entry = this.dex.data.Scripts[i];\n\t\t\tif (typeof entry === 'function') (this as any)[i] = entry;\n\t\t}\n\t\tif (format.battle) Object.assign(this, format.battle);\n\n\t\tthis.id = '';\n\t\tthis.debugMode = format.debug || !!options.debug;\n\t\t// Require debug mode and explicitly passed true/false\n\t\tthis.forceRandomChance = (this.debugMode && typeof options.forceRandomChance === 'boolean') ?\n\t\t\toptions.forceRandomChance : null;\n\t\tthis.deserialized = !!options.deserialized;\n\t\tthis.strictChoices = !!options.strictChoices;\n\t\tthis.formatData = this.initEffectState({ id: format.id });\n\t\tthis.gameType = (format.gameType || 'singles');\n\t\tthis.field = new Field(this);\n\t\tthis.sides = Array(format.playerCount).fill(null) as any;\n\t\tthis.activePerHalf = this.gameType === 'triples' ? 3 :\n\t\t\t(format.playerCount > 2 || this.gameType === 'doubles') ? 2 :\n\t\t\t1;\n\t\tthis.prng = options.prng || new PRNG(options.seed || undefined);\n\t\tthis.prngSeed = this.prng.startingSeed;\n\t\tthis.rated = options.rated || !!options.rated;\n\t\tthis.reportExactHP = !!format.debug;\n\t\tthis.reportPercentages = false;\n\t\tthis.supportCancel = false;\n\n\t\tthis.queue = new BattleQueue(this);\n\t\tthis.actions = new BattleActions(this);\n\t\tthis.faintQueue = [];\n\n\t\tthis.inputLog = [];\n\t\tthis.messageLog = [];\n\t\tthis.sentLogPos = 0;\n\t\tthis.sentEnd = false;\n\n\t\tthis.requestState = '';\n\t\tthis.turn = 0;\n\t\tthis.midTurn = false;\n\t\tthis.started = false;\n\t\tthis.ended = false;\n\n\t\tthis.effect = { id: '' } as Effect;\n\t\tthis.effectState = this.initEffectState({ id: '' });\n\n\t\tthis.event = { id: '' };\n\t\tthis.events = null;\n\t\tthis.eventDepth = 0;\n\n\t\tthis.activeMove = null;\n\t\tthis.activePokemon = null;\n\t\tthis.activeTarget = null;\n\n\t\tthis.lastMove = null;\n\t\tthis.lastMoveLine = -1;\n\t\tthis.lastSuccessfulMoveThisTurn = null;\n\t\tthis.lastDamage = 0;\n\t\tthis.effectOrder = 0;\n\t\tthis.quickClawRoll = false;\n\t\tthis.speedOrder = [];\n\t\tfor (let i = 0; i < this.activePerHalf * 2; i++) {\n\t\t\tthis.speedOrder.push(i);\n\t\t}\n\n\t\tthis.teamGenerator = null;\n\n\t\tthis.hints = new Set();\n\n\t\tthis.NOT_FAIL = '';\n\t\tthis.HIT_SUBSTITUTE = 0;\n\t\tthis.FAIL = false;\n\t\tthis.SILENT_FAIL = null;\n\n\t\tthis.send = options.send || (() => {});\n\n\t\tconst inputOptions: { formatid: ID, seed: PRNGSeed, rated?: string | true } = {\n\t\t\tformatid: options.formatid, seed: this.prngSeed,\n\t\t};\n\t\tif (this.rated) inputOptions.rated = this.rated;\n\t\tif (typeof __version !== 'undefined') {\n\t\t\tif (__version.head) {\n\t\t\t\tthis.inputLog.push(`>version ${__version.head}`);\n\t\t\t}\n\t\t\tif (__version.origin) {\n\t\t\t\tthis.inputLog.push(`>version-origin ${__version.origin}`);\n\t\t\t}\n\t\t}\n\t\tthis.inputLog.push(`>start ` + JSON.stringify(inputOptions));\n\n\t\tthis.add('gametype', this.gameType);\n\n\t\t// timing is early enough to hook into ModifySpecies event\n\t\tfor (const rule of this.ruleTable.keys()) {\n\t\t\tif ('+*-!'.includes(rule.charAt(0))) continue;\n\t\t\tconst subFormat = this.dex.formats.get(rule);\n\t\t\tif (subFormat.exists) {\n\t\t\t\tconst hasEventHandler = Object.keys(subFormat).some(\n\t\t\t\t\t// skip event handlers that are handled elsewhere\n\t\t\t\t\tval => val.startsWith('on') && ![\n\t\t\t\t\t\t'onBegin', 'onTeamPreview', 'onBattleStart', 'onValidateRule', 'onValidateTeam', 'onChangeSet', 'onValidateSet',\n\t\t\t\t\t].includes(val)\n\t\t\t\t);\n\t\t\t\tif (hasEventHandler) this.field.addPseudoWeather(rule);\n\t\t\t}\n\t\t}\n\n\t\tconst sides: SideID[] = ['p1', 'p2', 'p3', 'p4'];\n\t\tfor (const side of sides) {\n\t\t\tif (options[side]) {\n\t\t\t\tthis.setPlayer(side, options[side]);\n\t\t\t}\n\t\t}\n\t}\n\n\ttoJSON(): AnyObject {\n\t\treturn State.serializeBattle(this);\n\t}\n\n\tstatic fromJSON(serialized: string | AnyObject): Battle {\n\t\treturn State.deserializeBattle(serialized);\n\t}\n\n\tget p1() {\n\t\treturn this.sides[0];\n\t}\n\n\tget p2() {\n\t\treturn this.sides[1];\n\t}\n\n\tget p3() {\n\t\treturn this.sides[2];\n\t}\n\n\tget p4() {\n\t\treturn this.sides[3];\n\t}\n\n\ttoString() {\n\t\treturn `Battle: ${this.format}`;\n\t}\n\n\trandom(m?: number, n?: number) {\n\t\treturn this.prng.random(m, n);\n\t}\n\n\trandomChance(numerator: number, denominator: number) {\n\t\tif (this.forceRandomChance !== null) return this.forceRandomChance;\n\t\treturn this.prng.randomChance(numerator, denominator);\n\t}\n\n\tsample<T>(items: readonly T[]): T {\n\t\treturn this.prng.sample(items);\n\t}\n\n\t/** Note that passing `undefined` resets to the starting seed, but `null` will roll a new seed */\n\tresetRNG(seed: PRNGSeed | null = this.prngSeed) {\n\t\tthis.prng = new PRNG(seed);\n\t\tthis.add('message', \"The battle's RNG was reset.\");\n\t}\n\n\tsuppressingAbility(target?: Pokemon) {\n\t\treturn this.activePokemon && this.activePokemon.isActive && (this.activePokemon !== target || this.gen < 8) &&\n\t\t\tthis.activeMove && this.activeMove.ignoreAbility && !target?.hasItem('Ability Shield');\n\t}\n\n\tsetActiveMove(move?: ActiveMove | null, pokemon?: Pokemon | null, target?: Pokemon | null) {\n\t\tthis.activeMove = move || null;\n\t\tthis.activePokemon = pokemon || null;\n\t\tthis.activeTarget = target || pokemon || null;\n\t}\n\n\tclearActiveMove(failed?: boolean) {\n\t\tif (this.activeMove) {\n\t\t\tif (!failed) {\n\t\t\t\tthis.lastMove = this.activeMove;\n\t\t\t}\n\t\t\tthis.activeMove = null;\n\t\t\tthis.activePokemon = null;\n\t\t\tthis.activeTarget = null;\n\t\t}\n\t}\n\n\tupdateSpeed() {\n\t\tfor (const pokemon of this.getAllActive()) {\n\t\t\tpokemon.updateSpeed();\n\t\t}\n\t}\n\n\t/**\n\t * The default sort order for actions, but also event listeners.\n\t *\n\t * 1. Order, low to high (default last)\n\t * 2. Priority, high to low (default 0)\n\t * 3. Speed, high to low (default 0)\n\t * 4. SubOrder, low to high (default 0)\n\t * 5. EffectOrder, low to high (default 0)\n\t *\n\t * Doesn't reference `this` so doesn't need to be bound.\n\t */\n\tcomparePriority(this: void, a: AnyObject, b: AnyObject) {\n\t\treturn -((b.order || 4294967296) - (a.order || 4294967296)) ||\n\t\t\t((b.priority || 0) - (a.priority || 0)) ||\n\t\t\t((b.speed || 0) - (a.speed || 0)) ||\n\t\t\t-((b.subOrder || 0) - (a.subOrder || 0)) ||\n\t\t\t-((b.effectOrder || 0) - (a.effectOrder || 0)) ||\n\t\t\t0;\n\t}\n\n\tstatic compareRedirectOrder(this: void, a: AnyObject, b: AnyObject) {\n\t\treturn ((b.priority || 0) - (a.priority || 0)) ||\n\t\t\t((b.speed || 0) - (a.speed || 0)) ||\n\t\t\t((a.effectHolder?.abilityState && b.effectHolder?.abilityState) ?\n\t\t\t\t-(b.effectHolder.abilityState.effectOrder - a.effectHolder.abilityState.effectOrder) : 0) ||\n\t\t\t\t0;\n\t}\n\n\tstatic compareLeftToRightOrder(this: void, a: AnyObject, b: AnyObject) {\n\t\treturn -((b.order || 4294967296) - (a.order || 4294967296)) ||\n\t\t\t((b.priority || 0) - (a.priority || 0)) ||\n\t\t\t-((b.index || 0) - (a.index || 0)) ||\n\t\t\t0;\n\t}\n\n\t/** Sort a list, resolving speed ties the way the games do. */\n\tspeedSort<T extends AnyObject>(list: T[], comparator: (a: T, b: T) => number = this.comparePriority) {\n\t\tif (list.length < 2) return;\n\t\tlet sorted = 0;\n\t\t// This is a Selection Sort - not the fastest sort in general, but\n\t\t// actually faster than QuickSort for small arrays like the ones\n\t\t// `speedSort` is used for.\n\t\t// More importantly, it makes it easiest to resolve speed ties\n\t\t// properly.\n\t\twhile (sorted + 1 < list.length) {\n\t\t\tlet nextIndexes = [sorted];\n\t\t\t// grab list of next indexes\n\t\t\tfor (let i = sorted + 1; i < list.length; i++) {\n\t\t\t\tconst delta = comparator(list[nextIndexes[0]], list[i]);\n\t\t\t\tif (delta < 0) continue;\n\t\t\t\tif (delta > 0) nextIndexes = [i];\n\t\t\t\tif (delta === 0) nextIndexes.push(i);\n\t\t\t}\n\t\t\t// put list of next indexes where they belong\n\t\t\tfor (let i = 0; i < nextIndexes.length; i++) {\n\t\t\t\tconst index = nextIndexes[i];\n\t\t\t\tif (index !== sorted + i) {\n\t\t\t\t\t// nextIndexes is guaranteed to be in order, so it will never have\n\t\t\t\t\t// been disturbed by an earlier swap\n\t\t\t\t\t[list[sorted + i], list[index]] = [list[index], list[sorted + i]];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (nextIndexes.length > 1) {\n\t\t\t\tthis.prng.shuffle(list, sorted, sorted + nextIndexes.length);\n\t\t\t}\n\t\t\tsorted += nextIndexes.length;\n\t\t}\n\t}\n\n\t/**\n\t * Runs an event with no source on each Pok\u00E9mon on the field, in Speed order.\n\t */\n\teachEvent(eventid: string, effect?: Effect | null, relayVar?: boolean) {\n\t\tconst actives = this.getAllActive();\n\t\tif (!effect && this.effect) effect = this.effect;\n\t\tthis.speedSort(actives, (a, b) => b.speed - a.speed);\n\t\tfor (const pokemon of actives) {\n\t\t\tthis.runEvent(eventid, pokemon, null, effect, relayVar);\n\t\t}\n\t\tif (eventid === 'Weather' && this.gen >= 7) {\n\t\t\t// TODO: further research when updates happen\n\t\t\tthis.eachEvent('Update');\n\t\t}\n\t}\n\n\t/**\n\t * Runs an event with no source on each effect on the field, in Speed order.\n\t *\n\t * Unlike `eachEvent`, this contains a lot of other handling and is only intended for\n\t * the 'Residual' and 'SwitchIn' events.\n\t */\n\tfieldEvent(eventid: string, targets?: Pokemon[]) {\n\t\tconst callbackName = `on${eventid}`;\n\t\tlet getKey: undefined | 'duration';\n\t\tif (eventid === 'Residual') {\n\t\t\tgetKey = 'duration';\n\t\t}\n\t\tlet handlers = this.findFieldEventHandlers(this.field, `onField${eventid}`, getKey);\n\t\tfor (const side of this.sides) {\n\t\t\tif (side.n < 2 || !side.allySide) {\n\t\t\t\thandlers = handlers.concat(this.findSideEventHandlers(side, `onSide${eventid}`, getKey));\n\t\t\t}\n\t\t\tfor (const active of side.active) {\n\t\t\t\tif (!active) continue;\n\t\t\t\tif (eventid === 'SwitchIn') {\n\t\t\t\t\thandlers = handlers.concat(this.findPokemonEventHandlers(active, `onAny${eventid}`));\n\t\t\t\t}\n\t\t\t\tif (targets && !targets.includes(active)) continue;\n\t\t\t\thandlers = handlers.concat(this.findPokemonEventHandlers(active, callbackName, getKey));\n\t\t\t\thandlers = handlers.concat(this.findSideEventHandlers(side, callbackName, undefined, active));\n\t\t\t\thandlers = handlers.concat(this.findFieldEventHandlers(this.field, callbackName, undefined, active));\n\t\t\t\thandlers = handlers.concat(this.findBattleEventHandlers(callbackName, getKey, active));\n\t\t\t}\n\t\t}\n\t\tthis.speedSort(handlers);\n\t\twhile (handlers.length) {\n\t\t\tconst handler = handlers[0];\n\t\t\thandlers.shift();\n\t\t\tconst effect = handler.effect;\n\t\t\tif ((handler.effectHolder as Pokemon).fainted) {\n\t\t\t\tif (!(handler.state?.isSlotCondition)) continue;\n\t\t\t}\n\t\t\tif (eventid === 'Residual' && handler.end && handler.state?.duration) {\n\t\t\t\thandler.state.duration--;\n\t\t\t\tif (!handler.state.duration) {\n\t\t\t\t\tconst endCallArgs = handler.endCallArgs || [handler.effectHolder, effect.id];\n\t\t\t\t\thandler.end.call(...endCallArgs as [any, ...any[]]);\n\t\t\t\t\tif (this.ended) return;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet handlerEventid = eventid;\n\t\t\tif ((handler.effectHolder as Side).sideConditions) handlerEventid = `Side${eventid}`;\n\t\t\tif ((handler.effectHolder as Field).pseudoWeather) handlerEventid = `Field${eventid}`;\n\t\t\tif (handler.callback) {\n\t\t\t\tthis.singleEvent(handlerEventid, effect, handler.state, handler.effectHolder, null, null, undefined, handler.callback);\n\t\t\t}\n\n\t\t\tthis.faintMessages();\n\t\t\tif (this.ended) return;\n\t\t}\n\t}\n\n\t/** The entire event system revolves around this function and runEvent. */\n\tsingleEvent(\n\t\teventid: string, effect: Effect, state: EffectState | Record<string, never> | null,\n\t\ttarget: string | Pokemon | Side | Field | Battle | null, source?: string | Pokemon | Effect | false | null,\n\t\tsourceEffect?: Effect | string | null, relayVar?: any, customCallback?: unknown\n\t) {\n\t\tif (this.eventDepth >= 8) {\n\t\t\t// oh fuck\n\t\t\tthis.add('message', 'STACK LIMIT EXCEEDED');\n\t\t\tthis.add('message', 'PLEASE REPORT IN BUG THREAD');\n\t\t\tthis.add('message', 'Event: ' + eventid);\n\t\t\tthis.add('message', 'Parent event: ' + this.event.id);\n\t\t\tthrow new Error(\"Stack overflow\");\n\t\t}\n\t\tif (this.log.length - this.sentLogPos > 1000) {\n\t\t\tthis.add('message', 'LINE LIMIT EXCEEDED');\n\t\t\tthis.add('message', 'PLEASE REPORT IN BUG THREAD');\n\t\t\tthis.add('message', 'Event: ' + eventid);\n\t\t\tthis.add('message', 'Parent event: ' + this.event.id);\n\t\t\tthrow new Error(\"Infinite loop\");\n\t\t}\n\t\t// this.add('Event: ' + eventid + ' (depth ' + this.eventDepth + ')');\n\t\tlet hasRelayVar = true;\n\t\tif (relayVar === undefined) {\n\t\t\trelayVar = true;\n\t\t\thasRelayVar = false;\n\t\t}\n\n\t\tif (effect.effectType === 'Status' && (target instanceof Pokemon) && target.status !== effect.id) {\n\t\t\t// it's changed; call it off\n\t\t\treturn relayVar;\n\t\t}\n\t\tif (eventid !== 'Start' && eventid !== 'TakeItem' && effect.effectType === 'Item' &&\n\t\t\t(target instanceof Pokemon) && target.ignoringItem()) {\n\t\t\tthis.debug(eventid + ' handler suppressed by Embargo, Klutz or Magic Room');\n\t\t\treturn relayVar;\n\t\t}\n\t\tif (eventid !== 'End' && effect.effectType === 'Ability' && (target instanceof Pokemon) && target.ignoringAbility()) {\n\t\t\tthis.debug(eventid + ' handler suppressed by Gastro Acid or Neutralizing Gas');\n\t\t\treturn relayVar;\n\t\t}\n\t\tif (\n\t\t\teffect.effectType === 'Weather' && eventid !== 'FieldStart' && eventid !== 'FieldResidual' &&\n\t\t\teventid !== 'FieldEnd' && this.field.suppressingWeather()\n\t\t) {\n\t\t\tthis.debug(eventid + ' handler suppressed by Air Lock');\n\t\t\treturn relayVar;\n\t\t}\n\n\t\tconst callback = customCallback || (effect as any)[`on${eventid}`];\n\t\tif (callback === undefined) return relayVar;\n\n\t\tconst parentEffect = this.effect;\n\t\tconst parentEffectState = this.effectState;\n\t\tconst parentEvent = this.event;\n\n\t\tthis.effect = effect;\n\t\tthis.effectState = state as EffectState || this.initEffectState({});\n\t\tthis.event = { id: eventid, target, source, effect: sourceEffect };\n\t\tthis.eventDepth++;\n\n\t\tconst args = [target, source, sourceEffect];\n\t\tif (hasRelayVar) args.unshift(relayVar);\n\n\t\tlet returnVal;\n\t\tif (typeof callback === 'function') {\n\t\t\treturnVal = callback.apply(this, args);\n\t\t} else {\n\t\t\treturnVal = callback;\n\t\t}\n\n\t\tthis.eventDepth--;\n\t\tthis.effect = parentEffect;\n\t\tthis.effectState = parentEffectState;\n\t\tthis.event = parentEvent;\n\n\t\treturn returnVal === undefined ? relayVar : returnVal;\n\t}\n\n\t/**\n\t * runEvent is the core of Pokemon Showdown's event system.\n\t *\n\t * Basic usage\n\t * ===========\n\t *\n\t * this.runEvent('Blah')\n\t * will trigger any onBlah global event handlers.\n\t *\n\t * this.runEvent('Blah', target)\n\t * will additionally trigger any onBlah handlers on the target, onAllyBlah\n\t * handlers on any active pokemon on the target's team, and onFoeBlah\n\t * handlers on any active pokemon on the target's foe's team\n\t *\n\t * this.runEvent('Blah', target, source)\n\t * will additionally trigger any onSourceBlah handlers on the source\n\t *\n\t * this.runEvent('Blah', target, source, effect)\n\t * will additionally pass the effect onto all event handlers triggered\n\t *\n\t * this.runEvent('Blah', target, source, effect, relayVar)\n\t * will additionally pass the relayVar as the first argument along all event\n\t * handlers\n\t *\n\t * You may leave any of these null. For instance, if you have a relayVar but\n\t * no source or effect:\n\t * this.runEvent('Damage', target, null, null, 50)\n\t *\n\t * Event handlers\n\t * ==============\n\t *\n\t * Items, abilities, statuses, and other effects like SR, confusion, weather,\n\t * or Trick Room can have event handlers. Event handlers are functions that\n\t * can modify what happens during an event.\n\t *\n\t * event handlers are passed:\n\t * function (target, source, effect)\n\t * although some of these can be blank.\n\t *\n\t * certain events have a relay variable, in which case they're passed:\n\t * function (relayVar, target, source, effect)\n\t *\n\t * Relay variables are variables that give additional information about the\n\t * event. For instance, the damage event has a relayVar which is the amount\n\t * of damage dealt.\n\t *\n\t * If a relay variable isn't passed to runEvent, there will still be a secret\n\t * relayVar defaulting to `true`, but it won't get passed to any event\n\t * handlers.\n\t *\n\t * After an event handler is run, its return value helps determine what\n\t * happens next:\n\t * 1. If the return value isn't `undefined`, relayVar is set to the return\n\t * value\n\t * 2. If relayVar is falsy, no more event handlers are run\n\t * 3. Otherwise, if there are more event handlers, the next one is run and\n\t * we go back to step 1.\n\t * 4. Once all event handlers are run (or one of them results in a falsy\n\t * relayVar), relayVar is returned by runEvent\n\t *\n\t * As a shortcut, an event handler that isn't a function will be interpreted\n\t * as a function that returns that value.\n\t *\n\t * You can have return values mean whatever you like, but in general, we\n\t * follow the convention that returning `false` or `null` means\n\t * stopping or interrupting the event.\n\t *\n\t * For instance, returning `false` from a TrySetStatus handler means that\n\t * the pokemon doesn't get statused.\n\t *\n\t * If a failed event usually results in a message like \"But it failed!\"\n\t * or \"It had no effect!\", returning `null` will suppress that message and\n\t * returning `false` will display it. Returning `null` is useful if your\n\t * event handler already gave its own custom failure message.\n\t *\n\t * Returning `undefined` means \"don't change anything\" or \"keep going\".\n\t * A function that does nothing but return `undefined` is the equivalent\n\t * of not having an event handler at all.\n\t *\n\t * Returning a value means that that value is the new `relayVar`. For\n\t * instance, if a Damage event handler returns 50, the damage event\n\t * will deal 50 damage instead of whatever it was going to deal before.\n\t *\n\t * Useful values\n\t * =============\n\t *\n\t * In addition to all the methods and attributes of Dex, Battle, and\n\t * Scripts, event handlers have some additional values they can access:\n\t *\n\t * this.effect:\n\t * the Effect having the event handler\n\t * this.effectState:\n\t * the data store associated with the above Effect. This is a plain Object\n\t * and you can use it to store data for later event handlers.\n\t * this.effectState.target:\n\t * the Pokemon, Side, or Battle that the event handler's effect was\n\t * attached to.\n\t * this.event.id:\n\t * the event ID\n\t * this.event.target, this.event.source, this.event.effect:\n\t * the target, source, and effect of the event. These are the same\n\t * variables that are passed as arguments to the event handler, but\n\t * they're useful for functions called by the event handler.\n\t */\n\trunEvent(\n\t\teventid: string, target?: Pokemon | Pokemon[] | Side | Battle | null, source?: string | Pokemon | false | null,\n\t\tsourceEffect?: Effect | null, relayVar?: any, onEffect?: boolean, fastExit?: boolean\n\t) {\n\t\t// if (Battle.eventCounter) {\n\t\t// \tif (!Battle.eventCounter[eventid]) Battle.eventCounter[eventid] = 0;\n\t\t// \tBattle.eventCounter[eventid]++;\n\t\t// }\n\t\tif (this.eventDepth >= 8) {\n\t\t\t// oh fuck\n\t\t\tthis.add('message', 'STACK LIMIT EXCEEDED');\n\t\t\tthis.add('message', 'PLEASE REPORT IN BUG THREAD');\n\t\t\tthis.add('message', 'Event: ' + eventid);\n\t\t\tthis.add('message', 'Parent event: ' + this.event.id);\n\t\t\tthrow new Error(\"Stack overflow\");\n\t\t}\n\t\tif (!target) target = this;\n\t\tlet effectSource = null;\n\t\tif (source instanceof Pokemon) effectSource = source;\n\t\tconst handlers = this.findEventHandlers(target, eventid, effectSource);\n\t\tif (onEffect) {\n\t\t\tif (!sourceEffect) throw new Error(\"onEffect passed without an effect\");\n\t\t\tconst callback = (sourceEffect as any)[`on${eventid}`];\n\t\t\tif (callback !== undefined) {\n\t\t\t\tif (Array.isArray(target)) throw new Error(\"\");\n\t\t\t\thandlers.unshift(this.resolvePriority({\n\t\t\t\t\teffect: sourceEffect, callback, state: this.initEffectState({}), end: null, effectHolder: target,\n\t\t\t\t}, `on${eventid}`));\n\t\t\t}\n\t\t}\n\n\t\tif (['Invulnerability', 'TryHit', 'DamagingHit', 'EntryHazard'].includes(eventid)) {\n\t\t\thandlers.sort(Battle.compareLeftToRightOrder);\n\t\t} else if (fastExit) {\n\t\t\thandlers.sort(Battle.compareRedirectOrder);\n\t\t} else {\n\t\t\tthis.speedSort(handlers);\n\t\t}\n\t\tlet hasRelayVar = 1;\n\t\tconst args = [target, source, sourceEffect];\n\t\t// console.log('Event: ' + eventid + ' (depth ' + this.eventDepth + ') t:' + target.id + ' s:' + (!source || source.id) + ' e:' + effect.id);\n\t\tif (relayVar === undefined || relayVar === null) {\n\t\t\trelayVar = true;\n\t\t\thasRelayVar = 0;\n\t\t} else {\n\t\t\targs.unshift(relayVar);\n\t\t}\n\n\t\tconst parentEvent = this.event;\n\t\tthis.event = { id: eventid, target, source, effect: sourceEffect, modifier: 1 };\n\t\tthis.eventDepth++;\n\n\t\tlet targetRelayVars = [];\n\t\tif (Array.isArray(target)) {\n\t\t\tif (Array.isArray(relayVar)) {\n\t\t\t\ttargetRelayVars = relayVar;\n\t\t\t} else {\n\t\t\t\tfor (let i = 0; i < target.length; i++) targetRelayVars[i] = true;\n\t\t\t}\n\t\t}\n\t\tfor (const handler of handlers) {\n\t\t\tif (handler.index !== undefined) {\n\t\t\t\t// TODO: find a better way to do this\n\t\t\t\tif (!targetRelayVars[handler.index] && !(targetRelayVars[handler.index] === 0 &&\n\t\t\t\t\teventid === 'DamagingHit')) continue;\n\t\t\t\tif (handler.target) {\n\t\t\t\t\targs[hasRelayVar] = handler.target;\n\t\t\t\t\tthis.event.target = handler.target;\n\t\t\t\t}\n\t\t\t\tif (hasRelayVar) args[0] = targetRelayVars[handler.index];\n\t\t\t}\n\t\t\tconst effect = handler.effect;\n\t\t\tconst effectHolder = handler.effectHolder;\n\t\t\t// this.debug('match ' + eventid + ': ' + status.id + ' ' + status.effectType);\n\t\t\tif (effect.effectType === 'Status' && (effectHolder as Pokemon).status !== effect.id) {\n\t\t\t\t// it's changed; call it off\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (effect.effectType === 'Ability' && effect.flags['breakable'] &&\n\t\t\t\tthis.suppressingAbility(effectHolder as Pokemon)) {\n\t\t\t\tif (effect.flags['breakable']) {\n\t\t\t\t\tthis.debug(eventid + ' handler suppressed by Mold Breaker');\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!effect.num) {\n\t\t\t\t\t// ignore attacking events for custom abilities\n\t\t\t\t\tconst AttackingEvents = {\n\t\t\t\t\t\tBeforeMove: 1,\n\t\t\t\t\t\tBasePower: 1,\n\t\t\t\t\t\tImmunity: 1,\n\t\t\t\t\t\tRedirectTarget: 1,\n\t\t\t\t\t\tHeal: 1,\n\t\t\t\t\t\tSetStatus: 1,\n\t\t\t\t\t\tCriticalHit: 1,\n\t\t\t\t\t\tModifyAtk: 1, ModifyDef: 1, ModifySpA: 1, ModifySpD: 1, ModifySpe: 1, ModifyAccuracy: 1,\n\t\t\t\t\t\tModifyBoost: 1,\n\t\t\t\t\t\tModifyDamage: 1,\n\t\t\t\t\t\tModifySecondaries: 1,\n\t\t\t\t\t\tModifyWeight: 1,\n\t\t\t\t\t\tTryAddVolatile: 1,\n\t\t\t\t\t\tTryHit: 1,\n\t\t\t\t\t\tTryHitSide: 1,\n\t\t\t\t\t\tTryMove: 1,\n\t\t\t\t\t\tBoost: 1,\n\t\t\t\t\t\tDragOut: 1,\n\t\t\t\t\t\tEffectiveness: 1,\n\t\t\t\t\t};\n\t\t\t\t\tif (eventid in AttackingEvents) {\n\t\t\t\t\t\tthis.debug(eventid + ' handler suppressed by Mold Breaker');\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else if (eventid === 'Damage' && sourceEffect && sourceEffect.effectType === 'Move') {\n\t\t\t\t\t\tthis.debug(eventid + ' handler suppressed by Mold Breaker');\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (eventid !== 'Start' && eventid !== 'SwitchIn' && eventid !== 'TakeItem' &&\n\t\t\t\teffect.effectType === 'Item' && (effectHolder instanceof Pokemon) && effectHolder.ignoringItem()) {\n\t\t\t\tif (eventid !== 'Update') {\n\t\t\t\t\tthis.debug(eventid + ' handler suppressed by Embargo, Klutz or Magic Room');\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t} else if (\n\t\t\t\teventid !== 'End' && effect.effectType === 'Ability' &&\n\t\t\t\t(effectHolder instanceof Pokemon) && effectHolder.ignoringAbility()\n\t\t\t) {\n\t\t\t\tif (eventid !== 'Update') {\n\t\t\t\t\tthis.debug(eventid + ' handler suppressed by Gastro Acid or Neutralizing Gas');\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t(effect.effectType === 'Weather' || eventid === 'Weather') &&\n\t\t\t\teventid !== 'Residual' && eventid !== 'End' && this.field.suppressingWeather()\n\t\t\t) {\n\t\t\t\tthis.debug(eventid + ' handler suppressed by Air Lock');\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet returnVal;\n\t\t\tif (typeof handler.callback === 'function') {\n\t\t\t\tconst parentEffect = this.effect;\n\t\t\t\tconst parentEffectState = this.effectState;\n\t\t\t\tthis.effect = handler.effect;\n\t\t\t\tthis.effectState = handler.state || this.initEffectState({});\n\t\t\t\tthis.effectState.target = effectHolder;\n\n\t\t\t\treturnVal = handler.callback.apply(this, args);\n\n\t\t\t\tthis.effect = parentEffect;\n\t\t\t\tthis.effectState = parentEffectState;\n\t\t\t} else {\n\t\t\t\treturnVal = handler.callback;\n\t\t\t}\n\n\t\t\tif (returnVal !== undefined) {\n\t\t\t\trelayVar = returnVal;\n\t\t\t\tif (!relayVar || fastExit) {\n\t\t\t\t\tif (handler.index !== undefined) {\n\t\t\t\t\t\ttargetRelayVars[handler.index] = relayVar;\n\t\t\t\t\t\tif (targetRelayVars.every(val => !val)) break;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (hasRelayVar) {\n\t\t\t\t\targs[0] = relayVar;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.eventDepth--;\n\t\tif (typeof relayVar === 'number' && relayVar === Math.abs(Math.floor(relayVar))) {\n\t\t\t// this.debug(eventid + ' modifier: 0x' +\n\t\t\t// \t('0000' + (this.event.modifier * 4096).toString(16)).slice(-4).toUpperCase());\n\t\t\trelayVar = this.modify(relayVar, this.event.modifier);\n\t\t}\n\t\tthis.event = parentEvent;\n\n\t\treturn Array.isArray(target) ? targetRelayVars : relayVar;\n\t}\n\n\t/**\n\t * priorityEvent works just like runEvent, except it exits and returns\n\t * on the first non-undefined value instead of only on null/false.\n\t */\n\tpriorityEvent(\n\t\teventid: string, target: Pokemon | Side | Battle, source?: Pokemon | null,\n\t\teffect?: Effect, relayVar?: any, onEffect?: boolean\n\t): any {\n\t\treturn this.runEvent(eventid, target, source, effect, relayVar, onEffect, true);\n\t}\n\n\tresolvePriority(h: EventListenerWithoutPriority, callbackName: string) {\n\t\tconst handler = h as EventListener;\n\t\thandler.order = (handler.effect as any)[`${callbackName}Order`] || false;\n\t\thandler.priority = (handler.effect as any)[`${callbackName}Priority`] || 0;\n\t\thandler.subOrder = (handler.effect as any)[`${callbackName}SubOrder`] || 0;\n\t\tif (!handler.subOrder) {\n\t\t\t// https://www.smogon.com/forums/threads/sword-shield-battle-mechanics-research.3655528/page-59#post-8685465\n\t\t\tconst effectTypeOrder: { [k in EffectType]?: number } = {\n\t\t\t\t// Z-Move: 1,\n\t\t\t\tCondition: 2,\n\t\t\t\t// Slot Condition: 3,\n\t\t\t\t// Side Condition: 4,\n\t\t\t\t// Field Condition: 5, (includes weather but also terrains and pseudoweathers)\n\t\t\t\tWeather: 5,\n\t\t\t\tFormat: 5,\n\t\t\t\tRule: 5,\n\t\t\t\tRuleset: 5,\n\t\t\t\t// Poison Touch: 6, (also includes Perish Body)\n\t\t\t\tAbility: 7,\n\t\t\t\tItem: 8,\n\t\t\t\t// Stall: 9,\n\t\t\t};\n\t\t\thandler.subOrder = effectTypeOrder[handler.effect.effectType] || 0;\n\t\t\tif (handler.effect.effectType === 'Condition') {\n\t\t\t\tif (handler.state?.target instanceof Side) {\n\t\t\t\t\tif (handler.state.isSlotCondition) {\n\t\t\t\t\t\t// slot condition\n\t\t\t\t\t\thandler.subOrder = 3;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// side condition\n\t\t\t\t\t\thandler.subOrder = 4;\n\t\t\t\t\t}\n\t\t\t\t} else if (handler.state?.target instanceof Field) {\n\t\t\t\t\t// field condition\n\t\t\t\t\thandler.subOrder = 5;\n\t\t\t\t}\n\t\t\t} else if (handler.effect.effectType === 'Ability') {\n\t\t\t\tif (handler.effect.name === 'Poison Touch' || handler.effect.name === 'Perish Body') {\n\t\t\t\t\thandler.subOrder = 6;\n\t\t\t\t} else if (handler.effect.name === 'Stall') {\n\t\t\t\t\thandler.subOrder = 9;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (callbackName.endsWith('SwitchIn') || callbackName.endsWith('RedirectTarget')) {\n\t\t\t// If multiple hazards are present on one side, their event handlers all perfectly tie in speed, priority,\n\t\t\t// and subOrder. They should activate in the order they were created, which is where effectOrder comes in.\n\t\t\t// This also applies to speed ties for which ability like Lightning Rod redirects moves.\n\t\t\t// TODO: In-game, other events are also sorted this way, but that's an implementation for another refactor\n\t\t\thandler.effectOrder = handler.state?.effectOrder;\n\t\t}\n\t\tif (handler.effectHolder && (handler.effectHolder as Pokemon).getStat) {\n\t\t\tconst pokemon = handler.effectHolder as Pokemon;\n\t\t\thandler.speed = pokemon.speed;\n\t\t\tif (callbackName.endsWith('SwitchIn')) {\n\t\t\t\t// Pokemon speeds including ties are resolved before all onSwitchIn handlers and aren't re-sorted in-between\n\t\t\t\t// so we subtract a fractional speed from each Pokemon's respective event handlers by using the index of their\n\t\t\t\t// unique field position in a pre-sorted-by-speed array\n\t\t\t\tconst fieldPositionValue = pokemon.side.n * this.sides.length + pokemon.position;\n\t\t\t\thandler.speed -= this.speedOrder.indexOf(fieldPositionValue) / (this.activePerHalf * 2);\n\t\t\t}\n\t\t}\n\t\treturn handler;\n\t}\n\n\tfindEventHandlers(target: Pokemon | Pokemon[] | Side | Battle, eventName: string, source?: Pokemon | null) {\n\t\tlet handlers: EventListener[] = [];\n\t\tif (Array.isArray(target)) {\n\t\t\tfor (const [i, pokemon] of target.entries()) {\n\t\t\t\t// console.log(`Event: ${eventName}, Target: ${pokemon}, ${i}`);\n\t\t\t\tconst curHandlers = this.findEventHandlers(pokemon, eventName, source);\n\t\t\t\tfor (const handler of curHandlers) {\n\t\t\t\t\thandler.target = pokemon; // Original \"effectHolder\"\n\t\t\t\t\thandler.index = i;\n\t\t\t\t}\n\t\t\t\thandlers = handlers.concat(curHandlers);\n\t\t\t}\n\t\t\treturn handlers;\n\t\t}\n\t\t// events usually run through EachEvent should never have any handlers besides `on${eventName}` so don't check for them\n\t\tconst prefixedHandlers = !['BeforeTurn', 'Update', 'Weather', 'WeatherChange', 'TerrainChange'].includes(eventName);\n\t\tif (target instanceof Pokemon && (target.isActive || source?.isActive)) {\n\t\t\thandlers = this.findPokemonEventHandlers(target, `on${eventName}`);\n\t\t\tif (prefixedHandlers) {\n\t\t\t\tfor (const allyActive of target.alliesAndSelf()) {\n\t\t\t\t\thandlers.push(...this.findPokemonEventHandlers(allyActive, `onAlly${eventName}`));\n\t\t\t\t\thandlers.push(...this.findPokemonEventHandlers(allyActive, `onAny${eventName}`));\n\t\t\t\t}\n\t\t\t\tfor (const foeActive of target.foes()) {\n\t\t\t\t\thandlers.push(...this.findPokemonEventHandlers(foeActive, `onFoe${eventName}`));\n\t\t\t\t\thandlers.push(...this.findPokemonEventHandlers(foeActive, `onAny${eventName}`));\n\t\t\t\t}\n\t\t\t}\n\t\t\ttarget = target.side;\n\t\t}\n\t\tif (source && prefixedHandlers) {\n\t\t\thandlers.push(...this.findPokemonEventHandlers(source, `onSource${eventName}`));\n\t\t}\n\t\tif (target instanceof Side) {\n\t\t\tfor (const side of this.sides) {\n\t\t\t\tif (side.n >= 2 && side.allySide) break;\n\t\t\t\tif (side === target || side === target.allySide) {\n\t\t\t\t\thandlers.push(...this.findSideEventHandlers(side, `on${eventName}`));\n\t\t\t\t} else if (prefixedHandlers) {\n\t\t\t\t\thandlers.push(...this.findSideEventHandlers(side, `onFoe${eventName}`));\n\t\t\t\t}\n\t\t\t\tif (prefixedHandlers) handlers.push(...this.findSideEventHandlers(side, `onAny${eventName}`));\n\t\t\t}\n\t\t}\n\t\thandlers.push(...this.findFieldEventHandlers(this.field, `on${eventName}`));\n\t\thandlers.push(...this.findBattleEventHandlers(`on${eventName}`));\n\t\treturn handlers;\n\t}\n\n\tfindPokemonEventHandlers(pokemon: Pokemon, callbackName: string, getKey?: 'duration') {\n\t\tconst handlers: EventListener[] = [];\n\n\t\tconst status = pokemon.getStatus();\n\t\t// @ts-expect-error dynamic lookup\n\t\tlet callback = status[callbackName];\n\t\tif (callback !== undefined || (getKey && pokemon.statusState[getKey])) {\n\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\teffect: status, callback, state: pokemon.statusState, end: pokemon.clearStatus, effectHolder: pokemon,\n\t\t\t}, callbackName));\n\t\t}\n\t\tfor (const id in pokemon.volatiles) {\n\t\t\tconst volatileState = pokemon.volatiles[id];\n\t\t\tconst volatile = this.dex.conditions.getByID(id as ID);\n\t\t\t// @ts-expect-error dynamic lookup\n\t\t\tcallback = volatile[callbackName];\n\t\t\tif (callback !== undefined || (getKey && volatileState[getKey])) {\n\t\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\t\teffect: volatile, callback, state: volatileState, end: pokemon.removeVolatile, effectHolder: pokemon,\n\t\t\t\t}, callbackName));\n\t\t\t} else if (['ability', 'item'].includes(volatile.id.split(':')[0])) {\n\t\t\t\t// Innate abilities/items; see comment below\n\t\t\t\t// @ts-expect-error dynamic lookup\n\t\t\t\tif (this.gen >= 5 && callbackName === 'onSwitchIn' && !volatile.onAnySwitchIn) {\n\t\t\t\t\tcallback = volatile.onStart;\n\t\t\t\t\tif (callback !== undefined || (getKey && volatileState[getKey])) {\n\t\t\t\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\t\t\t\teffect: volatile, callback, state: volatileState, end: pokemon.removeVolatile, effectHolder: pokemon,\n\t\t\t\t\t\t}, callbackName));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Abilities and items Start at different times during the SwitchIn event, so we run their onStart handlers\n\t\t// during the SwitchIn event instead of running the Start event during switch-ins\n\t\t// gens 4 and before still use the old system, though\n\t\tconst ability = pokemon.getAbility();\n\t\t// @ts-expect-error dynamic lookup\n\t\tcallback = ability[callbackName];\n\t\tif (callback !== undefined || (getKey && pokemon.abilityState[getKey])) {\n\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\teffect: ability, callback, state: pokemon.abilityState, end: pokemon.clearAbility, effectHolder: pokemon,\n\t\t\t}, callbackName));\n\t\t\t// @ts-expect-error dynamic lookup\n\t\t} else if (this.gen >= 5 && callbackName === 'onSwitchIn' && !ability.onAnySwitchIn) {\n\t\t\t// @ts-expect-error dynamic lookup\n\t\t\tcallback = ability.onStart;\n\t\t\tif (callback !== undefined || (getKey && pokemon.abilityState[getKey])) {\n\t\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\t\teffect: ability, callback, state: pokemon.abilityState, end: pokemon.clearAbility, effectHolder: pokemon,\n\t\t\t\t}, callbackName));\n\t\t\t}\n\t\t}\n\t\tconst item = pokemon.getItem();\n\t\t// @ts-expect-error dynamic lookup\n\t\tcallback = item[callbackName];\n\t\tif (callback !== undefined || (getKey && pokemon.itemState[getKey])) {\n\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\teffect: item, callback, state: pokemon.itemState, end: pokemon.clearItem, effectHolder: pokemon,\n\t\t\t}, callbackName));\n\t\t\t// @ts-expect-error dynamic lookup\n\t\t} else if (this.gen >= 5 && callbackName === 'onSwitchIn' && !item.onAnySwitchIn) {\n\t\t\tcallback = item.onStart;\n\t\t\tif (callback !== undefined || (getKey && pokemon.itemState[getKey])) {\n\t\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\t\teffect: item, callback, state: pokemon.itemState, end: pokemon.clearItem, effectHolder: pokemon,\n\t\t\t\t}, callbackName));\n\t\t\t}\n\t\t}\n\t\tconst species = pokemon.baseSpecies;\n\t\t// @ts-expect-error dynamic lookup\n\t\tcallback = species[callbackName];\n\t\tif (callback !== undefined) {\n\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\teffect: species, callback, state: pokemon.speciesState, end() {}, effectHolder: pokemon,\n\t\t\t}, callbackName));\n\t\t}\n\t\tconst side = pokemon.side;\n\t\tfor (const conditionid in side.slotConditions[pokemon.position]) {\n\t\t\tconst slotConditionState = side.slotConditions[pokemon.position][conditionid];\n\t\t\tconst slotCondition = this.dex.conditions.getByID(conditionid as ID);\n\t\t\t// @ts-expect-error dynamic lookup\n\t\t\tcallback = slotCondition[callbackName];\n\t\t\tif (callback !== undefined || (getKey && slotConditionState[getKey])) {\n\t\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\t\teffect: slotCondition,\n\t\t\t\t\tcallback,\n\t\t\t\t\tstate: slotConditionState,\n\t\t\t\t\tend: side.removeSlotCondition,\n\t\t\t\t\tendCallArgs: [side, pokemon, slotCondition.id],\n\t\t\t\t\teffectHolder: pokemon,\n\t\t\t\t}, callbackName));\n\t\t\t}\n\t\t}\n\n\t\treturn handlers;\n\t}\n\n\tfindBattleEventHandlers(callbackName: string, getKey?: 'duration', customHolder?: Pokemon) {\n\t\tconst handlers: EventListener[] = [];\n\n\t\tlet callback;\n\t\tconst format = this.format;\n\t\t// @ts-expect-error dynamic lookup\n\t\tcallback = format[callbackName];\n\t\tif (callback !== undefined || (getKey && this.formatData[getKey])) {\n\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\teffect: format, callback, state: this.formatData, end: null, effectHolder: customHolder || this,\n\t\t\t}, callbackName));\n\t\t}\n\t\tif (this.events && (callback = this.events[callbackName]) !== undefined) {\n\t\t\tfor (const handler of callback) {\n\t\t\t\tconst state = (handler.target.effectType === 'Format') ? this.formatData : null;\n\t\t\t\thandlers.push({\n\t\t\t\t\teffect: handler.target, callback: handler.callback, state, end: null, effectHolder: customHolder || this,\n\t\t\t\t\tpriority: handler.priority, order: handler.order, subOrder: handler.subOrder,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn handlers;\n\t}\n\n\tfindFieldEventHandlers(field: Field, callbackName: string, getKey?: 'duration', customHolder?: Pokemon) {\n\t\tconst handlers: EventListener[] = [];\n\n\t\tlet callback;\n\t\tfor (const id in field.pseudoWeather) {\n\t\t\tconst pseudoWeatherState = field.pseudoWeather[id];\n\t\t\tconst pseudoWeather = this.dex.conditions.getByID(id as ID);\n\t\t\t// @ts-expect-error dynamic lookup\n\t\t\tcallback = pseudoWeather[callbackName];\n\t\t\tif (callback !== undefined || (getKey && pseudoWeatherState[getKey])) {\n\t\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\t\teffect: pseudoWeather, callback, state: pseudoWeatherState,\n\t\t\t\t\tend: customHolder ? null : field.removePseudoWeather, effectHolder: customHolder || field,\n\t\t\t\t}, callbackName));\n\t\t\t}\n\t\t}\n\t\tconst weather = field.getWeather();\n\t\t// @ts-expect-error dynamic lookup\n\t\tcallback = weather[callbackName];\n\t\tif (callback !== undefined || (getKey && this.field.weatherState[getKey])) {\n\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\teffect: weather, callback, state: this.field.weatherState,\n\t\t\t\tend: customHolder ? null : field.clearWeather, effectHolder: customHolder || field,\n\t\t\t}, callbackName));\n\t\t}\n\t\tconst terrain = field.getTerrain();\n\t\t// @ts-expect-error dynamic lookup\n\t\tcallback = terrain[callbackName];\n\t\tif (callback !== undefined || (getKey && field.terrainState[getKey])) {\n\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\teffect: terrain, callback, state: field.terrainState,\n\t\t\t\tend: customHolder ? null : field.clearTerrain, effectHolder: customHolder || field,\n\t\t\t}, callbackName));\n\t\t}\n\n\t\treturn handlers;\n\t}\n\n\tfindSideEventHandlers(side: Side, callbackName: string, getKey?: 'duration', customHolder?: Pokemon) {\n\t\tconst handlers: EventListener[] = [];\n\n\t\tfor (const id in side.sideConditions) {\n\t\t\tconst sideConditionData = side.sideConditions[id];\n\t\t\tconst sideCondition = this.dex.conditions.getByID(id as ID);\n\t\t\t// @ts-expect-error dynamic lookup\n\t\t\tconst callback = sideCondition[callbackName];\n\t\t\tif (callback !== undefined || (getKey && sideConditionData[getKey])) {\n\t\t\t\thandlers.push(this.resolvePriority({\n\t\t\t\t\teffect: sideCondition, callback, state: sideConditionData,\n\t\t\t\t\tend: customHolder ? null : side.removeSideCondition, effectHolder: customHolder || side,\n\t\t\t\t}, callbackName));\n\t\t\t}\n\t\t}\n\t\treturn handlers;\n\t}\n\n\t/**\n\t * Use this function to attach custom event handlers to a battle. See Battle#runEvent for\n\t * more information on how to write callbacks for event handlers.\n\t *\n\t * Try to use this sparingly. Most event handlers can be simply placed in a format instead.\n\t *\n\t * this.onEvent(eventid, target, callback)\n\t * will set the callback as an event handler for the target when eventid is called with the\n\t * default priority. Currently only valid formats are supported as targets but this will\n\t * eventually be expanded to support other target types.\n\t *\n\t * this.onEvent(eventid, target, priority, callback)\n\t * will set the callback as an event handler for the target when eventid is called with the\n\t * provided priority. Priority can either be a number or an object that contains the priority,\n\t * order, and subOrder for the event handler as needed (undefined keys will use default values)\n\t */\n\tonEvent(eventid: string, target: Format, ...rest: AnyObject[]) { // rest = [priority, callback]\n\t\tif (!eventid) throw new TypeError(\"Event handlers must have an event to listen to\");\n\t\tif (!target) throw new TypeError(\"Event handlers must have a target\");\n\t\tif (!rest.length) throw new TypeError(\"Event handlers must have a callback\");\n\n\t\tif (target.effectType !== 'Format') {\n\t\t\tthrow new TypeError(`${target.name} is a ${target.effectType} but only Format targets are supported right now`);\n\t\t}\n\n\t\tlet callback, priority, order, subOrder, data;\n\t\tif (rest.length === 1) {\n\t\t\t[callback] = rest;\n\t\t\tpriority = 0;\n\t\t\torder = false;\n\t\t\tsubOrder = 0;\n\t\t} else {\n\t\t\t[data, callback] = rest;\n\t\t\tif (typeof data === 'object') {\n\t\t\t\tpriority = data['priority'] || 0;\n\t\t\t\torder = data['order'] || false;\n\t\t\t\tsubOrder = data['subOrder'] || 0;\n\t\t\t} else {\n\t\t\t\tpriority = data || 0;\n\t\t\t\torder = false;\n\t\t\t\tsubOrder = 0;\n\t\t\t}\n\t\t}\n\n\t\tconst eventHandler = { callback, target, priority, order, subOrder };\n\n\t\tif (!this.events) this.events = {};\n\t\tconst callbackName = `on${eventid}`;\n\t\tconst eventHandlers = this.events[callbackName];\n\t\tif (eventHandlers === undefined) {\n\t\t\tthis.events[callbackName] = [eventHandler];\n\t\t} else {\n\t\t\teventHandlers.push(eventHandler);\n\t\t}\n\t}\n\n\tcheckMoveMakesContact(move: ActiveMove, attacker: Pokemon, defender: Pokemon, announcePads = false) {\n\t\tif (move.flags['contact'] && attacker.hasItem('protectivepads')) {\n\t\t\tif (announcePads) {\n\t\t\t\tthis.add('-activate', defender, this.effect.fullname);\n\t\t\t\tthis.add('-activate', attacker, 'item: Protective Pads');\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn !!move.flags['contact'];\n\t}\n\n\tgetPokemon(fullname: string | Pokemon) {\n\t\tif (typeof fullname !== 'string') fullname = fullname.fullname;\n\t\tfor (const side of this.sides) {\n\t\t\tfor (const pokemon of side.pokemon) {\n\t\t\t\tif (pokemon.fullname === fullname) return pokemon;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tgetAllPokemon() {\n\t\tconst pokemonList: Pokemon[] = [];\n\t\tfor (const side of this.sides) {\n\t\t\tpokemonList.push(...side.pokemon);\n\t\t}\n\t\treturn pokemonList;\n\t}\n\n\tgetAllActive(includeFainted?: boolean) {\n\t\tconst pokemonList: Pokemon[] = [];\n\t\tfor (const side of this.sides) {\n\t\t\tfor (const pokemon of side.active) {\n\t\t\t\tif (pokemon && (includeFainted || !pokemon.fainted)) {\n\t\t\t\t\tpokemonList.push(pokemon);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn pokemonList;\n\t}\n\n\tmakeRequest(type?: RequestState) {\n\t\tif (type) {\n\t\t\tthis.requestState = type;\n\t\t\tfor (const side of this.sides) {\n\t\t\t\tside.clearChoice();\n\t\t\t}\n\t\t} else {\n\t\t\ttype = this.requestState;\n\t\t}\n\n\t\tfor (const side of this.sides) {\n\t\t\tside.activeRequest = null;\n\t\t}\n\n\t\tif (type === 'teampreview') {\n\t\t\t// `pickedTeamSize = 6` means the format wants the user to select\n\t\t\t// the entire team order, unlike `pickedTeamSize = undefined` which\n\t\t\t// will only ask the user to select their lead(s).\n\t\t\tconst pickedTeamSize = this.ruleTable.pickedTeamSize;\n\t\t\tthis.add(`teampreview${pickedTeamSize ? `|${pickedTeamSize}` : ''}`);\n\t\t}\n\n\t\tconst requests = this.getRequests(type);\n\t\tfor (let i = 0; i < this.sides.length; i++) {\n\t\t\tthis.sides[i].emitRequest(requests[i]);\n\t\t}\n\n\t\tif (this.sides.every(side => side.isChoiceDone())) {\n\t\t\tthrow new Error(`Choices are done immediately after a request`);\n\t\t}\n\t}\n\n\tclearRequest() {\n\t\tthis.requestState = '';\n\t\tfor (const side of this.sides) {\n\t\t\tside.activeRequest = null;\n\t\t\tside.clearChoice();\n\t\t}\n\t}\n\n\tgetRequests(type: RequestState) {\n\t\t// default to no request\n\t\tconst requests: ChoiceRequest[] = Array(this.sides.length).fill(null);\n\n\t\tswitch (type) {\n\t\tcase 'switch':\n\t\t\tfor (let i = 0; i < this.sides.length; i++) {\n\t\t\t\tconst side = this.sides[i];\n\t\t\t\tif (!side.pokemonLeft) continue;\n\t\t\t\tconst switchTable = side.active.map(pokemon => !!pokemon?.switchFlag);\n\t\t\t\tif (switchTable.some(Boolean)) {\n\t\t\t\t\trequests[i] = { forceSwitch: switchTable, side: side.getRequestData() };\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 'teampreview':\n\t\t\tfor (let i = 0; i < this.sides.length; i++) {\n\t\t\t\tconst side = this.sides[i];\n\t\t\t\tconst maxChosenTeamSize = this.ruleTable.pickedTeamSize || undefined;\n\t\t\t\trequests[i] = { teamPreview: true, maxChosenTeamSize, side: side.getRequestData() };\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tfor (let i = 0; i < this.sides.length; i++) {\n\t\t\t\tconst side = this.sides[i];\n\t\t\t\tif (!side.pokemonLeft) continue;\n\t\t\t\tconst activeData = side.active.map(pokemon => pokemon?.getMoveRequestData());\n\t\t\t\trequests[i] = { active: activeData, side: side.getRequestData() };\n\t\t\t\tif (side.allySide) {\n\t\t\t\t\t(requests[i] as MoveRequest).ally = side.allySide.getRequestData(true);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tconst multipleRequestsExist = requests.filter(Boolean).length >= 2;\n\t\tfor (let i = 0; i < this.sides.length; i++) {\n\t\t\tif (requests[i]) {\n\t\t\t\tif (!this.supportCancel || !multipleRequestsExist) requests[i].noCancel = true;\n\t\t\t} else {\n\t\t\t\trequests[i] = { wait: true, side: this.sides[i].getRequestData() };\n\t\t\t}\n\t\t}\n\n\t\treturn requests;\n\t}\n\n\ttiebreak() {\n\t\tif (this.ended) return false;\n\n\t\tthis.inputLog.push(`>tiebreak`);\n\t\tthis.add('message', \"Time's up! Going to tiebreaker...\");\n\t\tconst notFainted = this.sides.map(side => (\n\t\t\tside.pokemon.filter(pokemon => !pokemon.fainted).length\n\t\t));\n\t\tthis.add('-message', this.sides.map((side, i) => (\n\t\t\t`${side.name}: ${notFainted[i]} Pokemon left`\n\t\t)).join('; '));\n\t\tconst maxNotFainted = Math.max(...notFainted);\n\t\tlet tiedSides = this.sides.filter((side, i) => notFainted[i] === maxNotFainted);\n\t\tif (tiedSides.length <= 1) {\n\t\t\treturn this.win(tiedSides[0]);\n\t\t}\n\n\t\tconst hpPercentage = tiedSides.map(side => (\n\t\t\tside.pokemon.map(pokemon => pokemon.hp / pokemon.maxhp).reduce((a, b) => a + b) * 100 / 6\n\t\t));\n\t\tthis.add('-message', tiedSides.map((side, i) => (\n\t\t\t`${side.name}: ${Math.round(hpPercentage[i])}% total HP left`\n\t\t)).join('; '));\n\t\tconst maxPercentage = Math.max(...hpPercentage);\n\t\ttiedSides = tiedSides.filter((side, i) => hpPercentage[i] === maxPercentage);\n\t\tif (tiedSides.length <= 1) {\n\t\t\treturn this.win(tiedSides[0]);\n\t\t}\n\n\t\tconst hpTotal = tiedSides.map(side => (\n\t\t\tside.pokemon.map(pokemon => pokemon.hp).reduce((a, b) => a + b)\n\t\t));\n\t\tthis.add('-message', tiedSides.map((side, i) => (\n\t\t\t`${side.name}: ${Math.round(hpTotal[i])} total HP left`\n\t\t)).join('; '));\n\t\tconst maxTotal = Math.max(...hpTotal);\n\t\ttiedSides = tiedSides.filter((side, i) => hpTotal[i] === maxTotal);\n\t\tif (tiedSides.length <= 1) {\n\t\t\treturn this.win(tiedSides[0]);\n\t\t}\n\t\treturn this.tie();\n\t}\n\n\tforceWin(side: SideID | null = null) {\n\t\tif (this.ended) return false;\n\t\tthis.inputLog.push(side ? `>forcewin ${side}` : `>forcetie`);\n\t\treturn this.win(side);\n\t}\n\n\ttie() {\n\t\treturn this.win();\n\t}\n\n\twin(side?: SideID | '' | Side | null) {\n\t\tif (this.ended) return false;\n\t\tif (side && typeof side === 'string') {\n\t\t\tside = this.getSide(side);\n\t\t} else if (!side || !this.sides.includes(side)) {\n\t\t\tside = null;\n\t\t}\n\t\tthis.winner = side ? side.name : '';\n\n\t\tthis.add('');\n\t\tif (side?.allySide) {\n\t\t\tthis.add('win', side.name + ' & ' + side.allySide.name);\n\t\t} else if (side) {\n\t\t\tthis.add('win', side.name);\n\t\t} else {\n\t\t\tthis.add('tie');\n\t\t}\n\t\tthis.ended = true;\n\t\tthis.requestState = '';\n\t\tfor (const s of this.sides) {\n\t\t\tif (s) s.activeRequest = null;\n\t\t}\n\t\treturn true;\n\t}\n\n\tlose(side: SideID | Side) {\n\t\tif (typeof side === 'string') {\n\t\t\tside = this.getSide(side);\n\t\t}\n\t\tif (!side) return; // can happen if a battle crashes\n\t\tif (this.gameType !== 'freeforall') {\n\t\t\treturn this.win(side.foe);\n\t\t}\n\t\tif (!side.pokemonLeft) return;\n\n\t\tside.pokemonLeft = 0;\n\t\tside.active[0]?.faint();\n\t\tthis.faintMessages(false, true);\n\t\tif (!this.ended && side.requestState) {\n\t\t\tside.emitRequest({ wait: true, side: side.getRequestData() });\n\t\t\tside.clearChoice();\n\t\t\tif (this.allChoicesDone()) this.commitChoices();\n\t\t}\n\t\treturn true;\n\t}\n\n\tcanSwitch(side: Side) {\n\t\treturn this.possibleSwitches(side).length;\n\t}\n\n\tgetRandomSwitchable(side: Side) {\n\t\tconst canSwitchIn = this.possibleSwitches(side);\n\t\treturn canSwitchIn.length ? this.sample(canSwitchIn) : null;\n\t}\n\n\tprivate possibleSwitches(side: Side) {\n\t\tif (!side.pokemonLeft) return [];\n\n\t\tconst canSwitchIn = [];\n\t\tfor (let i = side.active.length; i < side.pokemon.length; i++) {\n\t\t\tconst pokemon = side.pokemon[i];\n\t\t\tif (!pokemon.fainted) {\n\t\t\t\tcanSwitchIn.push(pokemon);\n\t\t\t}\n\t\t}\n\t\treturn canSwitchIn;\n\t}\n\n\tswapPosition(pokemon: Pokemon, newPosition: number, attributes?: string) {\n\t\tif (newPosition >= pokemon.side.active.length) {\n\t\t\tthrow new Error(\"Invalid swap position\");\n\t\t}\n\t\tconst target = pokemon.side.active[newPosition];\n\t\tif (newPosition !== 1 && (!target || target.fainted)) return false;\n\n\t\tthis.add('swap', pokemon, newPosition, attributes || '');\n\n\t\tconst side = pokemon.side;\n\t\tside.pokemon[pokemon.position] = target;\n\t\tside.pokemon[newPosition] = pokemon;\n\t\tside.active[pokemon.position] = side.pokemon[pokemon.position];\n\t\tside.active[newPosition] = side.pokemon[newPosition];\n\t\tif (target) target.position = pokemon.position;\n\t\tpokemon.position = newPosition;\n\t\tthis.runEvent('Swap', target, pokemon);\n\t\tthis.runEvent('Swap', pokemon, target);\n\t\treturn true;\n\t}\n\n\tgetAtSlot(slot: PokemonSlot): Pokemon;\n\tgetAtSlot(slot: PokemonSlot | null): Pokemon | null;\n\tgetAtSlot(slot: PokemonSlot | null) {\n\t\tif (!slot) return null;\n\t\tconst side = this.sides[slot.charCodeAt(1) - 49]; // 49 is '1'\n\t\tconst position = slot.charCodeAt(2) - 97; // 97 is 'a'\n\t\tconst positionOffset = Math.floor(side.n / 2) * side.active.length;\n\t\treturn side.active[position - positionOffset];\n\t}\n\n\tfaint(pokemon: Pokemon, source?: Pokemon, effect?: Effect) {\n\t\tpokemon.faint(source, effect);\n\t}\n\n\tendTurn() {\n\t\tthis.turn++;\n\t\tthis.lastSuccessfulMoveThisTurn = null;\n\n\t\tconst dynamaxEnding: Pokemon[] = [];\n\t\tfor (const pokemon of this.getAllActive()) {\n\t\t\tif (pokemon.volatiles['dynamax']?.turns === 3) {\n\t\t\t\tdynamaxEnding.push(pokemon);\n\t\t\t}\n\t\t}\n\t\tif (dynamaxEnding.length > 1) {\n\t\t\tthis.updateSpeed();\n\t\t\tthis.speedSort(dynamaxEnding);\n\t\t}\n\t\tfor (const pokemon of dynamaxEnding) {\n\t\t\tpokemon.removeVolatile('dynamax');\n\t\t}\n\n\t\t// Gen 1 partial trapping ends when either Pokemon or a switch in faints to residual damage\n\t\tif (this.gen === 1) {\n\t\t\tfor (const pokemon of this.getAllActive()) {\n\t\t\t\tif (pokemon.volatiles['partialtrappinglock']) {\n\t\t\t\t\tconst target = pokemon.volatiles['partialtrappinglock'].locked;\n\t\t\t\t\tif (target.hp <= 0 || !target.volatiles['partiallytrapped']) {\n\t\t\t\t\t\tdelete pokemon.volatiles['partialtrappinglock'];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (pokemon.volatiles['partiallytrapped']) {\n\t\t\t\t\tconst source = pokemon.volatiles['partiallytrapped'].source;\n\t\t\t\t\tif (source.hp <= 0 || !source.volatiles['partialtrappinglock']) {\n\t\t\t\t\t\tdelete pokemon.volatiles['partiallytrapped'];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst trappedBySide: boolean[] = [];\n\t\tconst stalenessBySide: ('internal' | 'external' | undefined)[] = [];\n\t\tfor (const side of this.sides) {\n\t\t\tlet sideTrapped = true;\n\t\t\tlet sideStaleness: 'internal' | 'external' | undefined;\n\t\t\tfor (const pokemon of side.active) {\n\t\t\t\tif (!pokemon) continue;\n\t\t\t\tpokemon.moveThisTurn = '';\n\t\t\t\tpokemon.newlySwitched = false;\n\t\t\t\tpokemon.moveLastTurnResult = pokemon.moveThisTurnResult;\n\t\t\t\tpokemon.moveThisTurnResult = undefined;\n\t\t\t\tif (this.turn !== 1) {\n\t\t\t\t\tpokemon.usedItemThisTurn = false;\n\t\t\t\t\tpokemon.statsRaisedThisTurn = false;\n\t\t\t\t\tpokemon.statsLoweredThisTurn = false;\n\t\t\t\t\t// It shouldn't be possible in a normal battle for a Pokemon to be damaged before turn 1's move selection\n\t\t\t\t\t// However, this could be potentially relevant in certain OMs\n\t\t\t\t\tpokemon.hurtThisTurn = null;\n\t\t\t\t}\n\n\t\t\t\tpokemon.maybeDisabled = false;\n\t\t\t\tfor (const moveSlot of pokemon.moveSlots) {\n\t\t\t\t\tmoveSlot.disabled = false;\n\t\t\t\t\tmoveSlot.disabledSource = '';\n\t\t\t\t}\n\t\t\t\tthis.runEvent('DisableMove', pokemon);\n\t\t\t\tfor (const moveSlot of pokemon.moveSlots) {\n\t\t\t\t\tconst activeMove = this.dex.getActiveMove(moveSlot.id);\n\t\t\t\t\tthis.singleEvent('DisableMove', activeMove, null, pokemon);\n\t\t\t\t\tif (activeMove.flags['cantusetwice'] && pokemon.lastMove?.id === moveSlot.id) {\n\t\t\t\t\t\tpokemon.disableMove(pokemon.lastMove.id);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If it was an illusion, it's not any more\n\t\t\t\tif (pokemon.getLastAttackedBy() && this.gen >= 7) pokemon.knownType = true;\n\n\t\t\t\tfor (let i = pokemon.attackedBy.length - 1; i >= 0; i--) {\n\t\t\t\t\tconst attack = pokemon.attackedBy[i];\n\t\t\t\t\tif (attack.source.isActive) {\n\t\t\t\t\t\tattack.thisTurn = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpokemon.attackedBy.splice(pokemon.attackedBy.indexOf(attack), 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this.gen >= 7 && !pokemon.terastallized) {\n\t\t\t\t\t// In Gen 7, the real type of every Pokemon is visible to all players via the bottom screen while making choices\n\t\t\t\t\tconst seenPokemon = pokemon.illusion || pokemon;\n\t\t\t\t\tconst realTypeString = seenPokemon.getTypes(true).join('/');\n\t\t\t\t\tif (realTypeString !== seenPokemon.apparentType) {\n\t\t\t\t\t\tthis.add('-start', pokemon, 'typechange', realTypeString, '[silent]');\n\t\t\t\t\t\tseenPokemon.apparentType = realTypeString;\n\t\t\t\t\t\tif (pokemon.addedType) {\n\t\t\t\t\t\t\t// The typechange message removes the added type, so put it back\n\t\t\t\t\t\t\tthis.add('-start', pokemon, 'typeadd', pokemon.addedType, '[silent]');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpokemon.trapped = pokemon.maybeTrapped = false;\n\t\t\t\tthis.runEvent('TrapPokemon', pokemon);\n\t\t\t\tif (!pokemon.knownType || this.dex.getImmunity('trapped', pokemon)) {\n\t\t\t\t\tthis.runEvent('MaybeTrapPokemon', pokemon);\n\t\t\t\t}\n\t\t\t\t// canceling switches would leak information\n\t\t\t\t// if a foe might have a trapping ability\n\t\t\t\tif (this.gen > 2) {\n\t\t\t\t\tfor (const source of pokemon.foes()) {\n\t\t\t\t\t\tconst species = (source.illusion || source).species;\n\t\t\t\t\t\tif (!species.abilities) continue;\n\t\t\t\t\t\tfor (const abilitySlot in species.abilities) {\n\t\t\t\t\t\t\tconst abilityName = species.abilities[abilitySlot as keyof Species['abilities']];\n\t\t\t\t\t\t\tif (abilityName === source.ability) {\n\t\t\t\t\t\t\t\t// pokemon event was already run above so we don't need\n\t\t\t\t\t\t\t\t// to run it again.\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst ruleTable = this.ruleTable;\n\t\t\t\t\t\t\tif ((ruleTable.has('+hackmons') || !ruleTable.has('obtainableabilities')) && !this.format.team) {\n\t\t\t\t\t\t\t\t// hackmons format\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t} else if (abilitySlot === 'H' && species.unreleasedHidden) {\n\t\t\t\t\t\t\t\t// unreleased hidden ability\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst ability = this.dex.abilities.get(abilityName);\n\t\t\t\t\t\t\tif (ruleTable.has('-ability:' + ability.id)) continue;\n\t\t\t\t\t\t\tif (pokemon.knownType && !this.dex.getImmunity('trapped', pokemon)) continue;\n\t\t\t\t\t\t\tthis.singleEvent('FoeMaybeTrapPokemon', ability, {}, pokemon, source);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (pokemon.fainted) continue;\n\n\t\t\t\tsideTrapped = sideTrapped && pokemon.trapped;\n\t\t\t\tconst staleness = pokemon.volatileStaleness || pokemon.staleness;\n\t\t\t\tif (staleness) sideStaleness = sideStaleness === 'external' ? sideStaleness : staleness;\n\t\t\t\tpokemon.activeTurns++;\n\t\t\t}\n\t\t\ttrappedBySide.push(sideTrapped);\n\t\t\tstalenessBySide.push(sideStaleness);\n\t\t\tside.faintedLastTurn = side.faintedThisTurn;\n\t\t\tside.faintedThisTurn = null;\n\t\t}\n\n\t\tif (this.maybeTriggerEndlessBattleClause(trappedBySide, stalenessBySide)) return;\n\n\t\tif (this.gameType === 'triples' && this.sides.every(side => side.pokemonLeft === 1)) {\n\t\t\t// If both sides have one Pokemon left in triples and they are not adjacent, they are both moved to the center.\n\t\t\tconst actives = this.getAllActive();\n\t\t\tif (actives.length > 1 && !actives[0].isAdjacent(actives[1])) {\n\t\t\t\tthis.swapPosition(actives[0], 1, '[silent]');\n\t\t\t\tthis.swapPosition(actives[1], 1, '[silent]');\n\t\t\t\tthis.add('-center');\n\t\t\t}\n\t\t}\n\n\t\tthis.add('turn', this.turn);\n\t\tif (this.gameType === 'multi') {\n\t\t\tfor (const side of this.sides) {\n\t\t\t\tif (side.canDynamaxNow()) {\n\t\t\t\t\tif (this.turn === 1) {\n\t\t\t\t\t\tthis.addSplit(side.id, ['-candynamax', side.id]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.add('-candynamax', side.id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.gen === 2) this.quickClawRoll = this.randomChance(60, 256);\n\t\tif (this.gen === 3) this.quickClawRoll = this.randomChance(1, 5);\n\n\t\tthis.makeRequest('move');\n\t}\n\n\tmaybeTriggerEndlessBattleClause(\n\t\ttrappedBySide: boolean[], stalenessBySide: ('internal' | 'external' | undefined)[]\n\t) {\n\t\t// Gen 1 Endless Battle Clause triggers\n\t\t// These are checked before the 100 turn minimum as the battle cannot progress if they are true\n\t\tif (this.gen <= 1) {\n\t\t\tconst noProgressPossible = this.sides.every(side => {\n\t\t\t\tconst foeAllGhosts = side.foe.pokemon.every(pokemon => pokemon.fainted || pokemon.hasType('Ghost'));\n\t\t\t\tconst foeAllTransform = side.foe.pokemon.every(pokemon => (\n\t\t\t\t\tpokemon.fainted ||\n\t\t\t\t\t// true if transforming into this pokemon would lead to an endless battle\n\t\t\t\t\t// Transform will fail (depleting PP) if used against Ditto in Stadium 1\n\t\t\t\t\t(this.dex.currentMod !== 'gen1stadium' || pokemon.species.id !== 'ditto') &&\n\t\t\t\t\t// there are some subtleties such as a Mew with only Transform and auto-fail moves,\n\t\t\t\t\t// but it's unlikely to come up in a real game so there's no need to handle it\n\t\t\t\t\tpokemon.moves.every(moveid => moveid === 'transform')\n\t\t\t\t));\n\t\t\t\treturn side.pokemon.every(pokemon => (\n\t\t\t\t\tpokemon.fainted ||\n\t\t\t\t\t// frozen pokemon can't thaw in gen 1 without outside help\n\t\t\t\t\tpokemon.status === 'frz' ||\n\t\t\t\t\t// a pokemon can't lose PP if it Transforms into a pokemon with only Transform\n\t\t\t\t\t(pokemon.moves.every(moveid => moveid === 'transform') && foeAllTransform) ||\n\t\t\t\t\t// Struggle can't damage yourself if every foe is a Ghost\n\t\t\t\t\t(pokemon.moveSlots.every(slot => slot.pp === 0) && foeAllGhosts)\n\t\t\t\t));\n\t\t\t});\n\t\t\tif (noProgressPossible) {\n\t\t\t\tthis.add('-message', `This battle cannot progress. Endless Battle Clause activated!`);\n\t\t\t\treturn this.tie();\n\t\t\t}\n\t\t}\n\n\t\tif (this.turn <= 100) return;\n\n\t\t// the turn limit is not a part of Endless Battle Clause\n\t\tif (this.turn >= 1000) {\n\t\t\tthis.add('message', `It is turn 1000. You have hit the turn limit!`);\n\t\t\tthis.tie();\n\t\t\treturn true;\n\t\t}\n\t\tif (\n\t\t\t(this.turn >= 500 && this.turn % 100 === 0) || // every 100 turns past turn 500,\n\t\t\t(this.turn >= 900 && this.turn % 10 === 0) || // every 10 turns past turn 900,\n\t\t\tthis.turn >= 990 // every turn past turn 990\n\t\t) {\n\t\t\tconst turnsLeft = 1000 - this.turn;\n\t\t\tconst turnsLeftText = (turnsLeft === 1 ? `1 turn` : `${turnsLeft} turns`);\n\t\t\tthis.add('bigerror', `You will auto-tie if the battle doesn't end in ${turnsLeftText} (on turn 1000).`);\n\t\t}\n\n\t\tif (!this.ruleTable.has('endlessbattleclause')) return;\n\t\t// for now, FFA doesn't support Endless Battle Clause\n\t\tif (this.format.gameType === 'freeforall') return;\n\n\t\t// Are all Pokemon on every side stale, with at least one side containing an externally stale Pokemon?\n\t\tif (!stalenessBySide.every(s => !!s) || !stalenessBySide.some(s => s === 'external')) return;\n\n\t\t// Can both sides switch to a non-stale Pokemon?\n\t\tconst canSwitch = [];\n\t\tfor (const [i, trapped] of trappedBySide.entries()) {\n\t\t\tcanSwitch[i] = false;\n\t\t\tif (trapped) break;\n\t\t\tconst side = this.sides[i];\n\n\t\t\tfor (const pokemon of side.pokemon) {\n\t\t\t\tif (!pokemon.fainted && !(pokemon.volatileStaleness || pokemon.staleness)) {\n\t\t\t\t\tcanSwitch[i] = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (canSwitch.every(s => s)) return;\n\n\t\t// Endless Battle Clause activates - we determine the winner by looking at each side's sets.\n\t\tconst losers: Side[] = [];\n\t\tfor (const side of this.sides) {\n\t\t\tlet berry = false; // Restorative Berry\n\t\t\tlet cycle = false; // Harvest or Recycle\n\t\t\tfor (const pokemon of side.pokemon) {\n\t\t\t\tberry = RESTORATIVE_BERRIES.has(toID(pokemon.set.item));\n\t\t\t\tif (['harvest', 'pickup'].includes(toID(pokemon.set.ability)) ||\n\t\t\t\t\tpokemon.set.moves.map(toID).includes('recycle' as ID)) {\n\t\t\t\t\tcycle = true;\n\t\t\t\t}\n\t\t\t\tif (berry && cycle) break;\n\t\t\t}\n\t\t\tif (berry && cycle) losers.push(side);\n\t\t}\n\n\t\tif (losers.length === 1) {\n\t\t\tconst loser = losers[0];\n\t\t\tthis.add('-message', `${loser.name}'s team started with the rudimentary means to perform restorative berry-cycling and thus loses.`);\n\t\t\treturn this.win(loser.foe);\n\t\t}\n\t\tif (losers.length === this.sides.length) {\n\t\t\tthis.add('-message', `Each side's team started with the rudimentary means to perform restorative berry-cycling.`);\n\t\t}\n\n\t\treturn this.tie();\n\t}\n\n\tstart() {\n\t\t// Deserialized games should use restart()\n\t\tif (this.deserialized) return;\n\t\t// need all players to start\n\t\tif (!this.sides.every(side => !!side)) throw new Error(`Missing sides: ${this.sides}`);\n\n\t\tif (this.started) throw new Error(`Battle already started`);\n\n\t\tconst format = this.format;\n\t\tthis.started = true;\n\t\tif (this.gameType === 'multi') {\n\t\t\tthis.sides[1].foe = this.sides[2]!;\n\t\t\tthis.sides[0].foe = this.sides[3]!;\n\t\t\tthis.sides[2]!.foe = this.sides[1];\n\t\t\tthis.sides[3]!.foe = this.sides[0];\n\t\t\tthis.sides[1].allySide = this.sides[3]!;\n\t\t\tthis.sides[0].allySide = this.sides[2]!;\n\t\t\tthis.sides[2]!.allySide = this.sides[0];\n\t\t\tthis.sides[3]!.allySide = this.sides[1];\n\t\t\t// sync side conditions\n\t\t\tthis.sides[2]!.sideConditions = this.sides[0].sideConditions;\n\t\t\tthis.sides[3]!.sideConditions = this.sides[1].sideConditions;\n\t\t} else {\n\t\t\tthis.sides[1].foe = this.sides[0];\n\t\t\tthis.sides[0].foe = this.sides[1];\n\t\t\tif (this.sides.length > 2) { // ffa\n\t\t\t\tthis.sides[2]!.foe = this.sides[3]!;\n\t\t\t\tthis.sides[3]!.foe = this.sides[2]!;\n\t\t\t}\n\t\t}\n\n\t\tfor (const side of this.sides) {\n\t\t\tthis.add('teamsize', side.id, side.pokemon.length);\n\t\t}\n\n\t\tthis.add('gen', this.gen);\n\n\t\tthis.add('tier', format.name);\n\t\tif (this.rated) {\n\t\t\tif (this.rated === 'Rated battle') this.rated = true;\n\t\t\tthis.add('rated', typeof this.rated === 'string' ? this.rated : '');\n\t\t}\n\n\t\tformat.onBegin?.call(this);\n\t\tfor (const rule of this.ruleTable.keys()) {\n\t\t\tif ('+*-!'.includes(rule.charAt(0))) continue;\n\t\t\tconst subFormat = this.dex.formats.get(rule);\n\t\t\tsubFormat.onBegin?.call(this);\n\t\t}\n\n\t\tif (this.sides.some(side => !side.pokemon[0])) {\n\t\t\tthrow new Error('Battle not started: A player has an empty team.');\n\t\t}\n\n\t\tif (this.debugMode) {\n\t\t\tthis.checkEVBalance();\n\t\t}\n\n\t\tformat.onTeamPreview?.call(this);\n\t\tfor (const rule of this.ruleTable.keys()) {\n\t\t\tif ('+*-!'.includes(rule.charAt(0))) continue;\n\t\t\tconst subFormat = this.dex.formats.get(rule);\n\t\t\tsubFormat.onTeamPreview?.call(this);\n\t\t}\n\n\t\tthis.queue.addChoice({ choice: 'start' });\n\t\tthis.midTurn = true;\n\t\tif (!this.requestState) this.turnLoop();\n\t}\n\n\trestart(send?: (type: string, data: string | string[]) => void) {\n\t\tif (!this.deserialized) throw new Error('Attempt to restart a battle which has not been deserialized');\n\n\t\t(this as any).send = send;\n\t}\n\n\tcheckEVBalance() {\n\t\tlet limitedEVs: boolean | null = null;\n\t\tfor (const side of this.sides) {\n\t\t\tconst sideLimitedEVs = !side.pokemon.some(\n\t\t\t\tpokemon => Object.values(pokemon.set.evs).reduce((a, b) => a + b, 0) > 510\n\t\t\t);\n\t\t\tif (limitedEVs === null) {\n\t\t\t\tlimitedEVs = sideLimitedEVs;\n\t\t\t} else if (limitedEVs !== sideLimitedEVs) {\n\t\t\t\tthis.add('bigerror', \"Warning: One player isn't adhering to a 510 EV limit, and the other player is.\");\n\t\t\t}\n\t\t}\n\t}\n\n\tboost(\n\t\tboost: SparseBoostsTable, target: Pokemon | null = null, source: Pokemon | null = null,\n\t\teffect: Effect | null = null, isSecondary = false, isSelf = false\n\t) {\n\t\tif (this.event) {\n\t\t\ttarget ||= this.event.target;\n\t\t\tsource ||= this.event.source;\n\t\t\teffect ||= this.effect;\n\t\t}\n\t\tif (!target?.hp) return 0;\n\t\tif (!target.isActive) return false;\n\t\tif (this.gen > 5 && !target.side.foePokemonLeft()) return false;\n\t\tboost = this.runEvent('ChangeBoost', target, source, effect, { ...boost });\n\t\tboost = target.getCappedBoost(boost);\n\t\tboost = this.runEvent('TryBoost', target, source, effect, { ...boost });\n\t\tlet success = null;\n\t\tlet boosted = isSecondary;\n\t\tlet boostName: BoostID;\n\t\tfor (boostName in boost) {\n\t\t\tconst currentBoost: SparseBoostsTable = {\n\t\t\t\t[boostName]: boost[boostName],\n\t\t\t};\n\t\t\tlet boostBy = target.boostBy(currentBoost);\n\t\t\tlet msg = '-boost';\n\t\t\tif (boost[boostName]! < 0 || target.boosts[boostName] === -6) {\n\t\t\t\tmsg = '-unboost';\n\t\t\t\tboostBy = -boostBy;\n\t\t\t}\n\t\t\tif (boostBy) {\n\t\t\t\tsuccess = true;\n\t\t\t\tswitch (effect?.id) {\n\t\t\t\tcase 'bellydrum': case 'angerpoint':\n\t\t\t\t\tthis.add('-setboost', target, 'atk', target.boosts['atk'], '[from] ' + effect.fullname);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'bellydrum2':\n\t\t\t\t\tthis.add(msg, target, boostName, boostBy, '[silent]');\n\t\t\t\t\tthis.hint(\"In Gen 2, Belly Drum boosts by 2 when it fails.\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'zpower':\n\t\t\t\t\tthis.add(msg, target, boostName, boostBy, '[zeffect]');\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif (!effect) break;\n\t\t\t\t\tif (effect.effectType === 'Move') {\n\t\t\t\t\t\tthis.add(msg, target, boostName, boostBy);\n\t\t\t\t\t} else if (effect.effectType === 'Item') {\n\t\t\t\t\t\tthis.add(msg, target, boostName, boostBy, '[from] item: ' + effect.name);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (effect.effectType === 'Ability' && !boosted) {\n\t\t\t\t\t\t\tthis.add('-ability', target, effect.name, 'boost');\n\t\t\t\t\t\t\tboosted = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.add(msg, target, boostName, boostBy);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tthis.runEvent('AfterEachBoost', target, source, effect, currentBoost);\n\t\t\t} else if (effect?.effectType === 'Ability') {\n\t\t\t\tif (isSecondary || isSelf) this.add(msg, target, boostName, boostBy);\n\t\t\t} else if (!isSecondary && !isSelf) {\n\t\t\t\tthis.add(msg, target, boostName, boostBy);\n\t\t\t}\n\t\t}\n\t\tthis.runEvent('AfterBoost', target, source, effect, boost);\n\t\tif (success) {\n\t\t\tif (Object.values(boost).some(x => x > 0)) target.statsRaisedThisTurn = true;\n\t\t\tif (Object.values(boost).some(x => x < 0)) target.statsLoweredThisTurn = true;\n\t\t}\n\t\treturn success;\n\t}\n\n\tspreadDamage(\n\t\tdamage: SpreadMoveDamage, targetArray: (false | Pokemon | null)[] | null = null,\n\t\tsource: Pokemon | null = null, effect: 'drain' | 'recoil' | Effect | null = null, instafaint = false\n\t) {\n\t\tif (!targetArray) return [0];\n\t\tconst retVals: (number | false | undefined)[] = [];\n\t\tif (typeof effect === 'string' || !effect) effect = this.dex.conditions.getByID((effect || '') as ID);\n\t\tfor (const [i, curDamage] of damage.entries()) {\n\t\t\tconst target = targetArray[i];\n\t\t\tlet targetDamage = curDamage;\n\t\t\tif (!(targetDamage || targetDamage === 0)) {\n\t\t\t\tretVals[i] = targetDamage;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!target || !target.hp) {\n\t\t\t\tretVals[i] = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!target.isActive) {\n\t\t\t\tretVals[i] = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (targetDamage !== 0) targetDamage = this.clampIntRange(targetDamage, 1);\n\n\t\t\tif (effect.id !== 'struggle-recoil') { // Struggle recoil is not affected by effects\n\t\t\t\tif (effect.effectType === 'Weather' && !target.runStatusImmunity(effect.id)) {\n\t\t\t\t\tthis.debug('weather immunity');\n\t\t\t\t\tretVals[i] = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\ttargetDamage = this.runEvent('Damage', target, source, effect, targetDamage, true);\n\t\t\t\tif (!(targetDamage || targetDamage === 0)) {\n\t\t\t\t\tthis.debug('damage event failed');\n\t\t\t\t\tretVals[i] = curDamage === true ? undefined : targetDamage;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (targetDamage !== 0) targetDamage = this.clampIntRange(targetDamage, 1);\n\n\t\t\tif (this.gen <= 1) {\n\t\t\t\tif (this.dex.currentMod === 'gen1stadium' ||\n\t\t\t\t\t!['recoil', 'drain', 'leechseed'].includes(effect.id) && effect.effectType !== 'Status') {\n\t\t\t\t\tthis.lastDamage = targetDamage;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tretVals[i] = targetDamage = target.damage(targetDamage, source, effect);\n\t\t\tif (targetDamage !== 0) target.hurtThisTurn = target.hp;\n\t\t\tif (source && effect.effectType === 'Move') source.lastDamage = targetDamage;\n\n\t\t\tconst name = effect.fullname === 'tox' ? 'psn' : effect.fullname;\n\t\t\tswitch (effect.id) {\n\t\t\tcase 'partiallytrapped':\n\t\t\t\tthis.add('-damage', target, target.getHealth, '[from] ' + this.effectState.sourceEffect.fullname, '[partiallytrapped]');\n\t\t\t\tbreak;\n\t\t\tcase 'powder':\n\t\t\t\tthis.add('-damage', target, target.getHealth, '[silent]');\n\t\t\t\tbreak;\n\t\t\tcase 'confused':\n\t\t\t\tthis.add('-damage', target, target.getHealth, '[from] confusion');\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (effect.effectType === 'Move' || !name) {\n\t\t\t\t\tthis.add('-damage', target, target.getHealth);\n\t\t\t\t} else if (source && (source !== target || effect.effectType === 'Ability')) {\n\t\t\t\t\tthis.add('-damage', target, target.getHealth, `[from] ${name}`, `[of] ${source}`);\n\t\t\t\t} else {\n\t\t\t\t\tthis.add('-damage', target, target.getHealth, `[from] ${name}`);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (targetDamage && effect.effectType === 'Move') {\n\t\t\t\tif (this.gen <= 1 && effect.recoil && source) {\n\t\t\t\t\tif (this.dex.currentMod !== 'gen1stadium' || target.hp > 0) {\n\t\t\t\t\t\tconst amount = this.clampIntRange(Math.floor(targetDamage * effect.recoil[0] / effect.recoil[1]), 1);\n\t\t\t\t\t\tthis.damage(amount, source, target, 'recoil');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (this.gen <= 4 && effect.drain && source) {\n\t\t\t\t\tconst amount = this.clampIntRange(Math.floor(targetDamage * effect.drain[0] / effect.drain[1]), 1);\n\t\t\t\t\t// Draining can be countered in gen 1\n\t\t\t\t\tif (this.gen <= 1) this.lastDamage = amount;\n\t\t\t\t\tthis.heal(amount, source, target, 'drain');\n\t\t\t\t}\n\t\t\t\tif (this.gen > 4 && effect.drain && source) {\n\t\t\t\t\tconst amount = Math.round(targetDamage * effect.drain[0] / effect.drain[1]);\n\t\t\t\t\tthis.heal(amount, source, target, 'drain');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (instafaint) {\n\t\t\tfor (const [i, target] of targetArray.entries()) {\n\t\t\t\tif (!retVals[i] || !target) continue;\n\n\t\t\t\tif (target.hp <= 0) {\n\t\t\t\t\tthis.debug(`instafaint: ${this.faintQueue.map(entry => entry.target.name)}`);\n\t\t\t\t\tthis.faintMessages(true);\n\t\t\t\t\tif (this.gen <= 2) {\n\t\t\t\t\t\ttarget.faint();\n\t\t\t\t\t\tif (this.gen <= 1) {\n\t\t\t\t\t\t\tthis.queue.clear();\n\t\t\t\t\t\t\t// Fainting clears accumulated Bide damage\n\t\t\t\t\t\t\tfor (const pokemon of this.getAllActive()) {\n\t\t\t\t\t\t\t\tif (pokemon.volatiles['bide']?.damage) {\n\t\t\t\t\t\t\t\t\tpokemon.volatiles['bide'].damage = 0;\n\t\t\t\t\t\t\t\t\tthis.hint(\"Desync Clause Mod activated!\");\n\t\t\t\t\t\t\t\t\tthis.hint(\"In Gen 1, Bide's accumulated damage is reset to 0 when a Pokemon faints.\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn retVals;\n\t}\n\n\tdamage(\n\t\tdamage: number, target: Pokemon | null = null, source: Pokemon | null = null,\n\t\teffect: 'drain' | 'recoil' | Effect | null = null, instafaint = false\n\t) {\n\t\tif (this.event) {\n\t\t\ttarget ||= this.event.target;\n\t\t\tsource ||= this.event.source;\n\t\t\teffect ||= this.effect;\n\t\t}\n\t\treturn this.spreadDamage([damage], [target], source, effect, instafaint)[0];\n\t}\n\n\tdirectDamage(damage: number, target?: Pokemon, source: Pokemon | null = null, effect: Effect | null = null) {\n\t\tif (this.event) {\n\t\t\ttarget ||= this.event.target;\n\t\t\tsource ||= this.event.source;\n\t\t\teffect ||= this.effect;\n\t\t}\n\t\tif (!target?.hp) return 0;\n\t\tif (!damage) return 0;\n\t\tdamage = this.clampIntRange(damage, 1);\n\n\t\tif (typeof effect === 'string' || !effect) effect = this.dex.conditions.getByID((effect || '') as ID);\n\n\t\t// In Gen 1 BUT NOT STADIUM, Substitute also takes confusion and HJK recoil damage\n\t\tif (this.gen <= 1 && this.dex.currentMod !== 'gen1stadium' &&\n\t\t\t['confusion', 'jumpkick', 'highjumpkick'].includes(effect.id)) {\n\t\t\t// Confusion and recoil damage can be countered\n\t\t\tthis.lastDamage = damage;\n\t\t\tif (target.volatiles['substitute']) {\n\t\t\t\tconst hint = \"In Gen 1, if a Pokemon with a Substitute hurts itself due to confusion or Jump Kick/Hi Jump Kick recoil and the target\";\n\t\t\t\t// if the move was a self-targeting move, the source is the same as the target. We need to check the opposing substitute\n\t\t\t\tconst foe = target.side.foe.active[0];\n\t\t\t\tif (foe?.volatiles['substitute']) {\n\t\t\t\t\tfoe.volatiles['substitute'].hp -= damage;\n\t\t\t\t\tif (foe.volatiles['substitute'].hp <= 0) {\n\t\t\t\t\t\tfoe.removeVolatile('substitute');\n\t\t\t\t\t\tfoe.subFainted = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.add('-activate', foe, 'Substitute', '[damage]');\n\t\t\t\t\t}\n\t\t\t\t\tthis.hint(hint + \" has a Substitute, the target's Substitute takes the damage.\");\n\t\t\t\t\treturn damage;\n\t\t\t\t} else {\n\t\t\t\t\tthis.hint(hint + \" does not have a Substitute there is no damage dealt.\");\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdamage = target.damage(damage, source, effect);\n\t\tswitch (effect.id) {\n\t\tcase 'strugglerecoil':\n\t\t\tthis.add('-damage', target, target.getHealth, '[from] recoil');\n\t\t\tbreak;\n\t\tcase 'confusion':\n\t\t\tthis.add('-damage', target, target.getHealth, '[from] confusion');\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthis.add('-damage', target, target.getHealth);\n\t\t\tbreak;\n\t\t}\n\t\tif (target.fainted) this.faint(target);\n\t\treturn damage;\n\t}\n\n\theal(damage: number, target?: Pokemon, source: Pokemon | null = null, effect: 'drain' | Effect | null = null) {\n\t\tif (this.event) {\n\t\t\ttarget ||= this.event.target;\n\t\t\tsource ||= this.event.source;\n\t\t\teffect ||= this.effect;\n\t\t}\n\t\tif (effect === 'drain') effect = this.dex.conditions.getByID(effect as ID);\n\t\tif (damage && damage <= 1) damage = 1;\n\t\tdamage = this.trunc(damage);\n\t\t// for things like Liquid Ooze, the Heal event still happens when nothing is healed.\n\t\tdamage = this.runEvent('TryHeal', target, source, effect, damage);\n\t\tif (!damage) return damage;\n\t\tif (!target?.hp) return false;\n\t\tif (!target.isActive) return false;\n\t\tif (target.hp >= target.maxhp) return false;\n\t\tconst finalDamage = target.heal(damage, source, effect);\n\t\tswitch (effect?.id) {\n\t\tcase 'leechseed':\n\t\tcase 'rest':\n\t\t\tthis.add('-heal', target, target.getHealth, '[silent]');\n\t\t\tbreak;\n\t\tcase 'drain':\n\t\t\tthis.add('-heal', target, target.getHealth, '[from] drain', `[of] ${source}`);\n\t\t\tbreak;\n\t\tcase 'wish':\n\t\t\tbreak;\n\t\tcase 'zpower':\n\t\t\tthis.add('-heal', target, target.getHealth, '[zeffect]');\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (!effect) break;\n\t\t\tif (effect.effectType === 'Move') {\n\t\t\t\tthis.add('-heal', target, target.getHealth);\n\t\t\t} else if (source && source !== target) {\n\t\t\t\tthis.add('-heal', target, target.getHealth, `[from] ${effect.fullname}`, `[of] ${source}`);\n\t\t\t} else {\n\t\t\t\tthis.add('-heal', target, target.getHealth, `[from] ${effect.fullname}`);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tthis.runEvent('Heal', target, source, effect, finalDamage);\n\t\treturn finalDamage;\n\t}\n\n\tchain(previousMod: number | number[], nextMod: number | number[]) {\n\t\t// previousMod or nextMod can be either a number or an array [numerator, denominator]\n\t\tif (Array.isArray(previousMod)) {\n\t\t\tpreviousMod = this.trunc(previousMod[0] * 4096 / previousMod[1]);\n\t\t} else {\n\t\t\tpreviousMod = this.trunc(previousMod * 4096);\n\t\t}\n\n\t\tif (Array.isArray(nextMod)) {\n\t\t\tnextMod = this.trunc(nextMod[0] * 4096 / nextMod[1]);\n\t\t} else {\n\t\t\tnextMod = this.trunc(nextMod * 4096);\n\t\t}\n\t\treturn ((previousMod * nextMod + 2048) >> 12) / 4096; // M'' = ((M * M') + 0x800) >> 12\n\t}\n\n\tchainModify(numerator: number | number[], denominator = 1) {\n\t\tconst previousMod = this.trunc(this.event.modifier * 4096);\n\n\t\tif (Array.isArray(numerator)) {\n\t\t\tdenominator = numerator[1];\n\t\t\tnumerator = numerator[0];\n\t\t}\n\t\tconst nextMod = this.trunc(numerator * 4096 / denominator);\n\t\tthis.event.modifier = ((previousMod * nextMod + 2048) >> 12) / 4096;\n\t}\n\n\tmodify(value: number, numerator: number | number[], denominator = 1) {\n\t\t// You can also use:\n\t\t// modify(value, [numerator, denominator])\n\t\t// modify(value, fraction) - assuming you trust JavaScript's floating-point handler\n\t\tif (Array.isArray(numerator)) {\n\t\t\tdenominator = numerator[1];\n\t\t\tnumerator = numerator[0];\n\t\t}\n\t\tconst tr = this.trunc;\n\t\tconst modifier = tr(numerator * 4096 / denominator);\n\t\treturn tr((tr(value * modifier) + 2048 - 1) / 4096);\n\t}\n\n\t/** Given a table of base stats and a pokemon set, return the actual stats. */\n\tspreadModify(baseStats: StatsTable, set: PokemonSet): StatsTable {\n\t\tconst modStats: SparseStatsTable = { atk: 10, def: 10, spa: 10, spd: 10, spe: 10 };\n\t\tconst tr = this.trunc;\n\t\tlet statName: keyof StatsTable;\n\t\tfor (statName in modStats) {\n\t\t\tconst stat = baseStats[statName];\n\t\t\tmodStats[statName] = tr(tr(2 * stat + set.ivs[statName] + tr(set.evs[statName] / 4)) * set.level / 100 + 5);\n\t\t}\n\t\tif ('hp' in baseStats) {\n\t\t\tconst stat = baseStats['hp'];\n\t\t\tmodStats['hp'] = tr(tr(2 * stat + set.ivs['hp'] + tr(set.evs['hp'] / 4) + 100) * set.level / 100 + 10);\n\t\t}\n\t\treturn this.natureModify(modStats as StatsTable, set);\n\t}\n\n\tnatureModify(stats: StatsTable, set: PokemonSet): StatsTable {\n\t\t// Natures are calculated with 16-bit truncation.\n\t\t// This only affects Eternatus-Eternamax in Pure Hackmons.\n\t\tconst tr = this.trunc;\n\t\tconst nature = this.dex.natures.get(set.nature);\n\t\tlet s: StatIDExceptHP;\n\t\tif (nature.plus) {\n\t\t\ts = nature.plus;\n\t\t\tconst stat = this.ruleTable.has('overflowstatmod') ? Math.min(stats[s], 595) : stats[s];\n\t\t\tstats[s] = tr(tr(stat * 110, 16) / 100);\n\t\t}\n\t\tif (nature.minus) {\n\t\t\ts = nature.minus;\n\t\t\tconst stat = this.ruleTable.has('overflowstatmod') ? Math.min(stats[s], 728) : stats[s];\n\t\t\tstats[s] = tr(tr(stat * 90, 16) / 100);\n\t\t}\n\t\treturn stats;\n\t}\n\n\tfinalModify(relayVar: number) {\n\t\trelayVar = this.modify(relayVar, this.event.modifier);\n\t\tthis.event.modifier = 1;\n\t\treturn relayVar;\n\t}\n\n\tgetCategory(move: string | Move) {\n\t\treturn this.dex.moves.get(move).category || 'Physical';\n\t}\n\n\trandomizer(baseDamage: number) {\n\t\tconst tr = this.trunc;\n\t\treturn tr(tr(baseDamage * (100 - this.random(16))) / 100);\n\t}\n\n\t/**\n\t * Returns whether a proposed target for a move is valid.\n\t */\n\tvalidTargetLoc(targetLoc: number, source: Pokemon, targetType: string) {\n\t\tif (targetLoc === 0) return true;\n\t\tconst numSlots = this.activePerHalf;\n\t\tconst sourceLoc = source.getLocOf(source);\n\t\tif (Math.abs(targetLoc) > numSlots) return false;\n\t\tconst isSelf = (sourceLoc === targetLoc);\n\t\tconst isFoe = (this.gameType === 'freeforall' ? !isSelf : targetLoc > 0);\n\t\tconst acrossFromTargetLoc = -(numSlots + 1 - targetLoc);\n\t\tconst isAdjacent = (targetLoc > 0 ?\n\t\t\tMath.abs(acrossFromTargetLoc - sourceLoc) <= 1 :\n\t\t\tMath.abs(targetLoc - sourceLoc) === 1);\n\n\t\tif (this.gameType === 'freeforall' && targetType === 'adjacentAlly') {\n\t\t\t// moves targeting one ally can instead target foes in Battle Royal\n\t\t\treturn isAdjacent;\n\t\t}\n\n\t\tswitch (targetType) {\n\t\tcase 'randomNormal':\n\t\tcase 'scripted':\n\t\tcase 'normal':\n\t\t\treturn isAdjacent;\n\t\tcase 'adjacentAlly':\n\t\t\treturn isAdjacent && !isFoe;\n\t\tcase 'adjacentAllyOrSelf':\n\t\t\treturn isAdjacent && !isFoe || isSelf;\n\t\tcase 'adjacentFoe':\n\t\t\treturn isAdjacent && isFoe;\n\t\tcase 'any':\n\t\t\treturn !isSelf;\n\t\t}\n\t\treturn false;\n\t}\n\n\tvalidTarget(target: Pokemon, source: Pokemon, targetType: string) {\n\t\treturn this.validTargetLoc(source.getLocOf(target), source, targetType);\n\t}\n\n\tgetTarget(pokemon: Pokemon, move: string | Move, targetLoc: number, originalTarget?: Pokemon) {\n\t\tmove = this.dex.moves.get(move);\n\n\t\tlet tracksTarget = move.tracksTarget;\n\t\t// Stalwart sets trackTarget in ModifyMove, but ModifyMove happens after getTarget, so\n\t\t// we need to manually check for Stalwart here\n\t\tif (pokemon.hasAbility(['stalwart', 'propellertail'])) tracksTarget = true;\n\t\tif (tracksTarget && originalTarget?.isActive) {\n\t\t\t// smart-tracking move's original target is on the field: target it\n\t\t\treturn originalTarget;\n\t\t}\n\n\t\t// banning Dragon Darts from directly targeting itself is done in side.ts, but\n\t\t// Dragon Darts can target itself if Ally Switch is used afterwards\n\t\tif (move.smartTarget) {\n\t\t\tconst curTarget = pokemon.getAtLoc(targetLoc);\n\t\t\treturn curTarget && !curTarget.fainted ? curTarget : this.getRandomTarget(pokemon, move);\n\t\t}\n\n\t\t// Fails if the target is the user and the move can't target its own position\n\t\tconst selfLoc = pokemon.getLocOf(pokemon);\n\t\tif (\n\t\t\t['adjacentAlly', 'any', 'normal'].includes(move.target) && targetLoc === selfLoc &&\n\t\t\t!pokemon.volatiles['twoturnmove'] && !pokemon.volatiles['iceball'] && !pokemon.volatiles['rollout']\n\t\t) {\n\t\t\treturn move.flags['futuremove'] ? pokemon : null;\n\t\t}\n\t\tif (move.target !== 'randomNormal' && this.validTargetLoc(targetLoc, pokemon, move.target)) {\n\t\t\tconst target = pokemon.getAtLoc(targetLoc);\n\t\t\tif (target?.fainted) {\n\t\t\t\tif (this.gameType === 'freeforall') {\n\t\t\t\t\t// Target is a fainted opponent in a free-for-all battle; attack shouldn't retarget\n\t\t\t\t\treturn target;\n\t\t\t\t}\n\t\t\t\tif (target.isAlly(pokemon)) {\n\t\t\t\t\tif (move.target === 'adjacentAllyOrSelf' && this.gen !== 5) {\n\t\t\t\t\t\treturn pokemon;\n\t\t\t\t\t}\n\t\t\t\t\t// Target is a fainted ally: attack shouldn't retarget\n\t\t\t\t\treturn target;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (target && !target.fainted) {\n\t\t\t\t// Target is unfainted: use selected target location\n\t\t\t\treturn target;\n\t\t\t}\n\n\t\t\t// Chosen target not valid,\n\t\t\t// retarget randomly with getRandomTarget\n\t\t}\n\t\treturn this.getRandomTarget(pokemon, move);\n\t}\n\n\tgetRandomTarget(pokemon: Pokemon, move: string | Move) {\n\t\t// A move was used without a chosen target\n\n\t\t// For instance: Metronome chooses Ice Beam. Since the user didn't\n\t\t// choose a target when choosing Metronome, Ice Beam's target must\n\t\t// be chosen randomly.\n\n\t\t// The target is chosen randomly from possible targets, EXCEPT that\n\t\t// moves that can target either allies or foes will only target foes\n\t\t// when used without an explicit target.\n\n\t\tmove = this.dex.moves.get(move);\n\t\tif (['self', 'all', 'allySide', 'allyTeam', 'adjacentAllyOrSelf'].includes(move.target)) {\n\t\t\treturn pokemon;\n\t\t} else if (move.target === 'adjacentAlly') {\n\t\t\tif (this.gameType === 'singles') return null;\n\t\t\tconst adjacentAllies = pokemon.adjacentAllies();\n\t\t\treturn adjacentAllies.length ? this.sample(adjacentAllies) : null;\n\t\t}\n\t\tif (this.gameType === 'singles') return pokemon.side.foe.active[0];\n\n\t\tif (this.activePerHalf > 2) {\n\t\t\tif (move.target === 'adjacentFoe' || move.target === 'normal' || move.target === 'randomNormal') {\n\t\t\t\t// even if a move can target an ally, auto-resolution will never make it target an ally\n\t\t\t\t// i.e. if both your opponents faint before you use Flamethrower, it will fail instead of targeting your ally\n\t\t\t\tconst adjacentFoes = pokemon.adjacentFoes();\n\t\t\t\tif (adjacentFoes.length) return this.sample(adjacentFoes);\n\t\t\t\t// no valid target at all, return slot directly across for any possible redirection\n\t\t\t\treturn pokemon.side.foe.active[pokemon.side.foe.active.length - 1 - pokemon.position];\n\t\t\t}\n\t\t}\n\t\treturn pokemon.side.randomFoe() || pokemon.side.foe.active[0];\n\t}\n\n\tcheckFainted() {\n\t\tfor (const side of this.sides) {\n\t\t\tfor (const pokemon of side.active) {\n\t\t\t\tif (pokemon.fainted) {\n\t\t\t\t\tpokemon.status = 'fnt' as ID;\n\t\t\t\t\tpokemon.switchFlag = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfaintMessages(lastFirst = false, forceCheck = false, checkWin = true) {\n\t\tif (this.ended) return;\n\t\tconst length = this.faintQueue.length;\n\t\tif (!length) {\n\t\t\tif (forceCheck && this.checkWin()) return true;\n\t\t\treturn false;\n\t\t}\n\t\tif (lastFirst) {\n\t\t\tthis.faintQueue.unshift(this.faintQueue[this.faintQueue.length - 1]);\n\t\t\tthis.faintQueue.pop();\n\t\t}\n\t\tlet faintQueueLeft, faintData;\n\t\twhile (this.faintQueue.length) {\n\t\t\tfaintQueueLeft = this.faintQueue.length;\n\t\t\tfaintData = this.faintQueue.shift()!;\n\t\t\tconst pokemon: Pokemon = faintData.target;\n\t\t\tif (!pokemon.fainted && this.runEvent('BeforeFaint', pokemon, faintData.source, faintData.effect)) {\n\t\t\t\tthis.add('faint', pokemon);\n\t\t\t\tif (pokemon.side.pokemonLeft) pokemon.side.pokemonLeft--;\n\t\t\t\tif (pokemon.side.totalFainted < 100) pokemon.side.totalFainted++;\n\t\t\t\tthis.runEvent('Faint', pokemon, faintData.source, faintData.effect);\n\t\t\t\tthis.singleEvent('End', pokemon.getAbility(), pokemon.abilityState, pokemon);\n\t\t\t\tthis.singleEvent('End', pokemon.getItem(), pokemon.itemState, pokemon);\n\t\t\t\tif (pokemon.regressionForme) {\n\t\t\t\t\t// before clearing volatiles\n\t\t\t\t\tpokemon.baseSpecies = this.dex.species.get(pokemon.set.species || pokemon.set.name);\n\t\t\t\t\tpokemon.baseAbility = toID(pokemon.set.ability);\n\t\t\t\t}\n\t\t\t\tpokemon.clearVolatile(false);\n\t\t\t\tpokemon.fainted = true;\n\t\t\t\tpokemon.illusion = null;\n\t\t\t\tpokemon.isActive = false;\n\t\t\t\tpokemon.isStarted = false;\n\t\t\t\tdelete pokemon.terastallized;\n\t\t\t\tif (pokemon.regressionForme) {\n\t\t\t\t\t// after clearing volatiles\n\t\t\t\t\tpokemon.details = pokemon.getUpdatedDetails();\n\t\t\t\t\tpokemon.regressionForme = false;\n\t\t\t\t}\n\t\t\t\tpokemon.side.faintedThisTurn = pokemon;\n\t\t\t\tif (this.faintQueue.length >= faintQueueLeft) checkWin = true;\n\t\t\t}\n\t\t}\n\n\t\tif (this.gen <= 1) {\n\t\t\t// in gen 1, fainting skips the rest of the turn\n\t\t\t// residuals don't exist in gen 1\n\t\t\tthis.queue.clear();\n\t\t\t// Fainting clears accumulated Bide damage\n\t\t\tfor (const pokemon of this.getAllActive()) {\n\t\t\t\tif (pokemon.volatiles['bide']?.damage) {\n\t\t\t\t\tpokemon.volatiles['bide'].damage = 0;\n\t\t\t\t\tthis.hint(\"Desync Clause Mod activated!\");\n\t\t\t\t\tthis.hint(\"In Gen 1, Bide's accumulated damage is reset to 0 when a Pokemon faints.\");\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (this.gen <= 3 && this.gameType === 'singles') {\n\t\t\t// in gen 3 or earlier, fainting in singles skips to residuals\n\t\t\tfor (const pokemon of this.getAllActive()) {\n\t\t\t\tif (this.gen <= 2) {\n\t\t\t\t\t// in gen 2, fainting skips moves only\n\t\t\t\t\tthis.queue.cancelMove(pokemon);\n\t\t\t\t} else {\n\t\t\t\t\t// in gen 3, fainting skips all moves and switches\n\t\t\t\t\tthis.queue.cancelAction(pokemon);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (checkWin && this.checkWin(faintData)) return true;\n\n\t\tif (faintData && length) {\n\t\t\tthis.runEvent('AfterFaint', faintData.target, faintData.source, faintData.effect, length);\n\t\t}\n\t\treturn false;\n\t}\n\n\tcheckWin(faintData?: Battle['faintQueue'][0]) {\n\t\tconst team1PokemonLeft = this.sides[0].pokemonLeft + (this.sides[0].allySide?.pokemonLeft || 0);\n\t\tconst team2PokemonLeft = this.sides[1].pokemonLeft + (this.sides[1].allySide?.pokemonLeft || 0);\n\t\tconst team3PokemonLeft = this.gameType === 'freeforall' && this.sides[2]!.pokemonLeft;\n\t\tconst team4PokemonLeft = this.gameType === 'freeforall' && this.sides[3]!.pokemonLeft;\n\t\tif (!team1PokemonLeft && !team2PokemonLeft && !team3PokemonLeft && !team4PokemonLeft) {\n\t\t\tthis.win(faintData && this.gen > 4 ? faintData.target.side : null);\n\t\t\treturn true;\n\t\t}\n\t\tfor (const side of this.sides) {\n\t\t\tif (!side.foePokemonLeft()) {\n\t\t\t\tthis.win(side);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\tgetActionSpeed(action: AnyObject) {\n\t\tif (action.choice === 'move') {\n\t\t\tlet move = action.move;\n\t\t\tif (action.zmove) {\n\t\t\t\tconst zMoveName = this.actions.getZMove(action.move, action.pokemon, true);\n\t\t\t\tif (zMoveName) {\n\t\t\t\t\tconst zMove = this.dex.getActiveMove(zMoveName);\n\t\t\t\t\tif (zMove.exists && zMove.isZ) {\n\t\t\t\t\t\tmove = zMove;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (action.maxMove) {\n\t\t\t\tconst maxMoveName = this.actions.getMaxMove(action.maxMove, action.pokemon);\n\t\t\t\tif (maxMoveName) {\n\t\t\t\t\tconst maxMove = this.actions.getActiveMaxMove(action.move, action.pokemon);\n\t\t\t\t\tif (maxMove.exists && maxMove.isMax) {\n\t\t\t\t\t\tmove = maxMove;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// take priority from the base move, so abilities like Prankster only apply once\n\t\t\t// (instead of compounding every time `getActionSpeed` is called)\n\t\t\tlet priority = this.dex.moves.get(move.id).priority;\n\t\t\t// Grassy Glide priority\n\t\t\tpriority = this.singleEvent('ModifyPriority', move, null, action.pokemon, null, null, priority);\n\t\t\tpriority = this.runEvent('ModifyPriority', action.pokemon, null, move, priority);\n\t\t\taction.priority = priority + action.fractionalPriority;\n\t\t\t// In Gen 6, Quick Guard blocks moves with artificially enhanced priority.\n\t\t\tif (this.gen > 5) action.move.priority = priority;\n\t\t}\n\n\t\tif (!action.pokemon) {\n\t\t\taction.speed = 1;\n\t\t} else {\n\t\t\taction.speed = action.pokemon.getActionSpeed();\n\t\t}\n\t}\n\n\trunAction(action: Action) {\n\t\tconst pokemonOriginalHP = action.pokemon?.hp;\n\t\tlet residualPokemon: (readonly [Pokemon, number])[] = [];\n\t\t// returns whether or not we ended in a callback\n\t\tswitch (action.choice) {\n\t\tcase 'start': {\n\t\t\tfor (const side of this.sides) {\n\t\t\t\tif (side.pokemonLeft) side.pokemonLeft = side.pokemon.length;\n\t\t\t}\n\n\t\t\tthis.add('start');\n\n\t\t\t// Change Zacian/Zamazenta into their Crowned formes\n\t\t\tfor (const pokemon of this.getAllPokemon()) {\n\t\t\t\tlet rawSpecies: Species | null = null;\n\t\t\t\tif (pokemon.species.id === 'zacian' && pokemon.item === 'rustedsword') {\n\t\t\t\t\trawSpecies = this.dex.species.get('Zacian-Crowned');\n\t\t\t\t} else if (pokemon.species.id === 'zamazenta' && pokemon.item === 'rustedshield') {\n\t\t\t\t\trawSpecies = this.dex.species.get('Zamazenta-Crowned');\n\t\t\t\t}\n\t\t\t\tif (!rawSpecies) continue;\n\t\t\t\tconst species = pokemon.setSpecies(rawSpecies);\n\t\t\t\tif (!species) continue;\n\t\t\t\tpokemon.baseSpecies = rawSpecies;\n\t\t\t\tpokemon.details = pokemon.getUpdatedDetails();\n\t\t\t\tpokemon.setAbility(species.abilities['0'], null, true);\n\t\t\t\tpokemon.baseAbility = pokemon.ability;\n\n\t\t\t\tconst behemothMove: { [k: string]: string } = {\n\t\t\t\t\t'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash',\n\t\t\t\t};\n\t\t\t\tconst ironHead = pokemon.baseMoves.indexOf('ironhead');\n\t\t\t\tif (ironHead >= 0) {\n\t\t\t\t\tconst move = this.dex.moves.get(behemothMove[rawSpecies.name]);\n\t\t\t\t\tpokemon.baseMoveSlots[ironHead] = {\n\t\t\t\t\t\tmove: move.name,\n\t\t\t\t\t\tid: move.id,\n\t\t\t\t\t\tpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,\n\t\t\t\t\t\tmaxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,\n\t\t\t\t\t\ttarget: move.target,\n\t\t\t\t\t\tdisabled: false,\n\t\t\t\t\t\tdisabledSource: '',\n\t\t\t\t\t\tused: false,\n\t\t\t\t\t};\n\t\t\t\t\tpokemon.moveSlots = pokemon.baseMoveSlots.slice();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.format.onBattleStart) this.format.onBattleStart.call(this);\n\t\t\tfor (const rule of this.ruleTable.keys()) {\n\t\t\t\tif ('+*-!'.includes(rule.charAt(0))) continue;\n\t\t\t\tconst subFormat = this.dex.formats.get(rule);\n\t\t\t\tif (subFormat.onBattleStart) subFormat.onBattleStart.call(this);\n\t\t\t}\n\n\t\t\tfor (const side of this.sides) {\n\t\t\t\tfor (let i = 0; i < side.active.length; i++) {\n\t\t\t\t\tif (!side.pokemonLeft) {\n\t\t\t\t\t\t// forfeited before starting\n\t\t\t\t\t\tside.active[i] = side.pokemon[i];\n\t\t\t\t\t\tside.active[i].fainted = true;\n\t\t\t\t\t\tside.active[i].hp = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.actions.switchIn(side.pokemon[i], i);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const pokemon of this.getAllPokemon()) {\n\t\t\t\tthis.singleEvent('Start', this.dex.conditions.getByID(pokemon.species.id), pokemon.speciesState, pokemon);\n\t\t\t}\n\t\t\tthis.midTurn = true;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'move':\n\t\t\tif (!action.pokemon.isActive) return false;\n\t\t\tif (action.pokemon.fainted) return false;\n\t\t\tthis.actions.runMove(action.move, action.pokemon, action.targetLoc, {\n\t\t\t\tsourceEffect: action.sourceEffect, zMove: action.zmove,\n\t\t\t\tmaxMove: action.maxMove, originalTarget: action.originalTarget,\n\t\t\t});\n\t\t\tbreak;\n\t\tcase 'megaEvo':\n\t\t\tthis.actions.runMegaEvo(action.pokemon);\n\t\t\tbreak;\n\t\tcase 'megaEvoX':\n\t\t\tthis.actions.runMegaEvoX?.(action.pokemon);\n\t\t\tbreak;\n\t\tcase 'megaEvoY':\n\t\t\tthis.actions.runMegaEvoY?.(action.pokemon);\n\t\t\tbreak;\n\t\tcase 'runDynamax':\n\t\t\taction.pokemon.addVolatile('dynamax');\n\t\t\taction.pokemon.side.dynamaxUsed = true;\n\t\t\tif (action.pokemon.side.allySide) action.pokemon.side.allySide.dynamaxUsed = true;\n\t\t\tbreak;\n\t\tcase 'terastallize':\n\t\t\tthis.actions.terastallize(action.pokemon);\n\t\t\tbreak;\n\t\tcase 'beforeTurnMove':\n\t\t\tif (!action.pokemon.isActive) return false;\n\t\t\tif (action.pokemon.fainted) return false;\n\t\t\tthis.debug('before turn callback: ' + action.move.id);\n\t\t\tconst target = this.getTarget(action.pokemon, action.move, action.targetLoc);\n\t\t\tif (!target) return false;\n\t\t\tif (!action.move.beforeTurnCallback) throw new Error(`beforeTurnMove has no beforeTurnCallback`);\n\t\t\taction.move.beforeTurnCallback.call(this, action.pokemon, target);\n\t\t\tbreak;\n\t\tcase 'priorityChargeMove':\n\t\t\tif (!action.pokemon.isActive) return false;\n\t\t\tif (action.pokemon.fainted) return false;\n\t\t\tthis.debug('priority charge callback: ' + action.move.id);\n\t\t\tif (!action.move.priorityChargeCallback) throw new Error(`priorityChargeMove has no priorityChargeCallback`);\n\t\t\taction.move.priorityChargeCallback.call(this, action.pokemon);\n\t\t\tbreak;\n\n\t\tcase 'event':\n\t\t\tthis.runEvent(action.event!, action.pokemon);\n\t\t\tbreak;\n\t\tcase 'team':\n\t\t\tif (action.index === 0) {\n\t\t\t\taction.pokemon.side.pokemon = [];\n\t\t\t}\n\t\t\taction.pokemon.side.pokemon.push(action.pokemon);\n\t\t\taction.pokemon.position = action.index;\n\t\t\t// we return here because the update event would crash since there are no active pokemon yet\n\t\t\treturn;\n\n\t\tcase 'pass':\n\t\t\treturn;\n\t\tcase 'instaswitch':\n\t\tcase 'switch':\n\t\t\tif (action.choice === 'switch' && action.pokemon.status) {\n\t\t\t\tthis.singleEvent('CheckShow', this.dex.abilities.getByID('naturalcure' as ID), null, action.pokemon);\n\t\t\t}\n\t\t\tif (this.actions.switchIn(action.target, action.pokemon.position, action.sourceEffect) === 'pursuitfaint') {\n\t\t\t\t// a pokemon fainted from Pursuit before it could switch\n\t\t\t\tif (this.gen <= 4) {\n\t\t\t\t\t// in gen 2-4, the switch still happens\n\t\t\t\t\tthis.hint(\"Previously chosen switches continue in Gen 2-4 after a Pursuit target faints.\");\n\t\t\t\t\taction.priority = -101;\n\t\t\t\t\tthis.queue.unshift(action);\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\t// in gen 5+, the switch is cancelled\n\t\t\t\t\tthis.hint(\"A Pokemon can't switch between when it runs out of HP and when it faints\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'revivalblessing':\n\t\t\taction.pokemon.side.pokemonLeft++;\n\t\t\tif (action.target.position < action.pokemon.side.active.length) {\n\t\t\t\tthis.queue.addChoice({\n\t\t\t\t\tchoice: 'instaswitch',\n\t\t\t\t\tpokemon: action.target,\n\t\t\t\t\ttarget: action.target,\n\t\t\t\t});\n\t\t\t}\n\t\t\taction.target.fainted = false;\n\t\t\taction.target.faintQueued = false;\n\t\t\taction.target.subFainted = false;\n\t\t\taction.target.status = '';\n\t\t\taction.target.hp = 1; // Needed so hp functions works\n\t\t\taction.target.sethp(action.target.maxhp / 2);\n\t\t\tthis.add('-heal', action.target, action.target.getHealth, '[from] move: Revival Blessing');\n\t\t\taction.pokemon.side.removeSlotCondition(action.pokemon, 'revivalblessing');\n\t\t\tbreak;\n\t\tcase 'runSwitch':\n\t\t\tthis.actions.runSwitch(action.pokemon);\n\t\t\tbreak;\n\t\tcase 'shift':\n\t\t\tif (!action.pokemon.isActive) return false;\n\t\t\tif (action.pokemon.fainted) return false;\n\t\t\tthis.swapPosition(action.pokemon, 1);\n\t\t\tbreak;\n\n\t\tcase 'beforeTurn':\n\t\t\tthis.eachEvent('BeforeTurn');\n\t\t\tbreak;\n\t\tcase 'residual':\n\t\t\tthis.add('');\n\t\t\tthis.clearActiveMove(true);\n\t\t\tthis.updateSpeed();\n\t\t\tresidualPokemon = this.getAllActive().map(pokemon => [pokemon, pokemon.getUndynamaxedHP()] as const);\n\t\t\tthis.fieldEvent('Residual');\n\t\t\tthis.add('upkeep');\n\t\t\tbreak;\n\t\t}\n\n\t\t// phazing (Roar, etc)\n\t\tfor (const side of this.sides) {\n\t\t\tfor (const pokemon of side.active) {\n\t\t\t\tif (pokemon.forceSwitchFlag) {\n\t\t\t\t\tif (pokemon.hp) this.actions.dragIn(pokemon.side, pokemon.position);\n\t\t\t\t\tpokemon.forceSwitchFlag = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.clearActiveMove();\n\n\t\t// fainting\n\n\t\tthis.faintMessages();\n\t\tif (this.ended) return true;\n\n\t\t// switching (fainted pokemon, U-turn, Baton Pass, etc)\n\n\t\tif (!this.queue.peek() || (this.gen <= 3 && ['move', 'residual'].includes(this.queue.peek()!.choice))) {\n\t\t\t// in gen 3 or earlier, switching in fainted pokemon is done after\n\t\t\t// every move, rather than only at the end of the turn.\n\t\t\tthis.checkFainted();\n\t\t} else if (['megaEvo', 'megaEvoX', 'megaEvoY'].includes(action.choice) && this.gen === 7) {\n\t\t\tthis.eachEvent('Update');\n\t\t\t// In Gen 7, the action order is recalculated for a Pok\u00E9mon that mega evolves.\n\t\t\tfor (const [i, queuedAction] of this.queue.list.entries()) {\n\t\t\t\tif (queuedAction.pokemon === action.pokemon && queuedAction.choice === 'move') {\n\t\t\t\t\tthis.queue.list.splice(i, 1);\n\t\t\t\t\tqueuedAction.mega = 'done';\n\t\t\t\t\tthis.queue.insertChoice(queuedAction, true);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if (this.queue.peek()?.choice === 'instaswitch') {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.gen >= 5 && action.choice !== 'start') {\n\t\t\tthis.eachEvent('Update');\n\t\t\tfor (const [pokemon, originalHP] of residualPokemon) {\n\t\t\t\tconst maxhp = pokemon.getUndynamaxedHP(pokemon.maxhp);\n\t\t\t\tif (pokemon.hp && pokemon.getUndynamaxedHP() <= maxhp / 2 && originalHP > maxhp / 2) {\n\t\t\t\t\tthis.runEvent('EmergencyExit', pokemon);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (action.choice === 'runSwitch') {\n\t\t\tconst pokemon = action.pokemon;\n\t\t\tif (pokemon.hp && pokemon.hp <= pokemon.maxhp / 2 && pokemonOriginalHP! > pokemon.maxhp / 2) {\n\t\t\t\tthis.runEvent('EmergencyExit', pokemon);\n\t\t\t}\n\t\t}\n\n\t\tconst switches = this.sides.map(\n\t\t\tside => side.active.some(pokemon => pokemon && !!pokemon.switchFlag)\n\t\t);\n\n\t\tfor (let i = 0; i < this.sides.length; i++) {\n\t\t\tlet reviveSwitch = false; // Used to ignore the fake switch for Revival Blessing\n\t\t\tif (switches[i] && !this.canSwitch(this.sides[i])) {\n\t\t\t\tfor (const pokemon of this.sides[i].active) {\n\t\t\t\t\tif (this.sides[i].slotConditions[pokemon.position]['revivalblessing']) {\n\t\t\t\t\t\treviveSwitch = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tpokemon.switchFlag = false;\n\t\t\t\t}\n\t\t\t\tif (!reviveSwitch) switches[i] = false;\n\t\t\t} else if (switches[i]) {\n\t\t\t\tfor (const pokemon of this.sides[i].active) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tpokemon.hp && pokemon.switchFlag && pokemon.switchFlag !== 'revivalblessing' &&\n\t\t\t\t\t\t!pokemon.skipBeforeSwitchOutEventFlag\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.runEvent('BeforeSwitchOut', pokemon);\n\t\t\t\t\t\tpokemon.skipBeforeSwitchOutEventFlag = true;\n\t\t\t\t\t\tthis.faintMessages(); // Pokemon may have fainted in BeforeSwitchOut\n\t\t\t\t\t\tif (this.ended) return true;\n\t\t\t\t\t\tif (pokemon.fainted) {\n\t\t\t\t\t\t\tswitches[i] = this.sides[i].active.some(sidePokemon => sidePokemon && !!sidePokemon.switchFlag);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const playerSwitch of switches) {\n\t\t\tif (playerSwitch) {\n\t\t\t\tthis.makeRequest('switch');\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tif (this.gen < 5) this.eachEvent('Update');\n\n\t\tif (this.gen >= 8 && (this.queue.peek()?.choice === 'move' || this.queue.peek()?.choice === 'runDynamax')) {\n\t\t\t// In gen 8, speed is updated dynamically so update the queue's speed properties and sort it.\n\t\t\tthis.updateSpeed();\n\t\t\tfor (const queueAction of this.queue.list) {\n\t\t\t\tif (queueAction.pokemon) this.getActionSpeed(queueAction);\n\t\t\t}\n\t\t\tthis.queue.sort();\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Generally called at the beginning of a turn, to go through the\n\t * turn one action at a time.\n\t *\n\t * If there is a mid-turn decision (like U-Turn), this will return\n\t * and be called again later to resume the turn.\n\t */\n\tturnLoop() {\n\t\tthis.add('');\n\t\tthis.add('t:', Math.floor(Date.now() / 1000));\n\t\tif (this.requestState) this.requestState = '';\n\n\t\tif (!this.midTurn) {\n\t\t\tthis.queue.insertChoice({ choice: 'beforeTurn' });\n\t\t\tthis.queue.addChoice({ choice: 'residual' });\n\t\t\tthis.midTurn = true;\n\t\t}\n\n\t\tlet action;\n\t\twhile ((action = this.queue.shift())) {\n\t\t\tthis.runAction(action);\n\t\t\tif (this.requestState || this.ended) return;\n\t\t}\n\n\t\tthis.endTurn();\n\t\tthis.midTurn = false;\n\t\tthis.queue.clear();\n\t}\n\n\t/**\n\t * Takes a choice string passed from the client. Starts the next\n\t * turn if all required choices have been made.\n\t */\n\tchoose(sideid: SideID, input: string) {\n\t\tconst side = this.getSide(sideid);\n\n\t\tif (!side.choose(input)) {\n\t\t\tif (!side.choice.error) {\n\t\t\t\tside.emitChoiceError(`Unknown error for choice: ${input}. If you're not using a custom client, please report this as a bug.`);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!side.isChoiceDone()) {\n\t\t\tside.emitChoiceError(`Incomplete choice: ${input} - missing other pokemon`);\n\t\t\treturn false;\n\t\t}\n\t\tif (this.allChoicesDone()) this.commitChoices();\n\t\treturn true;\n\t}\n\n\t/**\n\t * Convenience method for easily making choices.\n\t */\n\tmakeChoices(...inputs: string[]) {\n\t\tif (inputs.length) {\n\t\t\tfor (const [i, input] of inputs.entries()) {\n\t\t\t\tif (input) this.sides[i].choose(input);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const side of this.sides) {\n\t\t\t\tside.autoChoose();\n\t\t\t}\n\t\t}\n\t\tthis.commitChoices();\n\t}\n\n\tcommitChoices() {\n\t\tthis.updateSpeed();\n\n\t\t// Sometimes you need to make switch choices mid-turn (e.g. U-turn,\n\t\t// fainting). When this happens, the rest of the turn is saved (and not\n\t\t// re-sorted), but the new switch choices are sorted and inserted before\n\t\t// the rest of the turn.\n\t\tconst oldQueue = this.queue.list;\n\t\tthis.queue.clear();\n\t\tif (!this.allChoicesDone()) throw new Error(\"Not all choices done\");\n\n\t\tfor (const side of this.sides) {\n\t\t\tconst choice = side.getChoice();\n\t\t\tif (choice) this.inputLog.push(`>${side.id} ${choice}`);\n\t\t}\n\t\tfor (const side of this.sides) {\n\t\t\tthis.queue.addChoice(side.choice.actions);\n\t\t}\n\t\tthis.clearRequest();\n\n\t\tthis.queue.sort();\n\t\tthis.queue.list.push(...oldQueue);\n\n\t\tthis.requestState = '';\n\t\tfor (const side of this.sides) {\n\t\t\tside.activeRequest = null;\n\t\t}\n\n\t\tthis.turnLoop();\n\n\t\t// workaround for tests\n\t\tif (this.log.length - this.sentLogPos > 500) this.sendUpdates();\n\t}\n\n\tundoChoice(sideid: SideID) {\n\t\tconst side = this.getSide(sideid);\n\t\tif (!side.requestState) return;\n\n\t\tif (side.choice.cantUndo) {\n\t\t\tside.emitChoiceError(`Can't undo: A trapping/disabling effect would cause undo to leak information`);\n\t\t\treturn;\n\t\t}\n\n\t\tside.clearChoice();\n\t}\n\n\t/**\n\t * returns true if both decisions are complete\n\t */\n\tallChoicesDone() {\n\t\tlet totalActions = 0;\n\t\tfor (const side of this.sides) {\n\t\t\tif (side.isChoiceDone()) {\n\t\t\t\tif (!this.supportCancel) side.choice.cantUndo = true;\n\t\t\t\ttotalActions++;\n\t\t\t}\n\t\t}\n\t\treturn totalActions >= this.sides.length;\n\t}\n\n\thint(hint: string, once?: boolean, side?: Side) {\n\t\tif (this.hints.has(hint)) return;\n\n\t\tif (side) {\n\t\t\tthis.addSplit(side.id, ['-hint', hint]);\n\t\t} else {\n\t\t\tthis.add('-hint', hint);\n\t\t}\n\n\t\tif (once) this.hints.add(hint);\n\t}\n\n\taddSplit(side: SideID, secret: Part[], shared?: Part[]) {\n\t\tthis.log.push(`|split|${side}`);\n\t\tthis.add(...secret);\n\t\tif (shared) {\n\t\t\tthis.add(...shared);\n\t\t} else {\n\t\t\tthis.log.push('');\n\t\t}\n\t}\n\n\tadd(...parts: (Part | (() => { side: SideID, secret: string, shared: string }))[]) {\n\t\tif (!parts.some(part => typeof part === 'function')) {\n\t\t\tthis.log.push(`|${parts.join('|')}`);\n\t\t\treturn;\n\t\t}\n\n\t\tlet side: SideID | null = null;\n\t\tconst secret = [];\n\t\tconst shared = [];\n\t\tfor (const part of parts) {\n\t\t\tif (typeof part === 'function') {\n\t\t\t\tconst split = part();\n\t\t\t\tif (side && side !== split.side) throw new Error(\"Multiple sides passed to add\");\n\t\t\t\tside = split.side;\n\t\t\t\tsecret.push(split.secret);\n\t\t\t\tshared.push(split.shared);\n\t\t\t} else {\n\t\t\t\tsecret.push(part);\n\t\t\t\tshared.push(part);\n\t\t\t}\n\t\t}\n\t\tthis.addSplit(side!, secret, shared);\n\t}\n\n\taddMove(...args: (string | number | Function | AnyObject)[]) {\n\t\tthis.lastMoveLine = this.log.length;\n\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\tthis.log.push(`|${args.join('|')}`);\n\t}\n\n\tattrLastMove(...args: (string | number | Function | AnyObject)[]) {\n\t\tif (this.lastMoveLine < 0) return;\n\t\tif (this.log[this.lastMoveLine].startsWith('|-anim|')) {\n\t\t\tif (args.includes('[still]')) {\n\t\t\t\tthis.log.splice(this.lastMoveLine, 1);\n\t\t\t\tthis.lastMoveLine = -1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else if (args.includes('[still]')) {\n\t\t\t// If no animation plays, the target should never be known\n\t\t\tconst parts = this.log[this.lastMoveLine].split('|');\n\t\t\tparts[4] = '';\n\t\t\tthis.log[this.lastMoveLine] = parts.join('|');\n\t\t}\n\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\tthis.log[this.lastMoveLine] += `|${args.join('|')}`;\n\t}\n\n\tretargetLastMove(newTarget: Pokemon) {\n\t\tif (this.lastMoveLine < 0) return;\n\t\tconst parts = this.log[this.lastMoveLine].split('|');\n\t\tparts[4] = newTarget.toString();\n\t\tthis.log[this.lastMoveLine] = parts.join('|');\n\t}\n\n\tdebug(activity: string) {\n\t\tif (this.debugMode) {\n\t\t\tthis.add('debug', activity);\n\t\t}\n\t}\n\n\tgetDebugLog() {\n\t\tconst channelMessages = extractChannelMessages(this.log.join('\\n'), [-1]);\n\t\treturn channelMessages[-1].join('\\n');\n\t}\n\n\tdebugError(activity: string) {\n\t\tthis.add('debug', activity);\n\t}\n\n\t// players\n\n\tgetTeam(options: PlayerOptions): PokemonSet[] {\n\t\tlet team = options.team;\n\t\tif (typeof team === 'string') team = Teams.unpack(team);\n\t\tif (team) return team;\n\n\t\tif (!options.seed) {\n\t\t\toptions.seed = PRNG.generateSeed();\n\t\t}\n\n\t\tif (!this.teamGenerator) {\n\t\t\tthis.teamGenerator = Teams.getGenerator(this.format, options.seed);\n\t\t} else {\n\t\t\tthis.teamGenerator.setSeed(options.seed);\n\t\t}\n\n\t\tteam = this.teamGenerator.getTeam(options);\n\t\treturn team as PokemonSet[];\n\t}\n\n\tshowOpenTeamSheets() {\n\t\tif (this.turn !== 0) return;\n\t\tfor (const side of this.sides) {\n\t\t\tconst team = side.pokemon.map(pokemon => {\n\t\t\t\tconst set = pokemon.set;\n\t\t\t\tconst newSet: PokemonSet = {\n\t\t\t\t\tname: '',\n\t\t\t\t\tspecies: set.species,\n\t\t\t\t\titem: set.item,\n\t\t\t\t\tability: set.ability,\n\t\t\t\t\tmoves: set.moves,\n\t\t\t\t\tnature: '',\n\t\t\t\t\tgender: pokemon.gender,\n\t\t\t\t\tevs: null!,\n\t\t\t\t\tivs: null!,\n\t\t\t\t\tlevel: set.level,\n\t\t\t\t};\n\t\t\t\tif (this.gen === 8) newSet.gigantamax = set.gigantamax;\n\t\t\t\tif (this.gen === 9) newSet.teraType = set.teraType;\n\t\t\t\t// Only display Hidden Power type if the Pokemon has Hidden Power\n\t\t\t\t// This is based on how team sheets were written in past VGC formats\n\t\t\t\tif (set.moves.some(m => this.dex.moves.get(m).id === 'hiddenpower')) newSet.hpType = set.hpType;\n\t\t\t\t// This is done so the client doesn't flag Zacian/Zamazenta as illusions\n\t\t\t\t// when they use their signature move\n\t\t\t\tif ((toID(set.species) === 'zacian' && toID(set.item) === 'rustedsword') ||\n\t\t\t\t\t(toID(set.species) === 'zamazenta' && toID(set.item) === 'rustedshield')) {\n\t\t\t\t\tnewSet.species = Dex.species.get(set.species + 'crowned').name;\n\t\t\t\t\tconst crowned: { [k: string]: string } = {\n\t\t\t\t\t\t'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash',\n\t\t\t\t\t};\n\t\t\t\t\tconst ironHead = set.moves.map(toID).indexOf('ironhead' as ID);\n\t\t\t\t\tif (ironHead >= 0) {\n\t\t\t\t\t\tnewSet.moves[ironHead] = crowned[newSet.species];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn newSet;\n\t\t\t});\n\n\t\t\tthis.add('showteam', side.id, Teams.pack(team));\n\t\t}\n\t}\n\n\tsetPlayer(slot: SideID, options: PlayerOptions) {\n\t\tlet side;\n\t\tlet didSomething = true;\n\t\tconst slotNum = parseInt(slot[1]) - 1;\n\t\tif (!this.sides[slotNum]) {\n\t\t\t// create player\n\t\t\tconst team = this.getTeam(options);\n\t\t\tside = new Side(options.name || `Player ${slotNum + 1}`, this, slotNum, team);\n\t\t\tif (options.avatar) side.avatar = `${options.avatar}`;\n\t\t\tthis.sides[slotNum] = side;\n\t\t} else {\n\t\t\t// edit player\n\t\t\tside = this.sides[slotNum];\n\t\t\tdidSomething = false;\n\t\t\tif (options.name && side.name !== options.name) {\n\t\t\t\tside.name = options.name;\n\t\t\t\tdidSomething = true;\n\t\t\t}\n\t\t\tif (options.avatar && side.avatar !== `${options.avatar}`) {\n\t\t\t\tside.avatar = `${options.avatar}`;\n\t\t\t\tdidSomething = true;\n\t\t\t}\n\t\t\tif (options.team) throw new Error(`Player ${slot} already has a team!`);\n\t\t}\n\t\tif (options.team && typeof options.team !== 'string') {\n\t\t\toptions.team = Teams.pack(options.team);\n\t\t}\n\t\tif (!didSomething) return;\n\t\tthis.inputLog.push(`>player ${slot} ` + JSON.stringify(options));\n\t\tthis.add('player', side.id, side.name, side.avatar, options.rating || '');\n\n\t\t// Start the battle if it's ready to start\n\t\tif (this.sides.every(playerSide => !!playerSide) && !this.started) this.start();\n\t}\n\n\t/** @deprecated */\n\tjoin(slot: SideID, name: string, avatar: string, team: PokemonSet[] | string | null) {\n\t\tthis.setPlayer(slot, { name, avatar, team });\n\t\treturn this.getSide(slot);\n\t}\n\n\tsendUpdates() {\n\t\tif (this.sentLogPos >= this.log.length) return;\n\t\tthis.send('update', this.log.slice(this.sentLogPos));\n\t\tthis.sentLogPos = this.log.length;\n\n\t\tif (!this.sentEnd && this.ended) {\n\t\t\tconst log = {\n\t\t\t\twinner: this.winner,\n\t\t\t\tseed: this.prngSeed,\n\t\t\t\tturns: this.turn,\n\t\t\t\tp1: this.sides[0].name,\n\t\t\t\tp2: this.sides[1].name,\n\t\t\t\tp3: this.sides[2]?.name,\n\t\t\t\tp4: this.sides[3]?.name,\n\t\t\t\tp1team: this.sides[0].team,\n\t\t\t\tp2team: this.sides[1].team,\n\t\t\t\tp3team: this.sides[2]?.team,\n\t\t\t\tp4team: this.sides[3]?.team,\n\t\t\t\tscore: [this.sides[0].pokemonLeft, this.sides[1].pokemonLeft],\n\t\t\t\tinputLog: this.inputLog,\n\t\t\t};\n\t\t\tif (this.sides[2]) {\n\t\t\t\tlog.score.push(this.sides[2].pokemonLeft);\n\t\t\t} else {\n\t\t\t\tdelete log.p3;\n\t\t\t\tdelete log.p3team;\n\t\t\t}\n\t\t\tif (this.sides[3]) {\n\t\t\t\tlog.score.push(this.sides[3].pokemonLeft);\n\t\t\t} else {\n\t\t\t\tdelete log.p4;\n\t\t\t\tdelete log.p4team;\n\t\t\t}\n\t\t\tthis.send('end', JSON.stringify(log));\n\t\t\tthis.sentEnd = true;\n\t\t}\n\t}\n\n\tgetSide(sideid: SideID): Side {\n\t\treturn this.sides[parseInt(sideid[1]) - 1];\n\t}\n\n\t/**\n\t * Currently, we treat Team Preview as turn 0, but the games start counting their turns at turn 0\n\t * There is also overflow that occurs in Gen 8+ that affects moves like Wish / Future Sight\n\t * https://www.smogon.com/forums/threads/10352797\n\t */\n\tgetOverflowedTurnCount(): number {\n\t\treturn this.gen >= 8 ? (this.turn - 1) % 256 : this.turn - 1;\n\t}\n\n\tinitEffectState(obj: Partial<EffectState>, effectOrder?: number): EffectState {\n\t\tif (!obj.id) obj.id = '';\n\t\tif (effectOrder !== undefined) {\n\t\t\tobj.effectOrder = effectOrder;\n\t\t} else if (obj.id && obj.target && (!(obj.target instanceof Pokemon) || obj.target.isActive)) {\n\t\t\tobj.effectOrder = this.effectOrder++;\n\t\t} else {\n\t\t\tobj.effectOrder = 0;\n\t\t}\n\t\treturn obj as EffectState;\n\t}\n\n\tclearEffectState(state: EffectState) {\n\t\tstate.id = '';\n\t\tfor (const k in state) {\n\t\t\tif (k === 'id' || k === 'target') {\n\t\t\t\tcontinue;\n\t\t\t} else if (k === 'effectOrder') {\n\t\t\t\tstate.effectOrder = 0;\n\t\t\t} else {\n\t\t\t\tdelete state[k];\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy() {\n\t\t// deallocate ourself\n\n\t\t// deallocate children and get rid of references to them\n\t\tthis.field.destroy();\n\t\t(this as any).field = null!;\n\n\t\tfor (let i = 0; i < this.sides.length; i++) {\n\t\t\tif (this.sides[i]) {\n\t\t\t\tthis.sides[i].destroy();\n\t\t\t\tthis.sides[i] = null!;\n\t\t\t}\n\t\t}\n\t\tfor (const action of this.queue.list) {\n\t\t\tdelete (action as any).pokemon;\n\t\t}\n\n\t\tthis.queue.battle = null!;\n\t\tthis.queue = null!;\n\t\t// in case the garbage collector really sucks, at least deallocate the log\n\t\t(this as any).log = [];\n\t}\n}\n"],
"mappings": "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",
"names": []
}