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