Major refactoring
Added cactus and lilypads
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package mods.betterfoliage.client.render;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.IIcon;
|
||||
|
||||
/** Same as {@link RenderBlockAOBase}, but does not actually render anything.
|
||||
* @author octarine-noise
|
||||
*/
|
||||
public class FakeRenderBlockAOBase extends RenderBlockAOBase {
|
||||
|
||||
@Override
|
||||
public void renderFaceZNeg(Block block, double x, double y, double z, IIcon icon) {
|
||||
saveShadingTopLeft(aoZNXYPP);
|
||||
saveShadingTopRight(aoZNXYNP);
|
||||
saveShadingBottomLeft(aoZNXYPN);
|
||||
saveShadingBottomRight(aoZNXYNN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaceZPos(Block block, double x, double y, double z, IIcon icon) {
|
||||
saveShadingTopLeft(aoZPXYNP);
|
||||
saveShadingTopRight(aoZPXYPP);
|
||||
saveShadingBottomLeft(aoZPXYNN);
|
||||
saveShadingBottomRight(aoZPXYPN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaceXNeg(Block block, double x, double y, double z, IIcon icon) {
|
||||
saveShadingTopLeft(aoXNYZPN);
|
||||
saveShadingTopRight(aoXNYZPP);
|
||||
saveShadingBottomLeft(aoXNYZNN);
|
||||
saveShadingBottomRight(aoXNYZNP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaceXPos(Block block, double x, double y, double z, IIcon icon) {
|
||||
saveShadingTopLeft(aoXPYZPP);
|
||||
saveShadingTopRight(aoXPYZPN);
|
||||
saveShadingBottomLeft(aoXPYZNP);
|
||||
saveShadingBottomRight(aoXPYZNN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaceYNeg(Block block, double x, double y, double z, IIcon icon) {
|
||||
saveShadingTopLeft(aoYNXZNP);
|
||||
saveShadingTopRight(aoYNXZPP);
|
||||
saveShadingBottomLeft(aoYNXZNN);
|
||||
saveShadingBottomRight(aoYNXZPN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaceYPos(Block block, double x, double y, double z, IIcon icon) {
|
||||
saveShadingTopLeft(aoYPXZPP);
|
||||
saveShadingTopRight(aoYPXZNP);
|
||||
saveShadingBottomLeft(aoYPXZPN);
|
||||
saveShadingBottomRight(aoYPXZNN);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package mods.betterfoliage.client.render;
|
||||
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
public interface IRenderBlockDecorator extends ISimpleBlockRenderingHandler {
|
||||
|
||||
public void init();
|
||||
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original);
|
||||
|
||||
}
|
||||
@@ -7,11 +7,13 @@ import java.util.List;
|
||||
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
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.init.Blocks;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@@ -40,6 +42,9 @@ public class RenderBlockAOBase extends RenderBlocks {
|
||||
protected double[] uValues = new double[] {0.0, 16.0, 16.0, 0.0};
|
||||
protected double[] vValues = new double[] {0.0, 0.0, 16.0, 16.0};
|
||||
|
||||
protected ForgeDirection[] faceDir1 = new ForgeDirection[] {ForgeDirection.WEST, ForgeDirection.WEST, ForgeDirection.WEST, ForgeDirection.EAST, ForgeDirection.SOUTH, ForgeDirection.NORTH};
|
||||
protected ForgeDirection[] faceDir2 = new ForgeDirection[] {ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.UP, ForgeDirection.UP, ForgeDirection.UP, ForgeDirection.UP};
|
||||
|
||||
/** Random vector pool. Unit rotation vectors in the XZ plane, Y coord goes between [-1.0, 1.0].
|
||||
* Filled at init time */
|
||||
public Double3[] pRot = new Double3[64];
|
||||
@@ -71,6 +76,9 @@ public class RenderBlockAOBase extends RenderBlocks {
|
||||
public ShadingValues aoZNXYPN = new ShadingValues();
|
||||
public ShadingValues aoZNXYNP = new ShadingValues();
|
||||
public ShadingValues aoZNXYNN = new ShadingValues();
|
||||
|
||||
// temporary shading values for a single face
|
||||
public ShadingValues faceAOPP, faceAOPN, faceAONN, faceAONP;
|
||||
|
||||
/** Initialize random values */
|
||||
public void init() {
|
||||
@@ -93,8 +101,24 @@ public class RenderBlockAOBase extends RenderBlocks {
|
||||
* @return semirandom value
|
||||
*/
|
||||
protected int getSemiRandomFromPos(double x, double y, double z, int seed) {
|
||||
int sum = MathHelper.floor_double(x) * 3 + MathHelper.floor_double(y) * 5 + MathHelper.floor_double(z) * 7 + seed * 11;
|
||||
return sum & 63;
|
||||
long lx = MathHelper.floor_double(x);
|
||||
long ly = MathHelper.floor_double(y);
|
||||
long lz = MathHelper.floor_double(z);
|
||||
long value = (lx * lx + ly * ly + lz * lz + lx * ly + ly * lz + lz * lx) & 63;
|
||||
value = (3 * lx * value + 5 * ly * value + 7 * lz * value) & 63;
|
||||
return (int) value;
|
||||
}
|
||||
|
||||
public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) {
|
||||
renderStandardBlockAsItem(renderer, block, metadata, 1.0f);
|
||||
}
|
||||
|
||||
public boolean shouldRender3DInInventory(int modelId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getRenderId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void renderStandardBlockAsItem(RenderBlocks renderer, Block p_147800_1_, int p_147800_2_, float p_147800_3_) {
|
||||
@@ -152,6 +176,101 @@ public class RenderBlockAOBase extends RenderBlocks {
|
||||
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
|
||||
}
|
||||
|
||||
protected void setShadingForFace(ForgeDirection dir) {
|
||||
if (dir == ForgeDirection.DOWN) {
|
||||
// dir1 WEST, dir2 NORTH
|
||||
faceAOPP = aoYNXZPP; faceAOPN = aoYNXZPN; faceAONN = aoYNXZNN; faceAONP = aoYNXZNP;
|
||||
} else if (dir == ForgeDirection.UP) {
|
||||
// dir1 WEST, dir2 SOUTH
|
||||
faceAOPP = aoYPXZPP; faceAOPN = aoYPXZPN; faceAONN = aoYPXZNN; faceAONP = aoYPXZNP;
|
||||
} else if (dir == ForgeDirection.NORTH) {
|
||||
// dir1 WEST, dir2 UP
|
||||
faceAOPP = aoZNXYNP; faceAOPN = aoZNXYNN; faceAONN = aoZNXYPN; faceAONP = aoZNXYPP;
|
||||
} else if (dir == ForgeDirection.SOUTH) {
|
||||
// dir1 EAST, dir2 UP
|
||||
faceAOPP = aoZPXYPP; faceAOPN = aoZPXYPN; faceAONN = aoZPXYNN; faceAONP = aoZPXYNP;
|
||||
} else if (dir == ForgeDirection.WEST) {
|
||||
// dir1 SOUTH, dir2 UP
|
||||
faceAOPP = aoXNYZPP; faceAOPN = aoXNYZNP; faceAONN = aoXNYZNN; faceAONP = aoXNYZPN;
|
||||
} else if (dir == ForgeDirection.EAST) {
|
||||
// dir1 NORTH, dir2 UP
|
||||
faceAOPP = aoXPYZPN; faceAOPN = aoXPYZNN; faceAONN = aoXPYZNP; faceAONP = aoXPYZPP;
|
||||
}
|
||||
}
|
||||
|
||||
public void renderCrossedSideQuads(Double3 drawBase, ForgeDirection dir, double scale, double halfHeight, Double3 rendomVec, double offset, IIcon renderIcon, int uvRot, boolean noShading) {
|
||||
Double3 facePP, faceNP, faceNormal, drawCenter;
|
||||
|
||||
if (dir == ForgeDirection.UP) {
|
||||
// special case for block top, we'll be rendering a LOT of those
|
||||
facePP = new Double3(-scale, 0.0, scale);
|
||||
faceNP = new Double3(scale, 0.0, scale);
|
||||
faceNormal = new Double3(0.0, halfHeight, 0.0);
|
||||
drawCenter = drawBase.add(faceNormal);
|
||||
if (rendomVec != null) {
|
||||
drawCenter = drawBase.add(faceNormal).add(rendomVec.scaleAxes(-offset, 0.0, offset));
|
||||
}
|
||||
} else {
|
||||
facePP = new Double3(faceDir1[dir.ordinal()]).add(new Double3(faceDir2[dir.ordinal()])).scale(scale);
|
||||
faceNP = new Double3(faceDir1[dir.ordinal()]).inverse().add(new Double3(faceDir2[dir.ordinal()])).scale(scale);
|
||||
faceNormal = new Double3(dir).scale(halfHeight);
|
||||
drawCenter = drawBase.add(faceNormal);
|
||||
if (rendomVec != null) {
|
||||
drawCenter = drawCenter.add(new Double3(faceDir1[dir.ordinal()]).scale(rendomVec.x).scale(offset))
|
||||
.add(new Double3(faceDir2[dir.ordinal()]).scale(rendomVec.z).scale(offset));
|
||||
}
|
||||
}
|
||||
|
||||
if (Minecraft.isAmbientOcclusionEnabled() && !noShading) {
|
||||
setShadingForFace(dir);
|
||||
renderQuadWithShading(renderIcon, drawCenter, facePP, faceNormal, uvRot, faceAOPP, faceAONN, faceAONN, faceAOPP);
|
||||
renderQuadWithShading(renderIcon, drawCenter, facePP.inverse(), faceNormal, uvRot, faceAONN, faceAOPP, faceAOPP, faceAONN);
|
||||
renderQuadWithShading(renderIcon, drawCenter, faceNP, faceNormal, uvRot, faceAONP, faceAOPN, faceAOPN, faceAONP);
|
||||
renderQuadWithShading(renderIcon, drawCenter, faceNP.inverse(), faceNormal, uvRot, faceAOPN, faceAONP, faceAONP, faceAOPN);
|
||||
} else {
|
||||
renderQuad(renderIcon, drawCenter, facePP, faceNormal, uvRot);
|
||||
renderQuad(renderIcon, drawCenter, facePP.inverse(), faceNormal, uvRot);
|
||||
renderQuad(renderIcon, drawCenter, faceNP, faceNormal, uvRot);
|
||||
renderQuad(renderIcon, drawCenter, faceNP.inverse(), faceNormal, uvRot);
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderCrossedBlockQuadsTranslate(Double3 blockCenter, double halfSize, Double3 offsetVec, IIcon crossLeafIcon, int uvRot, boolean isAirTop, boolean isAirBottom) {
|
||||
Double3 drawCenter = blockCenter;
|
||||
if (offsetVec != null) drawCenter = drawCenter.add(offsetVec);
|
||||
Double3 horz1 = new Double3(halfSize, 0.0, halfSize);
|
||||
Double3 horz2 = new Double3(halfSize, 0.0, -halfSize);
|
||||
Double3 vert1 = new Double3(0.0, halfSize * 1.41, 0.0);
|
||||
|
||||
renderCrossedBlockQuadsInternal(drawCenter, horz1, horz2, vert1, crossLeafIcon, uvRot, isAirTop, isAirBottom);
|
||||
}
|
||||
|
||||
protected void renderCrossedBlockQuadsSkew(Double3 blockCenter, double halfSize, Double3 offsetVec1, Double3 offsetVec2, IIcon crossLeafIcon, int uvRot, boolean isAirTop, boolean isAirBottom) {
|
||||
Double3 horz1 = new Double3(halfSize, 0.0, halfSize).add(offsetVec1);
|
||||
Double3 horz2 = new Double3(halfSize, 0.0, -halfSize).add(offsetVec2);
|
||||
Double3 vert1 = new Double3(0.0, halfSize * 1.41, 0.0);
|
||||
|
||||
renderCrossedBlockQuadsInternal(blockCenter, horz1, horz2, vert1, crossLeafIcon, uvRot, isAirTop, isAirBottom);
|
||||
}
|
||||
|
||||
private void renderCrossedBlockQuadsInternal(Double3 drawCenter, Double3 horz1, Double3 horz2, Double3 vert1, IIcon crossLeafIcon, int uvRot, boolean isAirTop, boolean isAirBottom) {
|
||||
if (Minecraft.isAmbientOcclusionEnabled()) {
|
||||
renderQuadWithShading(crossLeafIcon, drawCenter, horz1, vert1, uvRot,
|
||||
isAirTop ? aoYPXZPP : aoZPXYPP, isAirTop ? aoYPXZNN : aoXNYZPN, isAirBottom ? aoYNXZNN : aoXNYZNN, isAirBottom ? aoYNXZPP : aoZPXYPN);
|
||||
renderQuadWithShading(crossLeafIcon, drawCenter, horz1.inverse(), vert1, uvRot,
|
||||
isAirTop ? aoYPXZNN : aoZNXYNP, isAirTop ? aoYPXZPP : aoXPYZPP, isAirBottom ? aoYNXZPP : aoXPYZNP, isAirBottom ? aoYNXZNN : aoZNXYNN);
|
||||
renderQuadWithShading(crossLeafIcon, drawCenter, horz2, vert1, uvRot,
|
||||
isAirTop ? aoYPXZPN : aoXPYZPN, isAirTop ? aoYPXZNP : aoZPXYNP, isAirBottom ? aoYNXZNP : aoZPXYNN, isAirBottom ? aoYNXZPN : aoXPYZNN);
|
||||
renderQuadWithShading(crossLeafIcon, drawCenter, horz2.inverse(), vert1, uvRot,
|
||||
isAirTop ? aoYPXZNP : aoXNYZPP, isAirTop ? aoYPXZPN : aoZNXYPP, isAirBottom ? aoYNXZPN : aoZNXYPN, isAirBottom ? aoYNXZNP : aoXNYZNP);
|
||||
} else {
|
||||
renderQuad(crossLeafIcon, drawCenter, horz1, vert1, uvRot);
|
||||
renderQuad(crossLeafIcon, drawCenter, horz1.inverse(), vert1, uvRot);
|
||||
renderQuad(crossLeafIcon, drawCenter, horz2, vert1, uvRot);
|
||||
renderQuad(crossLeafIcon, drawCenter, horz2.inverse(), vert1, uvRot);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaceZNeg(Block block, double x, double y, double z, IIcon icon) {
|
||||
super.renderFaceZNeg(block, x, y, z, icon);
|
||||
@@ -206,9 +325,6 @@ public class RenderBlockAOBase extends RenderBlocks {
|
||||
saveShadingBottomRight(aoYPXZNN);
|
||||
}
|
||||
|
||||
/** Save AO values for top left vertex
|
||||
* @param values {@link ShadingValues} to store values in
|
||||
*/
|
||||
protected void saveShadingTopLeft(ShadingValues values) {
|
||||
if (--values.passCounter != 0) return;
|
||||
values.brightness = brightnessTopLeft;
|
||||
@@ -314,4 +430,8 @@ public class RenderBlockAOBase extends RenderBlocks {
|
||||
tessellator.setColorOpaque_F(aoPN.red, aoPN.green, aoPN.blue);
|
||||
tessellator.addVertexWithUV(center.x + vec1.x - vec2.x, center.y + vec1.y - vec2.y, center.z + vec1.z - vec2.z, icon.getInterpolatedU(uValues[(uvRot + 3) & 3]), icon.getInterpolatedV(vValues[(uvRot + 3) & 3]));
|
||||
}
|
||||
|
||||
protected int getBrightness(Block block, int x, int y, int z) {
|
||||
return block.getMixedBrightnessForBlock(blockAccess, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
package mods.betterfoliage.client.render;
|
||||
|
||||
import mods.betterfoliage.common.config.Config;
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
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.util.IIcon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderBlockBetterGrass extends RenderBlockAOBase implements ISimpleBlockRenderingHandler {
|
||||
|
||||
public IIcon grassIcons[] = new IIcon[2];
|
||||
|
||||
public static int register() {
|
||||
int result = RenderingRegistry.getNextAvailableRenderId();
|
||||
RenderBlockBetterGrass renderGrass = new RenderBlockBetterGrass();
|
||||
RenderingRegistry.registerBlockHandler(result, renderGrass);
|
||||
MinecraftForge.EVENT_BUS.register(renderGrass);
|
||||
renderGrass.init();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) {
|
||||
renderStandardBlockAsItem(renderer, block, metadata, 1.0f);
|
||||
}
|
||||
|
||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// render grass block
|
||||
setRenderBoundsFromBlock(block);
|
||||
setPassCounters(1);
|
||||
boolean result = renderStandardBlock(block, x, y, z);
|
||||
|
||||
if (y == 255 || !blockAccess.isAirBlock(x, y + 1, z)) return result;
|
||||
|
||||
int variation = getSemiRandomFromPos(x, y, z, 0);
|
||||
int heightVariation = getSemiRandomFromPos(x, y, z, 1);
|
||||
double halfSize = Config.grassSize.value * 0.5;
|
||||
double halfHeight = 0.5 * (Config.grassHeightMin.value + pRand[heightVariation] * (Config.grassHeightMax.value - Config.grassHeightMin.value));
|
||||
Double3 drawCenter = new Double3(x + 0.5, y + 1.0 + halfHeight, z + 0.5).add(pRot[variation].scaleAxes(Config.grassHOffset.value, 0.0, Config.grassHOffset.value));
|
||||
Double3 horz1 = new Double3(halfSize, 0.0, halfSize);
|
||||
Double3 horz2 = new Double3(halfSize, 0.0, -halfSize);
|
||||
Double3 vert1 = new Double3(0.0, halfHeight, 0.0);
|
||||
IIcon grassIcon = grassIcons[variation % 2];
|
||||
|
||||
if (Minecraft.isAmbientOcclusionEnabled()) {
|
||||
renderQuadWithShading(grassIcon, drawCenter, horz1, vert1, 0, aoYPXZPP, aoYPXZNN, aoYPXZNN, aoYPXZPP);
|
||||
renderQuadWithShading(grassIcon, drawCenter, horz1.inverse(), vert1, 0, aoYPXZNN, aoYPXZPP, aoYPXZPP, aoYPXZNN);
|
||||
renderQuadWithShading(grassIcon, drawCenter, horz2, vert1, 0, aoYPXZPN, aoYPXZNP, aoYPXZNP, aoYPXZPN);
|
||||
renderQuadWithShading(grassIcon, drawCenter, horz2.inverse(), vert1, 0, aoYPXZNP, aoYPXZPN, aoYPXZPN, aoYPXZNP);
|
||||
} else {
|
||||
Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(blockAccess, x, y + 1, z));
|
||||
renderQuad(grassIcon, drawCenter, horz1, vert1, 0);
|
||||
renderQuad(grassIcon, drawCenter, horz1.inverse(), vert1, 0);
|
||||
renderQuad(grassIcon, drawCenter, horz2, vert1, 0);
|
||||
renderQuad(grassIcon, drawCenter, horz2.inverse(), vert1, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean shouldRender3DInInventory(int modelId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getRenderId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
for (int idx = 0; idx < 2; idx++) {
|
||||
grassIcons[idx] = event.map.registerIcon(String.format("betterfoliage:grass_%d", idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package mods.betterfoliage.client.render;
|
||||
|
||||
import mods.betterfoliage.client.BetterFoliageClient;
|
||||
import mods.betterfoliage.common.config.Config;
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
import mods.betterfoliage.common.util.ReflectionUtil;
|
||||
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.TextureAtlasSprite;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderBlockBetterLeaves extends RenderBlockAOBase implements ISimpleBlockRenderingHandler {
|
||||
|
||||
public static int register() {
|
||||
int result = RenderingRegistry.getNextAvailableRenderId();
|
||||
RenderBlockBetterLeaves renderLeaves = new RenderBlockBetterLeaves();
|
||||
RenderingRegistry.registerBlockHandler(result, renderLeaves);
|
||||
renderLeaves.init();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) {
|
||||
renderStandardBlockAsItem(renderer, block, metadata, 1.0f);
|
||||
}
|
||||
|
||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// render leaves center
|
||||
setPassCounters(1);
|
||||
int origRenderType = block.getRenderType();
|
||||
boolean result;
|
||||
|
||||
setRenderBoundsFromBlock(block);
|
||||
if (origRenderType == 0) {
|
||||
result = renderStandardBlock(block, x, y, z);
|
||||
} else {
|
||||
ISimpleBlockRenderingHandler handler = ReflectionUtil.getRenderingHandler(origRenderType);
|
||||
result = handler.renderWorldBlock(world, x, y, z, block, origRenderType, this);
|
||||
}
|
||||
|
||||
if (isBlockSurrounded(x, y, z)) return result;
|
||||
|
||||
// find generated texture to render with, assume the
|
||||
// "true" texture of the block is the one on the north size
|
||||
TextureAtlasSprite blockLeafIcon = (TextureAtlasSprite) block.getIcon(world, x, y, z, ForgeDirection.NORTH.ordinal());
|
||||
IIcon crossLeafIcon = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(BetterFoliageClient.leafGenerator.domainName + ":" + blockLeafIcon.getIconName());
|
||||
if (crossLeafIcon == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int variation = getSemiRandomFromPos(x, y, z, 0);
|
||||
double halfSize = 0.5 * Config.leavesSize.value;
|
||||
boolean isAirTop = y == 255 || blockAccess.isAirBlock(x, y + 1, z);
|
||||
boolean isAirBottom = y == 0 || blockAccess.isAirBlock(x, y - 1, z);
|
||||
Double3 drawCenter = new Double3(x + 0.5, y + 0.5, z + 0.5);
|
||||
Double3 horz1 = new Double3(halfSize, 0.0, halfSize).add(pRot[variation].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value));
|
||||
Double3 horz2 = new Double3(halfSize, 0.0, -halfSize).add(pRot[(variation + 1) & 63].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value));
|
||||
Double3 vert1 = new Double3(0.0, halfSize * 1.41, 0.0);
|
||||
|
||||
if (Minecraft.isAmbientOcclusionEnabled()) {
|
||||
renderQuadWithShading(crossLeafIcon, drawCenter, horz1, vert1, variation,
|
||||
isAirTop ? aoYPXZPP : aoZPXYPP, isAirTop ? aoYPXZNN : aoXNYZPN, isAirBottom ? aoYNXZNN : aoXNYZNN, isAirBottom ? aoYNXZPP : aoZPXYPN);
|
||||
renderQuadWithShading(crossLeafIcon, drawCenter, horz1.inverse(), vert1, variation,
|
||||
isAirTop ? aoYPXZNN : aoZNXYNP, isAirTop ? aoYPXZPP : aoXPYZPP, isAirBottom ? aoYNXZPP : aoXPYZNP, isAirBottom ? aoYNXZNN : aoZNXYNN);
|
||||
renderQuadWithShading(crossLeafIcon, drawCenter, horz2, vert1, variation,
|
||||
isAirTop ? aoYPXZPN : aoXPYZPN, isAirTop ? aoYPXZNP : aoZPXYNP, isAirBottom ? aoYNXZNP : aoZPXYNN, isAirBottom ? aoYNXZPN : aoXPYZNN);
|
||||
renderQuadWithShading(crossLeafIcon, drawCenter, horz2.inverse(), vert1, variation,
|
||||
isAirTop ? aoYPXZNP : aoXNYZPP, isAirTop ? aoYPXZPN : aoZNXYPP, isAirBottom ? aoYNXZPN : aoZNXYPN, isAirBottom ? aoYNXZNP : aoXNYZNP);
|
||||
} else {
|
||||
if (isAirTop) Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(blockAccess, x, y + 1, z));
|
||||
else if (isAirBottom) Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(blockAccess, x, y - 1, z));
|
||||
else Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(blockAccess, x, y, z));
|
||||
|
||||
renderQuad(crossLeafIcon, drawCenter, horz1, vert1, variation);
|
||||
renderQuad(crossLeafIcon, drawCenter, horz1.inverse(), vert1, variation);
|
||||
renderQuad(crossLeafIcon, drawCenter, horz2, vert1, variation);
|
||||
renderQuad(crossLeafIcon, drawCenter, horz2.inverse(), vert1, variation);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean shouldRender3DInInventory(int modelId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getRenderId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected boolean isBlockSurrounded(int x, int y, int z) {
|
||||
if (blockAccess.isAirBlock(x + 1, y, z)) return false;
|
||||
if (blockAccess.isAirBlock(x - 1, y, z)) return false;
|
||||
if (blockAccess.isAirBlock(x, y, z + 1)) return false;
|
||||
if (blockAccess.isAirBlock(x, y, z - 1)) return false;
|
||||
if (y == 255 || blockAccess.isAirBlock(x, y + 1, z)) return false;
|
||||
if (y == 0 || blockAccess.isAirBlock(x, y - 1, z)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package mods.betterfoliage.client.render.impl;
|
||||
|
||||
import mods.betterfoliage.client.render.FakeRenderBlockAOBase;
|
||||
import mods.betterfoliage.client.render.IRenderBlockDecorator;
|
||||
import mods.betterfoliage.common.config.Config;
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
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.init.Blocks;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IRenderBlockDecorator {
|
||||
|
||||
public IIcon cactusRoundIcon;
|
||||
public IIcon cactusSideIcons[] = new IIcon[2];
|
||||
|
||||
public static ForgeDirection[] cactusDirections = new ForgeDirection[] { ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.EAST, ForgeDirection.WEST};
|
||||
public static double cactusRadius = 0.4375;
|
||||
|
||||
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) {
|
||||
return Config.cactusEnabled && block == Blocks.cactus;
|
||||
}
|
||||
|
||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// render cactus center
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
Double3 blockCenter = new Double3(x + 0.5, y + 0.5, z + 0.5);
|
||||
renderStandardBlock(block, x, y, z);
|
||||
Tessellator.instance.setBrightness(getBrightness(block,x, y, z));
|
||||
renderCactusCore(block.getBlockTextureFromSide(ForgeDirection.UP.ordinal()),
|
||||
block.getBlockTextureFromSide(ForgeDirection.NORTH.ordinal()),
|
||||
blockCenter, 0);
|
||||
|
||||
// render side growth
|
||||
ForgeDirection drawDirection = cactusDirections[getSemiRandomFromPos(x, y, z, 0) % 4];
|
||||
int iconVariation = getSemiRandomFromPos(x, y, z, 1);
|
||||
Double3 drawBase = blockCenter.add(new Double3(drawDirection).scale(cactusRadius));
|
||||
|
||||
Tessellator.instance.setBrightness(getBrightness(block, x, y, z));
|
||||
renderCrossedSideQuads(drawBase, drawDirection, 0.5, 0.5, pRot[iconVariation], 0.2, cactusSideIcons[iconVariation % 2], 0, false);
|
||||
renderCrossedBlockQuadsSkew(blockCenter, 0.65,
|
||||
pRot[iconVariation].scaleAxes(0.1, 0.0, 0.1),
|
||||
pRot[(iconVariation + 1) & 63].scaleAxes(0.1, 0.0, 0.1),
|
||||
cactusRoundIcon, iconVariation, false, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void renderCactusCore(IIcon topIcon, IIcon sideIcon, Double3 blockCenter, int sideUvRot) {
|
||||
if (Minecraft.isAmbientOcclusionEnabled()) {
|
||||
renderQuadWithShading(sideIcon, blockCenter.add(cactusRadius, 0.0, 0.0), new Double3(0.0, 0.0, -0.5), new Double3(0.0, 0.5, 0.0), sideUvRot, aoXPYZPN, aoXPYZPP, aoXPYZNP, aoXPYZNN);
|
||||
renderQuadWithShading(sideIcon, blockCenter.add(-cactusRadius, 0.0, 0.0), new Double3(0.0, 0.0, 0.5), new Double3(0.0, 0.5, 0.0), sideUvRot, aoXNYZPP, aoXNYZPN, aoXNYZNN, aoXNYZNP);
|
||||
renderQuadWithShading(sideIcon, blockCenter.add(0.0, 0.0, cactusRadius), new Double3(0.5, 0.0, 0.0), new Double3(0.0, 0.5, 0.0), sideUvRot, aoZPXYPP, aoZPXYNP, aoZPXYNN, aoZPXYPN);
|
||||
renderQuadWithShading(sideIcon, blockCenter.add(0.0, 0.0, -cactusRadius), new Double3(-0.5, 0.0, 0.0), new Double3(0.0, 0.5, 0.0), sideUvRot, aoZNXYNP, aoZNXYPP, aoZNXYPN, aoZNXYNN);
|
||||
renderQuadWithShading(topIcon, blockCenter.add(0.0, 0.5, 0.0), new Double3(-0.5, 0.0, 0.0), new Double3(0.0, 0.0, 0.5), 0, aoYPXZNP, aoYPXZPP, aoYPXZPN, aoYPXZNN);
|
||||
} else {
|
||||
renderQuad(sideIcon, blockCenter.add(cactusRadius, 0.0, 0.0), new Double3(0.0, 0.0, -0.5), new Double3(0.0, 0.5, 0.0), sideUvRot);
|
||||
renderQuad(sideIcon, blockCenter.add(-cactusRadius, 0.0, 0.0), new Double3(0.0, 0.0, 0.5), new Double3(0.0, 0.5, 0.0), sideUvRot);
|
||||
renderQuad(sideIcon, blockCenter.add(0.0, 0.0, cactusRadius), new Double3(0.5, 0.0, 0.0), new Double3(0.0, 0.5, 0.0), sideUvRot);
|
||||
renderQuad(sideIcon, blockCenter.add(0.0, 0.0, -cactusRadius), new Double3(-0.5, 0.0, 0.0), new Double3(0.0, 0.5, 0.0), sideUvRot);
|
||||
renderQuad(topIcon, blockCenter.add(0.0, 0.5, 0.0), new Double3(-0.5, 0.0, 0.0), new Double3(0.0, 0.0, 0.5), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
cactusRoundIcon = event.map.registerIcon("bettergrassandleaves:better_cactus");
|
||||
for (int idx = 0; idx < 2; idx++) cactusSideIcons[idx] = event.map.registerIcon("bettergrassandleaves:better_cactus_arm_" + Integer.toString(idx));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package mods.betterfoliage.client.render.impl;
|
||||
|
||||
import mods.betterfoliage.client.render.IRenderBlockDecorator;
|
||||
import mods.betterfoliage.client.render.RenderBlockAOBase;
|
||||
import mods.betterfoliage.common.config.Config;
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockGrass;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRenderBlockDecorator {
|
||||
|
||||
public IIcon grassIcons[] = new IIcon[5];
|
||||
public IIcon myceliumIcons[] = new IIcon[4];
|
||||
|
||||
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) {
|
||||
if (!Config.grassEnabled) return false;
|
||||
if (!((block instanceof BlockGrass || block == Blocks.mycelium))) return false;
|
||||
if (y == 255 || !blockAccess.isAirBlock(x, y + 1, z)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// render grass block
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
renderStandardBlock(block, x, y, z);
|
||||
|
||||
int variation = getSemiRandomFromPos(x, y, z, 0);
|
||||
int heightVariation = getSemiRandomFromPos(x, y, z, 1);
|
||||
|
||||
IIcon renderIcon = (block == Blocks.mycelium) ? myceliumIcons[variation % 4] : grassIcons[variation % 5];
|
||||
|
||||
double scale = Config.grassSize.value * 0.5;
|
||||
double halfHeight = 0.5 * (Config.grassHeightMin.value + pRand[heightVariation] * (Config.grassHeightMax.value - Config.grassHeightMin.value));
|
||||
Tessellator.instance.setBrightness(getBrightness(block, x, y + 1, z));
|
||||
renderCrossedSideQuads(new Double3(x + 0.5, y + 1.0, z + 0.5), ForgeDirection.UP, scale, halfHeight, pRot[variation], Config.grassHOffset.value, renderIcon, 0, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
for (int idx = 0; idx < 5; idx++) {
|
||||
grassIcons[idx] = event.map.registerIcon(String.format("bettergrassandleaves:better_grass_long_%d", idx));
|
||||
}
|
||||
for (int idx = 0; idx < 4; idx++) {
|
||||
myceliumIcons[idx] = event.map.registerIcon(String.format("bettergrassandleaves:better_mycel_%d", idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package mods.betterfoliage.client.render.impl;
|
||||
|
||||
import mods.betterfoliage.client.BetterFoliageClient;
|
||||
import mods.betterfoliage.client.render.IRenderBlockDecorator;
|
||||
import mods.betterfoliage.client.render.RenderBlockAOBase;
|
||||
import mods.betterfoliage.common.config.Config;
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
import mods.betterfoliage.common.util.ReflectionUtil;
|
||||
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.TextureAtlasSprite;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderBlockBetterLeaves extends RenderBlockAOBase implements IRenderBlockDecorator {
|
||||
|
||||
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) {
|
||||
if (!Config.leavesEnabled) return false;
|
||||
if (original > 0 && original < 42) return false;
|
||||
for (Class<?> clazz : BetterFoliageClient.blockLeavesClasses)
|
||||
if (clazz.isAssignableFrom(block.getClass()))
|
||||
return !isBlockSurrounded(blockAccess, x, y, z);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// render leaves center
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
if (block.getRenderType() == 0) {
|
||||
renderStandardBlock(block, x, y, z);
|
||||
} else {
|
||||
ISimpleBlockRenderingHandler handler = ReflectionUtil.getRenderingHandler(block.getRenderType());
|
||||
handler.renderWorldBlock(world, x, y, z, block, block.getRenderType(), this);
|
||||
}
|
||||
|
||||
// find generated texture to render with, assume the
|
||||
// "true" texture of the block is the one on the north size
|
||||
TextureAtlasSprite blockLeafIcon = (TextureAtlasSprite) block.getIcon(world, x, y, z, ForgeDirection.NORTH.ordinal());
|
||||
IIcon crossLeafIcon = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(BetterFoliageClient.leafGenerator.domainName + ":" + blockLeafIcon.getIconName());
|
||||
if (crossLeafIcon == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int offsetVariation = getSemiRandomFromPos(x, y, z, 0);
|
||||
int uvVariation = getSemiRandomFromPos(x, y, z, 1);
|
||||
double halfSize = 0.5 * Config.leavesSize.value;
|
||||
boolean isAirTop = y == 255 || blockAccess.isAirBlock(x, y + 1, z);
|
||||
boolean isAirBottom = y == 0 || blockAccess.isAirBlock(x, y - 1, z);
|
||||
|
||||
Tessellator.instance.setBrightness(isAirTop ? getBrightness(block, x, y + 1, z) : (isAirBottom ? getBrightness(block, x, y - 1, z) : getBrightness(block, x, y, z)));
|
||||
Tessellator.instance.setColorOpaque_I(block.colorMultiplier(blockAccess, x, y, z));
|
||||
|
||||
if (Config.leavesSkew) {
|
||||
renderCrossedBlockQuadsSkew(new Double3(x + 0.5, y + 0.5, z + 0.5), halfSize,
|
||||
pRot[offsetVariation].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value),
|
||||
pRot[(offsetVariation + 1) & 63].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value),
|
||||
crossLeafIcon, uvVariation, isAirTop, isAirBottom);
|
||||
} else {
|
||||
renderCrossedBlockQuadsTranslate(new Double3(x + 0.5, y + 0.5, z + 0.5), halfSize,
|
||||
pRot[offsetVariation].scaleAxes(Config.leavesHOffset.value, Config.leavesVOffset.value, Config.leavesHOffset.value),
|
||||
crossLeafIcon, uvVariation, isAirTop, isAirBottom);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isBlockSurrounded(IBlockAccess blockAccess, int x, int y, int z) {
|
||||
if (blockAccess.isAirBlock(x + 1, y, z)) return false;
|
||||
if (blockAccess.isAirBlock(x - 1, y, z)) return false;
|
||||
if (blockAccess.isAirBlock(x, y, z + 1)) return false;
|
||||
if (blockAccess.isAirBlock(x, y, z - 1)) return false;
|
||||
if (y == 255 || blockAccess.isAirBlock(x, y + 1, z)) return false;
|
||||
if (y == 0 || blockAccess.isAirBlock(x, y - 1, z)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package mods.betterfoliage.client.render.impl;
|
||||
|
||||
import mods.betterfoliage.client.render.FakeRenderBlockAOBase;
|
||||
import mods.betterfoliage.client.render.IRenderBlockDecorator;
|
||||
import mods.betterfoliage.common.config.Config;
|
||||
import mods.betterfoliage.common.util.Double3;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements IRenderBlockDecorator {
|
||||
|
||||
public IIcon lilypadFlowers[] = new IIcon[2];
|
||||
public IIcon lilypadRoots[] = new IIcon[3];
|
||||
|
||||
public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) {
|
||||
return Config.lilypadEnabled && block == Blocks.waterlily;
|
||||
}
|
||||
|
||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// render grass block
|
||||
renderBlockLilyPad(block, x, y, z);
|
||||
|
||||
int chanceVariation = getSemiRandomFromPos(x, y, z, 0);
|
||||
int iconVariation = getSemiRandomFromPos(x, y, z, 1);
|
||||
int offsetVariation = getSemiRandomFromPos(x, y, z, 2);
|
||||
|
||||
Tessellator.instance.setBrightness(getBrightness(block, x, y, z));
|
||||
Tessellator.instance.setColorOpaque(255, 255, 255);
|
||||
renderCrossedSideQuads(new Double3(x + 0.5, y + 0.015, z + 0.5), ForgeDirection.DOWN,
|
||||
0.2, 0.3,
|
||||
null, 0.0,
|
||||
lilypadRoots[iconVariation % 3], 2,
|
||||
true);
|
||||
if (chanceVariation < Config.lilypadChance.value)
|
||||
renderCrossedSideQuads(new Double3(x + 0.5, y + 0.02, z + 0.5), ForgeDirection.UP,
|
||||
0.2, 0.3,
|
||||
pRot[offsetVariation], Config.lilypadHOffset.value,
|
||||
lilypadFlowers[iconVariation % 2], 0,
|
||||
true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void handleTextureReload(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() != 0) return;
|
||||
for (int idx = 0; idx < 2; idx++) lilypadFlowers[idx] = event.map.registerIcon("bettergrassandleaves:better_lilypad_flower_" + Integer.toString(idx));
|
||||
for (int idx = 0; idx < 3; idx++) lilypadRoots[idx] = event.map.registerIcon("bettergrassandleaves:better_lilypad_roots_" + Integer.toString(idx));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user