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    }