Files
healer-man/src/game/romStats.ts
T
2026-08-14 15:56:39 -04:00

54 lines
2.1 KiB
TypeScript

import { isRomClassId, type ClassId, type RomClassId } from "../app/characterCatalog";
import catalog from "./romPlayerCatalog.generated.json";
type SourceStatName = "strength" | "stamina" | "intellect" | "wisdom" | "agility" | "health" | "mana";
interface GrowthRow { readonly levelOne: number; readonly flatGrowth: number; readonly percentGrowth: number }
type GrowthTable = Readonly<Record<RomClassId, Readonly<Record<SourceStatName, GrowthRow>>>>;
const GROWTH = catalog.baseStatGrowth as unknown as GrowthTable;
function sourceValue(row: GrowthRow, level: number): number {
const safeLevel = Math.max(1, Math.min(80, Math.trunc(level)));
let value = row.levelOne;
for (let current = 2; current <= safeLevel; current += 1) value = value * (1 + row.percentGrowth) + row.flatGrowth;
return Math.max(0, value);
}
export interface RomNativeBaseStats {
readonly strength: number;
readonly stamina: number;
readonly intellect: number;
readonly wisdom: number;
readonly agility: number;
readonly health: number;
readonly mana: number;
}
export function romNativeClassBaseStats(classId: RomClassId, level: number): RomNativeBaseStats {
const rows = GROWTH[classId];
return Object.freeze({
strength: sourceValue(rows.strength, level),
stamina: sourceValue(rows.stamina, level),
intellect: sourceValue(rows.intellect, level),
wisdom: sourceValue(rows.wisdom, level),
agility: sourceValue(rows.agility, level),
health: sourceValue(rows.health, level),
mana: sourceValue(rows.mana, level),
});
}
export function romDualClassBaseStats(
primaryClassId: ClassId,
secondaryClassId: ClassId | null | undefined,
level: number,
): RomNativeBaseStats | null {
if (!isRomClassId(primaryClassId)) return null;
const primary = romNativeClassBaseStats(primaryClassId, level);
if (!secondaryClassId || !isRomClassId(secondaryClassId)) return primary;
const secondary = romNativeClassBaseStats(secondaryClassId, level);
return Object.freeze(Object.fromEntries(Object.keys(primary).map((key) => [
key,
primary[key as keyof RomNativeBaseStats] + secondary[key as keyof RomNativeBaseStats] * .1,
])) as unknown as RomNativeBaseStats);
}