Create a sprite asset from a texture's context menu

The sprite takes the whole image at its pixel size and the texture's name,
numbered like any other clash. CreateAssetCommand now accepts starting
properties; they go through the schema in execute, so an unknown key or a
bad value is refused before the project is touched, and one undo removes
the asset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5 committed 2026-09-11 09:57:19 +02:00
1 parent 1e2285c545
commit 9212e61c4c
9 files changed
+137 -7

No files matched your search

+43
View File
@@ -326,4 +326,47 @@ export async function textures(t) {
'undo takes the adopted asset back out',
(await json("__gm.state.project.assets.filter((a) => a.type === 'texture').length")) === 1,
);
// 19f. Right-clicking a texture asset makes a sprite wearing it at the picture's pixel size.
const entryText = 'Create sprite from texture';
const spriteRow = await json("__gm.assetRow('crate')");
await click(spriteRow.x, spriteRow.y, 'right');
await sleep(200);
check(
'a sprite asset does not offer making a sprite from it',
(await json(`__gm.locate(${JSON.stringify(entryText)}, false)`)) === null,
);
await press('Escape');
await sleep(150);
const spritesBefore = await json("__gm.state.project.assets.filter((a) => a.type === 'sprite').length");
const textureRow = await json(`__gm.assetRow(${JSON.stringify(texture.id)})`);
await click(textureRow.x, textureRow.y, 'right');
await sleep(200);
const createEntry = await json(`__gm.locate(${JSON.stringify(entryText)}, false)`);
check('a texture asset offers making a sprite from it', createEntry !== null);
if (createEntry) {
await click(createEntry.x, createEntry.y);
await sleep(400);
const made = await json(`(() => {
const s = __gm.state.selection;
const a = s && s.kind === 'asset' ? __gm.state.project.assets.find((x) => x.id === s.assetId) : null;
return a ? { type: a.type, name: a.name, props: a.props } : null;
})()`);
check(
'the new sprite is selected and wears the texture at its pixel size',
made?.type === 'sprite' &&
made.props.texture === texture.id &&
made.props.width === 64 &&
made.props.height === 48,
JSON.stringify(made),
);
check('it is named after the texture', made?.name === `${texture.name} 2`, JSON.stringify(made?.name));
await shot('35b-sprite-from-texture');
await undo();
check(
'undo takes the new sprite back out',
(await json("__gm.state.project.assets.filter((a) => a.type === 'sprite').length")) === spritesBefore,
);
}
}