    001package net.minecraft.client.renderer.entity;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.Random;
    006import net.minecraft.client.Minecraft;
    007import net.minecraft.client.gui.FontRenderer;
    008import net.minecraft.client.model.ModelBase;
    009import net.minecraft.client.model.ModelBox;
    010import net.minecraft.client.model.ModelRenderer;
    011import net.minecraft.client.renderer.OpenGlHelper;
    012import net.minecraft.client.renderer.RenderHelper;
    013import net.minecraft.client.renderer.Tessellator;
    014import net.minecraft.entity.Entity;
    015import net.minecraft.entity.EntityLiving;
    016import net.minecraft.entity.projectile.EntityArrow;
    017import net.minecraft.util.MathHelper;
    018import org.lwjgl.opengl.GL11;
    019import org.lwjgl.opengl.GL12;
    020
    021@SideOnly(Side.CLIENT)
    022public class RenderLiving extends Render
    023{
    024    protected ModelBase mainModel;
    025
    026    /** The model to be used during the render passes. */
    027    protected ModelBase renderPassModel;
    028
    029    public RenderLiving(ModelBase par1ModelBase, float par2)
    030    {
    031        this.mainModel = par1ModelBase;
    032        this.shadowSize = par2;
    033    }
    034
    035    /**
    036     * Sets the model to be used in the current render pass (the first render pass is done after the primary model is
    037     * rendered) Args: model
    038     */
    039    public void setRenderPassModel(ModelBase par1ModelBase)
    040    {
    041        this.renderPassModel = par1ModelBase;
    042    }
    043
    044    /**
    045     * Returns a rotation angle that is inbetween two other rotation angles. par1 and par2 are the angles between which
    046     * to interpolate, par3 is probably a float between 0.0 and 1.0 that tells us where "between" the two angles we are.
    047     * Example: par1 = 30, par2 = 50, par3 = 0.5, then return = 40
    048     */
    049    private float interpolateRotation(float par1, float par2, float par3)
    050    {
    051        float f3;
    052
    053        for (f3 = par2 - par1; f3 < -180.0F; f3 += 360.0F)
    054        {
    055            ;
    056        }
    057
    058        while (f3 >= 180.0F)
    059        {
    060            f3 -= 360.0F;
    061        }
    062
    063        return par1 + par3 * f3;
    064    }
    065
    066    public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9)
    067    {
    068        GL11.glPushMatrix();
    069        GL11.glDisable(GL11.GL_CULL_FACE);
    070        this.mainModel.onGround = this.renderSwingProgress(par1EntityLiving, par9);
    071
    072        if (this.renderPassModel != null)
    073        {
    074            this.renderPassModel.onGround = this.mainModel.onGround;
    075        }
    076
    077        this.mainModel.isRiding = par1EntityLiving.isRiding();
    078
    079        if (this.renderPassModel != null)
    080        {
    081            this.renderPassModel.isRiding = this.mainModel.isRiding;
    082        }
    083
    084        this.mainModel.isChild = par1EntityLiving.isChild();
    085
    086        if (this.renderPassModel != null)
    087        {
    088            this.renderPassModel.isChild = this.mainModel.isChild;
    089        }
    090
    091        try
    092        {
    093            float f2 = this.interpolateRotation(par1EntityLiving.prevRenderYawOffset, par1EntityLiving.renderYawOffset, par9);
    094            float f3 = this.interpolateRotation(par1EntityLiving.prevRotationYawHead, par1EntityLiving.rotationYawHead, par9);
    095            float f4 = par1EntityLiving.prevRotationPitch + (par1EntityLiving.rotationPitch - par1EntityLiving.prevRotationPitch) * par9;
    096            this.renderLivingAt(par1EntityLiving, par2, par4, par6);
    097            float f5 = this.handleRotationFloat(par1EntityLiving, par9);
    098            this.rotateCorpse(par1EntityLiving, f5, f2, par9);
    099            float f6 = 0.0625F;
    100            GL11.glEnable(GL12.GL_RESCALE_NORMAL);
    101            GL11.glScalef(-1.0F, -1.0F, 1.0F);
    102            this.preRenderCallback(par1EntityLiving, par9);
    103            GL11.glTranslatef(0.0F, -24.0F * f6 - 0.0078125F, 0.0F);
    104            float f7 = par1EntityLiving.prevLimbYaw + (par1EntityLiving.limbYaw - par1EntityLiving.prevLimbYaw) * par9;
    105            float f8 = par1EntityLiving.limbSwing - par1EntityLiving.limbYaw * (1.0F - par9);
    106
    107            if (par1EntityLiving.isChild())
    108            {
    109                f8 *= 3.0F;
    110            }
    111
    112            if (f7 > 1.0F)
    113            {
    114                f7 = 1.0F;
    115            }
    116
    117            GL11.glEnable(GL11.GL_ALPHA_TEST);
    118            this.mainModel.setLivingAnimations(par1EntityLiving, f8, f7, par9);
    119            this.renderModel(par1EntityLiving, f8, f7, f5, f3 - f2, f4, f6);
    120            float f9;
    121            int i;
    122            float f10;
    123            float f11;
    124
    125            for (int j = 0; j < 4; ++j)
    126            {
    127                i = this.shouldRenderPass(par1EntityLiving, j, par9);
    128
    129                if (i > 0)
    130                {
    131                    this.renderPassModel.setLivingAnimations(par1EntityLiving, f8, f7, par9);
    132                    this.renderPassModel.render(par1EntityLiving, f8, f7, f5, f3 - f2, f4, f6);
    133
    134                    if ((i & 240) == 16)
    135                    {
    136                        this.func_82408_c(par1EntityLiving, j, par9);
    137                        this.renderPassModel.render(par1EntityLiving, f8, f7, f5, f3 - f2, f4, f6);
    138                    }
    139
    140                    if ((i & 15) == 15)
    141                    {
    142                        f9 = (float)par1EntityLiving.ticksExisted + par9;
    143                        this.loadTexture("%blur%/misc/glint.png");
    144                        GL11.glEnable(GL11.GL_BLEND);
    145                        f10 = 0.5F;
    146                        GL11.glColor4f(f10, f10, f10, 1.0F);
    147                        GL11.glDepthFunc(GL11.GL_EQUAL);
    148                        GL11.glDepthMask(false);
    149
    150                        for (int k = 0; k < 2; ++k)
    151                        {
    152                            GL11.glDisable(GL11.GL_LIGHTING);
    153                            f11 = 0.76F;
    154                            GL11.glColor4f(0.5F * f11, 0.25F * f11, 0.8F * f11, 1.0F);
    155                            GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE);
    156                            GL11.glMatrixMode(GL11.GL_TEXTURE);
    157                            GL11.glLoadIdentity();
    158                            float f12 = f9 * (0.001F + (float)k * 0.003F) * 20.0F;
    159                            float f13 = 0.33333334F;
    160                            GL11.glScalef(f13, f13, f13);
    161                            GL11.glRotatef(30.0F - (float)k * 60.0F, 0.0F, 0.0F, 1.0F);
    162                            GL11.glTranslatef(0.0F, f12, 0.0F);
    163                            GL11.glMatrixMode(GL11.GL_MODELVIEW);
    164                            this.renderPassModel.render(par1EntityLiving, f8, f7, f5, f3 - f2, f4, f6);
    165                        }
    166
    167                        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    168                        GL11.glMatrixMode(GL11.GL_TEXTURE);
    169                        GL11.glDepthMask(true);
    170                        GL11.glLoadIdentity();
    171                        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    172                        GL11.glEnable(GL11.GL_LIGHTING);
    173                        GL11.glDisable(GL11.GL_BLEND);
    174                        GL11.glDepthFunc(GL11.GL_LEQUAL);
    175                    }
    176
    177                    GL11.glDisable(GL11.GL_BLEND);
    178                    GL11.glEnable(GL11.GL_ALPHA_TEST);
    179                }
    180            }
    181
    182            GL11.glDepthMask(true);
    183            this.renderEquippedItems(par1EntityLiving, par9);
    184            float f14 = par1EntityLiving.getBrightness(par9);
    185            i = this.getColorMultiplier(par1EntityLiving, f14, par9);
    186            OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
    187            GL11.glDisable(GL11.GL_TEXTURE_2D);
    188            OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
    189
    190            if ((i >> 24 & 255) > 0 || par1EntityLiving.hurtTime > 0 || par1EntityLiving.deathTime > 0)
    191            {
    192                GL11.glDisable(GL11.GL_TEXTURE_2D);
    193                GL11.glDisable(GL11.GL_ALPHA_TEST);
    194                GL11.glEnable(GL11.GL_BLEND);
    195                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    196                GL11.glDepthFunc(GL11.GL_EQUAL);
    197
    198                if (par1EntityLiving.hurtTime > 0 || par1EntityLiving.deathTime > 0)
    199                {
    200                    GL11.glColor4f(f14, 0.0F, 0.0F, 0.4F);
    201                    this.mainModel.render(par1EntityLiving, f8, f7, f5, f3 - f2, f4, f6);
    202
    203                    for (int l = 0; l < 4; ++l)
    204                    {
    205                        if (this.inheritRenderPass(par1EntityLiving, l, par9) >= 0)
    206                        {
    207                            GL11.glColor4f(f14, 0.0F, 0.0F, 0.4F);
    208                            this.renderPassModel.render(par1EntityLiving, f8, f7, f5, f3 - f2, f4, f6);
    209                        }
    210                    }
    211                }
    212
    213                if ((i >> 24 & 255) > 0)
    214                {
    215                    f9 = (float)(i >> 16 & 255) / 255.0F;
    216                    f10 = (float)(i >> 8 & 255) / 255.0F;
    217                    float f15 = (float)(i & 255) / 255.0F;
    218                    f11 = (float)(i >> 24 & 255) / 255.0F;
    219                    GL11.glColor4f(f9, f10, f15, f11);
    220                    this.mainModel.render(par1EntityLiving, f8, f7, f5, f3 - f2, f4, f6);
    221
    222                    for (int i1 = 0; i1 < 4; ++i1)
    223                    {
    224                        if (this.inheritRenderPass(par1EntityLiving, i1, par9) >= 0)
    225                        {
    226                            GL11.glColor4f(f9, f10, f15, f11);
    227                            this.renderPassModel.render(par1EntityLiving, f8, f7, f5, f3 - f2, f4, f6);
    228                        }
    229                    }
    230                }
    231
    232                GL11.glDepthFunc(GL11.GL_LEQUAL);
    233                GL11.glDisable(GL11.GL_BLEND);
    234                GL11.glEnable(GL11.GL_ALPHA_TEST);
    235                GL11.glEnable(GL11.GL_TEXTURE_2D);
    236            }
    237
    238            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    239        }
    240        catch (Exception exception)
    241        {
    242            exception.printStackTrace();
    243        }
    244
    245        OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
    246        GL11.glEnable(GL11.GL_TEXTURE_2D);
    247        OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
    248        GL11.glEnable(GL11.GL_CULL_FACE);
    249        GL11.glPopMatrix();
    250        this.passSpecialRender(par1EntityLiving, par2, par4, par6);
    251    }
    252
    253    /**
    254     * Renders the model in RenderLiving
    255     */
    256    protected void renderModel(EntityLiving par1EntityLiving, float par2, float par3, float par4, float par5, float par6, float par7)
    257    {
    258        this.func_98190_a(par1EntityLiving);
    259
    260        if (!par1EntityLiving.getHasActivePotion())
    261        {
    262            this.mainModel.render(par1EntityLiving, par2, par3, par4, par5, par6, par7);
    263        }
    264        else if (!par1EntityLiving.func_98034_c(Minecraft.getMinecraft().thePlayer))
    265        {
    266            GL11.glPushMatrix();
    267            GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.15F);
    268            GL11.glDepthMask(false);
    269            GL11.glEnable(GL11.GL_BLEND);
    270            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    271            GL11.glAlphaFunc(GL11.GL_GREATER, 0.003921569F);
    272            this.mainModel.render(par1EntityLiving, par2, par3, par4, par5, par6, par7);
    273            GL11.glDisable(GL11.GL_BLEND);
    274            GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F);
    275            GL11.glPopMatrix();
    276            GL11.glDepthMask(true);
    277        }
    278        else
    279        {
    280            this.mainModel.setRotationAngles(par2, par3, par4, par5, par6, par7, par1EntityLiving);
    281        }
    282    }
    283
    284    protected void func_98190_a(EntityLiving par1EntityLiving)
    285    {
    286        this.loadTexture(par1EntityLiving.getTexture());
    287    }
    288
    289    /**
    290     * Sets a simple glTranslate on a LivingEntity.
    291     */
    292    protected void renderLivingAt(EntityLiving par1EntityLiving, double par2, double par4, double par6)
    293    {
    294        GL11.glTranslatef((float)par2, (float)par4, (float)par6);
    295    }
    296
    297    protected void rotateCorpse(EntityLiving par1EntityLiving, float par2, float par3, float par4)
    298    {
    299        GL11.glRotatef(180.0F - par3, 0.0F, 1.0F, 0.0F);
    300
    301        if (par1EntityLiving.deathTime > 0)
    302        {
    303            float f3 = ((float)par1EntityLiving.deathTime + par4 - 1.0F) / 20.0F * 1.6F;
    304            f3 = MathHelper.sqrt_float(f3);
    305
    306            if (f3 > 1.0F)
    307            {
    308                f3 = 1.0F;
    309            }
    310
    311            GL11.glRotatef(f3 * this.getDeathMaxRotation(par1EntityLiving), 0.0F, 0.0F, 1.0F);
    312        }
    313    }
    314
    315    protected float renderSwingProgress(EntityLiving par1EntityLiving, float par2)
    316    {
    317        return par1EntityLiving.getSwingProgress(par2);
    318    }
    319
    320    /**
    321     * Defines what float the third param in setRotationAngles of ModelBase is
    322     */
    323    protected float handleRotationFloat(EntityLiving par1EntityLiving, float par2)
    324    {
    325        return (float)par1EntityLiving.ticksExisted + par2;
    326    }
    327
    328    protected void renderEquippedItems(EntityLiving par1EntityLiving, float par2) {}
    329
    330    /**
    331     * renders arrows the Entity has been attacked with, attached to it
    332     */
    333    protected void renderArrowsStuckInEntity(EntityLiving par1EntityLiving, float par2)
    334    {
    335        int i = par1EntityLiving.getArrowCountInEntity();
    336
    337        if (i > 0)
    338        {
    339            EntityArrow entityarrow = new EntityArrow(par1EntityLiving.worldObj, par1EntityLiving.posX, par1EntityLiving.posY, par1EntityLiving.posZ);
    340            Random random = new Random((long)par1EntityLiving.entityId);
    341            RenderHelper.disableStandardItemLighting();
    342
    343            for (int j = 0; j < i; ++j)
    344            {
    345                GL11.glPushMatrix();
    346                ModelRenderer modelrenderer = this.mainModel.getRandomModelBox(random);
    347                ModelBox modelbox = (ModelBox)modelrenderer.cubeList.get(random.nextInt(modelrenderer.cubeList.size()));
    348                modelrenderer.postRender(0.0625F);
    349                float f1 = random.nextFloat();
    350                float f2 = random.nextFloat();
    351                float f3 = random.nextFloat();
    352                float f4 = (modelbox.posX1 + (modelbox.posX2 - modelbox.posX1) * f1) / 16.0F;
    353                float f5 = (modelbox.posY1 + (modelbox.posY2 - modelbox.posY1) * f2) / 16.0F;
    354                float f6 = (modelbox.posZ1 + (modelbox.posZ2 - modelbox.posZ1) * f3) / 16.0F;
    355                GL11.glTranslatef(f4, f5, f6);
    356                f1 = f1 * 2.0F - 1.0F;
    357                f2 = f2 * 2.0F - 1.0F;
    358                f3 = f3 * 2.0F - 1.0F;
    359                f1 *= -1.0F;
    360                f2 *= -1.0F;
    361                f3 *= -1.0F;
    362                float f7 = MathHelper.sqrt_float(f1 * f1 + f3 * f3);
    363                entityarrow.prevRotationYaw = entityarrow.rotationYaw = (float)(Math.atan2((double)f1, (double)f3) * 180.0D / Math.PI);
    364                entityarrow.prevRotationPitch = entityarrow.rotationPitch = (float)(Math.atan2((double)f2, (double)f7) * 180.0D / Math.PI);
    365                double d0 = 0.0D;
    366                double d1 = 0.0D;
    367                double d2 = 0.0D;
    368                float f8 = 0.0F;
    369                this.renderManager.renderEntityWithPosYaw(entityarrow, d0, d1, d2, f8, par2);
    370                GL11.glPopMatrix();
    371            }
    372
    373            RenderHelper.enableStandardItemLighting();
    374        }
    375    }
    376
    377    protected int inheritRenderPass(EntityLiving par1EntityLiving, int par2, float par3)
    378    {
    379        return this.shouldRenderPass(par1EntityLiving, par2, par3);
    380    }
    381
    382    /**
    383     * Queries whether should render the specified pass or not.
    384     */
    385    protected int shouldRenderPass(EntityLiving par1EntityLiving, int par2, float par3)
    386    {
    387        return -1;
    388    }
    389
    390    protected void func_82408_c(EntityLiving par1EntityLiving, int par2, float par3) {}
    391
    392    protected float getDeathMaxRotation(EntityLiving par1EntityLiving)
    393    {
    394        return 90.0F;
    395    }
    396
    397    /**
    398     * Returns an ARGB int color back. Args: entityLiving, lightBrightness, partialTickTime
    399     */
    400    protected int getColorMultiplier(EntityLiving par1EntityLiving, float par2, float par3)
    401    {
    402        return 0;
    403    }
    404
    405    /**
    406     * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args:
    407     * entityLiving, partialTickTime
    408     */
    409    protected void preRenderCallback(EntityLiving par1EntityLiving, float par2) {}
    410
    411    /**
    412     * Passes the specialRender and renders it
    413     */
    414    protected void passSpecialRender(EntityLiving par1EntityLiving, double par2, double par4, double par6)
    415    {
    416        if (Minecraft.isGuiEnabled() && par1EntityLiving != this.renderManager.livingPlayer && !par1EntityLiving.func_98034_c(Minecraft.getMinecraft().thePlayer) && (par1EntityLiving.func_94059_bO() || par1EntityLiving.func_94056_bM() && par1EntityLiving == this.renderManager.field_96451_i))
    417        {
    418            float f = 1.6F;
    419            float f1 = 0.016666668F * f;
    420            double d3 = par1EntityLiving.getDistanceSqToEntity(this.renderManager.livingPlayer);
    421            float f2 = par1EntityLiving.isSneaking() ? 32.0F : 64.0F;
    422
    423            if (d3 < (double)(f2 * f2))
    424            {
    425                String s = par1EntityLiving.func_96090_ax();
    426
    427                if (par1EntityLiving.isSneaking())
    428                {
    429                    FontRenderer fontrenderer = this.getFontRendererFromRenderManager();
    430                    GL11.glPushMatrix();
    431                    GL11.glTranslatef((float)par2 + 0.0F, (float)par4 + par1EntityLiving.height + 0.5F, (float)par6);
    432                    GL11.glNormal3f(0.0F, 1.0F, 0.0F);
    433                    GL11.glRotatef(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
    434                    GL11.glRotatef(this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
    435                    GL11.glScalef(-f1, -f1, f1);
    436                    GL11.glDisable(GL11.GL_LIGHTING);
    437                    GL11.glTranslatef(0.0F, 0.25F / f1, 0.0F);
    438                    GL11.glDepthMask(false);
    439                    GL11.glEnable(GL11.GL_BLEND);
    440                    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    441                    Tessellator tessellator = Tessellator.instance;
    442                    GL11.glDisable(GL11.GL_TEXTURE_2D);
    443                    tessellator.startDrawingQuads();
    444                    int i = fontrenderer.getStringWidth(s) / 2;
    445                    tessellator.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F);
    446                    tessellator.addVertex((double)(-i - 1), -1.0D, 0.0D);
    447                    tessellator.addVertex((double)(-i - 1), 8.0D, 0.0D);
    448                    tessellator.addVertex((double)(i + 1), 8.0D, 0.0D);
    449                    tessellator.addVertex((double)(i + 1), -1.0D, 0.0D);
    450                    tessellator.draw();
    451                    GL11.glEnable(GL11.GL_TEXTURE_2D);
    452                    GL11.glDepthMask(true);
    453                    fontrenderer.drawString(s, -fontrenderer.getStringWidth(s) / 2, 0, 553648127);
    454                    GL11.glEnable(GL11.GL_LIGHTING);
    455                    GL11.glDisable(GL11.GL_BLEND);
    456                    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    457                    GL11.glPopMatrix();
    458                }
    459                else
    460                {
    461                    this.func_96449_a(par1EntityLiving, par2, par4, par6, s, f1, d3);
    462                }
    463            }
    464        }
    465    }
    466
    467    protected void func_96449_a(EntityLiving par1EntityLiving, double par2, double par4, double par6, String par8Str, float par9, double par10)
    468    {
    469        if (par1EntityLiving.isPlayerSleeping())
    470        {
    471            this.renderLivingLabel(par1EntityLiving, par8Str, par2, par4 - 1.5D, par6, 64);
    472        }
    473        else
    474        {
    475            this.renderLivingLabel(par1EntityLiving, par8Str, par2, par4, par6, 64);
    476        }
    477    }
    478
    479    /**
    480     * Draws the debug or playername text above a living
    481     */
    482    protected void renderLivingLabel(EntityLiving par1EntityLiving, String par2Str, double par3, double par5, double par7, int par9)
    483    {
    484        double d3 = par1EntityLiving.getDistanceSqToEntity(this.renderManager.livingPlayer);
    485
    486        if (d3 <= (double)(par9 * par9))
    487        {
    488            FontRenderer fontrenderer = this.getFontRendererFromRenderManager();
    489            float f = 1.6F;
    490            float f1 = 0.016666668F * f;
    491            GL11.glPushMatrix();
    492            GL11.glTranslatef((float)par3 + 0.0F, (float)par5 + par1EntityLiving.height + 0.5F, (float)par7);
    493            GL11.glNormal3f(0.0F, 1.0F, 0.0F);
    494            GL11.glRotatef(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
    495            GL11.glRotatef(this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
    496            GL11.glScalef(-f1, -f1, f1);
    497            GL11.glDisable(GL11.GL_LIGHTING);
    498            GL11.glDepthMask(false);
    499            GL11.glDisable(GL11.GL_DEPTH_TEST);
    500            GL11.glEnable(GL11.GL_BLEND);
    501            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    502            Tessellator tessellator = Tessellator.instance;
    503            byte b0 = 0;
    504
    505            if (par2Str.equals("deadmau5"))
    506            {
    507                b0 = -10;
    508            }
    509
    510            GL11.glDisable(GL11.GL_TEXTURE_2D);
    511            tessellator.startDrawingQuads();
    512            int j = fontrenderer.getStringWidth(par2Str) / 2;
    513            tessellator.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F);
    514            tessellator.addVertex((double)(-j - 1), (double)(-1 + b0), 0.0D);
    515            tessellator.addVertex((double)(-j - 1), (double)(8 + b0), 0.0D);
    516            tessellator.addVertex((double)(j + 1), (double)(8 + b0), 0.0D);
    517            tessellator.addVertex((double)(j + 1), (double)(-1 + b0), 0.0D);
    518            tessellator.draw();
    519            GL11.glEnable(GL11.GL_TEXTURE_2D);
    520            fontrenderer.drawString(par2Str, -fontrenderer.getStringWidth(par2Str) / 2, b0, 553648127);
    521            GL11.glEnable(GL11.GL_DEPTH_TEST);
    522            GL11.glDepthMask(true);
    523            fontrenderer.drawString(par2Str, -fontrenderer.getStringWidth(par2Str) / 2, b0, -1);
    524            GL11.glEnable(GL11.GL_LIGHTING);
    525            GL11.glDisable(GL11.GL_BLEND);
    526            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    527            GL11.glPopMatrix();
    528        }
    529    }
    530
    531    /**
    532     * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
    533     * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
    534     * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
    535     * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
    536     */
    537    public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
    538    {
    539        this.doRenderLiving((EntityLiving)par1Entity, par2, par4, par6, par8, par9);
    540    }
    541}