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