package vorquel.mod.similsaxtranstructors;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.opengl.GL11;
public class BlockOverlay {
private final ResourceLocation overlayLocation = new ResourceLocation(SimilsaxTranstructors.MOD_ID.toLowerCase(), "textures/overlay.png");
private final Vec3d[] vs = new Vec3d[8];
{
for(int i=0; i<8; ++i) {
int x = (i & 1) == 1 ? 1 : 0;
int y = (i & 2) == 2 ? 1 : 0;
int z = (i & 4) == 4 ? 1 : 0;
vs[i] = new Vec3d(x, y, z);
}
}
private final float[][][] uvs = new float[7][4][];
{
//arrow 1
uvs[0][0] = new float[]{0,0};
uvs[0][1] = new float[]{0,.5f};
uvs[0][2] = new float[]{.5f,.5f};
uvs[0][3] = new float[]{.5f,0};
//arrow 2
uvs[1][0] = new float[]{0,.5f};
uvs[1][1] = new float[]{.5f,.5f};
uvs[1][2] = new float[]{.5f,0};
uvs[1][3] = new float[]{0,0};
//arrow 3
uvs[2][0] = new float[]{.5f,.5f};
uvs[2][1] = new float[]{.5f,0};
uvs[2][2] = new float[]{0,0};
uvs[2][3] = new float[]{0,.5f};
//arrow 4
uvs[3][0] = new float[]{.5f,0};
uvs[3][1] = new float[]{0,0};
uvs[3][2] = new float[]{0,.5f};
uvs[3][3] = new float[]{.5f,.5f};
//cross
uvs[4][0] = new float[]{.5f,0};
uvs[4][1] = new float[]{.5f,.5f};
uvs[4][2] = new float[]{1,.5f};
uvs[4][3] = new float[]{1,0};
//bullseye
uvs[5][0] = new float[]{0,.5f};
uvs[5][1] = new float[]{0,1};
uvs[5][2] = new float[]{.5f,1};
uvs[5][3] = new float[]{.5f,.5f};
//cancel
uvs[6][0] = new float[]{.5f,.5f};
uvs[6][1] = new float[]{.5f,1};
uvs[6][2] = new float[]{1,1};
uvs[6][3] = new float[]{1,.5f};
}
private final int[][] lookUps = new int[7][6];
{
lookUps[0] = new int[]{2, 5, 1, 1, 4, 2};
lookUps[1] = new int[]{0, 4, 3, 3, 5, 0};
lookUps[2] = new int[]{1, 2, 5, 2, 1, 4};
lookUps[3] = new int[]{3, 0, 4, 0, 3, 5};
lookUps[4] = new int[]{5, 1, 2, 4, 2, 1};
lookUps[5] = new int[]{4, 3, 0, 5, 0, 3};
lookUps[6] = new int[]{6, 6, 6, 6, 6, 6};
}
@SubscribeEvent
public void renderOverlay(DrawBlockHighlightEvent event) {
if(shouldSkip(event))
return;
RayTraceResult m = event.getTarget();
BlockPos mPos = m.getBlockPos();
Vec3d h = m.hitVec;
int index;
if(isBadBlock(event))
index = 6;
else
index = ItemSimilsaxTranstructor.getSide(m.sideHit.getIndex(), h.xCoord-mPos.getX(), h.yCoord-mPos.getY(), h.zCoord-mPos.getZ());
Minecraft.getMinecraft().renderEngine.bindTexture(overlayLocation);
Vec3d v = getViewerPosition(event.getPartialTicks());
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushMatrix();
GL11.glTranslated(mPos.getX(), mPos.getY(), mPos.getZ());
GL11.glTranslated(-v.xCoord, -v.yCoord, -v.zCoord);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glAlphaFunc(GL11.GL_GREATER, 0);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1, 1, 1, .375f);
final float P = 1/256f, N = -1/256f;
final int X = 1, Y = 2, Z = 4;
GL11.glTranslatef(P, 0, 0);
drawSide(X, Y, Z, uvs[lookUps[index][0]]);
GL11.glTranslatef(N, P, 0);
drawSide(Y, Z, X, uvs[lookUps[index][1]]);
GL11.glTranslatef(0, N, P);
drawSide(Z, X, Y, uvs[lookUps[index][2]]);
GL11.glTranslatef(N, 0, N);
drawSide(0, Z, Y, uvs[lookUps[index][3]]);
GL11.glTranslatef(P, N, 0);
drawSide(0, X, Z, uvs[lookUps[index][4]]);
GL11.glTranslatef(0, P, N);
drawSide(0, Y, X, uvs[lookUps[index][5]]);
GL11.glPopMatrix();
GL11.glPopAttrib();
}
private boolean shouldSkip(DrawBlockHighlightEvent event) {
if(event.getTarget().typeOfHit != RayTraceResult.Type.BLOCK) return true;
ItemStack mainItemStack = event.getPlayer().getHeldItem(EnumHand.MAIN_HAND);
Item mainItem = mainItemStack == null ? null : mainItemStack.getItem();
ItemStack offItemStack = event.getPlayer().getHeldItem(EnumHand.OFF_HAND);
Item offItem = offItemStack == null ? null : offItemStack.getItem();
return !(mainItem instanceof ItemSimilsaxTranstructor || offItem instanceof ItemSimilsaxTranstructor);
}
private boolean isBadBlock(DrawBlockHighlightEvent event) {
BlockPos pos = event.getTarget().getBlockPos();
World world = event.getPlayer().worldObj;
IBlockState state = world.getBlockState(pos);
Block block = state.getBlock();
return block.hasTileEntity(state) || block.isReplaceable(world, pos);
}
private Vec3d getViewerPosition(float partialTicks) {
Entity viewer = Minecraft.getMinecraft().getRenderViewEntity();
double x = partial(partialTicks, viewer.prevPosX, viewer.posX);
double y = partial(partialTicks, viewer.prevPosY, viewer.posY);
double z = partial(partialTicks, viewer.prevPosZ, viewer.posZ);
return new Vec3d(x, y, z);
}
private double partial(float partialTicks, double prevPos, double pos) {
return partialTicks == 1 ? pos : prevPos + partialTicks * (pos - prevPos);
}
private void drawSide(int c, int i, int j, float[][] uv) {
Tessellator.getInstance().getBuffer().begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
addVertex(uv[0][0], uv[0][1], c);
addVertex(uv[1][0], uv[1][1], c + i);
addVertex(uv[2][0], uv[2][1], c + i + j);
addVertex(uv[3][0], uv[3][1], c + j);
Tessellator.getInstance().draw();
}
private void addVertex(double u, double v, int i) {
Tessellator.getInstance().getBuffer().pos(vs[i].xCoord, vs[i].yCoord, vs[i].zCoord).tex(u, v).endVertex();
}
}