UNPKG

pogo-data-generator

Version:
1,073 lines (1,072 loc) 48.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const pogo_protos_1 = require("@na-ji/pogo-protos"); const Masterfile_1 = __importDefault(require("./Masterfile")); const PokeApi_1 = __importDefault(require("./PokeApi")); class Pokemon extends Masterfile_1.default { constructor(options) { super(); this.options = options; this.formsToSkip = this.options.skipForms ? this.options.skipForms.map((name) => name.toLowerCase()) : []; this.parsedPokemon = {}; this.parsedForms = { 0: { formName: options.unsetFormName ?? 'Unset', proto: 'FORM_UNSET', formId: 0, }, }; this.formsRef = {}; this.evolvedPokemon = new Set(); this.generations = { 1: { name: 'Kanto', range: [1, 151], }, 2: { name: 'Johto', range: [152, 251], }, 3: { name: 'Hoenn', range: [252, 386], }, 4: { name: 'Sinnoh', range: [387, 493], }, 5: { name: 'Unova', range: [494, 649], }, 6: { name: 'Kalos', range: [650, 721], }, 7: { name: 'Alola', range: [722, 809], }, 8: { name: 'Galar', range: [810, 905], }, 9: { name: 'Paldea', range: [906, 1010], }, }; this.evolutionQuests = {}; this.parsedCostumes = {}; this.jungleCupRules = { types: [], banned: [] }; } pokemonName(id) { try { switch (id) { case 29: return 'Nidoran♀'; case 32: return 'Nidoran♂'; default: return this.capitalize(pogo_protos_1.Rpc.HoloPokemonId[id]); } } catch (e) { console.warn(e, `Failed to set pokemon name for ${id}`); } } formName(id, formName) { if (!formName) return ''; try { const name = formName.substring(id === pogo_protos_1.Rpc.HoloPokemonId.NIDORAN_FEMALE || id === pogo_protos_1.Rpc.HoloPokemonId.NIDORAN_MALE ? 8 : pogo_protos_1.Rpc.HoloPokemonId[id].length + 1); return this.capitalize(name); } catch (e) { console.warn(e, `Failed to lookup form name for ${formName}, ID#`, id); } } skipForms(formName) { if (!formName) return false; try { return this.formsToSkip.some((form) => formName.toLowerCase() === form); } catch (e) { console.warn(e, `Failed to skip forms for ${formName}`); } } lookupPokemon(name) { if (!name) return ''; try { for (const key of Object.keys(pogo_protos_1.Rpc.HoloPokemonId)) { if (name.startsWith('PORYGON_Z_')) { return 'PORYGON_Z'; } else if (name.startsWith(`${key}_`)) { return key; } } } catch (e) { console.warn(e, `Failed to lookup pokemon for ${name}`); } } lookupForm(id) { if (!id) return ''; try { return (Object.entries(pogo_protos_1.Rpc.PokemonDisplayProto.Form).find(([_, v]) => { return v === id; })?.[0] || ''); } catch (e) { console.warn(e, `Failed to lookup form for ${id}`); } } getGeneration(id) { try { const genInfo = {}; genInfo.genId = +Object.keys(this.generations).find((gen) => { return (id >= this.generations[gen].range[0] && id <= this.generations[gen].range[1]); }); if (genInfo.genId) { genInfo.generation = this.generations[genInfo.genId].name; } return genInfo; } catch (e) { console.warn(e, `Failed to lookup generation for ${id}`); } } getMoves(moves) { if (!moves) return []; try { return moves .map((move) => typeof move === 'string' ? pogo_protos_1.Rpc.HoloPokemonMove[move] : move) .filter(Boolean) .sort((a, b) => a - b); } catch (e) { console.warn(e, `Failed to lookup moves for ${moves}`); } } getTypes(incomingTypes) { if (!incomingTypes) return []; try { if (!incomingTypes[1]) { incomingTypes.pop(); } return incomingTypes .map((type) => typeof type === 'string' ? pogo_protos_1.Rpc.HoloPokemonType[type] : type) .filter(Boolean) .sort((a, b) => a - b); } catch (e) { console.warn(e, `Failed to lookup types for ${incomingTypes}`); } } getCostumeOverrides(costumes) { try { return costumes.map((costume) => ({ costumeId: pogo_protos_1.Rpc.PokemonDisplayProto.Costume[costume], costumeProto: costume, costumeName: this.capitalize(costume), })); } catch (e) { console.warn('Failed to process costume overrides', e, costumes); } } compileEvos(mfObject) { switch (mfObject[0].evolution) { case 'RAICHU': if (mfObject.length > 1) { console.warn('Alolan Raichu added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.RAICHU); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.RAICHU, candyCost: 50 }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.RAICHU, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.RAICHU_ALOLA, candyCost: 50, }, ]; } case 'EXEGGUTOR': if (mfObject.length > 1) { console.warn('Alolan Exeggutor added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.EXEGGUTOR); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.EXEGGUTOR, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.EXEGGUTOR_NORMAL, candyCost: 50, }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.EXEGGUTOR, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.EXEGGUTOR_ALOLA, candyCost: 50, }, ]; } case 'MAROWAK': if (mfObject.length > 1) { console.warn('Alolan Marowak added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.MAROWAK); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.MAROWAK, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.MAROWAK_NORMAL, candyCost: 50, }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.MAROWAK, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.MAROWAK_ALOLA, candyCost: 50, }, ]; } case 'WEEZING': if (mfObject.length > 1) { console.warn('Galarian Weezing added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.WEEZING); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.WEEZING, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.WEEZING_NORMAL, candyCost: 50, }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.WEEZING, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.WEEZING_GALARIAN, candyCost: 50, }, ]; } case 'MR_MIME': if (mfObject.length > 1) { console.warn('Galarian Mr Mime added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.MR_MIME); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.MR_MIME, candyCost: 50, questRequirement: 'MR_MIME_EVOLUTION_QUEST', }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.MR_MIME, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.MR_MIME_GALARIAN, candyCost: 50, }, ]; } case 'TYPHLOSION': if (mfObject.length > 1) { console.warn('Hisuian Typhlosion added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.TYPHLOSION); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.TYPHLOSION, candyCost: 100 }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.TYPHLOSION, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.TYPHLOSION_HISUIAN, candyCost: 100, }, ]; } case 'SAMUROTT': if (mfObject.length > 1) { console.warn('Hisuian Samurott added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.SAMUROTT); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.SAMUROTT, candyCost: 100 }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.SAMUROTT, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.SAMUROTT_HISUIAN, candyCost: 100, }, ]; } case 'LILLIGANT': if (mfObject.length > 1) { console.warn('Hisuian Lilligant added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.LILLIGANT); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.LILLIGANT, candyCost: 50, itemRequirement: pogo_protos_1.Rpc.Item.ITEM_SUN_STONE, }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.LILLIGANT, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.LILLIGANT_HISUIAN, candyCost: 50, }, ]; } case 'BRAVIARY': if (mfObject.length > 1) { console.warn('Hisuian Braviary added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.BRAVIARY); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.BRAVIARY, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.BRAVIARY_NORMAL, candyCost: 50, }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.BRAVIARY, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.BRAVIARY_HISUIAN, candyCost: 50, }, ]; } case 'SLIGGOO': if (mfObject.length > 1) { console.warn('Hisuian Sliggoo added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.SLIGGOO); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.SLIGGOO, candyCost: 25 }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.SLIGGOO, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.SLIGGOO_HISUIAN, candyCost: 25, }, ]; } case 'AVALUGG': if (mfObject.length > 1) { console.warn('Hisuian Avalugg added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.AVALUGG); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.AVALUGG, candyCost: 50 }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.AVALUGG, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.AVALUGG_HISUIAN, candyCost: 50, }, ]; } case 'DECIDUEYE': if (mfObject.length > 1) { console.warn('Hisuian Decidueye added', mfObject.length); break; } else { this.evolvedPokemon.add(pogo_protos_1.Rpc.HoloPokemonId.DECIDUEYE); return [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.DECIDUEYE, candyCost: 100 }, { evoId: pogo_protos_1.Rpc.HoloPokemonId.DECIDUEYE, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.DECIDUEYE_HISUIAN, candyCost: 100, }, ]; } } try { const evolutions = []; mfObject.forEach((branch) => { if (branch.temporaryEvolution) { return; } else if (branch.evolution) { const id = pogo_protos_1.Rpc.HoloPokemonId[branch.evolution]; const formId = pogo_protos_1.Rpc.PokemonDisplayProto.Form[branch.form]; evolutions.push({ evoId: id, formId: this.options.includeUnset ? formId || 0 : formId, genderRequirement: this.options.genderString ? this.genders[pogo_protos_1.Rpc.PokemonDisplayProto.Gender[branch.genderRequirement]] : pogo_protos_1.Rpc.PokemonDisplayProto.Gender[branch.genderRequirement], candyCost: branch.candyCost, itemRequirement: pogo_protos_1.Rpc.Item[branch.evolutionItemRequirement], tradeBonus: branch.noCandyCostViaTrade, mustBeBuddy: branch.mustBeBuddy, onlyDaytime: branch.onlyDaytime, onlyNighttime: branch.onlyNighttime, questRequirement: branch.questDisplay ? branch.questDisplay[0].questRequirementTemplateId : undefined, }); this.evolvedPokemon.add(id); } }); return evolutions.sort((a, b) => a.evoId - b.evoId); } catch (e) { console.warn(e, `Failed to compile evos for ${JSON.stringify(mfObject, null, 2)}`); } } compileTempEvos(mfObject, evoBranch, primaryForm) { try { const tempEvolutions = mfObject .filter((tempEvo) => tempEvo.stats) .map((tempEvo) => { const newTempEvolution = { tempEvoId: pogo_protos_1.Rpc.HoloTemporaryEvolutionId[tempEvo.tempEvoId], }; switch (true) { case tempEvo.stats.baseAttack !== primaryForm.attack: case tempEvo.stats.baseDefense !== primaryForm.defense: case tempEvo.stats.baseStamina !== primaryForm.stamina: newTempEvolution.attack = tempEvo.stats.baseAttack; newTempEvolution.defense = tempEvo.stats.baseDefense; newTempEvolution.stamina = tempEvo.stats.baseStamina; } if (tempEvo.averageHeightM !== primaryForm.height) { newTempEvolution.height = tempEvo.averageHeightM; } if (tempEvo.averageWeightKg !== primaryForm.weight) { newTempEvolution.weight = tempEvo.averageWeightKg; } const types = this.getTypes([ tempEvo.typeOverride1, tempEvo.typeOverride2, ]); if (!this.compare(types, primaryForm.types)) { newTempEvolution.types = types; } const energy = evoBranch.find((branch) => branch.temporaryEvolution === tempEvo.tempEvoId); if (energy) { newTempEvolution.firstEnergyCost = energy.temporaryEvolutionEnergyCost; newTempEvolution.subsequentEnergyCost = energy.temporaryEvolutionEnergyCostSubsequent; } return newTempEvolution; }); return tempEvolutions.sort((a, b) => a.tempEvoId - b.tempEvoId); } catch (e) { console.warn(e, `Failed to compile temp evos for ${JSON.stringify(mfObject, null, 2)}`); } } generateProtoForms() { Object.entries(pogo_protos_1.Rpc.PokemonDisplayProto.Form).forEach((proto) => { const [name, formId] = proto; try { const pokemon = name.startsWith('NIDORAN_') ? ['NIDORAN_FEMALE', 'NIDORAN_MALE'] : [this.formsRef[name] || this.lookupPokemon(name)]; for (const pkmn of pokemon) { if (pkmn) { const id = pogo_protos_1.Rpc.HoloPokemonId[pkmn]; const formName = this.formName(id, name); if (!this.parsedPokemon[id]) { this.parsedPokemon[id] = { pokemonName: this.pokemonName(id), forms: this.options.includeUnset && !this.options.noFormPlaceholders ? [0] : [], pokedexId: id, defaultFormId: 0, ...this.getGeneration(+id), }; } if (!this.skipForms(formName) && !(this.parsedPokemon[id].defaultFormId === 0 && formName === 'Normal' && this.options.skipNormalIfUnset)) { this.parsedForms[formId] = { ...this.parsedForms[formId], formName, proto: name, formId: +formId, }; switch (formId) { case pogo_protos_1.Rpc.PokemonDisplayProto.Form.LILLIGANT_HISUIAN: this.addFormBaseStats(formId, 70, 105, 75, 50, 75, 105); break; case pogo_protos_1.Rpc.PokemonDisplayProto.Form.SLIGGOO_HISUIAN: this.addFormBaseStats(formId, 58, 75, 83, 83, 123, 40); if (this.parsedForms[formId].evolutions) { console.warn('Hisuian Sliggoo evolution added'); } else { this.parsedForms[formId].evolutions = [ { evoId: pogo_protos_1.Rpc.HoloPokemonId.GOODRA, formId: pogo_protos_1.Rpc.PokemonDisplayProto.Form.GOODRA_HISUIAN, candyCost: 100, }, ]; } break; case pogo_protos_1.Rpc.PokemonDisplayProto.Form.GOODRA_HISUIAN: this.addFormBaseStats(formId, 80, 100, 100, 110, 150, 60); break; } if (!this.parsedPokemon[id].forms.includes(+formId)) { this.parsedPokemon[id].forms.push(+formId); } } } } } catch (e) { console.warn(e, '\n', proto); } }); } addExtendedStats(object) { if ('pokemonExtendedSettings' in object.data) { const id = pogo_protos_1.Rpc.HoloPokemonId[object.data.pokemonExtendedSettings.uniqueId]; if (id) { if (!this.parsedPokemon[id]) { this.parsedPokemon[id] = {}; } const values = Object.entries(object.data.pokemonExtendedSettings.sizeSettings).map(([name, value]) => ({ name, value })); const protoForm = object.data.pokemonExtendedSettings.form ? pogo_protos_1.Rpc.PokemonDisplayProto.Form[object.data.pokemonExtendedSettings.form] : 0; if (protoForm) { if (!this.parsedForms[protoForm]) { this.parsedForms[protoForm] = {}; } this.parsedForms[protoForm].sizeSettings = values; } else { this.parsedPokemon[id].sizeSettings = values; } } } } cleanExtendedStats() { Object.values(this.parsedPokemon).forEach((pkmn) => { if (pkmn.sizeSettings && pkmn.forms) { const pkmnSizeTree = Object.fromEntries(pkmn.sizeSettings.map(({ name, value }) => [name, value])); pkmn.forms.forEach((formId) => { if (this.parsedForms[formId]?.sizeSettings) { if (this.parsedForms[formId].sizeSettings.every((size) => pkmnSizeTree[size.name] == size.value)) { delete this.parsedForms[formId].sizeSettings; } } }); } }); } addFormBaseStats(formId, hp, a, d, sa, sd, sp) { if (this.parsedForms[formId].attack || this.parsedForms[formId].defense || this.parsedForms[formId].stamina) { console.warn('Base stats already found for', pogo_protos_1.Rpc.PokemonDisplayProto.Form[formId]); return; } this.parsedForms[formId].attack = PokeApi_1.default.attack(a, sa, sp); this.parsedForms[formId].defense = PokeApi_1.default.defense(d, sd, sp); this.parsedForms[formId].stamina = PokeApi_1.default.stamina(hp); } addEvolutionQuest(object) { try { const { evolutionQuestTemplate } = object.data; this.evolutionQuests[object.templateId] = { questType: pogo_protos_1.Rpc.QuestType[evolutionQuestTemplate.questType], target: evolutionQuestTemplate.goals[0].target, assetsRef: evolutionQuestTemplate.display.description.toLowerCase(), }; if (this.evolutionQuests[object.templateId].target) { this.evolutionQuests[object.templateId].assetsRef = this.evolutionQuests[object.templateId].assetsRef.replace('single', 'plural'); } if (evolutionQuestTemplate.goals[1]) { console.warn(`Second quest goal detected, fix it. ${object.templateId}`); } } catch (e) { console.warn(e, `Failed to add evolution quest for ${JSON.stringify(object, null, 2)}`); } } addForm(object) { if (object.templateId.split('_')[1]) { const id = Number(object.templateId.split('_')[1].slice(1)); try { const forms = object.data.formSettings.forms; if (forms) { if (!this.parsedPokemon[id]) { this.parsedPokemon[id] = {}; } if (!this.parsedPokemon[id].forms) { this.parsedPokemon[id].forms = []; } for (let i = 0; i < forms.length; i += 1) { const value = forms[i].form; if (!value) continue; const formId = typeof value === 'number' ? value : pogo_protos_1.Rpc.PokemonDisplayProto.Form[value]; const form = typeof value === 'number' ? this.lookupForm(value) : value; this.formsRef[form] = object.data.formSettings.pokemon; const name = this.formName(id, form); if (i === 0) { this.parsedPokemon[id].defaultFormId = formId || 0; } if (!this.skipForms(name)) { this.parsedForms[formId] = { ...this.parsedForms[formId], formName: name, proto: form, formId, isCostume: forms[i].isCostume, }; } } } else { if (!this.parsedPokemon[id]) { this.parsedPokemon[id] = { pokemonName: this.pokemonName(id), forms: [], pokedexId: id, ...this.getGeneration(+id), }; } } if (this.options.includeUnset && !this.options.noFormPlaceholders) { this.parsedPokemon[id].forms.push(0); } } catch (e) { console.warn(e, '\n', JSON.stringify(object, null, 2)); } } } addPokemon(object) { const { templateId, data: { pokemonSettings }, } = object; const split = templateId.split('_'); const id = Number(split[0].slice(1)); try { if (!this.parsedPokemon[id]) { this.parsedPokemon[id] = {}; } let formId = /^V\d{4}_POKEMON_/.test(templateId) ? pogo_protos_1.Rpc.PokemonDisplayProto.Form[templateId.substring('V9999_POKEMON_'.length)] : null; if (formId) { if (!this.parsedPokemon[id].forms) { this.parsedPokemon[id].forms = []; } const primaryForm = this.parsedPokemon[id]; const formName = this.formName(id, split.filter((word, i) => i > 1 && word).join('_')); if (!this.skipForms(formName)) { this.parsedForms[formId] = { ...this.parsedForms[formId], formName, proto: templateId, formId, }; if (!this.parsedPokemon[id].forms.includes(formId)) { this.parsedPokemon[id].forms.push(formId); } const form = this.parsedForms[formId]; switch (true) { case pokemonSettings.stats.baseAttack !== primaryForm.attack: case pokemonSettings.stats.baseDefense !== primaryForm.defense: case pokemonSettings.stats.baseStamina !== primaryForm.stamina: form.attack = pokemonSettings.stats.baseAttack; form.defense = pokemonSettings.stats.baseDefense; form.stamina = pokemonSettings.stats.baseStamina; } switch (true) { case object.data.pokemonSettings.pokedexHeightM !== primaryForm.height: case object.data.pokemonSettings.pokedexWeightKg !== primaryForm.weight: form.height = object.data.pokemonSettings.pokedexHeightM; form.weight = object.data.pokemonSettings.pokedexWeightKg; } const qMoves = this.getMoves(pokemonSettings.quickMoves); if (!this.compare(qMoves, primaryForm.quickMoves)) { form.quickMoves = qMoves; } const cMoves = this.getMoves(pokemonSettings.cinematicMoves); if (!this.compare(cMoves, primaryForm.chargedMoves)) { form.chargedMoves = cMoves; } const eqMoves = this.getMoves(pokemonSettings.eliteQuickMove); if (!this.compare(eqMoves, primaryForm.eliteQuickMoves)) { form.eliteQuickMoves = eqMoves; } const ecMoves = this.getMoves(pokemonSettings.eliteCinematicMove); if (!this.compare(ecMoves, primaryForm.eliteChargedMoves)) { form.eliteChargedMoves = ecMoves; } const types = this.getTypes([ pokemonSettings.type, pokemonSettings.type2, ]); if (!this.compare(types, primaryForm.types)) { form.types = types; } const family = pogo_protos_1.Rpc.HoloPokemonFamilyId[pokemonSettings.familyId]; if (family !== primaryForm.family) { form.family = family; } if (pokemonSettings.evolutionBranch && pokemonSettings.evolutionBranch.some((evo) => evo.evolution)) { if (!form.evolutions) { form.evolutions = []; } form.evolutions.push(...this.compileEvos(pokemonSettings.evolutionBranch)); } if (pokemonSettings.tempEvoOverrides) { form.tempEvolutions = this.compileTempEvos(pokemonSettings.tempEvoOverrides, pokemonSettings.evolutionBranch, this.parsedPokemon[id]); } if ((form.formName === 'Normal' || form.formName === 'Purified') && primaryForm.tempEvolutions) { form.tempEvolutions = Object.values(primaryForm.tempEvolutions).map((tempEvo) => tempEvo); } if (pokemonSettings.shadow) { form.purificationDust = pokemonSettings.shadow.purificationStardustNeeded; form.purificationCandy = pokemonSettings.shadow.purificationCandyNeeded; } if (pokemonSettings.allowNoevolveEvolution) { form.costumeOverrideEvos = this.getCostumeOverrides(pokemonSettings.allowNoevolveEvolution); } } } else { this.parsedPokemon[id] = { pokemonName: this.pokemonName(id), forms: this.parsedPokemon[id].forms || [], ...this.parsedPokemon[id], pokedexId: id, types: this.getTypes([pokemonSettings.type, pokemonSettings.type2]), attack: pokemonSettings.stats.baseAttack, defense: pokemonSettings.stats.baseDefense, stamina: pokemonSettings.stats.baseStamina, height: pokemonSettings.pokedexHeightM, weight: pokemonSettings.pokedexWeightKg, quickMoves: this.getMoves(pokemonSettings.quickMoves), chargedMoves: this.getMoves(pokemonSettings.cinematicMoves), eliteQuickMoves: this.getMoves(pokemonSettings.eliteQuickMove), eliteChargedMoves: this.getMoves(pokemonSettings.eliteCinematicMove), family: pogo_protos_1.Rpc.HoloPokemonFamilyId[pokemonSettings.familyId], fleeRate: pokemonSettings.encounter.baseFleeRate, captureRate: pokemonSettings.encounter.baseCaptureRate, bonusCandyCapture: pokemonSettings.encounter.bonusCandyCaptureReward, bonusStardustCapture: pokemonSettings.encounter.bonusStardustCaptureReward, legendary: pogo_protos_1.Rpc.HoloPokemonClass[pokemonSettings.pokemonClass] === 1, mythic: pogo_protos_1.Rpc.HoloPokemonClass[pokemonSettings.pokemonClass] === 2, ultraBeast: pogo_protos_1.Rpc.HoloPokemonClass[pokemonSettings.pokemonClass] === 3, buddyGroupNumber: pokemonSettings.buddyGroupNumber, buddyDistance: pokemonSettings.kmBuddyDistance, buddyMegaEnergy: pokemonSettings.buddyWalkedMegaEnergyAward, thirdMoveStardust: pokemonSettings.thirdMove.stardustToUnlock, thirdMoveCandy: pokemonSettings.thirdMove.candyToUnlock, gymDefenderEligible: pokemonSettings.isDeployable, tradable: pokemonSettings.isTradable, transferable: pokemonSettings.isTransferable, ...this.getGeneration(id), }; if (pokemonSettings.evolutionBranch && pokemonSettings.evolutionBranch.some((evo) => evo.evolution)) { this.parsedPokemon[id].evolutions = this.compileEvos(pokemonSettings.evolutionBranch); } if (pokemonSettings.tempEvoOverrides) { this.parsedPokemon[id].tempEvolutions = this.compileTempEvos(pokemonSettings.tempEvoOverrides, pokemonSettings.evolutionBranch, this.parsedPokemon[id]); } if (pokemonSettings.allowNoevolveEvolution) { this.parsedPokemon[id].costumeOverrideEvos = this.getCostumeOverrides(pokemonSettings.allowNoevolveEvolution); } if (pokemonSettings.shadow) { this.parsedPokemon[id].purificationDust = pokemonSettings.shadow.purificationStardustNeeded; this.parsedPokemon[id].purificationCandy = pokemonSettings.shadow.purificationCandyNeeded; } } } catch (e) { console.warn(e, `Failed to parse Pokemon for ${id}`, JSON.stringify(object, null, 2)); } } addSourdoughMoveMappings({ data: { sourdoughMoveMappingSettings: { mappings } } }) { for (let i = 0; i < mappings.length; i += 1) try { let id = pogo_protos_1.Rpc.HoloPokemonId[mappings[i].pokemonId]; if (!this.parsedPokemon[id]) { this.parsedPokemon[id] = {}; } let target = this.parsedPokemon[id]; if (mappings[i].form) { let formId = pogo_protos_1.Rpc.PokemonDisplayProto.Form[mappings[i].form]; if (!this.parsedPokemon[id].forms) { this.parsedPokemon[id].forms = []; } const formName = this.formName(id, mappings[i].form); if (!this.skipForms(formName)) { this.parsedForms[formId] = { ...this.parsedForms[formId], formName, formId, }; if (!this.parsedPokemon[id].forms.includes(formId)) { this.parsedPokemon[id].forms.push(formId); } target = this.parsedForms[formId]; } } target.gmaxMove = pogo_protos_1.Rpc.HoloPokemonMove[mappings[i].move]; } catch (e) { console.warn(e, `Failed to parse gmax move mapping #${i}`, JSON.stringify(mappings[i], null, 2)); } } missingPokemon() { Object.values(pogo_protos_1.Rpc.HoloPokemonId).forEach((id) => { try { if (id) { this.parsedPokemon[id] = { pokemonName: this.pokemonName(+id), pokedexId: +id, defaultFormId: 0, types: [], quickMoves: [], chargedMoves: [], eliteQuickMoves: [], eliteChargedMoves: [], ...this.getGeneration(+id), ...this.parsedPokemon[id], }; if (!this.parsedPokemon[id].forms) { this.parsedPokemon[id].forms = this.options.noFormPlaceholders ? [] : [0]; } else if ((this.parsedPokemon[id].forms.length === 0 && !this.options.noFormPlaceholders) || this.parsedPokemon[id].defaultFormId === 0) { this.parsedPokemon[id].forms.push(0); } } } catch (e) { console.warn(e, `Failed to parse Future Pokemon for ${id}`); } }); } sortForms() { Object.values(this.parsedPokemon).forEach((pokemon) => { try { if (pokemon.forms) { pokemon.forms.sort((a, b) => a - b); } } catch (e) { console.warn(e, `Failed to sort forms for ${pokemon.pokemonName}`); } }); } littleCup() { try { if (this.lcBanList === undefined) { console.warn('Missing little cup ban list from Masterfile'); } else { this.lcBanList.add('FARFETCHD'); this.parsedForms[pogo_protos_1.Rpc.PokemonDisplayProto.Form.FARFETCHD_GALARIAN].little = true; } for (const [id, pokemon] of Object.entries(this.parsedPokemon)) { const allowed = !this.evolvedPokemon.has(+id) && pokemon.evolutions !== undefined; if (allowed || +id === pogo_protos_1.Rpc.HoloPokemonId.DEERLING) { pokemon.little = true; } } } catch (e) { console.warn(e, `Failed to parse Little Cup`); } } jungleCup(object) { const { data: { combatLeague: { pokemonCondition, bannedPokemon }, }, } = object; pokemonCondition.forEach((condition) => { if (condition.type === 'WITH_POKEMON_TYPE') { condition.withPokemonType.pokemonType.forEach((type) => { this.jungleCupRules.types.push(pogo_protos_1.Rpc.HoloPokemonType[type]); }); } }); this.jungleCupRules.banned = bannedPokemon && bannedPokemon.map((poke) => { return pogo_protos_1.Rpc.HoloPokemonId[poke]; }); } jungleEligibility() { Object.entries(this.parsedPokemon).forEach(([id, pokemon]) => { const allowed = this.jungleCupRules.types.some((type) => pokemon.types.includes(type)) && !this.jungleCupRules.banned.includes(+id); if (allowed) pokemon.jungle = true; }); } makeFormsSeparate() { try { this.parsedPokeForms = {}; Object.values(this.parsedPokemon).forEach((pokemon) => { if (pokemon.forms) { pokemon.forms.forEach((form) => { this.parsedPokeForms[`${pokemon.pokedexId}_${form}`] = { ...pokemon, evolutions: form === 0 ? pokemon.evolutions : undefined, tempEvolutions: form === 0 ? pokemon.tempEvolutions : undefined, ...this.parsedForms[form], forms: [form], }; }); } }); } catch (e) { console.warn(e, `Failed to make forms separate`); } } parseCostumes() { Object.entries(pogo_protos_1.Rpc.PokemonDisplayProto.Costume).forEach((proto) => { const [name, id] = proto; this.parsedCostumes[id] = { id: +id, name: this.capitalize(name), proto: name, noEvolve: name.endsWith('_NOEVOLVE'), }; }); } parsePokeApi(baseStats, tempEvos) { if (this.options.includeEstimatedPokemon === true || this.options.includeEstimatedPokemon.baseStats) { Object.keys(baseStats).forEach((id) => { try { if (!this.parsedPokemon[id]) { this.parsedPokemon[id] = { pokemonName: this.pokemonName(+id), pokedexId: +id, defaultFormId: 0, forms: this.options.includeUnset && !this.options.noFormPlaceholders ? [0] : [], types: [], quickMoves: [], chargedMoves: [], ...this.getGeneration(+id), }; } let { evolutions } = this.parsedPokemon[id]; if (baseStats[id].evolutions) { const cleaned = baseStats[id].evolutions.map((evo) => { return { evoId: evo.evoId, formId: evo.formId || (this.options.includeUnset && !this.options.noFormPlaceholders ? 0 : undefined), }; }); evolutions = evolutions ? [...evolutions, ...cleaned] : cleaned; } this.parsedPokemon[id] = { ...this.parsedPokemon[id], ...baseStats[id], pokemonName: this.parsedPokemon[id].pokemonName || baseStats[id].pokemonName, quickMoves: this.parsedPokemon[id].quickMoves.length ? this.parsedPokemon[id].quickMoves : baseStats[id].quickMoves, chargedMoves: this.parsedPokemon[id].chargedMoves.length ? this.parsedPokemon[id].chargedMoves : baseStats[id].chargedMoves, evolutions, }; } catch (e) { console.warn(e, `Failed to parse base stats for ${id}`); } }); } Object.keys(tempEvos).forEach((category) => { try { if (this.options.includeEstimatedPokemon === true || this.options.includeEstimatedPokemon[category]) { Object.keys(tempEvos[category]).forEach((id) => { try { const tempEvolutions = [ ...tempEvos[category][id].tempEvolutions, ...(this.parsedPokemon[id].tempEvolutions ? this.parsedPokemon[id].tempEvolutions : []), ]; this.parsedPokemon[id] = { ...this.parsedPokemon[id], tempEvolutions, }; if (this.parsedPokemon[id].forms) { this.parsedPokemon[id].forms.forEach((form) => { if (this.parsedForms[form].formName === 'Normal' || this.parsedForms[form].formName === 'Purified') { this.parsedForms[form].tempEvolutions = tempEvolutions; } }); } } catch (e) { console.warn(e, `Failed to parse temp evos for ${category}-${id}`); } }); } } catch (e) { console.warn(e, `Failed to parse temp evos for ${category}`); } }); } } exports.default = Pokemon;