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