77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
import type { CutsceneFile, Cutscene, ImageSegment, SubtitleLine } from '../types/cutscene';
|
|
|
|
function parseSegment(raw: Record<string, unknown>): ImageSegment {
|
|
const from = (raw.from as Record<string, number> | undefined) ?? {};
|
|
const to = (raw.to as Record<string, number> | undefined) ?? {};
|
|
return {
|
|
path: String(raw.path ?? ''),
|
|
width: Number(raw.width ?? 1280),
|
|
height: Number(raw.height ?? 720),
|
|
startMs: Number(raw.startMs ?? 0),
|
|
endMs: Number(raw.endMs ?? 5000),
|
|
fadeInMs: Number(raw.fadeInMs ?? 0),
|
|
fadeOutMs: Number(raw.fadeOutMs ?? 0),
|
|
easing: String(raw.easing ?? 'Linear') as ImageSegment['easing'],
|
|
from: {
|
|
centerX: Number(from.centerX ?? 0.5),
|
|
centerY: Number(from.centerY ?? 0.5),
|
|
scale: Number(from.scale ?? 1.0),
|
|
},
|
|
to: {
|
|
centerX: Number(to.centerX ?? from.centerX ?? 0.5),
|
|
centerY: Number(to.centerY ?? from.centerY ?? 0.5),
|
|
scale: Number(to.scale ?? from.scale ?? 1.0),
|
|
},
|
|
};
|
|
}
|
|
|
|
function parseLine(raw: Record<string, unknown>): SubtitleLine {
|
|
return {
|
|
speaker: String(raw.speaker ?? ''),
|
|
text: String(raw.text ?? ''),
|
|
durationMs: Number(raw.durationMs ?? 0),
|
|
waitForConfirm: Boolean(raw.waitForConfirm ?? false),
|
|
luaCallback: String(raw.luaCallback ?? ''),
|
|
};
|
|
}
|
|
|
|
function parseCutscene(raw: Record<string, unknown>): Cutscene {
|
|
const segments = Array.isArray(raw.imageSegments)
|
|
? (raw.imageSegments as Record<string, unknown>[]).map(parseSegment)
|
|
: [];
|
|
const lines = Array.isArray(raw.lines)
|
|
? (raw.lines as Record<string, unknown>[]).map(parseLine)
|
|
: [];
|
|
return {
|
|
id: String(raw.id ?? 'untitled'),
|
|
skippable: raw.skippable !== false,
|
|
durationMs: Number(raw.durationMs ?? 0),
|
|
fadeOutMs: Number(raw.fadeOutMs ?? 0),
|
|
fadeInMs: Number(raw.fadeInMs ?? 0),
|
|
endFadeOutMs: Number(raw.endFadeOutMs ?? 0),
|
|
endFadeInMs: Number(raw.endFadeInMs ?? 0),
|
|
onFadeInCallback: String(raw.onFadeInCallback ?? ''),
|
|
imageSegments: segments,
|
|
lines,
|
|
};
|
|
}
|
|
|
|
export function parseFile(json: unknown): CutsceneFile {
|
|
const raw = json as Record<string, unknown>;
|
|
const cutscenes = Array.isArray(raw.cutscenes)
|
|
? (raw.cutscenes as Record<string, unknown>[]).map(parseCutscene)
|
|
: [];
|
|
return { cutscenes };
|
|
}
|
|
|
|
export function triggerDownload(file: CutsceneFile, filename = 'cutscenes.json') {
|
|
const json = JSON.stringify(file, null, 4);
|
|
const blob = new Blob([json], { type: 'application/json' });
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = filename;
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
}
|