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 == 15) 123 { 124 var19 = (float)par1EntityLiving.ticksExisted + par9; 125 this.loadTexture("%blur%/misc/glint.png"); 126 GL11.glEnable(GL11.GL_BLEND); 127 var20 = 0.5F; 128 GL11.glColor4f(var20, var20, var20, 1.0F); 129 GL11.glDepthFunc(GL11.GL_EQUAL); 130 GL11.glDepthMask(false); 131 132 for (int var21 = 0; var21 < 2; ++var21) 133 { 134 GL11.glDisable(GL11.GL_LIGHTING); 135 var22 = 0.76F; 136 GL11.glColor4f(0.5F * var22, 0.25F * var22, 0.8F * var22, 1.0F); 137 GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); 138 GL11.glMatrixMode(GL11.GL_TEXTURE); 139 GL11.glLoadIdentity(); 140 float var23 = var19 * (0.001F + (float)var21 * 0.003F) * 20.0F; 141 float var24 = 0.33333334F; 142 GL11.glScalef(var24, var24, var24); 143 GL11.glRotatef(30.0F - (float)var21 * 60.0F, 0.0F, 0.0F, 1.0F); 144 GL11.glTranslatef(0.0F, var23, 0.0F); 145 GL11.glMatrixMode(GL11.GL_MODELVIEW); 146 this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 147 } 148 149 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 150 GL11.glMatrixMode(GL11.GL_TEXTURE); 151 GL11.glDepthMask(true); 152 GL11.glLoadIdentity(); 153 GL11.glMatrixMode(GL11.GL_MODELVIEW); 154 GL11.glEnable(GL11.GL_LIGHTING); 155 GL11.glDisable(GL11.GL_BLEND); 156 GL11.glDepthFunc(GL11.GL_LEQUAL); 157 } 158 159 GL11.glDisable(GL11.GL_BLEND); 160 GL11.glEnable(GL11.GL_ALPHA_TEST); 161 } 162 } 163 164 this.renderEquippedItems(par1EntityLiving, par9); 165 float var26 = par1EntityLiving.getBrightness(par9); 166 var18 = this.getColorMultiplier(par1EntityLiving, var26, par9); 167 OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); 168 GL11.glDisable(GL11.GL_TEXTURE_2D); 169 OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); 170 171 if ((var18 >> 24 & 255) > 0 || par1EntityLiving.hurtTime > 0 || par1EntityLiving.deathTime > 0) 172 { 173 GL11.glDisable(GL11.GL_TEXTURE_2D); 174 GL11.glDisable(GL11.GL_ALPHA_TEST); 175 GL11.glEnable(GL11.GL_BLEND); 176 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 177 GL11.glDepthFunc(GL11.GL_EQUAL); 178 179 if (par1EntityLiving.hurtTime > 0 || par1EntityLiving.deathTime > 0) 180 { 181 GL11.glColor4f(var26, 0.0F, 0.0F, 0.4F); 182 this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 183 184 for (int var27 = 0; var27 < 4; ++var27) 185 { 186 if (this.inheritRenderPass(par1EntityLiving, var27, par9) >= 0) 187 { 188 GL11.glColor4f(var26, 0.0F, 0.0F, 0.4F); 189 this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 190 } 191 } 192 } 193 194 if ((var18 >> 24 & 255) > 0) 195 { 196 var19 = (float)(var18 >> 16 & 255) / 255.0F; 197 var20 = (float)(var18 >> 8 & 255) / 255.0F; 198 float var29 = (float)(var18 & 255) / 255.0F; 199 var22 = (float)(var18 >> 24 & 255) / 255.0F; 200 GL11.glColor4f(var19, var20, var29, var22); 201 this.mainModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 202 203 for (int var28 = 0; var28 < 4; ++var28) 204 { 205 if (this.inheritRenderPass(par1EntityLiving, var28, par9) >= 0) 206 { 207 GL11.glColor4f(var19, var20, var29, var22); 208 this.renderPassModel.render(par1EntityLiving, var16, var15, var13, var11 - var10, var12, var14); 209 } 210 } 211 } 212 213 GL11.glDepthFunc(GL11.GL_LEQUAL); 214 GL11.glDisable(GL11.GL_BLEND); 215 GL11.glEnable(GL11.GL_ALPHA_TEST); 216 GL11.glEnable(GL11.GL_TEXTURE_2D); 217 } 218 219 GL11.glDisable(GL12.GL_RESCALE_NORMAL); 220 } 221 catch (Exception var25) 222 { 223 var25.printStackTrace(); 224 } 225 226 OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); 227 GL11.glEnable(GL11.GL_TEXTURE_2D); 228 OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); 229 GL11.glEnable(GL11.GL_CULL_FACE); 230 GL11.glPopMatrix(); 231 this.passSpecialRender(par1EntityLiving, par2, par4, par6); 232 } 233 234 /** 235 * Renders the model in RenderLiving 236 */ 237 protected void renderModel(EntityLiving par1EntityLiving, float par2, float par3, float par4, float par5, float par6, float par7) 238 { 239 this.loadDownloadableImageTexture(par1EntityLiving.skinUrl, par1EntityLiving.getTexture()); 240 this.mainModel.render(par1EntityLiving, par2, par3, par4, par5, par6, par7); 241 } 242 243 /** 244 * Sets a simple glTranslate on a LivingEntity. 245 */ 246 protected void renderLivingAt(EntityLiving par1EntityLiving, double par2, double par4, double par6) 247 { 248 GL11.glTranslatef((float)par2, (float)par4, (float)par6); 249 } 250 251 protected void rotateCorpse(EntityLiving par1EntityLiving, float par2, float par3, float par4) 252 { 253 GL11.glRotatef(180.0F - par3, 0.0F, 1.0F, 0.0F); 254 255 if (par1EntityLiving.deathTime > 0) 256 { 257 float var5 = ((float)par1EntityLiving.deathTime + par4 - 1.0F) / 20.0F * 1.6F; 258 var5 = MathHelper.sqrt_float(var5); 259 260 if (var5 > 1.0F) 261 { 262 var5 = 1.0F; 263 } 264 265 GL11.glRotatef(var5 * this.getDeathMaxRotation(par1EntityLiving), 0.0F, 0.0F, 1.0F); 266 } 267 } 268 269 protected float renderSwingProgress(EntityLiving par1EntityLiving, float par2) 270 { 271 return par1EntityLiving.getSwingProgress(par2); 272 } 273 274 /** 275 * Defines what float the third param in setRotationAngles of ModelBase is 276 */ 277 protected float handleRotationFloat(EntityLiving par1EntityLiving, float par2) 278 { 279 return (float)par1EntityLiving.ticksExisted + par2; 280 } 281 282 protected void renderEquippedItems(EntityLiving par1EntityLiving, float par2) {} 283 284 protected int inheritRenderPass(EntityLiving par1EntityLiving, int par2, float par3) 285 { 286 return this.shouldRenderPass(par1EntityLiving, par2, par3); 287 } 288 289 /** 290 * Queries whether should render the specified pass or not. 291 */ 292 protected int shouldRenderPass(EntityLiving par1EntityLiving, int par2, float par3) 293 { 294 return -1; 295 } 296 297 protected float getDeathMaxRotation(EntityLiving par1EntityLiving) 298 { 299 return 90.0F; 300 } 301 302 /** 303 * Returns an ARGB int color back. Args: entityLiving, lightBrightness, partialTickTime 304 */ 305 protected int getColorMultiplier(EntityLiving par1EntityLiving, float par2, float par3) 306 { 307 return 0; 308 } 309 310 /** 311 * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: 312 * entityLiving, partialTickTime 313 */ 314 protected void preRenderCallback(EntityLiving par1EntityLiving, float par2) {} 315 316 /** 317 * Passes the specialRender and renders it 318 */ 319 protected void passSpecialRender(EntityLiving par1EntityLiving, double par2, double par4, double par6) 320 { 321 if (Minecraft.isDebugInfoEnabled()) 322 { 323 ; 324 } 325 } 326 327 /** 328 * Draws the debug or playername text above a living 329 */ 330 protected void renderLivingLabel(EntityLiving par1EntityLiving, String par2Str, double par3, double par5, double par7, int par9) 331 { 332 double var10 = par1EntityLiving.getDistanceSqToEntity(this.renderManager.livingPlayer); 333 334 if (var10 <= (double)(par9 * par9)) 335 { 336 FontRenderer var12 = this.getFontRendererFromRenderManager(); 337 float var13 = 1.6F; 338 float var14 = 0.016666668F * var13; 339 GL11.glPushMatrix(); 340 GL11.glTranslatef((float)par3 + 0.0F, (float)par5 + 2.3F, (float)par7); 341 GL11.glNormal3f(0.0F, 1.0F, 0.0F); 342 GL11.glRotatef(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); 343 GL11.glRotatef(this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F); 344 GL11.glScalef(-var14, -var14, var14); 345 GL11.glDisable(GL11.GL_LIGHTING); 346 GL11.glDepthMask(false); 347 GL11.glDisable(GL11.GL_DEPTH_TEST); 348 GL11.glEnable(GL11.GL_BLEND); 349 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 350 Tessellator var15 = Tessellator.instance; 351 byte var16 = 0; 352 353 if (par2Str.equals("deadmau5")) 354 { 355 var16 = -10; 356 } 357 358 GL11.glDisable(GL11.GL_TEXTURE_2D); 359 var15.startDrawingQuads(); 360 int var17 = var12.getStringWidth(par2Str) / 2; 361 var15.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F); 362 var15.addVertex((double)(-var17 - 1), (double)(-1 + var16), 0.0D); 363 var15.addVertex((double)(-var17 - 1), (double)(8 + var16), 0.0D); 364 var15.addVertex((double)(var17 + 1), (double)(8 + var16), 0.0D); 365 var15.addVertex((double)(var17 + 1), (double)(-1 + var16), 0.0D); 366 var15.draw(); 367 GL11.glEnable(GL11.GL_TEXTURE_2D); 368 var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, 553648127); 369 GL11.glEnable(GL11.GL_DEPTH_TEST); 370 GL11.glDepthMask(true); 371 var12.drawString(par2Str, -var12.getStringWidth(par2Str) / 2, var16, -1); 372 GL11.glEnable(GL11.GL_LIGHTING); 373 GL11.glDisable(GL11.GL_BLEND); 374 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 375 GL11.glPopMatrix(); 376 } 377 } 378 379 /** 380 * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then 381 * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic 382 * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1, 383 * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that. 384 */ 385 public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) 386 { 387 this.doRenderLiving((EntityLiving)par1Entity, par2, par4, par6, par8, par9); 388 } 389 }