Add support for FluidStack-dependant colouring to Forge bucket (#4952)

This commit is contained in:
Ben Staddon 2018-07-14 22:52:54 +01:00 committed by LexManos
parent cfebf27393
commit 6ae2287d57
7 changed files with 172 additions and 32 deletions

View File

@ -0,0 +1,39 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client;
import net.minecraft.client.renderer.color.IItemColor;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import javax.annotation.Nonnull;
public class FluidContainerColorer implements IItemColor
{
@Override
public int colorMultiplier(@Nonnull ItemStack stack, int tintIndex)
{
if (tintIndex != 1) return 0xFFFFFFFF;
FluidStack fluidStack = FluidUtil.getFluidContained(stack);
if (fluidStack == null) return 0xFFFFFFFF;
return fluidStack.getFluid().getColor(fluidStack);
}
}

View File

@ -0,0 +1,49 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client;
import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class ForgeClientHandler
{
@SubscribeEvent
public static void registerModels(ModelRegistryEvent event)
{
// register model for the universal bucket, if it exists
if (FluidRegistry.isUniversalBucketEnabled())
{
ModelLoader.setBucketModelDefinition(ForgeModContainer.getInstance().universalBucket);
}
}
@SubscribeEvent
public static void registerItemHandlers(ColorHandlerEvent.Item event)
{
if (FluidRegistry.isUniversalBucketEnabled())
{
event.getItemColors().registerItemColorHandler(new FluidContainerColorer(), ForgeModContainer.getInstance().universalBucket);
}
}
}

View File

@ -38,6 +38,13 @@ public final class ItemTextureQuadConverter
// non-instantiable
}
/** @deprecated use {@link #convertTexture(VertexFormat, TRSRTransformation, TextureAtlasSprite, TextureAtlasSprite, float, EnumFacing, int, int)}*/
@Deprecated // TODO: remove
public static List<UnpackedBakedQuad> convertTexture(VertexFormat format, TRSRTransformation transform, TextureAtlasSprite template, TextureAtlasSprite sprite, float z, EnumFacing facing, int color)
{
return convertTexture(format, transform, template, sprite, z, facing, color, -1);
}
/**
* Takes a texture and converts it into BakedQuads.
* The conversion is done by scanning the texture horizontally and vertically and creating "strips" of the texture.
@ -48,21 +55,29 @@ public final class ItemTextureQuadConverter
*
* @param format
* @param template The input texture to convert
* @param sprite The texture whose UVs shall be used @return The generated quads.
* @param sprite The texture whose UVs shall be used
* @return The generated quads.
*/
public static List<UnpackedBakedQuad> convertTexture(VertexFormat format, TRSRTransformation transform, TextureAtlasSprite template, TextureAtlasSprite sprite, float z, EnumFacing facing, int color)
public static List<UnpackedBakedQuad> convertTexture(VertexFormat format, TRSRTransformation transform, TextureAtlasSprite template, TextureAtlasSprite sprite, float z, EnumFacing facing, int color, int tint)
{
List<UnpackedBakedQuad> horizontal = convertTextureHorizontal(format, transform, template, sprite, z, facing, color);
List<UnpackedBakedQuad> vertical = convertTextureVertical(format, transform, template, sprite, z, facing, color);
List<UnpackedBakedQuad> horizontal = convertTextureHorizontal(format, transform, template, sprite, z, facing, color, tint);
List<UnpackedBakedQuad> vertical = convertTextureVertical(format, transform, template, sprite, z, facing, color, tint);
return horizontal.size() >= vertical.size() ? horizontal : vertical;
}
/** @deprecated use {@link #convertTextureHorizontal(VertexFormat, TRSRTransformation, TextureAtlasSprite, TextureAtlasSprite, float, EnumFacing, int, int)} */
@Deprecated // TODO: remove
public static List<UnpackedBakedQuad> convertTextureHorizontal(VertexFormat format, TRSRTransformation transform, TextureAtlasSprite template, TextureAtlasSprite sprite, float z, EnumFacing facing, int color)
{
return convertTextureHorizontal(format, transform, template, sprite, z, facing, color, -1);
}
/**
* Scans a texture and converts it into a list of horizontal strips stacked on top of each other.
* The height of the strips is as big as possible.
*/
public static List<UnpackedBakedQuad> convertTextureHorizontal(VertexFormat format, TRSRTransformation transform, TextureAtlasSprite template, TextureAtlasSprite sprite, float z, EnumFacing facing, int color)
public static List<UnpackedBakedQuad> convertTextureHorizontal(VertexFormat format, TRSRTransformation transform, TextureAtlasSprite template, TextureAtlasSprite sprite, float z, EnumFacing facing, int color, int tint)
{
int w = template.getIconWidth();
int h = template.getIconHeight();
@ -116,7 +131,7 @@ public final class ItemTextureQuadConverter
(float)y * hScale,
(float)x * wScale,
(float)endY * hScale,
z, sprite, facing, color));
z, sprite, facing, color, tint));
// update Y if all the rows match. no need to rescan
if (endY - y > 1)
@ -132,11 +147,18 @@ public final class ItemTextureQuadConverter
return quads;
}
/** @deprecated use {@link #convertTextureVertical(VertexFormat, TRSRTransformation, TextureAtlasSprite, TextureAtlasSprite, float, EnumFacing, int, int)} */
@Deprecated // TODO: remove
public static List<UnpackedBakedQuad> convertTextureVertical(VertexFormat format, TRSRTransformation transform, TextureAtlasSprite template, TextureAtlasSprite sprite, float z, EnumFacing facing, int color)
{
return convertTextureVertical(format, transform, template, sprite, z, facing, color, -1);
}
/**
* Scans a texture and converts it into a list of vertical strips stacked next to each other from left to right.
* The width of the strips is as big as possible.
*/
public static List<UnpackedBakedQuad> convertTextureVertical(VertexFormat format, TRSRTransformation transform, TextureAtlasSprite template, TextureAtlasSprite sprite, float z, EnumFacing facing, int color)
public static List<UnpackedBakedQuad> convertTextureVertical(VertexFormat format, TRSRTransformation transform, TextureAtlasSprite template, TextureAtlasSprite sprite, float z, EnumFacing facing, int color, int tint)
{
int w = template.getIconWidth();
int h = template.getIconHeight();
@ -190,7 +212,7 @@ public final class ItemTextureQuadConverter
(float)start * hScale,
(float)endX * wScale,
(float)y * hScale,
z, sprite, facing, color));
z, sprite, facing, color, tint));
// update X if all the columns match. no need to rescan
if (endX - x > 1)
@ -211,11 +233,18 @@ public final class ItemTextureQuadConverter
return (color >> 24 & 255) / 255f > 0.1f;
}
/** @deprecated use {@link #genQuad(VertexFormat, TRSRTransformation, float, float, float, float, float, TextureAtlasSprite, EnumFacing, int, int)} */
@Deprecated // TODO: remove
public static UnpackedBakedQuad genQuad(VertexFormat format, TRSRTransformation transform, float x1, float y1, float x2, float y2, float z, TextureAtlasSprite sprite, EnumFacing facing, int color)
{
return genQuad(format, transform, x1, y1, x2, y2, z, sprite, facing, color, -1);
}
/**
* Generates a Front/Back quad for an itemmodel. Therefore only supports facing NORTH and SOUTH.
* Coordinates are [0,16] to match the usual coordinates used in TextureAtlasSprites
*/
public static UnpackedBakedQuad genQuad(VertexFormat format, TRSRTransformation transform, float x1, float y1, float x2, float y2, float z, TextureAtlasSprite sprite, EnumFacing facing, int color)
public static UnpackedBakedQuad genQuad(VertexFormat format, TRSRTransformation transform, float x1, float y1, float x2, float y2, float z, TextureAtlasSprite sprite, EnumFacing facing, int color, int tint)
{
float u1 = sprite.getInterpolatedU(x1);
float v1 = sprite.getInterpolatedV(y1);
@ -231,15 +260,16 @@ public final class ItemTextureQuadConverter
y1 = 1f - y2;
y2 = 1f - tmp;
return putQuad(format, transform, facing, sprite, color, x1, y1, x2, y2, z, u1, v1, u2, v2);
return putQuad(format, transform, facing, sprite, color, tint, x1, y1, x2, y2, z, u1, v1, u2, v2);
}
private static UnpackedBakedQuad putQuad(VertexFormat format, TRSRTransformation transform, EnumFacing side, TextureAtlasSprite sprite, int color,
private static UnpackedBakedQuad putQuad(VertexFormat format, TRSRTransformation transform, EnumFacing side, TextureAtlasSprite sprite, int color, int tint,
float x1, float y1, float x2, float y2, float z,
float u1, float v1, float u2, float v2)
{
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
builder.setQuadTint(-1);
builder.setQuadTint(tint);
builder.setQuadOrientation(side);
builder.setTexture(sprite);
@ -249,7 +279,8 @@ public final class ItemTextureQuadConverter
putVertex(builder, format, transform, side, x2, y1, z, u2, v2, color);
putVertex(builder, format, transform, side, x2, y2, z, u2, v1, color);
putVertex(builder, format, transform, side, x1, y2, z, u1, v1, color);
} else
}
else
{
putVertex(builder, format, transform, side, x1, y1, z, u1, v2, color);
putVertex(builder, format, transform, side, x1, y2, z, u1, v1, color);

View File

@ -84,20 +84,30 @@ public final class ModelDynBucket implements IModel
private final ResourceLocation coverLocation;
@Nullable
private final Fluid fluid;
private final boolean flipGas;
private final boolean tint;
public ModelDynBucket()
{
this(null, null, null, null, false);
this(null, null, null, null, false, true);
}
/** @deprecated use {@link #ModelDynBucket(ResourceLocation, ResourceLocation, ResourceLocation, Fluid, boolean, boolean)} */
@Deprecated // TODO: remove
public ModelDynBucket(@Nullable ResourceLocation baseLocation, @Nullable ResourceLocation liquidLocation, @Nullable ResourceLocation coverLocation, @Nullable Fluid fluid, boolean flipGas)
{
this(baseLocation, liquidLocation, coverLocation, fluid, flipGas, true);
}
public ModelDynBucket(@Nullable ResourceLocation baseLocation, @Nullable ResourceLocation liquidLocation, @Nullable ResourceLocation coverLocation, @Nullable Fluid fluid, boolean flipGas, boolean tint)
{
this.baseLocation = baseLocation;
this.liquidLocation = liquidLocation;
this.coverLocation = coverLocation;
this.fluid = fluid;
this.flipGas = flipGas;
this.tint = tint;
}
@Override
@ -150,16 +160,16 @@ public final class ModelDynBucket implements IModel
{
TextureAtlasSprite liquid = bakedTextureGetter.apply(liquidLocation);
// build liquid layer (inside)
builder.addAll(ItemTextureQuadConverter.convertTexture(format, transform, liquid, fluidSprite, NORTH_Z_FLUID, EnumFacing.NORTH, fluid.getColor()));
builder.addAll(ItemTextureQuadConverter.convertTexture(format, transform, liquid, fluidSprite, SOUTH_Z_FLUID, EnumFacing.SOUTH, fluid.getColor()));
builder.addAll(ItemTextureQuadConverter.convertTexture(format, transform, liquid, fluidSprite, NORTH_Z_FLUID, EnumFacing.NORTH, tint ? fluid.getColor() : 0xFFFFFFFF, 1));
builder.addAll(ItemTextureQuadConverter.convertTexture(format, transform, liquid, fluidSprite, SOUTH_Z_FLUID, EnumFacing.SOUTH, tint ? fluid.getColor() : 0xFFFFFFFF, 1));
particleSprite = fluidSprite;
}
if (coverLocation != null)
{
// cover (the actual item around the other two)
TextureAtlasSprite cover = bakedTextureGetter.apply(coverLocation);
builder.add(ItemTextureQuadConverter.genQuad(format, transform, 0, 0, 16, 16, NORTH_Z_COVER, cover, EnumFacing.NORTH, 0xffffffff));
builder.add(ItemTextureQuadConverter.genQuad(format, transform, 0, 0, 16, 16, SOUTH_Z_COVER, cover, EnumFacing.SOUTH, 0xffffffff));
builder.add(ItemTextureQuadConverter.genQuad(format, transform, 0, 0, 16, 16, NORTH_Z_COVER, cover, EnumFacing.NORTH, 0xFFFFFFFF, 2));
builder.add(ItemTextureQuadConverter.genQuad(format, transform, 0, 0, 16, 16, SOUTH_Z_COVER, cover, EnumFacing.SOUTH, 0xFFFFFFFF, 2));
if (particleSprite == null)
{
particleSprite = cover;
@ -171,8 +181,9 @@ public final class ModelDynBucket implements IModel
/**
* Sets the liquid in the model.
* fluid - Name of the fluid in the FluidRegistry
* flipGas - If "true" the model will be flipped upside down if the liquid is a gas. If "false" it wont
* "fluid" - Name of the fluid in the FluidRegistry
* "flipGas" - If "true" the model will be flipped upside down if the liquid is a gas. If "false" it won't.
* "applyTint" - If "true" the model will tint the fluid quads according to the fluid's base color.
* <p/>
* If the fluid can't be found, water is used
*/
@ -194,8 +205,20 @@ public final class ModelDynBucket implements IModel
throw new IllegalArgumentException(String.format("DynBucket custom data \"flipGas\" must have value \'true\' or \'false\' (was \'%s\')", flipStr));
}
boolean tint = this.tint;
if (customData.containsKey("applyTint"))
{
String string = customData.get("applyTint");
switch (string)
{
case "true": tint = true; break;
case "false": tint = false; break;
default: throw new IllegalArgumentException(String.format("DynBucket custom data \"applyTint\" must have value \'true\' or \'false\' (was \'%s\')", string));
}
}
// create new model with correct liquid
return new ModelDynBucket(baseLocation, liquidLocation, coverLocation, fluid, flip);
return new ModelDynBucket(baseLocation, liquidLocation, coverLocation, fluid, flip, tint);
}
/**
@ -222,7 +245,7 @@ public final class ModelDynBucket implements IModel
if (textures.containsKey("cover"))
cover = new ResourceLocation(textures.get("cover"));
return new ModelDynBucket(base, liquid, cover, fluid, flipGas);
return new ModelDynBucket(base, liquid, cover, fluid, flipGas, tint);
}
public enum LoaderDynBucket implements ICustomModelLoader

View File

@ -73,14 +73,12 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.IRegistry;
import net.minecraftforge.client.model.animation.AnimationItemOverrideList;
import net.minecraftforge.client.model.animation.ModelBlockAnimation;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.Models;
import net.minecraftforge.common.model.TRSRTransformation;
import net.minecraftforge.common.model.animation.IClip;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.Properties;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.ProgressManager;
@ -276,12 +274,6 @@ public final class ModelLoader extends ModelBakery
@Override
protected void loadItemModels()
{
// register model for the universal bucket, if it exists
if(FluidRegistry.isUniversalBucketEnabled())
{
setBucketModelDefinition(ForgeModContainer.getInstance().universalBucket);
}
registerVariantNames();
List<Item> items = StreamSupport.stream(Item.REGISTRY.spliterator(), false)

View File

@ -32,7 +32,6 @@ import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -48,6 +47,7 @@ import net.minecraft.stats.StatList;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo;
import net.minecraftforge.classloading.FMLForgePlugin;
import net.minecraftforge.client.ForgeClientHandler;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.ConfigManager;
@ -97,6 +97,7 @@ import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.relauncher.Side;
import javax.annotation.Nullable;
@ -470,6 +471,10 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
CapabilityAnimation.register();
CapabilityEnergy.register();
MinecraftForge.EVENT_BUS.register(MinecraftForge.INTERNAL_HANDLER);
if (FMLCommonHandler.instance().getSide() == Side.CLIENT)
{
MinecraftForge.EVENT_BUS.register(ForgeClientHandler.class);
}
ForgeChunkManager.captureConfig(evt.getModConfigurationDirectory());
MinecraftForge.EVENT_BUS.register(this);

View File

@ -11,7 +11,8 @@
"transform": "forge:default-item",
"custom": {
"fluid": "water",
"flipGas": true
"flipGas": true,
"applyTint": false
}
}
}