Spaces:
Running
Running
; | |
var __defProp = Object.defineProperty; | |
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | |
var __getOwnPropNames = Object.getOwnPropertyNames; | |
var __hasOwnProp = Object.prototype.hasOwnProperty; | |
var __export = (target, all) => { | |
for (var name in all) | |
__defProp(target, name, { get: all[name], enumerable: true }); | |
}; | |
var __copyProps = (to, from, except, desc) => { | |
if (from && typeof from === "object" || typeof from === "function") { | |
for (let key of __getOwnPropNames(from)) | |
if (!__hasOwnProp.call(to, key) && key !== except) | |
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | |
} | |
return to; | |
}; | |
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | |
var dex_species_exports = {}; | |
__export(dex_species_exports, { | |
DexSpecies: () => DexSpecies, | |
Learnset: () => Learnset, | |
Species: () => Species | |
}); | |
module.exports = __toCommonJS(dex_species_exports); | |
var import_dex_data = require("./dex-data"); | |
var import_utils = require("../lib/utils"); | |
var import_node_util = require("node:util"); | |
class Species extends import_dex_data.BasicEffect { | |
constructor(data) { | |
super(data); | |
this.fullname = `pokemon: ${data.name}`; | |
this.effectType = "Pokemon"; | |
this.baseSpecies = data.baseSpecies || this.name; | |
this.forme = data.forme || ""; | |
this.baseForme = data.baseForme || ""; | |
this.cosmeticFormes = data.cosmeticFormes || void 0; | |
this.otherFormes = data.otherFormes || void 0; | |
this.formeOrder = data.formeOrder || void 0; | |
this.spriteid = data.spriteid || (0, import_dex_data.toID)(this.baseSpecies) + (this.baseSpecies !== this.name ? `-${(0, import_dex_data.toID)(this.forme)}` : ""); | |
this.abilities = data.abilities || { 0: "" }; | |
this.types = data.types || ["???"]; | |
this.addedType = data.addedType || void 0; | |
this.prevo = data.prevo || ""; | |
this.tier = data.tier || ""; | |
this.doublesTier = data.doublesTier || ""; | |
this.natDexTier = data.natDexTier || ""; | |
this.evos = data.evos || []; | |
this.evoType = data.evoType || void 0; | |
this.evoMove = data.evoMove || void 0; | |
this.evoLevel = data.evoLevel || void 0; | |
this.nfe = data.nfe || false; | |
this.eggGroups = data.eggGroups || []; | |
this.canHatch = data.canHatch || false; | |
this.gender = data.gender || ""; | |
this.genderRatio = data.genderRatio || (this.gender === "M" ? { M: 1, F: 0 } : this.gender === "F" ? { M: 0, F: 1 } : this.gender === "N" ? { M: 0, F: 0 } : { M: 0.5, F: 0.5 }); | |
this.requiredItem = data.requiredItem || void 0; | |
this.requiredItems = data.requiredItems || (this.requiredItem ? [this.requiredItem] : void 0); | |
this.baseStats = data.baseStats || { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 }; | |
this.bst = this.baseStats.hp + this.baseStats.atk + this.baseStats.def + this.baseStats.spa + this.baseStats.spd + this.baseStats.spe; | |
this.weightkg = data.weightkg || 0; | |
this.weighthg = this.weightkg * 10; | |
this.heightm = data.heightm || 0; | |
this.color = data.color || ""; | |
this.tags = data.tags || []; | |
this.unreleasedHidden = data.unreleasedHidden || false; | |
this.maleOnlyHidden = !!data.maleOnlyHidden; | |
this.maxHP = data.maxHP || void 0; | |
this.isMega = !!(this.forme && ["Mega", "Mega-X", "Mega-Y"].includes(this.forme)) || void 0; | |
this.canGigantamax = data.canGigantamax || void 0; | |
this.gmaxUnreleased = !!data.gmaxUnreleased; | |
this.cannotDynamax = !!data.cannotDynamax; | |
this.battleOnly = data.battleOnly || (this.isMega ? this.baseSpecies : void 0); | |
this.changesFrom = data.changesFrom || (this.battleOnly !== this.baseSpecies ? this.battleOnly : this.baseSpecies); | |
if (Array.isArray(this.changesFrom)) | |
this.changesFrom = this.changesFrom[0]; | |
this.pokemonGoData = data.pokemonGoData || void 0; | |
if (!this.gen && this.num >= 1) { | |
if (this.num >= 906 || this.forme.includes("Paldea")) { | |
this.gen = 9; | |
} else if (this.num >= 810 || ["Gmax", "Galar", "Galar-Zen", "Hisui"].includes(this.forme)) { | |
this.gen = 8; | |
} else if (this.num >= 722 || this.forme.startsWith("Alola") || this.forme === "Starter") { | |
this.gen = 7; | |
} else if (this.forme === "Primal") { | |
this.gen = 6; | |
this.isPrimal = true; | |
this.battleOnly = this.baseSpecies; | |
} else if (this.num >= 650 || this.isMega) { | |
this.gen = 6; | |
} else if (this.num >= 494) { | |
this.gen = 5; | |
} else if (this.num >= 387) { | |
this.gen = 4; | |
} else if (this.num >= 252) { | |
this.gen = 3; | |
} else if (this.num >= 152) { | |
this.gen = 2; | |
} else { | |
this.gen = 1; | |
} | |
} | |
(0, import_dex_data.assignMissingFields)(this, data); | |
} | |
} | |
const EMPTY_SPECIES = import_utils.Utils.deepFreeze(new Species({ | |
id: "", | |
name: "", | |
exists: false, | |
tier: "Illegal", | |
doublesTier: "Illegal", | |
natDexTier: "Illegal", | |
isNonstandard: "Custom" | |
})); | |
class Learnset { | |
constructor(data, species) { | |
this.exists = true; | |
this.effectType = "Learnset"; | |
this.learnset = data.learnset || void 0; | |
this.eventOnly = !!data.eventOnly; | |
this.eventData = data.eventData || void 0; | |
this.encounters = data.encounters || void 0; | |
this.species = species; | |
} | |
} | |
class DexSpecies { | |
constructor(dex) { | |
this.speciesCache = /* @__PURE__ */ new Map(); | |
this.learnsetCache = /* @__PURE__ */ new Map(); | |
this.allCache = null; | |
this.dex = dex; | |
} | |
get(name) { | |
if (name && typeof name !== "string") | |
return name; | |
let id = ""; | |
if (name) { | |
name = name.trim(); | |
id = (0, import_dex_data.toID)(name); | |
if (id === "nidoran" && name.endsWith("\u2640")) { | |
id = "nidoranf"; | |
} else if (id === "nidoran" && name.endsWith("\u2642")) { | |
id = "nidoranm"; | |
} | |
} | |
return this.getByID(id); | |
} | |
getByID(id) { | |
if (id === "") | |
return EMPTY_SPECIES; | |
let species = this.speciesCache.get(id); | |
if (species) | |
return species; | |
if (this.dex.data.Aliases.hasOwnProperty(id)) { | |
if (this.dex.data.FormatsData.hasOwnProperty(id)) { | |
const baseId = (0, import_dex_data.toID)(this.dex.data.Aliases[id]); | |
species = new Species({ | |
...this.dex.data.Pokedex[baseId], | |
...this.dex.data.FormatsData[id], | |
name: id | |
}); | |
species.abilities = { 0: species.abilities["S"] }; | |
} else { | |
species = this.get(this.dex.data.Aliases[id]); | |
if (species.cosmeticFormes) { | |
for (const forme of species.cosmeticFormes) { | |
if ((0, import_dex_data.toID)(forme) === id) { | |
species = new Species({ | |
...species, | |
name: forme, | |
forme: forme.slice(species.name.length + 1), | |
baseForme: "", | |
baseSpecies: species.name, | |
otherFormes: null, | |
cosmeticFormes: null | |
}); | |
break; | |
} | |
} | |
} | |
} | |
this.speciesCache.set(id, this.dex.deepFreeze(species)); | |
return species; | |
} | |
if (!this.dex.data.Pokedex.hasOwnProperty(id)) { | |
let aliasTo = ""; | |
const formeNames = { | |
alola: ["a", "alola", "alolan"], | |
galar: ["g", "galar", "galarian"], | |
hisui: ["h", "hisui", "hisuian"], | |
paldea: ["p", "paldea", "paldean"], | |
mega: ["m", "mega"], | |
primal: ["p", "primal"] | |
}; | |
for (const forme in formeNames) { | |
let pokeName = ""; | |
for (const i of formeNames[forme]) { | |
if (id.startsWith(i)) { | |
pokeName = id.slice(i.length); | |
} else if (id.endsWith(i)) { | |
pokeName = id.slice(0, -i.length); | |
} | |
} | |
if (this.dex.data.Aliases.hasOwnProperty(pokeName)) | |
pokeName = (0, import_dex_data.toID)(this.dex.data.Aliases[pokeName]); | |
if (this.dex.data.Pokedex[pokeName + forme]) { | |
aliasTo = pokeName + forme; | |
break; | |
} | |
} | |
if (aliasTo) { | |
species = this.get(aliasTo); | |
if (species.exists) { | |
this.speciesCache.set(id, species); | |
return species; | |
} | |
} | |
} | |
if (id && this.dex.data.Pokedex.hasOwnProperty(id)) { | |
const pokedexData = this.dex.data.Pokedex[id]; | |
const baseSpeciesTags = pokedexData.baseSpecies && this.dex.data.Pokedex[(0, import_dex_data.toID)(pokedexData.baseSpecies)].tags; | |
species = new Species({ | |
tags: baseSpeciesTags, | |
...pokedexData, | |
...this.dex.data.FormatsData[id] | |
}); | |
const baseSpeciesStatuses = this.dex.data.Conditions[(0, import_dex_data.toID)(species.baseSpecies)]; | |
if (baseSpeciesStatuses !== void 0) { | |
for (const key in baseSpeciesStatuses) { | |
if (!(key in species)) { | |
species[key] = baseSpeciesStatuses[key]; | |
} | |
} | |
} | |
if (!species.tier && !species.doublesTier && !species.natDexTier && species.baseSpecies !== species.name) { | |
if (species.baseSpecies === "Mimikyu") { | |
species.tier = this.dex.data.FormatsData[(0, import_dex_data.toID)(species.baseSpecies)].tier || "Illegal"; | |
species.doublesTier = this.dex.data.FormatsData[(0, import_dex_data.toID)(species.baseSpecies)].doublesTier || "Illegal"; | |
species.natDexTier = this.dex.data.FormatsData[(0, import_dex_data.toID)(species.baseSpecies)].natDexTier || "Illegal"; | |
} else if (species.id.endsWith("totem")) { | |
species.tier = this.dex.data.FormatsData[species.id.slice(0, -5)].tier || "Illegal"; | |
species.doublesTier = this.dex.data.FormatsData[species.id.slice(0, -5)].doublesTier || "Illegal"; | |
species.natDexTier = this.dex.data.FormatsData[species.id.slice(0, -5)].natDexTier || "Illegal"; | |
} else if (species.battleOnly) { | |
species.tier = this.dex.data.FormatsData[(0, import_dex_data.toID)(species.battleOnly)].tier || "Illegal"; | |
species.doublesTier = this.dex.data.FormatsData[(0, import_dex_data.toID)(species.battleOnly)].doublesTier || "Illegal"; | |
species.natDexTier = this.dex.data.FormatsData[(0, import_dex_data.toID)(species.battleOnly)].natDexTier || "Illegal"; | |
} else { | |
const baseFormatsData = this.dex.data.FormatsData[(0, import_dex_data.toID)(species.baseSpecies)]; | |
if (!baseFormatsData) { | |
throw new Error(`${species.baseSpecies} has no formats-data entry`); | |
} | |
species.tier = baseFormatsData.tier || "Illegal"; | |
species.doublesTier = baseFormatsData.doublesTier || "Illegal"; | |
species.natDexTier = baseFormatsData.natDexTier || "Illegal"; | |
} | |
} | |
if (!species.tier) | |
species.tier = "Illegal"; | |
if (!species.doublesTier) | |
species.doublesTier = species.tier; | |
if (!species.natDexTier) | |
species.natDexTier = species.tier; | |
if (species.gen > this.dex.gen) { | |
species.tier = "Illegal"; | |
species.doublesTier = "Illegal"; | |
species.natDexTier = "Illegal"; | |
species.isNonstandard = "Future"; | |
} | |
if (this.dex.currentMod === "gen7letsgo" && !species.isNonstandard) { | |
const isLetsGo = (species.num <= 151 || ["Meltan", "Melmetal"].includes(species.name)) && (!species.forme || ["Alola", "Mega", "Mega-X", "Mega-Y", "Starter"].includes(species.forme) && species.name !== "Pikachu-Alola"); | |
if (!isLetsGo) | |
species.isNonstandard = "Past"; | |
} | |
if (this.dex.currentMod === "gen8bdsp" && (!species.isNonstandard || ["Gigantamax", "CAP"].includes(species.isNonstandard))) { | |
if (species.gen > 4 || species.num < 1 && species.isNonstandard !== "CAP" || species.id === "pichuspikyeared") { | |
species.isNonstandard = "Future"; | |
species.tier = species.doublesTier = species.natDexTier = "Illegal"; | |
} | |
} | |
species.nfe = species.evos.some((evo) => { | |
const evoSpecies = this.get(evo); | |
return !evoSpecies.isNonstandard || evoSpecies.isNonstandard === species?.isNonstandard || // Pokemon with Hisui evolutions | |
evoSpecies.isNonstandard === "Unobtainable"; | |
}); | |
species.canHatch = species.canHatch || !["Ditto", "Undiscovered"].includes(species.eggGroups[0]) && !species.prevo && species.name !== "Manaphy"; | |
if (this.dex.gen === 1) | |
species.bst -= species.baseStats.spd; | |
if (this.dex.gen < 5) { | |
species.abilities = this.dex.deepClone(species.abilities); | |
delete species.abilities["H"]; | |
} | |
if (this.dex.gen === 3 && this.dex.abilities.get(species.abilities["1"]).gen === 4) | |
delete species.abilities["1"]; | |
if (this.dex.parentMod) { | |
const parentMod = this.dex.mod(this.dex.parentMod); | |
if (this.dex.data.Pokedex[id] === parentMod.data.Pokedex[id]) { | |
const parentSpecies = parentMod.species.getByID(id); | |
if (species.tier === parentSpecies.tier && (0, import_node_util.isDeepStrictEqual)(species, parentSpecies)) { | |
species = parentSpecies; | |
} | |
} | |
} | |
} else { | |
species = new Species({ | |
id, | |
name: id, | |
exists: false, | |
tier: "Illegal", | |
doublesTier: "Illegal", | |
natDexTier: "Illegal", | |
isNonstandard: "Custom" | |
}); | |
} | |
if (species.exists) | |
this.speciesCache.set(id, this.dex.deepFreeze(species)); | |
return species; | |
} | |
/** | |
* @param id the ID of the species the move pool belongs to | |
* @param isNatDex | |
* @returns a Set of IDs of the full valid movepool of the given species for the current generation/mod. | |
* Note that inter-move incompatibilities, such as those from exclusive events, are not considered and all moves are | |
* lumped together. However, Necturna and Necturine's Sketchable moves are omitted from this pool, as their fundamental | |
* incompatibility with each other is essential to the nature of those species. | |
*/ | |
getMovePool(id, isNatDex = false) { | |
let eggMovesOnly = false; | |
let maxGen = this.dex.gen; | |
const gen3HMMoves = ["cut", "fly", "surf", "strength", "flash", "rocksmash", "waterfall", "dive"]; | |
const gen4HMMoves = ["cut", "fly", "surf", "strength", "rocksmash", "waterfall", "rockclimb"]; | |
const movePool = /* @__PURE__ */ new Set(); | |
for (const { species, learnset } of this.getFullLearnset(id)) { | |
if (!eggMovesOnly) | |
eggMovesOnly = this.eggMovesOnly(species, this.get(id)); | |
for (const moveid in learnset) { | |
if (species.isNonstandard !== "CAP") { | |
if (gen4HMMoves.includes(moveid) && this.dex.gen >= 5) { | |
if (!learnset[moveid].some((source) => parseInt(source.charAt(0)) >= 5 && parseInt(source.charAt(0)) <= this.dex.gen)) | |
continue; | |
} else if (gen3HMMoves.includes(moveid) && this.dex.gen >= 4 && !learnset[moveid].some( | |
(source) => parseInt(source.charAt(0)) >= 4 && parseInt(source.charAt(0)) <= this.dex.gen | |
)) { | |
continue; | |
} | |
} | |
if (eggMovesOnly) { | |
if (learnset[moveid].some((source) => source.startsWith("9E"))) { | |
movePool.add(moveid); | |
} | |
} else if (maxGen >= 9) { | |
if (isNatDex || learnset[moveid].some((source) => source.startsWith("9"))) { | |
movePool.add(moveid); | |
} | |
} else { | |
if (learnset[moveid].some((source) => parseInt(source.charAt(0)) <= maxGen)) { | |
movePool.add(moveid); | |
} | |
} | |
if (moveid === "sketch" && movePool.has("sketch")) { | |
if (species.isNonstandard === "CAP") { | |
continue; | |
} | |
const sketchables = this.dex.moves.all().filter((m) => !m.flags["nosketch"] && !m.isNonstandard); | |
for (const move of sketchables) { | |
movePool.add(move.id); | |
} | |
break; | |
} | |
} | |
if (species.evoRegion) { | |
if (this.dex.gen >= 9) | |
eggMovesOnly = true; | |
if (this.dex.gen === 8 && species.evoRegion === "Alola") | |
maxGen = 7; | |
} | |
} | |
return movePool; | |
} | |
getFullLearnset(id) { | |
const originalSpecies = this.get(id); | |
let species = originalSpecies; | |
const out = []; | |
const alreadyChecked = {}; | |
while (species?.name && !alreadyChecked[species.id]) { | |
alreadyChecked[species.id] = true; | |
const learnset = this.getLearnsetData(species.id); | |
if (learnset.learnset) { | |
out.push(learnset); | |
species = this.learnsetParent(species, true); | |
continue; | |
} | |
if ((species.changesFrom || species.baseSpecies) !== species.name) { | |
species = this.get(species.changesFrom || species.baseSpecies); | |
continue; | |
} | |
if (species.isNonstandard) { | |
return out; | |
} | |
if (species.prevo && this.getLearnsetData((0, import_dex_data.toID)(species.prevo)).learnset) { | |
species = this.get((0, import_dex_data.toID)(species.prevo)); | |
continue; | |
} | |
throw new Error(`Species with no learnset data: ${species.id}`); | |
} | |
return out; | |
} | |
learnsetParent(species, checkingMoves = false) { | |
if (["Gastrodon", "Pumpkaboo", "Sinistea", "Tatsugiri"].includes(species.baseSpecies) && species.forme) { | |
return this.get(species.baseSpecies); | |
} else if (species.prevo) { | |
species = this.get(species.prevo); | |
if (species.gen > Math.max(2, this.dex.gen)) | |
return null; | |
return species; | |
} else if (species.changesFrom && species.baseSpecies !== "Kyurem") { | |
return this.get(species.changesFrom); | |
} else if (checkingMoves && !species.prevo && species.baseSpecies && this.get(species.baseSpecies).prevo) { | |
let baseEvo = this.get(species.baseSpecies); | |
while (baseEvo.prevo) { | |
baseEvo = this.get(baseEvo.prevo); | |
} | |
return baseEvo; | |
} | |
return null; | |
} | |
/** | |
* Gets the raw learnset data for the species. | |
* | |
* In practice, if you're trying to figure out what moves a pokemon learns, | |
* you probably want to `getFullLearnset` or `getMovePool` instead. | |
*/ | |
getLearnsetData(id) { | |
let learnsetData = this.learnsetCache.get(id); | |
if (learnsetData) | |
return learnsetData; | |
if (!this.dex.data.Learnsets.hasOwnProperty(id)) { | |
return new Learnset({ exists: false }, this.get(id)); | |
} | |
learnsetData = new Learnset(this.dex.data.Learnsets[id], this.get(id)); | |
this.learnsetCache.set(id, this.dex.deepFreeze(learnsetData)); | |
return learnsetData; | |
} | |
getPokemonGoData(id) { | |
return this.dex.data.PokemonGoData[id]; | |
} | |
all() { | |
if (this.allCache) | |
return this.allCache; | |
const species = []; | |
for (const id in this.dex.data.Pokedex) { | |
species.push(this.getByID(id)); | |
} | |
this.allCache = Object.freeze(species); | |
return this.allCache; | |
} | |
eggMovesOnly(child, father) { | |
if (child.baseSpecies === father?.baseSpecies) | |
return false; | |
while (father) { | |
if (father.name === child.name) | |
return false; | |
father = this.learnsetParent(father); | |
} | |
return true; | |
} | |
} | |
//# sourceMappingURL=dex-species.js.map | |