|
| 1 | + |
| 2 | +dir <%export_namespace%> { |
| 3 | + function invalid_version_warning { |
| 4 | + # This function will contain a tellraw if the datapack is loaded in the wrong version. |
| 5 | + } |
| 6 | + |
| 7 | + dir root { |
| 8 | + IF (show_outdated_warning) { |
| 9 | + function on_load { |
| 10 | + execute unless entity @s[tag=<%TAGS.PROJECT_ROOT(export_namespace)%>] run return 0 |
| 11 | + execute on passengers if entity @s[tag=<%TAGS.PROJECT_DATA(export_namespace)%>] \ |
| 12 | + unless data entity @s {data:{rigHash: '<%rigHash%>'}} on vehicle run { |
| 13 | + execute store result storage aj:temp x int 1 store result score #this.x aj.i run data get entity @s Pos[0] 1 |
| 14 | + execute store result storage aj:temp y int 1 store result score #this.y aj.i run data get entity @s Pos[1] 1 |
| 15 | + execute store result storage aj:temp z int 1 store result score #this.z aj.i run data get entity @s Pos[2] 1 |
| 16 | + block outdated_tellraw { with storage aj:temp |
| 17 | + $tellraw @a <%TELLRAW.RIG_OUTDATED()%> |
| 18 | + } |
| 19 | + data modify entity @s data.rigHash set value '<%rigHash%>' |
| 20 | + execute on passengers run data merge entity @s {Glowing: 1b, glow_color_override: <%0xff0000%>} |
| 21 | + summon minecraft:text_display ~ ~ ~ {Tags:['<%TAGS.GLOBAL_ENTITY()%>', '<%TAGS.OUTDATED_RIG_TEXT_DISPLAY()%>', '<%TAGS.NEW()%>'], text:'<%TELLRAW.RIG_OUTDATED_TEXT_DISPLAY()%>', billboard: "vertical", transformation:{translation:[0f,<%boundingBox[1]/16%>f,0f],left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],scale:[1f,1f,1f]}} |
| 22 | + ride @e[type=minecraft:text_display,tag=<%TAGS.NEW()%>,limit=1,distance=..0.01] mount @s |
| 23 | + tag @e[type=minecraft:text_display,tag=<%TAGS.NEW()%>,limit=1,distance=..0.01] remove <%TAGS.NEW()%> |
| 24 | + } |
| 25 | + scoreboard players set @s <%OBJECTIVES.IS_RIG_LOADED()%> 1 |
| 26 | + } |
| 27 | + } |
| 28 | + function on_tick { |
| 29 | + execute unless entity @s[tag=<%TAGS.PROJECT_ROOT(export_namespace)%>] run return 0 |
| 30 | + IF (show_outdated_warning) { |
| 31 | + execute unless score @s <%OBJECTIVES.IS_RIG_LOADED()%> matches 1 run function #*global/root/on_load |
| 32 | + } |
| 33 | + # Pre tick |
| 34 | + function #*<%export_namespace%>/as_root/pre_tick |
| 35 | + IF (has_locators || has_cameras) { |
| 36 | + execute on passengers if entity @s[tag=<%TAGS.PROJECT_DATA(export_namespace)%>] run { |
| 37 | + REPEAT (Object.values(rig.nodes).filter(v => v.type === 'locator')) as node { |
| 38 | + IF (node.config?.use_entity) { |
| 39 | + block { with entity @s data.locators.<%node.storage_name%> |
| 40 | + $execute as $(uuid) positioned ^$(posx) ^$(posy) ^$(posz) rotated ~$(roty) ~$(rotx) run { |
| 41 | + tp @s ~ ~ ~ ~ ~ |
| 42 | + <%% |
| 43 | + if (node.config?.ticking_commands) { |
| 44 | + emit.mcb(node.config.ticking_commands) |
| 45 | + } |
| 46 | + %%> |
| 47 | + } |
| 48 | + } |
| 49 | + } ELSE IF (node.config?.ticking_commands) { |
| 50 | + block { with entity @s data.locators.<%node.storage_name%> |
| 51 | + $execute positioned ^$(posx) ^$(posy) ^$(posz) rotated ~$(roty) ~$(rotx) run { |
| 52 | + <%% |
| 53 | + if (node.config?.ticking_commands) { |
| 54 | + emit.mcb(node.config.ticking_commands) |
| 55 | + } |
| 56 | + %%> |
| 57 | + } |
| 58 | + } |
| 59 | + } |
| 60 | + } |
| 61 | + REPEAT (Object.values(rig.nodes).filter(v => v.type === 'camera')) as node { |
| 62 | + block { with entity @s data.cameras.<%node.storage_name%> |
| 63 | + $execute as $(uuid) positioned ^$(posx) ^$(posy) ^$(posz) rotated ~$(roty) ~$(rotx) run tp @s ~ ~ ~ ~ ~ |
| 64 | + } |
| 65 | + } |
| 66 | + } |
| 67 | + } |
| 68 | + # Rotation Logic |
| 69 | + execute at @s on passengers run rotate @s ~ ~ |
| 70 | + IF (root_ticking_commands) { |
| 71 | + <%% |
| 72 | + emit.mcb(root_ticking_commands) |
| 73 | + %%> |
| 74 | + } |
| 75 | + # Post tick |
| 76 | + function #*<%export_namespace%>/as_root/post_tick |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | + # FIXME - Maybe remove these in favor of the new options-based system? |
| 81 | + # Function Tag Hooks |
| 82 | + dir as_root { |
| 83 | + # All child functions of this folder run as the root entity |
| 84 | + # Runs before the rig is ticked. |
| 85 | + tag functions pre_tick { |
| 86 | + } |
| 87 | + # Runs after the rig is ticked. |
| 88 | + tag functions post_tick { |
| 89 | + } |
| 90 | + # Runs when the rig is summoned. |
| 91 | + tag functions on_summon { |
| 92 | + } |
| 93 | + # Runs when the rig is removed. |
| 94 | + tag functions on_remove { |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + function summon { |
| 99 | + #Args: {args:{variant: string}} |
| 100 | + |
| 101 | + data modify storage aj:temp args set value {variant:''} |
| 102 | + $execute store success score #success <%OBJECTIVES.I()%> run data modify storage aj:temp args set value $(args) |
| 103 | + |
| 104 | + summon minecraft:item_display ~ ~ ~ { \ |
| 105 | + Tags:[ \ |
| 106 | + '<%TAGS.NEW()%>', \ |
| 107 | + '<%TAGS.GLOBAL_ENTITY()%>', \ |
| 108 | + '<%TAGS.GLOBAL_ROOT()%>', \ |
| 109 | + '<%TAGS.PROJECT_ENTITY(export_namespace)%>', \ |
| 110 | + '<%TAGS.PROJECT_ROOT(export_namespace)%>' \ |
| 111 | + ], \ |
| 112 | + teleport_duration: 0, \ |
| 113 | + interpolation_duration: <%interpolation_duration%>, \ |
| 114 | + Passengers:<%root_entity_passengers%>, \ |
| 115 | + } |
| 116 | + execute as @e[type=item_display,tag=<%TAGS.NEW()%>,limit=1,distance=..0.01] run { |
| 117 | + execute store result score @s <%OBJECTIVES.ID()%> run scoreboard players add aj.last_id <%OBJECTIVES.ID()%> 1 |
| 118 | + |
| 119 | + execute on passengers if entity @s[tag=<%TAGS.GLOBAL_DATA()%>] run { |
| 120 | + function *global/internal/gu/convert_uuid_array_to_string with entity @s |
| 121 | + data modify entity @s data.bones.data_data set from storage aj:uuid main.out |
| 122 | + |
| 123 | + REPEAT (Object.values(rig.nodes).filter(v => v.type === 'locator' && v.config?.use_entity)) as locator { |
| 124 | + summon <%locator.config.entity_type%> \ |
| 125 | + ^<%locator.default_transform.pos[0]%> \ |
| 126 | + ^<%locator.default_transform.pos[1]%> \ |
| 127 | + ^<%locator.default_transform.pos[2]%> \ |
| 128 | + {Tags:<%getNodeTags(locator, rig)%>} |
| 129 | + execute as @e[type=<%locator.config.entity_type%>,tag=<%TAGS.NEW()%>,tag=<%TAGS.GLOBAL_LOCATOR()%>,limit=1,distance=..0.01] run { |
| 130 | + tag @s remove <%TAGS.NEW()%> |
| 131 | + |
| 132 | + function *global/internal/gu/convert_uuid_array_to_string with entity @s |
| 133 | + tp @s \ |
| 134 | + ^<%roundTo(locator.default_transform.pos[0], 10)%> \ |
| 135 | + ^<%roundTo(locator.default_transform.pos[1], 10)%> \ |
| 136 | + ^<%roundTo(locator.default_transform.pos[2], 10)%> \ |
| 137 | + ~<%roundTo(locator.default_transform.head_rot[1], 10)%> \ |
| 138 | + ~<%roundTo(locator.default_transform.head_rot[0], 10)%> |
| 139 | + <%% |
| 140 | + if (locator.config.summon_commands) { |
| 141 | + emit.mcb(locator.config.summon_commands) |
| 142 | + } |
| 143 | + %%> |
| 144 | + } |
| 145 | + data modify entity @s data.locators.<%locator.name%>.uuid set from storage aj:uuid main.out |
| 146 | + } |
| 147 | + |
| 148 | + REPEAT (Object.values(rig.nodes).filter(v => v.type === 'camera')) as camera { |
| 149 | + summon item_display \ |
| 150 | + ^<%camera.default_transform.pos[0]%> \ |
| 151 | + ^<%camera.default_transform.pos[1]%> \ |
| 152 | + ^<%camera.default_transform.pos[2]%> \ |
| 153 | + {Tags:<%getNodeTags(camera, rig)%>, teleport_duration: 2} |
| 154 | + execute as @e[type=item_display,tag=<%TAGS.NEW()%>,tag=<%TAGS.GLOBAL_CAMERA()%>,limit=1,distance=..0.01] run { |
| 155 | + tag @s remove <%TAGS.NEW()%> |
| 156 | + function *global/internal/gu/convert_uuid_array_to_string with entity @s |
| 157 | + tp @s \ |
| 158 | + ^<%roundTo(camera.default_transform.pos[0], 10)%> \ |
| 159 | + ^<%roundTo(camera.default_transform.pos[1], 10)%> \ |
| 160 | + ^<%roundTo(camera.default_transform.pos[2], 10)%> \ |
| 161 | + ~<%roundTo(camera.default_transform.head_rot[1], 10)%> \ |
| 162 | + ~<%roundTo(camera.default_transform.head_rot[0], 10)%> |
| 163 | + } |
| 164 | + data modify entity @s data.cameras.<%camera.name%>.uuid set from storage aj:uuid main.out |
| 165 | + } |
| 166 | + |
| 167 | + REPEAT (Object.values(rig.nodes).filter(v => ['bone', 'text_display', 'item_display', 'block_display'].includes(v.type))) as node { |
| 168 | + execute on vehicle on passengers if entity @s[tag=<%TAGS.PROJECT_NODE_NAMED(export_namespace, node.name)%>] run \ |
| 169 | + function *global/internal/gu/convert_uuid_array_to_string with entity @s |
| 170 | + data modify entity @s data.bones.<%node.type + '_' + node.name%> set from storage aj:uuid main.out |
| 171 | + } |
| 172 | + } |
| 173 | + |
| 174 | + # Variant Arguement |
| 175 | + IF (Object.keys(rig.variants).length > 1) { |
| 176 | + execute if data storage aj:temp args.variant run { with storage aj:temp args |
| 177 | + execute if data storage aj:temp {args:{variant:''}} run return run { |
| 178 | + tellraw @a <%TELLRAW.VARIANT_CANNOT_BE_EMPTY()%> |
| 179 | + function *<%export_namespace%>/remove/this |
| 180 | + } |
| 181 | + # Attempt to apply the variant, if it fails, print an error. |
| 182 | + execute store success score #success <%OBJECTIVES.I()%> run { with storage aj:temp args |
| 183 | + $execute store success score #success <%OBJECTIVES.I()%> run function *<%export_namespace%>/variants/$(variant)/apply |
| 184 | + execute if score #success <%OBJECTIVES.I()%> matches 1 run return 1 |
| 185 | + return fail |
| 186 | + } |
| 187 | + execute unless score #success <%OBJECTIVES.I()%> matches 1 run return run { with storage aj:temp args |
| 188 | + $tellraw @a <%TELLRAW.INVALID_VARIANT('$(variant)', rig.variants)%> |
| 189 | + function *<%export_namespace%>/remove/this |
| 190 | + } |
| 191 | + } |
| 192 | + } ELSE { |
| 193 | + execute if data storage aj:temp args.variant run { |
| 194 | + tellraw @a <%TELLRAW.NO_VARIANTS()%> |
| 195 | + function *<%export_namespace%>/remove/this |
| 196 | + } |
| 197 | + } |
| 198 | + |
| 199 | + function *<%export_namespace%>/set_default_pose |
| 200 | + |
| 201 | + tp @s ~ ~ ~ ~ ~ |
| 202 | + execute at @s on passengers run rotate @s ~ ~ |
| 203 | + data modify entity @s teleport_duration set value <%teleportation_duration%> |
| 204 | + execute on passengers run data modify entity @s teleport_duration set value <%teleportation_duration%> |
| 205 | + # Custom Summon Commands |
| 206 | + <%% |
| 207 | + if (custom_summon_commands) emit.mcb(custom_summon_commands) |
| 208 | + %%> |
| 209 | + # Custom Summon Commands |
| 210 | + |
| 211 | + tag @s remove <%TAGS.NEW()%> |
| 212 | + execute on passengers run tag @s remove <%TAGS.NEW()%> |
| 213 | + |
| 214 | + # Run the on_summon function for the root entity. |
| 215 | + function #*<%export_namespace%>/as_root/on_summon |
| 216 | + } |
| 217 | + } |
| 218 | + |
| 219 | + IF (has_entity_locators) { |
| 220 | + function as_own_locator_entities { |
| 221 | + #ARGS: {command: string} |
| 222 | + IF (show_function_errors) { |
| 223 | + execute unless entity @s[type=item_display,tag=<%TAGS.PROJECT_ROOT(export_namespace)%>] run return run \ |
| 224 | + function *global/errors/function_not_executed_as_root_entity \ |
| 225 | + {'export_namespace': '<%export_namespace%>', 'function_path': 'animated_java:<%export_namespace%>/as_all_locators'} |
| 226 | + } |
| 227 | + $data modify storage aj:temp command set value '$(command)' |
| 228 | + execute on passengers if entity @s[tag=<%TAGS.GLOBAL_DATA()%>] run { |
| 229 | + REPEAT (Object.values(rig.nodes).filter(v => v.type === 'locator' && v.config?.use_entity)) as locator { |
| 230 | + data modify storage aj:temp uuid set from entity @s data.locators.<%locator.name%>.uuid |
| 231 | + block zzz/execute { with storage aj:temp |
| 232 | + $execute as $(uuid) run $(command) |
| 233 | + } |
| 234 | + } |
| 235 | + } |
| 236 | + } |
| 237 | + } |
| 238 | + |
| 239 | + dir remove { |
| 240 | + function all { |
| 241 | + # Removes all instances of this rig from the world. |
| 242 | + execute as @e[type=item_display,tag=<%TAGS.PROJECT_ROOT(export_namespace)%>] run function *<%export_namespace%>/remove/this |
| 243 | + } |
| 244 | + |
| 245 | + function entities { |
| 246 | + # Removes all entities related to this rig from the world. |
| 247 | + kill @e[tag=<%TAGS.PROJECT_ENTITY(export_namespace)%>] |
| 248 | + } |
| 249 | + |
| 250 | + function this { |
| 251 | + # Removes the rig this function is executed as. |
| 252 | + IF (show_function_errors) { |
| 253 | + execute unless entity @s[type=item_display,tag=<%TAGS.PROJECT_ROOT(export_namespace)%>] run return run \ |
| 254 | + function *global/errors/function_not_executed_as_root_entity \ |
| 255 | + {'export_namespace': '<%export_namespace%>', 'function_path': 'animated_java:<%export_namespace%>/remove/this'} |
| 256 | + } |
| 257 | + |
| 258 | + # On Remove Event |
| 259 | + function #*<%export_namespace%>/as_root/on_remove |
| 260 | + |
| 261 | + IF (has_entity_locators || has_cameras) { |
| 262 | + execute on passengers if entity @s[tag=<%TAGS.GLOBAL_DATA()%>] run { |
| 263 | + REPEAT (Object.values(rig.nodes).filter(v => v.type === 'locator' && v.config?.use_entity)) as locator { |
| 264 | + block zzz/kill { with entity @s data.locators.<%locator.name%> |
| 265 | + # Recursively remove any stacked locator entities |
| 266 | + $execute as $(uuid) run block kill_passengers { |
| 267 | + execute on passengers run function ^0 |
| 268 | + kill @s |
| 269 | + } |
| 270 | + } |
| 271 | + } |
| 272 | + REPEAT (Object.values(rig.nodes).filter(v => v.type === 'camera')) as camera { |
| 273 | + block zzz/kill { with entity @s data.cameras.<%camera.name%> |
| 274 | + $execute as $(uuid) run kill @s |
| 275 | + } |
| 276 | + } |
| 277 | + } |
| 278 | + } |
| 279 | + |
| 280 | + execute on passengers run kill @s |
| 281 | + kill @s |
| 282 | + } |
| 283 | + } |
| 284 | + |
| 285 | + IF (Object.keys(rig.variants).length > 1) { |
| 286 | + dir variants { |
| 287 | + REPEAT (Object.values(rig.variants)) as variant { |
| 288 | + dir <%variant.name%> { |
| 289 | + function apply { |
| 290 | + IF (show_function_errors) { |
| 291 | + execute unless entity @s[type=item_display,tag=<%TAGS.PROJECT_ROOT(export_namespace)%>] run return run \ |
| 292 | + function *global/errors/function_not_executed_as_root_entity \ |
| 293 | + {'export_namespace': '<%export_namespace%>', 'function_path': 'animated_java:<%export_namespace%>/variants/<%variant.name%>/apply'} |
| 294 | + } |
| 295 | + REPEAT (Object.values(rig.nodes)) as node { |
| 296 | + IF (node.type === 'bone' && !variant.excluded_nodes.includes(node.uuid) && (variant.models[node.uuid] !== undefined || node.configs.variants[variant.uuid] !== undefined)) { |
| 297 | + execute on passengers if entity @s[tag=aj.<%export_namespace%>.bone.<%node.path_name%>] run { |
| 298 | + IF (variant.models[node.uuid] !== undefined) { |
| 299 | + data modify entity @s item.components.minecraft:custom_model_data.strings[0] set value "<%variant.name%>" |
| 300 | + } |
| 301 | + IF (node.configs.variants[variant.uuid]) { |
| 302 | + <%% |
| 303 | + global.config = BoneConfig.fromJSON(node.configs.variants[variant.uuid]) |
| 304 | + %%> |
| 305 | + IF (!global.config.isDefault()) { |
| 306 | + data merge entity @s <%global.config.toNBT(undefined, variant.is_default)%> |
| 307 | + } |
| 308 | + } |
| 309 | + } |
| 310 | + } |
| 311 | + } |
| 312 | + } |
| 313 | + } |
| 314 | + } |
| 315 | + } |
| 316 | + } |
| 317 | + |
| 318 | + function set_default_pose { |
| 319 | + # Changes the pose of the rig to the the default pose without interpolation |
| 320 | + execute unless entity @s[type=item_display,tag=<%TAGS.PROJECT_ROOT(export_namespace)%>] run return run \ |
| 321 | + function *global/errors/function_not_executed_as_root_entity \ |
| 322 | + {'export_namespace': '<%export_namespace%>', 'function_path': 'animated_java:<%export_namespace%>/set_default_pose'} |
| 323 | + REPEAT (Object.values(rig.nodes)) as node { |
| 324 | + IF (['bone', 'text_display', 'item_display', 'block_display'].includes(node.type)) { |
| 325 | + execute on passengers if entity @s[tag=aj.<%export_namespace%>.bone.<%node.path_name%>] run \ |
| 326 | + data merge entity @s {transformation: <%matrixToNbtFloatArray(node.default_transform.matrix).toString()%>, start_interpolation: -1} |
| 327 | + } |
| 328 | + } |
| 329 | + } |
| 330 | +} |
0 commit comments