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                    var3.onUpdate();
068    
069                    if (var3.isDead)
070                    {
071                        this.fxLayers[var1].remove(var2--);
072                    }
073                }
074            }
075    
076            Iterator<Entry<String, EntityFX>> itr = effectList.entries().iterator();
077            while (itr.hasNext())
078            {
079                EntityFX fx = itr.next().getValue();
080                fx.onUpdate();
081                if (fx.isDead)
082                {
083                    itr.remove();
084                }
085            }
086        }
087    
088        /**
089         * Renders all current particles. Args player, partialTickTime
090         */
091        public void renderParticles(Entity par1Entity, float par2)
092        {
093            float var3 = ActiveRenderInfo.rotationX;
094            float var4 = ActiveRenderInfo.rotationZ;
095            float var5 = ActiveRenderInfo.rotationYZ;
096            float var6 = ActiveRenderInfo.rotationXY;
097            float var7 = ActiveRenderInfo.rotationXZ;
098            EntityFX.interpPosX = par1Entity.lastTickPosX + (par1Entity.posX - par1Entity.lastTickPosX) * (double)par2;
099            EntityFX.interpPosY = par1Entity.lastTickPosY + (par1Entity.posY - par1Entity.lastTickPosY) * (double)par2;
100            EntityFX.interpPosZ = par1Entity.lastTickPosZ + (par1Entity.posZ - par1Entity.lastTickPosZ) * (double)par2;
101    
102            for (int var8 = 0; var8 < 3; ++var8)
103            {
104                if (!this.fxLayers[var8].isEmpty())
105                {
106                    int var9 = 0;
107    
108                    if (var8 == 0)
109                    {
110                        var9 = this.renderer.getTexture("/particles.png");
111                    }
112    
113                    if (var8 == 1)
114                    {
115                        var9 = this.renderer.getTexture("/terrain.png");
116                    }
117    
118                    if (var8 == 2)
119                    {
120                        var9 = this.renderer.getTexture("/gui/items.png");
121                    }
122    
123                    GL11.glBindTexture(GL11.GL_TEXTURE_2D, var9);
124                    Tessellator var10 = Tessellator.instance;
125                    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
126                    var10.startDrawingQuads();
127    
128                    for (int var11 = 0; var11 < this.fxLayers[var8].size(); ++var11)
129                    {
130                        EntityFX var12 = (EntityFX)this.fxLayers[var8].get(var11);
131                        var10.setBrightness(var12.getBrightnessForRender(par2));
132                        var12.renderParticle(var10, par2, var3, var7, var4, var5, var6);
133                    }
134    
135                    var10.draw();
136                }
137            }
138    
139            for (String key : effectList.keySet())
140            {
141                ForgeHooksClient.bindTexture(key, 0);
142                for (EntityFX entry : effectList.get(key))
143                {                
144                    Tessellator tessallator = Tessellator.instance;
145                    //GL11.glBindTexture(GL11.GL_TEXTURE_2D, renderer.getTexture(key));
146                    tessallator.startDrawingQuads();
147        
148                    if (entry.getFXLayer() != 3)
149                    {
150                        tessallator.setBrightness(entry.getBrightnessForRender(par2));
151                        entry.renderParticle(tessallator, par2, var3, var7, var4, var5, var6);
152                    }
153        
154                    tessallator.draw();
155                }
156                ForgeHooksClient.unbindTexture();
157            }
158        }
159    
160        public void renderLitParticles(Entity par1Entity, float par2)
161        {
162            float var4 = MathHelper.cos(par1Entity.rotationYaw * 0.017453292F);
163            float var5 = MathHelper.sin(par1Entity.rotationYaw * 0.017453292F);
164            float var6 = -var5 * MathHelper.sin(par1Entity.rotationPitch * 0.017453292F);
165            float var7 = var4 * MathHelper.sin(par1Entity.rotationPitch * 0.017453292F);
166            float var8 = MathHelper.cos(par1Entity.rotationPitch * 0.017453292F);
167            byte var9 = 3;
168    
169            if (!this.fxLayers[var9].isEmpty())
170            {
171                Tessellator var10 = Tessellator.instance;
172    
173                for (int var11 = 0; var11 < this.fxLayers[var9].size(); ++var11)
174                {
175                    EntityFX var12 = (EntityFX)this.fxLayers[var9].get(var11);
176                    var10.setBrightness(var12.getBrightnessForRender(par2));
177                    var12.renderParticle(var10, par2, var4, var8, var5, var6, var7);
178                }
179            }
180        }
181    
182        public void clearEffects(World par1World)
183        {
184            this.worldObj = par1World;
185    
186            for (int var2 = 0; var2 < 4; ++var2)
187            {
188                this.fxLayers[var2].clear();
189            }
190    
191            effectList.clear();
192        }
193    
194        public void addBlockDestroyEffects(int par1, int par2, int par3, int par4, int par5)
195        {
196            if (par4 != 0)
197            {
198                Block var6 = Block.blocksList[par4];
199                byte var7 = 4;
200    
201                for (int var8 = 0; var8 < var7; ++var8)
202                {
203                    for (int var9 = 0; var9 < var7; ++var9)
204                    {
205                        for (int var10 = 0; var10 < var7; ++var10)
206                        {
207                            double var11 = (double)par1 + ((double)var8 + 0.5D) / (double)var7;
208                            double var13 = (double)par2 + ((double)var9 + 0.5D) / (double)var7;
209                            double var15 = (double)par3 + ((double)var10 + 0.5D) / (double)var7;
210                            int var17 = this.rand.nextInt(6);
211                            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);
212                        }
213                    }
214                }
215            }
216        }
217    
218        /**
219         * Adds block hit particles for the specified block. Args: x, y, z, sideHit
220         */
221        public void addBlockHitEffects(int par1, int par2, int par3, int par4)
222        {
223            int var5 = this.worldObj.getBlockId(par1, par2, par3);
224    
225            if (var5 != 0)
226            {
227                Block var6 = Block.blocksList[var5];
228                float var7 = 0.1F;
229                double var8 = (double)par1 + this.rand.nextDouble() * (var6.maxX - var6.minX - (double)(var7 * 2.0F)) + (double)var7 + var6.minX;
230                double var10 = (double)par2 + this.rand.nextDouble() * (var6.maxY - var6.minY - (double)(var7 * 2.0F)) + (double)var7 + var6.minY;
231                double var12 = (double)par3 + this.rand.nextDouble() * (var6.maxZ - var6.minZ - (double)(var7 * 2.0F)) + (double)var7 + var6.minZ;
232    
233                if (par4 == 0)
234                {
235                    var10 = (double)par2 + var6.minY - (double)var7;
236                }
237    
238                if (par4 == 1)
239                {
240                    var10 = (double)par2 + var6.maxY + (double)var7;
241                }
242    
243                if (par4 == 2)
244                {
245                    var12 = (double)par3 + var6.minZ - (double)var7;
246                }
247    
248                if (par4 == 3)
249                {
250                    var12 = (double)par3 + var6.maxZ + (double)var7;
251                }
252    
253                if (par4 == 4)
254                {
255                    var8 = (double)par1 + var6.minX - (double)var7;
256                }
257    
258                if (par4 == 5)
259                {
260                    var8 = (double)par1 + var6.maxX + (double)var7;
261                }
262    
263                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);
264            }
265        }
266    
267        public String getStatistics()
268        {
269            int size = 0;
270            for (List x : fxLayers)
271            {
272                size += x.size();
273            }
274            size += effectList.size();
275            return Integer.toString(size);
276        }
277    
278        public void addEffect(EntityFX effect, Object obj)
279        {
280            if (obj == null || !(obj instanceof Block || obj instanceof Item))
281            {
282                addEffect(effect);
283                return;
284            }
285    
286            if (obj instanceof Item && ((Item)obj).isDefaultTexture)
287            {
288                addEffect(effect);
289                return;
290            }
291    
292            if (obj instanceof Block && ((Block)obj).isDefaultTexture)
293            {
294                addEffect(effect);
295                return;
296            }
297    
298            String texture = "/terrain.png";
299            if (effect.getFXLayer() == 0)
300            {
301                texture = "/particles.png";
302            }
303            else if (effect.getFXLayer() == 2)
304            {
305                texture = "/gui/items.png";
306            }        
307            texture = ForgeHooks.getTexture(texture, obj);
308            effectList.put(texture, effect);
309        }
310    }