Changes

281 bytes added ,  16:56, 17 November 2021
m
Add Groovy language code examples
Line 1: Line 1: −
Many blocks and items in vanilla change their texture color depending on where they are, such as grass. Models support specifying “tint indices” on faces, which are integers that can then be handled by <code>IBlockColor</code>s and <code>IItemColor</code>s. See the wiki for information on how tint indices are defined in vanilla models.
+
Many blocks and items in vanilla change their texture color depending on where they are, such as grass. Models support specifying “tint indices” on faces, which are integers that can then be handled by <code>BlockColor</code>s and <code>IItemColor</code>s. See the wiki for information on how tint indices are defined in vanilla models.
   −
=== IBlockColor / IItemColor ===
+
=== BlockColor / ItemColor ===
Both of these are single-method interfaces. <code>IBlockColor</code> takes an <code>IBlockState</code>, an (<code>nullable</code>) <code>IBlockDisplayReader</code>, and a (<code>nullable</code>) <code>BlockPos</code>. <code>IItemColor</code> takes an <code>ItemStack</code>. Both of them take a parameter <code>tintIndex</code>, which is the tint index of the face being colored. Both of them return an <code>int</code>, a color multiplier. This int is treated as four unsigned bytes, alpha, red, green, and blue, in that order, from most significant byte to least. For each pixel in the tinted face, the value of each color channel is <code><nowiki>(int)((float)base * multiplier / 255)</nowiki></code>, where <code>base</code> is the original value for the channel, and <code>multiplier</code> is the associated byte from the color multiplier. Note that blocks do not use the alpha channel. For example, the grass texture, untinted, looks white and gray. The <code>IBlockColor</code> and <code>IItemColor</code> for grass return color multipliers with low red and blue components, but high alpha and green components, (at least in warm biomes) so when the multiplication is performed, the green is brought out and the red/blue diminished.
+
Both of these are single-method interfaces. <code>BlockColor</code> takes a <code>BlockState</code>, a (<code>nullable</code>) <code>BlockAndTintGetter</code>, and a (<code>nullable</code>) <code>BlockPos</code>. <code>ItemColor</code> takes an <code>ItemStack</code>. Both of them take a parameter <code>tintIndex</code>, which is the tint index of the face being colored. Both of them return an <code>int</code>, a color multiplier. This int is treated as four unsigned bytes, alpha, red, green, and blue, in that order, from most significant byte to least. For each pixel in the tinted face, the value of each color channel is <code><nowiki>(int)((float)base * multiplier / 255)</nowiki></code>, where <code>base</code> is the original value for the channel, and <code>multiplier</code> is the associated byte from the color multiplier. Note that blocks do not use the alpha channel. For example, the grass texture, untinted, looks white and gray. The <code>BlockColor</code> and <code>ItemColor</code> for grass return color multipliers with low red and blue components, but high alpha and green components, (at least in warm biomes) so when the multiplication is performed, the green is brought out and the red/blue diminished.
    
If an item inherits from the <code><nowiki>builtin/generated</nowiki></code> model, each layer (“layer0”, “layer1”, etc.) has a tint index corresponding to its layer index. For blocks, the “particle” layer is index 0.
 
If an item inherits from the <code><nowiki>builtin/generated</nowiki></code> model, each layer (“layer0”, “layer1”, etc.) has a tint index corresponding to its layer index. For blocks, the “particle” layer is index 0.
    
=== Creating Color Handlers ===
 
=== Creating Color Handlers ===
<code>IBlockColor</code>s need to be registered to the <code>BlockColors</code> instance of the game. <code>BlockColors</code> can be acquired through <code>ColorHandlerEvent$Block</code>, and an <code>IBlockColor</code> can be registered by <code><nowiki>BlockColors#register</nowiki></code>. Note that this does not cause the <code>BlockItem</code> for the given block to be colored. <code>BlockItem</code> are items and need to colored with an <code>IItemColor</code>.
+
<code>BlockColor</code>s need to be registered to the <code>BlockColors</code> instance of the game. <code>BlockColors</code> can be acquired through <code>ColorHandlerEvent$Block</code>, and an <code>BlockColor</code> can be registered by <code><nowiki>BlockColors#register</nowiki></code>. Note that this does not cause the <code>BlockItem</code> for the given block to be colored. <code>BlockItem</code> are items and need to colored with an <code>ItemColor</code>.
<syntaxhighlight lang="java">
+
{{Template:Tabs/Code_Snippets
public void registerBlockColors(ColorHandlerEvent.Block event){
+
|java=public void registerBlockColors(final ColorHandlerEvent.Block event) {
     event.getBlockColors().register(myIBlockColor, coloredBlock1, coloredBlock2, ...);
+
     event.getBlockColors().register(myBlockColor, coloredBlock1, coloredBlock2, ...);
 
}
 
}
</syntaxhighlight>
+
|groovy=void registerBlockColors(final ColorHandlerEvent.Block event) {
<code>IItemColor</code>s need to be registered to the <code>ItemColors</code> instance of the game. <code>ItemColors</code> can be acquired through <code><nowiki>ColorHandlerEvent$Item()</nowiki></code>, and an <code>IItemColor</code> can be registered by <code><nowiki>ItemColors#register</nowiki></code>. This method is overloaded to also take <code>Block</code>s, which simply registers the color handler for the item <code><nowiki>Block#asItem</nowiki></code> (i.e. the block’s <code>BlockItem</code>).
+
     event.blockColors.register(myBlockColor, coloredBlock1, coloredBlock2, ...);
<syntaxhighlight lang="java">
  −
public void registerItemColors(ColorHandlerEvent.Item event){
  −
     event.getItemColors().register(myIItemColor, coloredItem1, coloredItem2, ...);
   
}
 
}
</syntaxhighlight>
+
|}}
 +
<code>ItemColor</code>s need to be registered to the <code>ItemColors</code> instance of the game. <code>ItemColors</code> can be acquired through <code><nowiki>ColorHandlerEvent$Item</nowiki></code>, and an <code>ItemColor</code> can be registered by <code><nowiki>ItemColors#register</nowiki></code>. This method is overloaded to also take <code>Block</code>s, which simply registers the color handler for the item <code><nowiki>Block#asItem</nowiki></code> (i.e. the block’s <code>BlockItem</code>).
 +
{{Template:Tabs/Code_Snippets
 +
|java=public void registerItemColors(final ColorHandlerEvent.Item event) {
 +
    event.getItemColors().register(myItemColor, coloredItem1, coloredItem2, ...);
 +
}
 +
|groovy=void registerBlockColors(final ColorHandlerEvent.Item event) {
 +
    event.itemColors.register(myItemColor, coloredItem1, coloredItem2, ...);
 +
}
 +
|}}
 
This registration must be done client-side, in the initialization phase.
 
This registration must be done client-side, in the initialization phase.