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.block.Block;
007 import net.minecraft.client.Minecraft;
008 import net.minecraft.client.gui.FontRenderer;
009 import net.minecraft.client.renderer.RenderBlocks;
010 import net.minecraft.client.renderer.RenderEngine;
011 import net.minecraft.client.renderer.Tessellator;
012 import net.minecraft.entity.Entity;
013 import net.minecraft.entity.item.EntityItem;
014 import net.minecraft.item.Item;
015 import net.minecraft.item.ItemBlock;
016 import net.minecraft.item.ItemStack;
017 import net.minecraft.util.MathHelper;
018 import org.lwjgl.opengl.GL11;
019 import org.lwjgl.opengl.GL12;
020
021 import net.minecraftforge.client.ForgeHooksClient;
022
023 @SideOnly(Side.CLIENT)
024 public class RenderItem extends Render
025 {
026 private RenderBlocks renderBlocks = new RenderBlocks();
027
028 /** The RNG used in RenderItem (for bobbing itemstacks on the ground) */
029 private Random random = new Random();
030 public boolean field_77024_a = true;
031
032 /** Defines the zLevel of rendering of item on GUI. */
033 public float zLevel = 0.0F;
034 public static boolean field_82407_g = false;
035
036 public RenderItem()
037 {
038 this.shadowSize = 0.15F;
039 this.shadowOpaque = 0.75F;
040 }
041
042 /**
043 * Renders the item
044 */
045 public void doRenderItem(EntityItem par1EntityItem, double par2, double par4, double par6, float par8, float par9)
046 {
047 this.random.setSeed(187L);
048 ItemStack var10 = par1EntityItem.item;
049
050 if (var10.getItem() != null)
051 {
052 GL11.glPushMatrix();
053 float var11 = MathHelper.sin(((float)par1EntityItem.age + par9) / 10.0F + par1EntityItem.hoverStart) * 0.1F + 0.1F;
054 float var12 = (((float)par1EntityItem.age + par9) / 20.0F + par1EntityItem.hoverStart) * (180F / (float)Math.PI);
055 byte var13 = 1;
056
057 if (par1EntityItem.item.stackSize > 1)
058 {
059 var13 = 2;
060 }
061
062 if (par1EntityItem.item.stackSize > 5)
063 {
064 var13 = 3;
065 }
066
067 if (par1EntityItem.item.stackSize > 20)
068 {
069 var13 = 4;
070 }
071
072 GL11.glTranslatef((float)par2, (float)par4 + var11, (float)par6);
073 GL11.glEnable(GL12.GL_RESCALE_NORMAL);
074 int var16;
075 float var19;
076 float var20;
077 float var24;
078
079 if (ForgeHooksClient.renderEntityItem(par1EntityItem, var10, var11, var12, random, renderManager.renderEngine, renderBlocks))
080 {
081 ;
082 }
083 else if (var10.getItem() instanceof ItemBlock && RenderBlocks.renderItemIn3d(Block.blocksList[var10.itemID].getRenderType()))
084 {
085 GL11.glRotatef(var12, 0.0F, 1.0F, 0.0F);
086
087 if (field_82407_g)
088 {
089 GL11.glScalef(1.25F, 1.25F, 1.25F);
090 GL11.glTranslatef(0.0F, 0.05F, 0.0F);
091 GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F);
092 }
093
094 this.loadTexture(Block.blocksList[var10.itemID].getTextureFile());
095 float var22 = 0.25F;
096 var16 = Block.blocksList[var10.itemID].getRenderType();
097
098 if (var16 == 1 || var16 == 19 || var16 == 12 || var16 == 2)
099 {
100 var22 = 0.5F;
101 }
102
103 GL11.glScalef(var22, var22, var22);
104
105 for (int var23 = 0; var23 < var13; ++var23)
106 {
107 GL11.glPushMatrix();
108
109 if (var23 > 0)
110 {
111 var24 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.2F / var22;
112 var19 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.2F / var22;
113 var20 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.2F / var22;
114 GL11.glTranslatef(var24, var19, var20);
115 }
116
117 var24 = 1.0F;
118 this.renderBlocks.renderBlockAsItem(Block.blocksList[var10.itemID], var10.getItemDamage(), var24);
119 GL11.glPopMatrix();
120 }
121 }
122 else
123 {
124 int var15;
125 float var17;
126
127 if (var10.getItem().requiresMultipleRenderPasses())
128 {
129 if (field_82407_g)
130 {
131 GL11.glScalef(0.5128205F, 0.5128205F, 0.5128205F);
132 GL11.glTranslatef(0.0F, -0.05F, 0.0F);
133 GL11.glDisable(GL11.GL_LIGHTING);
134 }
135 else
136 {
137 GL11.glScalef(0.5F, 0.5F, 0.5F);
138 }
139
140 this.loadTexture(Item.itemsList[var10.itemID].getTextureFile());
141
142 for (var15 = 0; var15 < var10.getItem().getRenderPasses(var10.getItemDamage()); ++var15)
143 {
144 this.random.setSeed(187L); //Fixes Vanilla bug where layers would not render aligns properly.
145 var16 = var10.getItem().getIconFromItemStackForMultiplePasses(var10, var15);
146 var17 = 1.0F;
147
148 if (this.field_77024_a)
149 {
150 int var18 = Item.itemsList[var10.itemID].getColorFromItemStack(var10, var15);
151 var19 = (float)(var18 >> 16 & 255) / 255.0F;
152 var20 = (float)(var18 >> 8 & 255) / 255.0F;
153 float var21 = (float)(var18 & 255) / 255.0F;
154 GL11.glColor4f(var19 * var17, var20 * var17, var21 * var17, 1.0F);
155 }
156
157 this.func_77020_a(var16, var13);
158 }
159 }
160 else
161 {
162 if (field_82407_g)
163 {
164 GL11.glScalef(0.5128205F, 0.5128205F, 0.5128205F);
165 GL11.glTranslatef(0.0F, -0.05F, 0.0F);
166 GL11.glDisable(GL11.GL_LIGHTING);
167 }
168 else
169 {
170 GL11.glScalef(0.5F, 0.5F, 0.5F);
171 }
172
173 var15 = var10.getIconIndex();
174
175 this.loadTexture(var10.getItem().getTextureFile());
176
177 if (this.field_77024_a)
178 {
179 var16 = Item.itemsList[var10.itemID].getColorFromItemStack(var10, 0);
180 var17 = (float)(var16 >> 16 & 255) / 255.0F;
181 var24 = (float)(var16 >> 8 & 255) / 255.0F;
182 var19 = (float)(var16 & 255) / 255.0F;
183 var20 = 1.0F;
184 GL11.glColor4f(var17 * var20, var24 * var20, var19 * var20, 1.0F);
185 }
186
187 this.func_77020_a(var15, var13);
188 }
189 }
190
191 GL11.glDisable(GL12.GL_RESCALE_NORMAL);
192 GL11.glPopMatrix();
193 }
194 }
195
196 private void func_77020_a(int par1, int par2)
197 {
198 Tessellator var3 = Tessellator.instance;
199 float var4 = (float)(par1 % 16 * 16 + 0) / 256.0F;
200 float var5 = (float)(par1 % 16 * 16 + 16) / 256.0F;
201 float var6 = (float)(par1 / 16 * 16 + 0) / 256.0F;
202 float var7 = (float)(par1 / 16 * 16 + 16) / 256.0F;
203 float var8 = 1.0F;
204 float var9 = 0.5F;
205 float var10 = 0.25F;
206
207 for (int var11 = 0; var11 < par2; ++var11)
208 {
209 GL11.glPushMatrix();
210
211 if (var11 > 0)
212 {
213 float var12 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.3F;
214 float var13 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.3F;
215 float var14 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.3F;
216 GL11.glTranslatef(var12, var13, var14);
217 }
218
219 GL11.glRotatef(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
220 var3.startDrawingQuads();
221 var3.setNormal(0.0F, 1.0F, 0.0F);
222 var3.addVertexWithUV((double)(0.0F - var9), (double)(0.0F - var10), 0.0D, (double)var4, (double)var7);
223 var3.addVertexWithUV((double)(var8 - var9), (double)(0.0F - var10), 0.0D, (double)var5, (double)var7);
224 var3.addVertexWithUV((double)(var8 - var9), (double)(1.0F - var10), 0.0D, (double)var5, (double)var6);
225 var3.addVertexWithUV((double)(0.0F - var9), (double)(1.0F - var10), 0.0D, (double)var4, (double)var6);
226 var3.draw();
227 GL11.glPopMatrix();
228 }
229 }
230
231 /**
232 * Renders the item's icon or block into the UI at the specified position.
233 */
234 public void renderItemIntoGUI(FontRenderer par1FontRenderer, RenderEngine par2RenderEngine, ItemStack par3ItemStack, int par4, int par5)
235 {
236 int var6 = par3ItemStack.itemID;
237 int var7 = par3ItemStack.getItemDamage();
238 int var8 = par3ItemStack.getIconIndex();
239 int var10;
240 float var12;
241 float var13;
242 float var16;
243
244 if (par3ItemStack.getItem() instanceof ItemBlock && RenderBlocks.renderItemIn3d(Block.blocksList[par3ItemStack.itemID].getRenderType()))
245 {
246 Block var15 = Block.blocksList[var6];
247 par2RenderEngine.bindTexture(par2RenderEngine.getTexture(var15.getTextureFile()));
248 GL11.glPushMatrix();
249 GL11.glTranslatef((float)(par4 - 2), (float)(par5 + 3), -3.0F + this.zLevel);
250 GL11.glScalef(10.0F, 10.0F, 10.0F);
251 GL11.glTranslatef(1.0F, 0.5F, 1.0F);
252 GL11.glScalef(1.0F, 1.0F, -1.0F);
253 GL11.glRotatef(210.0F, 1.0F, 0.0F, 0.0F);
254 GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
255 var10 = Item.itemsList[var6].getColorFromItemStack(par3ItemStack, 0);
256 var16 = (float)(var10 >> 16 & 255) / 255.0F;
257 var12 = (float)(var10 >> 8 & 255) / 255.0F;
258 var13 = (float)(var10 & 255) / 255.0F;
259
260 if (this.field_77024_a)
261 {
262 GL11.glColor4f(var16, var12, var13, 1.0F);
263 }
264
265 GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F);
266 this.renderBlocks.useInventoryTint = this.field_77024_a;
267 this.renderBlocks.renderBlockAsItem(var15, var7, 1.0F);
268 this.renderBlocks.useInventoryTint = true;
269 GL11.glPopMatrix();
270 }
271 else
272 {
273 int var9;
274
275 if (Item.itemsList[var6].requiresMultipleRenderPasses())
276 {
277 GL11.glDisable(GL11.GL_LIGHTING);
278 par2RenderEngine.bindTexture(par2RenderEngine.getTexture(Item.itemsList[var6].getTextureFile()));
279
280 for (var9 = 0; var9 < Item.itemsList[var6].getRenderPasses(var7); ++var9)
281 {
282 var10 = Item.itemsList[var6].getIconFromItemStackForMultiplePasses(par3ItemStack, var9);
283 int var11 = Item.itemsList[var6].getColorFromItemStack(par3ItemStack, var9);
284 var12 = (float)(var11 >> 16 & 255) / 255.0F;
285 var13 = (float)(var11 >> 8 & 255) / 255.0F;
286 float var14 = (float)(var11 & 255) / 255.0F;
287
288 if (this.field_77024_a)
289 {
290 GL11.glColor4f(var12, var13, var14, 1.0F);
291 }
292
293 this.renderTexturedQuad(par4, par5, var10 % 16 * 16, var10 / 16 * 16, 16, 16);
294 }
295
296 GL11.glEnable(GL11.GL_LIGHTING);
297 }
298 else if (var8 >= 0)
299 {
300 GL11.glDisable(GL11.GL_LIGHTING);
301
302 par2RenderEngine.bindTexture(par2RenderEngine.getTexture(par3ItemStack.getItem().getTextureFile()));
303
304 var9 = Item.itemsList[var6].getColorFromItemStack(par3ItemStack, 0);
305 float var17 = (float)(var9 >> 16 & 255) / 255.0F;
306 var16 = (float)(var9 >> 8 & 255) / 255.0F;
307 var12 = (float)(var9 & 255) / 255.0F;
308
309 if (this.field_77024_a)
310 {
311 GL11.glColor4f(var17, var16, var12, 1.0F);
312 }
313
314 this.renderTexturedQuad(par4, par5, var8 % 16 * 16, var8 / 16 * 16, 16, 16);
315 GL11.glEnable(GL11.GL_LIGHTING);
316 }
317 }
318
319 GL11.glEnable(GL11.GL_CULL_FACE);
320 }
321
322 /**
323 * Render the item's icon or block into the GUI, including the glint effect.
324 */
325 public void renderItemAndEffectIntoGUI(FontRenderer par1FontRenderer, RenderEngine par2RenderEngine, ItemStack par3ItemStack, int par4, int par5)
326 {
327 if (par3ItemStack != null)
328 {
329 if (!ForgeHooksClient.renderInventoryItem(renderBlocks, par2RenderEngine, par3ItemStack, field_77024_a, zLevel, (float)par4, (float)par5))
330 {
331 this.renderItemIntoGUI(par1FontRenderer, par2RenderEngine, par3ItemStack, par4, par5);
332 }
333
334 if (par3ItemStack != null && par3ItemStack.hasEffect())
335 {
336 GL11.glDepthFunc(GL11.GL_GREATER);
337 GL11.glDisable(GL11.GL_LIGHTING);
338 GL11.glDepthMask(false);
339 par2RenderEngine.bindTexture(par2RenderEngine.getTexture("%blur%/misc/glint.png"));
340 this.zLevel -= 50.0F;
341 GL11.glEnable(GL11.GL_BLEND);
342 GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_DST_COLOR);
343 GL11.glColor4f(0.5F, 0.25F, 0.8F, 1.0F);
344 this.func_77018_a(par4 * 431278612 + par5 * 32178161, par4 - 2, par5 - 2, 20, 20);
345 GL11.glDisable(GL11.GL_BLEND);
346 GL11.glDepthMask(true);
347 this.zLevel += 50.0F;
348 GL11.glEnable(GL11.GL_LIGHTING);
349 GL11.glDepthFunc(GL11.GL_LEQUAL);
350 }
351 }
352 }
353
354 private void func_77018_a(int par1, int par2, int par3, int par4, int par5)
355 {
356 for (int var6 = 0; var6 < 2; ++var6)
357 {
358 if (var6 == 0)
359 {
360 GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE);
361 }
362
363 if (var6 == 1)
364 {
365 GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE);
366 }
367
368 float var7 = 0.00390625F;
369 float var8 = 0.00390625F;
370 float var9 = (float)(Minecraft.getSystemTime() % (long)(3000 + var6 * 1873)) / (3000.0F + (float)(var6 * 1873)) * 256.0F;
371 float var10 = 0.0F;
372 Tessellator var11 = Tessellator.instance;
373 float var12 = 4.0F;
374
375 if (var6 == 1)
376 {
377 var12 = -1.0F;
378 }
379
380 var11.startDrawingQuads();
381 var11.addVertexWithUV((double)(par2 + 0), (double)(par3 + par5), (double)this.zLevel, (double)((var9 + (float)par5 * var12) * var7), (double)((var10 + (float)par5) * var8));
382 var11.addVertexWithUV((double)(par2 + par4), (double)(par3 + par5), (double)this.zLevel, (double)((var9 + (float)par4 + (float)par5 * var12) * var7), (double)((var10 + (float)par5) * var8));
383 var11.addVertexWithUV((double)(par2 + par4), (double)(par3 + 0), (double)this.zLevel, (double)((var9 + (float)par4) * var7), (double)((var10 + 0.0F) * var8));
384 var11.addVertexWithUV((double)(par2 + 0), (double)(par3 + 0), (double)this.zLevel, (double)((var9 + 0.0F) * var7), (double)((var10 + 0.0F) * var8));
385 var11.draw();
386 }
387 }
388
389 /**
390 * Renders the item's overlay information. Examples being stack count or damage on top of the item's image at the
391 * specified position.
392 */
393 public void renderItemOverlayIntoGUI(FontRenderer par1FontRenderer, RenderEngine par2RenderEngine, ItemStack par3ItemStack, int par4, int par5)
394 {
395 if (par3ItemStack != null)
396 {
397 if (par3ItemStack.stackSize > 1)
398 {
399 String var6 = "" + par3ItemStack.stackSize;
400 GL11.glDisable(GL11.GL_LIGHTING);
401 GL11.glDisable(GL11.GL_DEPTH_TEST);
402 par1FontRenderer.drawStringWithShadow(var6, par4 + 19 - 2 - par1FontRenderer.getStringWidth(var6), par5 + 6 + 3, 16777215);
403 GL11.glEnable(GL11.GL_LIGHTING);
404 GL11.glEnable(GL11.GL_DEPTH_TEST);
405 }
406
407 if (par3ItemStack.isItemDamaged())
408 {
409 int var11 = (int)Math.round(13.0D - (double)par3ItemStack.getItemDamageForDisplay() * 13.0D / (double)par3ItemStack.getMaxDamage());
410 int var7 = (int)Math.round(255.0D - (double)par3ItemStack.getItemDamageForDisplay() * 255.0D / (double)par3ItemStack.getMaxDamage());
411 GL11.glDisable(GL11.GL_LIGHTING);
412 GL11.glDisable(GL11.GL_DEPTH_TEST);
413 GL11.glDisable(GL11.GL_TEXTURE_2D);
414 Tessellator var8 = Tessellator.instance;
415 int var9 = 255 - var7 << 16 | var7 << 8;
416 int var10 = (255 - var7) / 4 << 16 | 16128;
417 this.renderQuad(var8, par4 + 2, par5 + 13, 13, 2, 0);
418 this.renderQuad(var8, par4 + 2, par5 + 13, 12, 1, var10);
419 this.renderQuad(var8, par4 + 2, par5 + 13, var11, 1, var9);
420 GL11.glEnable(GL11.GL_TEXTURE_2D);
421 GL11.glEnable(GL11.GL_LIGHTING);
422 GL11.glEnable(GL11.GL_DEPTH_TEST);
423 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
424 }
425 }
426 }
427
428 /**
429 * Adds a quad to the tesselator at the specified position with the set width and height and color. Args:
430 * tessellator, x, y, width, height, color
431 */
432 private void renderQuad(Tessellator par1Tessellator, int par2, int par3, int par4, int par5, int par6)
433 {
434 par1Tessellator.startDrawingQuads();
435 par1Tessellator.setColorOpaque_I(par6);
436 par1Tessellator.addVertex((double)(par2 + 0), (double)(par3 + 0), 0.0D);
437 par1Tessellator.addVertex((double)(par2 + 0), (double)(par3 + par5), 0.0D);
438 par1Tessellator.addVertex((double)(par2 + par4), (double)(par3 + par5), 0.0D);
439 par1Tessellator.addVertex((double)(par2 + par4), (double)(par3 + 0), 0.0D);
440 par1Tessellator.draw();
441 }
442
443 /**
444 * Adds a textured quad to the tesselator at the specified position with the specified texture coords, width and
445 * height. Args: x, y, u, v, width, height
446 */
447 public void renderTexturedQuad(int par1, int par2, int par3, int par4, int par5, int par6)
448 {
449 float var7 = 0.00390625F;
450 float var8 = 0.00390625F;
451 Tessellator var9 = Tessellator.instance;
452 var9.startDrawingQuads();
453 var9.addVertexWithUV((double)(par1 + 0), (double)(par2 + par6), (double)this.zLevel, (double)((float)(par3 + 0) * var7), (double)((float)(par4 + par6) * var8));
454 var9.addVertexWithUV((double)(par1 + par5), (double)(par2 + par6), (double)this.zLevel, (double)((float)(par3 + par5) * var7), (double)((float)(par4 + par6) * var8));
455 var9.addVertexWithUV((double)(par1 + par5), (double)(par2 + 0), (double)this.zLevel, (double)((float)(par3 + par5) * var7), (double)((float)(par4 + 0) * var8));
456 var9.addVertexWithUV((double)(par1 + 0), (double)(par2 + 0), (double)this.zLevel, (double)((float)(par3 + 0) * var7), (double)((float)(par4 + 0) * var8));
457 var9.draw();
458 }
459
460 /**
461 * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
462 * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
463 * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
464 * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
465 */
466 public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
467 {
468 this.doRenderItem((EntityItem)par1Entity, par2, par4, par6, par8, par9);
469 }
470 }