vazkii.botania.client.core.handler.RedStringRenderer.java Source code

Java tutorial

Introduction

Here is the source code for vazkii.botania.client.core.handler.RedStringRenderer.java

Source

/**
 * This class was created by <Vazkii>. It's distributed as
 * part of the Botania Mod. Get the Source Code in github:
 * https://github.com/Vazkii/Botania
 *
 * Botania is Open Source and distributed under the
 * Botania License: http://botaniamod.net/license.php
 *
 * File Created @ [Nov 14, 2014, 7:05:32 PM (GMT)]
 */
package vazkii.botania.client.core.handler;

import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Random;

import org.lwjgl.opengl.GL11;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import vazkii.botania.common.block.tile.string.TileRedString;
import vazkii.botania.common.core.helper.PlayerHelper;
import vazkii.botania.common.core.helper.Vector3;
import vazkii.botania.common.item.ModItems;

public final class RedStringRenderer {

    public static final Queue<TileRedString> redStringTiles = new ArrayDeque<>();
    private static float sizeAlpha = 0F;

    public static void renderAll() {
        if (!redStringTiles.isEmpty()) {
            GlStateManager.pushMatrix();
            GlStateManager.disableTexture2D();
            GlStateManager.enableBlend();
            GL11.glPushAttrib(GL11.GL_LIGHTING_BIT);
            GlStateManager.disableLighting();
            GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
            GlStateManager.color(1F, 0F, 0F, sizeAlpha);

            TileRedString tile;
            while ((tile = redStringTiles.poll()) != null)
                renderTile(tile);

            GlStateManager.enableTexture2D();
            GlStateManager.disableBlend();
            GL11.glPopAttrib();
            GlStateManager.popMatrix();

        }
    }

    public static void tick() {
        EntityPlayer player = Minecraft.getMinecraft().thePlayer;
        boolean hasWand = player != null && PlayerHelper.hasHeldItem(player, ModItems.twigWand);
        if (sizeAlpha > 0F && !hasWand)
            sizeAlpha -= 0.1F;
        else if (sizeAlpha < 1F && hasWand)
            sizeAlpha += 0.1F;
    }

    private static void renderTile(TileRedString tile) {
        double renderPosX, renderPosY, renderPosZ;

        try {
            renderPosX = (double) ClientMethodHandles.renderPosX_getter
                    .invokeExact(Minecraft.getMinecraft().getRenderManager());
            renderPosY = (double) ClientMethodHandles.renderPosY_getter
                    .invokeExact(Minecraft.getMinecraft().getRenderManager());
            renderPosZ = (double) ClientMethodHandles.renderPosZ_getter
                    .invokeExact(Minecraft.getMinecraft().getRenderManager());
        } catch (Throwable t) {
            return;
        }

        EnumFacing dir = tile.getOrientation();
        BlockPos bind = tile.getBinding();

        if (bind != null) {
            GlStateManager.pushMatrix();
            GlStateManager.translate(tile.getPos().getX() + 0.5 - renderPosX,
                    tile.getPos().getY() + 0.5 - renderPosY, tile.getPos().getZ() + 0.5 - renderPosZ);
            Vector3 vecOrig = new Vector3(bind.getX() - tile.getPos().getX(), bind.getY() - tile.getPos().getY(),
                    bind.getZ() - tile.getPos().getZ());
            Vector3 vecNorm = vecOrig.normalize();
            Vector3 vecMag = vecNorm.multiply(0.025);
            Vector3 vecApply = vecMag;

            int stages = (int) (vecOrig.mag() / vecMag.mag());

            Tessellator tessellator = Tessellator.getInstance();
            GL11.glLineWidth(1F);
            tessellator.getBuffer().begin(GL11.GL_LINES, DefaultVertexFormats.POSITION);

            double len = (double) -ClientTickHandler.ticksInGame / 100F
                    + new Random(dir.ordinal() ^ tile.getPos().hashCode()).nextInt(10000);
            double add = vecMag.mag();
            double rand = Math.random() - 0.5;
            for (int i = 0; i < stages; i++) {
                addVertexAtWithTranslation(tessellator, dir, vecApply.x, vecApply.y, vecApply.z, rand, len);
                rand = Math.random() - 0.5;
                vecApply = vecApply.add(vecMag);
                len += add;
                addVertexAtWithTranslation(tessellator, dir, vecApply.x, vecApply.y, vecApply.z, rand, len);
            }

            tessellator.draw();

            GlStateManager.popMatrix();
        }
    }

    private static void addVertexAtWithTranslation(Tessellator tess, EnumFacing dir, double xpos, double ypos,
            double zpos, double rand, double l) {
        double freq = 20;
        double ampl = (0.15 * (Math.sin(l * 2F) * 0.5 + 0.5) + 0.1) * sizeAlpha;
        double randMul = 0.05;
        double x = xpos + Math.sin(l * freq) * ampl * Math.abs(Math.abs(dir.getFrontOffsetX()) - 1)
                + rand * randMul;
        double y = ypos + Math.cos(l * freq) * ampl * Math.abs(Math.abs(dir.getFrontOffsetY()) - 1)
                + rand * randMul;
        double z = zpos + (dir.getFrontOffsetY() == 0 ? Math.sin(l * freq) : Math.cos(l * freq)) * ampl
                * Math.abs(Math.abs(dir.getFrontOffsetZ()) - 1) + rand * randMul;

        tess.getBuffer().pos(x, y, z).endVertex();
    }

}