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.getHasActivePotion()) 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 }