Package crazypants.enderio.enderface

Source Code of crazypants.enderio.enderface.GuiEnderface

package crazypants.enderio.enderface;

import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.client.ForgeHooksClient;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;

import crazypants.enderio.EnderIO;
import crazypants.enderio.config.Config;
import crazypants.enderio.network.PacketHandler;
import crazypants.enderio.teleport.TravelController;
import crazypants.render.RenderUtil;
import crazypants.util.BlockCoord;
import crazypants.vecmath.Camera;
import crazypants.vecmath.Matrix4d;
import crazypants.vecmath.VecmathUtil;
import crazypants.vecmath.Vector3d;

public class GuiEnderface extends GuiScreen {

  protected static final RenderBlocks RB = new RenderBlocks();

  private float pitch = -45;
  private float yaw = 45;

  private final EntityPlayer player;
  private final World world;
  private final int ioX;
  private final int ioY;
  private final int ioZ;
  private boolean chunkLoaded;

  private List<ViewableBlocks> blocks = new ArrayList<ViewableBlocks>();

  private int gw;
  private int gh;
  private int guiLeft;
  private int guiTop;
  private int finalGw;
  private int finalGh;
  // private boolean animateInX = true;
  private boolean animateInX = false;
  private boolean animateInY = false;
  // private boolean animating = true;
  float animationDuration = 60;

  private final Vector3d origin = new Vector3d();
  private final Vector3d eye = new Vector3d();
  private final Camera camera = new Camera();
  private final Matrix4d pitchRot = new Matrix4d();
  private final Matrix4d yawRot = new Matrix4d();

  private float scaleAnimX;

  private int range;

  boolean dragging = false;

  private double distance;

  private long initTime;

  public GuiEnderface(EntityPlayer player, World world, int ioX, int ioY, int ioZ) {
    this.player = player;
    this.world = world;
    this.ioX = ioX;
    this.ioY = ioY;
    this.ioZ = ioZ;

    range = Config.enderIoRange;
    distance = 10 + (range * 2);

    TileEntity te = world.getTileEntity(ioX, ioY, ioZ);
    if(te instanceof TileEnderIO) {
      pitch = ((TileEnderIO) te).lastUiPitch;
      yaw = ((TileEnderIO) te).lastUiYaw;
      distance = ((TileEnderIO) te).lastUiDistance;
    }

    origin.set(ioX + 0.5, ioY + 0.5, ioZ + 0.5);
    pitchRot.setIdentity();
    yawRot.setIdentity();

    Chunk c = world.getChunkFromBlockCoords(ioX, ioZ);
    chunkLoaded = c != null && c.isChunkLoaded;
    RB.blockAccess = world;

    blocks.add(new ViewableBlocks(ioX, ioY, ioZ, EnderIO.blockEnderIo));

    for (int x = ioX - range; x <= ioX + range; x++) {
      for (int y = ioY - range; y <= ioY + range; y++) {
        for (int z = ioZ - range; z <= ioZ + range; z++) {
          Block block = world.getBlock(x, y, z);
          blocks.add(new ViewableBlocks(x, y, z, block));
        }
      }
    }
  }

  @Override
  public void onGuiClosed() {
    TileEntity te = world.getTileEntity(ioX, ioY, ioZ);
    if(te instanceof TileEnderIO) {
      ((TileEnderIO) te).lastUiPitch = pitch;
      ((TileEnderIO) te).lastUiYaw = yaw;
      ((TileEnderIO) te).lastUiDistance = distance;
    }
  }

  /**
   * Adds the buttons (and other controls) to the screen in question.
   */
  @Override
  public void initGui() {

    finalGw = width * 1;
    finalGh = height * 1;
    // gw = finalGw - 1;
    // gh = finalGh - 1;
    gw = finalGw;
    gh = finalGh;
    // gw = 0;
    // gh = 0;
    guiLeft = (width - gw) / 2;
    guiTop = (height - gh) / 2;

    initTime = world.getTotalWorldTime();
  }

  @Override
  public boolean doesGuiPauseGame() {
    return false;
  }

  /**
   * Handles mouse input.
   */
  @Override
  public void handleMouseInput() {
    super.handleMouseInput();

    if(Mouse.getEventButton() == 0) {
      dragging = Mouse.getEventButtonState();
    }

    if(dragging) {

      double dx = (Mouse.getEventDX() / (double) mc.displayWidth);
      double dy = (Mouse.getEventDY() / (double) mc.displayHeight);
      if(Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
        distance -= dy * 15;
      } else {
        yaw -= dx * 180;
        pitch += dy * 180;
        pitch = (float) VecmathUtil.clamp(pitch, -80, 80);
      }
    }

    distance -= Mouse.getDWheel() * 0.01;
    distance = VecmathUtil.clamp(distance, 0.1, 20);

    long elapsed = world.getTotalWorldTime() - initTime;

    if(Mouse.getEventButton() == 1 && !Mouse.getEventButtonState() && camera.isValid() && elapsed > 10) {

      int x = Mouse.getEventX();
      int y = Mouse.getEventY();
      Vector3d start = new Vector3d();
      Vector3d end = new Vector3d();
      if(camera.getRayForPixel(x, y, start, end)) {
        end.scale(distance * 2);
        end.add(start);
        doSelection(start, end);
      }

    }

  }

  private void doSelection(Vector3d start, Vector3d end) {
    start.add(origin);
    end.add(origin);
    List<MovingObjectPosition> hits = new ArrayList<MovingObjectPosition>();
    for (ViewableBlocks ug : blocks) {
      if(!ug.bc.equals(new BlockCoord(ioX, ioY, ioZ))) {
        MovingObjectPosition res = player.worldObj.rayTraceBlocks(Vec3.createVectorHelper(start.x, start.y, start.z),
            Vec3.createVectorHelper(end.x, end.y, end.z), false);

        if(res != null) {
          hits.add(res);
        }
      }
    }
    MovingObjectPosition hit = getClosestHit(Vec3.createVectorHelper(start.x, start.y, start.z), hits);
    if(hit != null) {
      Block block = world.getBlock(hit.blockX, hit.blockY, hit.blockZ);
      if(block == EnderIO.blockHyperCube || block == EnderIO.blockCapacitorBank) {
        block.onBlockActivated(world, hit.blockX, hit.blockY, hit.blockZ, player, 0, 0, 0, 0);
      } else {
        openInterface(hit.blockX, hit.blockY, hit.blockZ);
      }
    }

  }

  public static MovingObjectPosition getClosestHit(Vec3 origin, Collection<MovingObjectPosition> candidates) {
    double minLengthSquared = Double.POSITIVE_INFINITY;
    MovingObjectPosition closest = null;

    for (MovingObjectPosition hit : candidates) {
      if(hit != null) {
        double lengthSquared = hit.hitVec.squareDistanceTo(origin);
        if(lengthSquared < minLengthSquared) {
          minLengthSquared = lengthSquared;
          closest = hit;
        }
      }
    }
    return closest;
  }

  /**
   * Draws the screen and all the components in it.
   */
  @Override
  public void drawScreen(int par1, int par2, float partialTick) {

    animateBackground(partialTick);
    drawDefaultBackground();

    RenderHelper.disableStandardItemLighting();
    RenderHelper.enableGUIStandardItemLighting();
    drawEnderfaceBackground();

    if(!updateCamera(partialTick)) {
      return;
    }
    applyCamera(partialTick);

    if(!animateInX && !animateInY) {

      if(chunkLoaded) {

        //TODO: Need to depth sort transparent passes

        TravelController.instance.setSelectionEnabled(false);

        GL11.glEnable(GL11.GL_CULL_FACE);
        GL11.glEnable(GL12.GL_RESCALE_NORMAL);

        RenderHelper.disableStandardItemLighting();
        mc.entityRenderer.enableLightmap(0);
        RenderUtil.bindBlockTexture();

        Vector3d trans = new Vector3d((-origin.x) + eye.x, (-origin.y) + eye.y, (-origin.z) + eye.z);
        for (int pass = 0; pass < 2; pass++) {

          ForgeHooksClient.setRenderPass(pass);
          setGlStateForPass(pass);

          Tessellator.instance.startDrawingQuads();
          Tessellator.instance.setTranslation(trans.x, trans.y, trans.z);

          for (ViewableBlocks ug : blocks) {
            if(ug.block.canRenderInPass(pass)) {
              RB.setRenderBounds(0, 0, 0, 1, 1, 1);
              RB.renderBlockByRenderType(ug.block, ug.bc.x, ug.bc.y, ug.bc.z);
            }
          }
          Tessellator.instance.draw();
          Tessellator.instance.setTranslation(0, 0, 0);
        }

        RenderHelper.enableStandardItemLighting();

        TileEntityRendererDispatcher.instance.field_147558_l = origin.x - eye.x;
        TileEntityRendererDispatcher.instance.field_147560_j = origin.y - eye.y;
        TileEntityRendererDispatcher.instance.field_147561_k = origin.z - eye.z;

        TileEntityRendererDispatcher.staticPlayerX = origin.x - eye.x;
        TileEntityRendererDispatcher.staticPlayerY = origin.y - eye.y;
        TileEntityRendererDispatcher.staticPlayerZ = origin.z - eye.z;

        for (int pass = 0; pass < 2; pass++) {

          ForgeHooksClient.setRenderPass(pass);
          setGlStateForPass(pass);

          for (ViewableBlocks ug : blocks) {
            TileEntity tile = world.getTileEntity(ug.bc.x, ug.bc.y, ug.bc.z);
            if(tile != null) {
              Vector3d at = new Vector3d(eye.x - 0.5, eye.y - 0.5, eye.z - 0.5);
              at.x += ug.bc.x - ioX;
              at.y += ug.bc.y - ioY;
              at.z += ug.bc.z - ioZ;
              TileEntityRendererDispatcher.instance.renderTileEntityAt(tile, at.x, at.y, at.z, 0);
            }
          }
        }
        ForgeHooksClient.setRenderPass(-1);
        setGlStateForPass(0);
        TravelController.instance.setSelectionEnabled(true);

      } else {
        drawCenteredString(Minecraft.getMinecraft().fontRenderer, "EnderIO chunk not loaded.", width / 2, height / 2 - 32, 0xFFFFFFFF);
      }
    }

    drawEffectOverlay(partialTick);
  }

  private void setGlStateForPass(int pass) {
    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    if(pass == 0) {
      GL11.glDisable(GL11.GL_BLEND);
      GL11.glDepthMask(true);
    } else {
      GL11.glEnable(GL11.GL_BLEND);
      GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
      GL11.glDepthMask(false);
    }

  }

  private boolean updateCamera(float partialTick) {
    ScaledResolution scaledresolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
    int vpx = guiLeft * scaledresolution.getScaleFactor();
    int vpy = guiTop * scaledresolution.getScaleFactor();
    int vpw = (int) ((float) gw / width * mc.displayWidth);
    int vph = (int) ((float) gh / height * mc.displayHeight);
    if(vpw <= 0 || vph <= 0) {
      return false;
    }

    camera.setViewport(vpx, vpy, vpw, vph);
    camera.setProjectionMatrixAsPerspective(30, 0.05, 50, vpw, vph);

    eye.set(0, 0, distance);
    pitchRot.makeRotationX(Math.toRadians(pitch));
    yawRot.makeRotationY(Math.toRadians(yaw));
    pitchRot.transform(eye);
    yawRot.transform(eye);
    camera.setViewMatrixAsLookAt(eye, RenderUtil.ZERO_V, RenderUtil.UP_V);
    return camera.isValid();
  }

  private void applyCamera(float partialTick) {
    Rectangle vp = camera.getViewport();
    GL11.glViewport(vp.x, vp.y, vp.width, vp.height);
    GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    RenderUtil.loadMatrix(camera.getTransposeProjectionMatrix());
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    RenderUtil.loadMatrix(camera.getTransposeViewMatrix());

    scaleAnimX += (partialTick * 0.25);
    float v = 0.4f;
    float sf = 1.0F * (1 + v / 32);
    GL11.glRotatef((scaleAnimX + partialTick) * 7, 0.0F, 1.0F, 1.0F);
    GL11.glScalef(sf, 1.0F, 1.0f);
    GL11.glRotatef(-(scaleAnimX + partialTick) * 7, 0.0F, 1.0F, 1.0F);

    GL11.glTranslatef(-(float) eye.x, -(float) eye.y, -(float) eye.z);
  }

  private float portalFade = 1;

  private void drawEffectOverlay(float partialTick) {
    ScaledResolution scaledresolution = new ScaledResolution(this.mc, this.mc.displayWidth, this.mc.displayHeight);
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(0.0D, scaledresolution.getScaledWidth_double(), scaledresolution.getScaledHeight_double(), 0.0D, 1000.0D, 3000.0D);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();
    GL11.glTranslatef(0.0F, 0.0F, -2000.0F);
    GL11.glEnable(GL11.GL_BLEND);
    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    GL11.glDisable(GL11.GL_DEPTH_TEST);
    GL11.glDisable(GL11.GL_ALPHA_TEST);
    GL11.glDepthMask(false);

    RenderHelper.disableStandardItemLighting();
    RenderHelper.enableGUIStandardItemLighting();

    GL11.glDisable(GL11.GL_LIGHTING);
    mc.entityRenderer.disableLightmap(0);

    portalFade -= (partialTick * (1f / animationDuration));
    portalFade = Math.max(0, portalFade);
    if(portalFade >= 0) {
      drawRect(scaledresolution.getScaledWidth(), scaledresolution.getScaledHeight(), 0, 0.3f, 0.16f, Math.max(0.3f, portalFade));
    }

    GL11.glEnable(GL11.GL_LIGHTING);
    mc.entityRenderer.enableLightmap(0);

    renderPortalOverlay(0.8f - (0.2f * (1 - portalFade)), scaledresolution.getScaledWidth(), scaledresolution.getScaledHeight());

    GL11.glDepthMask(true);
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glEnable(GL11.GL_ALPHA_TEST);
    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);

  }

  /**
   * Renders the portal overlay. Args: portalStrength, width, height
   */
  protected void renderPortalOverlay(float par1, int par2, int par3) {
    if(par1 < 1.0F) {
      par1 *= par1;
      par1 *= par1;
      par1 = par1 * 0.9F + 0.1F;
    }
    GL11.glColor4f(1.0F, 1.0F, 1.0F, par1);
    RenderUtil.bindBlockTexture();
    IIcon icon = Blocks.portal.getBlockTextureFromSide(1);
    float f1 = icon.getMinU();
    float f2 = icon.getMinV();
    float f3 = icon.getMaxU();
    float f4 = icon.getMaxV();
    Tessellator tessellator = Tessellator.instance;
    tessellator.startDrawingQuads();
    tessellator.addVertexWithUV(0.0D, par3, -90.0D, f1, f4);
    tessellator.addVertexWithUV(par2, par3, -90.0D, f3, f4);
    tessellator.addVertexWithUV(par2, 0.0D, -90.0D, f3, f2);
    tessellator.addVertexWithUV(0.0D, 0.0D, -90.0D, f1, f2);
    tessellator.draw();
  }

  private boolean animating() {
    return gw < finalGw || gh < finalGh;
  }

  private void drawRect(int width, int height, float r, float g,
      float b, float a) {
    Tessellator tessellator = Tessellator.instance;
    GL11.glDisable(GL11.GL_TEXTURE_2D);
    GL11.glColor4f(r, g, b, a);
    tessellator.startDrawingQuads();
    tessellator.addVertex(0.0D, height, 0.0D);
    tessellator.addVertex(width, height, 0.0D);
    tessellator.addVertex(width, 0.0D, 0.0D);
    tessellator.addVertex(0.0D, 0.0D, 0.0D);
    tessellator.draw();
    GL11.glEnable(GL11.GL_TEXTURE_2D);
  }

  private void animateBackground(float partialTick) {

    if(!animating()) {
      return;
    }

    // if (animateInX) {
    // animationDuration *= 0.8;
    // }
    int mag = (int) ((width / (animationDuration * 0.5f)) * partialTick);
    int mag2 = mag * 2;

    int ymag = (int) ((height / (animationDuration * 0.5f)) * partialTick);
    // int ymag = mag;
    int ymag2 = ymag * 2;

    if(animateInX) {
      gw -= mag2;
      guiLeft += mag;
      if(gw <= 0) {
        animateInX = false;
        // animateInY = false;
      }
    } else {
      gw += mag2;
      guiLeft -= mag;
    }

    if(animateInY) {
      gh -= ymag2;
      guiTop += ymag;
      if(gh <= 0) {
        animateInY = false;
        // animateInX= false;
      }
    } else {
      gh += ymag2;
      guiTop -= ymag;
    }

    gw = Math.min(gw, finalGw);
    gh = Math.min(gh, finalGh);
    guiLeft = Math.max((width - finalGw) / 2, guiLeft);
    guiTop = Math.max((height - finalGh) / 2, guiTop);

  }

  private void drawEnderfaceBackground() {

    int w = this.gw;
    int h = this.gh;
    int left = this.guiLeft;
    int top = this.guiTop;
    int cx = left + w / 2;
    int cy = top + h / 2;

    // black outline
    drawRect(left, top, left + w, top + h, 0xFF000000);
    left += 1;
    top += 1;
    w -= 2;
    h -= 2;

    // border
    int topH = 0xFFFFFFFF;
    int botH = 0xFF555555;
    int rightH = 0xFF555555;
    int leftH = 0xFFFFFFFF;
    if(animateInX) {
      leftH = 0xFF555555;
      rightH = 0xFFFFFFFF;
    }
    if(animateInY) {
      topH = 0xFF555555;
      botH = 0xFFFFFFFF;
    }

    left += 1;
    top += 1;
    w -= 2;
    h -= 2;
    drawRect(left, top, left + w, top + h, 0xFF00331C);

  }

  void openInterface(int x, int y, int z) {
    PacketOpenRemoteUi p = new PacketOpenRemoteUi(x, y, z);
    PacketHandler.INSTANCE.sendToServer(p);
  }

  static class ViewableBlocks {
    BlockCoord bc;
    Block block;

    private ViewableBlocks(int x, int y, int z, Block block) {
      super();
      this.bc = new BlockCoord(x, y, z);
      this.block = block;
    }

  }

}
TOP

Related Classes of crazypants.enderio.enderface.GuiEnderface

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.