package crazypants.enderio.machine.painter; 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.tileentity.TileEntity; import net.minecraft.world.IBlockAccess; import net.minecraftforge.common.util.ForgeDirection; import com.enderio.core.client.render.CubeRenderer; import com.enderio.core.client.render.IconUtil; import com.enderio.core.common.util.BlockCoord; import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; public class PaintedBlockRenderer implements ISimpleBlockRenderingHandler { private int renderId; private Block defaultBlock; public PaintedBlockRenderer(int renderId, Block defaultBlock) { this.renderId = renderId; this.defaultBlock = defaultBlock; } @Override public int getRenderId() { return renderId; } @Override public void renderInventoryBlock(Block blk, int meta, int modelId, RenderBlocks arg3) { Tessellator.instance.startDrawingQuads(); CubeRenderer.render(blk, meta); Tessellator.instance.draw(); } @Override public boolean renderWorldBlock(IBlockAccess ba, int x, int y, int z, Block block, int arg5, RenderBlocks rb) { TileEntity tile = ba.getTileEntity(x, y, z); if(!(tile instanceof IPaintableTileEntity)) { return false; } IPaintableTileEntity te = (IPaintableTileEntity) tile; Block srcBlk = te.getSourceBlock(); if(srcBlk == null) { srcBlk = defaultBlock; } IBlockAccess origBa = rb.blockAccess; try { rb.blockAccess = new PaintedBlockAccessWrapper(origBa); if (block.isOpaqueCube() && nonSolidPaintedBlockAround(new BlockCoord(x, y, z), origBa, rb.blockAccess)) { if (srcBlk == block) { rb.setRenderAllFaces(true); rb.renderStandardBlock(srcBlk, x, y, z); rb.setRenderAllFaces(false); } else { rb.renderBlockAllFaces(srcBlk, x, y, z); } } else { if (srcBlk == block) { rb.renderStandardBlock(srcBlk, x, y, z); } else { rb.renderBlockByRenderType(srcBlk, x, y, z); } } } catch (Exception e) { //just in case the paint source wont render safely in this way rb.setOverrideBlockTexture(IconUtil.errorTexture); rb.renderStandardBlock(Blocks.stone, x, y, z); rb.setOverrideBlockTexture(null); } finally { rb.blockAccess = origBa; } return true; } /* * If a non-solid block is painted with a solid block, the renderer would * think it didn't need to render faces of adjacent blocks that touch it * because it only sees the paint. * * This detects this case, so the renderer can be told to just render all * faces, even if it thinks it could save some quads. */ private boolean nonSolidPaintedBlockAround(BlockCoord bc, IBlockAccess reality, IBlockAccess fake) { for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { BlockCoord toTest = bc.getLocation(dir); if (toTest.y >= 0 && toTest.y <= 255 && toTest.getBlock(reality).isOpaqueCube() != toTest.getBlock(fake).isOpaqueCube()) { return true; } } return false; } @Override public boolean shouldRender3DInInventory(int arg0) { return false; } }