/*
* Copyright (c) CovertJaguar, 2014 http://railcraft.info
*
* This code is the property of CovertJaguar
* and may only be used with explicit written
* permission unless otherwise specified on the
* license page at http://railcraft.info/wiki/info:license.
*/
package mods.railcraft.client.render;
import java.util.EnumSet;
import mods.railcraft.api.electricity.GridTools;
import mods.railcraft.api.electricity.IElectricGrid;
import mods.railcraft.api.electricity.IElectricGrid.ChargeHandler.ConnectType;
import mods.railcraft.common.blocks.RailcraftBlocks;
import mods.railcraft.common.blocks.frame.BlockFrame;
import mods.railcraft.common.blocks.machine.delta.EnumMachineDelta;
import mods.railcraft.common.blocks.machine.delta.TileWire;
import mods.railcraft.common.blocks.machine.delta.TileWire.AddonType;
import mods.railcraft.common.blocks.tracks.TrackTools;
import mods.railcraft.common.plugins.forge.WorldPlugin;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.client.IItemRenderer;
import net.minecraftforge.common.util.ForgeDirection;
/**
*
* @author CovertJaguar <http://www.railcraft.info>
*/
public class RenderBlockMachineDelta extends BlockRenderer {
public RenderBlockMachineDelta() {
super(RailcraftBlocks.getBlockMachineDelta());
addCombinedRenderer(EnumMachineDelta.WIRE.ordinal(), new WireRenderer());
addBlockRenderer(EnumMachineDelta.CAGE.ordinal(), new CageRenderer());
}
private class WireRenderer extends DefaultRenderer {
private final RenderBlockFrame renderFrame;
private RenderFakeBlock.RenderInfo info = new RenderFakeBlock.RenderInfo();
public WireRenderer() {
if (BlockFrame.getBlock() != null)
renderFrame = new RenderBlockFrame();
else
renderFrame = null;
info.template = getBlock();
}
@Override
public void renderBlock(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) {
EnumSet<ForgeDirection> wireCons = EnumSet.noneOf(ForgeDirection.class);
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
TileEntity tile = WorldPlugin.getTileEntityOnSide(world, x, y, z, dir);
if (tile instanceof TileWire)
wireCons.add(dir);
}
EnumSet<ForgeDirection> plugCons = EnumSet.noneOf(ForgeDirection.class);
EnumSet<ForgeDirection> search = EnumSet.allOf(ForgeDirection.class);
search.remove(ForgeDirection.UNKNOWN);
search.removeAll(wireCons);
for (ForgeDirection dir : search) {
TileEntity tile = WorldPlugin.getTileEntityOnSide(world, x, y, z, dir);
if (tile instanceof IElectricGrid && ((IElectricGrid) tile).getChargeHandler().getType() == ConnectType.BLOCK)
plugCons.add(dir);
}
wireCons.addAll(plugCons);
boolean powered = false;
IElectricGrid above = GridTools.getGridObjectAt(world, x, y + 1, z);
if (above != null && TrackTools.isRailBlockAt(world, x, y + 1, z)) {
wireCons.add(ForgeDirection.UP);
plugCons.add(ForgeDirection.UP);
// renderPlatform(renderblocks, world, x, y, z, block);
powered = true;
}
renderWire(renderblocks, world, x, y, z, block, wireCons);
renderPlug(renderblocks, world, x, y, z, block, plugCons);
TileEntity tile = WorldPlugin.getBlockTile(world, x, y, z);
if (tile instanceof TileWire) {
TileWire wire = (TileWire) tile;
if (wire.getAddon() == AddonType.FRAME) {
BlockFrame.poweredTexture = powered;
renderFrame(renderblocks, world, x, y, z, block);
BlockFrame.poweredTexture = false;
}
}
block.setBlockBounds(0, 0, 0, 1, 1, 1);
}
private void renderFrame(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) {
if (renderFrame != null)
renderFrame.renderWorldBlock(world, x, y, z, BlockFrame.getBlock(), BlockFrame.getBlock().getRenderType(), renderblocks);
}
private void renderPlatform(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) {
block.setBlockBounds(0.0F, 14 * RenderTools.PIXEL, 0.0F, 1.0F, 1.0F, 1.0F);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
private void renderWire(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block, EnumSet<ForgeDirection> wireCons) {
float pix = RenderTools.PIXEL;
float max = 0.999F;
float min = 0.001F;
if (wireCons.isEmpty()) {
block.setBlockBounds(6 * pix, 6 * pix, 6 * pix, 10 * pix, 10 * pix, 10 * pix);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
block.setBlockBounds(0, 0, 0, 1, 1, 1);
return;
}
boolean down = wireCons.contains(ForgeDirection.DOWN);
boolean up = wireCons.contains(ForgeDirection.UP);
if (down || up) {
block.setBlockBounds(6 * pix, down ? min : 6 * pix, 6 * pix, 10 * pix, up ? max : 10 * pix, 10 * pix);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
boolean north = wireCons.contains(ForgeDirection.NORTH);
boolean south = wireCons.contains(ForgeDirection.SOUTH);
if (north || south) {
block.setBlockBounds(6 * pix - 0.0001f, 6 * pix - 0.0001f, north ? min : 6 * pix - 0.0001f, 10 * pix + 0.0001f, 10 * pix + 0.0001f, south ? max : 10 * pix + 0.0001f);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
boolean west = wireCons.contains(ForgeDirection.WEST);
boolean east = wireCons.contains(ForgeDirection.EAST);
if (west || east) {
block.setBlockBounds(west ? min : 6 * pix - 0.0002f, 6 * pix - 0.0002f, 6 * pix - 0.0002f, east ? max : 10 * pix + 0.0002f, 10 * pix + 0.0002f, 10 * pix + 0.0002f);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
}
private void renderPlug(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block, EnumSet<ForgeDirection> plugCons) {
if (plugCons.isEmpty())
return;
float pix = RenderTools.PIXEL;
float center = 8 * pix;
float length = 4 * pix;
float width = 2 * pix;
float thickness = 4 * pix;
float[][] plugA = new float[3][2];
float[][] plugB = new float[3][2];
// X START - END
plugA[0][0] = center - length;
plugA[0][1] = center + length;
// Y START - END
plugA[1][0] = 0.001F;
plugA[1][1] = thickness;
// Z START - END
plugA[2][0] = center - width;
plugA[2][1] = center + width;
// X START - END
plugB[0][0] = center - width;
plugB[0][1] = center + width;
// Y START - END
plugB[1][0] = 0.001F;
plugB[1][1] = thickness;
// Z START - END
plugB[2][0] = center - length;
plugB[2][1] = center + length;
float[][] rotated;
for (ForgeDirection dir : plugCons) {
rotated = MatrixTransformations.deepClone(plugA);
MatrixTransformations.transform(rotated, dir);
block.setBlockBounds(rotated[0][0], rotated[1][0], rotated[2][0], rotated[0][1], rotated[1][1], rotated[2][1]);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
rotated = MatrixTransformations.deepClone(plugB);
MatrixTransformations.transform(rotated, dir);
block.setBlockBounds(rotated[0][0], rotated[1][0], rotated[2][0], rotated[0][1], rotated[1][1], rotated[2][1]);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
}
@Override
public void renderItem(RenderBlocks renderblocks, ItemStack item, IItemRenderer.ItemRenderType renderType) {
float pix = RenderTools.PIXEL;
float max = 0.999F;
float min = 0.001F;
info.setBlockBounds(6 * pix, min, 6 * pix, 10 * pix, max, 10 * pix);
RenderFakeBlock.renderBlockOnInventory(renderblocks, info, 1);
info.setBlockBounds(6 * pix - 0.0001f, 6 * pix - 0.0001f, min, 10 * pix + 0.0001f, 10 * pix + 0.0001f, max);
RenderFakeBlock.renderBlockOnInventory(renderblocks, info, 1);
info.setBlockBounds(min, 6 * pix - 0.0002f, 6 * pix - 0.0002f, max, 10 * pix + 0.0002f, 10 * pix + 0.0002f);
RenderFakeBlock.renderBlockOnInventory(renderblocks, info, 1);
}
}
private class CageRenderer extends DefaultRenderer {
@Override
public void renderBlock(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) {
Tessellator tessellator = Tessellator.instance;
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z));
float c = 1.0F;
tessellator.setColorOpaque_F(c, c, c);
IIcon icon = renderblocks.getBlockIcon(block, world, x, y, z, 2);
if (renderblocks.hasOverrideBlockTexture())
icon = renderblocks.overrideBlockTexture;
double minU = (double) icon.getMinU();
double minV = (double) icon.getMinV();
double maxU = (double) icon.getMaxU();
double maxV = (double) icon.getMaxV();
double border = 0.0D;
double offset = 0.001D;
double[][] vertices;
if (WorldPlugin.getBlock(world, x - 1, y, z) != block || world.getBlockMetadata(x - 1, y, z) != EnumMachineDelta.CAGE.ordinal()) {
vertices = new double[][]{
{x + offset, (y + 1) + border, (z + 1) + border, minU, minV},
{x + offset, (y + 0) - border, (z + 1) + border, minU, maxV},
{x + offset, (y + 0) - border, (z + 0) - border, maxU, maxV},
{x + offset, (y + 1) + border, (z + 0) - border, maxU, minV},};
renderFace(tessellator, vertices);
}
if (WorldPlugin.getBlock(world, x + 1, y, z) != block || world.getBlockMetadata(x + 1, y, z) != EnumMachineDelta.CAGE.ordinal()) {
vertices = new double[][]{
{(x + 1) - offset, (y + 0) - border, (z + 1) + border, maxU, maxV},
{(x + 1) - offset, (y + 1) + border, (z + 1) + border, maxU, minV},
{(x + 1) - offset, (y + 1) + border, (z + 0) - border, minU, minV},
{(x + 1) - offset, (y + 0) - border, (z + 0) - border, minU, maxV},};
renderFace(tessellator, vertices);
}
if (WorldPlugin.getBlock(world, x, y, z - 1) != block || world.getBlockMetadata(x, y, z - 1) != EnumMachineDelta.CAGE.ordinal()) {
vertices = new double[][]{
{(x + 1) + border, (y + 0) - border, z + offset, maxU, maxV},
{(x + 1) + border, (y + 1) + border, z + offset, maxU, minV},
{(x + 0) - border, (y + 1) + border, z + offset, minU, minV},
{(x + 0) - border, (y + 0) - border, z + offset, minU, maxV},};
renderFace(tessellator, vertices);
}
if (WorldPlugin.getBlock(world, x, y, z + 1) != block || world.getBlockMetadata(x, y, z + 1) != EnumMachineDelta.CAGE.ordinal()) {
vertices = new double[][]{
{(x + 1) + border, (y + 1) + border, (z + 1) - offset, minU, minV},
{(x + 1) + border, (y + 0) - border, (z + 1) - offset, minU, maxV},
{(x + 0) - border, (y + 0) - border, (z + 1) - offset, maxU, maxV},
{(x + 0) - border, (y + 1) + border, (z + 1) - offset, maxU, minV},};
renderFace(tessellator, vertices);
}
if (WorldPlugin.getBlock(world, x, y - 1, z) != block || world.getBlockMetadata(x, y - 1, z) != EnumMachineDelta.CAGE.ordinal()) {
icon = renderblocks.getBlockIcon(block, world, x, y, z, 0);
if (renderblocks.hasOverrideBlockTexture())
icon = renderblocks.overrideBlockTexture;
minU = (double) icon.getMinU();
minV = (double) icon.getMinV();
maxU = (double) icon.getMaxU();
maxV = (double) icon.getMaxV();
vertices = new double[][]{
{(x + 1) + border, y + offset, (z + 1) + border, minU, minV},
{(x + 0) - border, y + offset, (z + 1) + border, minU, maxV},
{(x + 0) - border, y + offset, (z + 0) - border, maxU, maxV},
{(x + 1) + border, y + offset, (z + 0) - border, maxU, minV},};
renderFace(tessellator, vertices);
}
if (WorldPlugin.getBlock(world, x, y + 1, z) != block || world.getBlockMetadata(x, y + 1, z) != EnumMachineDelta.CAGE.ordinal()) {
icon = renderblocks.getBlockIcon(block, world, x, y, z, 1);
if (renderblocks.hasOverrideBlockTexture())
icon = renderblocks.overrideBlockTexture;
minU = (double) icon.getMinU();
minV = (double) icon.getMinV();
maxU = (double) icon.getMaxU();
maxV = (double) icon.getMaxV();
vertices = new double[][]{
{(x + 0) - border, (y + 1) - offset, (z + 1) + border, maxU, maxV},
{(x + 1) + border, (y + 1) - offset, (z + 1) + border, maxU, minV},
{(x + 1) + border, (y + 1) - offset, (z + 0) - border, minU, minV},
{(x + 0) - border, (y + 1) - offset, (z + 0) - border, minU, maxV},};
renderFace(tessellator, vertices);
}
}
private void renderFace(Tessellator tess, double[][] vertices) {
for (int i = 0; i < 4; i++) {
tess.addVertexWithUV(vertices[i][0], vertices[i][1], vertices[i][2], vertices[i][3], vertices[i][4]);
}
for (int i = 0; i < 4; i++) {
tess.addVertexWithUV(vertices[3 - i][0], vertices[3 - i][1], vertices[3 - i][2], vertices[i][3], vertices[i][4]);
}
}
}
}