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