001 package net.minecraft.client.renderer.entity; 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 net.minecraft.client.gui.FontRenderer; 008 import net.minecraft.client.model.ModelBase; 009 import net.minecraft.client.model.ModelBox; 010 import net.minecraft.client.model.ModelRenderer; 011 import net.minecraft.client.renderer.OpenGlHelper; 012 import net.minecraft.client.renderer.RenderHelper; 013 import net.minecraft.client.renderer.Tessellator; 014 import net.minecraft.entity.Entity; 015 import net.minecraft.entity.EntityLiving; 016 import net.minecraft.entity.projectile.EntityArrow; 017 import net.minecraft.util.MathHelper; 018 import org.lwjgl.opengl.GL11; 019 import org.lwjgl.opengl.GL12; 020 021 @SideOnly(Side.CLIENT) 022 public 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 var4; 052 053 for (var4 = par2 - par1; var4 < -180.0F; var4 += 360.0F) 054 { 055 ; 056 } 057 058 while (var4 >= 180.0F) 059 { 060 var4 -= 360.0F; 061 } 062 063 return par1 + par3 * var4; 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 var10 = this.interpolateRotation(par1EntityLiving.prevRenderYawOffset, par1EntityLiving.renderYawOffset, par9); 094 float var11 = this.interpolateRotation(par1EntityLiving.prevRotationYawHead, par1EntityLiving.rotationYawHead, par9); 095 float var12 = par1EntityLiving.prevRotationPitch + (par1EntityLiving.rotationPitch - par1EntityLiving.prevRotationPitch) * par9; 096 this.renderLivingAt(par1EntityLiving, par2, par4, par6); 097 float var13 = this.handleRotationFloat(par1EntityLiving, par9); 098 this.rotateCorpse(par1EntityLiving, var13, var10, par9); 099 float var14 = 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 * var14 - 0.0078125F, 0.0F); 104 float var15 = par1EntityLiving.prevLegYaw + (par1EntityLiving.legYaw - par1EntityLiving.prevLegYaw) * par9; 105 float var16 = par1EntityLiving.legSwing - par1EntityLiving.legYaw * (1.0F - par9); 106 107 if (par1EntityLiving.isChild()) 108 { 109 var16 *= 3.0F; 110 } 111 112 if (var15 > 1.0F) 113 { 114 var15 = 1.0F; 115 } 116 117 GL11.glEnable(GL11.GL_ALPHA_TEST); 118 this.mainModel.setLivingAnimations(par1EntityLiving, var16, var15, par9); 119 this.renderModel(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 120 float var19; 121 int var18; 122 float var20; 123 float var22; 124 125 for (int var17 = 0; var17 < 4; ++var17) 126 { 127 var18 = this.shouldRenderPass(par1EntityLiving, var17, par9); 128 129 if (var18 > 0) 130 { 131 this.renderPassModel.setLivingAnimations(par1EntityLiving, var16, var15, par9); 132 this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 133 134 if ((var18 & 240) == 16) 135 { 136 this.func_82408_c(par1EntityLiving, var17, par9); 137 this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 138 } 139 140 if ((var18 & 15) == 15) 141 { 142 var19 = (float)par1EntityLiving.ticksExisted + par9; 143 this.loadTexture("%blur%/misc/glint.png"); 144 GL11.glEnable(GL11.GL_BLEND); 145 var20 = 0.5F; 146 GL11.glColor4f(var20, var20, var20, 1.0F); 147 GL11.glDepthFunc(GL11.GL_EQUAL); 148 GL11.glDepthMask(false); 149 150 for (int var21 = 0; var21 < 2; ++var21) 151 { 152 GL11.glDisable(GL11.GL_LIGHTING); 153 var22 = 0.76F; 154 GL11.glColor4f(0.5F * var22, 0.25F * var22, 0.8F * var22, 1.0F); 155 GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); 156 GL11.glMatrixMode(GL11.GL_TEXTURE); 157 GL11.glLoadIdentity(); 158 float var23 = var19 * (0.001F + (float)var21 * 0.003F) * 20.0F; 159 float var24 = 0.33333334F; 160 GL11.glScalef(var24, var24, var24); 161 GL11.glRotatef(30.0F - (float)var21 * 60.0F, 0.0F, 0.0F, 1.0F); 162 GL11.glTranslatef(0.0F, var23, 0.0F); 163 GL11.glMatrixMode(GL11.GL_MODELVIEW); 164 this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 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 var26 = par1EntityLiving.getBrightness(par9); 185 var18 = this.getColorMultiplier(par1EntityLiving, var26, par9); 186 OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); 187 GL11.glDisable(GL11.GL_TEXTURE_2D); 188 OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); 189 190 if ((var18 >> 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(var26, 0.0F, 0.0F, 0.4F); 201 this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 202 203 for (int var27 = 0; var27 < 4; ++var27) 204 { 205 if (this.inheritRenderPass(par1EntityLiving, var27, par9) >= 0) 206 { 207 GL11.glColor4f(var26, 0.0F, 0.0F, 0.4F); 208 this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 209 } 210 } 211 } 212 213 if ((var18 >> 24 & 255) > 0) 214 { 215 var19 = (float)(var18 >> 16 & 255) / 255.0F; 216 var20 = (float)(var18 >> 8 & 255) / 255.0F; 217 float var29 = (float)(var18 & 255) / 255.0F; 218 var22 = (float)(var18 >> 24 & 255) / 255.0F; 219 GL11.glColor4f(var19, var20, var29, var22); 220 this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 221 222 for (int var28 = 0; var28 < 4; ++var28) 223 { 224 if (this.inheritRenderPass(par1EntityLiving, var28, par9) >= 0) 225 { 226 GL11.glColor4f(var19, var20, var29, var22); 227 this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 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 var25) 241 { 242 var25.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 if (!par1EntityLiving.getHasActivePotion()) 259 { 260 this.loadDownloadableImageTexture(par1EntityLiving.skinUrl, par1EntityLiving.getTexture()); 261 this.mainModel.render(par1EntityLiving, par2, par3, par4, par5, par6, par7); 262 } 263 else 264 { 265 this.mainModel.setRotationAngles(par2, par3, par4, par5, par6, par7, par1EntityLiving); 266 } 267 } 268 269 /** 270 * Sets a simple glTranslate on a LivingEntity. 271 */ 272 protected void renderLivingAt(EntityLiving par1EntityLiving, double par2, double par4, double par6) 273 { 274 GL11.glTranslatef((float)par2, (float)par4, (float)par6); 275 } 276 277 protected void rotateCorpse(EntityLiving par1EntityLiving, float par2, float par3, float par4) 278 { 279 GL11.glRotatef(180.0F - par3, 0.0F, 1.0F, 0.0F); 280 281 if (par1EntityLiving.deathTime > 0) 282 { 283 float var5 = ((float)par1EntityLiving.deathTime + par4 - 1.0F) / 20.0F * 1.6F; 284 var5 = MathHelper.sqrt_float(var5); 285 286 if (var5 > 1.0F) 287 { 288 var5 = 1.0F; 289 } 290 291 GL11.glRotatef(var5 * this.getDeathMaxRotation(par1EntityLiving), 0.0F, 0.0F, 1.0F); 292 } 293 } 294 295 protected float renderSwingProgress(EntityLiving par1EntityLiving, float par2) 296 { 297 return par1EntityLiving.getSwingProgress(par2); 298 } 299 300 /** 301 * Defines what float the third param in setRotationAngles of ModelBase is 302 */ 303 protected float handleRotationFloat(EntityLiving par1EntityLiving, float par2) 304 { 305 return (float)par1EntityLiving.ticksExisted + par2; 306 } 307 308 protected void renderEquippedItems(EntityLiving par1EntityLiving, float par2) {} 309 310 protected void func_85093_e(EntityLiving par1EntityLiving, float par2) 311 { 312 int var3 = par1EntityLiving.func_85035_bI(); 313 314 if (var3 > 0) 315 { 316 EntityArrow var4 = new EntityArrow(par1EntityLiving.worldObj, par1EntityLiving.posX, par1EntityLiving.posY, par1EntityLiving.posZ); 317 Random var5 = new Random((long)par1EntityLiving.entityId); 318 RenderHelper.disableStandardItemLighting(); 319 320 for (int var6 = 0; var6 < var3; ++var6) 321 { 322 GL11.glPushMatrix(); 323 ModelRenderer var7 = this.mainModel.func_85181_a(var5); 324 ModelBox var8 = (ModelBox)var7.cubeList.get(var5.nextInt(var7.cubeList.size())); 325 var7.postRender(0.0625F); 326 float var9 = var5.nextFloat(); 327 float var10 = var5.nextFloat(); 328 float var11 = var5.nextFloat(); 329 float var12 = (var8.posX1 + (var8.posX2 - var8.posX1) * var9) / 16.0F; 330 float var13 = (var8.posY1 + (var8.posY2 - var8.posY1) * var10) / 16.0F; 331 float var14 = (var8.posZ1 + (var8.posZ2 - var8.posZ1) * var11) / 16.0F; 332 GL11.glTranslatef(var12, var13, var14); 333 var9 = var9 * 2.0F - 1.0F; 334 var10 = var10 * 2.0F - 1.0F; 335 var11 = var11 * 2.0F - 1.0F; 336 var9 *= -1.0F; 337 var10 *= -1.0F; 338 var11 *= -1.0F; 339 float var15 = MathHelper.sqrt_float(var9 * var9 + var11 * var11); 340 var4.prevRotationYaw = var4.rotationYaw = (float)(Math.atan2((double)var9, (double)var11) * 180.0D / Math.PI); 341 var4.prevRotationPitch = var4.rotationPitch = (float)(Math.atan2((double)var10, (double)var15) * 180.0D / Math.PI); 342 double var16 = 0.0D; 343 double var18 = 0.0D; 344 double var20 = 0.0D; 345 float var22 = 0.0F; 346 this.renderManager.renderEntityWithPosYaw(var4, var16, var18, var20, var22, par2); 347 GL11.glPopMatrix(); 348 } 349 350 RenderHelper.enableStandardItemLighting(); 351 } 352 } 353 354 protected int inheritRenderPass(EntityLiving par1EntityLiving, int par2, float par3) 355 { 356 return this.shouldRenderPass(par1EntityLiving, par2, par3); 357 } 358 359 /** 360 * Queries whether should render the specified pass or not. 361 */ 362 protected int shouldRenderPass(EntityLiving par1EntityLiving, int par2, float par3) 363 { 364 return -1; 365 } 366 367 protected void func_82408_c(EntityLiving par1EntityLiving, int par2, float par3) {} 368 369 protected float getDeathMaxRotation(EntityLiving par1EntityLiving) 370 { 371 return 90.0F; 372 } 373 374 /** 375 * Returns an ARGB int color back. Args: entityLiving, lightBrightness, partialTickTime 376 */ 377 protected int getColorMultiplier(EntityLiving par1EntityLiving, float par2, float par3) 378 { 379 return 0; 380 } 381 382 /** 383 * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: 384 * entityLiving, partialTickTime 385 */ 386 protected void preRenderCallback(EntityLiving par1EntityLiving, float par2) {} 387 388 /** 389 * Passes the specialRender and renders it 390 */ 391 protected void passSpecialRender(EntityLiving par1EntityLiving, double par2, double par4, double par6) 392 { 393 if (Minecraft.isDebugInfoEnabled()) 394 { 395 ; 396 } 397 } 398 399 /** 400 * Draws the debug or playername text above a living 401 */ 402 protected void renderLivingLabel(EntityLiving par1EntityLiving, String par2Str, double par3, double par5, double par7, int par9) 403 { 404 double var10 = par1EntityLiving.getDistanceSqToEntity(this.renderManager.livingPlayer); 405 406 if (var10 <= (double)(par9 * par9)) 407 { 408 FontRenderer var12 = this.getFontRendererFromRenderManager(); 409 float var13 = 1.6F; 410 float var14 = 0.016666668F * var13; 411 GL11.glPushMatrix(); 412 GL11.glTranslatef((float)par3 + 0.0F, (float)par5 + 2.3F, (float)par7); 413 GL11.glNormal3f(0.0F, 1.0F, 0.0F); 414 GL11.glRotatef(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); 415 GL11.glRotatef(this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F); 416 GL11.glScalef(-var14, -var14, var14); 417 GL11.glDisable(GL11.GL_LIGHTING); 418 GL11.glDepthMask(false); 419 GL11.glDisable(GL11.GL_DEPTH_TEST); 420 GL11.glEnable(GL11.GL_BLEND); 421 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 422 Tessellator var15 = Tessellator.instance; 423 byte var16 = 0; 424 425 if (par2Str.equals("deadmau5")) 426 { 427 var16 = -10; 428 } 429 430 GL11.glDisable(GL11.GL_TEXTURE_2D); 431 var15.startDrawingQuads(); 432 int var17 = var12.getStringWidth(par2Str) / 2; 433 var15.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F); 434 var15.addVertex((double)(-var17 - 1), (double)(-1 + var16), 0.0D); 435 var15.addVertex((double)(-var17 - 1), (double)(8 + var16), 0.0D); 436 var15.addVertex((double)(var17 + 1), (double)(8 + var16), 0.0D); 437 var15.addVertex((double)(var17 + 1), (double)(-1 + var16), 0.0D); 438 var15.draw(); 439 GL11.glEnable(GL11.GL_TEXTURE_2D); 440 var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, 553648127); 441 GL11.glEnable(GL11.GL_DEPTH_TEST); 442 GL11.glDepthMask(true); 443 var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, -1); 444 GL11.glEnable(GL11.GL_LIGHTING); 445 GL11.glDisable(GL11.GL_BLEND); 446 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 447 GL11.glPopMatrix(); 448 } 449 } 450 451 /** 452 * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then 453 * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic 454 * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1, 455 * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that. 456 */ 457 public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) 458 { 459 this.doRenderLiving((EntityLiving)par1Entity, par2, par4, par6, par8, par9); 460 } 461 }