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.ArrayList; 006 import java.util.Hashtable; 007 import java.util.Iterator; 008 import java.util.List; 009 import java.util.Map.Entry; 010 import java.util.Random; 011 012 import net.minecraftforge.client.ForgeHooksClient; 013 import net.minecraftforge.common.ForgeHooks; 014 import com.google.common.collect.ArrayListMultimap; 015 import com.google.common.collect.Multimap; 016 017 import org.lwjgl.opengl.GL11; 018 019 020 @SideOnly(Side.CLIENT) 021 public class EffectRenderer 022 { 023 /** Reference to the World object. */ 024 protected World worldObj; 025 private List[] fxLayers = new List[4]; 026 private RenderEngine renderer; 027 028 /** RNG. */ 029 private Random rand = new Random(); 030 031 private Multimap<String, EntityFX> effectList = ArrayListMultimap.create(); 032 033 public EffectRenderer(World par1World, RenderEngine par2RenderEngine) 034 { 035 if (par1World != null) 036 { 037 this.worldObj = par1World; 038 } 039 040 this.renderer = par2RenderEngine; 041 042 for (int var3 = 0; var3 < 4; ++var3) 043 { 044 this.fxLayers[var3] = new ArrayList(); 045 } 046 } 047 048 public void addEffect(EntityFX par1EntityFX) 049 { 050 int var2 = par1EntityFX.getFXLayer(); 051 052 if (this.fxLayers[var2].size() >= 4000) 053 { 054 this.fxLayers[var2].remove(0); 055 } 056 057 this.fxLayers[var2].add(par1EntityFX); 058 } 059 060 public void updateEffects() 061 { 062 for (int var1 = 0; var1 < 4; ++var1) 063 { 064 for (int var2 = 0; var2 < this.fxLayers[var1].size(); ++var2) 065 { 066 EntityFX var3 = (EntityFX)this.fxLayers[var1].get(var2); 067 068 if (var3 != null) 069 { 070 var3.onUpdate(); 071 } 072 073 if (var3 == null || var3.isDead) 074 { 075 this.fxLayers[var1].remove(var2--); 076 } 077 } 078 } 079 080 Iterator<Entry<String, EntityFX>> itr = effectList.entries().iterator(); 081 while (itr.hasNext()) 082 { 083 EntityFX fx = itr.next().getValue(); 084 fx.onUpdate(); 085 if (fx.isDead) 086 { 087 itr.remove(); 088 } 089 } 090 } 091 092 /** 093 * Renders all current particles. Args player, partialTickTime 094 */ 095 public void renderParticles(Entity par1Entity, float par2) 096 { 097 float var3 = ActiveRenderInfo.rotationX; 098 float var4 = ActiveRenderInfo.rotationZ; 099 float var5 = ActiveRenderInfo.rotationYZ; 100 float var6 = ActiveRenderInfo.rotationXY; 101 float var7 = ActiveRenderInfo.rotationXZ; 102 EntityFX.interpPosX = par1Entity.lastTickPosX + (par1Entity.posX - par1Entity.lastTickPosX) * (double)par2; 103 EntityFX.interpPosY = par1Entity.lastTickPosY + (par1Entity.posY - par1Entity.lastTickPosY) * (double)par2; 104 EntityFX.interpPosZ = par1Entity.lastTickPosZ + (par1Entity.posZ - par1Entity.lastTickPosZ) * (double)par2; 105 106 for (int var8 = 0; var8 < 3; ++var8) 107 { 108 if (!this.fxLayers[var8].isEmpty()) 109 { 110 int var9 = 0; 111 112 if (var8 == 0) 113 { 114 var9 = this.renderer.getTexture("/particles.png"); 115 } 116 117 if (var8 == 1) 118 { 119 var9 = this.renderer.getTexture("/terrain.png"); 120 } 121 122 if (var8 == 2) 123 { 124 var9 = this.renderer.getTexture("/gui/items.png"); 125 } 126 127 GL11.glBindTexture(GL11.GL_TEXTURE_2D, var9); 128 Tessellator var10 = Tessellator.instance; 129 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 130 GL11.glEnable(GL11.GL_BLEND); 131 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 132 var10.startDrawingQuads(); 133 134 for (int var11 = 0; var11 < this.fxLayers[var8].size(); ++var11) 135 { 136 EntityFX var12 = (EntityFX)this.fxLayers[var8].get(var11); 137 if (var12 == null) continue; 138 var10.setBrightness(var12.getBrightnessForRender(par2)); 139 var12.renderParticle(var10, par2, var3, var7, var4, var5, var6); 140 } 141 142 var10.draw(); 143 GL11.glDisable(GL11.GL_BLEND); 144 } 145 } 146 147 for (String key : effectList.keySet()) 148 { 149 ForgeHooksClient.bindTexture(key, 0); 150 for (EntityFX entry : effectList.get(key)) 151 { 152 if (entry == null) continue; 153 Tessellator tessallator = Tessellator.instance; 154 //GL11.glBindTexture(GL11.GL_TEXTURE_2D, renderer.getTexture(key)); 155 tessallator.startDrawingQuads(); 156 157 if (entry.getFXLayer() != 3) 158 { 159 tessallator.setBrightness(entry.getBrightnessForRender(par2)); 160 entry.renderParticle(tessallator, par2, var3, var7, var4, var5, var6); 161 } 162 163 tessallator.draw(); 164 } 165 ForgeHooksClient.unbindTexture(); 166 } 167 } 168 169 public void renderLitParticles(Entity par1Entity, float par2) 170 { 171 float var4 = MathHelper.cos(par1Entity.rotationYaw * 0.017453292F); 172 float var5 = MathHelper.sin(par1Entity.rotationYaw * 0.017453292F); 173 float var6 = -var5 * MathHelper.sin(par1Entity.rotationPitch * 0.017453292F); 174 float var7 = var4 * MathHelper.sin(par1Entity.rotationPitch * 0.017453292F); 175 float var8 = MathHelper.cos(par1Entity.rotationPitch * 0.017453292F); 176 byte var9 = 3; 177 178 if (!this.fxLayers[var9].isEmpty()) 179 { 180 Tessellator var10 = Tessellator.instance; 181 182 for (int var11 = 0; var11 < this.fxLayers[var9].size(); ++var11) 183 { 184 EntityFX var12 = (EntityFX)this.fxLayers[var9].get(var11); 185 if (var12 == null) continue; 186 var10.setBrightness(var12.getBrightnessForRender(par2)); 187 var12.renderParticle(var10, par2, var4, var8, var5, var6, var7); 188 } 189 } 190 } 191 192 public void clearEffects(World par1World) 193 { 194 this.worldObj = par1World; 195 196 for (int var2 = 0; var2 < 4; ++var2) 197 { 198 this.fxLayers[var2].clear(); 199 } 200 201 effectList.clear(); 202 } 203 204 public void addBlockDestroyEffects(int par1, int par2, int par3, int par4, int par5) 205 { 206 Block var6 = Block.blocksList[par4]; 207 if (var6 != null && !var6.addBlockDestroyEffects(worldObj, par1, par2, par3, par5, this)) 208 { 209 byte var7 = 4; 210 211 for (int var8 = 0; var8 < var7; ++var8) 212 { 213 for (int var9 = 0; var9 < var7; ++var9) 214 { 215 for (int var10 = 0; var10 < var7; ++var10) 216 { 217 double var11 = (double)par1 + ((double)var8 + 0.5D) / (double)var7; 218 double var13 = (double)par2 + ((double)var9 + 0.5D) / (double)var7; 219 double var15 = (double)par3 + ((double)var10 + 0.5D) / (double)var7; 220 int var17 = this.rand.nextInt(6); 221 this.addEffect((new EntityDiggingFX(this.worldObj, var11, var13, var15, var11 - (double)par1 - 0.5D, var13 - (double)par2 - 0.5D, var15 - (double)par3 - 0.5D, var6, var17, par5)).func_70596_a(par1, par2, par3), var6); 222 } 223 } 224 } 225 } 226 } 227 228 /** 229 * Adds block hit particles for the specified block. Args: x, y, z, sideHit 230 */ 231 public void addBlockHitEffects(int par1, int par2, int par3, int par4) 232 { 233 int var5 = this.worldObj.getBlockId(par1, par2, par3); 234 235 if (var5 != 0) 236 { 237 Block var6 = Block.blocksList[var5]; 238 float var7 = 0.1F; 239 double var8 = (double)par1 + this.rand.nextDouble() * (var6.getBlockBoundsMaxX() - var6.getBlockBoundsMinX() - (double)(var7 * 2.0F)) + (double)var7 + var6.getBlockBoundsMinX(); 240 double var10 = (double)par2 + this.rand.nextDouble() * (var6.getBlockBoundsMaxY() - var6.getBlockBoundsMinY() - (double)(var7 * 2.0F)) + (double)var7 + var6.getBlockBoundsMinY(); 241 double var12 = (double)par3 + this.rand.nextDouble() * (var6.getBlockBoundsMaxZ() - var6.getBlockBoundsMinZ() - (double)(var7 * 2.0F)) + (double)var7 + var6.getBlockBoundsMinZ(); 242 243 if (par4 == 0) 244 { 245 var10 = (double)par2 + var6.getBlockBoundsMinY() - (double)var7; 246 } 247 248 if (par4 == 1) 249 { 250 var10 = (double)par2 + var6.getBlockBoundsMaxY() + (double)var7; 251 } 252 253 if (par4 == 2) 254 { 255 var12 = (double)par3 + var6.getBlockBoundsMinZ() - (double)var7; 256 } 257 258 if (par4 == 3) 259 { 260 var12 = (double)par3 + var6.getBlockBoundsMaxZ() + (double)var7; 261 } 262 263 if (par4 == 4) 264 { 265 var8 = (double)par1 + var6.getBlockBoundsMinX() - (double)var7; 266 } 267 268 if (par4 == 5) 269 { 270 var8 = (double)par1 + var6.getBlockBoundsMaxX() + (double)var7; 271 } 272 273 this.addEffect((new EntityDiggingFX(this.worldObj, var8, var10, var12, 0.0D, 0.0D, 0.0D, var6, par4, this.worldObj.getBlockMetadata(par1, par2, par3))).func_70596_a(par1, par2, par3).multiplyVelocity(0.2F).multipleParticleScaleBy(0.6F), var6); 274 } 275 } 276 277 public String getStatistics() 278 { 279 int size = 0; 280 for (List x : fxLayers) 281 { 282 size += x.size(); 283 } 284 size += effectList.size(); 285 return Integer.toString(size); 286 } 287 288 public void addEffect(EntityFX effect, Object obj) 289 { 290 if (obj == null || !(obj instanceof Block || obj instanceof Item)) 291 { 292 addEffect(effect); 293 return; 294 } 295 296 if (obj instanceof Item && ((Item)obj).isDefaultTexture) 297 { 298 addEffect(effect); 299 return; 300 } 301 302 if (obj instanceof Block && ((Block)obj).isDefaultTexture) 303 { 304 addEffect(effect); 305 return; 306 } 307 308 String texture = "/terrain.png"; 309 if (effect.getFXLayer() == 0) 310 { 311 texture = "/particles.png"; 312 } 313 else if (effect.getFXLayer() == 2) 314 { 315 texture = "/gui/items.png"; 316 } 317 texture = ForgeHooks.getTexture(texture, obj); 318 effectList.put(texture, effect); 319 } 320 321 public void addBlockHitEffects(int x, int y, int z, MovingObjectPosition target) 322 { 323 Block block = Block.blocksList[worldObj.getBlockId(x, y, z)]; 324 if (block != null && !block.addBlockHitEffects(worldObj, target, this)) 325 { 326 addBlockHitEffects(x, y, z, target.sideHit); 327 } 328 } 329 }