diff --git a/.scripts/plugins/releaseNoteTemplates/discord_release_notes_template b/.scripts/plugins/releaseNoteTemplates/discord_release_notes_template index 747f9d28..353e14bf 100644 --- a/.scripts/plugins/releaseNoteTemplates/discord_release_notes_template +++ b/.scripts/plugins/releaseNoteTemplates/discord_release_notes_template @@ -6,9 +6,8 @@ ## How to Install -For now, you can download and install the latest build of AJ [here](https://builds.animated-java.dev/latest) or install it via this link: -https://builds.animated-java.dev/latest/download/animated_java.js -Once [this PR](https://github.com/JannisX11/blockbench-plugins/pull/{pr_number}) has been merged, you can install the latest release of AJ from the Blockbench plugin list. -[Follow this tutorial](https://animated-java.github.io/docs/getting-started/installing-animated-java) if you don't know how to install plugins in Blockbench. +Download `animated_java.js` from the [release page](), then [Follow this tutorial]() + +Once [this PR]() has been merged, you can install the latest release of AJ directly from the Blockbench plugin list. -# {pings} diff --git a/.scripts/plugins/releaseNoteTemplates/github_release_notes_template b/.scripts/plugins/releaseNoteTemplates/github_release_notes_template index 87690e56..c26f0d77 100644 --- a/.scripts/plugins/releaseNoteTemplates/github_release_notes_template +++ b/.scripts/plugins/releaseNoteTemplates/github_release_notes_template @@ -4,7 +4,6 @@ ## How to Install -For now, you can download and install the latest build of AJ [here](https://builds.animated-java.dev/latest) or install it via this link: -https://builds.animated-java.dev/latest/download/animated_java.js -Once [this PR](https://github.com/JannisX11/blockbench-plugins/pull/{pr_number}) has been merged, you can install the latest release of AJ from the Blockbench plugin list. -[Follow this tutorial](https://animated-java.github.io/docs/getting-started/installing-animated-java) if you don't know how to install plugins in Blockbench. +Download `animated_java.js` from the [release page](https://github.com/Animated-Java/animated-java/releases/tag/v1.10.1), then [Follow this tutorial](https://animated-java.dev/docs/getting-started/installing#advanced-installation-url) + +Once [this PR](https://github.com/JannisX11/blockbench-plugins/pull/930) has been merged, you can install the latest release of AJ directly from the Blockbench plugin list. diff --git a/TODO.md b/TODO.md index 0f231bce..4c714895 100644 --- a/TODO.md +++ b/TODO.md @@ -5,6 +5,7 @@ - [ ] Add Variants to the UndoSystem (Blocked by vanilla Blockbench not supporting custom undo actions). - [ ] Add an option to generate a `damage_flash` variant for mob-type entities. - [ ] Add a fix for 360 rotation snap by using `set_frame` instead of `apply_frame` for the first frame of the animation. +- [ ] Add a toggle for node custom names. # Data Pack Compiler diff --git a/bun.lock b/bun.lock index ed4cbd80..0a05cac1 100644 --- a/bun.lock +++ b/bun.lock @@ -37,7 +37,7 @@ "firebase": "^9.19.0", "jiti": "^2.6.1", "js-yaml": "^4.1.0", - "mc-build": "^4.1.2", + "mc-build": "^4.1.3", "node-modules-vscode-problems-patch": "^1.0.9", "octokit": "^5.0.3", "prettier": "^3.8.2", @@ -829,7 +829,7 @@ "matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], - "mc-build": ["mc-build@4.1.2", "", { "bin": { "mcb3": "dist/mcb.js", "mc-build": "dist/mcb.js", "mcb": "dist/mcb.js" } }, "sha512-C/Su40vSUn2IPtbtLPzkQXUUiv2ATCOwvkE4dE4JhORIWM6qTWHwCZlABeqpegcjRvR6PuqWQeyqd2cVeCW8BQ=="], + "mc-build": ["mc-build@4.1.3", "", { "bin": { "mcb3": "dist/mcb.js", "mc-build": "dist/mcb.js", "mcb": "dist/mcb.js" } }, "sha512-toWLAGIkd69Dc5V+RnTtuZQJkyFYR9H7rLWHMN3+e/0lIWp/srJZalE2qTVS1+HHdbMaq1iKtBADW0rW9JbAnQ=="], "md5": ["md5@2.3.0", "", { "dependencies": { "charenc": "0.0.2", "crypt": "0.0.2", "is-buffer": "~1.1.6" } }, "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g=="], diff --git a/package.json b/package.json index 6ec4dcbb..90fe060f 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "title": "Animated Java", "icon": "icon.svg", "description": "Effortlessly craft complex animations for Minecraft: Java Edition", - "version": "1.10.1", + "version": "1.10.2", "min_blockbench_version": "5.1.4", "variant": "desktop", "tags": [ diff --git a/src/assets/icons/command_block.webp b/src/assets/icons/command_block.webp new file mode 100644 index 00000000..42fe7796 Binary files /dev/null and b/src/assets/icons/command_block.webp differ diff --git a/src/constants.ts b/src/constants.ts index 914058a3..6f56deb3 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,7 +4,6 @@ export const PACKAGE: typeof PACKAGEJSON = PACKAGEJSON let cachedFsModule: ScopedFS | null = null export function getFsModule() { - debugger cachedFsModule ??= requireNativeModule('fs', { message: localize('require.fs'), optional: false, diff --git a/src/dialogs/blueprintSettings/blueprintSettings.ts b/src/dialogs/blueprintSettings/blueprintSettings.ts index b1584feb..500a0354 100644 --- a/src/dialogs/blueprintSettings/blueprintSettings.ts +++ b/src/dialogs/blueprintSettings/blueprintSettings.ts @@ -7,6 +7,8 @@ import { OPEN_DOCUMENTATION, } from '../../interface/animatedJavaBarItem' import { updateAllCubeOutlines } from '../../mods/cube' +import { VanillaBlockDisplay } from '../../outliner/vanillaBlockDisplay' +import { VanillaItemDisplay } from '../../outliner/vanillaItemDisplay' import { createScopedTranslator } from '../../util/lang' import FooterComponent from './footer.svelte' import DatapackComponent from './pages/datapack.svelte' @@ -81,6 +83,9 @@ export function openBlueprintSettings() { disableKeybinds: true, buttons: [tl('dialog.close')], onClose: () => { + VanillaBlockDisplay.forceUpdateAll() + VanillaItemDisplay.forceUpdateAll() + VanillaItemDisplay.forceUpdateAll() updateRotationConstraints() updateAllCubeOutlines() Canvas.updateAll() diff --git a/src/dialogs/blueprintSettings/pages/general.svelte b/src/dialogs/blueprintSettings/pages/general.svelte index d8187293..2bd15e41 100644 --- a/src/dialogs/blueprintSettings/pages/general.svelte +++ b/src/dialogs/blueprintSettings/pages/general.svelte @@ -1,7 +1,7 @@ - - - -
- - - - - - -
- -
- - - - saveConfig()} + > + +
+ + + + + + + + {#if overrideBrightness} + + + + {/if} + + {#if !(displayEntity instanceof TextDisplay)} + {#if !(displayEntity instanceof VanillaBlockDisplay)} + + {/if} + + + + + + + {/if} + + + + +
+ + diff --git a/src/dialogs/entityCount/entityCount.svelte b/src/dialogs/entityCount/entityCount.svelte index 4eb822b7..605697aa 100644 --- a/src/dialogs/entityCount/entityCount.svelte +++ b/src/dialogs/entityCount/entityCount.svelte @@ -1,34 +1,17 @@
diff --git a/src/dialogs/variantConfig/variantConfig.svelte b/src/dialogs/variantConfig/variantConfig.svelte index 555bffe7..a53aaec3 100644 --- a/src/dialogs/variantConfig/variantConfig.svelte +++ b/src/dialogs/variantConfig/variantConfig.svelte @@ -8,6 +8,7 @@ -

- {translate('panel.vanilla_block_display.title')} -

+{#if selected} +

+ {translate('panel.vanilla_block_display.title')} +

-
-
- +
+
+ +
-
-{#if $error} -
- {$error} -
+ {#if $error} +
+ {$error} +
+ {/if} {/if} diff --git a/src/svelteComponents/sidebarDialogItems/boxSelect.svelte b/src/svelteComponents/sidebarDialogItems/boxSelect.svelte index 3a20c892..5e8ec564 100644 --- a/src/svelteComponents/sidebarDialogItems/boxSelect.svelte +++ b/src/svelteComponents/sidebarDialogItems/boxSelect.svelte @@ -95,5 +95,6 @@ user-select: none; transform: translate(0px, 0px) rotate(345deg); transition: transform 0.1s cubic-bezier(0.25, 0.68, 0.53, 1.3); + image-rendering: auto; } diff --git a/src/svelteComponents/sidebarDialogItems/select.svelte b/src/svelteComponents/sidebarDialogItems/select.svelte new file mode 100644 index 00000000..b3716225 --- /dev/null +++ b/src/svelteComponents/sidebarDialogItems/select.svelte @@ -0,0 +1,55 @@ + + + + + + {#snippet inlineChildren()} +
+
+ {/snippet} +
+ + diff --git a/src/systems/datapackCompiler/1.20.4/global.mcb b/src/systems/datapackCompiler/1.20.4/global.mcb index ecac0c6b..7a33de9f 100644 --- a/src/systems/datapackCompiler/1.20.4/global.mcb +++ b/src/systems/datapackCompiler/1.20.4/global.mcb @@ -31,10 +31,10 @@ dir global { dir root { function on_tick { + data_manager prep read IF (debug_mode) { execute unless score @s <%OBJECTIVES.IS_RIG_LOADED()%> matches 1 run function *global/root/on_load } - data_manager prep read function *global/root/run_project_tick with storage <%temp_storage%> entry.data } @@ -62,11 +62,23 @@ dir global { # Overwrite the rig hash so the warning doesn't show again. data modify storage <%temp_storage%> entry.data.rig_hash set value '<%rig_hash%>' data_manager write + block run_print { with storage <%temp_storage%> entry.data + $function $(blueprint_id)/zzz/outdated_rig_warning with storage <%temp_storage%> args + } - block print { with storage <%temp_storage%> args - $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + # Loop over rig entities and glow them red. + data modify storage <%temp_storage%> list set from storage <%temp_storage%> entry.data.uuids + block loop { + data modify storage <%temp_storage%> args.uuid set from storage <%temp_storage%> list[-1] + data remove storage <%temp_storage%> list[-1] + block as_uuid { with storage <%temp_storage%> args + $data merge entity $(uuid) {Glowing: 1b, glow_color_override: <%0xff0000%>} + } + + execute store result score #length <%OBJECTIVES.I()%> run data get storage <%temp_storage%> list + execute if score #length <%OBJECTIVES.I()%> matches 1.. run function ^0 } - execute on passengers run data merge entity @s {Glowing: 1b, glow_color_override: <%0xff0000%>} + summon minecraft:text_display ~ ~ ~ { \ Tags:[ \ '<%TAGS.GLOBAL_ENTITY()%>', \ @@ -153,7 +165,7 @@ dir global { # Returns 1 if the rig is outdated, else returns 0. function is_rig_outdated { data_manager prep read - block { with storage <%temp_storage%> entry.data + return run block { with storage <%temp_storage%> entry.data # REVIEW - The replace here is a bit hacky. # Because this is a core function, I need to create a generic version of # project_storage that uses a macro to get the blueprint ID instead of hardcoding it. diff --git a/src/systems/datapackCompiler/1.20.4/main.mcb b/src/systems/datapackCompiler/1.20.4/main.mcb index ab5c9c9d..6586e159 100644 --- a/src/systems/datapackCompiler/1.20.4/main.mcb +++ b/src/systems/datapackCompiler/1.20.4/main.mcb @@ -29,6 +29,12 @@ IF (has_animations) { } } +dir zzz { + function outdated_rig_warning { + $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + } +} + dir root { function on_tick { # Custom pre-tick function @@ -411,23 +417,23 @@ IF (has_animations) { $execute \ as $(<%node.storage_name%>) \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } ELSE { execute \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } @@ -495,11 +501,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.locators[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } @@ -507,8 +513,8 @@ IF (has_animations) { if (node.config?.use_entity) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -517,8 +523,8 @@ IF (has_animations) { } else { frameFuncEnd += `\nexecute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `${transform.function}` @@ -532,19 +538,19 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.interactions[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } if (transform.function) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_interaction_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -668,9 +674,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { summon minecraft:interaction \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ { \ Tags:<%getNodeTags(interaction, rig)%>, \ response: <%interaction.config.response ?? false%>, \ @@ -704,9 +710,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { summon <%locator.config.entity_type%> \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(locator, rig)%>} execute \ as @e[ \ @@ -729,9 +735,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { summon minecraft:item_display \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(camera, rig)%>, teleport_duration: 2} execute \ as @e[ \ @@ -766,20 +772,10 @@ function summon { data modify storage <%temp_storage%> entry.data.uuids_by_name.<%node.storage_name%> set from storage <%gu_storage%> out } - IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - # Track any custom entities on the locator. - $execute at @s as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids - } - data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids - } - } + data_manager write function <%blueprint_id%>/zzz/set_default_pose - data_manager write - # Variant Arguement IF (Object.keys(rig.variants).length > 1) { execute if data storage <%temp_storage%> args.variant run block variant_arg/process { with storage <%temp_storage%> args @@ -863,9 +859,6 @@ function summon { execute if score #success <%OBJECTIVES.I()%> matches 0 run return fail } - IF (has_locators || has_cameras) { - function <%blueprint_id%>/root/on_tick/transform_floating_entities - } execute on passengers run tp @s ~ ~ ~ ~ ~ # Apply teleport duration @@ -873,23 +866,41 @@ function summon { execute on passengers run data modify entity @s teleport_duration set value <%teleportation_duration%> IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { - <%% - emit.mcb(locator.config.on_summon_function) - %%> + # Capture the value of entry.data.locators in the macro call to prevent unexpected + # behavior if entry.data.locators is modified by any on_summon_function calls. + block { with storage <%temp_storage%> entry.data.locators + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { + $block { $(<%locator.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { + <%% + emit.mcb(locator.config.on_summon_function) + %%> + } } } } + + data_manager prep read + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { + block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> + # Track any custom entities on the locator. + $execute as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids + } + data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids + } + data_manager write } - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { - block { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { - <%% - emit.mcb(interaction.config.on_summon_function) - %%> + IF (has_interactions) { + block { with storage <%temp_storage%> entry.data.interactions + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { + $block { $(<%interaction.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { + <%% + emit.mcb(interaction.config.on_summon_function) + %%> + } + } } } } @@ -1653,6 +1664,12 @@ IF (Object.keys(rig.variants).length > 1) { } } } + IF (variant.on_apply_function) { + <%% + emit.mcb(variant.on_apply_function) + %%> + } + # Return success to allow this function to be used in function conditions. return 1 } @@ -1668,27 +1685,27 @@ IF (has_locators || has_cameras) { IF (locator.config?.use_entity) { execute at @s run block set_default_pose/as_locator_<%locator.storage_name%> { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> $tp $(uuid) \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[0], 10)%> + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } ELSE { data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } @@ -1696,17 +1713,17 @@ IF (has_locators || has_cameras) { REPEAT(Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { execute at @s run block set_default_pose/as_interaction_<%interaction.storage_name%> { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> $tp $(uuid) \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[0], 10)%> + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> merge value { \ - px: <%roundTo(interaction.default_transform.pos[0], 10)%>, \ - py: <%roundTo(interaction.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(interaction.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(interaction.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(interaction.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(interaction.default_transform.pos[0], 4)%>, \ + py: <%roundTo(interaction.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(interaction.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(interaction.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(interaction.default_transform.head_rot[0], 4)%> \ } } } @@ -1714,18 +1731,18 @@ IF (has_locators || has_cameras) { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { execute at @s run block set_default_pose/as_camera_<%camera.storage_name%> { with storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> $tp $(uuid) \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[0], 10)%> + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> merge value { \ - px: <%roundTo(camera.default_transform.pos[0], 10)%>, \ - py: <%roundTo(camera.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(camera.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(camera.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(camera.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(camera.default_transform.pos[0], 4)%>, \ + py: <%roundTo(camera.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(camera.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(camera.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(camera.default_transform.head_rot[0], 4)%> \ } } } @@ -1776,9 +1793,7 @@ IF (has_animations) { # Changes the pose of the rig to the the default pose with interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/apply_default_pose } } @@ -1787,8 +1802,6 @@ function set_default_pose { # Changes the pose of the rig to the the default pose without interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/set_default_pose } diff --git a/src/systems/datapackCompiler/1.20.5/main.mcb b/src/systems/datapackCompiler/1.20.5/main.mcb index 713934b6..2a4ca6e0 100644 --- a/src/systems/datapackCompiler/1.20.5/main.mcb +++ b/src/systems/datapackCompiler/1.20.5/main.mcb @@ -32,6 +32,12 @@ IF (has_animations) { } } +dir zzz { + function outdated_rig_warning { + $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + } +} + dir root { function on_tick { # Custom pre-tick function @@ -414,23 +420,23 @@ IF (has_animations) { $execute \ as $(<%node.storage_name%>) \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } ELSE { execute \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } @@ -498,11 +504,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.locators[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } @@ -510,8 +516,8 @@ IF (has_animations) { if (node.config?.use_entity) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -520,8 +526,8 @@ IF (has_animations) { } else { frameFuncEnd += `\nexecute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `${transform.function}` @@ -535,19 +541,19 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.interactions[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } if (transform.function) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_interaction_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -671,9 +677,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { summon minecraft:interaction \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ { \ Tags:<%getNodeTags(interaction, rig)%>, \ response: <%interaction.config.response ?? false%>, \ @@ -707,9 +713,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { summon <%locator.config.entity_type%> \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(locator, rig)%>} execute \ as @e[ \ @@ -732,9 +738,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { summon minecraft:item_display \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(camera, rig)%>, teleport_duration: 2} execute \ as @e[ \ @@ -769,19 +775,8 @@ function summon { data modify storage <%temp_storage%> entry.data.uuids_by_name.<%node.storage_name%> set from storage <%gu_storage%> out } - IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - # Track any custom entities on the locator. - $execute at @s as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids - } - data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids - } - } - - function <%blueprint_id%>/zzz/set_default_pose - data_manager write + function <%blueprint_id%>/zzz/set_default_pose # Variant Arguement IF (Object.keys(rig.variants).length > 1) { @@ -866,9 +861,6 @@ function summon { execute if score #success <%OBJECTIVES.I()%> matches 0 run return fail } - IF (has_locators || has_cameras) { - function <%blueprint_id%>/root/on_tick/transform_floating_entities - } execute on passengers run tp @s ~ ~ ~ ~ ~ # Apply teleport duration @@ -876,23 +868,41 @@ function summon { execute on passengers run data modify entity @s teleport_duration set value <%teleportation_duration%> IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { - <%% - emit.mcb(locator.config.on_summon_function) - %%> + # Capture the value of entry.data.locators in the macro call to prevent unexpected + # behavior if entry.data.locators is modified by any on_summon_function calls. + block { with storage <%temp_storage%> entry.data.locators + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { + $block { $(<%locator.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { + <%% + emit.mcb(locator.config.on_summon_function) + %%> + } } } } + + data_manager prep read + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { + block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> + # Track any custom entities on the locator. + $execute as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids + } + data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids + } + data_manager write } - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { - block { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { - <%% - emit.mcb(interaction.config.on_summon_function) - %%> + IF (has_interactions) { + block { with storage <%temp_storage%> entry.data.interactions + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { + $block { $(<%interaction.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { + <%% + emit.mcb(interaction.config.on_summon_function) + %%> + } + } } } } @@ -1656,6 +1666,12 @@ IF (Object.keys(rig.variants).length > 1) { } } } + IF (variant.on_apply_function) { + <%% + emit.mcb(variant.on_apply_function) + %%> + } + # Return success to allow this function to be used in function conditions. return 1 } @@ -1671,27 +1687,27 @@ IF (has_locators || has_cameras) { IF (locator.config?.use_entity) { execute at @s run block set_default_pose/as_locator_<%locator.storage_name%> { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> $tp $(uuid) \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[0], 10)%> + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } ELSE { data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } @@ -1699,17 +1715,17 @@ IF (has_locators || has_cameras) { REPEAT(Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { execute at @s run block set_default_pose/as_interaction_<%interaction.storage_name%> { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> $tp $(uuid) \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[0], 10)%> + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> merge value { \ - px: <%roundTo(interaction.default_transform.pos[0], 10)%>, \ - py: <%roundTo(interaction.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(interaction.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(interaction.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(interaction.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(interaction.default_transform.pos[0], 4)%>, \ + py: <%roundTo(interaction.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(interaction.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(interaction.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(interaction.default_transform.head_rot[0], 4)%> \ } } } @@ -1717,18 +1733,18 @@ IF (has_locators || has_cameras) { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { execute at @s run block set_default_pose/as_camera_<%camera.storage_name%> { with storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> $tp $(uuid) \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[0], 10)%> + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> merge value { \ - px: <%roundTo(camera.default_transform.pos[0], 10)%>, \ - py: <%roundTo(camera.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(camera.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(camera.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(camera.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(camera.default_transform.pos[0], 4)%>, \ + py: <%roundTo(camera.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(camera.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(camera.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(camera.default_transform.head_rot[0], 4)%> \ } } } @@ -1779,9 +1795,7 @@ IF (has_animations) { # Changes the pose of the rig to the the default pose with interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/apply_default_pose } } @@ -1790,8 +1804,6 @@ function set_default_pose { # Changes the pose of the rig to the the default pose without interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/set_default_pose } diff --git a/src/systems/datapackCompiler/1.21.0/global.mcb b/src/systems/datapackCompiler/1.21.0/global.mcb index ce13c472..38bf4eff 100644 --- a/src/systems/datapackCompiler/1.21.0/global.mcb +++ b/src/systems/datapackCompiler/1.21.0/global.mcb @@ -34,10 +34,10 @@ dir global { dir root { function on_tick { + data_manager prep read IF (debug_mode) { execute unless score @s <%OBJECTIVES.IS_RIG_LOADED()%> matches 1 run function *global/root/on_load } - data_manager prep read function *global/root/run_project_tick with storage <%temp_storage%> entry.data } @@ -65,11 +65,23 @@ dir global { # Overwrite the rig hash so the warning doesn't show again. data modify storage <%temp_storage%> entry.data.rig_hash set value '<%rig_hash%>' data_manager write + block run_print { with storage <%temp_storage%> entry.data + $function $(blueprint_id)/zzz/outdated_rig_warning with storage <%temp_storage%> args + } - block print { with storage <%temp_storage%> args - $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + # Loop over rig entities and glow them red. + data modify storage <%temp_storage%> list set from storage <%temp_storage%> entry.data.uuids + block loop { + data modify storage <%temp_storage%> args.uuid set from storage <%temp_storage%> list[-1] + data remove storage <%temp_storage%> list[-1] + block as_uuid { with storage <%temp_storage%> args + $data merge entity $(uuid) {Glowing: 1b, glow_color_override: <%0xff0000%>} + } + + execute store result score #length <%OBJECTIVES.I()%> run data get storage <%temp_storage%> list + execute if score #length <%OBJECTIVES.I()%> matches 1.. run function ^0 } - execute on passengers run data merge entity @s {Glowing: 1b, glow_color_override: <%0xff0000%>} + summon minecraft:text_display ~ ~ ~ { \ Tags:[ \ '<%TAGS.GLOBAL_ENTITY()%>', \ @@ -156,7 +168,7 @@ dir global { # Returns 1 if the rig is outdated, else returns 0. function is_rig_outdated { data_manager prep read - block { with storage <%temp_storage%> entry.data + return run block { with storage <%temp_storage%> entry.data # REVIEW - The replace here is a bit hacky. # Because this is a core function, I need to create a generic version of # project_storage that uses a macro to get the blueprint ID instead of hardcoding it. diff --git a/src/systems/datapackCompiler/1.21.0/main.mcb b/src/systems/datapackCompiler/1.21.0/main.mcb index 9970d1cd..d5048c81 100644 --- a/src/systems/datapackCompiler/1.21.0/main.mcb +++ b/src/systems/datapackCompiler/1.21.0/main.mcb @@ -33,6 +33,12 @@ IF (has_animations) { } } +dir zzz { + function outdated_rig_warning { + $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + } +} + dir root { function on_tick { # Custom pre-tick function @@ -415,23 +421,23 @@ IF (has_animations) { $execute \ as $(<%node.storage_name%>) \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } ELSE { execute \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } @@ -499,11 +505,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.locators[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } @@ -511,8 +517,8 @@ IF (has_animations) { if (node.config?.use_entity) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -521,8 +527,8 @@ IF (has_animations) { } else { frameFuncEnd += `\nexecute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `${transform.function}` @@ -536,19 +542,19 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.interactions[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } if (transform.function) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_interaction_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -672,9 +678,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { summon minecraft:interaction \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ { \ Tags:<%getNodeTags(interaction, rig)%>, \ response: <%interaction.config.response ?? false%>, \ @@ -708,9 +714,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { summon <%locator.config.entity_type%> \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(locator, rig)%>} execute \ as @n[ \ @@ -733,9 +739,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { summon minecraft:item_display \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(camera, rig)%>, teleport_duration: 2} execute \ as @n[ \ @@ -770,19 +776,8 @@ function summon { data modify storage <%temp_storage%> entry.data.uuids_by_name.<%node.storage_name%> set from storage <%gu_storage%> out } - IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - # Track any custom entities on the locator. - $execute at @s as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids - } - data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids - } - } - - function <%blueprint_id%>/zzz/set_default_pose - data_manager write + function <%blueprint_id%>/zzz/set_default_pose # Variant Arguement IF (Object.keys(rig.variants).length > 1) { @@ -867,9 +862,6 @@ function summon { execute if score #success <%OBJECTIVES.I()%> matches 0 run return fail } - IF (has_locators || has_cameras) { - function <%blueprint_id%>/root/on_tick/transform_floating_entities - } execute on passengers run tp @s ~ ~ ~ ~ ~ # Apply teleport duration @@ -877,23 +869,41 @@ function summon { execute on passengers run data modify entity @s teleport_duration set value <%teleportation_duration%> IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { - <%% - emit.mcb(locator.config.on_summon_function) - %%> + # Capture the value of entry.data.locators in the macro call to prevent unexpected + # behavior if entry.data.locators is modified by any on_summon_function calls. + block { with storage <%temp_storage%> entry.data.locators + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { + $block { $(<%locator.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { + <%% + emit.mcb(locator.config.on_summon_function) + %%> + } } } } + + data_manager prep read + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { + block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> + # Track any custom entities on the locator. + $execute as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids + } + data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids + } + data_manager write } - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { - block { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { - <%% - emit.mcb(interaction.config.on_summon_function) - %%> + IF (has_interactions) { + block { with storage <%temp_storage%> entry.data.interactions + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { + $block { $(<%interaction.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { + <%% + emit.mcb(interaction.config.on_summon_function) + %%> + } + } } } } @@ -1657,6 +1667,12 @@ IF (Object.keys(rig.variants).length > 1) { } } } + IF (variant.on_apply_function) { + <%% + emit.mcb(variant.on_apply_function) + %%> + } + # Return success to allow this function to be used in function conditions. return 1 } @@ -1672,27 +1688,27 @@ IF (has_locators || has_cameras) { IF (locator.config?.use_entity) { execute at @s run block set_default_pose/as_locator_<%locator.storage_name%> { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> $tp $(uuid) \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[0], 10)%> + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } ELSE { data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } @@ -1700,17 +1716,17 @@ IF (has_locators || has_cameras) { REPEAT(Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { execute at @s run block set_default_pose/as_interaction_<%interaction.storage_name%> { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> $tp $(uuid) \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[0], 10)%> + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> merge value { \ - px: <%roundTo(interaction.default_transform.pos[0], 10)%>, \ - py: <%roundTo(interaction.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(interaction.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(interaction.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(interaction.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(interaction.default_transform.pos[0], 4)%>, \ + py: <%roundTo(interaction.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(interaction.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(interaction.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(interaction.default_transform.head_rot[0], 4)%> \ } } } @@ -1718,18 +1734,18 @@ IF (has_locators || has_cameras) { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { execute at @s run block set_default_pose/as_camera_<%camera.storage_name%> { with storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> $tp $(uuid) \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[0], 10)%> + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> merge value { \ - px: <%roundTo(camera.default_transform.pos[0], 10)%>, \ - py: <%roundTo(camera.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(camera.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(camera.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(camera.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(camera.default_transform.pos[0], 4)%>, \ + py: <%roundTo(camera.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(camera.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(camera.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(camera.default_transform.head_rot[0], 4)%> \ } } } @@ -1780,9 +1796,7 @@ IF (has_animations) { # Changes the pose of the rig to the the default pose with interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/apply_default_pose } } @@ -1791,8 +1805,6 @@ function set_default_pose { # Changes the pose of the rig to the the default pose without interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/set_default_pose } diff --git a/src/systems/datapackCompiler/1.21.2/main.mcb b/src/systems/datapackCompiler/1.21.2/main.mcb index f15230dc..92252b33 100644 --- a/src/systems/datapackCompiler/1.21.2/main.mcb +++ b/src/systems/datapackCompiler/1.21.2/main.mcb @@ -32,6 +32,12 @@ IF (has_animations) { } } +dir zzz { + function outdated_rig_warning { + $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + } +} + dir root { function on_tick { # Custom pre-tick function @@ -414,23 +420,23 @@ IF (has_animations) { $execute \ as $(<%node.storage_name%>) \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } ELSE { execute \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } @@ -498,11 +504,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.locators[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } @@ -510,8 +516,8 @@ IF (has_animations) { if (node.config?.use_entity) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -520,8 +526,8 @@ IF (has_animations) { } else { frameFuncEnd += `\nexecute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `${transform.function}` @@ -535,19 +541,19 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.interactions[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } if (transform.function) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_interaction_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -671,9 +677,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { summon minecraft:interaction \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ { \ Tags:<%getNodeTags(interaction, rig)%>, \ response: <%interaction.config.response ?? false%>, \ @@ -707,9 +713,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { summon <%locator.config.entity_type%> \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(locator, rig)%>} execute \ as @n[ \ @@ -732,9 +738,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { summon minecraft:item_display \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(camera, rig)%>, teleport_duration: 2} execute \ as @n[ \ @@ -769,19 +775,8 @@ function summon { data modify storage <%temp_storage%> entry.data.uuids_by_name.<%node.storage_name%> set from storage <%gu_storage%> out } - IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - # Track any custom entities on the locator. - $execute at @s as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids - } - data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids - } - } - - function <%blueprint_id%>/zzz/set_default_pose - data_manager write + function <%blueprint_id%>/zzz/set_default_pose # Variant Arguement IF (Object.keys(rig.variants).length > 1) { @@ -866,9 +861,6 @@ function summon { execute if score #success <%OBJECTIVES.I()%> matches 0 run return fail } - IF (has_locators || has_cameras) { - function <%blueprint_id%>/root/on_tick/transform_floating_entities - } execute on passengers run rotate @s ~ ~ # Apply teleport duration @@ -876,23 +868,41 @@ function summon { execute on passengers run data modify entity @s teleport_duration set value <%teleportation_duration%> IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { - <%% - emit.mcb(locator.config.on_summon_function) - %%> + # Capture the value of entry.data.locators in the macro call to prevent unexpected + # behavior if entry.data.locators is modified by any on_summon_function calls. + block { with storage <%temp_storage%> entry.data.locators + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { + $block { $(<%locator.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { + <%% + emit.mcb(locator.config.on_summon_function) + %%> + } } } } + + data_manager prep read + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { + block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> + # Track any custom entities on the locator. + $execute as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids + } + data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids + } + data_manager write } - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { - block { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { - <%% - emit.mcb(interaction.config.on_summon_function) - %%> + IF (has_interactions) { + block { with storage <%temp_storage%> entry.data.interactions + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { + $block { $(<%interaction.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { + <%% + emit.mcb(interaction.config.on_summon_function) + %%> + } + } } } } @@ -1656,6 +1666,12 @@ IF (Object.keys(rig.variants).length > 1) { } } } + IF (variant.on_apply_function) { + <%% + emit.mcb(variant.on_apply_function) + %%> + } + # Return success to allow this function to be used in function conditions. return 1 } @@ -1671,27 +1687,27 @@ IF (has_locators || has_cameras) { IF (locator.config?.use_entity) { execute at @s run block set_default_pose/as_locator_<%locator.storage_name%> { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> $tp $(uuid) \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[0], 10)%> + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } ELSE { data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } @@ -1699,17 +1715,17 @@ IF (has_locators || has_cameras) { REPEAT(Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { execute at @s run block set_default_pose/as_interaction_<%interaction.storage_name%> { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> $tp $(uuid) \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[0], 10)%> + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> merge value { \ - px: <%roundTo(interaction.default_transform.pos[0], 10)%>, \ - py: <%roundTo(interaction.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(interaction.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(interaction.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(interaction.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(interaction.default_transform.pos[0], 4)%>, \ + py: <%roundTo(interaction.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(interaction.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(interaction.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(interaction.default_transform.head_rot[0], 4)%> \ } } } @@ -1717,18 +1733,18 @@ IF (has_locators || has_cameras) { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { execute at @s run block set_default_pose/as_camera_<%camera.storage_name%> { with storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> $tp $(uuid) \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[0], 10)%> + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> merge value { \ - px: <%roundTo(camera.default_transform.pos[0], 10)%>, \ - py: <%roundTo(camera.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(camera.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(camera.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(camera.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(camera.default_transform.pos[0], 4)%>, \ + py: <%roundTo(camera.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(camera.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(camera.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(camera.default_transform.head_rot[0], 4)%> \ } } } @@ -1779,9 +1795,7 @@ IF (has_animations) { # Changes the pose of the rig to the the default pose with interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/apply_default_pose } } @@ -1790,8 +1804,6 @@ function set_default_pose { # Changes the pose of the rig to the the default pose without interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/set_default_pose } diff --git a/src/systems/datapackCompiler/1.21.4/main.mcb b/src/systems/datapackCompiler/1.21.4/main.mcb index 0ebd7ccd..2da1285d 100644 --- a/src/systems/datapackCompiler/1.21.4/main.mcb +++ b/src/systems/datapackCompiler/1.21.4/main.mcb @@ -33,6 +33,12 @@ IF (has_animations) { } } +dir zzz { + function outdated_rig_warning { + $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + } +} + dir root { function on_tick { # Custom pre-tick function @@ -502,23 +508,23 @@ IF (has_animations) { $execute \ as $(<%node.storage_name%>) \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } ELSE { execute \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } @@ -586,11 +592,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.locators[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } @@ -598,8 +604,8 @@ IF (has_animations) { if (node.config?.use_entity) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -608,8 +614,8 @@ IF (has_animations) { } else { frameFuncEnd += `\nexecute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `${transform.function}` @@ -623,19 +629,19 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.interactions[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } if (transform.function) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_interaction_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -759,9 +765,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { summon minecraft:interaction \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ { \ Tags:<%getNodeTags(interaction, rig)%>, \ response: <%interaction.config.response ?? false%>, \ @@ -795,9 +801,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { summon <%locator.config.entity_type%> \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(locator, rig)%>} execute \ as @n[ \ @@ -820,9 +826,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { summon minecraft:item_display \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(camera, rig)%>, teleport_duration: 2} execute \ as @n[ \ @@ -857,19 +863,8 @@ function summon { data modify storage <%temp_storage%> entry.data.uuids_by_name.<%node.storage_name%> set from storage <%gu_storage%> out } - IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - # Track any custom entities on the locator. - $execute at @s as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids - } - data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids - } - } - - function <%blueprint_id%>/zzz/set_default_pose - data_manager write + function <%blueprint_id%>/zzz/set_default_pose # Variant Arguement IF (Object.keys(rig.variants).length > 1) { @@ -954,9 +949,6 @@ function summon { execute if score #success <%OBJECTIVES.I()%> matches 0 run return fail } - IF (has_locators || has_cameras) { - function <%blueprint_id%>/root/on_tick/transform_floating_entities - } execute on passengers run rotate @s ~ ~ # Apply teleport duration @@ -964,23 +956,41 @@ function summon { execute on passengers run data modify entity @s teleport_duration set value <%teleportation_duration%> IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { - <%% - emit.mcb(locator.config.on_summon_function) - %%> + # Capture the value of entry.data.locators in the macro call to prevent unexpected + # behavior if entry.data.locators is modified by any on_summon_function calls. + block { with storage <%temp_storage%> entry.data.locators + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { + $block { $(<%locator.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { + <%% + emit.mcb(locator.config.on_summon_function) + %%> + } } } } + + data_manager prep read + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { + block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> + # Track any custom entities on the locator. + $execute as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids + } + data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids + } + data_manager write } - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { - block { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { - <%% - emit.mcb(interaction.config.on_summon_function) - %%> + IF (has_interactions) { + block { with storage <%temp_storage%> entry.data.interactions + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { + $block { $(<%interaction.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { + <%% + emit.mcb(interaction.config.on_summon_function) + %%> + } + } } } } @@ -1747,6 +1757,12 @@ IF (Object.keys(rig.variants).length > 1) { } } + IF (variant.on_apply_function) { + <%% + emit.mcb(variant.on_apply_function) + %%> + } + # Return success to allow this function to be used in function conditions. return 1 } @@ -1762,27 +1778,27 @@ IF (has_locators || has_cameras) { IF (locator.config?.use_entity) { execute at @s run block set_default_pose/as_locator_<%locator.storage_name%> { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> $tp $(uuid) \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[0], 10)%> + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } ELSE { data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } @@ -1790,17 +1806,17 @@ IF (has_locators || has_cameras) { REPEAT(Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { execute at @s run block set_default_pose/as_interaction_<%interaction.storage_name%> { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> $tp $(uuid) \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[0], 10)%> + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> merge value { \ - px: <%roundTo(interaction.default_transform.pos[0], 10)%>, \ - py: <%roundTo(interaction.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(interaction.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(interaction.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(interaction.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(interaction.default_transform.pos[0], 4)%>, \ + py: <%roundTo(interaction.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(interaction.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(interaction.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(interaction.default_transform.head_rot[0], 4)%> \ } } } @@ -1808,18 +1824,18 @@ IF (has_locators || has_cameras) { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { execute at @s run block set_default_pose/as_camera_<%camera.storage_name%> { with storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> $tp $(uuid) \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[0], 10)%> + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> merge value { \ - px: <%roundTo(camera.default_transform.pos[0], 10)%>, \ - py: <%roundTo(camera.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(camera.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(camera.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(camera.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(camera.default_transform.pos[0], 4)%>, \ + py: <%roundTo(camera.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(camera.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(camera.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(camera.default_transform.head_rot[0], 4)%> \ } } } @@ -1866,9 +1882,7 @@ IF (has_animations) { # Changes the pose of the rig to the the default pose with interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/apply_default_pose } } @@ -1877,8 +1891,6 @@ function set_default_pose { # Changes the pose of the rig to the the default pose without interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/set_default_pose } diff --git a/src/systems/datapackCompiler/1.21.5/global.mcb b/src/systems/datapackCompiler/1.21.5/global.mcb index 09bc8ed6..926d375d 100644 --- a/src/systems/datapackCompiler/1.21.5/global.mcb +++ b/src/systems/datapackCompiler/1.21.5/global.mcb @@ -34,10 +34,10 @@ dir global { dir root { function on_tick { + data_manager prep read IF (debug_mode) { execute unless score @s <%OBJECTIVES.IS_RIG_LOADED()%> matches 1 run function *global/root/on_load } - data_manager prep read function *global/root/run_project_tick with storage <%temp_storage%> entry.data } @@ -65,11 +65,23 @@ dir global { # Overwrite the rig hash so the warning doesn't show again. data modify storage <%temp_storage%> entry.data.rig_hash set value '<%rig_hash%>' data_manager write + block run_print { with storage <%temp_storage%> entry.data + $function $(blueprint_id)/zzz/outdated_rig_warning with storage <%temp_storage%> args + } - block print { with storage <%temp_storage%> args - $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + # Loop over rig entities and glow them red. + data modify storage <%temp_storage%> list set from storage <%temp_storage%> entry.data.uuids + block loop { + data modify storage <%temp_storage%> args.uuid set from storage <%temp_storage%> list[-1] + data remove storage <%temp_storage%> list[-1] + block as_uuid { with storage <%temp_storage%> args + $data merge entity $(uuid) {Glowing: 1b, glow_color_override: <%0xff0000%>} + } + + execute store result score #length <%OBJECTIVES.I()%> run data get storage <%temp_storage%> list + execute if score #length <%OBJECTIVES.I()%> matches 1.. run function ^0 } - execute on passengers run data merge entity @s {Glowing: 1b, glow_color_override: <%0xff0000%>} + summon minecraft:text_display ~ ~ ~ { \ Tags:[ \ '<%TAGS.GLOBAL_ENTITY()%>', \ @@ -156,7 +168,7 @@ dir global { # Returns 1 if the rig is outdated, else returns 0. function is_rig_outdated { data_manager prep read - block { with storage <%temp_storage%> entry.data + return run block { with storage <%temp_storage%> entry.data # REVIEW - The replace here is a bit hacky. # Because this is a core function, I need to create a generic version of # project_storage that uses a macro to get the blueprint ID instead of hardcoding it. diff --git a/src/systems/datapackCompiler/1.21.5/main.mcb b/src/systems/datapackCompiler/1.21.5/main.mcb index 78b5af29..47b1f078 100644 --- a/src/systems/datapackCompiler/1.21.5/main.mcb +++ b/src/systems/datapackCompiler/1.21.5/main.mcb @@ -32,6 +32,12 @@ IF (has_animations) { } } +dir zzz { + function outdated_rig_warning { + $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + } +} + dir root { function on_tick { # Custom pre-tick function @@ -501,23 +507,23 @@ IF (has_animations) { $execute \ as $(<%node.storage_name%>) \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } ELSE { execute \ positioned \ - ^<%roundTo(global.transform.pos[0], 10)%> \ - ^<%roundTo(global.transform.pos[1], 10)%> \ - ^<%roundTo(global.transform.pos[2], 10)%> \ + ^<%roundTo(global.transform.pos[0], 4)%> \ + ^<%roundTo(global.transform.pos[1], 4)%> \ + ^<%roundTo(global.transform.pos[2], 4)%> \ rotated \ - ~<%roundTo(global.transform.head_rot[1], 10)%> \ - ~<%roundTo(global.transform.head_rot[0], 10)%> \ + ~<%roundTo(global.transform.head_rot[1], 4)%> \ + ~<%roundTo(global.transform.head_rot[0], 4)%> \ <%global.transform.function_execute_condition ? global.transform.function_execute_condition + ' ' : ''%>run \ function ./<%animation.duration%>_locator_<%node.storage_name%> } @@ -585,11 +591,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.locators[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } @@ -597,8 +603,8 @@ IF (has_animations) { if (node.config?.use_entity) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -607,8 +613,8 @@ IF (has_animations) { } else { frameFuncEnd += `\nexecute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_locator_${node.storage_name}%NEWLINE_PATCH%{\n` + `${transform.function}` @@ -622,19 +628,19 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.interactions[node.storage_name] = { - px: roundTo(transform.pos[0], 10), - py: roundTo(transform.pos[1], 10), - pz: roundTo(transform.pos[2], 10), - ry: roundTo(transform.head_rot[1], 10), - rx: roundTo(transform.head_rot[0], 10) + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } if (transform.function) { frameFuncEnd += `\n$execute unless entity @s[tag=${TAGS.TRANSFORMS_ONLY()}] as $(${node.storage_name}) ` - + `positioned ^${roundTo(transform.pos[0], 10)} ^${roundTo(transform.pos[1], 10)} ^${roundTo(transform.pos[2], 10)} ` - + `rotated ~${roundTo(transform.head_rot[1], 10)} ~${roundTo(transform.head_rot[0], 10)} ` + + `positioned ^${roundTo(transform.pos[0], 4)} ^${roundTo(transform.pos[1], 4)} ^${roundTo(transform.pos[2], 4)} ` + + `rotated ~${roundTo(transform.head_rot[1], 4)} ~${roundTo(transform.head_rot[0], 4)} ` + `${transform.function_execute_condition ? transform.function_execute_condition + ' ' : ''}run ` + `block ${frameIndex}_interaction_${node.storage_name}%NEWLINE_PATCH%{\n` + `tp @s ~ ~ ~ ~ ~\n` @@ -758,9 +764,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { summon minecraft:interaction \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ { \ Tags:<%getNodeTags(interaction, rig)%>, \ response: <%interaction.config.response ?? false%>, \ @@ -794,9 +800,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { summon <%locator.config.entity_type%> \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(locator, rig)%>} execute \ as @n[ \ @@ -819,9 +825,9 @@ function summon { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { summon minecraft:item_display \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ {Tags:<%getNodeTags(camera, rig)%>, teleport_duration: 2} execute \ as @n[ \ @@ -856,19 +862,8 @@ function summon { data modify storage <%temp_storage%> entry.data.uuids_by_name.<%node.storage_name%> set from storage <%gu_storage%> out } - IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - # Track any custom entities on the locator. - $execute at @s as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids - } - data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids - } - } - - function <%blueprint_id%>/zzz/set_default_pose - data_manager write + function <%blueprint_id%>/zzz/set_default_pose # Variant Arguement IF (Object.keys(rig.variants).length > 1) { @@ -953,9 +948,6 @@ function summon { execute if score #success <%OBJECTIVES.I()%> matches 0 run return fail } - IF (has_locators || has_cameras) { - function <%blueprint_id%>/root/on_tick/transform_floating_entities - } execute on passengers run rotate @s ~ ~ # Apply teleport duration @@ -963,23 +955,41 @@ function summon { execute on passengers run data modify entity @s teleport_duration set value <%teleportation_duration%> IF (has_entity_locators) { - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { - block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { - <%% - emit.mcb(locator.config.on_summon_function) - %%> + # Capture the value of entry.data.locators in the macro call to prevent unexpected + # behavior if entry.data.locators is modified by any on_summon_function calls. + block { with storage <%temp_storage%> entry.data.locators + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity && node.config.on_summon_function)) as locator { + $block { $(<%locator.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%locator.type + '_' + locator.storage_name%> { + <%% + emit.mcb(locator.config.on_summon_function) + %%> + } } } } + + data_manager prep read + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'locator' && node.config?.use_entity)) as locator { + block { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> + # Track any custom entities on the locator. + $execute as $(uuid) at @s run function animated_java:global/util/get_entity_stack_uuids + } + data modify storage <%temp_storage%> entry.data.uuids append from storage <%temp_storage%> uuids + } + data_manager write } - REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { - block { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> - $execute at @s as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { - <%% - emit.mcb(interaction.config.on_summon_function) - %%> + IF (has_interactions) { + block { with storage <%temp_storage%> entry.data.interactions + REPEAT (Object.values(rig.nodes).filter(node => node.type === 'interaction' && node.config.on_summon_function)) as interaction { + $block { $(<%interaction.storage_name%>) + $execute as $(uuid) at @s run block on_summon/custom_<%interaction.type + '_' + interaction.storage_name%> { + <%% + emit.mcb(interaction.config.on_summon_function) + %%> + } + } } } } @@ -1746,6 +1756,12 @@ IF (Object.keys(rig.variants).length > 1) { } } + IF (variant.on_apply_function) { + <%% + emit.mcb(variant.on_apply_function) + %%> + } + # Return success to allow this function to be used in function conditions. return 1 } @@ -1761,27 +1777,27 @@ IF (has_locators || has_cameras) { IF (locator.config?.use_entity) { execute at @s run block set_default_pose/as_locator_<%locator.storage_name%> { with storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> $tp $(uuid) \ - ^<%roundTo(locator.default_transform.pos[0], 10)%> \ - ^<%roundTo(locator.default_transform.pos[1], 10)%> \ - ^<%roundTo(locator.default_transform.pos[2], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(locator.default_transform.head_rot[0], 10)%> + ^<%roundTo(locator.default_transform.pos[0], 4)%> \ + ^<%roundTo(locator.default_transform.pos[1], 4)%> \ + ^<%roundTo(locator.default_transform.pos[2], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(locator.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } ELSE { data modify storage <%temp_storage%> entry.data.locators.<%locator.storage_name%> merge value { \ - px: <%roundTo(locator.default_transform.pos[0], 10)%>, \ - py: <%roundTo(locator.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(locator.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(locator.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(locator.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(locator.default_transform.pos[0], 4)%>, \ + py: <%roundTo(locator.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(locator.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(locator.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(locator.default_transform.head_rot[0], 4)%> \ } } } @@ -1789,17 +1805,17 @@ IF (has_locators || has_cameras) { REPEAT(Object.values(rig.nodes).filter(node => node.type === 'interaction')) as interaction { execute at @s run block set_default_pose/as_interaction_<%interaction.storage_name%> { with storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> $tp $(uuid) \ - ^<%roundTo(interaction.default_transform.pos[0], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[1], 10)%> \ - ^<%roundTo(interaction.default_transform.pos[2], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(interaction.default_transform.head_rot[0], 10)%> + ^<%roundTo(interaction.default_transform.pos[0], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[1], 4)%> \ + ^<%roundTo(interaction.default_transform.pos[2], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(interaction.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.interactions.<%interaction.storage_name%> merge value { \ - px: <%roundTo(interaction.default_transform.pos[0], 10)%>, \ - py: <%roundTo(interaction.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(interaction.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(interaction.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(interaction.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(interaction.default_transform.pos[0], 4)%>, \ + py: <%roundTo(interaction.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(interaction.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(interaction.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(interaction.default_transform.head_rot[0], 4)%> \ } } } @@ -1807,21 +1823,22 @@ IF (has_locators || has_cameras) { REPEAT (Object.values(rig.nodes).filter(node => node.type === 'camera')) as camera { execute at @s run block set_default_pose/as_camera_<%camera.storage_name%> { with storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> $tp $(uuid) \ - ^<%roundTo(camera.default_transform.pos[0], 10)%> \ - ^<%roundTo(camera.default_transform.pos[1], 10)%> \ - ^<%roundTo(camera.default_transform.pos[2], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[1], 10)%> \ - ~<%roundTo(camera.default_transform.head_rot[0], 10)%> + ^<%roundTo(camera.default_transform.pos[0], 4)%> \ + ^<%roundTo(camera.default_transform.pos[1], 4)%> \ + ^<%roundTo(camera.default_transform.pos[2], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[1], 4)%> \ + ~<%roundTo(camera.default_transform.head_rot[0], 4)%> data modify storage <%temp_storage%> entry.data.cameras.<%camera.storage_name%> merge value { \ - px: <%roundTo(camera.default_transform.pos[0], 10)%>, \ - py: <%roundTo(camera.default_transform.pos[1], 10)%>, \ - pz: <%roundTo(camera.default_transform.pos[2], 10)%>, \ - ry: <%roundTo(camera.default_transform.head_rot[1], 10)%>, \ - rx: <%roundTo(camera.default_transform.head_rot[0], 10)%> \ + px: <%roundTo(camera.default_transform.pos[0], 4)%>, \ + py: <%roundTo(camera.default_transform.pos[1], 4)%>, \ + pz: <%roundTo(camera.default_transform.pos[2], 4)%>, \ + ry: <%roundTo(camera.default_transform.head_rot[1], 4)%>, \ + rx: <%roundTo(camera.default_transform.head_rot[0], 4)%> \ } } } + data_manager write } } } @@ -1865,9 +1882,7 @@ IF (has_animations) { # Changes the pose of the rig to the the default pose with interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/apply_default_pose } } @@ -1876,8 +1891,6 @@ function set_default_pose { # Changes the pose of the rig to the the default pose without interpolation debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> - IF (has_locators || has_cameras || has_interactions) { - data_manager prep read - } + data_manager prep read function ./zzz/set_default_pose } diff --git a/src/systems/datapackCompiler/26.2/global.mcb b/src/systems/datapackCompiler/26.2/global.mcb index b3df6418..d70b7d51 100644 --- a/src/systems/datapackCompiler/26.2/global.mcb +++ b/src/systems/datapackCompiler/26.2/global.mcb @@ -34,10 +34,10 @@ dir global { dir root { function on_tick { + data_manager prep read IF (debug_mode) { execute unless score @s <%OBJECTIVES.IS_RIG_LOADED()%> matches 1 run function *global/root/on_load } - data_manager prep read function *global/root/run_project_tick with storage <%temp_storage%> entry.data } @@ -65,11 +65,23 @@ dir global { # Overwrite the rig hash so the warning doesn't show again. data modify storage <%temp_storage%> entry.data.rig_hash set value '<%rig_hash%>' data_manager write + block run_print { with storage <%temp_storage%> entry.data + $function $(blueprint_id)/zzz/outdated_rig_warning with storage <%temp_storage%> args + } - block print { with storage <%temp_storage%> args - $tellraw @a <%TELLRAW.RIG_OUTDATED()%> + # Loop over rig entities and glow them red. + data modify storage <%temp_storage%> list set from storage <%temp_storage%> entry.data.uuids + block loop { + data modify storage <%temp_storage%> args.uuid set from storage <%temp_storage%> list[-1] + data remove storage <%temp_storage%> list[-1] + block as_uuid { with storage <%temp_storage%> args + $data merge entity $(uuid) {Glowing: 1b, glow_color_override: <%0xff0000%>} + } + + execute store result score #length <%OBJECTIVES.I()%> run data get storage <%temp_storage%> list + execute if score #length <%OBJECTIVES.I()%> matches 1.. run function ^0 } - execute on passengers run data merge entity @s {Glowing: 1b, glow_color_override: <%0xff0000%>} + summon minecraft:text_display ~ ~ ~ { \ Tags:[ \ '<%TAGS.GLOBAL_ENTITY()%>', \ @@ -156,7 +168,7 @@ dir global { # Returns 1 if the rig is outdated, else returns 0. function is_rig_outdated { data_manager prep read - block { with storage <%temp_storage%> entry.data + return run block { with storage <%temp_storage%> entry.data # REVIEW - The replace here is a bit hacky. # Because this is a core function, I need to create a generic version of # project_storage that uses a macro to get the blueprint ID instead of hardcoding it. diff --git a/src/systems/datapackCompiler/tellraw.ts b/src/systems/datapackCompiler/tellraw.ts index 36dd8129..a6bd06a3 100644 --- a/src/systems/datapackCompiler/tellraw.ts +++ b/src/systems/datapackCompiler/tellraw.ts @@ -1,4 +1,5 @@ import { TextComponent, type TextElement } from 'book-and-quill' +import { projectTargetVersionIsAtLeast } from '../../formats/blueprint' import { toSmallCaps } from '../../util/minecraftUtil' import { type IRenderedAnimation } from '../animationRenderer' import { type IRenderedVariant } from '../rigRenderer' @@ -111,14 +112,17 @@ namespace TELLRAW { }, ]) - export const RIG_OUTDATED_TEXT_DISPLAY = () => - new TextComponent([ + export const RIG_OUTDATED_TEXT_DISPLAY = () => { + let text = new TextComponent([ { text: '⚠ This rig instance is outdated! ⚠', color: 'red' }, '\n It should be removed and re-summoned to ensure it functions correctly.', - ]) - // Because this is used as NBT in a summon command, we need to double-escape the newlines. - .toString() - .replaceAll('\\n', '\\\\n') + ]).toString() + if (!projectTargetVersionIsAtLeast('1.21.5')) { + // Because this is used as an NBT string in 1.21.4 and below, we need to double-escape the newlines. + text = text.replaceAll('\\n', '\\\\n') + } + return text + } export const FUNCTION_NOT_EXECUTED_AS_ROOT_ERROR = (functionPath: string, tag: string) => { const hoverText = new TextComponent([ diff --git a/src/systems/jsonText/wrapping.ts b/src/systems/jsonText/wrapping.ts index c3a2e4f2..5588e943 100644 --- a/src/systems/jsonText/wrapping.ts +++ b/src/systems/jsonText/wrapping.ts @@ -254,14 +254,15 @@ export async function wrapJsonText(jsonText: TextComponent, maxLineWidth = 200) const words = await parseWords(jsonText.toJSON()) const lines: Line[] = [] - // FIXME - This will not work for custom fonts - const font = await MinecraftFont.getById('minecraft:default') + // The `getWordWidth` function handles getting the width of words with different / custom fonts + const font = (await MinecraftFont.getById('minecraft:default'))! let backgroundWidth = 0 let currentLine: Line = { words: [], width: 0 } for (const word of words) { const wordWidth = await font.getWordWidth(word) const wordStyles = [...word.styles] + // If the word is longer than than the max line width, split it into multiple lines if (wordWidth - 1 > maxLineWidth) { if (currentLine.words.length) { @@ -344,6 +345,15 @@ export async function wrapJsonText(jsonText: TextComponent, maxLineWidth = 200) currentLine.words.pop() currentLine.width -= lastWord.width } + if (word.text.at(0) === ' ') { + // If the word starts with a space, remove it. + word.text = word.text.slice(1) + word.styles.forEach(span => { + span.start = Math.max(0, span.start - 1) + span.end = Math.max(0, span.end - 1) + }) + // word.width = await font.getWordWidth(word) + } lines.push(currentLine) backgroundWidth = Math.max(backgroundWidth, currentLine.width) currentLine = { words: [], width: 0 } diff --git a/src/systems/minecraft/blockModelManager.ts b/src/systems/minecraft/blockModelManager.ts index 7a732327..6ecebf09 100644 --- a/src/systems/minecraft/blockModelManager.ts +++ b/src/systems/minecraft/blockModelManager.ts @@ -49,8 +49,12 @@ const BLACKLISTED_BLOCKS = new Map([ ['piglin_wall_head', translate('block_model_manager.mob_head_warning')], ]) -export async function getBlockModel(block: string): Promise { - let result = BLOCK_MODEL_CACHE.get(block) +export async function getBlockModel( + block: string, + minecraftVersion = Project.animated_java.target_minecraft_version +): Promise { + const key = minecraftVersion + '|' + block + let result = BLOCK_MODEL_CACHE.get(key) if (!result) { const parsed = await parseBlock(block) if (!parsed) return undefined @@ -58,7 +62,7 @@ export async function getBlockModel(block: string): Promise() id: string providers: FontProvider[] = [] @@ -291,18 +291,23 @@ export class MinecraftFont { this.assetPath = assetPath this.fallback = fallback - MinecraftFont.all.push(this) + MinecraftFont.all.set(this.id, this) } static async getById(id: string) { - let font = MinecraftFont.all.find(font => font.id === id) + let font = MinecraftFont.all.get(id) if (!font) { const path = getPathFromResourceLocation(id, 'font') + '.json' font = new MinecraftFont(id, path) } - await font.load() + try { + await font.load() + } catch (error) { + console.error(`Failed to load font ${font.id} from ${font.assetPath}:`, error) + return undefined + } return font } @@ -407,9 +412,12 @@ export class MinecraftFont { return Math.max(width, 0) } - getColorMaterial(color: tinycolor.Instance): THREE.Material { - const colorString = color.toHex8String() - let material = this.materialCache.get(colorString) + getColorMaterial( + color: tinycolor.Instance, + minecraftVersion = Project.animated_java.target_minecraft_version + ): THREE.Material { + const cacheKey = color.toHex8String() + ';' + minecraftVersion + let material = this.materialCache.get(cacheKey) if (!material) { const alpha = color.getAlpha() if (alpha < 1) { @@ -421,7 +429,7 @@ export class MinecraftFont { } else { material = new THREE.MeshBasicMaterial({ color: color.toHexString() }) } - this.materialCache.set(colorString, material) + this.materialCache.set(cacheKey, material) } return material } @@ -571,7 +579,11 @@ export class MinecraftFont { return { mesh, hitbox: backgroundGeo, outline } } - async getCharGeo(char: string, style: TextComponentStyle): Promise { + async getCharGeo( + char: string, + style: TextComponentStyle, + minecraftVersion = Project.animated_java.target_minecraft_version + ): Promise { let font: MinecraftFont = this if (style.font) { const newFont = await MinecraftFont.getById(style.font) @@ -580,12 +592,12 @@ export class MinecraftFont { const hash = createHash('sha256') hash.update(char) + hash.update(';' + minecraftVersion) hash.update(';' + font.id) - if (style.bold) hash.update('bold') - if (style.italic) hash.update('italic') - if (style.underlined) hash.update('underlined') - if (style.strikethrough) hash.update('strikethrough') - if (style.font) hash.update(';' + font.id) + if (style.bold) hash.update(';bold') + if (style.italic) hash.update(';italic') + if (style.underlined) hash.update(';underlined') + if (style.strikethrough) hash.update(';strikethrough') const digest = hash.digest('hex') const charData = font.getChar(char) diff --git a/src/systems/minecraft/itemModelManager.ts b/src/systems/minecraft/itemModelManager.ts index 6250c393..3c6e4167 100644 --- a/src/systems/minecraft/itemModelManager.ts +++ b/src/systems/minecraft/itemModelManager.ts @@ -18,9 +18,10 @@ const ITEM_MODEL_CACHE = new Map() export async function getItemModel( item: string, - itemDisplay: ItemDisplayMode + itemDisplay: ItemDisplayMode, + minecraftVersion = Project.animated_java.target_minecraft_version ): Promise { - const cacheKey = item + '|' + itemDisplay + const cacheKey = minecraftVersion + '|' + item + '|' + itemDisplay let result = ITEM_MODEL_CACHE.get(cacheKey) if (!result) { result = await parseItemModel(getItemResourceLocation(item), itemDisplay) @@ -95,18 +96,18 @@ export function applyModelDisplayTransform( const rot = display.rotation.map((n: number) => (n * Math.PI) / 180) matrix.makeRotationFromEuler(Reusable.euler1.set(-rot[0], -rot[1], rot[2])) } + if (display.scale) { + matrix.scale(Reusable.vec2.set(...display.scale)) + } if (display.translation) { matrix.setPosition( Reusable.vec1.set( display.translation[0], display.translation[1], - display.translation[2] + -display.translation[2] ) ) } - if (display.scale) { - matrix.scale(Reusable.vec2.set(...display.scale)) - } itemModel.boundingBox.applyMatrix4(matrix) itemModel.outline.geometry.applyMatrix4(matrix) diff --git a/src/variants.ts b/src/variants.ts index 083d9b7f..7b278b35 100644 --- a/src/variants.ts +++ b/src/variants.ts @@ -1,4 +1,7 @@ -import type { IBlueprintVariantJSON } from './formats/blueprint' +import type { IBlueprintDisplayEntityConfigJSON, IBlueprintVariantJSON } from './formats/blueprint' +import { VanillaBlockDisplay } from './outliner/vanillaBlockDisplay' +import { VanillaItemDisplay } from './outliner/vanillaItemDisplay' +import type { IDisplayEntityConfigs } from './systems/rigRenderer' import EVENTS from './util/events' import { sanitizeStorageKey } from './util/minecraftUtil' @@ -83,6 +86,7 @@ export class Variant { textureMap: TextureMap isDefault = false generateNameFromDisplayName = true + onApplyFunction?: string excludedNodes: CollectionItem[] = [] constructor(displayName: string, isDefault = false) { @@ -107,9 +111,21 @@ export class Variant { if (Variant.selected) Variant.selected.unselect() Variant.selected = this Canvas.updateAllFaces() + VanillaBlockDisplay.forceUpdateAll() + VanillaItemDisplay.forceUpdateAll() EVENTS.SELECT_VARIANT.publish(this) } + getDisplayEntityConfig( + element: OutlinerElement & { configs: IDisplayEntityConfigs } + ): IBlueprintDisplayEntityConfigJSON { + if (this.isDefault) { + return element.configs.default + } else { + return element.configs.variants[this.uuid] ?? element.configs.default + } + } + unselect() { Variant.selected = undefined } @@ -138,6 +154,7 @@ export class Variant { uuid: this.uuid, texture_map: Object.fromEntries(this.textureMap.map), excluded_nodes: this.excludedNodes.map(item => item.value), + on_apply_function: this.onApplyFunction, } if (this.isDefault) { json.is_default = true @@ -174,6 +191,7 @@ export class Variant { return group ? { name: group.name, value: uuid } : undefined }) .filter(Boolean) as CollectionItem[] + variant.onApplyFunction = json.on_apply_function return variant }