    001package net.minecraftforge.client;
    002
    003import java.util.HashMap;
    004import java.util.Random;
    005import java.util.TreeSet;
    006
    007import org.lwjgl.opengl.GL11;
    008import org.lwjgl.opengl.GL12;
    009
    010import cpw.mods.fml.client.FMLClientHandler;
    011
    012import net.minecraft.client.Minecraft;
    013import net.minecraft.block.Block;
    014import net.minecraft.entity.item.EntityItem;
    015import net.minecraft.entity.EntityLiving;
    016import net.minecraft.entity.player.EntityPlayer;
    017import net.minecraft.client.texturepacks.ITexturePack;
    018import net.minecraft.item.Item;
    019import net.minecraft.item.ItemBlock;
    020import net.minecraft.item.ItemStack;
    021import net.minecraft.util.MathHelper;
    022import net.minecraft.util.MovingObjectPosition;
    023import net.minecraft.client.renderer.RenderBlocks;
    024import net.minecraft.client.renderer.RenderEngine;
    025import net.minecraft.client.renderer.RenderGlobal;
    026import net.minecraft.client.renderer.Tessellator;
    027import net.minecraft.client.renderer.entity.RenderItem;
    028import net.minecraft.client.renderer.texture.TextureMap;
    029import net.minecraftforge.client.event.DrawBlockHighlightEvent;
    030import net.minecraftforge.client.event.RenderWorldLastEvent;
    031import net.minecraftforge.client.event.TextureLoadEvent;
    032import net.minecraftforge.client.event.TextureStitchEvent;
    033import net.minecraftforge.common.IArmorTextureProvider;
    034import net.minecraftforge.common.MinecraftForge;
    035import static net.minecraftforge.client.IItemRenderer.ItemRenderType.*;
    036import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.*;
    037
    038public class ForgeHooksClient
    039{
    040    static RenderEngine engine()
    041    {
    042        return FMLClientHandler.instance().getClient().renderEngine;
    043    }
    044
    045    public static String getArmorTexture(ItemStack armor, String _default)
    046    {
    047        if (armor.getItem() instanceof IArmorTextureProvider)
    048        {
    049            return ((IArmorTextureProvider)armor.getItem()).getArmorTextureFile(armor);
    050        }
    051        return _default;
    052    }
    053
    054    public static boolean renderEntityItem(EntityItem entity, ItemStack item, float bobing, float rotation, Random random, RenderEngine engine, RenderBlocks renderBlocks)
    055    {
    056        IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, ENTITY);
    057        if (customRenderer == null)
    058        {
    059            return false;
    060        }
    061
    062        if (customRenderer.shouldUseRenderHelper(ENTITY, item, ENTITY_ROTATION))
    063        {
    064            GL11.glRotatef(rotation, 0.0F, 1.0F, 0.0F);
    065        }
    066        if (!customRenderer.shouldUseRenderHelper(ENTITY, item, ENTITY_BOBBING))
    067        {
    068            GL11.glTranslatef(0.0F, -bobing, 0.0F);
    069        }
    070        boolean is3D = customRenderer.shouldUseRenderHelper(ENTITY, item, BLOCK_3D);
    071
    072        if (item.getItem() instanceof ItemBlock && (is3D || RenderBlocks.renderItemIn3d(Block.blocksList[item.itemID].getRenderType())))
    073        {
    074            engine.func_98187_b("/terrain.png");
    075            int renderType = Block.blocksList[item.itemID].getRenderType();
    076            float scale = (renderType == 1 || renderType == 19 || renderType == 12 || renderType == 2 ? 0.5F : 0.25F);
    077
    078            if (RenderItem.field_82407_g)
    079            {
    080                GL11.glScalef(1.25F, 1.25F, 1.25F);
    081                GL11.glTranslatef(0.0F, 0.05F, 0.0F);
    082                GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F);
    083            }
    084
    085            GL11.glScalef(scale, scale, scale);
    086
    087            int size = item.stackSize;
    088            int count = (size > 20 ? 4 : (size > 5 ? 3 : (size > 1 ? 2 : 1)));
    089
    090            for(int j = 0; j < count; j++)
    091            {
    092                GL11.glPushMatrix();
    093                if (j > 0)
    094                {
    095                    GL11.glTranslatef(
    096                        ((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / 0.5F,
    097                        ((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / 0.5F,
    098                        ((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / 0.5F);
    099                }
    100                customRenderer.renderItem(ENTITY, item, renderBlocks, entity);
    101                GL11.glPopMatrix();
    102            }
    103        }
    104        else
    105        {
    106            engine.func_98187_b(item.func_94608_d() == 0 ? "/terrain.png" : "/gui/items.png");
    107            GL11.glScalef(0.5F, 0.5F, 0.5F);
    108            customRenderer.renderItem(ENTITY, item, renderBlocks, entity);
    109        }
    110        return true;
    111    }
    112
    113    public static boolean renderInventoryItem(RenderBlocks renderBlocks, RenderEngine engine, ItemStack item, boolean inColor, float zLevel, float x, float y)
    114    {
    115        IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, INVENTORY);
    116        if (customRenderer == null)
    117        {
    118            return false;
    119        }
    120
    121        engine.func_98187_b(item.func_94608_d() == 0 ? "/terrain.png" : "/gui/items.png");
    122        if (customRenderer.shouldUseRenderHelper(INVENTORY, item, INVENTORY_BLOCK))
    123        {
    124            GL11.glPushMatrix();
    125            GL11.glTranslatef(x - 2, y + 3, -3.0F + zLevel);
    126            GL11.glScalef(10F, 10F, 10F);
    127            GL11.glTranslatef(1.0F, 0.5F, 1.0F);
    128            GL11.glScalef(1.0F, 1.0F, -1F);
    129            GL11.glRotatef(210F, 1.0F, 0.0F, 0.0F);
    130            GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F);
    131
    132            if(inColor)
    133            {
    134                int color = Item.itemsList[item.itemID].getColorFromItemStack(item, 0);
    135                float r = (float)(color >> 16 & 0xff) / 255F;
    136                float g = (float)(color >> 8 & 0xff) / 255F;
    137                float b = (float)(color & 0xff) / 255F;
    138                GL11.glColor4f(r, g, b, 1.0F);
    139            }
    140
    141            GL11.glRotatef(-90F, 0.0F, 1.0F, 0.0F);
    142            renderBlocks.useInventoryTint = inColor;
    143            customRenderer.renderItem(INVENTORY, item, renderBlocks);
    144            renderBlocks.useInventoryTint = true;
    145            GL11.glPopMatrix();
    146        }
    147        else
    148        {
    149            GL11.glDisable(GL11.GL_LIGHTING);
    150            GL11.glPushMatrix();
    151            GL11.glTranslatef(x, y, -3.0F + zLevel);
    152
    153            if (inColor)
    154            {
    155                int color = Item.itemsList[item.itemID].getColorFromItemStack(item, 0);
    156                float r = (float)(color >> 16 & 255) / 255.0F;
    157                float g = (float)(color >> 8 & 255) / 255.0F;
    158                float b = (float)(color & 255) / 255.0F;
    159                GL11.glColor4f(r, g, b, 1.0F);
    160            }
    161
    162            customRenderer.renderItem(INVENTORY, item, renderBlocks);
    163            GL11.glPopMatrix();
    164            GL11.glEnable(GL11.GL_LIGHTING);
    165        }
    166        return true;
    167    }
    168
    169    public static void renderEquippedItem(IItemRenderer customRenderer, RenderBlocks renderBlocks, EntityLiving entity, ItemStack item)
    170    {
    171        if (customRenderer.shouldUseRenderHelper(EQUIPPED, item, EQUIPPED_BLOCK))
    172        {
    173            GL11.glPushMatrix();
    174            GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
    175            customRenderer.renderItem(EQUIPPED, item, renderBlocks, entity);
    176            GL11.glPopMatrix();
    177        }
    178        else
    179        {
    180            GL11.glPushMatrix();
    181            GL11.glEnable(GL12.GL_RESCALE_NORMAL);
    182            GL11.glTranslatef(0.0F, -0.3F, 0.0F);
    183            GL11.glScalef(1.5F, 1.5F, 1.5F);
    184            GL11.glRotatef(50.0F, 0.0F, 1.0F, 0.0F);
    185            GL11.glRotatef(335.0F, 0.0F, 0.0F, 1.0F);
    186            GL11.glTranslatef(-0.9375F, -0.0625F, 0.0F);
    187            customRenderer.renderItem(EQUIPPED, item, renderBlocks, entity);
    188            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    189            GL11.glPopMatrix();
    190        }
    191    }
    192
    193    //Optifine Helper Functions u.u, these are here specifically for Optifine
    194    //Note: When using Optfine, these methods are invoked using reflection, which
    195    //incurs a major performance penalty.
    196    public static void orientBedCamera(Minecraft mc, EntityLiving entity)
    197    {
    198        int x = MathHelper.floor_double(entity.posX);
    199        int y = MathHelper.floor_double(entity.posY);
    200        int z = MathHelper.floor_double(entity.posZ);
    201        Block block = Block.blocksList[mc.theWorld.getBlockId(x, y, z)];
    202
    203        if (block != null && block.isBed(mc.theWorld, x, y, z, entity))
    204        {
    205            int var12 = block.getBedDirection(mc.theWorld, x, y, z);
    206            GL11.glRotatef((float)(var12 * 90), 0.0F, 1.0F, 0.0F);
    207        }
    208    }
    209
    210    public static boolean onDrawBlockHighlight(RenderGlobal context, EntityPlayer player, MovingObjectPosition target, int subID, ItemStack currentItem, float partialTicks)
    211    {
    212        return MinecraftForge.EVENT_BUS.post(new DrawBlockHighlightEvent(context, player, target, subID, currentItem, partialTicks));
    213    }
    214
    215    public static void dispatchRenderLast(RenderGlobal context, float partialTicks)
    216    {
    217        MinecraftForge.EVENT_BUS.post(new RenderWorldLastEvent(context, partialTicks));
    218    }
    219
    220    public static void onTextureLoad(String texture, ITexturePack pack)
    221    {
    222        MinecraftForge.EVENT_BUS.post(new TextureLoadEvent(texture, pack));
    223    }
    224
    225    public static void onTextureStitchedPre(TextureMap map)
    226    {
    227        MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Pre(map));
    228    }
    229
    230    public static void onTextureStitchedPost(TextureMap map)
    231    {
    232        MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Post(map));
    233    }
    234
    235    /**
    236     * This is added for Optifine's convenience. And to explode if a ModMaker is developing.
    237     * @param texture
    238     */
    239    public static void onTextureLoadPre(String texture)
    240    {
    241        if (Tessellator.renderingWorldRenderer)
    242        {
    243            String msg = String.format("Warning: Texture %s not preloaded, will cause render glitches!", texture);
    244            System.out.println(msg);
    245            if (Tessellator.class.getPackage() != null)
    246            {
    247                if (Tessellator.class.getPackage().getName().startsWith("net.minecraft."))
    248                {
    249                    Minecraft mc = FMLClientHandler.instance().getClient();
    250                    if (mc.ingameGUI != null)
    251                    {
    252                        mc.ingameGUI.getChatGUI().printChatMessage(msg);
    253                    }
    254                }
    255            }
    256        }
    257    }
    258
    259    static int renderPass = -1;
    260    public static void setRenderPass(int pass)
    261    {
    262        renderPass = pass;
    263    }
    264}