zenno: runner model

This commit is contained in:
2026-04-26 22:01:22 -04:00
parent 1a55150ddd
commit 7abe427c03

View File

@@ -1,6 +1,71 @@
// Umamusume race mechanics adapted from KuromiAK's doc: // Umamusume race mechanics adapted from KuromiAK's doc:
// https://docs.google.com/document/d/15VzW9W2tXBBTibBRbZ8IVpW6HaMX8H0RP03kq6Az7Xg/edit?usp=sharing // https://docs.google.com/document/d/15VzW9W2tXBBTibBRbZ8IVpW6HaMX8H0RP03kq6Az7Xg/edit?usp=sharing
import type { Uma } from './data/uma';
export interface Runner {
name: string;
chara_card_id: number;
style: RunningStyle;
mood: Mood;
speed: number;
stamina: number;
power: number;
guts: number;
wit: number;
sprint: AptitudeLevel;
mile: AptitudeLevel;
medium: AptitudeLevel;
long: AptitudeLevel;
front: AptitudeLevel;
pace: AptitudeLevel;
late: AptitudeLevel;
end: AptitudeLevel;
turf: AptitudeLevel;
dirt: AptitudeLevel;
skills: number[];
unique_level: number;
}
export function new_runner(name?: string, base_uma?: Uma): Runner {
return {
name: name ?? '',
chara_card_id: base_uma?.chara_card_id ?? 0,
// TODO(zeph): default running style
style: RunningStyle.FrontRunner,
mood: Mood.Normal,
speed: 1200,
stamina: 1200,
power: 1200,
guts: 1200,
wit: 1200,
sprint: base_uma?.sprint ?? AptitudeLevel.A,
mile: base_uma?.mile ?? AptitudeLevel.A,
medium: base_uma?.medium ?? AptitudeLevel.A,
long: base_uma?.long ?? AptitudeLevel.A,
front: base_uma?.front ?? AptitudeLevel.A,
pace: base_uma?.pace ?? AptitudeLevel.A,
late: base_uma?.late ?? AptitudeLevel.A,
end: base_uma?.end ?? AptitudeLevel.A,
turf: base_uma?.turf ?? AptitudeLevel.A,
dirt: base_uma?.dirt ?? AptitudeLevel.A,
skills: base_uma != null ? [base_uma.unique] : [],
unique_level: 4,
};
}
export enum Mood {
Awful = -2,
Bad,
Normal,
Good,
Great,
}
export enum RunningStyle { export enum RunningStyle {
FrontRunner, FrontRunner,
PaceChaser, PaceChaser,
@@ -26,6 +91,100 @@ export enum Phase {
LateRace, LateRace,
} }
namespace Alpha123Umalator {
const aptitude_map = {
G: AptitudeLevel.G,
F: AptitudeLevel.F,
E: AptitudeLevel.E,
D: AptitudeLevel.D,
C: AptitudeLevel.C,
B: AptitudeLevel.B,
A: AptitudeLevel.A,
S: AptitudeLevel.S,
} as const;
type AptitudeString = keyof typeof aptitude_map;
const style_map = {
Nige: RunningStyle.FrontRunner,
Sentou: RunningStyle.PaceChaser,
Sasi: RunningStyle.LateSurger,
Oikomi: RunningStyle.EndCloser,
Oonige: RunningStyle.GreatEscape,
} as const;
export interface ImportUma {
outfitId: string;
starCount: number;
speed: number;
stamina: number;
power: number;
guts: number;
wisdom: number;
strategy: keyof typeof style_map;
distanceAptitude: AptitudeString;
surfaceAptitude: AptitudeString;
strategyAptitude: AptitudeString;
aptitudes: [
AptitudeString,
AptitudeString,
AptitudeString,
AptitudeString,
AptitudeString,
AptitudeString,
AptitudeString,
AptitudeString,
AptitudeString,
AptitudeString,
];
skills: string[];
uniqueLv: number;
mood: Mood;
popularity: number;
}
export function load(obj: ImportUma, name?: string): Runner {
return {
name: name ?? '',
chara_card_id: obj.outfitId !== '' ? parseInt(obj.outfitId) : 0,
style: style_map[obj.strategy],
mood: obj.mood,
speed: obj.speed,
stamina: obj.stamina,
power: obj.power,
guts: obj.guts,
wit: obj.wisdom,
sprint: aptitude_map[obj.aptitudes[0]],
mile: aptitude_map[obj.aptitudes[1]],
medium: aptitude_map[obj.aptitudes[2]],
long: aptitude_map[obj.aptitudes[3]],
front: aptitude_map[obj.aptitudes[4]],
pace: aptitude_map[obj.aptitudes[5]],
late: aptitude_map[obj.aptitudes[6]],
end: aptitude_map[obj.aptitudes[7]],
turf: aptitude_map[obj.aptitudes[8]],
dirt: aptitude_map[obj.aptitudes[9]],
skills: obj.skills.map((s) => parseInt(s)),
unique_level: obj.uniqueLv,
};
}
}
export function import_runner(obj: any, name?: string): Runner | null {
// TODO(zeph): check for keys that identify the uma source
if (typeof obj === 'object') {
try {
const r = Alpha123Umalator.load(obj as Alpha123Umalator.ImportUma, name);
// TODO(zeph): validate?
return r;
} catch (exc) {
console.warn('failed to import', obj, 'as alpha123 umalator:', exc);
return null;
}
}
console.warn('no guess on how to import', obj);
return null;
}
function baseSpeed(raceLen: number): number { function baseSpeed(raceLen: number): number {
return 20 - (raceLen - 2000) / 1000; return 20 - (raceLen - 2000) / 1000;
} }