Go to file
2023-07-06 01:44:00 -04:00
gradle/wrapper update gradle wrapper 2023-06-15 01:26:08 -04:00
src/main We have quark posts at home 2023-07-06 01:44:00 -04:00
.gitattributes Initial commit 2019-06-18 02:33:36 -07:00
.gitignore Json model retexturing (kinda works) 2023-07-04 01:00:41 -04:00
build.gradle oh here we go 2023-06-15 02:06:21 -04:00
gradle.properties oh here we go 2023-06-15 02:06:21 -04:00
gradlew update gradle wrapper 2023-06-15 01:26:08 -04:00
gradlew.bat Initial commit 2019-06-18 02:33:36 -07:00
icon.png oh right icons are important 2019-06-19 16:04:38 -07:00
LICENSE Initial commit 2019-06-18 02:33:36 -07:00
README.md Texture rotation/uvlock 2023-07-05 23:05:31 -04:00

Templates

>> Downloads <<

Slopes?

This mod is open source and under a permissive license. As such, it can be included in any modpack on any platform without prior permission. We appreciate hearing about people using our mods, but you do not need to ask to use them. See the LICENSE file for more details.

Template blocks can be placed in the world, then right-clicked with a full-size block to set the textures for the template. Template blocks will inherit light and redstone values from the blocks they're given, or they can have light or redstone output added to any given block by right-clicking the template with glowstone dust or a redstone torch, respectively.

While Templates itself adds a handful of common shapes, it's also not too hard for other mods to interface with Templates and add their own templatable blocks.

quat was here

Todo move this into the main readme section

Todo

  • More templates !!

For addon developers

Creating your block

So there are various block interactions in Templates, like adding glowstone to make the block illuminate, adding redstone to make it a power source, etc. In an ideal world, I'd be able to simply provide the TemplateBlock class implementing all those features and ask that you extend it from your block. And if your block doesn't already have a superclass I recommend doing this - alas, if it does you can't extend TemplateBlock, so the implementation of everything has been farmed out to public static methods in TemplateInteractionUtil in the api package. Simply wire everything up. Don't forget to feed your Block.Settings through TemplateInteractionUtil.configureSettings too.

The only other requirement is that your block must have a block entity that both returns a BlockState object from RenderAttachmentBlockEntity.getRenderAttachmentData and implements ThemeableBlockEntity. TemplateEntity is an implementation of this (and also implements the other half of the features from TemplateInteractionUtil); I recommend using it if you can.

Creating the custom model

TL;DR: Look at assets/templates/blockstates, look at assets/templates/models/block, and look at the bottom of TemplatesClient.

Using a JSON model

We will construct a RetexturedJsonModelUnbakedModel. You need the ID of the json model to retexture.

The base model can have a parent of anything you want. To make a surface retexturable, give it the texture templates:templates_special/down, templates:templates_special/north, templates:templates_special/east (etc). These textures will be replaced at runtime by the corresponding region of the corresponding texture of the template's theme block. (For example, a surface textured using templates:templates_special/north will look like the north side of the template's theme.)

If possible, I don't recommend making a wholly new json model. If you have an existing model that defines north, south, east etc texture variables, just use this:

{
	"parent": "yourmod:your/cool/json/model",
	"textures": {
		"down": "templates:templates_special/down",
		"up": "templates:templates_special/up",
		"north": "templates:templates_special/north",
		"south": "templates:templates_special/south",
		"west": "templates:templates_special/west",
		"east": "templates:templates_special/east"
	}
}

(If your model has texture variables that look more like up/down/side instead of up/down/north/south/east/west, you can cheat and assign something like templates:templates_special/east to the side texture slot - but imagine a player retexturing your template to look like a sideways log, which is not rotationally symmetric. It won't work as expected.)

Finally, if your base model is a multipart model, and you plan on using it as an item model, I need a representative blockstate in order to select the correct configuration of the base model. Pick one and pass it as the second parameter to RetexturedJsonModelUnbakedModel. If the base model is not a multipart model, this is not required.

That's all you need to construct a RetexturedJsonModelUnbakedModel, so to finish things off, register it.

Using a custom Mesh-based model

If you have a shape in mind that can't be represented with a json model (like a perfect 45 degree wedge), this is a good option.

We will construct a RetexturedMeshUnbakedModel. You need two things - the ID of a parent model, and a Supplier<> of a Mesh to retexture.

Ideally, the parent model should have a parent of block/block, or at least define some non-default rotations (smokey the bear voice Only You Can Prevent Weirdly Rotated First-Person Models) and set "gui_light": "front" (lest the item model look weird). You should use a json model for this, but keep in mind that no quads will be read from the json model - it's only used to source all the miscellaneous BakedModel options.

When building the Mesh, if you want a face to be dynamically retextured, .tag() it with the .ordinal() + 1 of the Direction it corresponds to, and give the face UV coordinates ranging from 0 to 1. (For example, if you tag a face with 3 (Direction.NORTH.ordinal() + 1), it will be retextured to the north side of the template's theme.)

(TODO: implement a system for baking unchanging Sprites onto the mesh, potentially by "registering" more tags; the problem is you don't have access to sprite uvs at mesh building time. Or just provide a way to get sprite UVs at mesh building time...?)

That's all you need in order to construct a RetexturedMeshUnbakedModel, so to finish things off, register it.

Registering the custom model

  1. Decide on an ID for your special model that's different from the ID used for the base model.
    • If your base model lives at yourmod:block/awesome_template, something like yourmod:awesome_template_special would do.
  2. Register it using TemplatesClient.provider.addTemplateModel.
  3. Create a blockstate json for your block, and point it at the ID you decided for your special model in 1).
    • You may rotate the blockmodel with the x and y properties. You can also toggle uvlock. Things should work as expected.

You may create a regular item model, or use ours by calling TemplatesClient.provider.assignItemModel, passing the ID of the special model & the items you want to assign it to. (The reason you have to do this instead of simply creating a regular item model and setting its parent, is that JsonUnbakedModels can't have non-JsonUnbakedModels as their parent, and even a trivial item model with only the parent field set counts as a JsonUnbakedModel. This isn't a problem for block models because blockstates are a layer of indirection before model loading.)