package zmaster587.advancedRocketry.inventory;
import java.nio.IntBuffer;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import zmaster587.advancedRocketry.client.render.ClientDynamicTexture;
import zmaster587.advancedRocketry.satellite.SatelliteOreMapping;
import zmaster587.libVulpes.render.RenderHelper;
import zmaster587.libVulpes.util.VulpineMath;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
public class GuiOreMappingSatellite extends GuiContainer {
ClientDynamicTexture texture;
Thread currentMapping;
TileEntity masterConsole;
boolean merged = false;
private static final int SCREEN_SIZE = 146;
private int maxZoom = 128;
private static final int MAXRADIUS = 16;
private static final int FANCYSCANMAXSIZE = 57;
private int fancyScanOffset;
private long prevWorldTickTime;
private int prevSlot;
private int mouseValue;
private int scanSize = 2;
private int radius = 1;
private int xSelected, zSelected, xCenter, zCenter, playerPosZ, playerPosX;
private static final ResourceLocation backdrop = new ResourceLocation("advancedrocketry", "textures/gui/VideoSatallite.png");
int[][] oreMap;
World world;
SatelliteOreMapping tile;
public GuiOreMappingSatellite(SatelliteOreMapping tile,EntityPlayer inventoryPlayer) {
super( new ContainerOreMappingSatallite(tile,inventoryPlayer.inventory));
world = inventoryPlayer.worldObj;
prevSlot = -1;
this.tile = tile;
//masterConsole = tile;
playerPosX = xCenter = (int) inventoryPlayer.posX;
playerPosZ = zCenter = (int) inventoryPlayer.posZ;
//Max zoom is 128
if(tile != null)
maxZoom = (int) Math.pow(2, tile.getZoomRadius());
if(maxZoom == 1)
this.tile = null;
scanSize = maxZoom;
prevWorldTickTime = world.getTotalWorldTime();
fancyScanOffset = 0;
}
//Create separate thread to do this because it takes a while!
Runnable mapper = new Runnable() {
@Override
public void run() {
oreMap = SatelliteOreMapping.scanChunk(world, xCenter, zCenter, scanSize/2, radius);
if(oreMap != null)
merged = true;
else merged = false;
}
};
//Create separate thread to do this because it takes a while!
class ItemMapper implements Runnable {
private ItemStack myBlock;
ItemMapper(ItemStack block) {
//Copy so we dont have any possible CME or oddness due to that
myBlock = block.copy();
}
@Override
public void run() {
oreMap = SatelliteOreMapping.scanChunk(world, xCenter, zCenter, scanSize/2, radius, myBlock);
if(oreMap != null)
merged = true;
else merged = false;
}
};
//Don't pause the game whilst player is looking at the satellite
public boolean doesGuiPauseGame(){ return false; }
private void runMapperWithSelection() {
if(tile == null)
return;
currentMapping.interrupt();
resetTexture();
if(prevSlot == -1) {
currentMapping = new Thread(mapper);
currentMapping.setName("Ore Scan");
}
else {
currentMapping = new Thread(new ItemMapper(inventorySlots.getSlot(prevSlot).getStack()));
currentMapping.setName("Ore Scan");
}
currentMapping.start();
}
@Override
protected void mouseMovedOrUp(int x, int y, int button) {
super.mouseMovedOrUp(x, y, button);
if(tile == null)
return;
int xOffset = 47 + (width - 240) / 2, yOffset = 20 + (height - 192) / 2;
//Get selected slot and begin scan!
if(button == 0 && tile.getSelectedSlot() != prevSlot) {
prevSlot = tile.getSelectedSlot();
runMapperWithSelection();
}
//Clicked off screen don't do anything
if(x < xOffset || x > xOffset + SCREEN_SIZE || y < yOffset || y > yOffset + SCREEN_SIZE)
return;
//If the grid is displayed get the value at this location
if(oreMap != null) {
double numPixels = (scanSize/(float)(SCREEN_SIZE*radius));
mouseValue = oreMap[(int)((x - xOffset) * numPixels)][(int)((y - yOffset) * numPixels)]/0xFF;
xSelected = (int)((x - xOffset) * numPixels) + xCenter - (radius*scanSize/2);
zSelected = (int)((y - yOffset) * numPixels) + zCenter - (radius*scanSize/2);
}
}
@Override
protected void keyTyped(char c, int i) {
if(i == Keyboard.KEY_W) {
zCenter -= radius;
runMapperWithSelection();
}
else if(i == Keyboard.KEY_S) {
zCenter += radius;
runMapperWithSelection();
}
else if(i == Keyboard.KEY_A) {
xCenter -= radius;
runMapperWithSelection();
}
else if(i == Keyboard.KEY_D) {
xCenter += radius;
runMapperWithSelection();
}
else if(i == Keyboard.KEY_DOWN){
scanSize = Math.min(scanSize*2, maxZoom);
runMapperWithSelection();
}
else if(i == Keyboard.KEY_UP) {
if((scanSize/2)/radius > 0) {
scanSize = Math.max(scanSize/2, 2);
runMapperWithSelection();
}
}
//TODO: fix radius
/*else if(i == Keyboard.KEY_LEFT) {
radius = Math.max(radius / 2, 1);
currentMapping.interrupt();
resetTexture();
currentMapping = new Thread(mapper);
currentMapping.start();
} else if(i == Keyboard.KEY_RIGHT) {
if(scanSize/(radius*2) > 0) {
radius = Math.min(radius*2, MAXRADIUS);
currentMapping.interrupt();
resetTexture();
currentMapping = new Thread(mapper);
currentMapping.start();
}
}*/
else
super.keyTyped(c, i);
}
//Create our image here
@Override
public void initGui() {
super.initGui();
texture = new ClientDynamicTexture(Math.max(scanSize/radius,1),Math.max(scanSize/radius,1));
ItemStack stack = inventorySlots.getSlot(0).getStack();
if(tile != null) {
currentMapping = new Thread(mapper);
currentMapping.setName("Ore Scan");
currentMapping.start();
}
}
//Reset the texture and prevent memory leaks
private void resetTexture() {
GL11.glDeleteTextures(texture.getTextureId());
texture = new ClientDynamicTexture(Math.max(scanSize/radius,1),Math.max(scanSize/radius,1));
}
@Override
public void onGuiClosed() {
super.onGuiClosed();
//Delete texture and stop any mapping on close
GL11.glDeleteTextures(texture.getTextureId());
if(currentMapping != null)
currentMapping.interrupt();
}
@Override
protected void drawGuiContainerForegroundLayer(int p_146979_1_, int p_146979_2_) {
Tessellator tessellator = Tessellator.instance;
//Draw fancy things
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glColor3f(0f, 0.8f, 0f);
tessellator.startDrawingQuads();
tessellator.addVertex(-21, 82 + fancyScanOffset, (double)this.zLevel);
tessellator.addVertex(0, 84 + fancyScanOffset, (double)this.zLevel);
tessellator.addVertex(0, 81 + fancyScanOffset, (double)this.zLevel);
tessellator.addVertex(-21, 81 + fancyScanOffset, (double)this.zLevel);
tessellator.draw();
tessellator.startDrawingQuads();
tessellator.addVertex(-21, 82 - fancyScanOffset + FANCYSCANMAXSIZE, (double)this.zLevel);
tessellator.addVertex(0, 84 - fancyScanOffset + FANCYSCANMAXSIZE, (double)this.zLevel);
tessellator.addVertex(0, 81 - fancyScanOffset + FANCYSCANMAXSIZE, (double)this.zLevel);
tessellator.addVertex(-21, 81 - fancyScanOffset + FANCYSCANMAXSIZE, (double)this.zLevel);
tessellator.draw();
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_DST_ALPHA);
GL11.glColor4f(0.5f, 0.5f, 0.0f,0.3f + ((float)Math.sin(Math.PI*(fancyScanOffset/(float)FANCYSCANMAXSIZE))/3f));
tessellator.startDrawingQuads();
tessellator.addVertex(173, 141, (double)this.zLevel);
tessellator.addVertex(194, 141, (double)this.zLevel);
tessellator.addVertex(194, 82, (double)this.zLevel);
tessellator.addVertex(173, 82, (double)this.zLevel);
tessellator.draw();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
if(world.getTotalWorldTime() - prevWorldTickTime >= 1 ) {
prevWorldTickTime = world.getTotalWorldTime();
if(fancyScanOffset >= FANCYSCANMAXSIZE)
fancyScanOffset = 0;
else
fancyScanOffset++;
}
//If a slot is selected draw an indicator
int slot;
if(tile != null && (slot = tile.getSelectedSlot()) != -1) {
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glColor3f(0f, 0.8f, 0f);
tessellator.startDrawingQuads();
tessellator.addVertexWithUV(13 + (18*slot), 155 + 16, (double)this.zLevel, 0, 1);
tessellator.addVertexWithUV(13 + 16 + (18*slot), 155 + 16, (double)this.zLevel, 1, 1);
tessellator.addVertexWithUV(13 + 16 + (18*slot), 155, (double)this.zLevel, 1, 0);
tessellator.addVertexWithUV(13 + (18*slot), 155, (double)this.zLevel, 0, 0);
tessellator.draw();
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
}
@Override
protected void drawGuiContainerBackgroundLayer(float p_146976_1_,
int p_146976_2_, int p_146976_3_) {
int x = (width - 240) / 2, y = (height - 192) / 2;
//If the scan is done then
if(merged) {
IntBuffer buffer = texture.getByteBuffer();
int scanWidth = Math.max(scanSize/radius,1);
for(int yt = 0; yt < (texture.getImage().getHeight() * texture.getImage().getWidth()); yt++) {
buffer.put(yt, oreMap[yt % scanWidth][yt / scanWidth] | 0xFF000000);
}
buffer.flip();
texture.setByteBuffer(buffer);
merged = false;
}
//Render the background then render
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.renderEngine.bindTexture(backdrop);
this.drawTexturedModalRect(x, y, 0, 0, 240, 192);
//NOTE: if the controls are rendered first the display never shows up
//Draw the actual display
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture.getTextureId());
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.addVertexWithUV(47 + x, 20 + y + SCREEN_SIZE, (double)this.zLevel, 0, 1);
tessellator.addVertexWithUV(47 + x + SCREEN_SIZE, 20 + y + SCREEN_SIZE, (double)this.zLevel, 1, 1);
tessellator.addVertexWithUV(47 + x + SCREEN_SIZE, 20 + y, (double)this.zLevel, 1, 0);
tessellator.addVertexWithUV(47 + x, 20 + y, (double)this.zLevel, 0, 0);
tessellator.draw();
//Render player location
float offsetX = playerPosX - xCenter;
float offsetY = zCenter - playerPosZ ;
double numPixels = SCREEN_SIZE/scanSize;//(scanSize/(float)(SCREEN_SIZE*radius));
float radius = 2;
if(Math.abs(offsetX) < scanSize/2 && Math.abs(offsetY) < scanSize/2) {
offsetX *= numPixels;
offsetY *= numPixels;
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glColor3f(0.4f, 1f, 0.4f);
tessellator.startDrawingQuads();
RenderHelper.renderNorthFaceWithUV(tessellator, this.zLevel, offsetX + 47 + x + SCREEN_SIZE/2 - radius, offsetY + 20 + y + SCREEN_SIZE/2 - radius, offsetX + 47 + x + SCREEN_SIZE/2 + radius, offsetY + 20 + y + SCREEN_SIZE/2 + radius, 0, 1, 0, 1);
tessellator.draw();
GL11.glColor3f(1, 1, 1);
GL11.glEnable(GL11.GL_TEXTURE_2D);
this.drawCenteredString(this.fontRendererObj, "You", (int)(offsetX + 47 + x + SCREEN_SIZE/2 - radius), (int)(offsetY + 20 + y + SCREEN_SIZE/2 - radius) -10, 0xF0F0F0);
}
//Render sliders and controls
this.mc.renderEngine.bindTexture(backdrop);
this.drawTexturedModalRect(197 + x, 31 + y, 0, 192, 32, 14);
this.drawVerticalLine((int)(32*VulpineMath.log2(scanSize-1)/8F) + 199 + x, 34 + y, 45 + y, 0xFFC00F0F);
//this.drawTexturedModalRect(197 + x, 63 + y, 0, 192, 32, 14);
//this.drawVerticalLine((int)(28*MathVulpes.log2(radius)/4F) + 199 + x, 67 + y, 77 + y, 0xFF000000);
this.drawString(this.fontRendererObj, "Zoom", 198 + x, 22 + y, 0xF0F0F0);
//this.drawString(this.fontRendererObj, "Clarity", 198 + x, 52 + y, 0xb0b0b0);
this.drawString(this.fontRendererObj, "X: " + xSelected, 6 + x, 33 + y, 0xF0F0F0);
this.drawString(this.fontRendererObj, "Z: " + zSelected, 6 + x, 49 + y, 0xF0F0F0);
//this.drawString(this.fontRendererObj, "Value: ", 6 + x, 65 + y, 0xF0F0F0);
//this.drawString(this.fontRendererObj, String.valueOf(mouseValue), 6 + x, 79 + y, 0xF0F0F0);
}
}