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 == 15)
123                        {
124                            var19 = (float)par1EntityLiving.ticksExisted + par9;
125                            this.loadTexture("%blur%/misc/glint.png");
126                            GL11.glEnable(GL11.GL_BLEND);
127                            var20 = 0.5F;
128                            GL11.glColor4f(var20, var20, var20, 1.0F);
129                            GL11.glDepthFunc(GL11.GL_EQUAL);
130                            GL11.glDepthMask(false);
131    
132                            for (int var21 = 0; var21 < 2; ++var21)
133                            {
134                                GL11.glDisable(GL11.GL_LIGHTING);
135                                var22 = 0.76F;
136                                GL11.glColor4f(0.5F * var22, 0.25F * var22, 0.8F * var22, 1.0F);
137                                GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE);
138                                GL11.glMatrixMode(GL11.GL_TEXTURE);
139                                GL11.glLoadIdentity();
140                                float var23 = var19 * (0.001F + (float)var21 * 0.003F) * 20.0F;
141                                float var24 = 0.33333334F;
142                                GL11.glScalef(var24, var24, var24);
143                                GL11.glRotatef(30.0F - (float)var21 * 60.0F, 0.0F, 0.0F, 1.0F);
144                                GL11.glTranslatef(0.0F, var23, 0.0F);
145                                GL11.glMatrixMode(GL11.GL_MODELVIEW);
146                                this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
147                            }
148    
149                            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
150                            GL11.glMatrixMode(GL11.GL_TEXTURE);
151                            GL11.glDepthMask(true);
152                            GL11.glLoadIdentity();
153                            GL11.glMatrixMode(GL11.GL_MODELVIEW);
154                            GL11.glEnable(GL11.GL_LIGHTING);
155                            GL11.glDisable(GL11.GL_BLEND);
156                            GL11.glDepthFunc(GL11.GL_LEQUAL);
157                        }
158    
159                        GL11.glDisable(GL11.GL_BLEND);
160                        GL11.glEnable(GL11.GL_ALPHA_TEST);
161                    }
162                }
163    
164                this.renderEquippedItems(par1EntityLiving, par9);
165                float var26 = par1EntityLiving.getBrightness(par9);
166                var18 = this.getColorMultiplier(par1EntityLiving, var26, par9);
167                OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
168                GL11.glDisable(GL11.GL_TEXTURE_2D);
169                OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
170    
171                if ((var18 >> 24 & 255) > 0 || par1EntityLiving.hurtTime > 0 || par1EntityLiving.deathTime > 0)
172                {
173                    GL11.glDisable(GL11.GL_TEXTURE_2D);
174                    GL11.glDisable(GL11.GL_ALPHA_TEST);
175                    GL11.glEnable(GL11.GL_BLEND);
176                    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
177                    GL11.glDepthFunc(GL11.GL_EQUAL);
178    
179                    if (par1EntityLiving.hurtTime > 0 || par1EntityLiving.deathTime > 0)
180                    {
181                        GL11.glColor4f(var26, 0.0F, 0.0F, 0.4F);
182                        this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
183    
184                        for (int var27 = 0; var27 < 4; ++var27)
185                        {
186                            if (this.inheritRenderPass(par1EntityLiving, var27, par9) >= 0)
187                            {
188                                GL11.glColor4f(var26, 0.0F, 0.0F, 0.4F);
189                                this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
190                            }
191                        }
192                    }
193    
194                    if ((var18 >> 24 & 255) > 0)
195                    {
196                        var19 = (float)(var18 >> 16 & 255) / 255.0F;
197                        var20 = (float)(var18 >> 8 & 255) / 255.0F;
198                        float var29 = (float)(var18 & 255) / 255.0F;
199                        var22 = (float)(var18 >> 24 & 255) / 255.0F;
200                        GL11.glColor4f(var19, var20, var29, var22);
201                        this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
202    
203                        for (int var28 = 0; var28 < 4; ++var28)
204                        {
205                            if (this.inheritRenderPass(par1EntityLiving, var28, par9) >= 0)
206                            {
207                                GL11.glColor4f(var19, var20, var29, var22);
208                                this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14);
209                            }
210                        }
211                    }
212    
213                    GL11.glDepthFunc(GL11.GL_LEQUAL);
214                    GL11.glDisable(GL11.GL_BLEND);
215                    GL11.glEnable(GL11.GL_ALPHA_TEST);
216                    GL11.glEnable(GL11.GL_TEXTURE_2D);
217                }
218    
219                GL11.glDisable(GL12.GL_RESCALE_NORMAL);
220            }
221            catch (Exception var25)
222            {
223                var25.printStackTrace();
224            }
225    
226            OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
227            GL11.glEnable(GL11.GL_TEXTURE_2D);
228            OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
229            GL11.glEnable(GL11.GL_CULL_FACE);
230            GL11.glPopMatrix();
231            this.passSpecialRender(par1EntityLiving, par2, par4, par6);
232        }
233    
234        /**
235         * Renders the model in RenderLiving
236         */
237        protected void renderModel(EntityLiving par1EntityLiving, float par2, float par3, float par4, float par5, float par6, float par7)
238        {
239            this.loadDownloadableImageTexture(par1EntityLiving.skinUrl, par1EntityLiving.getTexture());
240            this.mainModel.render(par1EntityLiving, par2, par3, par4, par5, par6, par7);
241        }
242    
243        /**
244         * Sets a simple glTranslate on a LivingEntity.
245         */
246        protected void renderLivingAt(EntityLiving par1EntityLiving, double par2, double par4, double par6)
247        {
248            GL11.glTranslatef((float)par2, (float)par4, (float)par6);
249        }
250    
251        protected void rotateCorpse(EntityLiving par1EntityLiving, float par2, float par3, float par4)
252        {
253            GL11.glRotatef(180.0F - par3, 0.0F, 1.0F, 0.0F);
254    
255            if (par1EntityLiving.deathTime > 0)
256            {
257                float var5 = ((float)par1EntityLiving.deathTime + par4 - 1.0F) / 20.0F * 1.6F;
258                var5 = MathHelper.sqrt_float(var5);
259    
260                if (var5 > 1.0F)
261                {
262                    var5 = 1.0F;
263                }
264    
265                GL11.glRotatef(var5 * this.getDeathMaxRotation(par1EntityLiving), 0.0F, 0.0F, 1.0F);
266            }
267        }
268    
269        protected float renderSwingProgress(EntityLiving par1EntityLiving, float par2)
270        {
271            return par1EntityLiving.getSwingProgress(par2);
272        }
273    
274        /**
275         * Defines what float the third param in setRotationAngles of ModelBase is
276         */
277        protected float handleRotationFloat(EntityLiving par1EntityLiving, float par2)
278        {
279            return (float)par1EntityLiving.ticksExisted + par2;
280        }
281    
282        protected void renderEquippedItems(EntityLiving par1EntityLiving, float par2) {}
283    
284        protected int inheritRenderPass(EntityLiving par1EntityLiving, int par2, float par3)
285        {
286            return this.shouldRenderPass(par1EntityLiving, par2, par3);
287        }
288    
289        /**
290         * Queries whether should render the specified pass or not.
291         */
292        protected int shouldRenderPass(EntityLiving par1EntityLiving, int par2, float par3)
293        {
294            return -1;
295        }
296    
297        protected float getDeathMaxRotation(EntityLiving par1EntityLiving)
298        {
299            return 90.0F;
300        }
301    
302        /**
303         * Returns an ARGB int color back. Args: entityLiving, lightBrightness, partialTickTime
304         */
305        protected int getColorMultiplier(EntityLiving par1EntityLiving, float par2, float par3)
306        {
307            return 0;
308        }
309    
310        /**
311         * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args:
312         * entityLiving, partialTickTime
313         */
314        protected void preRenderCallback(EntityLiving par1EntityLiving, float par2) {}
315    
316        /**
317         * Passes the specialRender and renders it
318         */
319        protected void passSpecialRender(EntityLiving par1EntityLiving, double par2, double par4, double par6)
320        {
321            if (Minecraft.isDebugInfoEnabled())
322            {
323                ;
324            }
325        }
326    
327        /**
328         * Draws the debug or playername text above a living
329         */
330        protected void renderLivingLabel(EntityLiving par1EntityLiving, String par2Str, double par3, double par5, double par7, int par9)
331        {
332            double var10 = par1EntityLiving.getDistanceSqToEntity(this.renderManager.livingPlayer);
333    
334            if (var10 <= (double)(par9 * par9))
335            {
336                FontRenderer var12 = this.getFontRendererFromRenderManager();
337                float var13 = 1.6F;
338                float var14 = 0.016666668F * var13;
339                GL11.glPushMatrix();
340                GL11.glTranslatef((float)par3 + 0.0F, (float)par5 + 2.3F, (float)par7);
341                GL11.glNormal3f(0.0F, 1.0F, 0.0F);
342                GL11.glRotatef(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
343                GL11.glRotatef(this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
344                GL11.glScalef(-var14, -var14, var14);
345                GL11.glDisable(GL11.GL_LIGHTING);
346                GL11.glDepthMask(false);
347                GL11.glDisable(GL11.GL_DEPTH_TEST);
348                GL11.glEnable(GL11.GL_BLEND);
349                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
350                Tessellator var15 = Tessellator.instance;
351                byte var16 = 0;
352    
353                if (par2Str.equals("deadmau5"))
354                {
355                    var16 = -10;
356                }
357    
358                GL11.glDisable(GL11.GL_TEXTURE_2D);
359                var15.startDrawingQuads();
360                int var17 = var12.getStringWidth(par2Str) / 2;
361                var15.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F);
362                var15.addVertex((double)(-var17 - 1), (double)(-1 + var16), 0.0D);
363                var15.addVertex((double)(-var17 - 1), (double)(8 + var16), 0.0D);
364                var15.addVertex((double)(var17 + 1), (double)(8 + var16), 0.0D);
365                var15.addVertex((double)(var17 + 1), (double)(-1 + var16), 0.0D);
366                var15.draw();
367                GL11.glEnable(GL11.GL_TEXTURE_2D);
368                var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, 553648127);
369                GL11.glEnable(GL11.GL_DEPTH_TEST);
370                GL11.glDepthMask(true);
371                var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, -1);
372                GL11.glEnable(GL11.GL_LIGHTING);
373                GL11.glDisable(GL11.GL_BLEND);
374                GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
375                GL11.glPopMatrix();
376            }
377        }
378    
379        /**
380         * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
381         * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
382         * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
383         * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
384         */
385        public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
386        {
387            this.doRenderLiving((EntityLiving)par1Entity, par2, par4, par6, par8, par9);
388        }
389    }