/*
* 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 mods.railcraft.api.core.IPostConnection.ConnectStyle;
import mods.railcraft.client.emblems.EmblemToolsClient;
import mods.railcraft.common.blocks.aesthetics.post.*;
import mods.railcraft.common.blocks.tracks.TrackTools;
import mods.railcraft.common.plugins.forge.WorldPlugin;
import mods.railcraft.common.util.misc.Game;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.client.IItemRenderer;
import net.minecraftforge.common.util.ForgeDirection;
import org.lwjgl.opengl.GL11;
/**
* @author CovertJaguar <http://www.railcraft.info>
*/
public class RenderBlockPost extends BlockRenderer {
private static final float PIX = RenderTools.PIXEL;
protected RenderBlockPost(Block block) {
super(block);
}
public static BlockRenderer make() {
BlockRenderer renderer = new RenderBlockPost(BlockPost.block);
renderer.addCombinedRenderer(EnumPost.WOOD.ordinal(), new RenderPost());
renderer.addCombinedRenderer(EnumPost.WOOD_PLATFORM.ordinal(), new RenderPost());
renderer.addCombinedRenderer(EnumPost.STONE.ordinal(), new RenderPostStone());
renderer.addCombinedRenderer(EnumPost.STONE_PLATFORM.ordinal(), new RenderPostStone());
renderer.addCombinedRenderer(EnumPost.METAL_UNPAINTED.ordinal(), new RenderPost());
renderer.addCombinedRenderer(EnumPost.METAL_PLATFORM_UNPAINTED.ordinal(), new RenderPost());
renderer.addCombinedRenderer(EnumPost.EMBLEM.ordinal(), new RenderPostSign());
return renderer;
}
protected static class RenderPost implements ICombinedRenderer {
@Override
public void renderBlock(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) {
BlockPostBase blockPost = (BlockPostBase) block;
int meta = world.getBlockMetadata(x, y, z);
TileEntity tile = null;
if (block.hasTileEntity(meta))
tile = world.getTileEntity(x, y, z);
boolean renderColumn = evaluateCenterColumn(renderblocks, world, x, y, z, blockPost, meta, tile);
boolean thinConnected = renderTwoThinConnectStyle(renderblocks, world, x, y, z, blockPost);
renderSingleThickConnectStyle(renderblocks, world, x, y, z, blockPost, thinConnected, renderColumn);
blockPost.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
private boolean renderTwoThinConnectStyle(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, BlockPostBase block) {
boolean east_west = false;
boolean north_south = false;
boolean west = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.WEST) == ConnectStyle.TWO_THIN;
boolean east = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.EAST) == ConnectStyle.TWO_THIN;
boolean north = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.NORTH) == ConnectStyle.TWO_THIN;
boolean south = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.SOUTH) == ConnectStyle.TWO_THIN;
if (east || west)
east_west = true;
if (north || south)
north_south = true;
if (!east_west && !north_south)
east_west = true;
float f = 0.4375F;
float f1 = 0.5625F;
float f2 = 11 * PIX;
float f3 = 14 * PIX;
float f4 = west ? 0.0F : f;
float f5 = east ? 1.0F : f1;
float f6 = north ? 0.0F : f;
float f7 = south ? 1.0F : f1;
if (east_west) {
block.setBlockBounds(f4, f2, f, f5, f3, f1);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
if (north_south) {
block.setBlockBounds(f, f2, f6, f1, f3, f7);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
f2 = 5 * PIX;
f3 = 8 * PIX;
if (east_west) {
block.setBlockBounds(f4, f2, f, f5, f3, f1);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
if (north_south) {
block.setBlockBounds(f, f2, f6, f1, f3, f7);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
return east || west || north || south;
}
private void renderSingleThickConnectStyle(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, BlockPostBase block, boolean thinConnected, boolean renderColumn) {
boolean east_west = false;
boolean north_south = false;
boolean west = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.WEST) == ConnectStyle.SINGLE_THICK;
boolean east = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.EAST) == ConnectStyle.SINGLE_THICK;
boolean north = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.NORTH) == ConnectStyle.SINGLE_THICK;
boolean south = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.SOUTH) == ConnectStyle.SINGLE_THICK;
if (east || west)
east_west = true;
if (north || south)
north_south = true;
if (!east_west && !north_south && thinConnected && !renderColumn)
east_west = true;
float f = 6 * PIX + 0.001F;
float f1 = 10 * PIX - 0.001F;
float f2 = 6 * PIX;
float f3 = 12 * PIX;
float f4 = west ? 0.0F : f;
float f5 = east ? 1.0F : f1;
float f6 = north ? 0.0F : f;
float f7 = south ? 1.0F : f1;
if (east_west) {
block.setBlockBounds(f4, f2, f, f5, f3, f1);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
if (north_south) {
block.setBlockBounds(f, f2, f6, f1, f3, f7);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
}
public boolean evaluateCenterColumn(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, BlockPostBase block, int meta, TileEntity tile) {
boolean renderColumm = shouldRenderColumn(world, x, y, z);
Block aboveBlock = world.getBlock(x, y + 1, z);
boolean renderPlatform = block.isPlatform(meta) || TrackTools.isRailBlock(aboveBlock);
if (renderColumm)
renderCenterColumn(renderblocks, x, y, z, block);
else if (!world.isAirBlock(x, y + 1, z) && !renderPlatform)
renderMiniPlatform(renderblocks, x, y, z, block);
if (renderPlatform)
renderPlatform(renderblocks, x, y, z, block);
return renderColumm;
}
public boolean shouldRenderColumn(IBlockAccess world, int x, int y, int z) {
Block below = WorldPlugin.getBlock(world, x, y - 1, z);
Block above = WorldPlugin.getBlock(world, x, y + 1, z);
if (below == null || !TrackTools.isRailBlock(below))
if (world.isSideSolid(x, y - 1, z, ForgeDirection.UP, true) || PostConnectionHelper.connect(world, x, y, z, ForgeDirection.DOWN) != ConnectStyle.NONE)
return true;
else if (above instanceof BlockPostBase)
// else if (PostConnectionHelper.connect(world, x, y, z, ForgeDirection.UP) || above instanceof BlockPostBase)
return true;
return false;
}
public void renderPlatform(RenderBlocks renderblocks, int x, int y, int z, Block block) {
block.setBlockBounds(0.0F, (16 - getPlatformThickness()) * RenderTools.PIXEL, 0.0F, 1.0F, 1.0F, 1.0F);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
public void renderCenterColumn(RenderBlocks renderblocks, int x, int y, int z, Block block) {
float w = getCenterColumnWidth();
float b1 = (8 - w / 2) * RenderTools.PIXEL;
float b2 = (8 + w / 2) * RenderTools.PIXEL;
block.setBlockBounds(b1, 0.0F, b1, b2, 0.999F, b2);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
public void renderMiniPlatform(RenderBlocks renderblocks, int x, int y, int z, Block block) {
float w = getCenterColumnWidth();
float b1 = (8 - w / 2) * RenderTools.PIXEL;
float b2 = (8 + w / 2) * RenderTools.PIXEL;
block.setBlockBounds(b1, 12 * RenderTools.PIXEL, b1, b2, 1.0F, b2);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
public float getPlatformThickness() {
return 2;
}
public float getCenterColumnWidth() {
return 4;
}
@Override
public void renderItem(RenderBlocks renderblocks, ItemStack item, IItemRenderer.ItemRenderType renderType) {
IIcon texture = item.getItem().getIcon(item, 0);
Block block = ((ItemBlock) item.getItem()).field_150939_a;
if (block == null)
return;
int numSections = ((BlockPostBase) block).isPlatform(item.getItemDamage()) ? 5 : 4;
for (int section = 0; section < numSections; section++) {
float f4 = 0.125F;
if (section == 0)
block.setBlockBounds(0.5F - f4, 0.0F, 0.0F, 0.5F + f4, 1.0F, f4 * 2.0F);
if (section == 1)
block.setBlockBounds(0.5F - f4, 0.0F, 1.0F - f4 * 2.0F, 0.5F + f4, 1.0F, 1.0F);
f4 = 0.0625F;
if (section == 2)
block.setBlockBounds(0.5F - f4, 1.0F - f4 * 3.0F, -f4 * 2.0F, 0.5F + f4, 1.0F - f4, 1.0F + f4 * 2.0F);
if (section == 3)
block.setBlockBounds(0.5F - f4, 0.5F - f4 * 3.0F, -f4 * 2.0F, 0.5F + f4, 0.5F - f4, 1.0F + f4 * 2.0F);
if (section == 4)
block.setBlockBounds(0.0F, (16 - getPlatformThickness()) * RenderTools.PIXEL, 0.0F, 1.0F, 1.0F, 1.0F);
renderblocks.setRenderBoundsFromBlock(block);
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
Tessellator tess = Tessellator.instance;
tess.startDrawingQuads();
tess.setNormal(0.0F, -1.0F, 0.0F);
renderblocks.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(0.0F, 1.0F, 0.0F);
renderblocks.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(0.0F, 0.0F, -1.0F);
renderblocks.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(0.0F, 0.0F, 1.0F);
renderblocks.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(-1.0F, 0.0F, 0.0F);
renderblocks.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(1.0F, 0.0F, 0.0F);
renderblocks.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
}
block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
}
protected static class RenderPostStone extends RenderPost {
@Override
public float getPlatformThickness() {
return 4;
}
@Override
public float getCenterColumnWidth() {
return 6;
}
@Override
public void renderBlock(RenderBlocks renderblocks, IBlockAccess iBlockAccess, int x, int y, int z, Block block) {
BlockPostBase blockPost = (BlockPostBase) block;
float pix = RenderTools.PIXEL;
World world = Game.getWorld();
int meta = world.getBlockMetadata(x, y, z);
TileEntity tile = null;
if (block.hasTileEntity(meta))
tile = world.getTileEntity(x, y, z);
evaluateCenterColumn(renderblocks, world, x, y, z, blockPost, meta, tile);
boolean east_west = false;
boolean north_south = false;
boolean west = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.WEST) != ConnectStyle.NONE;
boolean east = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.EAST) != ConnectStyle.NONE;
boolean north = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.NORTH) != ConnectStyle.NONE;
boolean south = PostConnectionHelper.connect(world, x, y, z, ForgeDirection.SOUTH) != ConnectStyle.NONE;
if (east || west)
east_west = true;
if (north || south)
north_south = true;
if (!east_west && !north_south)
east_west = true;
float f = 6 * pix;
float f1 = 10 * pix;
float f2 = 4 * pix;
float f3 = 15 * pix;
float f4 = west ? 0.0F : f;
float f5 = east ? 1.0F : f1;
float f6 = north ? 0.0F : f;
float f7 = south ? 1.0F : f1;
if (east_west) {
block.setBlockBounds(f4, f2, f, f5, f3, f1);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
if (north_south) {
block.setBlockBounds(f, f2, f6, f1, f3, f7);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
@Override
public void renderItem(RenderBlocks renderblocks, ItemStack item, IItemRenderer.ItemRenderType renderType) {
IIcon texture = item.getItem().getIconFromDamage(item.getItemDamage());
Block block = ((ItemBlock) item.getItem()).field_150939_a;
if (block == null)
return;
float pix = RenderTools.PIXEL;
float pix2 = 2 * pix;
float pix3 = 3 * pix;
int numSections = ((BlockPostBase) block).isPlatform(item.getItemDamage()) ? 4 : 3;
for (int section = 0; section < numSections; section++) {
if (section == 0)
block.setBlockBounds(0.5F - pix3, 0.0F, 0.0F, 0.5F + pix3, 1.0F, pix3 * 2.0F);
if (section == 1)
block.setBlockBounds(0.5F - pix3, 0.0F, 1.0F - pix3 * 2.0F, 0.5F + pix3, 1.0F, 1.0F);
if (section == 2)
block.setBlockBounds(0.5F - pix2, 0.5F - pix3, -pix * 2.0F, 0.5F + pix2, 1.0F - pix, 1.0F + pix2);
if (section == 3)
block.setBlockBounds(0.0F, (16 - getPlatformThickness()) * pix, 0.0F, 1.0F, 1.0F, 1.0F);
renderblocks.setRenderBoundsFromBlock(block);
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
Tessellator tess = Tessellator.instance;
tess.startDrawingQuads();
tess.setNormal(0.0F, -1.0F, 0.0F);
renderblocks.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(0.0F, 1.0F, 0.0F);
renderblocks.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(0.0F, 0.0F, -1.0F);
renderblocks.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(0.0F, 0.0F, 1.0F);
renderblocks.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(-1.0F, 0.0F, 0.0F);
renderblocks.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
tess.startDrawingQuads();
tess.setNormal(1.0F, 0.0F, 0.0F);
renderblocks.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, texture);
tess.draw();
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
}
block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
}
protected static class RenderPostSign extends RenderPost {
@Override
public void renderBlock(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) {
super.renderBlock(renderblocks, world, x, y, z, block);
renderSign(renderblocks, world, x, y, z, block);
}
public void renderSign(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) {
TileEntity tile = world.getTileEntity(x, y, z);
if (!(tile instanceof TilePostEmblem))
return;
TilePostEmblem tileEmblem = (TilePostEmblem) tile;
float pix = RenderTools.PIXEL;
float minY = 2 * pix;
float maxY = 1;
switch (tileEmblem.getFacing()) {
case NORTH:
block.setBlockBounds(pix, minY, 4 * pix, 15 * pix, maxY, 6 * pix);
break;
case SOUTH:
block.setBlockBounds(pix, minY, 10 * pix, 15 * pix, maxY, 12 * pix);
break;
case WEST:
block.setBlockBounds(4 * pix, minY, pix, 6 * pix, maxY, 15 * pix);
break;
default:
block.setBlockBounds(10 * pix, minY, pix, 12 * pix, maxY, 15 * pix);
break;
}
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
float w = getCenterColumnWidth();
float b1 = (8 - w / 2) * pix;
float b2 = (8 + w / 2) * pix;
minY = 2 * pix;
if (world.isSideSolid(x, y - 1, z, ForgeDirection.UP, true) || PostConnectionHelper.connect(world, x, y, z, ForgeDirection.DOWN) != ConnectStyle.NONE)
minY = 0;
block.setBlockBounds(b1, minY, b1, b2, 1.0F, b2);
RenderTools.renderStandardBlock(renderblocks, block, x, y, z);
}
@Override
public boolean shouldRenderColumn(IBlockAccess world, int x, int y, int z) {
return false;
}
@Override
public void renderPlatform(RenderBlocks renderblocks, int x, int y, int z, Block block) {
}
@Override
public void renderItem(RenderBlocks renderblocks, ItemStack item, IItemRenderer.ItemRenderType renderType) {
IIcon texture = item.getItem().getIcon(item, 0);
Block block = ((ItemBlock) item.getItem()).field_150939_a;
if (block == null)
return;
GL11.glPushMatrix();
// GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
switch (renderType) {
case EQUIPPED_FIRST_PERSON:
GL11.glRotatef(270, 0, 1, 0);
}
float pix = RenderTools.PIXEL;
float w = getCenterColumnWidth();
float b1 = (8 - w / 2) * pix;
float b2 = (8 + w / 2) * pix;
block.setBlockBounds(b1, 0, b1, b2, 1, b2);
RenderTools.renderBlockOnInventory(renderblocks, block, item.getItemDamage(), 1, -1, texture);
float minY = 2 * pix;
float maxY = 1;
block.setBlockBounds(pix, minY, 10 * pix, 15 * pix, maxY, 12 * pix);
RenderTools.renderBlockOnInventory(renderblocks, block, item.getItemDamage(), 1, -1, texture);
renderEmblem(ItemPost.getEmblem(item));
// GL11.glTranslatef(0.5F, 0.5F, 0.5F);
block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
GL11.glPopMatrix();
}
private void renderEmblem(String emblem) {
if (emblem == null || emblem.equals(""))
return;
GL11.glPushMatrix();
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
float pix = RenderTools.PIXEL;
float shift = 0.5F;
float scale = 0.6F;
GL11.glTranslatef(-0.5F, -0.5F + pix, 0.09F);
GL11.glTranslatef(shift, shift, shift);
GL11.glScalef(scale, scale, scale);
GL11.glTranslatef(-shift, -shift, -shift);
if (EmblemToolsClient.renderer != null)
EmblemToolsClient.renderer.renderIn3D(emblem, false);
GL11.glPopAttrib();
GL11.glPopMatrix();
}
}
public static class EmblemPostTESR extends TileEntitySpecialRenderer {
public EmblemPostTESR() {
}
@Override
public void renderTileEntityAt(TileEntity tile, double x, double y, double z, float f) {
TilePostEmblem post = (TilePostEmblem) tile;
if (post.getEmblem() == null || post.getEmblem().equals(""))
return;
GL11.glPushMatrix();
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
// GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_BLEND);
// GL11.glEnable(GL11.GL_CULL_FACE);
float pix = RenderTools.PIXEL;
float shift = 0.5F;
float scale = 0.6F;
GL11.glTranslatef((float) x, (float) y + pix, (float) z);
GL11.glTranslatef(shift, 0, shift);
switch (post.getFacing()) {
case NORTH:
GL11.glRotatef(180, 0, 1, 0);
break;
case EAST:
GL11.glRotatef(90, 0, 1, 0);
break;
case WEST:
GL11.glRotatef(-90, 0, 1, 0);
break;
}
GL11.glTranslatef(-shift, 0, -shift);
GL11.glTranslatef(shift, shift, shift);
GL11.glScalef(scale, scale, scale);
GL11.glTranslatef(-shift, -shift, -shift);
GL11.glTranslatef(0, 0, 1 - 0.02F);
if (EmblemToolsClient.renderer != null)
EmblemToolsClient.renderer.renderIn3D(post.getEmblem(), false);
GL11.glPopAttrib();
GL11.glPopMatrix();
}
}
}