    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    }