Spaces:
Running
Running
{ | |
"version": 3, | |
"sources": ["../../data/cg-teams.ts"], | |
"sourcesContent": ["/**\n * Computer-Generated Teams\n *\n * Generates teams based on heuristics, most of which carry over across generations.\n * Teams generated will not always be competitively great, but they will have variety\n * and be fun to play (i.e., tries to avoid awful sets).\n *\n * The [Gen 9] Computer-Generated Teams format is personally maintained by Annika,\n * and is not part of any official Smogon or PS format selection. If you enjoy playing\n * with teams you didn't make yourself, you may want to check out Random Battles, Battle Factory,\n * and/or the sample teams for usage-based formats like OU.\n *\n * The core of the generator is the weightedRandomPick function, which chooses from an array\n * of options based on a weight associated with each option. This way, better/stronger/more useful options\n * are more likely to be chosen, but there's still an opportunity for weaker, more situational,\n * or higher-risk/higher-reward options to be chosen. However, for moves, the 'worst' moves are excluded\n * altogether, both to reduce the likelihood of a bad moveset and improve generator performance.\n *\n * Certain less-relevant aspects of the set are not randomized at all, such as:\n * - IVs (all 31s, with 0 Attack IV if the Pok\u00E9mon has no Physical moves in case of Confusion)\n * - EVs (84 per stat, for +21 to each)\n * - Nature (always Quirky, which has no effect)\n * - Happiness (there are no Happiness-based moves in Gen IX)\n *\n * Currently, leveling is based on a Pok\u00E9mon's position within Smogon's usage-based tiers,\n * but an automatic leveling system is planned for the future. This would involve storing win and loss\n * data by Pok\u00E9mon species in a database, and increasing and decreasing the levels of Pok\u00E9mon species\n * each day based on their win/loss ratio. For example, if 60% of matches with a Pok\u00E9mon species are wins,\n * the species is probably overleveled!\n *\n * Other aspects of the team generator that may be worth implementing in the future include:\n * - Explicit support for weather-oriented teams (boosting moves and typings that synergize with that weather)\n * - Tracking type coverage to make it more likely that a moveset can hit every type\n */\n\nimport { Dex, PRNG, SQL } from '../sim';\nimport type { EventMethods } from '../sim/dex-conditions';\nimport {\n\tABILITY_MOVE_BONUSES,\n\tABILITY_MOVE_TYPE_BONUSES,\n\tHARDCODED_MOVE_WEIGHTS,\n\tMOVE_PAIRINGS,\n\tTARGET_HP_BASED_MOVES,\n\tWEIGHT_BASED_MOVES,\n} from './cg-team-data';\n\ninterface TeamStats {\n\thazardSetters: { [moveid: string]: number };\n\ttypeWeaknesses: { [type: string]: number };\n\thazardRemovers: number;\n}\ninterface MovesStats {\n\tattackTypes: { [type: string]: number };\n\tsetup: { atk: number, def: number, spa: number, spd: number, spe: number };\n\tnoSleepTalk: number;\n\thazards: number;\n\tstallingMoves: number;\n\tnonStatusMoves: number;\n\thealing: number;\n}\n\n// We put a limit on the number of Pok\u00E9mon on a team that can be weak to a given type.\nconst MAX_WEAK_TO_SAME_TYPE = 3;\n/** An estimate of the highest raw speed in the metagame */\nconst TOP_SPEED = 300;\n\nconst levelOverride: { [speciesID: string]: number } = {};\nexport let levelUpdateInterval: NodeJS.Timeout | null = null;\n\n// can't import the function cg-teams-leveling.ts uses to this context for some reason\nconst useBaseSpecies = [\n\t'Pikachu',\n\t'Gastrodon',\n\t'Magearna',\n\t'Dudunsparce',\n\t'Maushold',\n\t'Keldeo',\n\t'Zarude',\n\t'Polteageist',\n\t'Sinistcha',\n\t'Sawsbuck',\n\t'Vivillon',\n\t'Florges',\n\t'Minior',\n\t'Toxtricity',\n\t'Tatsugiri',\n\t'Alcremie',\n];\n\nasync function updateLevels(database: SQL.DatabaseManager) {\n\tconst updateSpecies = await database.prepare(\n\t\t'UPDATE gen9computergeneratedteams SET wins = 0, losses = 0, level = ? WHERE species_id = ?'\n\t);\n\tconst updateHistory = await database.prepare(\n\t\t`INSERT INTO gen9_historical_levels (level, species_id, timestamp) VALUES (?, ?, ${Date.now()})`\n\t);\n\tconst data = await database.all('SELECT species_id, wins, losses, level FROM gen9computergeneratedteams');\n\tfor (let { species_id, wins, losses, level } of data) {\n\t\tconst total = wins + losses;\n\n\t\tif (total > 10) {\n\t\t\tif (wins / total >= 0.55) level--;\n\t\t\tif (wins / total <= 0.45) level++;\n\t\t\tlevel = Math.max(1, Math.min(100, level));\n\t\t\tawait updateSpecies?.run([level, species_id]);\n\t\t\tawait updateHistory?.run([level, species_id]);\n\t\t}\n\n\t\tlevelOverride[species_id] = level;\n\t}\n}\n\nif (global.Config && Config.usesqlite && Config.usesqliteleveling) {\n\tconst database = SQL(module, { file: './databases/battlestats.db' });\n\n\t// update every 2 hours\n\tvoid updateLevels(database);\n\tlevelUpdateInterval = setInterval(() => void updateLevels(database), 1000 * 60 * 60 * 2);\n}\n\nexport default class TeamGenerator {\n\tdex: ModdedDex;\n\tformat: Format;\n\tteamSize: number;\n\tforceLevel?: number;\n\tprng: PRNG;\n\titemPool: Item[];\n\tspecialItems: { [pokemon: string]: string };\n\n\tconstructor(format: Format | string, seed: PRNG | PRNGSeed | null) {\n\t\tthis.dex = Dex.forFormat(format);\n\t\tthis.format = Dex.formats.get(format);\n\t\tthis.teamSize = this.format.ruleTable?.maxTeamSize || 6;\n\t\tthis.prng = PRNG.get(seed);\n\t\tthis.itemPool = this.dex.items.all().filter(i => i.exists && i.isNonstandard !== 'Past' && !i.isPokeball);\n\t\tthis.specialItems = {};\n\t\tfor (const i of this.itemPool) {\n\t\t\tif (i.itemUser && !i.isNonstandard) {\n\t\t\t\tfor (const user of i.itemUser) {\n\t\t\t\t\tif (Dex.species.get(user).requiredItems?.[0] !== i.name) this.specialItems[user] = i.id;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst rules = Dex.formats.getRuleTable(this.format);\n\t\tif (rules.adjustLevel) this.forceLevel = rules.adjustLevel;\n\t}\n\n\tgetTeam(): PokemonSet[] {\n\t\tlet speciesPool = this.dex.species.all().filter(s => {\n\t\t\tif (!s.exists) return false;\n\t\t\tif (s.isNonstandard || s.isNonstandard === 'Unobtainable') return false;\n\t\t\tif (s.nfe) return false;\n\t\t\tif (s.battleOnly && (!s.requiredItems?.length || s.name.endsWith('-Tera'))) return false;\n\n\t\t\treturn true;\n\t\t});\n\t\tconst teamStats: TeamStats = {\n\t\t\thazardSetters: {},\n\t\t\ttypeWeaknesses: {},\n\t\t\thazardRemovers: 0,\n\t\t};\n\n\t\tconst team: PokemonSet[] = [];\n\t\twhile (team.length < this.teamSize && speciesPool.length) {\n\t\t\tconst species = this.prng.sample(speciesPool);\n\n\t\t\tconst haveRoomToReject = speciesPool.length >= (this.teamSize - team.length);\n\t\t\tconst isGoodFit = this.speciesIsGoodFit(species, teamStats);\n\t\t\tif (haveRoomToReject && !isGoodFit) continue;\n\n\t\t\tspeciesPool = speciesPool.filter(s => s.baseSpecies !== species.baseSpecies);\n\t\t\tteam.push(this.makeSet(species, teamStats));\n\t\t}\n\n\t\treturn team;\n\t}\n\n\tprotected makeSet(species: Species, teamStats: TeamStats): PokemonSet {\n\t\tconst abilityPool: string[] = Object.values(species.abilities);\n\t\tconst abilityWeights = abilityPool.map(a => this.getAbilityWeight(this.dex.abilities.get(a)));\n\t\tconst ability = this.weightedRandomPick(abilityPool, abilityWeights);\n\t\tconst level = this.forceLevel || TeamGenerator.getLevel(species);\n\n\t\tconst moves: Move[] = [];\n\t\tlet movesStats: MovesStats = {\n\t\t\tsetup: { atk: 0, def: 0, spa: 0, spd: 0, spe: 0 },\n\t\t\tattackTypes: {},\n\t\t\tnoSleepTalk: 0,\n\t\t\thazards: 0,\n\t\t\tstallingMoves: 0,\n\t\t\thealing: 0,\n\t\t\tnonStatusMoves: 0,\n\t\t};\n\n\t\tlet movePool: IDEntry[] = [...this.dex.species.getMovePool(species.id)];\n\t\tif (!movePool.length) throw new Error(`No moves for ${species.id}`);\n\n\t\t// Consider either the top 15 moves or top 30% of moves, whichever is greater.\n\t\tconst numberOfMovesToConsider = Math.min(movePool.length, Math.max(15, Math.trunc(movePool.length * 0.3)));\n\t\tlet movePoolIsTrimmed = false;\n\t\t// Many moves' weights, such as Swords Dance, are dependent on having other moves in the moveset already\n\t\t// and end up very low when calculated with no moves chosen. This makes it difficult to add these moves without\n\t\t// weighing every move 4 times, and trimming once after the initial weighing makes them impossible for most Pokemon.\n\t\t// To get around this, after weighing against an empty moveset, trimming, and adding three moves, we weigh ALL\n\t\t// moves again against the populated moveset, then put the chosen 3 moves back into the pool with their\n\t\t// original empty-set weights, trim the pool again, and start over. This process results in about 15% fewer calls\n\t\t// to getMoveWeight than considering every move every time does.\n\t\tlet isRound2 = false;\n\t\t// this is just a second reference the array because movePool gets set to point to a new array before the old one\n\t\t// gets mutated\n\t\tconst movePoolCopy = movePool;\n\t\tlet interimMovePool: { move: IDEntry, weight: number }[] = [];\n\t\twhile (moves.length < 4 && movePool.length) {\n\t\t\tlet weights;\n\t\t\tif (!movePoolIsTrimmed) {\n\t\t\t\tif (!isRound2) {\n\t\t\t\t\tfor (const moveID of movePool) {\n\t\t\t\t\t\tconst move = this.dex.moves.get(moveID);\n\t\t\t\t\t\tconst weight = this.getMoveWeight(move, teamStats, species, moves, movesStats, ability, level);\n\t\t\t\t\t\tinterimMovePool.push({ move: moveID, weight });\n\t\t\t\t\t}\n\n\t\t\t\t\tinterimMovePool.sort((a, b) => b.weight - a.weight);\n\t\t\t\t} else {\n\t\t\t\t\tconst originalWeights: typeof interimMovePool = [];\n\t\t\t\t\tfor (const move of moves) {\n\t\t\t\t\t\toriginalWeights.push(interimMovePool.find(m => m.move === move.id)!);\n\t\t\t\t\t}\n\t\t\t\t\tinterimMovePool = originalWeights;\n\n\t\t\t\t\tfor (const moveID of movePoolCopy) {\n\t\t\t\t\t\tconst move = this.dex.moves.get(moveID);\n\t\t\t\t\t\tif (moves.includes(move)) continue;\n\t\t\t\t\t\tconst weight = this.getMoveWeight(move, teamStats, species, moves, movesStats, ability, level);\n\t\t\t\t\t\tinterimMovePool.push({ move: moveID, weight });\n\t\t\t\t\t}\n\n\t\t\t\t\tinterimMovePool.sort((a, b) => b.weight - a.weight);\n\t\t\t\t\tmoves.splice(0);\n\t\t\t\t\tmovesStats = {\n\t\t\t\t\t\tsetup: { atk: 0, def: 0, spa: 0, spd: 0, spe: 0 },\n\t\t\t\t\t\tattackTypes: {},\n\t\t\t\t\t\tnoSleepTalk: 0,\n\t\t\t\t\t\thazards: 0,\n\t\t\t\t\t\tstallingMoves: 0,\n\t\t\t\t\t\thealing: 0,\n\t\t\t\t\t\tnonStatusMoves: 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tmovePool = [];\n\t\t\t\tweights = [];\n\n\t\t\t\tfor (let i = 0; i < numberOfMovesToConsider; i++) {\n\t\t\t\t\tmovePool.push(interimMovePool[i].move);\n\t\t\t\t\tweights.push(interimMovePool[i].weight);\n\t\t\t\t}\n\t\t\t\tmovePoolIsTrimmed = true;\n\t\t\t} else {\n\t\t\t\tweights = movePool.map(\n\t\t\t\t\tm => this.getMoveWeight(this.dex.moves.get(m), teamStats, species, moves, movesStats, ability, level)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst moveID = this.weightedRandomPick(movePool, weights, { remove: true });\n\n\t\t\tconst move = this.dex.moves.get(moveID);\n\t\t\tmoves.push(move);\n\t\t\tif (TeamGenerator.moveIsHazard(moves[moves.length - 1])) {\n\t\t\t\tteamStats.hazardSetters[moveID] = (teamStats.hazardSetters[moveID] || 0) + 1;\n\t\t\t\tmovesStats.hazards++;\n\t\t\t}\n\t\t\tif (['defog', 'courtchange', 'tidyup', 'rapidspin', 'mortalspin'].includes(moveID)) teamStats.hazardRemovers++;\n\t\t\tconst boosts = move.boosts || move.self?.boosts || move.selfBoost?.boosts ||\n\t\t\t\tability !== 'Sheer Force' && move.secondary?.self?.boosts;\n\t\t\tif (move.category === 'Status') {\n\t\t\t\tif (boosts) {\n\t\t\t\t\tfor (const stat in boosts) {\n\t\t\t\t\t\tconst chance = Math.min(100, move.secondary?.chance || 100 * (ability === 'Serene Grace' ? 2 : 1));\n\t\t\t\t\t\tconst boost = (boosts[stat as StatIDExceptHP] || 0) * chance / 100;\n\t\t\t\t\t\tif (boost) {\n\t\t\t\t\t\t\tif (movesStats.setup[stat as StatIDExceptHP] < 0 && boost > 0) {\n\t\t\t\t\t\t\t\tmovesStats.setup[stat as StatIDExceptHP] = boost;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tmovesStats.setup[stat as StatIDExceptHP] += boost;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (boost > 1) movesStats.noSleepTalk++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmovesStats.noSleepTalk++;\n\t\t\t\t}\n\t\t\t\tif (move.heal) movesStats.healing++;\n\t\t\t\tif (move.stallingMove) movesStats.stallingMoves++;\n\t\t\t} else {\n\t\t\t\tmovesStats.nonStatusMoves++;\n\t\t\t\tconst bp = +move.basePower;\n\t\t\t\tconst moveType = TeamGenerator.moveType(move, species);\n\t\t\t\tif (movesStats.attackTypes[moveType] < bp) movesStats.attackTypes[moveType] = bp;\n\t\t\t}\n\n\t\t\tif (!isRound2 && moves.length === 3) {\n\t\t\t\tisRound2 = true;\n\t\t\t\tmovePoolIsTrimmed = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// add paired moves, like RestTalk\n\t\t\tconst pairedMove = MOVE_PAIRINGS[moveID];\n\t\t\tconst alreadyHavePairedMove = moves.some(m => m.id === pairedMove);\n\t\t\tif (\n\t\t\t\tmoves.length < 4 &&\n\t\t\t\tpairedMove &&\n\t\t\t\t!(pairedMove === 'sleeptalk' && movesStats.noSleepTalk) &&\n\t\t\t\t!alreadyHavePairedMove &&\n\t\t\t\t// We don't check movePool because sometimes paired moves are bad.\n\t\t\t\tthis.dex.species.getLearnsetData(species.id).learnset?.[pairedMove]\n\t\t\t) {\n\t\t\t\tmoves.push(this.dex.moves.get(pairedMove));\n\t\t\t\tconst pairedMoveIndex = movePool.indexOf(pairedMove);\n\t\t\t\tif (pairedMoveIndex > -1) movePool.splice(pairedMoveIndex, 1);\n\t\t\t}\n\t\t}\n\n\t\tlet item = '';\n\t\tconst nonStatusMoves = moves.filter(m => this.dex.moves.get(m).category !== 'Status');\n\t\tif (species.requiredItem) {\n\t\t\titem = species.requiredItem;\n\t\t} else if (species.requiredItems) {\n\t\t\titem = this.prng.sample(species.requiredItems.filter(i => !this.dex.items.get(i).isNonstandard));\n\t\t} else if (this.specialItems[species.name] && nonStatusMoves.length) {\n\t\t\t// If the species has a special item, we should use it.\n\t\t\titem = this.specialItems[species.name];\n\t\t} else if (moves.every(m => m.id !== 'acrobatics')) { // Don't assign an item if the set includes Acrobatics...\n\t\t\tconst weights = [];\n\t\t\tconst items = [];\n\t\t\tfor (const i of this.itemPool) {\n\t\t\t\tconst weight = this.getItemWeight(i, teamStats, species, moves, ability, level);\n\t\t\t\tif (weight !== 0) {\n\t\t\t\t\tweights.push(weight);\n\t\t\t\t\titems.push(i.name);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!item) item = this.weightedRandomPick(items, weights);\n\t\t} else if (['Quark Drive', 'Protosynthesis'].includes(ability)) {\n\t\t\t// ...unless the Pokemon can use Booster Energy\n\t\t\titem = 'Booster Energy';\n\t\t}\n\n\t\tconst ivs: PokemonSet['ivs'] = {\n\t\t\thp: 31,\n\t\t\tatk: moves.some(move => this.dex.moves.get(move).category === 'Physical') ? 31 : 0,\n\t\t\tdef: 31,\n\t\t\tspa: 31,\n\t\t\tspd: 31,\n\t\t\tspe: 31,\n\t\t};\n\n\t\t// For Tera Type, we just pick a random type if it's got Tera Blast, Revelation Dance, or no attacking moves,\n\t\t// and the type of one of its attacking moves otherwise (so it can take advantage of the boosts).\n\t\t// Pokemon with 3 or more attack types and Pokemon with both Tera Blast and Contrary can also get Stellar type\n\t\t// but Pokemon with Adaptability never get Stellar because Tera Stellar makes Adaptability have no effect\n\t\t// Ogerpon's formes are forced to the Tera type that matches their forme\n\t\t// Terapagos is forced to Stellar type\n\t\t// Pokemon with Black Sludge don't generally want to tera to a type other than Poison\n\t\tconst hasTeraBlast = moves.some(m => m.id === 'terablast');\n\t\tconst hasRevelationDance = moves.some(m => m.id === 'revelationdance');\n\t\tlet teraType;\n\t\tif (species.forceTeraType) {\n\t\t\tteraType = species.forceTeraType;\n\t\t} else if (item === 'blacksludge' && this.prng.randomChance(2, 3)) {\n\t\t\tteraType = 'Poison';\n\t\t} else if (hasTeraBlast && ability === 'Contrary' && this.prng.randomChance(2, 3)) {\n\t\t\tteraType = 'Stellar';\n\t\t} else {\n\t\t\tlet types = nonStatusMoves.map(m => TeamGenerator.moveType(this.dex.moves.get(m), species));\n\t\t\tconst noStellar = ability === 'Adaptability' || new Set(types).size < 3;\n\t\t\tif (hasTeraBlast || hasRevelationDance || !nonStatusMoves.length) {\n\t\t\t\ttypes = [...this.dex.types.names()];\n\t\t\t\tif (noStellar) types.splice(types.indexOf('Stellar'));\n\t\t\t} else {\n\t\t\t\tif (!noStellar) types.push('Stellar');\n\t\t\t}\n\t\t\tteraType = this.prng.sample(types);\n\t\t}\n\n\t\treturn {\n\t\t\tname: species.name,\n\t\t\tspecies: species.name,\n\t\t\titem,\n\t\t\tability,\n\t\t\tmoves: moves.map(m => m.name),\n\t\t\tnature: 'Quirky',\n\t\t\tgender: species.gender,\n\t\t\tevs: { hp: 84, atk: 84, def: 84, spa: 84, spd: 84, spe: 84 },\n\t\t\tivs,\n\t\t\tlevel,\n\t\t\tteraType,\n\t\t\tshiny: this.prng.randomChance(1, 1024),\n\t\t\thappiness: 255,\n\t\t};\n\t}\n\n\t/**\n\t * @returns true if the Pok\u00E9mon is a good fit for the team so far, and no otherwise\n\t */\n\tprotected speciesIsGoodFit(species: Species, stats: TeamStats): boolean {\n\t\t// type check\n\t\tfor (const typeName of this.dex.types.names()) {\n\t\t\tconst effectiveness = this.dex.getEffectiveness(typeName, species.types);\n\t\t\tif (effectiveness === 1) { // WEAKNESS!\n\t\t\t\tif (stats.typeWeaknesses[typeName] === undefined) {\n\t\t\t\t\tstats.typeWeaknesses[typeName] = 0;\n\t\t\t\t}\n\t\t\t\tif (stats.typeWeaknesses[typeName] >= MAX_WEAK_TO_SAME_TYPE) {\n\t\t\t\t\t// too many weaknesses to this type\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// species passes; increment counters\n\t\tfor (const typeName of this.dex.types.names()) {\n\t\t\tconst effectiveness = this.dex.getEffectiveness(typeName, species.types);\n\t\t\tif (effectiveness === 1) {\n\t\t\t\tstats.typeWeaknesses[typeName]++;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * @returns A weighting for the Pok\u00E9mon's ability.\n\t */\n\tprotected getAbilityWeight(ability: Ability): number {\n\t\treturn ability.rating + 1; // Some ability ratings are -1\n\t}\n\n\tprotected static moveIsHazard(move: Move): boolean {\n\t\treturn !!(move.sideCondition && move.target === 'foeSide') || ['stoneaxe', 'ceaselessedge'].includes(move.id);\n\t}\n\n\t/**\n\t * @returns A weight for a given move on a given Pok\u00E9mon.\n\t */\n\tprotected getMoveWeight(\n\t\tmove: Move,\n\t\tteamStats: TeamStats,\n\t\tspecies: Species,\n\t\tmovesSoFar: Move[],\n\t\tmovesStats: MovesStats,\n\t\tability: string,\n\t\tlevel: number,\n\t): number {\n\t\tif (!move.exists) return 0;\n\t\t// this is NOT doubles, so there will be no adjacent ally\n\t\tif (move.target === 'adjacentAlly') return 0;\n\n\t\t// There's an argument to be made for using Terapagos-Stellar's stats instead\n\t\t// but the important thing is to not use Terapagos-Base's stats since it never battles in that forme\n\t\tif (ability === 'Tera Shift') species = this.dex.species.get('Terapagos-Terastal');\n\n\t\t// Attack and Special Attack are scaled by level^2 because in addition to stats themselves being scaled by level,\n\t\t// damage dealt by attacks is also scaled by the user's level\n\t\tconst adjustedStats: StatsTable = {\n\t\t\thp: species.baseStats.hp * level / 100 + level,\n\t\t\tatk: species.baseStats.atk * level * level / 10000,\n\t\t\tdef: species.baseStats.def * level / 100,\n\t\t\tspa: species.baseStats.spa * level * level / 10000,\n\t\t\tspd: species.baseStats.spd * level / 100,\n\t\t\tspe: species.baseStats.spe * level / 100,\n\t\t};\n\n\t\tif (move.category === 'Status') {\n\t\t\t// The initial value of this weight determines how valuable status moves are vs. attacking moves.\n\t\t\t// You can raise it to make random status moves more valuable or lower it and increase multipliers\n\t\t\t// to make only CERTAIN status moves valuable.\n\t\t\tlet weight = 2400;\n\n\t\t\t// inflicts status\n\t\t\tif (move.status) weight *= TeamGenerator.statusWeight(move.status) * 2;\n\n\t\t\t// hazard setters: very important, but we don't need 2 pokemon to set the same hazard on a team\n\t\t\tif (TeamGenerator.moveIsHazard(move) && (teamStats.hazardSetters[move.id] || 0) < 1) {\n\t\t\t\tweight *= move.id === 'spikes' ? 12 : 16;\n\n\t\t\t\t// if we are ALREADY setting hazards, setting MORE is really good\n\t\t\t\tif (movesStats.hazards) weight *= 2;\n\t\t\t}\n\n\t\t\t// hazard removers: even more important than hazard setters, since they remove everything at once\n\t\t\t// we still don't need too many on one team, though\n\t\t\tif (['defog', 'courtchange', 'tidyup'].includes(move.id) && !teamStats.hazardRemovers) {\n\t\t\t\tweight *= 32;\n\n\t\t\t\t// these moves can also lessen the effectiveness of the user's team's own hazards\n\t\t\t\tweight *= 0.8 ** Object.values(teamStats.hazardSetters).reduce((total, num) => total + num, 0);\n\t\t\t}\n\n\t\t\t// boosts\n\t\t\tweight *= this.boostWeight(move, movesSoFar, species, ability, level);\n\t\t\tweight *= this.opponentDebuffWeight(move);\n\n\t\t\t// nonstandard boosting moves\n\t\t\tif (move.id === 'focusenergy' && ability !== 'Super Luck') {\n\t\t\t\tconst highCritMoves = movesSoFar.filter(m => m.critRatio && m.critRatio > 1);\n\t\t\t\tweight *= 1 + highCritMoves.length * (ability === 'Sniper' ? 2 : 1);\n\t\t\t} else if (move.id === 'tailwind' && ability === 'Wind Rider' && movesSoFar.some(m => m.category === 'Physical')) {\n\t\t\t\tweight *= 2.5; // grants +1 attack, but isn't spammable\n\t\t\t}\n\n\t\t\t// protection moves - useful for bulky/stally pokemon\n\t\t\tif (!movesStats.stallingMoves) {\n\t\t\t\tif (adjustedStats.def >= 80 || adjustedStats.spd >= 80 || adjustedStats.hp >= 80) {\n\t\t\t\t\tswitch (move.volatileStatus) {\n\t\t\t\t\tcase 'endure':\n\t\t\t\t\t\tweight *= 2;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'protect':\n\t\t\t\t\t\tweight *= 3;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'kingsshield': case 'silktrap':\n\t\t\t\t\t\tweight *= 4;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'banefulbunker': case 'burningbulwark': case 'spikyshield':\n\t\t\t\t\t\tweight *= 5;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Hardcoded boosts\n\t\t\tif (move.id in HARDCODED_MOVE_WEIGHTS) weight *= HARDCODED_MOVE_WEIGHTS[move.id];\n\n\t\t\t// Rest and Sleep Talk are pretty bad on Pokemon that can't fall asleep\n\t\t\tconst sleepImmunities = [\n\t\t\t\t'Comatose',\n\t\t\t\t'Purifying Salt',\n\t\t\t\t'Shields Down',\n\t\t\t\t'Insomnia',\n\t\t\t\t'Vital Spirit',\n\t\t\t\t'Sweet Veil',\n\t\t\t\t'Misty Surge',\n\t\t\t\t'Electric Surge',\n\t\t\t\t'Hadron Engine',\n\t\t\t];\n\t\t\tif (['sleeptalk', 'rest'].includes(move.id) && sleepImmunities.includes(ability)) return 0;\n\n\t\t\t// Sleep Talk is bad with moves that can't be used repeatedly, a.k.a. most status moves\n\t\t\t// the exceptions allowed here are moves which boost a stat by exactly 1 and moves that wake the user up\n\t\t\tif (move.id === 'sleeptalk') {\n\t\t\t\tif (movesStats.noSleepTalk) weight *= 0.1;\n\t\t\t} else if (movesSoFar.some(m => m.id === 'sleeptalk')) {\n\t\t\t\tlet sleepTalkSpammable = ['takeheart', 'junglehealing', 'healbell'].includes(move.id);\n\t\t\t\tif (move.boosts) {\n\t\t\t\t\tfor (const stat in move.boosts) {\n\t\t\t\t\t\tif (move.boosts[stat as StatIDExceptHP] === 1) {\n\t\t\t\t\t\t\tsleepTalkSpammable = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!sleepTalkSpammable) weight *= 0.1;\n\t\t\t}\n\n\t\t\t// Pok\u00E9mon with high Attack and Special Attack stats shouldn't have too many status moves,\n\t\t\t// but on bulkier Pok\u00E9mon it's more likely to be worth it.\n\t\t\tconst goodAttacker = adjustedStats.atk > 65 || adjustedStats.spa > 65;\n\t\t\tif (goodAttacker && movesStats.nonStatusMoves < 2) {\n\t\t\t\tweight *= 0.3;\n\t\t\t}\n\n\t\t\tif (movesSoFar.length === 3 && movesStats.nonStatusMoves === 0) {\n\t\t\t\t// uh oh\n\t\t\t\tweight *= 0.6;\n\t\t\t\tfor (const stat in movesStats.setup) {\n\t\t\t\t\tif (movesStats.setup[stat as StatIDExceptHP] > 0) {\n\t\t\t\t\t\t// having no attacks is bad; having setup but no attacks is REALLY bad\n\t\t\t\t\t\tweight *= 0.6;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// don't need 2 healing moves\n\t\t\tif (move.heal && movesStats.healing) weight *= 0.5;\n\n\t\t\treturn weight;\n\t\t}\n\n\t\tlet basePower = move.basePower;\n\t\t// For Grass Knot and friends, let's just assume they average out to around 60 base power.\n\t\t// Same with Crush Grip and Hard Press\n\t\tif (WEIGHT_BASED_MOVES.includes(move.id) || TARGET_HP_BASED_MOVES.includes(move.id)) basePower = 60;\n\t\t/** A value from 0 to 1, where 0 is the fastest and 1 is the slowest */\n\t\tconst slownessRating = Math.max(0, TOP_SPEED - adjustedStats.spe) / TOP_SPEED;\n\t\t// not how this calc works but it should be close enough\n\t\tif (move.id === 'gyroball') basePower = 150 * slownessRating * slownessRating;\n\t\tif (move.id === 'electroball') basePower = 150 * (1 - slownessRating) * (1 - slownessRating);\n\n\t\tlet baseStat = move.category === 'Physical' ? adjustedStats.atk : adjustedStats.spa;\n\t\tif (move.id === 'foulplay') baseStat = adjustedStats.spe * level / 100;\n\t\tif (move.id === 'bodypress') baseStat = adjustedStats.def * level / 100;\n\t\t// 10% bonus for never-miss moves\n\t\tlet accuracy = move.accuracy === true || ability === 'No Guard' ? 110 : move.accuracy;\n\t\tif (accuracy < 100) {\n\t\t\tif (ability === 'Compound Eyes') accuracy = Math.min(100, Math.round(accuracy * 1.3));\n\t\t\tif (ability === 'Victory Star') accuracy = Math.min(100, Math.round(accuracy * 1.1));\n\t\t}\n\t\taccuracy /= 100;\n\n\t\tconst moveType = TeamGenerator.moveType(move, species);\n\n\t\tlet powerEstimate = basePower * baseStat * accuracy;\n\t\t// STAB\n\t\tif (species.types.includes(moveType)) powerEstimate *= ability === 'Adaptability' ? 2 : 1.5;\n\t\tif (ability === 'Technician' && move.basePower <= 60) powerEstimate *= 1.5;\n\t\tif (ability === 'Sheer Force' && (move.secondary || move.secondaries)) powerEstimate *= 1.3;\n\t\tconst numberOfHits = Array.isArray(move.multihit) ?\n\t\t\t(ability === 'Skill Link' ? move.multihit[1] : (move.multihit[0] + move.multihit[1]) / 2) :\n\t\t\tmove.multihit || 1;\n\t\tpowerEstimate *= numberOfHits;\n\n\t\tif (species.requiredItems) {\n\t\t\tconst item: Item & EventMethods = this.dex.items.get(this.specialItems[species.name]);\n\t\t\tif (item.onBasePower && (species.types.includes(moveType) || item.name.endsWith('Mask'))) powerEstimate *= 1.2;\n\t\t} else if (this.specialItems[species.name]) {\n\t\t\tconst item: Item & EventMethods = this.dex.items.get(this.specialItems[species.name]);\n\t\t\tif (item.onBasePower && species.types.includes(moveType)) powerEstimate *= 1.2;\n\t\t\tif (item.id === 'lightball') powerEstimate *= 2;\n\t\t}\n\n\t\t// If it uses the attacking stat that we don't boost, it's less useful!\n\t\tconst specialSetup = movesStats.setup.spa;\n\t\tconst physicalSetup = movesStats.setup.atk;\n\t\tif (move.category === 'Physical' && !['bodypress', 'foulplay'].includes(move.id)) {\n\t\t\tpowerEstimate *= Math.max(0.5, 1 + physicalSetup) / Math.max(0.5, 1 + specialSetup);\n\t\t}\n\t\tif (move.category === 'Special') powerEstimate *= Math.max(0.5, 1 + specialSetup) / Math.max(0.5, 1 + physicalSetup);\n\n\t\tconst abilityBonus = (\n\t\t\t(ABILITY_MOVE_BONUSES[this.dex.toID(ability)]?.[move.id] || 1) *\n\t\t\t(ABILITY_MOVE_TYPE_BONUSES[this.dex.toID(ability)]?.[moveType] || 1)\n\t\t);\n\n\t\tlet weight = powerEstimate * abilityBonus;\n\t\tif (move.id in HARDCODED_MOVE_WEIGHTS) weight *= HARDCODED_MOVE_WEIGHTS[move.id];\n\t\t// semi-hardcoded move weights that depend on having control over the item\n\t\tif (!this.specialItems[species.name] && !species.requiredItem) {\n\t\t\tif (move.id === 'acrobatics') weight *= 1.75;\n\t\t\tif (move.id === 'facade') {\n\t\t\t\tif (!['Comatose', 'Purifying Salt', 'Shields Down', 'Natural Cure', 'Misty Surge'].includes(ability)) weight *= 1.5;\n\t\t\t}\n\t\t}\n\n\t\t// priority is more useful when you're slower\n\t\t// except Upper Hand, which is anti-priority and thus better on faster Pokemon\n\t\t// TODO: make weight scale with priority\n\t\tif (move.priority > 0 && move.id !== 'upperhand') weight *= (Math.max(105 - adjustedStats.spe, 0) / 105) * 0.5 + 1;\n\t\tif (move.priority < 0 || move.id === 'upperhand') weight *= Math.min((1 / adjustedStats.spe) * 25, 1);\n\n\t\t// flags\n\t\tif (move.flags.charge || (move.flags.recharge && ability !== 'Truant')) weight *= 0.5;\n\t\tif (move.flags.contact) {\n\t\t\tif (ability === 'Tough Claws') weight *= 1.3;\n\t\t\tif (ability === 'Unseen Fist') weight *= 1.1;\n\t\t\tif (ability === 'Poison Touch') weight *= TeamGenerator.statusWeight('psn', 1 - (0.7 ** numberOfHits));\n\t\t}\n\t\tif (move.flags.bite && ability === 'Strong Jaw') weight *= 1.5;\n\t\t// 5% boost for ability to break subs\n\t\tif (move.flags.bypasssub) weight *= 1.05;\n\t\tif (move.flags.pulse && ability === 'Mega Launcher') weight *= 1.5;\n\t\tif (move.flags.punch && ability === 'Iron Fist') weight *= 1.2;\n\t\tif (!move.flags.protect) weight *= 1.05;\n\t\tif (move.flags.slicing && ability === 'Sharpness') weight *= 1.5;\n\t\tif (move.flags.sound && ability === 'Punk Rock') weight *= 1.3;\n\n\t\t// boosts/secondaries\n\t\t// TODO: consider more possible secondaries\n\t\tweight *= this.boostWeight(move, movesSoFar, species, ability, level);\n\t\tconst secondaryChance = Math.min((move.secondary?.chance || 100) * (ability === 'Serene Grace' ? 2 : 1) / 100, 100);\n\t\tif (move.secondary || move.secondaries) {\n\t\t\tif (ability === 'Sheer Force') {\n\t\t\t\tweight *= 1.3;\n\t\t\t} else {\n\t\t\t\tconst secondaries = move.secondaries || [move.secondary!];\n\t\t\t\tfor (const secondary of secondaries) {\n\t\t\t\t\tif (secondary.status) {\n\t\t\t\t\t\tweight *= TeamGenerator.statusWeight(secondary.status, secondaryChance, slownessRating);\n\t\t\t\t\t\tif (ability === 'Poison Puppeteer' && ['psn', 'tox'].includes(secondary.status)) {\n\t\t\t\t\t\t\tweight *= TeamGenerator.statusWeight('confusion', secondaryChance);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (secondary.volatileStatus) {\n\t\t\t\t\t\tweight *= TeamGenerator.statusWeight(secondary.volatileStatus, secondaryChance, slownessRating);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (ability === 'Toxic Chain') weight *= TeamGenerator.statusWeight('tox', 1 - (0.7 ** numberOfHits));\n\n\t\t// Special effect if something special happened earlier in the turn\n\t\t// More useful on slower Pokemon\n\t\tif (move.id === 'lashout') weight *= 1 + 0.2 * slownessRating;\n\t\tif (move.id === 'burningjealousy') weight *= TeamGenerator.statusWeight('brn', 0.2 * slownessRating);\n\t\tif (move.id === 'alluringvoice') weight *= TeamGenerator.statusWeight('confusion', 0.2 * slownessRating);\n\n\t\t// self-inflicted confusion or locking yourself in\n\t\tif (move.self?.volatileStatus) weight *= 0.8;\n\n\t\t// downweight moves if we already have an attacking move of the same type\n\t\tif ((movesStats.attackTypes[moveType] || 0) > 60) weight *= 0.3;\n\n\t\tif (move.selfdestruct) weight *= 0.3;\n\t\tif (move.recoil && ability !== 'Rock Head' && ability !== 'Magic Guard') {\n\t\t\tweight *= 1 - (move.recoil[0] / move.recoil[1]);\n\t\t\tif (ability === 'Reckless') weight *= 1.2;\n\t\t}\n\t\tif (move.hasCrashDamage && ability !== 'Magic Guard') {\n\t\t\tweight *= 1 - 0.75 * (1.2 - accuracy);\n\t\t\tif (ability === 'Reckless') weight *= 1.2;\n\t\t}\n\t\tif (move.mindBlownRecoil) weight *= 0.25;\n\t\tif (move.flags['futuremove']) weight *= 0.3;\n\n\t\tlet critRate = move.willCrit ? 4 : move.critRatio || 1;\n\t\tif (ability === 'Super Luck') critRate++;\n\t\tif (movesSoFar.some(m => m.id === 'focusenergy')) {\n\t\t\tcritRate += 2;\n\t\t\tweight *= 0.9; // a penalty the extra turn of setup\n\t\t}\n\t\tif (critRate > 4) critRate = 4;\n\t\tweight *= 1 + [0, 1 / 24, 1 / 8, 1 / 2, 1][critRate] * (ability === 'Sniper' ? 1 : 0.5);\n\n\t\t// these two hazard removers don't clear hazards on the opponent's field, but can be blocked by type immunities\n\t\tif (['rapidspin', 'mortalspin'].includes(move.id)) {\n\t\t\tweight *= 1 + 20 * (0.25 ** teamStats.hazardRemovers);\n\t\t}\n\n\t\t// these moves have a hard-coded 16x bonus\n\t\tif (move.id === 'stoneaxe' && teamStats.hazardSetters.stealthrock) weight /= 4;\n\t\tif (move.id === 'ceaselessedge' && teamStats.hazardSetters.spikes) weight /= 2;\n\n\t\tif (move.drain) {\n\t\t\tconst drainedFraction = move.drain[0] / move.drain[1];\n\t\t\tweight *= 1 + (drainedFraction * 0.5);\n\t\t}\n\n\t\t// Oricorio should rarely get Tera Blast, as Revelation Dance is strictly better\n\t\t// Tera Blast is also bad on species with forced Tera types, a.k.a. Ogerpon and Terapagos\n\t\tif (move.id === 'terablast' && (species.baseSpecies === 'Oricorio' || species.forceTeraType)) weight *= 0.5;\n\n\t\treturn weight;\n\t}\n\n\t/**\n\t * @returns The effective type of moves with variable types such as Judgment\n\t */\n\tprotected static moveType(move: Move, species: Species) {\n\t\tswitch (move.id) {\n\t\tcase 'ivycudgel':\n\t\tcase 'ragingbull':\n\t\t\tif (species.types.length > 1) return species.types[1];\n\t\t\t// falls through for Ogerpon and Tauros's respective base formes\n\t\tcase 'judgment':\n\t\tcase 'revelationdance':\n\t\t\treturn species.types[0];\n\t\t}\n\t\treturn move.type;\n\t}\n\n\tprotected static moveIsPhysical(move: Move, species: Species) {\n\t\tif (move.category === 'Physical') {\n\t\t\treturn !(move.damageCallback || move.damage);\n\t\t} else if (['terablast', 'terastarstorm', 'photongeyser', 'shellsidearm'].includes(move.id)) {\n\t\t\treturn species.baseStats.atk > species.baseStats.spa;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprotected static moveIsSpecial(move: Move, species: Species) {\n\t\tif (move.category === 'Special') {\n\t\t\treturn !(move.damageCallback || move.damage);\n\t\t} else if (['terablast', 'terastarstorm', 'photongeyser', 'shellsidearm'].includes(move.id)) {\n\t\t\treturn species.baseStats.atk <= species.baseStats.spa;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * @returns A multiplier to a move weighting based on the status it inflicts.\n\t */\n\tprotected static statusWeight(status: string, chance = 1, slownessRating?: number): number {\n\t\tif (chance !== 1) return 1 + (TeamGenerator.statusWeight(status) - 1) * chance;\n\n\t\tswitch (status) {\n\t\tcase 'brn': return 2;\n\t\tcase 'frz': return 5;\n\t\t// paralysis is especially valuable on slow pokemon that can become faster than an opponent by paralyzing it\n\t\t// but some pokemon are so slow that most paralyzed pokemon would still outspeed them anyway\n\t\tcase 'par': return slownessRating && slownessRating > 0.25 ? 2 + slownessRating : 2;\n\t\tcase 'psn': return 1.75;\n\t\tcase 'tox': return 4;\n\t\tcase 'slp': return 4;\n\t\tcase 'confusion': return 1.5;\n\t\tcase 'healblock': return 1.75;\n\t\tcase 'flinch': return slownessRating ? slownessRating * 3 : 1;\n\t\tcase 'saltcure': return 2;\n\t\tcase 'sparklingaria': return 0.95;\n\t\tcase 'syrupbomb': return 1.5;\n\t\t}\n\t\treturn 1;\n\t}\n\n\t/**\n\t * @returns A multiplier to a move weighting based on the boosts it produces for the user.\n\t */\n\tprotected boostWeight(move: Move, movesSoFar: Move[], species: Species, ability: string, level: number): number {\n\t\tconst physicalIsRelevant = (\n\t\t\tTeamGenerator.moveIsPhysical(move, species) ||\n\t\t\tmovesSoFar.some(\n\t\t\t\tm => TeamGenerator.moveIsPhysical(m, species) && !m.overrideOffensiveStat && !m.overrideOffensivePokemon\n\t\t\t)\n\t\t);\n\t\tconst specialIsRelevant = (\n\t\t\tTeamGenerator.moveIsSpecial(move, species) ||\n\t\t\tmovesSoFar.some(m => TeamGenerator.moveIsSpecial(m, species))\n\t\t);\n\n\t\tconst adjustedStats: StatsTable = {\n\t\t\thp: species.baseStats.hp * level / 100 + level,\n\t\t\tatk: species.baseStats.atk * level * level / 10000,\n\t\t\tdef: species.baseStats.def * level / 100,\n\t\t\tspa: species.baseStats.spa * level * level / 10000,\n\t\t\tspd: species.baseStats.spd * level / 100,\n\t\t\tspe: species.baseStats.spe * level / 100,\n\t\t};\n\n\t\tlet weight = 0;\n\t\tconst accuracy = move.accuracy === true ? 100 : move.accuracy / 100;\n\t\tconst secondaryChance = move.secondary && ability !== 'Sheer Force' ?\n\t\t\tMath.min(((move.secondary.chance || 100) * (ability === 'Serene Grace' ? 2 : 1) / 100), 100) * accuracy : 0;\n\t\tconst abilityMod = ability === 'Simple' ? 2 : ability === 'Contrary' ? -1 : 1;\n\t\tconst bodyPressMod = movesSoFar.some(m => m.id === 'bodyPress') ? 2 : 1;\n\t\tconst electroBallMod = movesSoFar.some(m => m.id === 'electroball') ? 2 : 1;\n\t\tfor (const { chance, boosts } of [\n\t\t\t{ chance: 1, boosts: move.boosts },\n\t\t\t{ chance: 1, boosts: move.self?.boosts },\n\t\t\t{ chance: 1, boosts: move.selfBoost?.boosts },\n\t\t\t{\n\t\t\t\tchance: secondaryChance,\n\t\t\t\tboosts: move.secondary?.self?.boosts,\n\t\t\t},\n\t\t]) {\n\t\t\tif (!boosts || chance === 0) continue;\n\t\t\tconst statusMod = move.category === 'Status' ? 1 : 0.5;\n\n\t\t\tif (boosts.atk && physicalIsRelevant) weight += chance * boosts.atk * abilityMod * 2 * statusMod;\n\t\t\tif (boosts.spa && specialIsRelevant) weight += chance * boosts.spa * abilityMod * 2 * statusMod;\n\n\t\t\t// TODO: should these scale by base stat magnitude instead of using ternaries?\n\t\t\t// defense/special defense boost is less useful if we have some bulk to start with\n\t\t\tif (boosts.def) {\n\t\t\t\tweight += chance * boosts.def * abilityMod * bodyPressMod * (adjustedStats.def > 60 ? 0.5 : 1) * statusMod;\n\t\t\t}\n\t\t\tif (boosts.spd) weight += chance * boosts.spd * abilityMod * (adjustedStats.spd > 60 ? 0.5 : 1) * statusMod;\n\n\t\t\t// speed boost is less useful for fast pokemon\n\t\t\tif (boosts.spe) {\n\t\t\t\tweight += chance * boosts.spe * abilityMod * electroBallMod * (adjustedStats.spe > 95 ? 0.5 : 1) * statusMod;\n\t\t\t}\n\t\t}\n\n\t\treturn weight >= 0 ? 1 + weight : 1 / (1 - weight);\n\t}\n\n\t/**\n\t * @returns A weight for a move based on how much it will reduce the opponent's stats.\n\t */\n\tprotected opponentDebuffWeight(move: Move): number {\n\t\tif (!['allAdjacentFoes', 'allAdjacent', 'foeSide', 'normal'].includes(move.target)) return 1;\n\n\t\tlet averageNumberOfDebuffs = 0;\n\t\tfor (const { chance, boosts } of [\n\t\t\t{ chance: 1, boosts: move.boosts },\n\t\t\t{\n\t\t\t\tchance: move.secondary ? ((move.secondary.chance || 100) / 100) : 0,\n\t\t\t\tboosts: move.secondary?.boosts,\n\t\t\t},\n\t\t]) {\n\t\t\tif (!boosts || chance === 0) continue;\n\n\t\t\tconst numBoosts = Object.values(boosts).filter(x => x < 0).length;\n\t\t\taverageNumberOfDebuffs += chance * numBoosts;\n\t\t}\n\n\t\treturn 1 + (0.5 * averageNumberOfDebuffs);\n\t}\n\n\t/**\n\t * @returns A weight for an item.\n\t */\n\tprotected getItemWeight(\n\t\titem: Item, teamStats: TeamStats, species: Species, moves: Move[], ability: string, level: number\n\t): number {\n\t\tconst adjustedStats: StatsTable = {\n\t\t\thp: species.baseStats.hp * level / 100 + level,\n\t\t\tatk: species.baseStats.atk * level * level / 10000,\n\t\t\tdef: species.baseStats.def * level / 100,\n\t\t\tspa: species.baseStats.spa * level * level / 10000,\n\t\t\tspd: species.baseStats.spd * level / 100,\n\t\t\tspe: species.baseStats.spe * level / 100,\n\t\t};\n\t\tconst statusImmunities = ['Comatose', 'Purifying Salt', 'Shields Down', 'Natural Cure', 'Misty Surge'];\n\n\t\tlet weight;\n\t\tswitch (item.id) {\n\t\t// Choice Items\n\t\tcase 'choiceband':\n\t\t\treturn moves.every(x => TeamGenerator.moveIsPhysical(x, species)) ? 50 : 0;\n\t\tcase 'choicespecs':\n\t\t\treturn moves.every(x => TeamGenerator.moveIsSpecial(x, species)) ? 50 : 0;\n\t\tcase 'choicescarf':\n\t\t\tif (moves.some(x => x.category === 'Status' || x.secondary?.self?.boosts?.spe)) return 0;\n\t\t\tif (adjustedStats.spe > 50 && adjustedStats.spe < 120) return 50;\n\t\t\treturn 10;\n\n\t\t// Generally Decent Items\n\t\tcase 'lifeorb':\n\t\t\treturn moves.filter(x => x.category !== 'Status' && !x.damage && !x.damageCallback).length * 8;\n\t\tcase 'focussash':\n\t\t\tif (ability === 'Sturdy') return 0;\n\t\t\t// frail\n\t\t\tif (adjustedStats.hp < 65 && adjustedStats.def < 65 && adjustedStats.spd < 65) return 35;\n\t\t\treturn 10;\n\t\tcase 'heavydutyboots':\n\t\t\tswitch (this.dex.getEffectiveness('Rock', species)) {\n\t\t\tcase 1: return 30; // super effective\n\t\t\tcase 0: return 10; // neutral\n\t\t\t}\n\t\t\treturn 5; // not very effective/other\n\t\tcase 'assaultvest':\n\t\t\tif (moves.some(x => x.category === 'Status')) return 0;\n\t\t\treturn 30;\n\t\tcase 'scopelens':\n\t\t\tconst attacks = moves.filter(x => x.category !== 'Status' && !x.damage && !x.damageCallback && !x.willCrit);\n\t\t\tif (moves.some(m => m.id === 'focusenergy')) {\n\t\t\t\tif (ability === 'Super Luck') return 0; // we're already lucky enough, thank you\n\t\t\t\treturn attacks.length * (ability === 'Sniper' ? 16 : 12);\n\t\t\t} else if (attacks.filter(x => (x.critRatio || 1) > 1).length || ability === 'Super Luck') {\n\t\t\t\treturn attacks.reduce((total, x) => {\n\t\t\t\t\tlet ratio = ability === 'Super Luck' ? 2 : 1;\n\t\t\t\t\tif ((x.critRatio || 1) > 1) ratio++;\n\t\t\t\t\treturn total + [0, 3, 6, 12][ratio] * (ability === 'Sniper' ? 4 / 3 : 1);\n\t\t\t\t}, 0);\n\t\t\t}\n\t\t\treturn 0;\n\t\tcase 'eviolite':\n\t\t\treturn species.nfe || species.id === 'dipplin' ? 100 : 0;\n\n\t\t// status\n\t\tcase 'flameorb':\n\t\t\tif (species.types.includes('Fire')) return 0;\n\t\t\tif (statusImmunities.includes(ability)) return 0;\n\t\t\tif (['Thermal Exchange', 'Water Bubble', 'Water Veil'].includes(ability)) return 0;\n\t\t\tweight = ['Guts', 'Flare Boost'].includes(ability) ? 30 : 0;\n\t\t\tif (moves.some(m => m.id === 'facade')) {\n\t\t\t\tif (!weight && !moves.some(m => TeamGenerator.moveIsPhysical(m, species) && m.id !== 'facade')) {\n\t\t\t\t\tweight = 30;\n\t\t\t\t} else {\n\t\t\t\t\tweight *= 2;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn weight;\n\t\tcase 'toxicorb':\n\t\t\tif (species.types.includes('Poison') || species.types.includes('Steel')) return 0;\n\t\t\tif (statusImmunities.includes(ability)) return 0;\n\t\t\tif (ability === 'Immunity') return 0;\n\t\t\t// If facade is our only physical attack, Flame Orb is preferred\n\t\t\tif (!moves.some(m => TeamGenerator.moveIsPhysical(m, species) && m.id !== 'facade') &&\n\t\t\t\t!species.types.includes('Fire') && ['Thermal Exchange', 'Water Bubble', 'Water Veil'].includes(ability)\n\t\t\t) return 0;\n\n\t\t\tweight = 0;\n\t\t\tif (['Poison Heal', 'Toxic Boost'].includes('ability')) weight += 25;\n\t\t\tif (moves.some(m => m.id === 'facade')) weight += 25;\n\n\t\t\treturn weight;\n\n\t\t// Healing\n\t\tcase 'leftovers':\n\t\t\treturn moves.some(m => m.stallingMove) ? 40 : 20;\n\t\tcase 'blacksludge':\n\t\t\t// Even poison types don't really like Black Sludge in Gen 9 because it discourages them from terastallizing\n\t\t\t// to a type other than Poison, and thus reveals their Tera type when it activates\n\t\t\treturn species.types.includes('Poison') ? moves.some(m => m.stallingMove) ? 20 : 10 : 0;\n\n\t\t// berries\n\t\tcase 'sitrusberry': case 'magoberry':\n\t\t\treturn 20;\n\n\t\tcase 'throatspray':\n\t\t\tif (moves.some(m => m.flags.sound) && moves.some(m => m.category === 'Special')) return 30;\n\t\t\treturn 0;\n\n\t\tdefault:\n\t\t\t// probably not a very good item\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/**\n\t * @returns The level a Pok\u00E9mon should be.\n\t */\n\tprotected static getLevel(species: Species): number {\n\t\tif (['Zacian', 'Zamazenta'].includes(species.name)) {\n\t\t\tspecies = Dex.species.get(species.otherFormes![0]);\n\t\t} else if (species.baseSpecies === 'Squawkabilly') {\n\t\t\tif (['Yellow', 'White'].includes(species.forme)) {\n\t\t\t\tspecies = Dex.species.get('Squawkabilly-Yellow');\n\t\t\t} else {\n\t\t\t\tspecies = Dex.species.get('Squawkabilly');\n\t\t\t}\n\t\t} else if (useBaseSpecies.includes(species.baseSpecies)) {\n\t\t\tspecies = Dex.species.get(species.baseSpecies);\n\t\t}\n\t\tif (levelOverride[species.id]) return levelOverride[species.id];\n\n\t\tswitch (species.tier) {\n\t\tcase 'AG': return 60;\n\t\tcase 'Uber': return 70;\n\t\tcase 'OU': case 'Unreleased': return 80;\n\t\tcase 'UU': return 90;\n\t\tcase 'LC': case 'NFE': return 100;\n\t\t}\n\n\t\treturn 100;\n\t}\n\n\t/**\n\t * Picks a choice from `choices` based on the weights in `weights`.\n\t * `weights` must be the same length as `choices`.\n\t */\n\tweightedRandomPick<T>(\n\t\tchoices: T[],\n\t\tweights: number[],\n\t\toptions?: { remove?: boolean }\n\t) {\n\t\tif (!choices.length) throw new Error(`Can't pick from an empty list`);\n\t\tif (choices.length !== weights.length) throw new Error(`Choices and weights must be the same length`);\n\n\t\t/* console.log(choices.reduce((acc, element, index) => {\n\t\t\treturn {\n\t\t\t\t ...acc,\n\t\t\t\t [element as string]: weights[index],\n\t\t\t};\n\t }, {})) */\n\n\t\tconst totalWeight = weights.reduce((a, b) => a + b, 0);\n\n\t\tlet randomWeight = this.prng.random(0, totalWeight);\n\t\tfor (let i = 0; i < choices.length; i++) {\n\t\t\trandomWeight -= weights[i];\n\t\t\tif (randomWeight < 0) {\n\t\t\t\tconst choice = choices[i];\n\t\t\t\tif (options?.remove) choices.splice(i, 1);\n\t\t\t\treturn choice;\n\t\t\t}\n\t\t}\n\n\t\tif (options?.remove && choices.length) return choices.pop()!;\n\t\treturn choices[choices.length - 1];\n\t}\n\n\tsetSeed(seed: PRNGSeed) {\n\t\tthis.prng.setSeed(seed);\n\t}\n}\n"], | |
"mappings": "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", | |
"names": ["moveID", "move", "weight"] | |
} | |