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    }