    001    package net.minecraft.client.renderer.entity;
    002
    003    import cpw.mods.fml.relauncher.Side;
    004    import cpw.mods.fml.relauncher.SideOnly;
    005    import java.util.Random;
    006    import net.minecraft.client.Minecraft;
    007    import net.minecraft.client.gui.FontRenderer;
    008    import net.minecraft.client.model.ModelBase;
    009    import net.minecraft.client.model.ModelBox;
    010    import net.minecraft.client.model.ModelRenderer;
    011    import net.minecraft.client.renderer.OpenGlHelper;
    012    import net.minecraft.client.renderer.RenderHelper;
    013    import net.minecraft.client.renderer.Tessellator;
    014    import net.minecraft.entity.Entity;
    015    import net.minecraft.entity.EntityLiving;
    016    import net.minecraft.entity.projectile.EntityArrow;
    017    import net.minecraft.util.MathHelper;
    018    import org.lwjgl.opengl.GL11;
    019    import org.lwjgl.opengl.GL12;
    020
    021    @SideOnly(Side.CLIENT)
    022    public 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 var4;
    052
    053            for (var4 = par2 - par1; var4 < -180.0F; var4 += 360.0F)
    054            {
    055                ;
    056            }
    057
    058            while (var4 >= 180.0F)
    059            {
    060                var4 -= 360.0F;
    061            }
    062
    063            return par1 + par3 * var4;
    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 var10 = this.interpolateRotation(par1EntityLiving.prevRenderYawOffset, par1EntityLiving.renderYawOffset, par9);
    094                float var11 = this.interpolateRotation(par1EntityLiving.prevRotationYawHead, par1EntityLiving.rotationYawHead, par9);
    095                float var12 = par1EntityLiving.prevRotationPitch + (par1EntityLiving.rotationPitch - par1EntityLiving.prevRotationPitch) * par9;
    096                this.renderLivingAt(par1EntityLiving, par2, par4, par6);
    097                float var13 = this.handleRotationFloat(par1EntityLiving, par9);
    098                this.rotateCorpse(par1EntityLiving, var13, var10, par9);
    099                float var14 = 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 * var14 - 0.0078125F, 0.0F);
    104                float var15 = par1EntityLiving.prevLegYaw + (par1EntityLiving.legYaw - par1EntityLiving.prevLegYaw) * par9;
    105                float var16 = par1EntityLiving.legSwing - par1EntityLiving.legYaw * (1.0F - par9);
    106
    107                if (par1EntityLiving.isChild())
    108                {
    109                    var16 *= 3.0F;
    110                }
    111
    112                if (var15 > 1.0F)
    113                {
    114                    var15 = 1.0F;
    115                }
    116
    117                GL11.glEnable(GL11.GL_ALPHA_TEST);
    118                this.mainModel.setLivingAnimations(par1EntityLiving, var16, var15, par9);
    119                this.renderModel(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    120                float var19;
    121                int var18;
    122                float var20;
    123                float var22;
    124
    125                for (int var17 = 0; var17 < 4; ++var17)
    126                {
    127                    var18 = this.shouldRenderPass(par1EntityLiving, var17, par9);
    128
    129                    if (var18 > 0)
    130                    {
    131                        this.renderPassModel.setLivingAnimations(par1EntityLiving, var16, var15, par9);
    132                        this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    133
    134                        if ((var18 & 240) == 16)
    135                        {
    136                            this.func_82408_c(par1EntityLiving, var17, par9);
    137                            this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    138                        }
    139
    140                        if ((var18 & 15) == 15)
    141                        {
    142                            var19 = (float)par1EntityLiving.ticksExisted + par9;
    143                            this.loadTexture("%blur%/misc/glint.png");
    144                            GL11.glEnable(GL11.GL_BLEND);
    145                            var20 = 0.5F;
    146                            GL11.glColor4f(var20, var20, var20, 1.0F);
    147                            GL11.glDepthFunc(GL11.GL_EQUAL);
    148                            GL11.glDepthMask(false);
    149
    150                            for (int var21 = 0; var21 < 2; ++var21)
    151                            {
    152                                GL11.glDisable(GL11.GL_LIGHTING);
    153                                var22 = 0.76F;
    154                                GL11.glColor4f(0.5F * var22, 0.25F * var22, 0.8F * var22, 1.0F);
    155                                GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE);
    156                                GL11.glMatrixMode(GL11.GL_TEXTURE);
    157                                GL11.glLoadIdentity();
    158                                float var23 = var19 * (0.001F + (float)var21 * 0.003F) * 20.0F;
    159                                float var24 = 0.33333334F;
    160                                GL11.glScalef(var24, var24, var24);
    161                                GL11.glRotatef(30.0F - (float)var21 * 60.0F, 0.0F, 0.0F, 1.0F);
    162                                GL11.glTranslatef(0.0F, var23, 0.0F);
    163                                GL11.glMatrixMode(GL11.GL_MODELVIEW);
    164                                this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    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 var26 = par1EntityLiving.getBrightness(par9);
    185                var18 = this.getColorMultiplier(par1EntityLiving, var26, par9);
    186                OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
    187                GL11.glDisable(GL11.GL_TEXTURE_2D);
    188                OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
    189
    190                if ((var18 >> 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(var26, 0.0F, 0.0F, 0.4F);
    201                        this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    202
    203                        for (int var27 = 0; var27 < 4; ++var27)
    204                        {
    205                            if (this.inheritRenderPass(par1EntityLiving, var27, par9) >= 0)
    206                            {
    207                                GL11.glColor4f(var26, 0.0F, 0.0F, 0.4F);
    208                                this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    209                            }
    210                        }
    211                    }
    212
    213                    if ((var18 >> 24 & 255) > 0)
    214                    {
    215                        var19 = (float)(var18 >> 16 & 255) / 255.0F;
    216                        var20 = (float)(var18 >> 8 & 255) / 255.0F;
    217                        float var29 = (float)(var18 & 255) / 255.0F;
    218                        var22 = (float)(var18 >> 24 & 255) / 255.0F;
    219                        GL11.glColor4f(var19, var20, var29, var22);
    220                        this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    221
    222                        for (int var28 = 0; var28 < 4; ++var28)
    223                        {
    224                            if (this.inheritRenderPass(par1EntityLiving, var28, par9) >= 0)
    225                            {
    226                                GL11.glColor4f(var19, var20, var29, var22);
    227                                this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
    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 var25)
    241            {
    242                var25.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            if (!par1EntityLiving.getHasActivePotion())
    259            {
    260                this.loadDownloadableImageTexture(par1EntityLiving.skinUrl, par1EntityLiving.getTexture());
    261                this.mainModel.render(par1EntityLiving, par2, par3, par4, par5, par6, par7);
    262            }
    263            else
    264            {
    265                this.mainModel.setRotationAngles(par2, par3, par4, par5, par6, par7, par1EntityLiving);
    266            }
    267        }
    268
    269        /**
    270         * Sets a simple glTranslate on a LivingEntity.
    271         */
    272        protected void renderLivingAt(EntityLiving par1EntityLiving, double par2, double par4, double par6)
    273        {
    274            GL11.glTranslatef((float)par2, (float)par4, (float)par6);
    275        }
    276
    277        protected void rotateCorpse(EntityLiving par1EntityLiving, float par2, float par3, float par4)
    278        {
    279            GL11.glRotatef(180.0F - par3, 0.0F, 1.0F, 0.0F);
    280
    281            if (par1EntityLiving.deathTime > 0)
    282            {
    283                float var5 = ((float)par1EntityLiving.deathTime + par4 - 1.0F) / 20.0F * 1.6F;
    284                var5 = MathHelper.sqrt_float(var5);
    285
    286                if (var5 > 1.0F)
    287                {
    288                    var5 = 1.0F;
    289                }
    290
    291                GL11.glRotatef(var5 * this.getDeathMaxRotation(par1EntityLiving), 0.0F, 0.0F, 1.0F);
    292            }
    293        }
    294
    295        protected float renderSwingProgress(EntityLiving par1EntityLiving, float par2)
    296        {
    297            return par1EntityLiving.getSwingProgress(par2);
    298        }
    299
    300        /**
    301         * Defines what float the third param in setRotationAngles of ModelBase is
    302         */
    303        protected float handleRotationFloat(EntityLiving par1EntityLiving, float par2)
    304        {
    305            return (float)par1EntityLiving.ticksExisted + par2;
    306        }
    307
    308        protected void renderEquippedItems(EntityLiving par1EntityLiving, float par2) {}
    309
    310        /**
    311         * renders arrows the Entity has been attacked with, attached to it
    312         */
    313        protected void renderArrowsStuckInEntity(EntityLiving par1EntityLiving, float par2)
    314        {
    315            int var3 = par1EntityLiving.getArrowCountInEntity();
    316
    317            if (var3 > 0)
    318            {
    319                EntityArrow var4 = new EntityArrow(par1EntityLiving.worldObj, par1EntityLiving.posX, par1EntityLiving.posY, par1EntityLiving.posZ);
    320                Random var5 = new Random((long)par1EntityLiving.entityId);
    321                RenderHelper.disableStandardItemLighting();
    322
    323                for (int var6 = 0; var6 < var3; ++var6)
    324                {
    325                    GL11.glPushMatrix();
    326                    ModelRenderer var7 = this.mainModel.func_85181_a(var5);
    327                    ModelBox var8 = (ModelBox)var7.cubeList.get(var5.nextInt(var7.cubeList.size()));
    328                    var7.postRender(0.0625F);
    329                    float var9 = var5.nextFloat();
    330                    float var10 = var5.nextFloat();
    331                    float var11 = var5.nextFloat();
    332                    float var12 = (var8.posX1 + (var8.posX2 - var8.posX1) * var9) / 16.0F;
    333                    float var13 = (var8.posY1 + (var8.posY2 - var8.posY1) * var10) / 16.0F;
    334                    float var14 = (var8.posZ1 + (var8.posZ2 - var8.posZ1) * var11) / 16.0F;
    335                    GL11.glTranslatef(var12, var13, var14);
    336                    var9 = var9 * 2.0F - 1.0F;
    337                    var10 = var10 * 2.0F - 1.0F;
    338                    var11 = var11 * 2.0F - 1.0F;
    339                    var9 *= -1.0F;
    340                    var10 *= -1.0F;
    341                    var11 *= -1.0F;
    342                    float var15 = MathHelper.sqrt_float(var9 * var9 + var11 * var11);
    343                    var4.prevRotationYaw = var4.rotationYaw = (float)(Math.atan2((double)var9, (double)var11) * 180.0D / Math.PI);
    344                    var4.prevRotationPitch = var4.rotationPitch = (float)(Math.atan2((double)var10, (double)var15) * 180.0D / Math.PI);
    345                    double var16 = 0.0D;
    346                    double var18 = 0.0D;
    347                    double var20 = 0.0D;
    348                    float var22 = 0.0F;
    349                    this.renderManager.renderEntityWithPosYaw(var4, var16, var18, var20, var22, par2);
    350                    GL11.glPopMatrix();
    351                }
    352
    353                RenderHelper.enableStandardItemLighting();
    354            }
    355        }
    356
    357        protected int inheritRenderPass(EntityLiving par1EntityLiving, int par2, float par3)
    358        {
    359            return this.shouldRenderPass(par1EntityLiving, par2, par3);
    360        }
    361
    362        /**
    363         * Queries whether should render the specified pass or not.
    364         */
    365        protected int shouldRenderPass(EntityLiving par1EntityLiving, int par2, float par3)
    366        {
    367            return -1;
    368        }
    369
    370        protected void func_82408_c(EntityLiving par1EntityLiving, int par2, float par3) {}
    371
    372        protected float getDeathMaxRotation(EntityLiving par1EntityLiving)
    373        {
    374            return 90.0F;
    375        }
    376
    377        /**
    378         * Returns an ARGB int color back. Args: entityLiving, lightBrightness, partialTickTime
    379         */
    380        protected int getColorMultiplier(EntityLiving par1EntityLiving, float par2, float par3)
    381        {
    382            return 0;
    383        }
    384
    385        /**
    386         * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args:
    387         * entityLiving, partialTickTime
    388         */
    389        protected void preRenderCallback(EntityLiving par1EntityLiving, float par2) {}
    390
    391        /**
    392         * Passes the specialRender and renders it
    393         */
    394        protected void passSpecialRender(EntityLiving par1EntityLiving, double par2, double par4, double par6)
    395        {
    396            if (Minecraft.isDebugInfoEnabled())
    397            {
    398                ;
    399            }
    400        }
    401
    402        /**
    403         * Draws the debug or playername text above a living
    404         */
    405        protected void renderLivingLabel(EntityLiving par1EntityLiving, String par2Str, double par3, double par5, double par7, int par9)
    406        {
    407            double var10 = par1EntityLiving.getDistanceSqToEntity(this.renderManager.livingPlayer);
    408
    409            if (var10 <= (double)(par9 * par9))
    410            {
    411                FontRenderer var12 = this.getFontRendererFromRenderManager();
    412                float var13 = 1.6F;
    413                float var14 = 0.016666668F * var13;
    414                GL11.glPushMatrix();
    415                GL11.glTranslatef((float)par3 + 0.0F, (float)par5 + 2.3F, (float)par7);
    416                GL11.glNormal3f(0.0F, 1.0F, 0.0F);
    417                GL11.glRotatef(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
    418                GL11.glRotatef(this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
    419                GL11.glScalef(-var14, -var14, var14);
    420                GL11.glDisable(GL11.GL_LIGHTING);
    421                GL11.glDepthMask(false);
    422                GL11.glDisable(GL11.GL_DEPTH_TEST);
    423                GL11.glEnable(GL11.GL_BLEND);
    424                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    425                Tessellator var15 = Tessellator.instance;
    426                byte var16 = 0;
    427
    428                if (par2Str.equals("deadmau5"))
    429                {
    430                    var16 = -10;
    431                }
    432
    433                GL11.glDisable(GL11.GL_TEXTURE_2D);
    434                var15.startDrawingQuads();
    435                int var17 = var12.getStringWidth(par2Str) / 2;
    436                var15.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F);
    437                var15.addVertex((double)(-var17 - 1), (double)(-1 + var16), 0.0D);
    438                var15.addVertex((double)(-var17 - 1), (double)(8 + var16), 0.0D);
    439                var15.addVertex((double)(var17 + 1), (double)(8 + var16), 0.0D);
    440                var15.addVertex((double)(var17 + 1), (double)(-1 + var16), 0.0D);
    441                var15.draw();
    442                GL11.glEnable(GL11.GL_TEXTURE_2D);
    443                var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, 553648127);
    444                GL11.glEnable(GL11.GL_DEPTH_TEST);
    445                GL11.glDepthMask(true);
    446                var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, -1);
    447                GL11.glEnable(GL11.GL_LIGHTING);
    448                GL11.glDisable(GL11.GL_BLEND);
    449                GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    450                GL11.glPopMatrix();
    451            }
    452        }
    453
    454        /**
    455         * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
    456         * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
    457         * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
    458         * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
    459         */
    460        public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
    461        {
    462            this.doRenderLiving((EntityLiving)par1Entity, par2, par4, par6, par8, par9);
    463        }
    464    }