56 lines
3.2 KiB
TypeScript
56 lines
3.2 KiB
TypeScript
import type { Build, MainStatKey, RollKey, Team } from "./types";
|
|
import { translateRotation } from "./rotation";
|
|
import { ROTATION_DELAY_HELPER, ROTATION_ENVIRONMENT } from "./rotation-defaults";
|
|
|
|
export const SUBSTAT_SCALARS: Record<RollKey, number> = {
|
|
hp: 253.94, atk: 16.54, def: 19.68, em: 19.82,
|
|
er: 0.0551, "hp%": 0.0496, "atk%": 0.0496, "def%": 0.062,
|
|
cr: 0.0331, cd: 0.0662,
|
|
};
|
|
|
|
export const MAIN_STATS: Record<MainStatKey, number> = {
|
|
"hp%": 0.466, "atk%": 0.466, "def%": 0.583, em: 186.5, er: 0.518,
|
|
"pyro%": 0.466, "hydro%": 0.466, "cryo%": 0.466, "electro%": 0.466,
|
|
"anemo%": 0.466, "geo%": 0.466, "dendro%": 0.466, "phys%": 0.583,
|
|
cr: 0.311, cd: 0.622, heal: 0.359,
|
|
};
|
|
|
|
function number(value: number): string {
|
|
return value.toFixed(4).replace(/0+$/u, "").replace(/\.$/u, "");
|
|
}
|
|
|
|
function statsLine(character: string, stats: Record<string, number>, comment: string): string {
|
|
const body = Object.entries(stats).filter(([, value]) => value !== 0).map(([key, value]) => `${key}=${number(value)}`).join(" ");
|
|
return `${character} add stats ${body}; # ${comment}`;
|
|
}
|
|
|
|
export function calculateSubstats(build: Build): Record<RollKey, number> {
|
|
return Object.fromEntries(Object.entries(build.rolls).map(([key, count]) => [key, count * SUBSTAT_SCALARS[key as RollKey]])) as Record<RollKey, number>;
|
|
}
|
|
|
|
export function generateBuild(build: Build): string {
|
|
const main: Record<string, number> = { hp: 4780, atk: 311 };
|
|
for (const stat of [build.sands, build.goblet, build.circlet]) main[stat] = (main[stat] ?? 0) + MAIN_STATS[stat];
|
|
const sets = build.importedSets ? build.importedSets.map((set) => `${build.characterKey} add set="${set.key}" count=${set.count}${set.params ? ` +params=${set.params}` : ""};`) : build.artifactMode === "4pc"
|
|
? [`${build.characterKey} add set="${build.artifactOneKey}" count=4;`]
|
|
: [`${build.characterKey} add set="${build.artifactOneKey}" count=2;`, `${build.characterKey} add set="${build.artifactTwoKey}" count=2;`];
|
|
const importedBody = Object.entries(build.importedStats ?? {}).map(([key, value]) => `${key}=${value}`).join(" ");
|
|
const stats = build.importedStats
|
|
? (importedBody ? [`${build.characterKey} add stats ${importedBody}; # imported artifact stats`] : [])
|
|
: [statsLine(build.characterKey, main, "main stats"), statsLine(build.characterKey, calculateSubstats(build), "substats")];
|
|
return [
|
|
`${build.characterKey} char lvl=${build.level}/${build.maxLevel} cons=${build.constellation} talent=${build.talents.join(",")}${build.importedParams?.character ? ` +params=${build.importedParams.character}` : ""};`,
|
|
`${build.characterKey} add weapon="${build.weaponKey}" refine=${build.refinement} lvl=${build.weaponLevel}/${build.weaponMaxLevel}${build.importedParams?.weapon ? ` +params=${build.importedParams.weapon}` : ""};`,
|
|
...sets,
|
|
...stats,
|
|
].join("\n");
|
|
}
|
|
|
|
export function generateTeam(team: Team): string {
|
|
const builds = team.builds.map(generateBuild).join("\n\n");
|
|
const rotation = translateRotation(team);
|
|
if (!team.rotation?.enabled) return builds;
|
|
const config = `${ROTATION_DELAY_HELPER}\n\n${builds}\n\n${ROTATION_ENVIRONMENT}`;
|
|
return rotation.code ? `${config}\n\n# Rotation\n${rotation.code}` : config;
|
|
}
|