improved and fixed stuff

This commit is contained in:
2026-09-28 21:55:40 +02:00
parent 2486c3cb63
commit 8d1346986b
3 changed files with 90 additions and 4 deletions
+38 -2
View File
@@ -2686,12 +2686,16 @@
const stageNumbers = new Set(analysis.stages.map((stage) => stage.stageNumber));
const seenStages = new Set();
for (const stage of definition.stages) {
if (!isObject(stage) || !Number.isInteger(stage.stage) || !stageNumbers.has(stage.stage) || seenStages.has(stage.stage)) {
if (!isObject(stage) || !Number.isInteger(stage.stage) || stage.stage < 1 || seenStages.has(stage.stage)) {
throw new Error('Imported stages must have unique stage numbers matching the target animation.');
}
const playback = stage.use_stage ?? stage.stage;
if (!Number.isInteger(playback) || !stageNumbers.has(playback)) {
throw new Error(`Stage p${stage.stage} requires animation clips for playback stage p${playback}.`);
}
seenStages.add(stage.stage);
}
if (seenStages.size !== stageNumbers.size) throw new Error('The definition must include every stage of the target animation.');
if ([...stageNumbers].some((number) => !seenStages.has(number))) throw new Error('The definition must include every stage of the target animation.');
const roles = analysis.actorIndices.map((index) => analysis.actorLabels.get(index));
const labels = new Set();
@@ -2797,6 +2801,11 @@
const saved = getSavedAnimdef(group.id);
const savedActors = new Map((Array.isArray(saved.actors) ? saved.actors : []).map((actor) => [actor.label, actor]));
const savedStages = new Map((Array.isArray(saved.stages) ? saved.stages : []).map((stage) => [stage.stage, stage]));
const editableStages = new Map(analysis.stages.map((stage) => [stage.stageNumber, stage]));
const reusedStages = [...savedStages.values()].filter((stage) => !editableStages.has(stage.stage)
&& editableStages.has(stage.use_stage)).map((stage) => ({ ...editableStages.get(stage.use_stage),
stageNumber: stage.stage, loop: stage.loop ?? editableStages.get(stage.use_stage).loop }));
analysis = { ...analysis, stages: [...analysis.stages, ...reusedStages].sort((a, b) => a.stageNumber - b.stageNumber) };
const savedSystemTags = uniqueTrimmedStrings((Array.isArray(saved.system_tags) ? saved.system_tags : [])
.map((tag) => String(tag).toLowerCase()));
const savedTag = savedSystemTags[0] || '';
@@ -3592,6 +3601,32 @@
return combined;
}
function resolveDefinitionImportStages(parsed, definition) {
if (!Array.isArray(definition.stages) || !definition.stages.length) {
throw new Error('The definition must contain at least one stage.');
}
const numbers = new Set();
for (const stage of definition.stages) {
if (!stage || !Number.isInteger(stage.stage) || stage.stage < 1 || numbers.has(stage.stage)) {
throw new Error('Definition stages must have unique positive stage numbers.');
}
numbers.add(stage.stage);
}
const clips = new Map(parsed.stages.map((stage) => [stage.stageNumber, stage]));
for (const stage of definition.stages) {
const playback = stage.use_stage ?? stage.stage;
if (!Number.isInteger(playback) || !numbers.has(playback)) {
throw new Error(`Stage p${stage.stage} references missing playback stage p${playback}.`);
}
// NoN references the target's clips directly, not its own use_stage setting.
const source = clips.get(playback);
if (!source) throw new Error(`Stage p${stage.stage} requires animation clips for playback stage p${playback}.`);
}
// Reused stages remain definition metadata, not duplicate editable animations.
return definition.stages.filter((stage) => stage.use_stage == null || stage.use_stage === stage.stage)
.map((stage) => clips.get(stage.stage)).sort((a, b) => a.stageNumber - b.stageNumber);
}
function buildConjoinedImportFile(parsed, outputAnimationId, actorMapping) {
const animations = {};
const stageNames = [];
@@ -4239,6 +4274,7 @@
parsed.stages = parsed.stages.map((stage) => ({ ...stage,
entries: stage.entries.filter((entry) => selectedLabels.has(entry.actorLabel))
})).filter((stage) => stage.entries.length);
parsed.stages = resolveDefinitionImportStages(parsed, definition);
// Preserve role references while relabeling the definition for the selected asset clips.
const relabeled = clone(definition);
relabeled.actors.forEach((actor, index) => { actor.label ||= keys[index]; });