vazkii.b_baubles.common.item.equipment.bauble.ItemFlightTiara.java Source code

Java tutorial

Introduction

Here is the source code for vazkii.b_baubles.common.item.equipment.bauble.ItemFlightTiara.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 @ [May 26, 2014, 4:05:50 PM (GMT)]
 */
package vazkii.b_baubles.common.item.equipment.bauble;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.adapters.HexBinaryAdapter;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.Achievement;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraftforge.client.event.RenderPlayerEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;

import org.lwjgl.opengl.GL11;

import vazkii.b_baubles.api.BotaniaAPI;
import vazkii.b_baubles.api.item.IBaubleRender;
import vazkii.b_baubles.client.core.helper.IconHelper;
import vazkii.b_baubles.client.core.helper.RenderHelper;
import vazkii.b_baubles.client.lib.LibResources;
import vazkii.b_baubles.common.Botania;
import vazkii.b_baubles.common.core.handler.ConfigHandler;
import vazkii.b_baubles.common.core.helper.ItemNBTHelper;
import vazkii.b_baubles.common.core.helper.Vector3;
import vazkii.b_baubles.common.item.ModItems;
import vazkii.b_baubles.common.lib.LibItemNames;
import baubles.api.BaubleType;
import baubles.common.lib.PlayerHandler;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.PlayerEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class ItemFlightTiara extends ItemBauble implements IBaubleRender {

    private static ResourceLocation textureHud = new ResourceLocation(LibResources.GUI_HUD_ICONS);

    private static final String TAG_FLYING = "flying";
    private static final String TAG_TIME_LEFT = "timeLeft";
    private static final String TAG_INFINITE_FLIGHT = "infiniteFlight";
    private static final String TAG_DASH_COOLDOWN = "dashCooldown";
    private static final String TAG_IS_SPRINTING = "isSprinting";

    public static List<String> playersWithFlight = new ArrayList();
    private static final int COST = 0;
    private static final int COST_OVERKILL = COST * 3;
    private static int MAX_FLY_TIME = ConfigHandler.flugelTiaraMaxFlyTime;

    public static IIcon[] wingIcons;
    private static final int SUBTYPES = 5;
    private static final int WING_TYPES = 5;

    public ItemFlightTiara() {
        super(LibItemNames.FLIGHT_TIARA);
        MinecraftForge.EVENT_BUS.register(this);
        FMLCommonHandler.instance().bus().register(this);
        setHasSubtypes(true);
        if (ConfigHandler.flugelTiaraNerfDisabled) {
            MAX_FLY_TIME = Integer.MAX_VALUE;
        }
    }

    @Override
    public BaubleType getBaubleType(ItemStack arg0) {
        return BaubleType.AMULET;
    }

    @Override
    @SideOnly(Side.CLIENT)
    public void registerIcons(IIconRegister par1IconRegister) {
        itemIcon = IconHelper.forItem(par1IconRegister, this, 0);
        wingIcons = new IIcon[WING_TYPES];
        for (int i = 0; i < WING_TYPES; i++)
            wingIcons[i] = IconHelper.forItem(par1IconRegister, this, i + 1);
    }

    @Override
    public void getSubItems(Item item, CreativeTabs tab, List list) {
        for (int i = 0; i < SUBTYPES + 1; i++)
            list.add(new ItemStack(item, 1, i));
    }

    @Override
    public void addHiddenTooltip(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List,
            boolean par4) {
        super.addHiddenTooltip(par1ItemStack, par2EntityPlayer, par3List, par4);
        par3List.add(StatCollector.translateToLocal("b_baubles.wings" + par1ItemStack.getItemDamage()));
    }

    @Override
    public void onEquipped(ItemStack stack, EntityLivingBase player) {
        super.onEquipped(stack, player);
        if (stack.getItemDamage() != WING_TYPES && hash(stack.getDisplayName())
                .equals("16E1BDFD1D6AE1A954C9C5E1B2D9099780F3E1724541F1F2F77310B769CFFBAC")) {
            stack.setItemDamage(WING_TYPES);
            stack.getTagCompound().removeTag("display");
        }
    }

    String hash(String str) {
        if (str != null)
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-256");
                return new HexBinaryAdapter().marshal(md.digest(salt(str).getBytes()));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        return "";
    }

    // Might as well be called sugar given it's not secure at all :D
    String salt(String str) {
        str = str += "wowsuchsaltmuchsecurityverywow";
        SecureRandom rand = new SecureRandom(str.getBytes());
        int l = str.length();
        int steps = rand.nextInt(l);
        char[] chrs = str.toCharArray();
        for (int i = 0; i < steps; i++) {
            int indA = rand.nextInt(l);
            int indB;
            do {
                indB = rand.nextInt(l);
            } while (indB == indA);
            char c = (char) (chrs[indA] ^ chrs[indB]);
            chrs[indA] = c;
        }

        return String.copyValueOf(chrs);
    }

    @Override
    public void onWornTick(ItemStack stack, EntityLivingBase player) {
        super.onWornTick(stack, player);

        if (player instanceof EntityPlayer) {
            EntityPlayer p = (EntityPlayer) player;
            boolean flying = p.capabilities.isFlying;

            boolean wasSprting = ItemNBTHelper.getBoolean(stack, TAG_IS_SPRINTING, false);
            boolean isSprinting = p.isSprinting();
            if (isSprinting != wasSprting)
                ItemNBTHelper.setBoolean(stack, TAG_IS_SPRINTING, isSprinting);

            int time = ItemNBTHelper.getInt(stack, TAG_TIME_LEFT, MAX_FLY_TIME);
            int newTime = time;
            Vector3 look = new Vector3(p.getLookVec());
            look.y = 0;
            look.normalize();

            if (flying) {
                if (time > 0 && !ItemNBTHelper.getBoolean(stack, TAG_INFINITE_FLIGHT, false))
                    newTime--;
                final int maxCd = 80;
                int cooldown = ItemNBTHelper.getInt(stack, TAG_DASH_COOLDOWN, 0);
                if (!wasSprting && isSprinting && cooldown == 0) {
                    p.motionX += look.x;
                    p.motionZ += look.z;
                    p.worldObj.playSoundAtEntity(p, "b_baubles:dash", 1F, 1F);
                    ItemNBTHelper.setInt(stack, TAG_DASH_COOLDOWN, maxCd);
                } else if (cooldown > 0) {
                    if (maxCd - cooldown < 2)
                        player.moveFlying(0F, 1F, 5F);
                    else if (maxCd - cooldown < 10)
                        player.setSprinting(false);
                    ItemNBTHelper.setInt(stack, TAG_DASH_COOLDOWN, cooldown - 2);
                    if (player instanceof EntityPlayerMP)
                        BotaniaAPI.internalHandler.sendBaubleUpdatePacket((EntityPlayerMP) player, 0);
                }
            } else if (!flying) {
                boolean doGlide = player.isSneaking() && !player.onGround;
                if (time < MAX_FLY_TIME && player.ticksExisted % (doGlide ? 6 : 2) == 0)
                    newTime++;

                if (doGlide) {
                    player.motionY = Math.max(-0.15F, player.motionY);
                    float mul = 0.6F;
                    player.motionX = look.x * mul;
                    player.motionZ = look.z * mul;
                    player.fallDistance = 0F;
                }
            }

            ItemNBTHelper.setBoolean(stack, TAG_FLYING, flying);
            if (newTime != time)
                ItemNBTHelper.setInt(stack, TAG_TIME_LEFT, newTime);
        }
    }

    @SubscribeEvent
    public void updatePlayerFlyStatus(LivingUpdateEvent event) {
        if (event.entityLiving instanceof EntityPlayer) {
            EntityPlayer player = (EntityPlayer) event.entityLiving;
            ItemStack tiara = PlayerHandler.getPlayerBaubles(player).getStackInSlot(0);
            int left = ItemNBTHelper.getInt(tiara, TAG_TIME_LEFT, MAX_FLY_TIME);

            if (playersWithFlight.contains(playerStr(player))) {
                if (shouldPlayerHaveFlight(player)) {
                    player.capabilities.allowFlying = true;
                    if (player.capabilities.isFlying) {
                        if (!player.worldObj.isRemote)
                            ;
                        else if (Math.abs(player.motionX) > 0.1 || Math.abs(player.motionZ) > 0.1) {
                            double x = event.entityLiving.posX - 0.5;
                            double y = event.entityLiving.posY - 1.7;
                            double z = event.entityLiving.posZ - 0.5;

                            player.getGameProfile().getName();
                            float r = 1F;
                            float g = 1F;
                            float b = 1F;

                            switch (tiara.getItemDamage()) {
                            case 2: {
                                r = 0.1F;
                                g = 0.1F;
                                b = 0.1F;
                                break;
                            }
                            case 3: {
                                r = 0F;
                                g = 0.6F;
                                break;
                            }
                            case 4: {
                                g = 0.3F;
                                b = 0.3F;
                                break;
                            }

                            case 5: {
                                r = 0.2F;
                                g = 0.6F;
                                b = 0.2F;
                                break;
                            }

                            }

                            for (int i = 0; i < 2; i++)
                                Botania.proxy.sparkleFX(event.entityLiving.worldObj,
                                        x + Math.random() * event.entityLiving.width, y + Math.random() * 0.4,
                                        z + Math.random() * event.entityLiving.width, r, g, b,
                                        2F * (float) Math.random(), 20);
                        }
                    }
                } else {
                    if (!player.capabilities.isCreativeMode) {
                        player.capabilities.allowFlying = false;
                        player.capabilities.isFlying = false;
                        player.capabilities.disableDamage = false;
                    }
                    playersWithFlight.remove(playerStr(player));
                }
            } else if (shouldPlayerHaveFlight(player)) {
                playersWithFlight.add(playerStr(player));
                player.capabilities.allowFlying = true;
            }
        }
    }

    @SubscribeEvent
    public void playerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) {
        String username = event.player.getGameProfile().getName();
        playersWithFlight.remove(username + ":false");
        playersWithFlight.remove(username + ":true");
    }

    public static String playerStr(EntityPlayer player) {
        return player.getGameProfile().getName() + ":" + player.worldObj.isRemote;
    }

    private boolean shouldPlayerHaveFlight(EntityPlayer player) {
        ItemStack armor = PlayerHandler.getPlayerBaubles(player).getStackInSlot(0);
        if (armor != null && armor.getItem() == this) {
            int left = ItemNBTHelper.getInt(armor, TAG_TIME_LEFT, MAX_FLY_TIME);
            boolean flying = ItemNBTHelper.getBoolean(armor, TAG_FLYING, false);
            return (left > (flying ? 0 : MAX_FLY_TIME / 10));
        }

        return false;
    }

    public int getCost(ItemStack stack, int timeLeft) {
        return timeLeft <= 0 ? COST_OVERKILL : COST;
    }

    @Override
    @SideOnly(Side.CLIENT)
    public void onPlayerBaubleRender(ItemStack stack, RenderPlayerEvent event, RenderType type) {
        int meta = stack.getItemDamage();
        if (type == RenderType.BODY) {
            if (meta > 0 && meta <= ItemFlightTiara.wingIcons.length) {
                IIcon icon = ItemFlightTiara.wingIcons[meta - 1];
                Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationItemsTexture);

                boolean flying = event.entityPlayer.capabilities.isFlying;

                float rz = 120F;
                float rx = 20F
                        + (float) ((Math.sin((double) (event.entityPlayer.ticksExisted + event.partialRenderTick)
                                * (flying ? 0.4F : 0.2F)) + 0.5F) * (flying ? 30F : 5F));
                float ry = 0F;
                float h = 0.2F;
                float i = 0.15F;
                float s = 1F;

                GL11.glPushMatrix();
                GL11.glEnable(GL11.GL_BLEND);
                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
                GL11.glColor4f(1F, 1F, 1F, 1F);

                int light = 15728880;
                int lightmapX = light % 65536;
                int lightmapY = light / 65536;
                switch (meta) {
                case 1: { // White wing
                    h = 0.4F;
                    break;
                }
                case 2: { // Black wing
                    s = 1.3F;
                    break;
                }
                case 3: { // Ice fairy
                    h = -0.1F;
                    rz = 0F;
                    rx = 0F;
                    i = 0.3F;
                    break;
                }
                case 4: { // Phoenix
                    rz = 180F;
                    h = 0.5F;
                    rx = 20F;
                    ry = -(float) ((Math.sin((double) (event.entityPlayer.ticksExisted + event.partialRenderTick)
                            * (flying ? 0.4F : 0.2F)) + 0.6F) * (flying ? 30F : 5F));
                    OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, lightmapX, lightmapY);
                    break;
                }

                case 5: { // Pixie
                    h = -0.1F;
                    rz = 0F;
                    ry = -rx;
                    rx = 0F;
                    GL11.glColor4f(1F, 1F, 1F,
                            0.5F + (float) Math.cos(
                                    (double) (event.entityPlayer.ticksExisted + event.partialRenderTick) * 0.3F)
                                    * 0.2F);
                    break;
                }

                }

                float f = icon.getMinU();
                float f1 = icon.getMaxU();
                float f2 = icon.getMinV();
                float f3 = icon.getMaxV();
                float sr = 1F / s;

                Helper.rotateIfSneaking(event.entityPlayer);

                GL11.glTranslatef(0F, h, i);

                GL11.glRotatef(rz, 0F, 0F, 1F);
                GL11.glRotatef(rx, 1F, 0F, 0F);
                GL11.glRotatef(ry, 0F, 1F, 0F);
                GL11.glScalef(s, s, s);
                ItemRenderer.renderItemIn2D(Tessellator.instance, f1, f2, f, f3, icon.getIconWidth(),
                        icon.getIconHeight(), 1F / 32F);
                GL11.glScalef(sr, sr, sr);
                GL11.glRotatef(-ry, 0F, 1F, 0F);
                GL11.glRotatef(-rx, 1F, 0F, 0F);
                GL11.glRotatef(-rz, 0F, 0F, 1F);

                if (meta != 0) { // Sephiroth
                    GL11.glScalef(-1F, 1F, 1F);
                    GL11.glRotatef(rz, 0F, 0F, 1F);
                    GL11.glRotatef(rx, 1F, 0F, 0F);
                    GL11.glRotatef(ry, 0F, 1F, 0F);
                    GL11.glScalef(s, s, s);
                    ItemRenderer.renderItemIn2D(Tessellator.instance, f1, f2, f, f3, icon.getIconWidth(),
                            icon.getIconHeight(), 1F / 32F);
                    GL11.glScalef(sr, sr, sr);
                    GL11.glRotatef(-ry, 1F, 0F, 0F);
                    GL11.glRotatef(-rx, 1F, 0F, 0F);
                    GL11.glRotatef(-rz, 0F, 0F, 1F);
                }

                GL11.glColor3f(1F, 1F, 1F);
                GL11.glPopMatrix();
            }
        }
    }

    @SideOnly(Side.CLIENT)
    public static void renderHUD(ScaledResolution resolution, EntityPlayer player, ItemStack stack) {
        int u = Math.max(1, stack.getItemDamage()) * 9 - 9;
        int v = 0;

        Minecraft mc = Minecraft.getMinecraft();
        mc.renderEngine.bindTexture(textureHud);
        int xo = resolution.getScaledWidth() / 2 + 10;
        int x = xo;
        int y = resolution.getScaledHeight() - 49;
        if (player.getAir() < 300)
            y -= 10;

        int left = ItemNBTHelper.getInt(stack, TAG_TIME_LEFT, MAX_FLY_TIME);

        int segTime = MAX_FLY_TIME / 10;
        int segs = left / segTime + 1;
        int last = left % segTime;
        if (!ConfigHandler.flugelTiaraNerfDisabled) {
            for (int i = 0; i < segs; i++) {
                float trans = 1F;
                if (i == segs - 1) {
                    trans = (float) last / (float) segTime;
                    GL11.glEnable(GL11.GL_BLEND);
                    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
                    GL11.glDisable(GL11.GL_ALPHA_TEST);
                }

                GL11.glColor4f(1F, 1F, 1F, trans);
                RenderHelper.drawTexturedModalRect(x, y, 0, u, v, 9, 9);
                x += 8;
            }
        }
        if (player.capabilities.isFlying) {
            int width = ItemNBTHelper.getInt(stack, TAG_DASH_COOLDOWN, 0);
            GL11.glColor4f(1F, 1F, 1F, 1F);
            if (width > 0)
                Gui.drawRect(xo, y - 2, xo + 80, y - 1, 0x88000000);
            Gui.drawRect(xo, y - 2, xo + width, y - 1, 0xFFFFFFFF);
        }

        GL11.glEnable(GL11.GL_ALPHA_TEST);
        GL11.glColor4f(1F, 1F, 1F, 1F);
        mc.renderEngine.bindTexture(Gui.icons);
    }

}