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 }