pokerogue/src/data/api.ts

688 lines
27 KiB
TypeScript
Raw Normal View History

import { MainClient, NamedAPIResource } from "pokenode-ts";
import { MoveTarget, allMoves } from "./move";
import * as Utils from "../utils";
import fs from "vite-plugin-fs/browser";
import PokemonSpecies, { PokemonForm, SpeciesFormKey, allSpecies } from "./pokemon-species";
import { GrowthRate } from "./exp";
import { Type } from "./type";
import { allAbilities } from "./ability";
import { Abilities, Moves, Species } from "#enums";
import { pokemonFormLevelMoves } from "./pokemon-level-moves";
import { tmSpecies } from "./tms";
2023-11-30 16:37:16 -05:00
const targetMap = {
"specific-move": MoveTarget.ATTACKER,
"selected-pokemon-me-first": MoveTarget.NEAR_ENEMY,
"ally": MoveTarget.NEAR_ALLY,
"users-field": MoveTarget.USER_SIDE,
"user-or-ally": MoveTarget.USER_OR_NEAR_ALLY,
"opponents-field": MoveTarget.ENEMY_SIDE,
"user": MoveTarget.USER,
"random-opponent": MoveTarget.RANDOM_NEAR_ENEMY,
"all-other-pokemon": MoveTarget.ALL_NEAR_OTHERS,
"selected-pokemon": MoveTarget.NEAR_OTHER,
"all-opponents": MoveTarget.ALL_NEAR_ENEMIES,
"entire-field": MoveTarget.BOTH_SIDES,
"user-and-allies": MoveTarget.USER_AND_ALLIES,
"all-pokemon": MoveTarget.ALL,
"all-allies": MoveTarget.NEAR_ALLY,
"fainting-pokemon": MoveTarget.NEAR_OTHER
2023-11-30 16:37:16 -05:00
};
const generationMap = {
"generation-i": 1,
"generation-ii": 2,
"generation-iii": 3,
"generation-iv": 4,
"generation-v": 5,
"generation-vi": 6,
"generation-vii": 7,
"generation-viii": 8,
"generation-ix": 9
2023-11-30 16:37:16 -05:00
};
const growthRateMap = {
"slow-then-very-fast": GrowthRate.ERRATIC,
"fast": GrowthRate.FAST,
"medium": GrowthRate.MEDIUM_FAST,
"medium-slow": GrowthRate.MEDIUM_SLOW,
"slow": GrowthRate.SLOW,
"fast-then-very-slow": GrowthRate.FLUCTUATING
};
const regionalForms = [ "alola", "galar", "hisui", "paldea" ];
const ignoredForms = [ "gmax", "totem", "cap", "starter" ];
const generationDexNumbers = {
1: 151,
2: 251,
3: 386,
4: 494,
5: 649,
6: 721,
7: 809,
8: 905,
9: 1010
};
const versions = [ "scarlet-violet", "sword-shield", "sun-moon" ];
2023-11-30 16:37:16 -05:00
type LevelMove = [level: integer, moveId: integer];
interface SpeciesLevelMoves {
[key: string]: LevelMove[]
}
interface FormLevelMoves {
[key: integer]: LevelMove[]
}
interface SpeciesFormLevelMoves {
[key: string]: FormLevelMoves
}
interface TmSpecies {
2023-12-09 20:09:09 -05:00
[key: string]: Array<string | string[]>
}
2023-11-30 16:37:16 -05:00
export async function printPokemon() {
const api = new MainClient();
2023-12-11 13:02:02 -05:00
const useExistingTmList = true;
let enumStr = "export enum Species {\n";
let pokemonSpeciesStr = "\tallSpecies.push(\n";
const speciesLevelMoves: SpeciesLevelMoves = {};
const speciesFormLevelMoves: SpeciesFormLevelMoves = {};
const moveTmSpecies: TmSpecies = {};
let pokemonArr: NamedAPIResource[] = [];
const offset = 0;
const pokemonResponse = await api.pokemon.listPokemons(offset, 2000);
2024-05-24 01:45:04 +02:00
pokemonArr = pokemonResponse.results;
const types = Utils.getEnumKeys(Type).map(t => t.toLowerCase());
const abilities = Utils.getEnumKeys(Abilities).map(a => a.toLowerCase().replace(/\_/g, "-"));
const pokemonSpeciesList: PokemonSpecies[] = [];
for (const p of pokemonArr) {
const pokemon = await api.pokemon.getPokemonByName(p.name);
let region: string = "";
if (pokemon.id > 10000) {
const dexIdMatch = /\/(\d+)\//.exec(pokemon.species.url);
if (!dexIdMatch) {
continue;
}
2024-05-24 01:45:04 +02:00
const matchingSpecies = pokemonSpeciesList[parseInt(dexIdMatch[1]) - 1];
if (!matchingSpecies) {
2023-12-09 20:09:09 -05:00
continue;
}
2023-12-09 20:09:09 -05:00
const speciesKey = (matchingSpecies as any).key as string;
const formName = pokemon.name.slice(speciesKey.length + 1);
if (ignoredForms.filter(f => formName.indexOf(f) > -1).length) {
continue;
}
const shortFormName = formName.indexOf("-") > -1
? formName.slice(0, formName.indexOf("-"))
: formName;
if (regionalForms.indexOf(shortFormName) > -1) {
region = shortFormName.toUpperCase();
} else {
const formBaseStats: integer[] = [];
let formBaseTotal = 0;
// Assume correct stat order in API result
for (const stat of pokemon.stats) {
formBaseStats.push(stat.base_stat);
formBaseTotal += stat.base_stat;
}
const [ formType1, formType2 ] = [ types.indexOf(pokemon.types.find(t => t.slot === 1).type.name), types.indexOf(pokemon.types.find(t => t.slot === 2)?.type.name) ];
const [ formAbility1, formAbility2, formAbilityHidden ] = [
Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 1)?.ability.name), 0),
Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 2)?.ability.name), 0),
Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 3)?.ability.name), 0)
];
const pokemonForm = new PokemonForm(formName, formName, formType1 as Type, formType2 > -1 ? formType2 as Type : null, pokemon.height / 10, pokemon.weight / 10,
formAbility1 as Abilities, formAbility2 as Abilities, formAbilityHidden as Abilities, formBaseTotal, formBaseStats[0], formBaseStats[1], formBaseStats[2], formBaseStats[3], formBaseStats[4], formBaseStats[5],
matchingSpecies.catchRate, matchingSpecies.baseFriendship, matchingSpecies.baseExp, matchingSpecies.genderDiffs);
pokemonForm.speciesId = matchingSpecies.speciesId;
pokemonForm.formIndex = matchingSpecies.forms.length;
pokemonForm.generation = matchingSpecies.generation;
let moveVer: string;
if (!speciesFormLevelMoves.hasOwnProperty(speciesKey)) {
speciesFormLevelMoves[speciesKey] = [];
}
speciesFormLevelMoves[speciesKey][pokemonForm.formIndex] = [];
for (const version of versions) {
if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === "level-up"))) {
moveVer = version;
break;
}
}
if (moveVer) {
pokemon.moves.forEach(moveData => {
2023-12-11 13:02:02 -05:00
moveData.version_group_details.filter(v => versions.indexOf(v.version_group.name) > -1).forEach(verData => {
const isMoveVer = verData.version_group.name === moveVer;
const moveName = moveData.move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
2023-12-11 13:02:02 -05:00
const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0);
const learnMethod = verData.move_learn_method.name;
if (isMoveVer && learnMethod === "level-up") {
speciesFormLevelMoves[speciesKey][pokemonForm.formIndex].push([ verData.level_learned_at, moveId ]);
}
2023-12-11 13:02:02 -05:00
if ([ "machine", "tutor" ].indexOf(learnMethod) > -1 || (useExistingTmList && tmSpecies.hasOwnProperty(moveId as Moves) && learnMethod === "level-up")) {
if (!moveTmSpecies.hasOwnProperty(moveId)) {
2023-12-09 20:09:09 -05:00
moveTmSpecies[moveId] = [];
}
2023-12-09 20:09:09 -05:00
const speciesIndex = moveTmSpecies[moveId].findIndex(s => s[0] === speciesKey);
if (speciesIndex === -1) {
2023-12-09 20:09:09 -05:00
moveTmSpecies[moveId].push([ speciesKey, formName ]);
} else {
2023-12-09 20:09:09 -05:00
(moveTmSpecies[moveId][speciesIndex] as string[]).push(formName);
}
2023-12-11 13:02:02 -05:00
}
});
});
if (JSON.stringify(speciesLevelMoves[speciesKey]) === JSON.stringify(speciesFormLevelMoves[speciesKey][pokemonForm.formIndex])) {
delete speciesFormLevelMoves[speciesKey][pokemonForm.formIndex];
if (!Object.keys(speciesFormLevelMoves[speciesKey]).length) {
delete speciesFormLevelMoves[speciesKey];
}
}
}
matchingSpecies.forms.push(pokemonForm);
continue;
}
}
const species = await api.pokemon.getPokemonSpeciesByName(pokemon.species.name);
let speciesKey = species.name.toUpperCase().replace(/\-/g, "_");
2023-12-09 20:09:09 -05:00
const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === speciesKey);
let dexId = species.id;
if (region) {
dexId += (regionalForms.indexOf(region.toLowerCase()) + 1) * 2000;
speciesKey = `${region}_${speciesKey}`;
}
let generationIndex = 0;
if (!region) {
while (++generationIndex < 9 && dexId > generationDexNumbers[generationIndex]) {}
} else {
generationIndex = regionalForms.indexOf(region.toLowerCase()) + 6;
}
const baseStats: integer[] = [];
let baseTotal = 0;
// Assume correct stat order in API result
for (const stat of pokemon.stats) {
baseStats.push(stat.base_stat);
baseTotal += stat.base_stat;
}
console.log(pokemon);
const [ type1, type2 ] = [ types.indexOf(pokemon.types.find(t => t.slot === 1).type.name), types.indexOf(pokemon.types.find(t => t.slot === 2)?.type.name) ];
const [ ability1, ability2, abilityHidden ] = [
Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 1)?.ability.name), 0),
Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 2)?.ability.name), 0),
Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 3)?.ability.name), 0)
];
const pokemonSpecies = new PokemonSpecies(dexId, generationIndex, species.is_legendary && baseTotal < 660, species.is_legendary && baseTotal >= 660, species.is_mythical,
species.genera.find(g => g.language.name === "en")?.genus, type1 as Type, type2 > -1 ? type2 as Type : null, pokemon.height / 10, pokemon.weight / 10, ability1 as Abilities, ability2 as Abilities, abilityHidden as Abilities,
baseTotal, baseStats[0], baseStats[1], baseStats[2], baseStats[3], baseStats[4], baseStats[5], species.capture_rate, species.base_happiness, pokemon.base_experience, growthRateMap[species.growth_rate.name],
species.gender_rate < 9 ? 100 - (species.gender_rate * 12.5) : null, species.has_gender_differences, species.forms_switchable);
(pokemonSpecies as any).key = speciesKey;
pokemonSpeciesList.push(pokemonSpecies);
let moveVer: string;
speciesLevelMoves[speciesKey] = [];
for (const version of versions) {
if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === "level-up"))) {
moveVer = version;
break;
}
}
2023-12-09 20:09:09 -05:00
const speciesTmMoves: integer[] = [];
if (moveVer) {
pokemon.moves.forEach(moveData => {
const verData = moveData.version_group_details.find(v => v.version_group.name === moveVer);
if (!verData) {
return;
}
const moveName = moveData.move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0);
2023-12-09 20:09:09 -05:00
switch (verData.move_learn_method.name) {
case "level-up":
speciesLevelMoves[speciesKey].push([ verData.level_learned_at, moveId ]);
break;
case "machine":
case "tutor":
if (moveId > 0) {
if (!moveTmSpecies.hasOwnProperty(moveId)) {
moveTmSpecies[moveId] = [];
2023-12-09 20:09:09 -05:00
}
if (moveTmSpecies[moveId].indexOf(speciesKey) === -1) {
moveTmSpecies[moveId].push(speciesKey);
}
speciesTmMoves.push(moveId);
}
break;
}
});
}
for (const f of pokemon.forms) {
2023-12-09 20:09:09 -05:00
const form = await api.pokemon.getPokemonFormByName(f.name);
const formIndex = pokemonSpecies.forms.length;
const matchingForm = matchingExistingSpecies && matchingExistingSpecies.forms.length > formIndex
? matchingExistingSpecies.forms.find(f2 => f2.formKey === form.form_name || f2.formName === form.form_name) || matchingExistingSpecies.forms[formIndex]
: null;
const formName = matchingForm
? matchingForm.formName
: form.form_names.find(fn => fn.language.name === "en")?.name || form.form_name;
2023-12-09 20:09:09 -05:00
const formKey = matchingForm
? matchingForm.formKey
: form.form_name;
const [ formType1, formType2 ] = [ types.indexOf(form.types.find(t => t.slot === 1).type.name), types.indexOf(form.types.find(t => t.slot === 2)?.type.name) ];
const pokemonForm = new PokemonForm(formName, formKey, formType1 as Type, formType2 > -1 ? formType2 as Type : null,
pokemonSpecies.height, pokemonSpecies.weight, pokemonSpecies.ability1, pokemonSpecies.ability2, pokemonSpecies.abilityHidden, baseTotal, baseStats[0], baseStats[1], baseStats[2], baseStats[3], baseStats[4], baseStats[5],
pokemonSpecies.catchRate, pokemonSpecies.baseFriendship, pokemonSpecies.baseExp, pokemonSpecies.genderDiffs);
pokemonForm.speciesId = pokemonSpecies.speciesId;
pokemonForm.formIndex = formIndex;
pokemonForm.generation = pokemonSpecies.generation;
if (!pokemonForm.formIndex && speciesTmMoves.length) {
for (const moveId of speciesTmMoves) {
2023-12-09 20:09:09 -05:00
const speciesIndex = moveTmSpecies[moveId].findIndex(s => s === speciesKey);
moveTmSpecies[moveId][speciesIndex] = [
speciesKey,
formKey
];
}
}
pokemonSpecies.forms.push(pokemonForm);
}
console.log(pokemonSpecies.name, pokemonSpecies);
}
for (const pokemonSpecies of pokemonSpeciesList) {
const speciesKey = (pokemonSpecies as any).key as string;
enumStr += ` ${speciesKey}${pokemonSpecies.speciesId >= 2000 ? ` = ${pokemonSpecies.speciesId}` : ""},\n`;
pokemonSpeciesStr += ` new PokemonSpecies(Species.${speciesKey}, "${pokemonSpecies.name}", ${pokemonSpecies.generation}, ${pokemonSpecies.subLegendary}, ${pokemonSpecies.legendary}, ${pokemonSpecies.mythical}, "${pokemonSpecies.species}", Type.${Type[pokemonSpecies.type1]}, ${pokemonSpecies.type2 ? `Type.${Type[pokemonSpecies.type2]}` : "null"}, ${pokemonSpecies.height}, ${pokemonSpecies.weight}, Abilities.${Abilities[pokemonSpecies.ability1]}, Abilities.${Abilities[pokemonSpecies.ability2]}, Abilities.${Abilities[pokemonSpecies.abilityHidden]}, ${pokemonSpecies.baseTotal}, ${pokemonSpecies.baseStats[0]}, ${pokemonSpecies.baseStats[1]}, ${pokemonSpecies.baseStats[2]}, ${pokemonSpecies.baseStats[3]}, ${pokemonSpecies.baseStats[4]}, ${pokemonSpecies.baseStats[5]}, ${pokemonSpecies.catchRate}, ${pokemonSpecies.baseFriendship}, ${pokemonSpecies.baseExp}, GrowthRate.${GrowthRate[pokemonSpecies.growthRate]}, ${pokemonSpecies.malePercent}, ${pokemonSpecies.genderDiffs}`;
if (pokemonSpecies.forms.length > 1) {
pokemonSpeciesStr += `, ${pokemonSpecies.canChangeForm},`;
for (const form of pokemonSpecies.forms) {
pokemonSpeciesStr += `\n new PokemonForm("${form.formName}", "${form.formName}", Type.${Type[form.type1]}, ${form.type2 ? `Type.${Type[form.type2]}` : "null"}, ${form.height}, ${form.weight}, Abilities.${Abilities[form.ability1]}, Abilities.${Abilities[form.ability2]}, Abilities.${Abilities[form.abilityHidden]}, ${form.baseTotal}, ${form.baseStats[0]}, ${form.baseStats[1]}, ${form.baseStats[2]}, ${form.baseStats[3]}, ${form.baseStats[4]}, ${form.baseStats[5]}, ${form.catchRate}, ${form.baseFriendship}, ${form.baseExp}${form.genderDiffs ? ", true" : ""}),`;
}
pokemonSpeciesStr += "\n ";
}
pokemonSpeciesStr += "),\n";
}
let speciesLevelMovesStr = "export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {\n";
let speciesFormLevelMovesStr = "export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {\n";
let tmSpeciesStr = "export const tmSpecies: TmSpecies = {\n";
for (const species of Object.keys(speciesLevelMoves)) {
speciesLevelMovesStr += ` [Species.${species}]: [\n`;
const orderedLevelMoves = speciesLevelMoves[species].sort((a: LevelMove, b: LevelMove) => {
if (a[0] !== b[0]) {
return a[0] < b[0] ? -1 : 1;
}
return a[1] < b[1] ? -1 : 1;
});
for (const lm of orderedLevelMoves) {
speciesLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`;
}
speciesLevelMovesStr += " ],\n";
}
for (const species of Object.keys(speciesFormLevelMoves)) {
speciesFormLevelMovesStr += ` [Species.${species}]: {\n`;
for (const f of Object.keys(speciesFormLevelMoves[species])) {
speciesFormLevelMovesStr += ` ${f}: [\n`;
const orderedLevelMoves = speciesFormLevelMoves[species][f].sort((a: LevelMove, b: LevelMove) => {
if (a[0] !== b[0]) {
return a[0] < b[0] ? -1 : 1;
}
return a[1] < b[1] ? -1 : 1;
});
for (const lm of orderedLevelMoves) {
speciesFormLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`;
}
speciesFormLevelMovesStr += " ],\n";
}
speciesFormLevelMovesStr += " },\n";
}
for (const moveId of Object.keys(moveTmSpecies)) {
2023-12-09 20:09:09 -05:00
tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`;
for (const species of moveTmSpecies[moveId]) {
if (typeof species === "string") {
2023-12-09 20:09:09 -05:00
tmSpeciesStr += ` Species.${species},\n`;
} else {
2023-12-09 20:09:09 -05:00
const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]);
const forms = (species as string[]).slice(1);
if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) {
2023-12-09 20:09:09 -05:00
tmSpeciesStr += ` Species.${species[0]},\n`;
} else {
2023-12-09 20:09:09 -05:00
tmSpeciesStr += ` [\n Species.${species[0]},\n`;
for (const form of forms) {
2023-12-09 20:09:09 -05:00
tmSpeciesStr += ` '${form}',\n`;
}
tmSpeciesStr += " ],\n";
2023-12-09 20:09:09 -05:00
}
}
}
tmSpeciesStr += " ],\n";
2023-12-09 20:09:09 -05:00
}
enumStr += "\n};";
pokemonSpeciesStr += " );";
speciesLevelMovesStr += "\n};";
speciesFormLevelMovesStr += "\n};";
tmSpeciesStr += "\n};";
console.log(enumStr);
console.log(pokemonSpeciesStr);
console.log(speciesLevelMovesStr);
console.log(speciesFormLevelMovesStr);
console.log(tmSpeciesStr);
2023-12-09 20:09:09 -05:00
console.log(moveTmSpecies);
}
export async function printAbilities() {
const replaceText = true;
let abilityContent: string = await fs.readFile("./src/data/ability.ts");
2024-05-24 01:45:04 +02:00
const api = new MainClient();
let enumStr = "export enum Abilities {\n NONE,";
let abilityStr = " allAbilities.push(";
abilityContent = abilityContent.slice(abilityContent.indexOf(abilityStr));
let abilities: NamedAPIResource[] = [];
const offset = 0;
const abilitiesResponse = await api.pokemon.listAbilities(offset, 2000);
abilities = abilitiesResponse.results;
for (const a of abilities) {
const ability = await api.pokemon.getAbilityByName(a.name);
const abilityEnumName = ability.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
enumStr += `\n ${abilityEnumName},`;
console.log(ability.name, ability);
const matchingLineIndex = abilityContent.search(new RegExp(`new Ability\\\(Abilities.${abilityEnumName},`));
let matchingLine = matchingLineIndex > -1 ? abilityContent.slice(matchingLineIndex) : null;
if (matchingLine) {
matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/));
}
let abilityName = ability.names.find(ln => ln.language.name === "en").name;
[ "N", "P" ].every(s => {
if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) {
abilityName += ` (${s})`;
return false;
}
return true;
});
let flavorText: string;
if (!matchingLine || replaceText) {
for (const version of versions) {
if ((flavorText = ability.flavor_text_entries.find(fte => fte.language.name === "en" && fte.version_group.name === version)?.flavor_text) || "") {
if (flavorText.indexOf("forgotten") > -1) {
continue;
}
break;
}
}
} else if (matchingLine) {
flavorText = allAbilities[ability.id].description;
}
abilityStr += `\n new Ability(Abilities.${abilityEnumName}, "${abilityName}", "${flavorText?.replace(/\n/g, "\\n").replace(/ /g, " ").replace(//g, "'") || ""}", ${generationMap[ability.generation.name]})`;
if (matchingLine && matchingLine.length > 1) {
const newLineIndex = matchingLine.indexOf("\n");
if (newLineIndex > -1) {
abilityStr += matchingLine.slice(newLineIndex);
}
}
abilityStr += ",";
}
enumStr += "\n};";
abilityStr += "\n);";
console.log(enumStr);
console.log(abilityStr);
2023-11-30 16:37:16 -05:00
}
export async function printMoves() {
const replaceText = true;
let moveContent: string = await fs.readFile("./src/data/move.ts");
2024-05-24 01:45:04 +02:00
2023-11-30 16:37:16 -05:00
const api = new MainClient();
let enumStr = "export enum Moves {\n NONE,";
let moveStr = " allMoves.push(";
2023-11-30 16:37:16 -05:00
moveContent = moveContent.slice(moveContent.indexOf(moveStr));
let moves: NamedAPIResource[] = [];
const offset = 0;
const movesResponse = await api.move.listMoves(offset, 2000);
moves = movesResponse.results;
2024-05-24 01:45:04 +02:00
2023-11-30 16:37:16 -05:00
console.log(moves);
for (const m of moves) {
2023-11-30 16:37:16 -05:00
const move = await api.move.getMoveByName(m.name);
const moveEnumName = move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
2023-11-30 16:37:16 -05:00
enumStr += `\n ${moveEnumName},`;
console.log(move.name, move);
const matchingLineIndex = moveContent.search(new RegExp(`new (?:Attack|(?:Self)?Status)Move\\\(Moves.${Moves[move.id]},`));
let matchingLine = matchingLineIndex > -1 ? moveContent.slice(matchingLineIndex) : null;
if (matchingLine) {
2023-11-30 16:37:16 -05:00
matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/));
}
2023-11-30 16:37:16 -05:00
let moveName = move.names.find(ln => ln.language.name === "en").name;
[ "N", "P" ].every(s => {
2023-11-30 16:37:16 -05:00
if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) {
moveName += ` (${s})`;
return false;
}
return true;
});
let flavorText: string;
if (!matchingLine || replaceText) {
for (const version of versions) {
if ((flavorText = move.flavor_text_entries.find(fte => fte.language.name === "en" && fte.version_group.name === version)?.flavor_text) || "") {
if (flavorText.indexOf("forgotten") > -1) {
2023-11-30 16:37:16 -05:00
continue;
}
2023-11-30 16:37:16 -05:00
break;
}
}
} else if (matchingLine) {
2023-11-30 16:37:16 -05:00
flavorText = allMoves[move.id].effect;
}
2023-11-30 16:37:16 -05:00
const moveTarget = targetMap[move.target.name];
moveStr += `\n new ${move.damage_class.name !== "status" ? "Attack" : (moveTarget === MoveTarget.USER ? "Self" : "") + "Status"}Move(Moves.${moveEnumName}, "${moveName}", Type.${move.type.name.toUpperCase()}${move.damage_class.name !== "status" ? `, MoveCategory.${move.damage_class.name.toUpperCase()}` : ""}${move.damage_class.name !== "status" ? `, ${move.power || -1}` : ""}, ${move.accuracy || -1}, ${move.pp}, "${flavorText?.replace(/\n/g, "\\n").replace(/ /g, " ").replace(//g, "'") || ""}", ${move.effect_chance || -1}, ${move.priority}, ${generationMap[move.generation.name]})`;
const expectedTarget = move.damage_class.name !== "status" || moveTarget !== MoveTarget.USER ? MoveTarget.NEAR_OTHER : MoveTarget.USER;
2023-11-30 16:37:16 -05:00
if (matchingLine && matchingLine.length > 1) {
const newLineIndex = matchingLine.indexOf("\n");
2023-11-30 16:37:16 -05:00
if (newLineIndex > -1) {
console.log(matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, ""), newLineIndex);
moveStr += matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, "");
2023-11-30 16:37:16 -05:00
}
}
if (moveTarget !== expectedTarget) {
2023-11-30 16:37:16 -05:00
moveStr += `\n .target(MoveTarget.${MoveTarget[moveTarget]})`;
}
moveStr += ",";
2023-11-30 16:37:16 -05:00
}
enumStr += "\n};";
moveStr += "\n);";
2023-11-30 16:37:16 -05:00
console.log(enumStr);
console.log(moveStr);
2023-12-11 13:02:02 -05:00
}
export async function printTmSpecies() {
const moveTmSpecies: TmSpecies = {};
const api = new MainClient();
const moveIds = Object.keys(tmSpecies).map(k => parseInt(k) as Moves);
2024-05-24 01:45:04 +02:00
for (const moveId of moveIds) {
2023-12-11 13:02:02 -05:00
const move = await api.move.getMoveById(moveId);
moveTmSpecies[moveId] = [];
for (const species of move.learned_by_pokemon) {
2023-12-11 13:02:02 -05:00
const dexIdMatch = /\/(\d+)\//.exec(species.url);
if (!dexIdMatch) {
2023-12-11 13:02:02 -05:00
continue;
}
2023-12-11 13:02:02 -05:00
const dexId = parseInt(dexIdMatch[1]);
2023-12-11 13:02:02 -05:00
let matchingSpecies: PokemonSpecies;
let formKey = "";
2023-12-11 13:02:02 -05:00
console.log(species.name);
if (dexId < 10000) {
2023-12-11 13:02:02 -05:00
matchingSpecies = allSpecies[dexId - 1];
} else {
2023-12-11 13:02:02 -05:00
const pokemon = await api.pokemon.getPokemonById(dexId);
const speciesDexIdMatch = /\/(\d+)\//.exec(pokemon.species.url);
if (!speciesDexIdMatch) {
2023-12-11 13:02:02 -05:00
continue;
}
2023-12-11 13:02:02 -05:00
const speciesDexId = parseInt(speciesDexIdMatch[1]);
const speciesKey = Species[allSpecies[speciesDexId - 1].speciesId];
formKey = species.name.slice(speciesKey.length + 1);
const regionKey = regionalForms.find(r => formKey.indexOf(r) > -1);
if (regionKey) {
formKey = formKey.slice(regionKey.length + 1);
matchingSpecies = allSpecies.find(s => Species[s.speciesId] === `${regionKey.toUpperCase()}_${speciesKey}`);
} else {
2023-12-11 13:02:02 -05:00
matchingSpecies = allSpecies[speciesDexId - 1];
}
2023-12-11 13:02:02 -05:00
}
if (!matchingSpecies) {
console.log("NO MATCH", species.name);
2023-12-11 13:02:02 -05:00
continue;
}
2024-05-24 01:45:04 +02:00
2023-12-11 13:02:02 -05:00
const speciesKey = Species[matchingSpecies.speciesId];
2024-05-24 01:45:04 +02:00
2023-12-11 13:02:02 -05:00
const matchingIndex = moveTmSpecies[moveId].findIndex(s => Array.isArray(s) ? s[0] === speciesKey : s === speciesKey);
if (matchingIndex === -1) {
2023-12-11 13:02:02 -05:00
moveTmSpecies[moveId].push(!formKey ? speciesKey : [ speciesKey, formKey ]);
} else {
if (!Array.isArray(moveTmSpecies[moveId][matchingIndex])) {
moveTmSpecies[moveId][matchingIndex] = [ moveTmSpecies[moveId][matchingIndex] as string, "" ];
}
2023-12-11 13:02:02 -05:00
(moveTmSpecies[moveId][matchingIndex] as string[]).push(formKey);
}
}
}
let tmSpeciesStr = "export const tmSpecies: TmSpecies = {\n";
2023-12-11 13:02:02 -05:00
for (const moveId of Object.keys(moveTmSpecies)) {
2023-12-11 13:02:02 -05:00
tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`;
for (const species of moveTmSpecies[moveId]) {
if (typeof species === "string") {
2023-12-11 13:02:02 -05:00
tmSpeciesStr += ` Species.${species},\n`;
} else {
2023-12-11 13:02:02 -05:00
const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]);
const forms = (species as string[]).slice(1);
if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) {
2023-12-11 13:02:02 -05:00
tmSpeciesStr += ` Species.${species[0]},\n`;
} else {
2023-12-11 13:02:02 -05:00
tmSpeciesStr += ` [\n Species.${species[0]},\n`;
for (const form of forms) {
2023-12-11 13:02:02 -05:00
tmSpeciesStr += ` '${form}',\n`;
}
tmSpeciesStr += " ],\n";
2023-12-11 13:02:02 -05:00
}
}
}
tmSpeciesStr += " ],\n";
2023-12-11 13:02:02 -05:00
}
tmSpeciesStr += "\n};";
2023-12-11 13:02:02 -05:00
console.log(tmSpeciesStr);
}