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