package openblocks.client.renderer.entity;
import java.util.Random;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.util.ForgeDirection;
import openblocks.client.model.ModelCartographer;
import openblocks.client.renderer.entity.EntitySelectionHandler.ISelectionRenderer;
import openblocks.common.entity.EntityCartographer;
import openblocks.common.entity.EntityCartographer.MapJobs;
import openmods.renderer.DisplayListWrapper;
import openmods.utils.BlockUtils;
import openmods.utils.render.RenderUtils;
import org.lwjgl.opengl.GL11;
public class EntityCartographerRenderer extends Render {
private static final double Z_FIGHTER = 0.0001;
private static final double CONE_START = 0.075;
private static final double CONE_END = 0.3;
private static final double BASE_SIZE = 0.125;
private static final double MAP_SIZE = 0.08;
private static final double INTERSECTION_DIST = 2.5 / 16.0;
private static final double INTERSECTION_SIZE = BASE_SIZE * (INTERSECTION_DIST - CONE_START) / (CONE_END - CONE_START);
private final static ResourceLocation TEXTURE = new ResourceLocation("openblocks:textures/models/cartographer.png");
private static final ModelCartographer MODEL = new ModelCartographer();
private static final DisplayListWrapper CONE_DISPLAY = new DisplayListWrapper() {
@Override
public void compile() {
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor4d(1, 1, 1, 1);
GL11.glVertex3d(-INTERSECTION_SIZE, -INTERSECTION_SIZE, -INTERSECTION_DIST - Z_FIGHTER);
GL11.glVertex3d(-INTERSECTION_SIZE, +INTERSECTION_SIZE, -INTERSECTION_DIST - Z_FIGHTER);
GL11.glVertex3d(+INTERSECTION_SIZE, +INTERSECTION_SIZE, -INTERSECTION_DIST - Z_FIGHTER);
GL11.glVertex3d(+INTERSECTION_SIZE, -INTERSECTION_SIZE, -INTERSECTION_DIST - Z_FIGHTER);
GL11.glEnd();
GL11.glEnable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glBegin(GL11.GL_TRIANGLE_FAN);
GL11.glColor4d(0, 1, 1, 0.125);
GL11.glVertex3d(0, 0, -CONE_START);
GL11.glVertex3d(-BASE_SIZE, -BASE_SIZE, -CONE_END);
GL11.glVertex3d(+BASE_SIZE, -BASE_SIZE, -CONE_END);
GL11.glVertex3d(+BASE_SIZE, +BASE_SIZE, -CONE_END);
GL11.glVertex3d(-BASE_SIZE, +BASE_SIZE, -CONE_END);
GL11.glVertex3d(-BASE_SIZE, -BASE_SIZE, -CONE_END);
GL11.glEnd();
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
};
public static class Selection implements ISelectionRenderer<EntityCartographer> {
private static final Random RANDOM = new Random();
private DynamicTexture mapTextureData;
private ResourceLocation mapTextureLocation;
@Override
public void render(EntityCartographer e, EntityPlayer player, RenderGlobal context, float partialTickTime) {
if (RANDOM.nextFloat() < 0.1f) return;
GL11.glPushMatrix();
RenderUtils.translateToPlayer(e, partialTickTime);
ForgeDirection side = BlockUtils.get2dOrientation(player).getOpposite();
switch (side) {
case EAST:
GL11.glRotated(-90, 0, 1, 0);
break;
case WEST:
GL11.glRotated(90, 0, 1, 0);
break;
case NORTH:
GL11.glRotated(0, 0, 1, 0);
break;
case SOUTH:
GL11.glRotated(180, 0, 1, 0);
break;
default:
break;
}
GL11.glTranslated(0, -0.03, 0);
CONE_DISPLAY.render();
GL11.glColor4f(1, 1, 1, 1);
final TextureManager textureManager = Minecraft.getMinecraft().getTextureManager();
if (e.isMapping.get()) {
GL11.glTranslated(+BASE_SIZE, +BASE_SIZE, -CONE_END);
bindMapTexture(textureManager);
renderProgressMap(e.jobs);
} else {
textureManager.bindTexture(TEXTURE);
drawBase();
GL11.glTranslated(+BASE_SIZE, +BASE_SIZE, -CONE_END - Z_FIGHTER);
renderText(e, context);
}
GL11.glPopMatrix();
}
private static void drawBase() {
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor4d(1, 1, 1, 1);
GL11.glTexCoord2d(0.0, 1.0);
GL11.glVertex3d(-BASE_SIZE, -BASE_SIZE, -CONE_END);
GL11.glTexCoord2d(0.5, 1.0);
GL11.glVertex3d(+BASE_SIZE, -BASE_SIZE, -CONE_END);
GL11.glTexCoord2d(0.5, 0.5);
GL11.glVertex3d(+BASE_SIZE, +BASE_SIZE, -CONE_END);
GL11.glTexCoord2d(0.0, 0.5);
GL11.glVertex3d(-BASE_SIZE, +BASE_SIZE, -CONE_END);
GL11.glEnd();
GL11.glEnable(GL11.GL_CULL_FACE);
}
private static void renderText(EntityCartographer e, RenderGlobal context) {
GL11.glScaled(2 * BASE_SIZE / 16.0, 2 * BASE_SIZE / 16.0, 1);
FontRenderer fonts = Minecraft.getMinecraft().fontRenderer;
String coords = String.format("%d,%d", e.getNewMapCenterX(), e.getNewMapCenterZ());
int len = fonts.getStringWidth(coords);
double scaleV = 4.0 / 8.0;
int margin = 2;
double available = 16 - 2 * margin;
double scaleH = available / len;
double scale = Math.min(scaleV, scaleH);
GL11.glTranslated(-margin, -2, 0);
GL11.glScaled(-scale, -scale, 1);
fonts.drawString(coords, 0, 0, 0);
}
private void renderProgressMap(MapJobs segments) {
final int[] mapColors = mapTextureData.getTextureData();
int bit = 0;
final int mapSize = segments.size();
for (int row = 0; row < mapSize; row++)
for (int column = 0; column < mapSize; column++)
mapColors[row * 64 + column] = segments.test(bit++)? 0xFF00FF19 : 0xFF00600B;
mapTextureData.updateDynamicTexture();
float maxTex = mapSize / 64.0f;
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0);
GL11.glVertex3d(-BASE_SIZE + MAP_SIZE, -BASE_SIZE + MAP_SIZE, 0);
GL11.glTexCoord2f(0, maxTex);
GL11.glVertex3d(-BASE_SIZE + MAP_SIZE, -BASE_SIZE - MAP_SIZE, 0);
GL11.glTexCoord2f(maxTex, maxTex);
GL11.glVertex3d(-BASE_SIZE - MAP_SIZE, -BASE_SIZE - MAP_SIZE, 0);
GL11.glTexCoord2f(maxTex, 0);
GL11.glVertex3d(-BASE_SIZE - MAP_SIZE, -BASE_SIZE + MAP_SIZE, 0);
GL11.glEnd();
}
private void bindMapTexture(TextureManager manager) {
if (mapTextureLocation == null) {
mapTextureData = new DynamicTexture(64, 64);
mapTextureLocation = manager.getDynamicTextureLocation("selection_", mapTextureData);
}
manager.bindTexture(mapTextureLocation);
}
}
@Override
public void doRender(Entity entity, double x, double y, double z, float scale, float partialTickTime) {
EntityCartographer cartographer = (EntityCartographer)entity;
GL11.glPushMatrix();
GL11.glTranslated(x, y, z);
GL11.glColor3f(1, 1, 1);
bindTexture(TEXTURE);
MODEL.renderBase(cartographer.eyeYaw);
bindTexture(TextureMap.locationItemsTexture);
MODEL.renderEye(cartographer.eyeYaw, cartographer.eyePitch);
cartographer.updateEye();
GL11.glPopMatrix();
}
@Override
protected ResourceLocation getEntityTexture(Entity entity) {
return TEXTURE;
}
}