{ "version": 3, "sources": ["../../sim/state.ts"], "sourcesContent": ["/**\n * Simulator State\n * Pokemon Showdown - http://pokemonshowdown.com/\n *\n * Helper functions for serializing Battle instances to JSON and back.\n *\n * (You might also consider using input logs instead.)\n *\n * @license MIT\n */\n\nimport { Battle } from './battle';\nimport { Dex } from './dex';\nimport { Field } from './field';\nimport { Pokemon } from './pokemon';\nimport { PRNG } from './prng';\nimport { type Choice, Side } from './side';\n\n// The simulator supports up to 24 different Pokemon on a team. Serialization\n// uses letters instead of numbers to indicate indices/positions, but where\n// the simulator only gives a position to active Pokemon, serialization\n// uses letters for every Pokemon on a team. Active pokemon will still\n// have the same letter as their position would indicate, but non-active\n// team members are filled in with subsequent letters.\nconst POSITIONS = 'abcdefghijklmnopqrstuvwx';\n\n// Several types we serialize as 'references' in the form '[Type]' because\n// they are either circular or they are (or at least, should be) immutable\n// and thus can simply be reconsituted as needed.\n// NOTE: Species is not strictly immutable as some OM formats rely on an\n// onModifySpecies event - deserialization is not possible for such formats.\ntype Referable = Battle | Field | Side | Pokemon | Condition | Ability | Item | Move | Species;\n\n// Certain fields are either redundant (transient caches, constants, duplicate\n// information) or require special treatment. These sets contain the specific\n// keys which we skip during default (de)serialization and (the keys which)\n// need special treatment from these sets are then handled manually.\n\nconst BATTLE = new Set([\n\t'dex', 'gen', 'ruleTable', 'id', 'log', 'inherit', 'format', 'teamGenerator',\n\t'HIT_SUBSTITUTE', 'NOT_FAIL', 'FAIL', 'SILENT_FAIL', 'field', 'sides', 'prng', 'hints',\n\t'deserialized', 'queue', 'actions',\n]);\nconst FIELD = new Set(['id', 'battle']);\nconst SIDE = new Set(['battle', 'team', 'pokemon', 'choice', 'activeRequest']);\nconst POKEMON = new Set([\n\t'side', 'battle', 'set', 'name', 'fullname', 'id',\n\t'happiness', 'level', 'pokeball', 'baseMoveSlots',\n]);\nconst CHOICE = new Set(['switchIns']);\nconst ACTIVE_MOVE = new Set(['move']);\n\nexport const State = new class {\n\t// REFERABLE is used to determine which objects are of the Referable type by\n\t// comparing their constructors. Unfortunately, we need to set this dynamically\n\t// due to circular module dependencies on Battle and Field instead\n\t// of simply initializing it as a const. See isReferable for where this\n\t// gets lazily created on demand.\n\tREFERABLE?: Set;\n\n\tserializeBattle(battle: Battle): /* Battle */ AnyObject {\n\t\tconst state: /* Battle */ AnyObject = this.serialize(battle, BATTLE, battle);\n\t\tstate.field = this.serializeField(battle.field);\n\t\tstate.sides = new Array(battle.sides.length);\n\t\tfor (const [i, side] of battle.sides.entries()) {\n\t\t\tstate.sides[i] = this.serializeSide(side);\n\t\t}\n\t\tstate.prng = battle.prng.getSeed();\n\t\tstate.hints = Array.from(battle.hints);\n\t\t// We treat log specially because we only set it back on Battle after everything\n\t\t// else has been deserialized to avoid anything accidentally `add`-ing to it.\n\t\tstate.log = battle.log;\n\t\tstate.queue = this.serializeWithRefs(battle.queue.list, battle);\n\t\tstate.formatid = battle.format.id;\n\t\treturn state;\n\t}\n\n\t// Deserialization can only really be done on the root Battle object as\n\t// the leaf nodes like Side or Pokemon contain backreferences to Battle\n\t// but don't contain the information to fill it in because the cycles in\n\t// the graph have been serialized as references. Once deserialzized, the\n\t// Battle can then be restarted (and provided with a `send` function for\n\t// receiving updates).\n\tdeserializeBattle(serialized: string | /* Battle */ AnyObject): Battle {\n\t\tconst state: /* Battle */ AnyObject =\n\t\t\ttypeof serialized === 'string' ? JSON.parse(serialized) : serialized;\n\t\tconst options = {\n\t\t\tformatid: state.formatid,\n\t\t\tseed: state.prngSeed,\n\t\t\trated: state.rated,\n\t\t\tdebug: state.debugMode,\n\t\t\t// We need to tell the Battle that we're creating that it's been\n\t\t\t// deserialized so that it allows us to populate it correctly and\n\t\t\t// doesn't attempt to start playing out until we're ready.\n\t\t\tdeserialized: true,\n\t\t\tstrictChoices: state.strictChoices,\n\t\t};\n\t\tfor (const side of state.sides) {\n\t\t\t// When we instantiate the Battle again we need the pokemon to be in\n\t\t\t// the correct order they were in at the start of the Battle which was\n\t\t\t// serialized. See serializeSide below for an explanation about the\n\t\t\t// encoding format used deserializeSide for where we reorder the Side's\n\t\t\t// pokemon to match their ordering at the point of serialization.\n\t\t\tconst team = side.team.split(side.team.length > 9 ? ',' : '');\n\t\t\t// @ts-expect-error index signature\n\t\t\toptions[side.id] = {\n\t\t\t\tname: side.name,\n\t\t\t\tavatar: side.avatar,\n\t\t\t\tteam: team.map((p: string) => side.pokemon[Number(p) - 1].set),\n\t\t\t};\n\t\t}\n\t\t// We create the Battle, allowing it to instantiate the Field/Side/Pokemon\n\t\t// objects for us. The objects it creates will be incorrect, but we descend\n\t\t// down through the fields and repopulate all of the objects with the\n\t\t// correct state afterwards.\n\t\tconst battle = new Battle(options);\n\t\t// Calling `new Battle(...)` means side.pokemon is ordered to match what it\n\t\t// was at the start of the battle (state.team), but we need to order the Pokemon\n\t\t// back in their correct order based on how the battle has progressed. We need\n\t\t// do to this before making any deserialization calls so that `fromRef` will\n\t\t// be correct.\n\t\tfor (const [i, s] of state.sides.entries()) {\n\t\t\tconst side = battle.sides[i];\n\t\t\tconst ordered = new Array(side.pokemon.length);\n\t\t\tconst team = s.team.split(s.team.length > 9 ? ',' : '');\n\t\t\tfor (const [j, pos] of team.entries()) {\n\t\t\t\tordered[Number(pos) - 1] = side.pokemon[j];\n\t\t\t}\n\t\t\tside.pokemon = ordered;\n\t\t}\n\t\tthis.deserialize(state, battle, BATTLE, battle);\n\t\tthis.deserializeField(state.field, battle.field);\n\t\tlet activeRequests = false;\n\t\tfor (const [i, side] of state.sides.entries()) {\n\t\t\tthis.deserializeSide(side, battle.sides[i]);\n\t\t\tactiveRequests = activeRequests || side.activeRequest === undefined;\n\t\t}\n\t\t// Since battle.getRequests depends on the state of each side we can't combine\n\t\t// this loop with the one above which deserializes the sides. We also only do this\n\t\t// if there are any active requests, not only to avoid have to recompute request\n\t\t// states we wouldnt be using, but also because battle.getRequests will mutate\n\t\t// state on occasion (eg. `pokemon.getMoves` sets `pokemon.trapped = true` if locked).\n\t\tif (activeRequests) {\n\t\t\tconst requests = battle.getRequests(battle.requestState);\n\t\t\tfor (const [i, side] of state.sides.entries()) {\n\t\t\t\tbattle.sides[i].activeRequest = side.activeRequest === null ? null : requests[i];\n\t\t\t}\n\t\t}\n\t\tbattle.prng = new PRNG(state.prng);\n\t\tconst queue = this.deserializeWithRefs(state.queue, battle);\n\t\tbattle.queue.list = queue;\n\t\t(battle as any).hints = new Set(state.hints);\n\t\t(battle as any).log = state.log;\n\t\treturn battle;\n\t}\n\n\t// Direct comparsions of serialized state will be flakey as the timestamp\n\t// protocol message |t:| can diverge between two different runs over the same state.\n\t// State must first be normalized before it is comparable.\n\tnormalize(state: AnyObject) {\n\t\tstate.log = this.normalizeLog(state.log);\n\t\treturn state;\n\t}\n\n\tnormalizeLog(log?: null | string | string[]) {\n\t\tif (!log) return log;\n\t\tconst normalized = (typeof log === 'string' ? log.split('\\n') : log).map(line =>\n\t\t\tline.startsWith(`|t:|`) ? `|t:|` : line);\n\t\treturn (typeof log === 'string' ? normalized.join('\\n') : normalized);\n\t}\n\n\tserializeField(field: Field): /* Field */ AnyObject {\n\t\treturn this.serialize(field, FIELD, field.battle);\n\t}\n\n\tdeserializeField(state: /* Field */ AnyObject, field: Field) {\n\t\tthis.deserialize(state, field, FIELD, field.battle);\n\t}\n\n\tserializeSide(side: Side): /* Side */ AnyObject {\n\t\tconst state: /* Side */ AnyObject = this.serialize(side, SIDE, side.battle);\n\t\tstate.pokemon = new Array(side.pokemon.length);\n\t\tconst team = new Array(side.pokemon.length);\n\t\tfor (const [i, pokemon] of side.pokemon.entries()) {\n\t\t\tstate.pokemon[i] = this.serializePokemon(pokemon);\n\t\t\tteam[side.team.indexOf(pokemon.set)] = i + 1;\n\t\t}\n\t\t// We encode the team such that it could be used as a valid `/team` command\n\t\t// during decoding to transform the current ordering of the serialized Side's\n\t\t// pokemon array into the original team ordering at the start of the battle.\n\t\t// This is *not* the same as the original `/team` command used to order the\n\t\t// pokemon in team preview, but this encoding results in the most intuitive\n\t\t// and readable debugging of the raw JSON, so we're willing to add a small\n\t\t// amount of complexity to the encoding/decoding process to accommodate this.\n\t\tstate.team = team.join(team.length > 9 ? ',' : '');\n\t\tstate.choice = this.serializeChoice(side.choice, side.battle);\n\t\t// If activeRequest is null we encode it as a tombstone indicator to ensure\n\t\t// that during serialization when we recompute the activeRequest we don't turn\n\t\t// `activeRequest = null` into `activeRequest = { wait: true, ... }`.\n\t\tif (side.activeRequest === null) state.activeRequest = null;\n\t\treturn state;\n\t}\n\n\tdeserializeSide(state: /* Side */ AnyObject, side: Side) {\n\t\tthis.deserialize(state, side, SIDE, side.battle);\n\t\tfor (const [i, pokemon] of state.pokemon.entries()) {\n\t\t\tthis.deserializePokemon(pokemon, side.pokemon[i]);\n\t\t}\n\t\tthis.deserializeChoice(state.choice, side.choice, side.battle);\n\t}\n\n\tserializePokemon(pokemon: Pokemon): /* Pokemon */ AnyObject {\n\t\tconst state: /* Pokemon */ AnyObject = this.serialize(pokemon, POKEMON, pokemon.battle);\n\t\tstate.set = pokemon.set;\n\t\t// Only serialize the baseMoveSlots if they differ from moveSlots. We could get fancy and\n\t\t// only serialize the diff and its index but thats overkill for a pretty niche case anyway.\n\t\tif (pokemon.baseMoveSlots.length !== pokemon.moveSlots.length ||\n\t\t\t!pokemon.baseMoveSlots.every((ms, i) => ms === pokemon.moveSlots[i])) {\n\t\t\tstate.baseMoveSlots = this.serializeWithRefs(pokemon.baseMoveSlots, pokemon.battle);\n\t\t}\n\t\treturn state;\n\t}\n\n\tdeserializePokemon(state: /* Pokemon */ AnyObject, pokemon: Pokemon) {\n\t\tthis.deserialize(state, pokemon, POKEMON, pokemon.battle);\n\t\t(pokemon as any).set = state.set;\n\t\t// baseMoveSlots and moveSlots need to point to the same objects (ie. identity, not equality).\n\t\t// If we serialized the baseMoveSlots, replace any that match moveSlots to preserve the\n\t\t// identity relationship requirement.\n\t\tlet baseMoveSlots;\n\t\tif (state.baseMoveSlots) {\n\t\t\tbaseMoveSlots = this.deserializeWithRefs(state.baseMoveSlots, pokemon.battle);\n\t\t\tfor (const [i, baseMoveSlot] of baseMoveSlots.entries()) {\n\t\t\t\tconst moveSlot = pokemon.moveSlots[i];\n\t\t\t\tif (moveSlot.id === baseMoveSlot.id && !moveSlot.virtual) {\n\t\t\t\t\tbaseMoveSlots[i] = moveSlot;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbaseMoveSlots = pokemon.moveSlots.slice();\n\t\t}\n\t\t(pokemon as any).baseMoveSlots = baseMoveSlots;\n\t\tif (state.showCure === undefined) pokemon.showCure = undefined;\n\t}\n\n\tserializeChoice(choice: Choice, battle: Battle): /* Choice */ AnyObject {\n\t\tconst state: /* Choice */ AnyObject = this.serialize(choice, CHOICE, battle);\n\t\tstate.switchIns = Array.from(choice.switchIns);\n\t\treturn state;\n\t}\n\n\tdeserializeChoice(state: /* Choice */ AnyObject, choice: Choice, battle: Battle) {\n\t\tthis.deserialize(state, choice, CHOICE, battle);\n\t\tchoice.switchIns = new Set(state.switchIns);\n\t}\n\n\t// Simply looking for a 'hit' field to determine if an object is an ActiveMove or not seems\n\t// pretty fragile, but its no different than what the simulator is doing. We go further and\n\t// also check if the object has an 'id', as that's what we will intrepret as the Move.\n\tisActiveMove(obj: AnyObject): obj is ActiveMove {\n\t\treturn obj.hasOwnProperty('hit') && (obj.hasOwnProperty('id') || obj.hasOwnProperty('move'));\n\t}\n\n\t// ActiveMove is somewhat problematic (#5415) as it sometimes extends a Move and adds on\n\t// some mutable fields. We'd like to avoid displaying all the readonly fields of Move\n\t// (which in theory should not be changed by the ActiveMove...), so we collapse them\n\t// into a 'move: [Move:...]' reference. If isActiveMove returns a false positive *and*\n\t// and object contains an 'id' field matching a Move *and* it contains fields with the\n\t// same name as said Move then we'll miss them during serialization and won't\n\t// deserialize properly. This is unlikely to be the case, and would probably indicate\n\t// a bug in the simulator if it ever happened, but if not, the isActiveMove check can\n\t// be extended.\n\tserializeActiveMove(move: ActiveMove, battle: Battle): /* ActiveMove */ AnyObject {\n\t\tconst base = battle.dex.moves.get(move.id);\n\t\tconst skip = new Set([...ACTIVE_MOVE]);\n\t\tfor (const [key, value] of Object.entries(base)) {\n\t\t\t// This should really be a deepEquals check to see if anything on ActiveMove was\n\t\t\t// modified from the base Move, but that ends up being expensive and mostly unnecessary\n\t\t\t// as ActiveMove currently only mutates its simple fields (eg. `type`, `target`) anyway.\n\t\t\t// @ts-expect-error index signature\n\t\t\tif (typeof value === 'object' || move[key] === value) skip.add(key);\n\t\t}\n\t\tconst state: /* ActiveMove */ AnyObject = this.serialize(move, skip, battle);\n\t\tstate.move = `[Move:${move.id}]`;\n\t\treturn state;\n\t}\n\n\tdeserializeActiveMove(state: /* ActiveMove */ AnyObject, battle: Battle): ActiveMove {\n\t\tconst move = battle.dex.getActiveMove(this.fromRef(state.move, battle)! as Move);\n\t\tthis.deserialize(state, move, ACTIVE_MOVE, battle);\n\t\treturn move;\n\t}\n\n\tserializeWithRefs(obj: unknown, battle: Battle): unknown {\n\t\tswitch (typeof obj) {\n\t\tcase 'function':\n\t\t\treturn undefined; // elide functions\n\t\tcase 'undefined':\n\t\tcase 'boolean':\n\t\tcase 'number':\n\t\tcase 'string':\n\t\t\treturn obj;\n\t\tcase 'object':\n\t\t\tif (obj === null) return null;\n\t\t\tif (Array.isArray(obj)) {\n\t\t\t\tconst arr = new Array(obj.length);\n\t\t\t\tfor (const [i, o] of obj.entries()) {\n\t\t\t\t\tarr[i] = this.serializeWithRefs(o, battle);\n\t\t\t\t}\n\t\t\t\treturn arr;\n\t\t\t}\n\n\t\t\tif (this.isActiveMove(obj)) return this.serializeActiveMove(obj, battle);\n\t\t\tif (this.isReferable(obj)) return this.toRef(obj);\n\t\t\tif (obj.constructor !== Object) {\n\t\t\t\t// If we're getting this error, some 'special' field has been added to\n\t\t\t\t// an object and we need to update the logic in this file to handle it.\n\t\t\t\t// The most common case it that someone added a Set/Map which probably\n\t\t\t\t// needs to be serialized as an Array/Object respectively - see how\n\t\t\t\t// Battle 'hints' or Choice 'switchIns' are handled (and you will likely\n\t\t\t\t// need to add the new field to the respective skip constant).\n\t\t\t\tthrow new TypeError(`Unsupported type ${obj.constructor.name}: ${obj as any}`);\n\t\t\t}\n\n\t\t\tconst o: any = {};\n\t\t\tfor (const [key, value] of Object.entries(obj)) {\n\t\t\t\to[key] = this.serializeWithRefs(value, battle);\n\t\t\t}\n\t\t\treturn o;\n\t\tdefault:\n\t\t\tthrow new TypeError(`Unexpected typeof === '${typeof obj}': ${obj}`);\n\t\t}\n\t}\n\n\tdeserializeWithRefs(obj: unknown, battle: Battle) {\n\t\tswitch (typeof obj) {\n\t\tcase 'undefined':\n\t\tcase 'boolean':\n\t\tcase 'number':\n\t\t\treturn obj;\n\t\tcase 'string':\n\t\t\treturn this.fromRef(obj, battle) || obj;\n\t\tcase 'object':\n\t\t\tif (obj === null) return null;\n\t\t\tif (Array.isArray(obj)) {\n\t\t\t\tconst arr = new Array(obj.length);\n\t\t\t\tfor (const [i, o] of obj.entries()) {\n\t\t\t\t\tarr[i] = this.deserializeWithRefs(o, battle);\n\t\t\t\t}\n\t\t\t\treturn arr;\n\t\t\t}\n\n\t\t\tif (this.isActiveMove(obj)) return this.deserializeActiveMove(obj, battle);\n\n\t\t\tconst o: any = {};\n\t\t\tfor (const [key, value] of Object.entries(obj)) {\n\t\t\t\to[key] = this.deserializeWithRefs(value, battle);\n\t\t\t}\n\t\t\treturn o;\n\t\tcase 'function': // lol wtf\n\t\tdefault:\n\t\t\tthrow new TypeError(`Unexpected typeof === '${typeof obj}': ${obj}`);\n\t\t}\n\t}\n\n\tisReferable(obj: object): obj is Referable {\n\t\t// NOTE: see explanation on the declaration above for why this must be defined lazily.\n\t\tif (!this.REFERABLE) {\n\t\t\tthis.REFERABLE = new Set([\n\t\t\t\tBattle, Field, Side, Pokemon, Dex.Condition,\n\t\t\t\tDex.Ability, Dex.Item, Dex.Move, Dex.Species,\n\t\t\t]);\n\t\t}\n\t\treturn this.REFERABLE.has(obj.constructor);\n\t}\n\n\ttoRef(obj: Referable): string {\n\t\t// Pokemon's 'id' is not only more verbose than a position, it also isn't guaranteed\n\t\t// to be uniquely identifying in custom games without Nickname/Species Clause.\n\t\tconst id = obj instanceof Pokemon ? `${obj.side.id}${POSITIONS[obj.position]}` : `${obj.id}`;\n\t\treturn `[${obj.constructor.name}${id ? ':' : ''}${id}]`;\n\t}\n\n\tfromRef(ref: string, battle: Battle): Referable | undefined {\n\t\t// References are sort of fragile - we're mostly just counting on there\n\t\t// being a low chance that some string field in a simulator object will not\n\t\t// 'look' like one. However, it also needs to match one of the Referable\n\t\t// class types to be decode, so we're probably OK. We could make the reference\n\t\t// markers more esoteric with additional sigils etc to avoid collisions, but\n\t\t// we're making a conscious decision to favor readability over robustness.\n\t\tif (!ref.startsWith('[') && !ref.endsWith(']')) return undefined;\n\n\t\tref = ref.substring(1, ref.length - 1);\n\t\t// There's only one instance of these thus they don't need an id to differentiate.\n\t\tif (ref === 'Battle') return battle;\n\t\tif (ref === 'Field') return battle.field;\n\n\t\tconst [type, id] = ref.split(':');\n\t\tswitch (type) {\n\t\tcase 'Side': return battle.sides[Number(id[1]) - 1];\n\t\tcase 'Pokemon': return battle.sides[Number(id[1]) - 1].pokemon[POSITIONS.indexOf(id[2])];\n\t\tcase 'Ability': return battle.dex.abilities.get(id);\n\t\tcase 'Item': return battle.dex.items.get(id);\n\t\tcase 'Move': return battle.dex.moves.get(id);\n\t\tcase 'Condition': return battle.dex.conditions.get(id);\n\t\tcase 'Species': return battle.dex.species.get(id);\n\t\tdefault: return undefined; // maybe we actually got unlucky and its a string\n\t\t}\n\t}\n\n\tserialize(obj: object, skip: Set, battle: Battle): AnyObject {\n\t\tconst state: AnyObject = {};\n\t\tfor (const [key, value] of Object.entries(obj)) {\n\t\t\tif (skip.has(key)) continue;\n\t\t\tconst val = this.serializeWithRefs(value, battle);\n\t\t\t// JSON.stringify will get rid of keys with undefined values anyway, but\n\t\t\t// we also do it here so that assert.deepEqual works on battle.toJSON().\n\t\t\tif (typeof val !== 'undefined') state[key] = val;\n\t\t}\n\t\treturn state;\n\t}\n\n\tdeserialize(state: AnyObject, obj: object, skip: Set, battle: Battle) {\n\t\tfor (const [key, value] of Object.entries(state)) {\n\t\t\tif (skip.has(key)) continue;\n\t\t\t// @ts-expect-error index signature\n\t\t\tobj[key] = this.deserializeWithRefs(value, battle);\n\t\t}\n\t}\n};\n"], "mappings": "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", "names": ["o"] }