Merge pull request #1922 from RainWarrior/model-fluid2
1.8 model fluid renderer
This commit is contained in:
commit
f2eec981ff
|
@ -285,14 +285,12 @@ public class ForgeHooksClient
|
||||||
{
|
{
|
||||||
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Pre(map));
|
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Pre(map));
|
||||||
ModelLoader.White.instance.register(map);
|
ModelLoader.White.instance.register(map);
|
||||||
|
FluidRegistry.onTextureStitchedPre(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onTextureStitchedPost(TextureMap map)
|
public static void onTextureStitchedPost(TextureMap map)
|
||||||
{
|
{
|
||||||
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Post(map));
|
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Post(map));
|
||||||
|
|
||||||
FluidRegistry.WATER.setIcons(map.getAtlasSprite("minecraft:blocks/water_still"), map.getAtlasSprite("minecraft:blocks/water_flow"));
|
|
||||||
FluidRegistry.LAVA.setIcons(map.getAtlasSprite("minecraft:blocks/lava_still"), map.getAtlasSprite("minecraft:blocks/lava_flow"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int renderPass = -1;
|
static int renderPass = -1;
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class BlockStateLoader
|
||||||
boolean uvLock = var.getUvLock().or(false);
|
boolean uvLock = var.getUvLock().or(false);
|
||||||
int weight = var.getWeight().or(1);
|
int weight = var.getWeight().or(1);
|
||||||
|
|
||||||
if (var.getModel() != null && var.getSubmodels().size() == 0 && var.getTextures().size() == 0)
|
if (var.getModel() != null && var.getSubmodels().size() == 0 && var.getTextures().size() == 0 && var.getCustomData().size() == 0)
|
||||||
mcVars.add(new ModelBlockDefinition.Variant(var.getModel(), rot, uvLock, weight));
|
mcVars.add(new ModelBlockDefinition.Variant(var.getModel(), rot, uvLock, weight));
|
||||||
else
|
else
|
||||||
mcVars.add(new ForgeVariant(var.getModel(), rot, uvLock, weight, var.getTextures(), var.getOnlyPartsVariant(), var.getCustomData()));
|
mcVars.add(new ForgeVariant(var.getModel(), rot, uvLock, weight, var.getTextures(), var.getOnlyPartsVariant(), var.getCustomData()));
|
||||||
|
|
|
@ -0,0 +1,354 @@
|
||||||
|
package net.minecraftforge.client.model;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
|
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||||
|
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||||
|
import net.minecraft.client.resources.IResourceManager;
|
||||||
|
import net.minecraft.client.resources.model.IBakedModel;
|
||||||
|
import net.minecraft.client.resources.model.ModelRotation;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.MathHelper;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||||
|
import net.minecraftforge.fluids.BlockFluidBase;
|
||||||
|
import net.minecraftforge.fluids.Fluid;
|
||||||
|
import net.minecraftforge.fluids.FluidRegistry;
|
||||||
|
import net.minecraftforge.fml.common.FMLLog;
|
||||||
|
|
||||||
|
import org.lwjgl.BufferUtils;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
|
public class ModelFluid implements IModelCustomData
|
||||||
|
{
|
||||||
|
public static final ModelFluid waterModel = new ModelFluid(FluidRegistry.WATER);
|
||||||
|
public static final ModelFluid lavaModel = new ModelFluid(FluidRegistry.LAVA);
|
||||||
|
private final Fluid fluid;
|
||||||
|
|
||||||
|
public ModelFluid(Fluid fluid)
|
||||||
|
{
|
||||||
|
this.fluid = fluid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<ResourceLocation> getDependencies()
|
||||||
|
{
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<ResourceLocation> getTextures()
|
||||||
|
{
|
||||||
|
return ImmutableSet.of(fluid.getStill(), fluid.getFlowing());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IFlexibleBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter)
|
||||||
|
{
|
||||||
|
return new BakedFluid(state.apply(this), format, fluid.getColor(), bakedTextureGetter.apply(fluid.getStill()), bakedTextureGetter.apply(fluid.getFlowing()), fluid.isGaseous());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IModelState getDefaultState()
|
||||||
|
{
|
||||||
|
return ModelRotation.X0_Y0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum FluidLoader implements ICustomModelLoader
|
||||||
|
{
|
||||||
|
instance;
|
||||||
|
|
||||||
|
public void onResourceManagerReload(IResourceManager resourceManager) {}
|
||||||
|
|
||||||
|
public boolean accepts(ResourceLocation modelLocation)
|
||||||
|
{
|
||||||
|
return modelLocation.getResourceDomain().equals("forge") && (
|
||||||
|
modelLocation.getResourcePath().equals("fluid") ||
|
||||||
|
modelLocation.getResourcePath().equals("models/block/fluid") ||
|
||||||
|
modelLocation.getResourcePath().equals("models/item/fluid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IModel loadModel(ResourceLocation modelLocation)
|
||||||
|
{
|
||||||
|
return waterModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BakedFluid implements IFlexibleBakedModel, ISmartBlockModel
|
||||||
|
{
|
||||||
|
private static final int x[] = { 0, 0, 1, 1 };
|
||||||
|
private static final int z[] = { 0, 1, 1, 0 };
|
||||||
|
private static final float eps = 1e-3f;
|
||||||
|
|
||||||
|
private final TRSRTransformation transformation;
|
||||||
|
private final VertexFormat format;
|
||||||
|
private final int color;
|
||||||
|
private final TextureAtlasSprite still, flowing;
|
||||||
|
private final boolean gas;
|
||||||
|
private final Optional<IExtendedBlockState> state;
|
||||||
|
private final EnumMap<EnumFacing, List<BakedQuad>> faceQuads;
|
||||||
|
|
||||||
|
public BakedFluid(TRSRTransformation transformation, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, boolean gas)
|
||||||
|
{
|
||||||
|
this(transformation, format, color, still, flowing, gas, Optional.<IExtendedBlockState>absent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BakedFluid(TRSRTransformation transformation, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, boolean gas, Optional<IExtendedBlockState> stateOption)
|
||||||
|
{
|
||||||
|
this.transformation = transformation;
|
||||||
|
this.format = format;
|
||||||
|
this.color = color;
|
||||||
|
this.still = still;
|
||||||
|
this.flowing = flowing;
|
||||||
|
this.gas = gas;
|
||||||
|
this.state = stateOption;
|
||||||
|
|
||||||
|
ByteBuffer buf = BufferUtils.createByteBuffer(4 * format.getNextOffset());
|
||||||
|
int[] data;
|
||||||
|
|
||||||
|
faceQuads = Maps.newEnumMap(EnumFacing.class);
|
||||||
|
for(EnumFacing side : EnumFacing.values())
|
||||||
|
{
|
||||||
|
faceQuads.put(side, ImmutableList.<BakedQuad>of());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(state.isPresent())
|
||||||
|
{
|
||||||
|
IExtendedBlockState state = this.state.get();
|
||||||
|
float[] y = new float[4];
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if(gas)
|
||||||
|
{
|
||||||
|
y[i] = 1 - state.getValue(BlockFluidBase.LEVEL_CORNERS[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y[i] = state.getValue(BlockFluidBase.LEVEL_CORNERS[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float flow = state.getValue(BlockFluidBase.FLOW_DIRECTION);
|
||||||
|
|
||||||
|
// top
|
||||||
|
|
||||||
|
TextureAtlasSprite topSprite = flowing;
|
||||||
|
float scale = 4;
|
||||||
|
if(flow < -999F)
|
||||||
|
{
|
||||||
|
flow = 0;
|
||||||
|
scale = 8;
|
||||||
|
topSprite = still;
|
||||||
|
}
|
||||||
|
|
||||||
|
float c = MathHelper.cos(flow) * scale;
|
||||||
|
float s = MathHelper.sin(flow) * scale;
|
||||||
|
|
||||||
|
EnumFacing side = gas ? EnumFacing.DOWN : EnumFacing.UP;
|
||||||
|
buf.clear();
|
||||||
|
for(int i = gas ? 3 : 0; i != (gas ? -1 : 4); i+= (gas ? -1 : 1))
|
||||||
|
{
|
||||||
|
putVertex(
|
||||||
|
buf, side,
|
||||||
|
x[i], y[i], z[i],
|
||||||
|
topSprite.getInterpolatedU(8 + c * (x[i] * 2 - 1) + s * (z[i] * 2 - 1)),
|
||||||
|
topSprite.getInterpolatedV(8 + c * (x[(i + 1) % 4] * 2 - 1) + s * (z[(i + 1) % 4] * 2 - 1)));
|
||||||
|
}
|
||||||
|
buf.flip();
|
||||||
|
data = new int[4 * format.getNextOffset() / 4];
|
||||||
|
buf.asIntBuffer().get(data);
|
||||||
|
faceQuads.put(side, ImmutableList.<BakedQuad>of(new IColoredBakedQuad.ColoredBakedQuad(data, -1, side)));
|
||||||
|
|
||||||
|
// bottom
|
||||||
|
|
||||||
|
side = side.getOpposite();
|
||||||
|
buf.clear();
|
||||||
|
for(int i = gas ? 3 : 0; i != (gas ? -1 : 4); i+= (gas ? -1 : 1))
|
||||||
|
{
|
||||||
|
putVertex(
|
||||||
|
buf, side,
|
||||||
|
z[i], gas ? 1 : 0, x[i],
|
||||||
|
still.getInterpolatedU(z[i] * 16),
|
||||||
|
still.getInterpolatedV(x[i] * 16));
|
||||||
|
}
|
||||||
|
buf.flip();
|
||||||
|
data = new int[4 * format.getNextOffset() / 4];
|
||||||
|
buf.asIntBuffer().get(data);
|
||||||
|
faceQuads.put(side, ImmutableList.<BakedQuad>of(new IColoredBakedQuad.ColoredBakedQuad(data, -1, side)));
|
||||||
|
|
||||||
|
// sides
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
side = EnumFacing.getHorizontal((5 - i) % 4);
|
||||||
|
BakedQuad q[] = new BakedQuad[2];
|
||||||
|
|
||||||
|
for(int k = 0; k < 2; k++)
|
||||||
|
{
|
||||||
|
buf.clear();
|
||||||
|
for(int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
int l = (k * 3) + (1 - 2 * k) * j;
|
||||||
|
float yl = z[l] * y[(i + x[l]) % 4];
|
||||||
|
if(gas && z[l] == 0) yl = 1;
|
||||||
|
putVertex(
|
||||||
|
buf, side,
|
||||||
|
x[(i + x[l]) % 4], yl, z[(i + x[l]) % 4],
|
||||||
|
flowing.getInterpolatedU(x[l] * 8),
|
||||||
|
flowing.getInterpolatedV((gas ? yl : 1 - yl) * 8));
|
||||||
|
}
|
||||||
|
buf.flip();
|
||||||
|
data = new int[4 * format.getNextOffset() / 4];
|
||||||
|
buf.asIntBuffer().get(data);
|
||||||
|
q[k] = new IColoredBakedQuad.ColoredBakedQuad(data, -1, side);
|
||||||
|
}
|
||||||
|
faceQuads.put(side, ImmutableList.of(q[0], q[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 1 quad for inventory
|
||||||
|
|
||||||
|
buf.clear();
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
putVertex(
|
||||||
|
buf, EnumFacing.UP,
|
||||||
|
z[i], x[i], 0,
|
||||||
|
still.getInterpolatedU(x[i] * 16),
|
||||||
|
still.getInterpolatedV(z[i] * 16));
|
||||||
|
}
|
||||||
|
buf.flip();
|
||||||
|
data = new int[4 * format.getNextOffset() / 4];
|
||||||
|
buf.asIntBuffer().get(data);
|
||||||
|
faceQuads.put(EnumFacing.SOUTH, ImmutableList.<BakedQuad>of(new IColoredBakedQuad.ColoredBakedQuad(data, -1, EnumFacing.UP)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void put(ByteBuffer buf, VertexFormatElement e, Float... fs)
|
||||||
|
{
|
||||||
|
Attributes.put(buf, e, true, 0f, fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float diffuse(EnumFacing side)
|
||||||
|
{
|
||||||
|
switch(side)
|
||||||
|
{
|
||||||
|
case DOWN:
|
||||||
|
return .5f;
|
||||||
|
case UP:
|
||||||
|
return 1f;
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
return .8f;
|
||||||
|
default:
|
||||||
|
return .6f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putVertex(ByteBuffer buf, EnumFacing side, float x, float y, float z, float u, float v)
|
||||||
|
{
|
||||||
|
for(VertexFormatElement e : (List<VertexFormatElement>)format.getElements())
|
||||||
|
{
|
||||||
|
// TODO transformation
|
||||||
|
switch(e.getUsage())
|
||||||
|
{
|
||||||
|
case POSITION:
|
||||||
|
put(buf, e, x - side.getDirectionVec().getX() * eps, y, z - side.getDirectionVec().getZ() * eps, 1f);
|
||||||
|
break;
|
||||||
|
case COLOR:
|
||||||
|
// temporarily add diffuse lighting
|
||||||
|
float d = diffuse(side);
|
||||||
|
put(buf, e,
|
||||||
|
d * ((color >> 16) & 0xFF) / 255f,
|
||||||
|
d * ((color >> 8) & 0xFF) / 255f,
|
||||||
|
d * (color & 0xFF) / 255f,
|
||||||
|
((color >> 24) & 0xFF) / 255f);
|
||||||
|
break;
|
||||||
|
case UV:
|
||||||
|
put(buf, e, u, v, 0f, 1f);
|
||||||
|
break;
|
||||||
|
case NORMAL:
|
||||||
|
put(buf, e, (float)side.getFrontOffsetX(), (float)side.getFrontOffsetX(), (float)side.getFrontOffsetX(), 0f);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
put(buf, e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAmbientOcclusion()
|
||||||
|
{
|
||||||
|
return false; // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGui3d()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBuiltInRenderer()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextureAtlasSprite getTexture()
|
||||||
|
{
|
||||||
|
return still;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemCameraTransforms getItemCameraTransforms()
|
||||||
|
{
|
||||||
|
return ItemCameraTransforms.DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BakedQuad> getFaceQuads(EnumFacing side)
|
||||||
|
{
|
||||||
|
return faceQuads.get(side);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BakedQuad> getGeneralQuads()
|
||||||
|
{
|
||||||
|
return ImmutableList.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
public VertexFormat getFormat()
|
||||||
|
{
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBakedModel handleBlockState(IBlockState state)
|
||||||
|
{
|
||||||
|
return new BakedFluid(transformation, format, color, still, flowing, gas, Optional.of((IExtendedBlockState)state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IModel process(ImmutableMap<String, String> customData)
|
||||||
|
{
|
||||||
|
if(!customData.containsKey("fluid")) return this;
|
||||||
|
|
||||||
|
String fluidStr = customData.get("fluid");
|
||||||
|
JsonElement e = new JsonParser().parse(fluidStr);
|
||||||
|
String fluid = e.getAsString();
|
||||||
|
if(!FluidRegistry.isFluidRegistered(fluid))
|
||||||
|
{
|
||||||
|
FMLLog.severe("fluid '%s' not found", fluid);
|
||||||
|
return waterModel;
|
||||||
|
}
|
||||||
|
return new ModelFluid(FluidRegistry.getFluid(fluid));
|
||||||
|
}
|
||||||
|
}
|
|
@ -116,7 +116,13 @@ public class ModelLoader extends ModelBakery
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
sprites.put(new ResourceLocation("missingno"), textureMap.getMissingSprite());
|
sprites.put(new ResourceLocation("missingno"), textureMap.getMissingSprite());
|
||||||
Function<ResourceLocation, TextureAtlasSprite> textureGetter = Functions.forMap(sprites, textureMap.getMissingSprite());
|
Function<ResourceLocation, TextureAtlasSprite> textureGetter = new Function<ResourceLocation, TextureAtlasSprite>()
|
||||||
|
{
|
||||||
|
public TextureAtlasSprite apply(ResourceLocation location)
|
||||||
|
{
|
||||||
|
return Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(location.toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
IFlexibleBakedModel missingBaked = missingModel.bake(missingModel.getDefaultState(), Attributes.DEFAULT_BAKED_FORMAT, textureGetter);
|
IFlexibleBakedModel missingBaked = missingModel.bake(missingModel.getDefaultState(), Attributes.DEFAULT_BAKED_FORMAT, textureGetter);
|
||||||
for (Entry<ModelResourceLocation, IModel> e : stateModels.entrySet())
|
for (Entry<ModelResourceLocation, IModel> e : stateModels.entrySet())
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,7 @@ import net.minecraft.client.resources.IResourceManager;
|
||||||
import net.minecraft.client.resources.IResourceManagerReloadListener;
|
import net.minecraft.client.resources.IResourceManagerReloadListener;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraftforge.client.model.ModelLoader.VanillaLoader;
|
import net.minecraftforge.client.model.ModelLoader.VanillaLoader;
|
||||||
|
import net.minecraftforge.client.model.b3d.B3DLoader;
|
||||||
import net.minecraftforge.fml.common.FMLLog;
|
import net.minecraftforge.fml.common.FMLLog;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
@ -27,6 +28,13 @@ public class ModelLoaderRegistry
|
||||||
private static final Set<ICustomModelLoader> loaders = new HashSet<ICustomModelLoader>();
|
private static final Set<ICustomModelLoader> loaders = new HashSet<ICustomModelLoader>();
|
||||||
private static final Map<ResourceLocation, IModel> cache = new HashMap<ResourceLocation, IModel>();
|
private static final Map<ResourceLocation, IModel> cache = new HashMap<ResourceLocation, IModel>();
|
||||||
|
|
||||||
|
// Forge built-in loaders
|
||||||
|
static
|
||||||
|
{
|
||||||
|
registerLoader(B3DLoader.instance);
|
||||||
|
registerLoader(ModelFluid.FluidLoader.instance);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Makes system aware of your loader.
|
* Makes system aware of your loader.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -82,11 +82,6 @@ public class B3DLoader implements ICustomModelLoader
|
||||||
private final Set<String> enabledDomains = new HashSet<String>();
|
private final Set<String> enabledDomains = new HashSet<String>();
|
||||||
private final Map<ResourceLocation, B3DModel> cache = new HashMap<ResourceLocation, B3DModel>();
|
private final Map<ResourceLocation, B3DModel> cache = new HashMap<ResourceLocation, B3DModel>();
|
||||||
|
|
||||||
public B3DLoader()
|
|
||||||
{
|
|
||||||
ModelLoaderRegistry.registerLoader(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addDomain(String domain)
|
public void addDomain(String domain)
|
||||||
{
|
{
|
||||||
enabledDomains.add(domain.toLowerCase());
|
enabledDomains.add(domain.toLowerCase());
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package net.minecraftforge.common.property;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
|
||||||
|
public class PropertyFloat implements IUnlistedProperty<Float>
|
||||||
|
{
|
||||||
|
private final String name;
|
||||||
|
private final Predicate<Float> validator;
|
||||||
|
|
||||||
|
public PropertyFloat(String name)
|
||||||
|
{
|
||||||
|
this(name, Predicates.<Float>alwaysTrue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyFloat(String name, Predicate<Float> validator)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.validator = validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid(Float value)
|
||||||
|
{
|
||||||
|
return validator.apply(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<Float> getType()
|
||||||
|
{
|
||||||
|
return Float.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String valueToString(Float value)
|
||||||
|
{
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,8 @@
|
||||||
package net.minecraftforge.fluids;
|
package net.minecraftforge.fluids;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.properties.IProperty;
|
import net.minecraft.block.properties.IProperty;
|
||||||
|
@ -22,9 +19,16 @@ import net.minecraft.util.EnumWorldBlockLayer;
|
||||||
import net.minecraft.util.Vec3;
|
import net.minecraft.util.Vec3;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.property.ExtendedBlockState;
|
||||||
|
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||||
|
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||||
|
import net.minecraftforge.common.property.PropertyFloat;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a base implementation for Fluid blocks.
|
* This is a base implementation for Fluid blocks.
|
||||||
*
|
*
|
||||||
|
@ -84,6 +88,22 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock
|
||||||
protected Map<Block, Boolean> displacements = Maps.newHashMap();
|
protected Map<Block, Boolean> displacements = Maps.newHashMap();
|
||||||
|
|
||||||
public static final PropertyInteger LEVEL = PropertyInteger.create("level", 0, 15);
|
public static final PropertyInteger LEVEL = PropertyInteger.create("level", 0, 15);
|
||||||
|
public static final PropertyFloat[] LEVEL_CORNERS = new PropertyFloat[4];
|
||||||
|
public static final PropertyFloat FLOW_DIRECTION = new PropertyFloat("flow_direction");
|
||||||
|
public static final IUnlistedProperty[] FLUID_RENDER_PROPS;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
ImmutableList.Builder<IUnlistedProperty> builder = ImmutableList.builder();
|
||||||
|
builder.add(FLOW_DIRECTION);
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
LEVEL_CORNERS[i] = new PropertyFloat("level_corner_" + i);
|
||||||
|
builder.add(LEVEL_CORNERS[i]);
|
||||||
|
}
|
||||||
|
FLUID_RENDER_PROPS = builder.build().toArray(new IUnlistedProperty[0]);
|
||||||
|
}
|
||||||
|
|
||||||
protected int quantaPerBlock = 8;
|
protected int quantaPerBlock = 8;
|
||||||
protected float quantaPerBlockFloat = 8F;
|
protected float quantaPerBlockFloat = 8F;
|
||||||
protected int density = 1;
|
protected int density = 1;
|
||||||
|
@ -126,7 +146,7 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock
|
||||||
@Override
|
@Override
|
||||||
protected BlockState createBlockState()
|
protected BlockState createBlockState()
|
||||||
{
|
{
|
||||||
return new BlockState(this, LEVEL);
|
return new ExtendedBlockState(this, new IProperty[] { LEVEL }, FLUID_RENDER_PROPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -345,12 +365,6 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock
|
||||||
return (int) (data / quantaPerBlockFloat * maxScaledLight);
|
return (int) (data / quantaPerBlockFloat * maxScaledLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRenderType()
|
|
||||||
{
|
|
||||||
return FluidRegistry.renderIdFluid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpaqueCube()
|
public boolean isOpaqueCube()
|
||||||
{
|
{
|
||||||
|
@ -397,11 +411,64 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock
|
||||||
public boolean shouldSideBeRendered(IBlockAccess world, BlockPos pos, EnumFacing side)
|
public boolean shouldSideBeRendered(IBlockAccess world, BlockPos pos, EnumFacing side)
|
||||||
{
|
{
|
||||||
Block block = world.getBlockState(pos).getBlock();
|
Block block = world.getBlockState(pos).getBlock();
|
||||||
if (block != this)
|
if (block.getMaterial() == this.blockMaterial)
|
||||||
{
|
{
|
||||||
return !block.isOpaqueCube();
|
return false;
|
||||||
}
|
}
|
||||||
return block.getMaterial() == this.getMaterial() ? false : super.shouldSideBeRendered(world, pos, side);
|
if(densityDir == -1 && side == EnumFacing.UP)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(densityDir == 1 && side == EnumFacing.DOWN)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.shouldSideBeRendered(world, pos, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockState getExtendedState(IBlockState oldState, IBlockAccess worldIn, BlockPos pos)
|
||||||
|
{
|
||||||
|
IExtendedBlockState state = (IExtendedBlockState)oldState;
|
||||||
|
state = state.withProperty(FLOW_DIRECTION, (float)getFlowDirection(worldIn, pos));
|
||||||
|
float[][] height = new float[3][3];
|
||||||
|
float[][] corner = new float[2][2];
|
||||||
|
height[1][1] = getFluidHeightForRender(worldIn, pos);
|
||||||
|
if(height[1][1] == 1)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
corner[i][j] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
if(i != 1 || j != 1)
|
||||||
|
{
|
||||||
|
height[i][j] = getFluidHeightForRender(worldIn, pos.add(i - 1, 0, j - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
corner[i][j] = getFluidHeightAverage(height[i][j], height[i][j + 1], height[i + 1][j], height[i + 1][j + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = state.withProperty(LEVEL_CORNERS[0], corner[0][0]);
|
||||||
|
state = state.withProperty(LEVEL_CORNERS[1], corner[0][1]);
|
||||||
|
state = state.withProperty(LEVEL_CORNERS[2], corner[1][1]);
|
||||||
|
state = state.withProperty(LEVEL_CORNERS[3], corner[1][0]);
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FLUID FUNCTIONS */
|
/* FLUID FUNCTIONS */
|
||||||
|
@ -462,6 +529,52 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock
|
||||||
return quantaRemaining / quantaPerBlockFloat;
|
return quantaRemaining / quantaPerBlockFloat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getFluidHeightAverage(float... flow)
|
||||||
|
{
|
||||||
|
float total = 0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
float end = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < flow.length; i++)
|
||||||
|
{
|
||||||
|
if (flow[i] >= 0.875F && end != 1F)
|
||||||
|
{
|
||||||
|
end = flow[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flow[i] >= 0)
|
||||||
|
{
|
||||||
|
total += flow[i];
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end == 0)
|
||||||
|
end = total / count;
|
||||||
|
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFluidHeightForRender(IBlockAccess world, BlockPos pos)
|
||||||
|
{
|
||||||
|
IBlockState here = world.getBlockState(pos);
|
||||||
|
IBlockState up = world.getBlockState(pos.down(densityDir));
|
||||||
|
if (here.getBlock() == this)
|
||||||
|
{
|
||||||
|
if (up.getBlock().getMaterial().isLiquid() || up.getBlock() instanceof IFluidBlock)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getMetaFromState(here) == getMaxRenderHeightMeta())
|
||||||
|
{
|
||||||
|
return 0.875F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !here.getBlock().getMaterial().isSolid() && up.getBlock() == this ? 1 : this.getQuantaPercentage(world, pos) * 0.875F;
|
||||||
|
}
|
||||||
|
|
||||||
public Vec3 getFlowVector(IBlockAccess world, BlockPos pos)
|
public Vec3 getFlowVector(IBlockAccess world, BlockPos pos)
|
||||||
{
|
{
|
||||||
Vec3 vec = new Vec3(0.0D, 0.0D, 0.0D);
|
Vec3 vec = new Vec3(0.0D, 0.0D, 0.0D);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.google.common.collect.Maps;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.util.BlockPos;
|
import net.minecraft.util.BlockPos;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.StatCollector;
|
import net.minecraft.util.StatCollector;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.common.ForgeModContainer;
|
import net.minecraftforge.common.ForgeModContainer;
|
||||||
|
@ -41,10 +42,18 @@ public class Fluid
|
||||||
/** The unlocalized name of this fluid. */
|
/** The unlocalized name of this fluid. */
|
||||||
protected String unlocalizedName;
|
protected String unlocalizedName;
|
||||||
|
|
||||||
/** The Icons for this fluid. */
|
/**
|
||||||
|
* The Icons for this fluid.
|
||||||
|
* @deprecated use ResourceLocation-based ones instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
protected TextureAtlasSprite stillIcon;
|
protected TextureAtlasSprite stillIcon;
|
||||||
|
@Deprecated
|
||||||
protected TextureAtlasSprite flowingIcon;
|
protected TextureAtlasSprite flowingIcon;
|
||||||
|
|
||||||
|
protected final ResourceLocation still;
|
||||||
|
protected final ResourceLocation flowing;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The light level emitted by this fluid.
|
* The light level emitted by this fluid.
|
||||||
*
|
*
|
||||||
|
@ -103,10 +112,21 @@ public class Fluid
|
||||||
*/
|
*/
|
||||||
protected Block block = null;
|
protected Block block = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use the constructor with texture locations.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public Fluid(String fluidName)
|
public Fluid(String fluidName)
|
||||||
|
{
|
||||||
|
this(fluidName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Fluid(String fluidName, ResourceLocation still, ResourceLocation flowing)
|
||||||
{
|
{
|
||||||
this.fluidName = fluidName.toLowerCase(Locale.ENGLISH);
|
this.fluidName = fluidName.toLowerCase(Locale.ENGLISH);
|
||||||
this.unlocalizedName = fluidName;
|
this.unlocalizedName = fluidName;
|
||||||
|
this.still = still;
|
||||||
|
this.flowing = flowing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fluid setUnlocalizedName(String unlocalizedName)
|
public Fluid setUnlocalizedName(String unlocalizedName)
|
||||||
|
@ -260,39 +280,55 @@ public class Fluid
|
||||||
|
|
||||||
public int getColor()
|
public int getColor()
|
||||||
{
|
{
|
||||||
return 0xFFFFFF;
|
return 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ResourceLocation getStill()
|
||||||
|
{
|
||||||
|
return still;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceLocation getFlowing()
|
||||||
|
{
|
||||||
|
return flowing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Fluid setStillIcon(TextureAtlasSprite stillIcon)
|
public final Fluid setStillIcon(TextureAtlasSprite stillIcon)
|
||||||
{
|
{
|
||||||
this.stillIcon = stillIcon;
|
this.stillIcon = stillIcon;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Fluid setFlowingIcon(TextureAtlasSprite flowingIcon)
|
public final Fluid setFlowingIcon(TextureAtlasSprite flowingIcon)
|
||||||
{
|
{
|
||||||
this.flowingIcon = flowingIcon;
|
this.flowingIcon = flowingIcon;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Fluid setIcons(TextureAtlasSprite stillIcon, TextureAtlasSprite flowingIcon)
|
public final Fluid setIcons(TextureAtlasSprite stillIcon, TextureAtlasSprite flowingIcon)
|
||||||
{
|
{
|
||||||
return this.setStillIcon(stillIcon).setFlowingIcon(flowingIcon);
|
return this.setStillIcon(stillIcon).setFlowingIcon(flowingIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Fluid setIcons(TextureAtlasSprite commonIcon)
|
public final Fluid setIcons(TextureAtlasSprite commonIcon)
|
||||||
{
|
{
|
||||||
return this.setStillIcon(commonIcon).setFlowingIcon(commonIcon);
|
return this.setStillIcon(commonIcon).setFlowingIcon(commonIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public TextureAtlasSprite getIcon(){ return getStillIcon(); }
|
public TextureAtlasSprite getIcon(){ return getStillIcon(); }
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public TextureAtlasSprite getStillIcon()
|
public TextureAtlasSprite getStillIcon()
|
||||||
{
|
{
|
||||||
return this.stillIcon;
|
return this.stillIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public TextureAtlasSprite getFlowingIcon()
|
public TextureAtlasSprite getFlowingIcon()
|
||||||
{
|
{
|
||||||
return this.flowingIcon;
|
return this.flowingIcon;
|
||||||
|
@ -306,7 +342,11 @@ public class Fluid
|
||||||
public boolean isGaseous(FluidStack stack){ return isGaseous(); }
|
public boolean isGaseous(FluidStack stack){ return isGaseous(); }
|
||||||
public EnumRarity getRarity(FluidStack stack){ return getRarity(); }
|
public EnumRarity getRarity(FluidStack stack){ return getRarity(); }
|
||||||
public int getColor(FluidStack stack){ return getColor(); }
|
public int getColor(FluidStack stack){ return getColor(); }
|
||||||
|
@Deprecated
|
||||||
public TextureAtlasSprite getIcon(FluidStack stack){ return getIcon(); }
|
public TextureAtlasSprite getIcon(FluidStack stack){ return getIcon(); }
|
||||||
|
public ResourceLocation getStill(FluidStack stack) { return getStill(); }
|
||||||
|
public ResourceLocation getFlowing(FluidStack stack) { return getFlowing(); }
|
||||||
|
|
||||||
/* World-based Accessors */
|
/* World-based Accessors */
|
||||||
public int getLuminosity(World world, BlockPos pos){ return getLuminosity(); }
|
public int getLuminosity(World world, BlockPos pos){ return getLuminosity(); }
|
||||||
public int getDensity(World world, BlockPos pos){ return getDensity(); }
|
public int getDensity(World world, BlockPos pos){ return getDensity(); }
|
||||||
|
@ -315,6 +355,9 @@ public class Fluid
|
||||||
public boolean isGaseous(World world, BlockPos pos){ return isGaseous(); }
|
public boolean isGaseous(World world, BlockPos pos){ return isGaseous(); }
|
||||||
public EnumRarity getRarity(World world, BlockPos pos){ return getRarity(); }
|
public EnumRarity getRarity(World world, BlockPos pos){ return getRarity(); }
|
||||||
public int getColor(World world, BlockPos pos){ return getColor(); }
|
public int getColor(World world, BlockPos pos){ return getColor(); }
|
||||||
|
@Deprecated
|
||||||
public TextureAtlasSprite getIcon(World world, BlockPos pos){ return getIcon(); }
|
public TextureAtlasSprite getIcon(World world, BlockPos pos){ return getIcon(); }
|
||||||
|
public ResourceLocation getStill(World world, BlockPos pos) { return getStill(); }
|
||||||
|
public ResourceLocation getFlowing(World world, BlockPos pos) { return getFlowing(); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,13 @@ import java.util.Set;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureMap;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraft.nbt.NBTTagString;
|
import net.minecraft.nbt.NBTTagString;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.StatCollector;
|
import net.minecraft.util.StatCollector;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
|
||||||
|
@ -47,14 +50,14 @@ public abstract class FluidRegistry
|
||||||
static BiMap<String,String> defaultFluidName = HashBiMap.create();
|
static BiMap<String,String> defaultFluidName = HashBiMap.create();
|
||||||
static Map<Fluid,FluidDelegate> delegates = Maps.newHashMap();
|
static Map<Fluid,FluidDelegate> delegates = Maps.newHashMap();
|
||||||
|
|
||||||
public static final Fluid WATER = new Fluid("water") {
|
public static final Fluid WATER = new Fluid("water", new ResourceLocation("blocks/water_still"), new ResourceLocation("blocks/water_flow")) {
|
||||||
@Override
|
@Override
|
||||||
public String getLocalizedName() {
|
public String getLocalizedName() {
|
||||||
return StatCollector.translateToLocal("tile.water.name");
|
return StatCollector.translateToLocal("tile.water.name");
|
||||||
}
|
}
|
||||||
}.setBlock(Blocks.water).setUnlocalizedName(Blocks.water.getUnlocalizedName());
|
}.setBlock(Blocks.water).setUnlocalizedName(Blocks.water.getUnlocalizedName());
|
||||||
|
|
||||||
public static final Fluid LAVA = new Fluid("lava") {
|
public static final Fluid LAVA = new Fluid("lava", new ResourceLocation("blocks/lava_still"), new ResourceLocation("blocks/lava_flow")) {
|
||||||
@Override
|
@Override
|
||||||
public String getLocalizedName() {
|
public String getLocalizedName() {
|
||||||
return StatCollector.translateToLocal("tile.lava.name");
|
return StatCollector.translateToLocal("tile.lava.name");
|
||||||
|
@ -393,4 +396,21 @@ public abstract class FluidRegistry
|
||||||
fluid = fluids.get(name);
|
fluid = fluids.get(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void onTextureStitchedPre(TextureMap map)
|
||||||
|
{
|
||||||
|
for(Fluid fluid : fluids.values())
|
||||||
|
{
|
||||||
|
if(fluid.getStill() != null)
|
||||||
|
{
|
||||||
|
TextureAtlasSprite still = map.registerSprite(fluid.getStill());
|
||||||
|
fluid.setStillIcon(still);
|
||||||
|
}
|
||||||
|
if(fluid.getFlowing() != null)
|
||||||
|
{
|
||||||
|
TextureAtlasSprite flowing = map.registerSprite(fluid.getFlowing());
|
||||||
|
fluid.setStillIcon(flowing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,360 +0,0 @@
|
||||||
package net.minecraftforge.fluids;
|
|
||||||
|
|
||||||
//TODO: Get some test liquids and test this out -.-
|
|
||||||
/*
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.renderer.RenderBlocks;
|
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
|
||||||
import net.minecraft.client.renderer.texture.TextureMap;
|
|
||||||
import net.minecraft.util.IIcon;
|
|
||||||
import net.minecraft.util.MathHelper;
|
|
||||||
import net.minecraft.world.IBlockAccess;
|
|
||||||
import net.minecraftforge.fml.client.registry.ISimpleBlockRenderingHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default renderer for Forge fluid blocks.
|
|
||||||
*
|
|
||||||
* @author King Lemming
|
|
||||||
*
|
|
||||||
* /
|
|
||||||
public class RenderBlockFluid implements ISimpleBlockRenderingHandler
|
|
||||||
{
|
|
||||||
public static RenderBlockFluid instance = new RenderBlockFluid();
|
|
||||||
|
|
||||||
static final float LIGHT_Y_NEG = 0.5F;
|
|
||||||
static final float LIGHT_Y_POS = 1.0F;
|
|
||||||
static final float LIGHT_XZ_NEG = 0.8F;
|
|
||||||
static final float LIGHT_XZ_POS = 0.6F;
|
|
||||||
static final double RENDER_OFFSET = 0.0010000000474974513D;
|
|
||||||
|
|
||||||
public float getFluidHeightAverage(float[] flow)
|
|
||||||
{
|
|
||||||
float total = 0;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
float end = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < flow.length; i++)
|
|
||||||
{
|
|
||||||
if (flow[i] >= 0.875F && end != 1F)
|
|
||||||
{
|
|
||||||
end = flow[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flow[i] >= 0)
|
|
||||||
{
|
|
||||||
total += flow[i];
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end == 0)
|
|
||||||
end = total / count;
|
|
||||||
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getFluidHeightForRender(IBlockAccess world, int x, int y, int z, BlockFluidBase block)
|
|
||||||
{
|
|
||||||
if (world.getBlock(x, y, z) == block)
|
|
||||||
{
|
|
||||||
Block verticalOrigin = world.getBlock(x, y - block.densityDir, z);
|
|
||||||
if (verticalOrigin.getMaterial().isLiquid() || verticalOrigin instanceof IFluidBlock)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (world.getBlockMetadata(x, y, z) == block.getMaxRenderHeightMeta())
|
|
||||||
{
|
|
||||||
return 0.875F;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !world.getBlock(x, y, z).getMaterial().isSolid() && world.getBlock(x, y - block.densityDir, z) == block ? 1 : block.getQuantaPercentage(world, x, y, z) * 0.875F;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ISimpleBlockRenderingHandler * /
|
|
||||||
@Override
|
|
||||||
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer){}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
|
|
||||||
{
|
|
||||||
if (!(block instanceof BlockFluidBase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tessellator tessellator = Tessellator.instance;
|
|
||||||
int color = block.colorMultiplier(world, x, y, z);
|
|
||||||
float red = (color >> 16 & 255) / 255.0F;
|
|
||||||
float green = (color >> 8 & 255) / 255.0F;
|
|
||||||
float blue = (color & 255) / 255.0F;
|
|
||||||
|
|
||||||
BlockFluidBase theFluid = (BlockFluidBase) block;
|
|
||||||
int bMeta = world.getBlockMetadata(x, y, z);
|
|
||||||
|
|
||||||
boolean renderTop = world.getBlock(x, y - theFluid.densityDir, z) != theFluid;
|
|
||||||
|
|
||||||
boolean renderBottom = block.shouldSideBeRendered(world, x, y + theFluid.densityDir, z, 0) && world.getBlock(x, y + theFluid.densityDir, z) != theFluid;
|
|
||||||
|
|
||||||
boolean[] renderSides = new boolean[]
|
|
||||||
{
|
|
||||||
block.shouldSideBeRendered(world, x, y, z - 1, 2),
|
|
||||||
block.shouldSideBeRendered(world, x, y, z + 1, 3),
|
|
||||||
block.shouldSideBeRendered(world, x - 1, y, z, 4),
|
|
||||||
block.shouldSideBeRendered(world, x + 1, y, z, 5)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!renderTop && !renderBottom && !renderSides[0] && !renderSides[1] && !renderSides[2] && !renderSides[3])
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
boolean rendered = false;
|
|
||||||
double heightNW, heightSW, heightSE, heightNE;
|
|
||||||
float flow11 = getFluidHeightForRender(world, x, y, z, theFluid);
|
|
||||||
|
|
||||||
if (flow11 != 1)
|
|
||||||
{
|
|
||||||
float flow00 = getFluidHeightForRender(world, x - 1, y, z - 1, theFluid);
|
|
||||||
float flow01 = getFluidHeightForRender(world, x - 1, y, z, theFluid);
|
|
||||||
float flow02 = getFluidHeightForRender(world, x - 1, y, z + 1, theFluid);
|
|
||||||
float flow10 = getFluidHeightForRender(world, x, y, z - 1, theFluid);
|
|
||||||
float flow12 = getFluidHeightForRender(world, x, y, z + 1, theFluid);
|
|
||||||
float flow20 = getFluidHeightForRender(world, x + 1, y, z - 1, theFluid);
|
|
||||||
float flow21 = getFluidHeightForRender(world, x + 1, y, z, theFluid);
|
|
||||||
float flow22 = getFluidHeightForRender(world, x + 1, y, z + 1, theFluid);
|
|
||||||
|
|
||||||
heightNW = getFluidHeightAverage(new float[]{ flow00, flow01, flow10, flow11 });
|
|
||||||
heightSW = getFluidHeightAverage(new float[]{ flow01, flow02, flow12, flow11 });
|
|
||||||
heightSE = getFluidHeightAverage(new float[]{ flow12, flow21, flow22, flow11 });
|
|
||||||
heightNE = getFluidHeightAverage(new float[]{ flow10, flow20, flow21, flow11 });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
heightNW = flow11;
|
|
||||||
heightSW = flow11;
|
|
||||||
heightSE = flow11;
|
|
||||||
heightNE = flow11;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean rises = theFluid.densityDir == 1;
|
|
||||||
if (renderer.renderAllFaces || renderTop)
|
|
||||||
{
|
|
||||||
rendered = true;
|
|
||||||
IIcon iconStill = getIcon(block.getIcon(1, bMeta));
|
|
||||||
float flowDir = (float) BlockFluidBase.getFlowDirection(world, x, y, z);
|
|
||||||
|
|
||||||
if (flowDir > -999.0F)
|
|
||||||
{
|
|
||||||
iconStill = getIcon(block.getIcon(2, bMeta));
|
|
||||||
}
|
|
||||||
|
|
||||||
heightNW -= RENDER_OFFSET;
|
|
||||||
heightSW -= RENDER_OFFSET;
|
|
||||||
heightSE -= RENDER_OFFSET;
|
|
||||||
heightNE -= RENDER_OFFSET;
|
|
||||||
|
|
||||||
double u1, u2, u3, u4, v1, v2, v3, v4;
|
|
||||||
|
|
||||||
if (flowDir < -999.0F)
|
|
||||||
{
|
|
||||||
u2 = iconStill.getInterpolatedU(0.0D);
|
|
||||||
v2 = iconStill.getInterpolatedV(0.0D);
|
|
||||||
u1 = u2;
|
|
||||||
v1 = iconStill.getInterpolatedV(16.0D);
|
|
||||||
u4 = iconStill.getInterpolatedU(16.0D);
|
|
||||||
v4 = v1;
|
|
||||||
u3 = u4;
|
|
||||||
v3 = v2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float xFlow = MathHelper.sin(flowDir) * 0.25F;
|
|
||||||
float zFlow = MathHelper.cos(flowDir) * 0.25F;
|
|
||||||
u2 = iconStill.getInterpolatedU(8.0F + (-zFlow - xFlow) * 16.0F);
|
|
||||||
v2 = iconStill.getInterpolatedV(8.0F + (-zFlow + xFlow) * 16.0F);
|
|
||||||
u1 = iconStill.getInterpolatedU(8.0F + (-zFlow + xFlow) * 16.0F);
|
|
||||||
v1 = iconStill.getInterpolatedV(8.0F + (zFlow + xFlow) * 16.0F);
|
|
||||||
u4 = iconStill.getInterpolatedU(8.0F + (zFlow + xFlow) * 16.0F);
|
|
||||||
v4 = iconStill.getInterpolatedV(8.0F + (zFlow - xFlow) * 16.0F);
|
|
||||||
u3 = iconStill.getInterpolatedU(8.0F + (zFlow - xFlow) * 16.0F);
|
|
||||||
v3 = iconStill.getInterpolatedV(8.0F + (-zFlow - xFlow) * 16.0F);
|
|
||||||
}
|
|
||||||
|
|
||||||
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z));
|
|
||||||
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
|
|
||||||
|
|
||||||
if (!rises)
|
|
||||||
{
|
|
||||||
tessellator.addVertexWithUV(x + 0, y + heightNW, z + 0, u2, v2);
|
|
||||||
tessellator.addVertexWithUV(x + 0, y + heightSW, z + 1, u1, v1);
|
|
||||||
tessellator.addVertexWithUV(x + 1, y + heightSE, z + 1, u4, v4);
|
|
||||||
tessellator.addVertexWithUV(x + 1, y + heightNE, z + 0, u3, v3);
|
|
||||||
|
|
||||||
tessellator.addVertexWithUV(x + 0, y + heightNW, z + 0, u2, v2);
|
|
||||||
tessellator.addVertexWithUV(x + 1, y + heightNE, z + 0, u3, v3);
|
|
||||||
tessellator.addVertexWithUV(x + 1, y + heightSE, z + 1, u4, v4);
|
|
||||||
tessellator.addVertexWithUV(x + 0, y + heightSW, z + 1, u1, v1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tessellator.addVertexWithUV(x + 1, y + 1 - heightNE, z + 0, u3, v3);
|
|
||||||
tessellator.addVertexWithUV(x + 1, y + 1 - heightSE, z + 1, u4, v4);
|
|
||||||
tessellator.addVertexWithUV(x + 0, y + 1 - heightSW, z + 1, u1, v1);
|
|
||||||
tessellator.addVertexWithUV(x + 0, y + 1 - heightNW, z + 0, u2, v2);
|
|
||||||
|
|
||||||
tessellator.addVertexWithUV(x + 1, y + 1 - heightNE, z + 0, u3, v3);
|
|
||||||
tessellator.addVertexWithUV(x + 0, y + 1 - heightNW, z + 0, u2, v2);
|
|
||||||
tessellator.addVertexWithUV(x + 0, y + 1 - heightSW, z + 1, u1, v1);
|
|
||||||
tessellator.addVertexWithUV(x + 1, y + 1 - heightSE, z + 1, u4, v4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderer.renderAllFaces || renderBottom)
|
|
||||||
{
|
|
||||||
rendered = true;
|
|
||||||
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y - 1, z));
|
|
||||||
if (!rises)
|
|
||||||
{
|
|
||||||
tessellator.setColorOpaque_F(LIGHT_Y_NEG * red, LIGHT_Y_NEG * green, LIGHT_Y_NEG * blue);
|
|
||||||
renderer.renderFaceYNeg(block, x, y + RENDER_OFFSET, z, getIcon(block.getIcon(0, bMeta)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
|
|
||||||
renderer.renderFaceYPos(block, x, y + RENDER_OFFSET, z, getIcon(block.getIcon(1, bMeta)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int side = 0; side < 4; ++side)
|
|
||||||
{
|
|
||||||
int x2 = x;
|
|
||||||
int z2 = z;
|
|
||||||
|
|
||||||
switch (side)
|
|
||||||
{
|
|
||||||
case 0: --z2; break;
|
|
||||||
case 1: ++z2; break;
|
|
||||||
case 2: --x2; break;
|
|
||||||
case 3: ++x2; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
IIcon iconFlow = getIcon(block.getIcon(side + 2, bMeta));
|
|
||||||
if (renderer.renderAllFaces || renderSides[side])
|
|
||||||
{
|
|
||||||
rendered = true;
|
|
||||||
|
|
||||||
double ty1;
|
|
||||||
double tx1;
|
|
||||||
double ty2;
|
|
||||||
double tx2;
|
|
||||||
double tz1;
|
|
||||||
double tz2;
|
|
||||||
|
|
||||||
if (side == 0)
|
|
||||||
{
|
|
||||||
ty1 = heightNW;
|
|
||||||
ty2 = heightNE;
|
|
||||||
tx1 = x;
|
|
||||||
tx2 = x + 1;
|
|
||||||
tz1 = z + RENDER_OFFSET;
|
|
||||||
tz2 = z + RENDER_OFFSET;
|
|
||||||
}
|
|
||||||
else if (side == 1)
|
|
||||||
{
|
|
||||||
ty1 = heightSE;
|
|
||||||
ty2 = heightSW;
|
|
||||||
tx1 = x + 1;
|
|
||||||
tx2 = x;
|
|
||||||
tz1 = z + 1 - RENDER_OFFSET;
|
|
||||||
tz2 = z + 1 - RENDER_OFFSET;
|
|
||||||
}
|
|
||||||
else if (side == 2)
|
|
||||||
{
|
|
||||||
ty1 = heightSW;
|
|
||||||
ty2 = heightNW;
|
|
||||||
tx1 = x + RENDER_OFFSET;
|
|
||||||
tx2 = x + RENDER_OFFSET;
|
|
||||||
tz1 = z + 1;
|
|
||||||
tz2 = z;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ty1 = heightNE;
|
|
||||||
ty2 = heightSE;
|
|
||||||
tx1 = x + 1 - RENDER_OFFSET;
|
|
||||||
tx2 = x + 1 - RENDER_OFFSET;
|
|
||||||
tz1 = z;
|
|
||||||
tz2 = z + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
float u1Flow = iconFlow.getInterpolatedU(0.0D);
|
|
||||||
float u2Flow = iconFlow.getInterpolatedU(8.0D);
|
|
||||||
float v1Flow = iconFlow.getInterpolatedV((1.0D - ty1) * 16.0D * 0.5D);
|
|
||||||
float v2Flow = iconFlow.getInterpolatedV((1.0D - ty2) * 16.0D * 0.5D);
|
|
||||||
float v3Flow = iconFlow.getInterpolatedV(8.0D);
|
|
||||||
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x2, y, z2));
|
|
||||||
float sideLighting = 1.0F;
|
|
||||||
|
|
||||||
if (side < 2)
|
|
||||||
{
|
|
||||||
sideLighting = LIGHT_XZ_NEG;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sideLighting = LIGHT_XZ_POS;
|
|
||||||
}
|
|
||||||
|
|
||||||
tessellator.setColorOpaque_F(LIGHT_Y_POS * sideLighting * red, LIGHT_Y_POS * sideLighting * green, LIGHT_Y_POS * sideLighting * blue);
|
|
||||||
|
|
||||||
if (!rises)
|
|
||||||
{
|
|
||||||
tessellator.addVertexWithUV(tx1, y + ty1, tz1, u1Flow, v1Flow);
|
|
||||||
tessellator.addVertexWithUV(tx2, y + ty2, tz2, u2Flow, v2Flow);
|
|
||||||
tessellator.addVertexWithUV(tx2, y + 0, tz2, u2Flow, v3Flow);
|
|
||||||
tessellator.addVertexWithUV(tx1, y + 0, tz1, u1Flow, v3Flow);
|
|
||||||
|
|
||||||
tessellator.addVertexWithUV(tx1, y + ty1, tz1, u1Flow, v1Flow);
|
|
||||||
tessellator.addVertexWithUV(tx1, y + 0, tz1, u1Flow, v3Flow);
|
|
||||||
tessellator.addVertexWithUV(tx2, y + 0, tz2, u2Flow, v3Flow);
|
|
||||||
tessellator.addVertexWithUV(tx2, y + ty2, tz2, u2Flow, v2Flow);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tessellator.addVertexWithUV(tx1, y + 1 - 0, tz1, u1Flow, v3Flow);
|
|
||||||
tessellator.addVertexWithUV(tx2, y + 1 - 0, tz2, u2Flow, v3Flow);
|
|
||||||
tessellator.addVertexWithUV(tx2, y + 1 - ty2, tz2, u2Flow, v2Flow);
|
|
||||||
tessellator.addVertexWithUV(tx1, y + 1 - ty1, tz1, u1Flow, v1Flow);
|
|
||||||
|
|
||||||
tessellator.addVertexWithUV(tx1, y + 1 - 0, tz1, u1Flow, v3Flow);
|
|
||||||
tessellator.addVertexWithUV(tx1, y + 1 - ty1, tz1, u1Flow, v1Flow);
|
|
||||||
tessellator.addVertexWithUV(tx2, y + 1 - ty2, tz2, u2Flow, v2Flow);
|
|
||||||
tessellator.addVertexWithUV(tx2, y + 1 - 0, tz2, u2Flow, v3Flow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
renderer.renderMinY = 0;
|
|
||||||
renderer.renderMaxY = 1;
|
|
||||||
return rendered;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldRender3DInInventory(int modelId){ return false; }
|
|
||||||
@Override
|
|
||||||
public int getRenderId()
|
|
||||||
{
|
|
||||||
return FluidRegistry.renderIdFluid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private IIcon getIcon(IIcon icon)
|
|
||||||
{
|
|
||||||
if (icon != null) return icon;
|
|
||||||
return ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).getAtlasSprite("missingno");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
package net.minecraftforge.debug;
|
||||||
|
|
||||||
|
import net.minecraft.block.material.Material;
|
||||||
|
import net.minecraft.block.properties.IProperty;
|
||||||
|
import net.minecraft.block.state.BlockState;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.renderer.ItemMeshDefinition;
|
||||||
|
import net.minecraft.client.renderer.block.statemap.StateMapperBase;
|
||||||
|
import net.minecraft.client.resources.model.ModelBakery;
|
||||||
|
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||||
|
import net.minecraft.creativetab.CreativeTabs;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.client.model.ModelFluid;
|
||||||
|
import net.minecraftforge.client.model.ModelLoader;
|
||||||
|
import net.minecraftforge.common.property.ExtendedBlockState;
|
||||||
|
import net.minecraftforge.fluids.BlockFluidClassic;
|
||||||
|
import net.minecraftforge.fluids.Fluid;
|
||||||
|
import net.minecraftforge.fluids.FluidRegistry;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||||
|
import net.minecraftforge.fml.common.SidedProxy;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||||
|
|
||||||
|
@Mod(modid = ModelFluidDebug.MODID, version = ModelFluidDebug.VERSION)
|
||||||
|
public class ModelFluidDebug
|
||||||
|
{
|
||||||
|
public static final String MODID = "ForgeDebugModelFluid";
|
||||||
|
public static final String VERSION = "1.0";
|
||||||
|
|
||||||
|
@SidedProxy(serverSide = "net.minecraftforge.debug.ModelFluidDebug$CommonProxy", clientSide = "net.minecraftforge.debug.ModelFluidDebug$ClientProxy")
|
||||||
|
public static CommonProxy proxy;
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void preInit(FMLPreInitializationEvent event) { proxy.preInit(event); }
|
||||||
|
|
||||||
|
public static class CommonProxy
|
||||||
|
{
|
||||||
|
public void preInit(FMLPreInitializationEvent event)
|
||||||
|
{
|
||||||
|
FluidRegistry.registerFluid(TestFluid.instance);
|
||||||
|
FluidRegistry.registerFluid(TestGas.instance);
|
||||||
|
GameRegistry.registerBlock(TestFluidBlock.instance, TestFluidBlock.name);
|
||||||
|
GameRegistry.registerBlock(TestGasBlock.instance, TestGasBlock.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ClientProxy extends CommonProxy
|
||||||
|
{
|
||||||
|
private static ModelResourceLocation fluidLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + TestFluidBlock.name, "fluid");
|
||||||
|
private static ModelResourceLocation gasLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + TestFluidBlock.name, "gas");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preInit(FMLPreInitializationEvent event)
|
||||||
|
{
|
||||||
|
super.preInit(event);
|
||||||
|
Item fluid = Item.getItemFromBlock(TestFluidBlock.instance);
|
||||||
|
Item gas = Item.getItemFromBlock(TestGasBlock.instance);
|
||||||
|
ModelBakery.addVariantName(fluid);
|
||||||
|
ModelBakery.addVariantName(gas);
|
||||||
|
ModelLoader.setCustomMeshDefinition(fluid, new ItemMeshDefinition()
|
||||||
|
{
|
||||||
|
public ModelResourceLocation getModelLocation(ItemStack stack)
|
||||||
|
{
|
||||||
|
return fluidLocation;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ModelLoader.setCustomMeshDefinition(gas, new ItemMeshDefinition()
|
||||||
|
{
|
||||||
|
public ModelResourceLocation getModelLocation(ItemStack stack)
|
||||||
|
{
|
||||||
|
return gasLocation;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ModelLoader.setCustomStateMapper(TestFluidBlock.instance, new StateMapperBase()
|
||||||
|
{
|
||||||
|
protected ModelResourceLocation getModelResourceLocation(IBlockState state)
|
||||||
|
{
|
||||||
|
return fluidLocation;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ModelLoader.setCustomStateMapper(TestGasBlock.instance, new StateMapperBase()
|
||||||
|
{
|
||||||
|
protected ModelResourceLocation getModelResourceLocation(IBlockState state)
|
||||||
|
{
|
||||||
|
return gasLocation;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class TestFluid extends Fluid
|
||||||
|
{
|
||||||
|
public static final String name = "testfluid";
|
||||||
|
public static final TestFluid instance = new TestFluid();
|
||||||
|
|
||||||
|
private TestFluid()
|
||||||
|
{
|
||||||
|
super(name, new ResourceLocation("blocks/water_still"), new ResourceLocation("blocks/water_flow"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColor()
|
||||||
|
{
|
||||||
|
return 0xFF00FF00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class TestGas extends Fluid
|
||||||
|
{
|
||||||
|
public static final String name = "testgas";
|
||||||
|
public static final TestGas instance = new TestGas();
|
||||||
|
|
||||||
|
private TestGas()
|
||||||
|
{
|
||||||
|
super(name, new ResourceLocation("blocks/lava_still"), new ResourceLocation("blocks/lava_flow"));
|
||||||
|
density = -1000;
|
||||||
|
isGaseous = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColor()
|
||||||
|
{
|
||||||
|
return 0xFFFF0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class TestFluidBlock extends BlockFluidClassic
|
||||||
|
{
|
||||||
|
public static final TestFluidBlock instance = new TestFluidBlock();
|
||||||
|
public static final String name = "TestFluidBlock";
|
||||||
|
|
||||||
|
private TestFluidBlock()
|
||||||
|
{
|
||||||
|
super(TestFluid.instance, Material.water);
|
||||||
|
setCreativeTab(CreativeTabs.tabBlock);
|
||||||
|
setUnlocalizedName(MODID + ":" + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class TestGasBlock extends BlockFluidClassic
|
||||||
|
{
|
||||||
|
public static final TestGasBlock instance = new TestGasBlock();
|
||||||
|
public static final String name = "TestGasBlock";
|
||||||
|
|
||||||
|
private TestGasBlock()
|
||||||
|
{
|
||||||
|
super(TestGas.instance, Material.lava);
|
||||||
|
setCreativeTab(CreativeTabs.tabBlock);
|
||||||
|
setUnlocalizedName(MODID + ":" + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"forge_marker": 1,
|
||||||
|
"variants": {
|
||||||
|
"fluid": {
|
||||||
|
"model": "forge:fluid",
|
||||||
|
"custom": { "fluid": "testfluid" }
|
||||||
|
},
|
||||||
|
"gas": {
|
||||||
|
"model": "forge:fluid",
|
||||||
|
"custom": { "fluid": "testgas" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue