    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import net.minecraft.client.Minecraft;
    006    import org.lwjgl.opengl.GL11;
    007    import org.lwjgl.opengl.GL12;
    008
    009    @SideOnly(Side.CLIENT)
    010    public class RenderLiving extends Render
    011    {
    012        protected ModelBase mainModel;
    013
    014        /** The model to be used during the render passes. */
    015        protected ModelBase renderPassModel;
    016
    017        public RenderLiving(ModelBase par1ModelBase, float par2)
    018        {
    019            this.mainModel = par1ModelBase;
    020            this.shadowSize = par2;
    021        }
    022
    023        /**
    024         * Sets the model to be used in the current render pass (the first render pass is done after the primary model is
    025         * rendered) Args: model
    026         */
    027        public void setRenderPassModel(ModelBase par1ModelBase)
    028        {
    029            this.renderPassModel = par1ModelBase;
    030        }
    031
    032        /**
    033         * Returns a rotation angle that is inbetween two other rotation angles. par1 and par2 are the angles between which
    034         * to interpolate, par3 is probably a float between 0.0 and 1.0 that tells us where "between" the two angles we are.
    035         * Example: par1 = 30, par2 = 50, par3 = 0.5, then return = 40
    036         */
    037        private float interpolateRotation(float par1, float par2, float par3)
    038        {
    039            float var4;
    040
    041            for (var4 = par2 - par1; var4 < -180.0F; var4 += 360.0F)
    042            {
    043                ;
    044            }
    045
    046            while (var4 >= 180.0F)
    047            {
    048                var4 -= 360.0F;
    049            }
    050
    051            return par1 + par3 * var4;
    052        }
    053
    054        public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9)
    055        {
    056            GL11.glPushMatrix();
    057            GL11.glDisable(GL11.GL_CULL_FACE);
    058            this.mainModel.onGround = this.renderSwingProgress(par1EntityLiving, par9);
    059
    060            if (this.renderPassModel != null)
    061            {
    062                this.renderPassModel.onGround = this.mainModel.onGround;
    063            }
    064
    065            this.mainModel.isRiding = par1EntityLiving.isRiding();
    066
    067            if (this.renderPassModel != null)
    068            {
    069                this.renderPassModel.isRiding = this.mainModel.isRiding;
    070            }
    071
    072            this.mainModel.isChild = par1EntityLiving.isChild();
    073
    074            if (this.renderPassModel != null)
    075            {
    076                this.renderPassModel.isChild = this.mainModel.isChild;
    077            }
    078
    079            try
    080            {
    081                float var10 = this.interpolateRotation(par1EntityLiving.prevRenderYawOffset, par1EntityLiving.renderYawOffset, par9);
    082                float var11 = this.interpolateRotation(par1EntityLiving.prevRotationYawHead, par1EntityLiving.rotationYawHead, par9);
    083                float var12 = par1EntityLiving.prevRotationPitch + (par1EntityLiving.rotationPitch - par1EntityLiving.prevRotationPitch) * par9;
    084                this.renderLivingAt(par1EntityLiving, par2, par4, par6);
    085                float var13 = this.handleRotationFloat(par1EntityLiving, par9);
    086                this.rotateCorpse(par1EntityLiving, var13, var10, par9);
    087                float var14 = 0.0625F;
    088                GL11.glEnable(GL12.GL_RESCALE_NORMAL);
    089                GL11.glScalef(-1.0F, -1.0F, 1.0F);
    090                this.preRenderCallback(par1EntityLiving, par9);
    091                GL11.glTranslatef(0.0F, -24.0F * var14 - 0.0078125F, 0.0F);
    092                float var15 = par1EntityLiving.prevLegYaw + (par1EntityLiving.legYaw - par1EntityLiving.prevLegYaw) * par9;
    093                float var16 = par1EntityLiving.legSwing - par1EntityLiving.legYaw * (1.0F - par9);
    094
    095                if (par1EntityLiving.isChild())
    096                {
    097                    var16 *= 3.0F;
    098                }
    099
    100                if (var15 > 1.0F)
    101                {
    102                    var15 = 1.0F;
    103                }
    104
    105                GL11.glEnable(GL11.GL_ALPHA_TEST);
    106                this.mainModel.setLivingAnimations(par1EntityLiving, var16, var15, par9);
    107                this.renderModel(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    108                float var19;
    109                int var18;
    110                float var20;
    111                float var22;
    112
    113                for (int var17 = 0; var17 < 4; ++var17)
    114                {
    115                    var18 = this.shouldRenderPass(par1EntityLiving, var17, par9);
    116
    117                    if (var18 > 0)
    118                    {
    119                        this.renderPassModel.setLivingAnimations(par1EntityLiving, var16, var15, par9);
    120                        this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    121
    122                        if ((var18 & 240) == 16)
    123                        {
    124                            this.func_82408_c(par1EntityLiving, var17, par9);
    125                            this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    126                        }
    127
    128                        if ((var18 & 15) == 15)
    129                        {
    130                            var19 = (float)par1EntityLiving.ticksExisted + par9;
    131                            this.loadTexture("%blur%/misc/glint.png");
    132                            GL11.glEnable(GL11.GL_BLEND);
    133                            var20 = 0.5F;
    134                            GL11.glColor4f(var20, var20, var20, 1.0F);
    135                            GL11.glDepthFunc(GL11.GL_EQUAL);
    136                            GL11.glDepthMask(false);
    137
    138                            for (int var21 = 0; var21 < 2; ++var21)
    139                            {
    140                                GL11.glDisable(GL11.GL_LIGHTING);
    141                                var22 = 0.76F;
    142                                GL11.glColor4f(0.5F * var22, 0.25F * var22, 0.8F * var22, 1.0F);
    143                                GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE);
    144                                GL11.glMatrixMode(GL11.GL_TEXTURE);
    145                                GL11.glLoadIdentity();
    146                                float var23 = var19 * (0.001F + (float)var21 * 0.003F) * 20.0F;
    147                                float var24 = 0.33333334F;
    148                                GL11.glScalef(var24, var24, var24);
    149                                GL11.glRotatef(30.0F - (float)var21 * 60.0F, 0.0F, 0.0F, 1.0F);
    150                                GL11.glTranslatef(0.0F, var23, 0.0F);
    151                                GL11.glMatrixMode(GL11.GL_MODELVIEW);
    152                                this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    153                            }
    154
    155                            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    156                            GL11.glMatrixMode(GL11.GL_TEXTURE);
    157                            GL11.glDepthMask(true);
    158                            GL11.glLoadIdentity();
    159                            GL11.glMatrixMode(GL11.GL_MODELVIEW);
    160                            GL11.glEnable(GL11.GL_LIGHTING);
    161                            GL11.glDisable(GL11.GL_BLEND);
    162                            GL11.glDepthFunc(GL11.GL_LEQUAL);
    163                        }
    164
    165                        GL11.glDisable(GL11.GL_BLEND);
    166                        GL11.glEnable(GL11.GL_ALPHA_TEST);
    167                    }
    168                }
    169
    170                GL11.glDepthMask(true);
    171                this.renderEquippedItems(par1EntityLiving, par9);
    172                float var26 = par1EntityLiving.getBrightness(par9);
    173                var18 = this.getColorMultiplier(par1EntityLiving, var26, par9);
    174                OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
    175                GL11.glDisable(GL11.GL_TEXTURE_2D);
    176                OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
    177
    178                if ((var18 >> 24 & 255) > 0 || par1EntityLiving.hurtTime > 0 || par1EntityLiving.deathTime > 0)
    179                {
    180                    GL11.glDisable(GL11.GL_TEXTURE_2D);
    181                    GL11.glDisable(GL11.GL_ALPHA_TEST);
    182                    GL11.glEnable(GL11.GL_BLEND);
    183                    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    184                    GL11.glDepthFunc(GL11.GL_EQUAL);
    185
    186                    if (par1EntityLiving.hurtTime > 0 || par1EntityLiving.deathTime > 0)
    187                    {
    188                        GL11.glColor4f(var26, 0.0F, 0.0F, 0.4F);
    189                        this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    190
    191                        for (int var27 = 0; var27 < 4; ++var27)
    192                        {
    193                            if (this.inheritRenderPass(par1EntityLiving, var27, par9) >= 0)
    194                            {
    195                                GL11.glColor4f(var26, 0.0F, 0.0F, 0.4F);
    196                                this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    197                            }
    198                        }
    199                    }
    200
    201                    if ((var18 >> 24 & 255) > 0)
    202                    {
    203                        var19 = (float)(var18 >> 16 & 255) / 255.0F;
    204                        var20 = (float)(var18 >> 8 & 255) / 255.0F;
    205                        float var29 = (float)(var18 & 255) / 255.0F;
    206                        var22 = (float)(var18 >> 24 & 255) / 255.0F;
    207                        GL11.glColor4f(var19, var20, var29, var22);
    208                        this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    209
    210                        for (int var28 = 0; var28 < 4; ++var28)
    211                        {
    212                            if (this.inheritRenderPass(par1EntityLiving, var28, par9) >= 0)
    213                            {
    214                                GL11.glColor4f(var19, var20, var29, var22);
    215                                this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    216                            }
    217                        }
    218                    }
    219
    220                    GL11.glDepthFunc(GL11.GL_LEQUAL);
    221                    GL11.glDisable(GL11.GL_BLEND);
    222                    GL11.glEnable(GL11.GL_ALPHA_TEST);
    223                    GL11.glEnable(GL11.GL_TEXTURE_2D);
    224                }
    225
    226                GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    227            }
    228            catch (Exception var25)
    229            {
    230                var25.printStackTrace();
    231            }
    232
    233            OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
    234            GL11.glEnable(GL11.GL_TEXTURE_2D);
    235            OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
    236            GL11.glEnable(GL11.GL_CULL_FACE);
    237            GL11.glPopMatrix();
    238            this.passSpecialRender(par1EntityLiving, par2, par4, par6);
    239        }
    240
    241        /**
    242         * Renders the model in RenderLiving
    243         */
    244        protected void renderModel(EntityLiving par1EntityLiving, float par2, float par3, float par4, float par5, float par6, float par7)
    245        {
    246            if (!par1EntityLiving.func_82150_aj())
    247            {
    248                this.loadDownloadableImageTexture(par1EntityLiving.skinUrl, par1EntityLiving.getTexture());
    249                this.mainModel.render(par1EntityLiving, par2, par3, par4, par5, par6, par7);
    250            }
    251        }
    252
    253        /**
    254         * Sets a simple glTranslate on a LivingEntity.
    255         */
    256        protected void renderLivingAt(EntityLiving par1EntityLiving, double par2, double par4, double par6)
    257        {
    258            GL11.glTranslatef((float)par2, (float)par4, (float)par6);
    259        }
    260
    261        protected void rotateCorpse(EntityLiving par1EntityLiving, float par2, float par3, float par4)
    262        {
    263            GL11.glRotatef(180.0F - par3, 0.0F, 1.0F, 0.0F);
    264
    265            if (par1EntityLiving.deathTime > 0)
    266            {
    267                float var5 = ((float)par1EntityLiving.deathTime + par4 - 1.0F) / 20.0F * 1.6F;
    268                var5 = MathHelper.sqrt_float(var5);
    269
    270                if (var5 > 1.0F)
    271                {
    272                    var5 = 1.0F;
    273                }
    274
    275                GL11.glRotatef(var5 * this.getDeathMaxRotation(par1EntityLiving), 0.0F, 0.0F, 1.0F);
    276            }
    277        }
    278
    279        protected float renderSwingProgress(EntityLiving par1EntityLiving, float par2)
    280        {
    281            return par1EntityLiving.getSwingProgress(par2);
    282        }
    283
    284        /**
    285         * Defines what float the third param in setRotationAngles of ModelBase is
    286         */
    287        protected float handleRotationFloat(EntityLiving par1EntityLiving, float par2)
    288        {
    289            return (float)par1EntityLiving.ticksExisted + par2;
    290        }
    291
    292        protected void renderEquippedItems(EntityLiving par1EntityLiving, float par2) {}
    293
    294        protected int inheritRenderPass(EntityLiving par1EntityLiving, int par2, float par3)
    295        {
    296            return this.shouldRenderPass(par1EntityLiving, par2, par3);
    297        }
    298
    299        /**
    300         * Queries whether should render the specified pass or not.
    301         */
    302        protected int shouldRenderPass(EntityLiving par1EntityLiving, int par2, float par3)
    303        {
    304            return -1;
    305        }
    306
    307        protected void func_82408_c(EntityLiving par1EntityLiving, int par2, float par3) {}
    308
    309        protected float getDeathMaxRotation(EntityLiving par1EntityLiving)
    310        {
    311            return 90.0F;
    312        }
    313
    314        /**
    315         * Returns an ARGB int color back. Args: entityLiving, lightBrightness, partialTickTime
    316         */
    317        protected int getColorMultiplier(EntityLiving par1EntityLiving, float par2, float par3)
    318        {
    319            return 0;
    320        }
    321
    322        /**
    323         * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args:
    324         * entityLiving, partialTickTime
    325         */
    326        protected void preRenderCallback(EntityLiving par1EntityLiving, float par2) {}
    327
    328        /**
    329         * Passes the specialRender and renders it
    330         */
    331        protected void passSpecialRender(EntityLiving par1EntityLiving, double par2, double par4, double par6)
    332        {
    333            if (Minecraft.isDebugInfoEnabled())
    334            {
    335                ;
    336            }
    337        }
    338
    339        /**
    340         * Draws the debug or playername text above a living
    341         */
    342        protected void renderLivingLabel(EntityLiving par1EntityLiving, String par2Str, double par3, double par5, double par7, int par9)
    343        {
    344            double var10 = par1EntityLiving.getDistanceSqToEntity(this.renderManager.livingPlayer);
    345
    346            if (var10 <= (double)(par9 * par9))
    347            {
    348                FontRenderer var12 = this.getFontRendererFromRenderManager();
    349                float var13 = 1.6F;
    350                float var14 = 0.016666668F * var13;
    351                GL11.glPushMatrix();
    352                GL11.glTranslatef((float)par3 + 0.0F, (float)par5 + 2.3F, (float)par7);
    353                GL11.glNormal3f(0.0F, 1.0F, 0.0F);
    354                GL11.glRotatef(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
    355                GL11.glRotatef(this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
    356                GL11.glScalef(-var14, -var14, var14);
    357                GL11.glDisable(GL11.GL_LIGHTING);
    358                GL11.glDepthMask(false);
    359                GL11.glDisable(GL11.GL_DEPTH_TEST);
    360                GL11.glEnable(GL11.GL_BLEND);
    361                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    362                Tessellator var15 = Tessellator.instance;
    363                byte var16 = 0;
    364
    365                if (par2Str.equals("deadmau5"))
    366                {
    367                    var16 = -10;
    368                }
    369
    370                GL11.glDisable(GL11.GL_TEXTURE_2D);
    371                var15.startDrawingQuads();
    372                int var17 = var12.getStringWidth(par2Str) / 2;
    373                var15.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F);
    374                var15.addVertex((double)(-var17 - 1), (double)(-1 + var16), 0.0D);
    375                var15.addVertex((double)(-var17 - 1), (double)(8 + var16), 0.0D);
    376                var15.addVertex((double)(var17 + 1), (double)(8 + var16), 0.0D);
    377                var15.addVertex((double)(var17 + 1), (double)(-1 + var16), 0.0D);
    378                var15.draw();
    379                GL11.glEnable(GL11.GL_TEXTURE_2D);
    380                var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, 553648127);
    381                GL11.glEnable(GL11.GL_DEPTH_TEST);
    382                GL11.glDepthMask(true);
    383                var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, -1);
    384                GL11.glEnable(GL11.GL_LIGHTING);
    385                GL11.glDisable(GL11.GL_BLEND);
    386                GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    387                GL11.glPopMatrix();
    388            }
    389        }
    390
    391        /**
    392         * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
    393         * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
    394         * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
    395         * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
    396         */
    397        public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
    398        {
    399            this.doRenderLiving((EntityLiving)par1Entity, par2, par4, par6, par8, par9);
    400        }
    401    }