|
| 1 | +########################### |
| 2 | +# This file is part of dModels / Denizen Models. |
| 3 | +# Refer to the header of "dmodels_main.dsc" for more information. |
| 4 | +########################### |
| 5 | + |
| 6 | + |
| 7 | +dmodels_load_bbmodel: |
| 8 | + type: task |
| 9 | + debug: false |
| 10 | + definitions: model_name |
| 11 | + script: |
| 12 | + # =============== Prep =============== |
| 13 | + - define pack_root data/dmodels/res_pack |
| 14 | + - define models_root <[pack_root]>/assets/minecraft/models/item/dmodels/<[model_name]> |
| 15 | + - define textures_root <[pack_root]>/assets/minecraft/textures/dmodels/<[model_name]> |
| 16 | + - define override_item_filepath <[pack_root]>/assets/minecraft/models/item/<script[dmodels_config].data_key[item]>.json |
| 17 | + - define file data/dmodels/<[model_name]>.bbmodel |
| 18 | + - define scale_factor <element[2.285].div[4]> |
| 19 | + - define mc_texture_data <map> |
| 20 | + - flag server dmodels_data.temp_<[model_name]>:! |
| 21 | + # =============== BBModel loading and validation =============== |
| 22 | + - if !<server.has_file[<[file]>]>: |
| 23 | + - debug error "Cannot load model '<[model_name]>' because file '<[file]>' does not exist." |
| 24 | + - stop |
| 25 | + - ~fileread path:<[file]> save:filedata |
| 26 | + - define data <util.parse_yaml[<entry[filedata].data.utf8_decode||>]||> |
| 27 | + - if !<[data].is_truthy>: |
| 28 | + - debug error "Something went wrong trying to load BBModel data for model '<[model_name]>' - fileread invalid." |
| 29 | + - stop |
| 30 | + - define meta <[data.meta]||> |
| 31 | + - define resolution <[data.resolution]||> |
| 32 | + - if !<[meta].is_truthy> || !<[resolution].is_truthy>: |
| 33 | + - debug error "Something went wrong trying to load BBModel data for model '<[model_name]>' - possibly not a valid BBModel file?" |
| 34 | + - stop |
| 35 | + - if !<[data.elements].exists>: |
| 36 | + - debug error "Can't load bbmodel for '<[model_name]>' - file has no elements?" |
| 37 | + - stop |
| 38 | + # =============== Pack validation =============== |
| 39 | + - if !<server.has_flag[data/dmodels/res_pack/pack.mcmeta]>: |
| 40 | + - filewrite path:data/dmodels/res_pack/pack.mcmeta data:<map.with[pack].as[<map[pack_format=8;description=dModels_AutoPack_Default]>].to_json[native_types=true;indent=4].utf8_encode> |
| 41 | + # =============== Textures loading =============== |
| 42 | + - define tex_id 0 |
| 43 | + - foreach <[data.textures]||<list>> as:texture: |
| 44 | + - define texname <[texture.name]> |
| 45 | + - if <[texname].ends_with[.png]>: |
| 46 | + - define texname <[texname].before[.png]> |
| 47 | + - define raw_source <[texture.source]||> |
| 48 | + - if !<[raw_source].starts_with[data:image/png;base64,]>: |
| 49 | + - debug error "Can't load bbmodel for '<[model_name]>': invalid texture source data." |
| 50 | + - stop |
| 51 | + - define texture_output_path <[textures_root]>/<[texname]>.png |
| 52 | + - ~filewrite path:<[texture_output_path]> data:<[raw_source].after[,].base64_to_binary> |
| 53 | + - define proper_path dmodels/<[model_name]>/<[texname]> |
| 54 | + - define mc_texture_data.<[tex_id]> <[proper_path]> |
| 55 | + - if <[texture.particle]||false>: |
| 56 | + - define mc_texture_data.particle <[proper_path]> |
| 57 | + - define tex_id:++ |
| 58 | + # =============== Elements loading =============== |
| 59 | + - foreach <[data.elements]> as:element: |
| 60 | + - if <[element.type]> != cube: |
| 61 | + - foreach next |
| 62 | + - define element.origin <[element.origin].separated_by[,]||0,0,0> |
| 63 | + - define element.rotation <[element.rotation].separated_by[,]||0,0,0> |
| 64 | + - define flagname dmodels_data.model_<[model_name]>.namecounter_element.<[element.name]> |
| 65 | + - flag server <[flagname]>:++ |
| 66 | + - if <server.flag[<[flagname]>]> > 1: |
| 67 | + - define element.name <[element.name]><server.flag[<[flagname]>]> |
| 68 | + - flag server dmodels_data.temp_<[model_name]>.raw_elements.<[element.uuid]>:<[element]> |
| 69 | + # =============== Outlines loading =============== |
| 70 | + - define root_outline null |
| 71 | + - foreach <[data.outliner]||<list>> as:outliner: |
| 72 | + - if <[outliner].matches_character_set[abcdef0123456789-]>: |
| 73 | + - if <[root_outline]> == null: |
| 74 | + - definemap root_outline name:__root__ origin:0,0,0 rotation:0,0,0 uuid:<util.random_uuid> |
| 75 | + - flag server dmodels_data.temp_<[model_name]>.raw_outlines.<[root_outline.uuid]>:<[root_outline]> |
| 76 | + - run dmodels_loader_addchild def.model_name:<[model_name]> def.parent:<[root_outline]> def.child:<[outliner]> |
| 77 | + - else: |
| 78 | + - define outliner.parent:none |
| 79 | + - run dmodels_loader_readoutline def.model_name:<[model_name]> def.outline:<[outliner]> |
| 80 | + # =============== Clear out pre-existing data =============== |
| 81 | + - flag server dmodels_data.model_<[model_name]>:! |
| 82 | + - flag server dmodels_data.animations_<[model_name]>:! |
| 83 | + # =============== Animations loading =============== |
| 84 | + - foreach <[data.animations]||<list>> as:animation: |
| 85 | + - narrate "TODO: Animation stuff <[animation.name]>" |
| 86 | + # TODO: Animation loading stuff |
| 87 | + # =============== Item model file generation =============== |
| 88 | + - if <server.has_flag[<[override_item_filepath]>]>: |
| 89 | + - ~fileread path:<[override_item_filepath]> save:override_item |
| 90 | + - define override_item_data <util.parse_yaml[<entry[override_item].utf8_decode>]> |
| 91 | + - else: |
| 92 | + - definemap override_item_data parent:minecraft:item/generated textures:<map[layer0=minecraft:item/leather_horse_armor]> |
| 93 | + - define overrides_changed false |
| 94 | + - foreach <server.flag[dmodels_data.temp_<[model_name]>.raw_outlines]> as:outline: |
| 95 | + - define outline_origin <location[<[outline.origin]>]> |
| 96 | + - define model_json.textures <[mc_texture_data]> |
| 97 | + - define model_json.elements <list> |
| 98 | + - define child_count 0 |
| 99 | + #### Element building |
| 100 | + - foreach <server.flag[dmodels_data.temp_<[model_name]>.raw_elements]> as:element: |
| 101 | + - if <[outline.children].contains[<[element.uuid]>]||false>: |
| 102 | + - define child_count:++ |
| 103 | + - define jsonelement.name <[element.name]> |
| 104 | + - define rot <location[<[element.rotation]>]> |
| 105 | + - define jsonelement.from <location[<[element.from].separated_by[,]>].sub[<[outline_origin]>].mul[<[scale_factor]>].xyz.split[,]> |
| 106 | + - define jsonelement.to <location[<[element.to].separated_by[,]>].sub[<[outline_origin]>].mul[<[scale_factor]>].xyz.split[,]> |
| 107 | + - define jsonelement.rotation.origin <location[<[element.origin]>].sub[<[outline_origin]>].mul[<[scale_factor]>].xyz.split[,]> |
| 108 | + - if <[rot].x> != 0: |
| 109 | + - define jsonelement.rotation.axis x |
| 110 | + - define jsonelement.rotation.angle <[rot].x> |
| 111 | + - else if <[rot].z> != 0: |
| 112 | + - define jsonelement.rotation.axis z |
| 113 | + - define jsonelement.rotation.angle <[rot].z> |
| 114 | + - else: |
| 115 | + - define jsonelement.rotation.axis y |
| 116 | + - define jsonelement.rotation.angle <[rot].y> |
| 117 | + - foreach <[element.faces]> key:faceid as:face: |
| 118 | + - define jsonelement.faces.<[faceid]> <[face].proc[dmodels_facefix].context[<[resolution]>]> |
| 119 | + - define model_json.elements:->:<[jsonelement]> |
| 120 | + - define outline.children:! |
| 121 | + - if <[child_count]> > 0: |
| 122 | + #### Item override building |
| 123 | + - definemap json_group name:<[outline.name]> color:0 children:<util.list_numbers[from=0;to=<[child_count]>]> origin:<[outline_origin].mul[<[scale_factor]>].xyz.split[,]> |
| 124 | + - define model_json.groups <list[<[json_group]>]> |
| 125 | + - define model_json.display.head.translation <list[32|25|32]> |
| 126 | + - define model_json.display.head.scale <list[4|4|4]> |
| 127 | + - define modelpath item/dmodels/<[model_name]>/<[outline.name]> |
| 128 | + - ~filewrite path:<[models_root]>/<[outline.name]>.json data:<[model_json].to_json[native_types=true;indent=4].utf8_encode> |
| 129 | + - define cmd 0 |
| 130 | + - define min_cmd 1000 |
| 131 | + - foreach <[override_item_data.overrides]||<list>> as:override: |
| 132 | + - if <[override.model]> == <[modelpath]>: |
| 133 | + - define cmd <[override.predicate.custom_model_data]> |
| 134 | + - define min_cmd <[min_cmd].max[<[override.predicate.custom_model_data].add[1]||1000>]> |
| 135 | + - if <[cmd]> == 0: |
| 136 | + - define cmd <[min_cmd]> |
| 137 | + - define override_item_data.overrides:->:<map[predicate=<map[custom_model_data=<[cmd]>]>].with[model].as[<[modelpath]>]> |
| 138 | + - define overrides_changed true |
| 139 | + - define outline.item <script[dmodels_config].data_key[item]>[custom_model_data=<[cmd]>] |
| 140 | + # This sets the actual live usage flag data |
| 141 | + - flag server dmodels_data.model_<[model_name]>.<[outline.uuid]>:<[outline]> |
| 142 | + - if <[overrides_changed]>: |
| 143 | + - ~filewrite path:<[override_item_filepath]> data:<[override_item_data].to_json[native_types=true;indent=4].utf8_encode> |
| 144 | + # Final clear of temp data |
| 145 | + - flag server dmodels_data.temp_<[model_name]>:! |
| 146 | + |
| 147 | +dmodels_facefix: |
| 148 | + type: procedure |
| 149 | + debug: false |
| 150 | + definitions: facedata|resolution |
| 151 | + script: |
| 152 | + - define uv <[facedata.uv]> |
| 153 | + - define out.texture #<[facedata.texture]> |
| 154 | + - define mul_x <element[16].div[<[resolution.width]>]> |
| 155 | + - define mul_y <element[16].div[<[resolution.height]>]> |
| 156 | + - define out.uv <list[<[uv].get[1].mul[<[mul_x]>]>|<[uv].get[2].mul[<[mul_y]>]>|<[uv].get[3].mul[<[mul_x]>]>|<[uv].get[4].mul[<[mul_y]>]>]> |
| 157 | + - determine <[out]> |
| 158 | + |
| 159 | +dmodels_loader_addchild: |
| 160 | + type: task |
| 161 | + debug: false |
| 162 | + definitions: model_name|parent|child |
| 163 | + script: |
| 164 | + - if <[child].matches_character_set[abcdef0123456789-]>: |
| 165 | + - define elementflag dmodels_data.temp_<[model_name]>.raw_elements.<[child]> |
| 166 | + - define element <server.flag[<[elementflag]>]||null> |
| 167 | + - if <[element]> == null: |
| 168 | + - stop |
| 169 | + - define valid_rots 0|22.5|45|-22.5|-45 |
| 170 | + - define rot <location[<[element.rotation]>]> |
| 171 | + - define xz <[rot].x.equals[0].if_true[0].if_false[1]> |
| 172 | + - define yz <[rot].y.equals[0].if_true[0].if_false[1]> |
| 173 | + - define zz <[rot].z.equals[0].if_true[0].if_false[1]> |
| 174 | + - define count <[xz].add[<[yz]>].add[<[zz]>]> |
| 175 | + - if <[rot].x> in <[valid_rots]> && <[rot].y> in <[valid_rots]> && <[rot].z> in <[valid_rots]> && <[count]> < 2: |
| 176 | + - flag server dmodels_data.temp_<[model_name]>.raw_outlines.<[parent.uuid]>.children:->:<[child]> |
| 177 | + - else: |
| 178 | + - definemap new_outline name:<[parent.name]>_auto_<[element.name]> origin:<[element.origin]> rotation:<[element.rotation]> uuid:<util.random_uuid> parent:<[parent.uuid]> children:<list[<[child]>]> |
| 179 | + - flag server dmodels_data.temp_<[model_name]>.raw_outlines.<[new_outline.uuid]>:<[new_outline]> |
| 180 | + - flag server <[elementflag]>.rotation:0,0,0 |
| 181 | + - flag server <[elementflag]>.origin:0,0,0 |
| 182 | + - else: |
| 183 | + - define child.parent:<[parent.uuid]> |
| 184 | + - run dmodels_loader_readoutline def.model_name:<[model_name]> def.outline:<[child]> |
| 185 | + |
| 186 | +dmodels_loader_readoutline: |
| 187 | + type: task |
| 188 | + debug: false |
| 189 | + definitions: model_name|outline |
| 190 | + script: |
| 191 | + - definemap new_outline name:<[outline.name]> uuid:<[outline.uuid]> origin:<[outline.origin].separated_by[,]||0,0,0> rotation:<[outline.rotation].separated_by[,]||0,0,0> parent:<[outline.parent]||none> |
| 192 | + - define flagname dmodels_data.model_<[model_name]>.namecounter_outline.<[outline.name]> |
| 193 | + - flag server <[flagname]>:++ |
| 194 | + - if <server.flag[<[flagname]>]> > 1: |
| 195 | + - define new_outline.name <[new_outline.name]><server.flag[<[flagname]>]> |
| 196 | + - define raw_children <[outline.children]||<list>> |
| 197 | + - define outline.children:! |
| 198 | + - flag server dmodels_data.temp_<[model_name]>.raw_outlines.<[new_outline.uuid]>:<[new_outline]> |
| 199 | + - foreach <[raw_children]> as:child: |
| 200 | + - run dmodels_loader_addchild def.model_name:<[model_name]> def.parent:<[outline]> def.child:<[child]> |
0 commit comments