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
+34 -1
View File
@@ -12,7 +12,7 @@ function harness(capture = false) {
const source = plugin.replace(' Plugin.register(PLUGIN_ID, {', `
globalThis.api = { desktopFiles, importFilePath, insidePack, importResourceId, readImportPack, findImportPack, importPackRegistry,
resolveImportModel, importModelCandidates, companionImportFiles, definitionActorKeys, defaultImportClipRoles,
validateImportGeometry, automaticallyImportAnimation, loadImportTextures, commitAutomaticImport };
validateImportGeometry, automaticallyImportAnimation, loadImportTextures, commitAutomaticImport, resolveDefinitionImportStages };
Plugin.register(PLUGIN_ID, {`).replace(' function commitAutomaticImport(plan) {',
` function commitAutomaticImport(plan) { ${capture ? 'globalThis.importedPlan = plan; return;' : ''}`);
const storage = new Map(), dialogs = [], errors = [], undo = [], messages = [];
@@ -309,6 +309,39 @@ test('a definition actor without a distinct clip still requires a valid mapping'
assert.equal(h.context.Project.uuid, 'original');
});
test('automatic import retains use_stage metadata without duplicating editor animations', async (t) => {
const f = fixtures(t), h = harness(true), source = f.makePack('source');
const file = f.write(path.join(source.root, 'data/test/afw_animdefs/example.json'), {
actors: [{ label: 'wolf', entity_types: ['minecraft:wolf'] }],
stages: [{ stage: 1, escapable: true }, { stage: 2, use_stage: 1, speed: 0.8, non_peak: true, escapable: false }],
});
f.write(path.join(source.root, 'assets/test/animations/afw/example.animation.json'), { animations: {
p1_wolf: { animation_length: 1, bones: { body: { rotation: [1, 2, 3] } },
sound_effects: { '0': { effect: 'example' } } },
} });
f.model(source, 'test:source/entity/wolf.m');
h.context.selectedFile = { path: file };
await h.automaticallyImportAnimation();
assert.deepEqual(h.errors, []);
const plan = h.context.importedPlan;
assert.deepEqual(Array.from(plan.imported.stageNames), ['example.p1']);
const clips = plan.imported.fileObj.animations;
assert.equal(clips['example.p2'], undefined);
assert.ok(clips['example.p1'].bones.actor1_body);
assert.equal(plan.definition.stages[1].use_stage, 1);
assert.equal(plan.definition.stages[1].speed, 0.8);
assert.equal(plan.definition.stages[1].non_peak, true);
assert.equal(plan.definition.stages[1].escapable, false);
});
test('playback references require declared stages and physical clips, not recursive aliases', () => {
const h = harness();
const parsed = { stages: [{ stageNumber: 1, entries: [{ actorLabel: 'wolf', key: 'p1_wolf', animObj: { bones: {} } }] }] };
assert.throws(() => h.resolveDefinitionImportStages(parsed, { stages: [{ stage: 1, use_stage: 9 }] }), /missing playback stage p9/);
assert.throws(() => h.resolveDefinitionImportStages(parsed, { stages: [{ stage: 1 }, { stage: 1 }] }), /unique positive/);
assert.throws(() => h.resolveDefinitionImportStages(parsed, { stages: [{ stage: 1, use_stage: 2 }, { stage: 2, use_stage: 1 }] }), /requires animation clips.*p2/);
});
test('canceling actor review leaves the open project and saved folders unchanged', async (t) => {
const f = fixtures(t), h = harness(true), source = f.makePack('source');
const file = f.write(path.join(source.root, 'data/test/afw_animdefs/example.json'), {