001    package net.minecraft.src;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    import java.nio.IntBuffer;
006    import java.util.ArrayList;
007    import java.util.Arrays;
008    import java.util.Collections;
009    import java.util.HashMap;
010    import java.util.Iterator;
011    import java.util.List;
012    import java.util.Map;
013    import java.util.Random;
014    
015    import net.minecraft.client.Minecraft;
016    import net.minecraftforge.client.SkyProvider;
017    
018    import org.lwjgl.opengl.ARBOcclusionQuery;
019    import org.lwjgl.opengl.GL11;
020    
021    @SideOnly(Side.CLIENT)
022    public class RenderGlobal implements IWorldAccess
023    {
024        public List tileEntities = new ArrayList();
025        public WorldClient theWorld;
026    
027        /** The RenderEngine instance used by RenderGlobal */
028        public final RenderEngine renderEngine;
029        private List worldRenderersToUpdate = new ArrayList();
030        private WorldRenderer[] sortedWorldRenderers;
031        private WorldRenderer[] worldRenderers;
032        private int renderChunksWide;
033        private int renderChunksTall;
034        private int renderChunksDeep;
035    
036        /** OpenGL render lists base */
037        private int glRenderListBase;
038    
039        /** A reference to the Minecraft object. */
040        public Minecraft mc;
041    
042        /** Global render blocks */
043        public RenderBlocks globalRenderBlocks;
044    
045        /** OpenGL occlusion query base */
046        private IntBuffer glOcclusionQueryBase;
047    
048        /** Is occlusion testing enabled */
049        private boolean occlusionEnabled = false;
050    
051        /**
052         * counts the cloud render updates. Used with mod to stagger some updates
053         */
054        private int cloudTickCounter = 0;
055    
056        /** The star GL Call list */
057        private int starGLCallList;
058    
059        /** OpenGL sky list */
060        private int glSkyList;
061    
062        /** OpenGL sky list 2 */
063        private int glSkyList2;
064    
065        /** Minimum block X */
066        private int minBlockX;
067    
068        /** Minimum block Y */
069        private int minBlockY;
070    
071        /** Minimum block Z */
072        private int minBlockZ;
073    
074        /** Maximum block X */
075        private int maxBlockX;
076    
077        /** Maximum block Y */
078        private int maxBlockY;
079    
080        /** Maximum block Z */
081        private int maxBlockZ;
082    
083        /**
084         * Stores blocks currently being broken. Key is entity ID of the thing doing the breaking. Value is a
085         * DestroyBlockProgress
086         */
087        public Map damagedBlocks = new HashMap();
088        private int renderDistance = -1;
089    
090        /** Render entities startup counter (init value=2) */
091        private int renderEntitiesStartupCounter = 2;
092    
093        /** Count entities total */
094        private int countEntitiesTotal;
095    
096        /** Count entities rendered */
097        private int countEntitiesRendered;
098    
099        /** Count entities hidden */
100        private int countEntitiesHidden;
101    
102        /** Dummy buffer (50k) not used */
103        int[] dummyBuf50k = new int[50000];
104    
105        /** Occlusion query result */
106        IntBuffer occlusionResult = GLAllocation.createDirectIntBuffer(64);
107    
108        /** How many renderers are loaded this frame that try to be rendered */
109        private int renderersLoaded;
110    
111        /** How many renderers are being clipped by the frustrum this frame */
112        private int renderersBeingClipped;
113    
114        /** How many renderers are being occluded this frame */
115        private int renderersBeingOccluded;
116    
117        /** How many renderers are actually being rendered this frame */
118        private int renderersBeingRendered;
119    
120        /**
121         * How many renderers are skipping rendering due to not having a render pass this frame
122         */
123        private int renderersSkippingRenderPass;
124    
125        /** Dummy render int */
126        private int dummyRenderInt;
127    
128        /** World renderers check index */
129        private int worldRenderersCheckIndex;
130    
131        /** List of OpenGL lists for the current render pass */
132        private List glRenderLists = new ArrayList();
133    
134        /** All render lists (fixed length 4) */
135        private RenderList[] allRenderLists = new RenderList[] {new RenderList(), new RenderList(), new RenderList(), new RenderList()};
136    
137        /**
138         * Previous x position when the renderers were sorted. (Once the distance moves more than 4 units they will be
139         * resorted)
140         */
141        double prevSortX = -9999.0D;
142    
143        /**
144         * Previous y position when the renderers were sorted. (Once the distance moves more than 4 units they will be
145         * resorted)
146         */
147        double prevSortY = -9999.0D;
148    
149        /**
150         * Previous Z position when the renderers were sorted. (Once the distance moves more than 4 units they will be
151         * resorted)
152         */
153        double prevSortZ = -9999.0D;
154    
155        /**
156         * The offset used to determine if a renderer is one of the sixteenth that are being updated this frame
157         */
158        int frustumCheckOffset = 0;
159    
160        public RenderGlobal(Minecraft par1Minecraft, RenderEngine par2RenderEngine)
161        {
162            this.mc = par1Minecraft;
163            this.renderEngine = par2RenderEngine;
164            byte var3 = 34;
165            byte var4 = 32;
166            this.glRenderListBase = GLAllocation.generateDisplayLists(var3 * var3 * var4 * 3);
167            this.occlusionEnabled = OpenGlCapsChecker.checkARBOcclusion();
168    
169            if (this.occlusionEnabled)
170            {
171                this.occlusionResult.clear();
172                this.glOcclusionQueryBase = GLAllocation.createDirectIntBuffer(var3 * var3 * var4);
173                this.glOcclusionQueryBase.clear();
174                this.glOcclusionQueryBase.position(0);
175                this.glOcclusionQueryBase.limit(var3 * var3 * var4);
176                ARBOcclusionQuery.glGenQueriesARB(this.glOcclusionQueryBase);
177            }
178    
179            this.starGLCallList = GLAllocation.generateDisplayLists(3);
180            GL11.glPushMatrix();
181            GL11.glNewList(this.starGLCallList, GL11.GL_COMPILE);
182            this.renderStars();
183            GL11.glEndList();
184            GL11.glPopMatrix();
185            Tessellator var5 = Tessellator.instance;
186            this.glSkyList = this.starGLCallList + 1;
187            GL11.glNewList(this.glSkyList, GL11.GL_COMPILE);
188            byte var7 = 64;
189            int var8 = 256 / var7 + 2;
190            float var6 = 16.0F;
191            int var9;
192            int var10;
193    
194            for (var9 = -var7 * var8; var9 <= var7 * var8; var9 += var7)
195            {
196                for (var10 = -var7 * var8; var10 <= var7 * var8; var10 += var7)
197                {
198                    var5.startDrawingQuads();
199                    var5.addVertex((double)(var9 + 0), (double)var6, (double)(var10 + 0));
200                    var5.addVertex((double)(var9 + var7), (double)var6, (double)(var10 + 0));
201                    var5.addVertex((double)(var9 + var7), (double)var6, (double)(var10 + var7));
202                    var5.addVertex((double)(var9 + 0), (double)var6, (double)(var10 + var7));
203                    var5.draw();
204                }
205            }
206    
207            GL11.glEndList();
208            this.glSkyList2 = this.starGLCallList + 2;
209            GL11.glNewList(this.glSkyList2, GL11.GL_COMPILE);
210            var6 = -16.0F;
211            var5.startDrawingQuads();
212    
213            for (var9 = -var7 * var8; var9 <= var7 * var8; var9 += var7)
214            {
215                for (var10 = -var7 * var8; var10 <= var7 * var8; var10 += var7)
216                {
217                    var5.addVertex((double)(var9 + var7), (double)var6, (double)(var10 + 0));
218                    var5.addVertex((double)(var9 + 0), (double)var6, (double)(var10 + 0));
219                    var5.addVertex((double)(var9 + 0), (double)var6, (double)(var10 + var7));
220                    var5.addVertex((double)(var9 + var7), (double)var6, (double)(var10 + var7));
221                }
222            }
223    
224            var5.draw();
225            GL11.glEndList();
226        }
227    
228        private void renderStars()
229        {
230            Random var1 = new Random(10842L);
231            Tessellator var2 = Tessellator.instance;
232            var2.startDrawingQuads();
233    
234            for (int var3 = 0; var3 < 1500; ++var3)
235            {
236                double var4 = (double)(var1.nextFloat() * 2.0F - 1.0F);
237                double var6 = (double)(var1.nextFloat() * 2.0F - 1.0F);
238                double var8 = (double)(var1.nextFloat() * 2.0F - 1.0F);
239                double var10 = (double)(0.15F + var1.nextFloat() * 0.1F);
240                double var12 = var4 * var4 + var6 * var6 + var8 * var8;
241    
242                if (var12 < 1.0D && var12 > 0.01D)
243                {
244                    var12 = 1.0D / Math.sqrt(var12);
245                    var4 *= var12;
246                    var6 *= var12;
247                    var8 *= var12;
248                    double var14 = var4 * 100.0D;
249                    double var16 = var6 * 100.0D;
250                    double var18 = var8 * 100.0D;
251                    double var20 = Math.atan2(var4, var8);
252                    double var22 = Math.sin(var20);
253                    double var24 = Math.cos(var20);
254                    double var26 = Math.atan2(Math.sqrt(var4 * var4 + var8 * var8), var6);
255                    double var28 = Math.sin(var26);
256                    double var30 = Math.cos(var26);
257                    double var32 = var1.nextDouble() * Math.PI * 2.0D;
258                    double var34 = Math.sin(var32);
259                    double var36 = Math.cos(var32);
260    
261                    for (int var38 = 0; var38 < 4; ++var38)
262                    {
263                        double var39 = 0.0D;
264                        double var41 = (double)((var38 & 2) - 1) * var10;
265                        double var43 = (double)((var38 + 1 & 2) - 1) * var10;
266                        double var47 = var41 * var36 - var43 * var34;
267                        double var49 = var43 * var36 + var41 * var34;
268                        double var53 = var47 * var28 + var39 * var30;
269                        double var55 = var39 * var28 - var47 * var30;
270                        double var57 = var55 * var22 - var49 * var24;
271                        double var61 = var49 * var22 + var55 * var24;
272                        var2.addVertex(var14 + var57, var16 + var53, var18 + var61);
273                    }
274                }
275            }
276    
277            var2.draw();
278        }
279    
280        /**
281         * set null to clear
282         */
283        public void setWorldAndLoadRenderers(WorldClient par1WorldClient)
284        {
285            if (this.theWorld != null)
286            {
287                this.theWorld.removeWorldAccess(this);
288            }
289    
290            this.prevSortX = -9999.0D;
291            this.prevSortY = -9999.0D;
292            this.prevSortZ = -9999.0D;
293            RenderManager.instance.set(par1WorldClient);
294            this.theWorld = par1WorldClient;
295            this.globalRenderBlocks = new RenderBlocks(par1WorldClient);
296    
297            if (par1WorldClient != null)
298            {
299                par1WorldClient.addWorldAccess(this);
300                this.loadRenderers();
301            }
302        }
303    
304        /**
305         * Loads all the renderers and sets up the basic settings usage
306         */
307        public void loadRenderers()
308        {
309            if (this.theWorld != null)
310            {
311                Block.leaves.setGraphicsLevel(this.mc.gameSettings.fancyGraphics);
312                this.renderDistance = this.mc.gameSettings.renderDistance;
313                int var1;
314    
315                if (this.worldRenderers != null)
316                {
317                    for (var1 = 0; var1 < this.worldRenderers.length; ++var1)
318                    {
319                        this.worldRenderers[var1].stopRendering();
320                    }
321                }
322    
323                var1 = 64 << 3 - this.renderDistance;
324    
325                if (var1 > 400)
326                {
327                    var1 = 400;
328                }
329    
330                this.renderChunksWide = var1 / 16 + 1;
331                this.renderChunksTall = 16;
332                this.renderChunksDeep = var1 / 16 + 1;
333                this.worldRenderers = new WorldRenderer[this.renderChunksWide * this.renderChunksTall * this.renderChunksDeep];
334                this.sortedWorldRenderers = new WorldRenderer[this.renderChunksWide * this.renderChunksTall * this.renderChunksDeep];
335                int var2 = 0;
336                int var3 = 0;
337                this.minBlockX = 0;
338                this.minBlockY = 0;
339                this.minBlockZ = 0;
340                this.maxBlockX = this.renderChunksWide;
341                this.maxBlockY = this.renderChunksTall;
342                this.maxBlockZ = this.renderChunksDeep;
343                int var4;
344    
345                for (var4 = 0; var4 < this.worldRenderersToUpdate.size(); ++var4)
346                {
347                    ((WorldRenderer)this.worldRenderersToUpdate.get(var4)).needsUpdate = false;
348                }
349    
350                this.worldRenderersToUpdate.clear();
351                this.tileEntities.clear();
352    
353                for (var4 = 0; var4 < this.renderChunksWide; ++var4)
354                {
355                    for (int var5 = 0; var5 < this.renderChunksTall; ++var5)
356                    {
357                        for (int var6 = 0; var6 < this.renderChunksDeep; ++var6)
358                        {
359                            this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4] = new WorldRenderer(this.theWorld, this.tileEntities, var4 * 16, var5 * 16, var6 * 16, this.glRenderListBase + var2);
360    
361                            if (this.occlusionEnabled)
362                            {
363                                this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4].glOcclusionQuery = this.glOcclusionQueryBase.get(var3);
364                            }
365    
366                            this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4].isWaitingOnOcclusionQuery = false;
367                            this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4].isVisible = true;
368                            this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4].isInFrustum = true;
369                            this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4].chunkIndex = var3++;
370                            this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4].markDirty();
371                            this.sortedWorldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4] = this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4];
372                            this.worldRenderersToUpdate.add(this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4]);
373                            var2 += 3;
374                        }
375                    }
376                }
377    
378                if (this.theWorld != null)
379                {
380                    EntityLiving var7 = this.mc.renderViewEntity;
381    
382                    if (var7 != null)
383                    {
384                        this.markRenderersForNewPosition(MathHelper.floor_double(var7.posX), MathHelper.floor_double(var7.posY), MathHelper.floor_double(var7.posZ));
385                        Arrays.sort(this.sortedWorldRenderers, new EntitySorter(var7));
386                    }
387                }
388    
389                this.renderEntitiesStartupCounter = 2;
390            }
391        }
392    
393        /**
394         * Renders all entities within range and within the frustrum. Args: pos, frustrum, partialTickTime
395         */
396        public void renderEntities(Vec3 par1Vec3, ICamera par2ICamera, float par3)
397        {
398            if (this.renderEntitiesStartupCounter > 0)
399            {
400                --this.renderEntitiesStartupCounter;
401            }
402            else
403            {
404                this.theWorld.theProfiler.startSection("prepare");
405                TileEntityRenderer.instance.cacheActiveRenderInfo(this.theWorld, this.renderEngine, this.mc.fontRenderer, this.mc.renderViewEntity, par3);
406                RenderManager.instance.cacheActiveRenderInfo(this.theWorld, this.renderEngine, this.mc.fontRenderer, this.mc.renderViewEntity, this.mc.gameSettings, par3);
407                this.countEntitiesTotal = 0;
408                this.countEntitiesRendered = 0;
409                this.countEntitiesHidden = 0;
410                EntityLiving var4 = this.mc.renderViewEntity;
411                RenderManager.renderPosX = var4.lastTickPosX + (var4.posX - var4.lastTickPosX) * (double)par3;
412                RenderManager.renderPosY = var4.lastTickPosY + (var4.posY - var4.lastTickPosY) * (double)par3;
413                RenderManager.renderPosZ = var4.lastTickPosZ + (var4.posZ - var4.lastTickPosZ) * (double)par3;
414                TileEntityRenderer.staticPlayerX = var4.lastTickPosX + (var4.posX - var4.lastTickPosX) * (double)par3;
415                TileEntityRenderer.staticPlayerY = var4.lastTickPosY + (var4.posY - var4.lastTickPosY) * (double)par3;
416                TileEntityRenderer.staticPlayerZ = var4.lastTickPosZ + (var4.posZ - var4.lastTickPosZ) * (double)par3;
417                this.mc.entityRenderer.enableLightmap((double)par3);
418                this.theWorld.theProfiler.endStartSection("global");
419                List var5 = this.theWorld.getLoadedEntityList();
420                this.countEntitiesTotal = var5.size();
421                int var6;
422                Entity var7;
423    
424                for (var6 = 0; var6 < this.theWorld.weatherEffects.size(); ++var6)
425                {
426                    var7 = (Entity)this.theWorld.weatherEffects.get(var6);
427                    ++this.countEntitiesRendered;
428    
429                    if (var7.isInRangeToRenderVec3D(par1Vec3))
430                    {
431                        RenderManager.instance.renderEntity(var7, par3);
432                    }
433                }
434    
435                this.theWorld.theProfiler.endStartSection("entities");
436    
437                for (var6 = 0; var6 < var5.size(); ++var6)
438                {
439                    var7 = (Entity)var5.get(var6);
440    
441                    if (var7.isInRangeToRenderVec3D(par1Vec3) && (var7.ignoreFrustumCheck || par2ICamera.isBoundingBoxInFrustum(var7.boundingBox) || var7.riddenByEntity == this.mc.thePlayer) && (var7 != this.mc.renderViewEntity || this.mc.gameSettings.thirdPersonView != 0 || this.mc.renderViewEntity.isPlayerSleeping()) && this.theWorld.blockExists(MathHelper.floor_double(var7.posX), 0, MathHelper.floor_double(var7.posZ)))
442                    {
443                        ++this.countEntitiesRendered;
444                        RenderManager.instance.renderEntity(var7, par3);
445                    }
446                }
447    
448                this.theWorld.theProfiler.endStartSection("tileentities");
449                RenderHelper.enableStandardItemLighting();
450    
451                for (var6 = 0; var6 < this.tileEntities.size(); ++var6)
452                {
453                    TileEntityRenderer.instance.renderTileEntity((TileEntity)this.tileEntities.get(var6), par3);
454                }
455    
456                this.mc.entityRenderer.disableLightmap((double)par3);
457                this.theWorld.theProfiler.endSection();
458            }
459        }
460    
461        /**
462         * Gets the render info for use on the Debug screen
463         */
464        public String getDebugInfoRenders()
465        {
466            return "C: " + this.renderersBeingRendered + "/" + this.renderersLoaded + ". F: " + this.renderersBeingClipped + ", O: " + this.renderersBeingOccluded + ", E: " + this.renderersSkippingRenderPass;
467        }
468    
469        /**
470         * Gets the entities info for use on the Debug screen
471         */
472        public String getDebugInfoEntities()
473        {
474            return "E: " + this.countEntitiesRendered + "/" + this.countEntitiesTotal + ". B: " + this.countEntitiesHidden + ", I: " + (this.countEntitiesTotal - this.countEntitiesHidden - this.countEntitiesRendered);
475        }
476    
477        /**
478         * Goes through all the renderers setting new positions on them and those that have their position changed are
479         * adding to be updated
480         */
481        private void markRenderersForNewPosition(int par1, int par2, int par3)
482        {
483            par1 -= 8;
484            par2 -= 8;
485            par3 -= 8;
486            this.minBlockX = Integer.MAX_VALUE;
487            this.minBlockY = Integer.MAX_VALUE;
488            this.minBlockZ = Integer.MAX_VALUE;
489            this.maxBlockX = Integer.MIN_VALUE;
490            this.maxBlockY = Integer.MIN_VALUE;
491            this.maxBlockZ = Integer.MIN_VALUE;
492            int var4 = this.renderChunksWide * 16;
493            int var5 = var4 / 2;
494    
495            for (int var6 = 0; var6 < this.renderChunksWide; ++var6)
496            {
497                int var7 = var6 * 16;
498                int var8 = var7 + var5 - par1;
499    
500                if (var8 < 0)
501                {
502                    var8 -= var4 - 1;
503                }
504    
505                var8 /= var4;
506                var7 -= var8 * var4;
507    
508                if (var7 < this.minBlockX)
509                {
510                    this.minBlockX = var7;
511                }
512    
513                if (var7 > this.maxBlockX)
514                {
515                    this.maxBlockX = var7;
516                }
517    
518                for (int var9 = 0; var9 < this.renderChunksDeep; ++var9)
519                {
520                    int var10 = var9 * 16;
521                    int var11 = var10 + var5 - par3;
522    
523                    if (var11 < 0)
524                    {
525                        var11 -= var4 - 1;
526                    }
527    
528                    var11 /= var4;
529                    var10 -= var11 * var4;
530    
531                    if (var10 < this.minBlockZ)
532                    {
533                        this.minBlockZ = var10;
534                    }
535    
536                    if (var10 > this.maxBlockZ)
537                    {
538                        this.maxBlockZ = var10;
539                    }
540    
541                    for (int var12 = 0; var12 < this.renderChunksTall; ++var12)
542                    {
543                        int var13 = var12 * 16;
544    
545                        if (var13 < this.minBlockY)
546                        {
547                            this.minBlockY = var13;
548                        }
549    
550                        if (var13 > this.maxBlockY)
551                        {
552                            this.maxBlockY = var13;
553                        }
554    
555                        WorldRenderer var14 = this.worldRenderers[(var9 * this.renderChunksTall + var12) * this.renderChunksWide + var6];
556                        boolean var15 = var14.needsUpdate;
557                        var14.setPosition(var7, var13, var10);
558    
559                        if (!var15 && var14.needsUpdate)
560                        {
561                            this.worldRenderersToUpdate.add(var14);
562                        }
563                    }
564                }
565            }
566        }
567    
568        /**
569         * Sorts all renderers based on the passed in entity. Args: entityLiving, renderPass, partialTickTime
570         */
571        public int sortAndRender(EntityLiving par1EntityLiving, int par2, double par3)
572        {
573            this.theWorld.theProfiler.startSection("sortchunks");
574    
575            for (int var5 = 0; var5 < 10; ++var5)
576            {
577                this.worldRenderersCheckIndex = (this.worldRenderersCheckIndex + 1) % this.worldRenderers.length;
578                WorldRenderer var6 = this.worldRenderers[this.worldRenderersCheckIndex];
579    
580                if (var6.needsUpdate && !this.worldRenderersToUpdate.contains(var6))
581                {
582                    this.worldRenderersToUpdate.add(var6);
583                }
584            }
585    
586            if (this.mc.gameSettings.renderDistance != this.renderDistance)
587            {
588                this.loadRenderers();
589            }
590    
591            if (par2 == 0)
592            {
593                this.renderersLoaded = 0;
594                this.dummyRenderInt = 0;
595                this.renderersBeingClipped = 0;
596                this.renderersBeingOccluded = 0;
597                this.renderersBeingRendered = 0;
598                this.renderersSkippingRenderPass = 0;
599            }
600    
601            double var33 = par1EntityLiving.lastTickPosX + (par1EntityLiving.posX - par1EntityLiving.lastTickPosX) * par3;
602            double var7 = par1EntityLiving.lastTickPosY + (par1EntityLiving.posY - par1EntityLiving.lastTickPosY) * par3;
603            double var9 = par1EntityLiving.lastTickPosZ + (par1EntityLiving.posZ - par1EntityLiving.lastTickPosZ) * par3;
604            double var11 = par1EntityLiving.posX - this.prevSortX;
605            double var13 = par1EntityLiving.posY - this.prevSortY;
606            double var15 = par1EntityLiving.posZ - this.prevSortZ;
607    
608            if (var11 * var11 + var13 * var13 + var15 * var15 > 16.0D)
609            {
610                this.prevSortX = par1EntityLiving.posX;
611                this.prevSortY = par1EntityLiving.posY;
612                this.prevSortZ = par1EntityLiving.posZ;
613                this.markRenderersForNewPosition(MathHelper.floor_double(par1EntityLiving.posX), MathHelper.floor_double(par1EntityLiving.posY), MathHelper.floor_double(par1EntityLiving.posZ));
614                Arrays.sort(this.sortedWorldRenderers, new EntitySorter(par1EntityLiving));
615            }
616    
617            RenderHelper.disableStandardItemLighting();
618            byte var17 = 0;
619            int var34;
620    
621            if (this.occlusionEnabled && this.mc.gameSettings.advancedOpengl && !this.mc.gameSettings.anaglyph && par2 == 0)
622            {
623                byte var18 = 0;
624                int var19 = 16;
625                this.checkOcclusionQueryResult(var18, var19);
626    
627                for (int var20 = var18; var20 < var19; ++var20)
628                {
629                    this.sortedWorldRenderers[var20].isVisible = true;
630                }
631    
632                this.theWorld.theProfiler.endStartSection("render");
633                var34 = var17 + this.renderSortedRenderers(var18, var19, par2, par3);
634    
635                do
636                {
637                    this.theWorld.theProfiler.endStartSection("occ");
638                    int var35 = var19;
639                    var19 *= 2;
640    
641                    if (var19 > this.sortedWorldRenderers.length)
642                    {
643                        var19 = this.sortedWorldRenderers.length;
644                    }
645    
646                    GL11.glDisable(GL11.GL_TEXTURE_2D);
647                    GL11.glDisable(GL11.GL_LIGHTING);
648                    GL11.glDisable(GL11.GL_ALPHA_TEST);
649                    GL11.glDisable(GL11.GL_FOG);
650                    GL11.glColorMask(false, false, false, false);
651                    GL11.glDepthMask(false);
652                    this.theWorld.theProfiler.startSection("check");
653                    this.checkOcclusionQueryResult(var35, var19);
654                    this.theWorld.theProfiler.endSection();
655                    GL11.glPushMatrix();
656                    float var36 = 0.0F;
657                    float var21 = 0.0F;
658                    float var22 = 0.0F;
659    
660                    for (int var23 = var35; var23 < var19; ++var23)
661                    {
662                        if (this.sortedWorldRenderers[var23].skipAllRenderPasses())
663                        {
664                            this.sortedWorldRenderers[var23].isInFrustum = false;
665                        }
666                        else
667                        {
668                            if (!this.sortedWorldRenderers[var23].isInFrustum)
669                            {
670                                this.sortedWorldRenderers[var23].isVisible = true;
671                            }
672    
673                            if (this.sortedWorldRenderers[var23].isInFrustum && !this.sortedWorldRenderers[var23].isWaitingOnOcclusionQuery)
674                            {
675                                float var24 = MathHelper.sqrt_float(this.sortedWorldRenderers[var23].distanceToEntitySquared(par1EntityLiving));
676                                int var25 = (int)(1.0F + var24 / 128.0F);
677    
678                                if (this.cloudTickCounter % var25 == var23 % var25)
679                                {
680                                    WorldRenderer var26 = this.sortedWorldRenderers[var23];
681                                    float var27 = (float)((double)var26.posXMinus - var33);
682                                    float var28 = (float)((double)var26.posYMinus - var7);
683                                    float var29 = (float)((double)var26.posZMinus - var9);
684                                    float var30 = var27 - var36;
685                                    float var31 = var28 - var21;
686                                    float var32 = var29 - var22;
687    
688                                    if (var30 != 0.0F || var31 != 0.0F || var32 != 0.0F)
689                                    {
690                                        GL11.glTranslatef(var30, var31, var32);
691                                        var36 += var30;
692                                        var21 += var31;
693                                        var22 += var32;
694                                    }
695    
696                                    this.theWorld.theProfiler.startSection("bb");
697                                    ARBOcclusionQuery.glBeginQueryARB(ARBOcclusionQuery.GL_SAMPLES_PASSED_ARB, this.sortedWorldRenderers[var23].glOcclusionQuery);
698                                    this.sortedWorldRenderers[var23].callOcclusionQueryList();
699                                    ARBOcclusionQuery.glEndQueryARB(ARBOcclusionQuery.GL_SAMPLES_PASSED_ARB);
700                                    this.theWorld.theProfiler.endSection();
701                                    this.sortedWorldRenderers[var23].isWaitingOnOcclusionQuery = true;
702                                }
703                            }
704                        }
705                    }
706    
707                    GL11.glPopMatrix();
708    
709                    if (this.mc.gameSettings.anaglyph)
710                    {
711                        if (EntityRenderer.anaglyphField == 0)
712                        {
713                            GL11.glColorMask(false, true, true, true);
714                        }
715                        else
716                        {
717                            GL11.glColorMask(true, false, false, true);
718                        }
719                    }
720                    else
721                    {
722                        GL11.glColorMask(true, true, true, true);
723                    }
724    
725                    GL11.glDepthMask(true);
726                    GL11.glEnable(GL11.GL_TEXTURE_2D);
727                    GL11.glEnable(GL11.GL_ALPHA_TEST);
728                    GL11.glEnable(GL11.GL_FOG);
729                    this.theWorld.theProfiler.endStartSection("render");
730                    var34 += this.renderSortedRenderers(var35, var19, par2, par3);
731                }
732                while (var19 < this.sortedWorldRenderers.length);
733            }
734            else
735            {
736                this.theWorld.theProfiler.endStartSection("render");
737                var34 = var17 + this.renderSortedRenderers(0, this.sortedWorldRenderers.length, par2, par3);
738            }
739    
740            this.theWorld.theProfiler.endSection();
741            return var34;
742        }
743    
744        private void checkOcclusionQueryResult(int par1, int par2)
745        {
746            for (int var3 = par1; var3 < par2; ++var3)
747            {
748                if (this.sortedWorldRenderers[var3].isWaitingOnOcclusionQuery)
749                {
750                    this.occlusionResult.clear();
751                    ARBOcclusionQuery.glGetQueryObjectuARB(this.sortedWorldRenderers[var3].glOcclusionQuery, ARBOcclusionQuery.GL_QUERY_RESULT_AVAILABLE_ARB, this.occlusionResult);
752    
753                    if (this.occlusionResult.get(0) != 0)
754                    {
755                        this.sortedWorldRenderers[var3].isWaitingOnOcclusionQuery = false;
756                        this.occlusionResult.clear();
757                        ARBOcclusionQuery.glGetQueryObjectuARB(this.sortedWorldRenderers[var3].glOcclusionQuery, ARBOcclusionQuery.GL_QUERY_RESULT_ARB, this.occlusionResult);
758                        this.sortedWorldRenderers[var3].isVisible = this.occlusionResult.get(0) != 0;
759                    }
760                }
761            }
762        }
763    
764        /**
765         * Renders the sorted renders for the specified render pass. Args: startRenderer, numRenderers, renderPass,
766         * partialTickTime
767         */
768        private int renderSortedRenderers(int par1, int par2, int par3, double par4)
769        {
770            this.glRenderLists.clear();
771            int var6 = 0;
772    
773            for (int var7 = par1; var7 < par2; ++var7)
774            {
775                if (par3 == 0)
776                {
777                    ++this.renderersLoaded;
778    
779                    if (this.sortedWorldRenderers[var7].skipRenderPass[par3])
780                    {
781                        ++this.renderersSkippingRenderPass;
782                    }
783                    else if (!this.sortedWorldRenderers[var7].isInFrustum)
784                    {
785                        ++this.renderersBeingClipped;
786                    }
787                    else if (this.occlusionEnabled && !this.sortedWorldRenderers[var7].isVisible)
788                    {
789                        ++this.renderersBeingOccluded;
790                    }
791                    else
792                    {
793                        ++this.renderersBeingRendered;
794                    }
795                }
796    
797                if (!this.sortedWorldRenderers[var7].skipRenderPass[par3] && this.sortedWorldRenderers[var7].isInFrustum && (!this.occlusionEnabled || this.sortedWorldRenderers[var7].isVisible))
798                {
799                    int var8 = this.sortedWorldRenderers[var7].getGLCallListForPass(par3);
800    
801                    if (var8 >= 0)
802                    {
803                        this.glRenderLists.add(this.sortedWorldRenderers[var7]);
804                        ++var6;
805                    }
806                }
807            }
808    
809            EntityLiving var19 = this.mc.renderViewEntity;
810            double var20 = var19.lastTickPosX + (var19.posX - var19.lastTickPosX) * par4;
811            double var10 = var19.lastTickPosY + (var19.posY - var19.lastTickPosY) * par4;
812            double var12 = var19.lastTickPosZ + (var19.posZ - var19.lastTickPosZ) * par4;
813            int var14 = 0;
814            int var15;
815    
816            for (var15 = 0; var15 < this.allRenderLists.length; ++var15)
817            {
818                this.allRenderLists[var15].func_78421_b();
819            }
820    
821            for (var15 = 0; var15 < this.glRenderLists.size(); ++var15)
822            {
823                WorldRenderer var16 = (WorldRenderer)this.glRenderLists.get(var15);
824                int var17 = -1;
825    
826                for (int var18 = 0; var18 < var14; ++var18)
827                {
828                    if (this.allRenderLists[var18].func_78418_a(var16.posXMinus, var16.posYMinus, var16.posZMinus))
829                    {
830                        var17 = var18;
831                    }
832                }
833    
834                if (var17 < 0)
835                {
836                    var17 = var14++;
837                    this.allRenderLists[var17].func_78422_a(var16.posXMinus, var16.posYMinus, var16.posZMinus, var20, var10, var12);
838                }
839    
840                this.allRenderLists[var17].func_78420_a(var16.getGLCallListForPass(par3));
841            }
842    
843            this.renderAllRenderLists(par3, par4);
844            return var6;
845        }
846    
847        /**
848         * Render all render lists
849         */
850        public void renderAllRenderLists(int par1, double par2)
851        {
852            this.mc.entityRenderer.enableLightmap(par2);
853    
854            for (int var4 = 0; var4 < this.allRenderLists.length; ++var4)
855            {
856                this.allRenderLists[var4].func_78419_a();
857            }
858    
859            this.mc.entityRenderer.disableLightmap(par2);
860        }
861    
862        public void updateClouds()
863        {
864            ++this.cloudTickCounter;
865    
866            if (this.cloudTickCounter % 20 == 0)
867            {
868                Iterator var1 = this.damagedBlocks.values().iterator();
869    
870                while (var1.hasNext())
871                {
872                    DestroyBlockProgress var2 = (DestroyBlockProgress)var1.next();
873                    int var3 = var2.getCreationCloudUpdateTick();
874    
875                    if (this.cloudTickCounter - var3 > 400)
876                    {
877                        var1.remove();
878                    }
879                }
880            }
881        }
882    
883        /**
884         * Renders the sky with the partial tick time. Args: partialTickTime
885         */
886        public void renderSky(float par1)
887        {
888            SkyProvider skyProvider = null;
889            if ((skyProvider = this.mc.theWorld.provider.getSkyProvider()) != null)
890            {
891                skyProvider.render(par1, this.theWorld, mc);
892                return;
893            }
894            if (this.mc.theWorld.provider.dimensionId == 1)
895            {
896                GL11.glDisable(GL11.GL_FOG);
897                GL11.glDisable(GL11.GL_ALPHA_TEST);
898                GL11.glEnable(GL11.GL_BLEND);
899                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
900                RenderHelper.disableStandardItemLighting();
901                GL11.glDepthMask(false);
902                this.renderEngine.bindTexture(this.renderEngine.getTexture("/misc/tunnel.png"));
903                Tessellator var21 = Tessellator.instance;
904    
905                for (int var22 = 0; var22 < 6; ++var22)
906                {
907                    GL11.glPushMatrix();
908    
909                    if (var22 == 1)
910                    {
911                        GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F);
912                    }
913    
914                    if (var22 == 2)
915                    {
916                        GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F);
917                    }
918    
919                    if (var22 == 3)
920                    {
921                        GL11.glRotatef(180.0F, 1.0F, 0.0F, 0.0F);
922                    }
923    
924                    if (var22 == 4)
925                    {
926                        GL11.glRotatef(90.0F, 0.0F, 0.0F, 1.0F);
927                    }
928    
929                    if (var22 == 5)
930                    {
931                        GL11.glRotatef(-90.0F, 0.0F, 0.0F, 1.0F);
932                    }
933    
934                    var21.startDrawingQuads();
935                    var21.setColorOpaque_I(2631720);
936                    var21.addVertexWithUV(-100.0D, -100.0D, -100.0D, 0.0D, 0.0D);
937                    var21.addVertexWithUV(-100.0D, -100.0D, 100.0D, 0.0D, 16.0D);
938                    var21.addVertexWithUV(100.0D, -100.0D, 100.0D, 16.0D, 16.0D);
939                    var21.addVertexWithUV(100.0D, -100.0D, -100.0D, 16.0D, 0.0D);
940                    var21.draw();
941                    GL11.glPopMatrix();
942                }
943    
944                GL11.glDepthMask(true);
945                GL11.glEnable(GL11.GL_TEXTURE_2D);
946                GL11.glEnable(GL11.GL_ALPHA_TEST);
947            }
948            else if (this.mc.theWorld.provider.isSurfaceWorld())
949            {
950                GL11.glDisable(GL11.GL_TEXTURE_2D);
951                Vec3 var2 = this.theWorld.getSkyColor(this.mc.renderViewEntity, par1);
952                float var3 = (float)var2.xCoord;
953                float var4 = (float)var2.yCoord;
954                float var5 = (float)var2.zCoord;
955                float var8;
956    
957                if (this.mc.gameSettings.anaglyph)
958                {
959                    float var6 = (var3 * 30.0F + var4 * 59.0F + var5 * 11.0F) / 100.0F;
960                    float var7 = (var3 * 30.0F + var4 * 70.0F) / 100.0F;
961                    var8 = (var3 * 30.0F + var5 * 70.0F) / 100.0F;
962                    var3 = var6;
963                    var4 = var7;
964                    var5 = var8;
965                }
966    
967                GL11.glColor3f(var3, var4, var5);
968                Tessellator var23 = Tessellator.instance;
969                GL11.glDepthMask(false);
970                GL11.glEnable(GL11.GL_FOG);
971                GL11.glColor3f(var3, var4, var5);
972                GL11.glCallList(this.glSkyList);
973                GL11.glDisable(GL11.GL_FOG);
974                GL11.glDisable(GL11.GL_ALPHA_TEST);
975                GL11.glEnable(GL11.GL_BLEND);
976                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
977                RenderHelper.disableStandardItemLighting();
978                float[] var24 = this.theWorld.provider.calcSunriseSunsetColors(this.theWorld.getCelestialAngle(par1), par1);
979                float var9;
980                float var10;
981                float var11;
982                float var12;
983    
984                if (var24 != null)
985                {
986                    GL11.glDisable(GL11.GL_TEXTURE_2D);
987                    GL11.glShadeModel(GL11.GL_SMOOTH);
988                    GL11.glPushMatrix();
989                    GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F);
990                    GL11.glRotatef(MathHelper.sin(this.theWorld.getCelestialAngleRadians(par1)) < 0.0F ? 180.0F : 0.0F, 0.0F, 0.0F, 1.0F);
991                    GL11.glRotatef(90.0F, 0.0F, 0.0F, 1.0F);
992                    var8 = var24[0];
993                    var9 = var24[1];
994                    var10 = var24[2];
995                    float var13;
996    
997                    if (this.mc.gameSettings.anaglyph)
998                    {
999                        var11 = (var8 * 30.0F + var9 * 59.0F + var10 * 11.0F) / 100.0F;
1000                        var12 = (var8 * 30.0F + var9 * 70.0F) / 100.0F;
1001                        var13 = (var8 * 30.0F + var10 * 70.0F) / 100.0F;
1002                        var8 = var11;
1003                        var9 = var12;
1004                        var10 = var13;
1005                    }
1006    
1007                    var23.startDrawing(6);
1008                    var23.setColorRGBA_F(var8, var9, var10, var24[3]);
1009                    var23.addVertex(0.0D, 100.0D, 0.0D);
1010                    byte var26 = 16;
1011                    var23.setColorRGBA_F(var24[0], var24[1], var24[2], 0.0F);
1012    
1013                    for (int var27 = 0; var27 <= var26; ++var27)
1014                    {
1015                        var13 = (float)var27 * (float)Math.PI * 2.0F / (float)var26;
1016                        float var14 = MathHelper.sin(var13);
1017                        float var15 = MathHelper.cos(var13);
1018                        var23.addVertex((double)(var14 * 120.0F), (double)(var15 * 120.0F), (double)(-var15 * 40.0F * var24[3]));
1019                    }
1020    
1021                    var23.draw();
1022                    GL11.glPopMatrix();
1023                    GL11.glShadeModel(GL11.GL_FLAT);
1024                }
1025    
1026                GL11.glEnable(GL11.GL_TEXTURE_2D);
1027                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
1028                GL11.glPushMatrix();
1029                var8 = 1.0F - this.theWorld.getRainStrength(par1);
1030                var9 = 0.0F;
1031                var10 = 0.0F;
1032                var11 = 0.0F;
1033                GL11.glColor4f(1.0F, 1.0F, 1.0F, var8);
1034                GL11.glTranslatef(var9, var10, var11);
1035                GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F);
1036                GL11.glRotatef(this.theWorld.getCelestialAngle(par1) * 360.0F, 1.0F, 0.0F, 0.0F);
1037                var12 = 30.0F;
1038                GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.renderEngine.getTexture("/terrain/sun.png"));
1039                var23.startDrawingQuads();
1040                var23.addVertexWithUV((double)(-var12), 100.0D, (double)(-var12), 0.0D, 0.0D);
1041                var23.addVertexWithUV((double)var12, 100.0D, (double)(-var12), 1.0D, 0.0D);
1042                var23.addVertexWithUV((double)var12, 100.0D, (double)var12, 1.0D, 1.0D);
1043                var23.addVertexWithUV((double)(-var12), 100.0D, (double)var12, 0.0D, 1.0D);
1044                var23.draw();
1045                var12 = 20.0F;
1046                GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.renderEngine.getTexture("/terrain/moon_phases.png"));
1047                int var28 = this.theWorld.getMoonPhase(par1);
1048                int var30 = var28 % 4;
1049                int var29 = var28 / 4 % 2;
1050                float var16 = (float)(var30 + 0) / 4.0F;
1051                float var17 = (float)(var29 + 0) / 2.0F;
1052                float var18 = (float)(var30 + 1) / 4.0F;
1053                float var19 = (float)(var29 + 1) / 2.0F;
1054                var23.startDrawingQuads();
1055                var23.addVertexWithUV((double)(-var12), -100.0D, (double)var12, (double)var18, (double)var19);
1056                var23.addVertexWithUV((double)var12, -100.0D, (double)var12, (double)var16, (double)var19);
1057                var23.addVertexWithUV((double)var12, -100.0D, (double)(-var12), (double)var16, (double)var17);
1058                var23.addVertexWithUV((double)(-var12), -100.0D, (double)(-var12), (double)var18, (double)var17);
1059                var23.draw();
1060                GL11.glDisable(GL11.GL_TEXTURE_2D);
1061                float var20 = this.theWorld.getStarBrightness(par1) * var8;
1062    
1063                if (var20 > 0.0F)
1064                {
1065                    GL11.glColor4f(var20, var20, var20, var20);
1066                    GL11.glCallList(this.starGLCallList);
1067                }
1068    
1069                GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
1070                GL11.glDisable(GL11.GL_BLEND);
1071                GL11.glEnable(GL11.GL_ALPHA_TEST);
1072                GL11.glEnable(GL11.GL_FOG);
1073                GL11.glPopMatrix();
1074                GL11.glDisable(GL11.GL_TEXTURE_2D);
1075                GL11.glColor3f(0.0F, 0.0F, 0.0F);
1076                double var25 = this.mc.thePlayer.getPosition(par1).yCoord - this.theWorld.getHorizon();
1077    
1078                if (var25 < 0.0D)
1079                {
1080                    GL11.glPushMatrix();
1081                    GL11.glTranslatef(0.0F, 12.0F, 0.0F);
1082                    GL11.glCallList(this.glSkyList2);
1083                    GL11.glPopMatrix();
1084                    var10 = 1.0F;
1085                    var11 = -((float)(var25 + 65.0D));
1086                    var12 = -var10;
1087                    var23.startDrawingQuads();
1088                    var23.setColorRGBA_I(0, 255);
1089                    var23.addVertex((double)(-var10), (double)var11, (double)var10);
1090                    var23.addVertex((double)var10, (double)var11, (double)var10);
1091                    var23.addVertex((double)var10, (double)var12, (double)var10);
1092                    var23.addVertex((double)(-var10), (double)var12, (double)var10);
1093                    var23.addVertex((double)(-var10), (double)var12, (double)(-var10));
1094                    var23.addVertex((double)var10, (double)var12, (double)(-var10));
1095                    var23.addVertex((double)var10, (double)var11, (double)(-var10));
1096                    var23.addVertex((double)(-var10), (double)var11, (double)(-var10));
1097                    var23.addVertex((double)var10, (double)var12, (double)(-var10));
1098                    var23.addVertex((double)var10, (double)var12, (double)var10);
1099                    var23.addVertex((double)var10, (double)var11, (double)var10);
1100                    var23.addVertex((double)var10, (double)var11, (double)(-var10));
1101                    var23.addVertex((double)(-var10), (double)var11, (double)(-var10));
1102                    var23.addVertex((double)(-var10), (double)var11, (double)var10);
1103                    var23.addVertex((double)(-var10), (double)var12, (double)var10);
1104                    var23.addVertex((double)(-var10), (double)var12, (double)(-var10));
1105                    var23.addVertex((double)(-var10), (double)var12, (double)(-var10));
1106                    var23.addVertex((double)(-var10), (double)var12, (double)var10);
1107                    var23.addVertex((double)var10, (double)var12, (double)var10);
1108                    var23.addVertex((double)var10, (double)var12, (double)(-var10));
1109                    var23.draw();
1110                }
1111    
1112                if (this.theWorld.provider.isSkyColored())
1113                {
1114                    GL11.glColor3f(var3 * 0.2F + 0.04F, var4 * 0.2F + 0.04F, var5 * 0.6F + 0.1F);
1115                }
1116                else
1117                {
1118                    GL11.glColor3f(var3, var4, var5);
1119                }
1120    
1121                GL11.glPushMatrix();
1122                GL11.glTranslatef(0.0F, -((float)(var25 - 16.0D)), 0.0F);
1123                GL11.glCallList(this.glSkyList2);
1124                GL11.glPopMatrix();
1125                GL11.glEnable(GL11.GL_TEXTURE_2D);
1126                GL11.glDepthMask(true);
1127            }
1128        }
1129    
1130        public void renderClouds(float par1)
1131        {
1132            if (this.mc.theWorld.provider.isSurfaceWorld())
1133            {
1134                if (this.mc.gameSettings.fancyGraphics)
1135                {
1136                    this.renderCloudsFancy(par1);
1137                }
1138                else
1139                {
1140                    GL11.glDisable(GL11.GL_CULL_FACE);
1141                    float var2 = (float)(this.mc.renderViewEntity.lastTickPosY + (this.mc.renderViewEntity.posY - this.mc.renderViewEntity.lastTickPosY) * (double)par1);
1142                    byte var3 = 32;
1143                    int var4 = 256 / var3;
1144                    Tessellator var5 = Tessellator.instance;
1145                    GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.renderEngine.getTexture("/environment/clouds.png"));
1146                    GL11.glEnable(GL11.GL_BLEND);
1147                    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
1148                    Vec3 var6 = this.theWorld.drawClouds(par1);
1149                    float var7 = (float)var6.xCoord;
1150                    float var8 = (float)var6.yCoord;
1151                    float var9 = (float)var6.zCoord;
1152                    float var10;
1153    
1154                    if (this.mc.gameSettings.anaglyph)
1155                    {
1156                        var10 = (var7 * 30.0F + var8 * 59.0F + var9 * 11.0F) / 100.0F;
1157                        float var11 = (var7 * 30.0F + var8 * 70.0F) / 100.0F;
1158                        float var12 = (var7 * 30.0F + var9 * 70.0F) / 100.0F;
1159                        var7 = var10;
1160                        var8 = var11;
1161                        var9 = var12;
1162                    }
1163    
1164                    var10 = 4.8828125E-4F;
1165                    double var24 = (double)((float)this.cloudTickCounter + par1);
1166                    double var13 = this.mc.renderViewEntity.prevPosX + (this.mc.renderViewEntity.posX - this.mc.renderViewEntity.prevPosX) * (double)par1 + var24 * 0.029999999329447746D;
1167                    double var15 = this.mc.renderViewEntity.prevPosZ + (this.mc.renderViewEntity.posZ - this.mc.renderViewEntity.prevPosZ) * (double)par1;
1168                    int var17 = MathHelper.floor_double(var13 / 2048.0D);
1169                    int var18 = MathHelper.floor_double(var15 / 2048.0D);
1170                    var13 -= (double)(var17 * 2048);
1171                    var15 -= (double)(var18 * 2048);
1172                    float var19 = this.theWorld.provider.getCloudHeight() - var2 + 0.33F;
1173                    float var20 = (float)(var13 * (double)var10);
1174                    float var21 = (float)(var15 * (double)var10);
1175                    var5.startDrawingQuads();
1176                    var5.setColorRGBA_F(var7, var8, var9, 0.8F);
1177    
1178                    for (int var22 = -var3 * var4; var22 < var3 * var4; var22 += var3)
1179                    {
1180                        for (int var23 = -var3 * var4; var23 < var3 * var4; var23 += var3)
1181                        {
1182                            var5.addVertexWithUV((double)(var22 + 0), (double)var19, (double)(var23 + var3), (double)((float)(var22 + 0) * var10 + var20), (double)((float)(var23 + var3) * var10 + var21));
1183                            var5.addVertexWithUV((double)(var22 + var3), (double)var19, (double)(var23 + var3), (double)((float)(var22 + var3) * var10 + var20), (double)((float)(var23 + var3) * var10 + var21));
1184                            var5.addVertexWithUV((double)(var22 + var3), (double)var19, (double)(var23 + 0), (double)((float)(var22 + var3) * var10 + var20), (double)((float)(var23 + 0) * var10 + var21));
1185                            var5.addVertexWithUV((double)(var22 + 0), (double)var19, (double)(var23 + 0), (double)((float)(var22 + 0) * var10 + var20), (double)((float)(var23 + 0) * var10 + var21));
1186                        }
1187                    }
1188    
1189                    var5.draw();
1190                    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
1191                    GL11.glDisable(GL11.GL_BLEND);
1192                    GL11.glEnable(GL11.GL_CULL_FACE);
1193                }
1194            }
1195        }
1196    
1197        public boolean func_72721_a(double par1, double par3, double par5, float par7)
1198        {
1199            return false;
1200        }
1201    
1202        /**
1203         * Renders the 3d fancy clouds
1204         */
1205        public void renderCloudsFancy(float par1)
1206        {
1207            GL11.glDisable(GL11.GL_CULL_FACE);
1208            float var2 = (float)(this.mc.renderViewEntity.lastTickPosY + (this.mc.renderViewEntity.posY - this.mc.renderViewEntity.lastTickPosY) * (double)par1);
1209            Tessellator var3 = Tessellator.instance;
1210            float var4 = 12.0F;
1211            float var5 = 4.0F;
1212            double var6 = (double)((float)this.cloudTickCounter + par1);
1213            double var8 = (this.mc.renderViewEntity.prevPosX + (this.mc.renderViewEntity.posX - this.mc.renderViewEntity.prevPosX) * (double)par1 + var6 * 0.029999999329447746D) / (double)var4;
1214            double var10 = (this.mc.renderViewEntity.prevPosZ + (this.mc.renderViewEntity.posZ - this.mc.renderViewEntity.prevPosZ) * (double)par1) / (double)var4 + 0.33000001311302185D;
1215            float var12 = this.theWorld.provider.getCloudHeight() - var2 + 0.33F;
1216            int var13 = MathHelper.floor_double(var8 / 2048.0D);
1217            int var14 = MathHelper.floor_double(var10 / 2048.0D);
1218            var8 -= (double)(var13 * 2048);
1219            var10 -= (double)(var14 * 2048);
1220            GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.renderEngine.getTexture("/environment/clouds.png"));
1221            GL11.glEnable(GL11.GL_BLEND);
1222            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
1223            Vec3 var15 = this.theWorld.drawClouds(par1);
1224            float var16 = (float)var15.xCoord;
1225            float var17 = (float)var15.yCoord;
1226            float var18 = (float)var15.zCoord;
1227            float var19;
1228            float var21;
1229            float var20;
1230    
1231            if (this.mc.gameSettings.anaglyph)
1232            {
1233                var19 = (var16 * 30.0F + var17 * 59.0F + var18 * 11.0F) / 100.0F;
1234                var20 = (var16 * 30.0F + var17 * 70.0F) / 100.0F;
1235                var21 = (var16 * 30.0F + var18 * 70.0F) / 100.0F;
1236                var16 = var19;
1237                var17 = var20;
1238                var18 = var21;
1239            }
1240    
1241            var19 = (float)(var8 * 0.0D);
1242            var20 = (float)(var10 * 0.0D);
1243            var21 = 0.00390625F;
1244            var19 = (float)MathHelper.floor_double(var8) * var21;
1245            var20 = (float)MathHelper.floor_double(var10) * var21;
1246            float var22 = (float)(var8 - (double)MathHelper.floor_double(var8));
1247            float var23 = (float)(var10 - (double)MathHelper.floor_double(var10));
1248            byte var24 = 8;
1249            byte var25 = 4;
1250            float var26 = 9.765625E-4F;
1251            GL11.glScalef(var4, 1.0F, var4);
1252    
1253            for (int var27 = 0; var27 < 2; ++var27)
1254            {
1255                if (var27 == 0)
1256                {
1257                    GL11.glColorMask(false, false, false, false);
1258                }
1259                else if (this.mc.gameSettings.anaglyph)
1260                {
1261                    if (EntityRenderer.anaglyphField == 0)
1262                    {
1263                        GL11.glColorMask(false, true, true, true);
1264                    }
1265                    else
1266                    {
1267                        GL11.glColorMask(true, false, false, true);
1268                    }
1269                }
1270                else
1271                {
1272                    GL11.glColorMask(true, true, true, true);
1273                }
1274    
1275                for (int var28 = -var25 + 1; var28 <= var25; ++var28)
1276                {
1277                    for (int var29 = -var25 + 1; var29 <= var25; ++var29)
1278                    {
1279                        var3.startDrawingQuads();
1280                        float var30 = (float)(var28 * var24);
1281                        float var31 = (float)(var29 * var24);
1282                        float var32 = var30 - var22;
1283                        float var33 = var31 - var23;
1284    
1285                        if (var12 > -var5 - 1.0F)
1286                        {
1287                            var3.setColorRGBA_F(var16 * 0.7F, var17 * 0.7F, var18 * 0.7F, 0.8F);
1288                            var3.setNormal(0.0F, -1.0F, 0.0F);
1289                            var3.addVertexWithUV((double)(var32 + 0.0F), (double)(var12 + 0.0F), (double)(var33 + (float)var24), (double)((var30 + 0.0F) * var21 + var19), (double)((var31 + (float)var24) * var21 + var20));
1290                            var3.addVertexWithUV((double)(var32 + (float)var24), (double)(var12 + 0.0F), (double)(var33 + (float)var24), (double)((var30 + (float)var24) * var21 + var19), (double)((var31 + (float)var24) * var21 + var20));
1291                            var3.addVertexWithUV((double)(var32 + (float)var24), (double)(var12 + 0.0F), (double)(var33 + 0.0F), (double)((var30 + (float)var24) * var21 + var19), (double)((var31 + 0.0F) * var21 + var20));
1292                            var3.addVertexWithUV((double)(var32 + 0.0F), (double)(var12 + 0.0F), (double)(var33 + 0.0F), (double)((var30 + 0.0F) * var21 + var19), (double)((var31 + 0.0F) * var21 + var20));
1293                        }
1294    
1295                        if (var12 <= var5 + 1.0F)
1296                        {
1297                            var3.setColorRGBA_F(var16, var17, var18, 0.8F);
1298                            var3.setNormal(0.0F, 1.0F, 0.0F);
1299                            var3.addVertexWithUV((double)(var32 + 0.0F), (double)(var12 + var5 - var26), (double)(var33 + (float)var24), (double)((var30 + 0.0F) * var21 + var19), (double)((var31 + (float)var24) * var21 + var20));
1300                            var3.addVertexWithUV((double)(var32 + (float)var24), (double)(var12 + var5 - var26), (double)(var33 + (float)var24), (double)((var30 + (float)var24) * var21 + var19), (double)((var31 + (float)var24) * var21 + var20));
1301                            var3.addVertexWithUV((double)(var32 + (float)var24), (double)(var12 + var5 - var26), (double)(var33 + 0.0F), (double)((var30 + (float)var24) * var21 + var19), (double)((var31 + 0.0F) * var21 + var20));
1302                            var3.addVertexWithUV((double)(var32 + 0.0F), (double)(var12 + var5 - var26), (double)(var33 + 0.0F), (double)((var30 + 0.0F) * var21 + var19), (double)((var31 + 0.0F) * var21 + var20));
1303                        }
1304    
1305                        var3.setColorRGBA_F(var16 * 0.9F, var17 * 0.9F, var18 * 0.9F, 0.8F);
1306                        int var34;
1307    
1308                        if (var28 > -1)
1309                        {
1310                            var3.setNormal(-1.0F, 0.0F, 0.0F);
1311    
1312                            for (var34 = 0; var34 < var24; ++var34)
1313                            {
1314                                var3.addVertexWithUV((double)(var32 + (float)var34 + 0.0F), (double)(var12 + 0.0F), (double)(var33 + (float)var24), (double)((var30 + (float)var34 + 0.5F) * var21 + var19), (double)((var31 + (float)var24) * var21 + var20));
1315                                var3.addVertexWithUV((double)(var32 + (float)var34 + 0.0F), (double)(var12 + var5), (double)(var33 + (float)var24), (double)((var30 + (float)var34 + 0.5F) * var21 + var19), (double)((var31 + (float)var24) * var21 + var20));
1316                                var3.addVertexWithUV((double)(var32 + (float)var34 + 0.0F), (double)(var12 + var5), (double)(var33 + 0.0F), (double)((var30 + (float)var34 + 0.5F) * var21 + var19), (double)((var31 + 0.0F) * var21 + var20));
1317                                var3.addVertexWithUV((double)(var32 + (float)var34 + 0.0F), (double)(var12 + 0.0F), (double)(var33 + 0.0F), (double)((var30 + (float)var34 + 0.5F) * var21 + var19), (double)((var31 + 0.0F) * var21 + var20));
1318                            }
1319                        }
1320    
1321                        if (var28 <= 1)
1322                        {
1323                            var3.setNormal(1.0F, 0.0F, 0.0F);
1324    
1325                            for (var34 = 0; var34 < var24; ++var34)
1326                            {
1327                                var3.addVertexWithUV((double)(var32 + (float)var34 + 1.0F - var26), (double)(var12 + 0.0F), (double)(var33 + (float)var24), (double)((var30 + (float)var34 + 0.5F) * var21 + var19), (double)((var31 + (float)var24) * var21 + var20));
1328                                var3.addVertexWithUV((double)(var32 + (float)var34 + 1.0F - var26), (double)(var12 + var5), (double)(var33 + (float)var24), (double)((var30 + (float)var34 + 0.5F) * var21 + var19), (double)((var31 + (float)var24) * var21 + var20));
1329                                var3.addVertexWithUV((double)(var32 + (float)var34 + 1.0F - var26), (double)(var12 + var5), (double)(var33 + 0.0F), (double)((var30 + (float)var34 + 0.5F) * var21 + var19), (double)((var31 + 0.0F) * var21 + var20));
1330                                var3.addVertexWithUV((double)(var32 + (float)var34 + 1.0F - var26), (double)(var12 + 0.0F), (double)(var33 + 0.0F), (double)((var30 + (float)var34 + 0.5F) * var21 + var19), (double)((var31 + 0.0F) * var21 + var20));
1331                            }
1332                        }
1333    
1334                        var3.setColorRGBA_F(var16 * 0.8F, var17 * 0.8F, var18 * 0.8F, 0.8F);
1335    
1336                        if (var29 > -1)
1337                        {
1338                            var3.setNormal(0.0F, 0.0F, -1.0F);
1339    
1340                            for (var34 = 0; var34 < var24; ++var34)
1341                            {
1342                                var3.addVertexWithUV((double)(var32 + 0.0F), (double)(var12 + var5), (double)(var33 + (float)var34 + 0.0F), (double)((var30 + 0.0F) * var21 + var19), (double)((var31 + (float)var34 + 0.5F) * var21 + var20));
1343                                var3.addVertexWithUV((double)(var32 + (float)var24), (double)(var12 + var5), (double)(var33 + (float)var34 + 0.0F), (double)((var30 + (float)var24) * var21 + var19), (double)((var31 + (float)var34 + 0.5F) * var21 + var20));
1344                                var3.addVertexWithUV((double)(var32 + (float)var24), (double)(var12 + 0.0F), (double)(var33 + (float)var34 + 0.0F), (double)((var30 + (float)var24) * var21 + var19), (double)((var31 + (float)var34 + 0.5F) * var21 + var20));
1345                                var3.addVertexWithUV((double)(var32 + 0.0F), (double)(var12 + 0.0F), (double)(var33 + (float)var34 + 0.0F), (double)((var30 + 0.0F) * var21 + var19), (double)((var31 + (float)var34 + 0.5F) * var21 + var20));
1346                            }
1347                        }
1348    
1349                        if (var29 <= 1)
1350                        {
1351                            var3.setNormal(0.0F, 0.0F, 1.0F);
1352    
1353                            for (var34 = 0; var34 < var24; ++var34)
1354                            {
1355                                var3.addVertexWithUV((double)(var32 + 0.0F), (double)(var12 + var5), (double)(var33 + (float)var34 + 1.0F - var26), (double)((var30 + 0.0F) * var21 + var19), (double)((var31 + (float)var34 + 0.5F) * var21 + var20));
1356                                var3.addVertexWithUV((double)(var32 + (float)var24), (double)(var12 + var5), (double)(var33 + (float)var34 + 1.0F - var26), (double)((var30 + (float)var24) * var21 + var19), (double)((var31 + (float)var34 + 0.5F) * var21 + var20));
1357                                var3.addVertexWithUV((double)(var32 + (float)var24), (double)(var12 + 0.0F), (double)(var33 + (float)var34 + 1.0F - var26), (double)((var30 + (float)var24) * var21 + var19), (double)((var31 + (float)var34 + 0.5F) * var21 + var20));
1358                                var3.addVertexWithUV((double)(var32 + 0.0F), (double)(var12 + 0.0F), (double)(var33 + (float)var34 + 1.0F - var26), (double)((var30 + 0.0F) * var21 + var19), (double)((var31 + (float)var34 + 0.5F) * var21 + var20));
1359                            }
1360                        }
1361    
1362                        var3.draw();
1363                    }
1364                }
1365            }
1366    
1367            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
1368            GL11.glDisable(GL11.GL_BLEND);
1369            GL11.glEnable(GL11.GL_CULL_FACE);
1370        }
1371    
1372        /**
1373         * Updates some of the renderers sorted by distance from the player
1374         */
1375        public boolean updateRenderers(EntityLiving par1EntityLiving, boolean par2)
1376        {
1377            byte var3 = 2;
1378            RenderSorter var4 = new RenderSorter(par1EntityLiving);
1379            WorldRenderer[] var5 = new WorldRenderer[var3];
1380            ArrayList var6 = null;
1381            int var7 = this.worldRenderersToUpdate.size();
1382            int var8 = 0;
1383            this.theWorld.theProfiler.startSection("nearChunksSearch");
1384            int var9;
1385            WorldRenderer var10;
1386            int var11;
1387            int var12;
1388            label136:
1389    
1390            for (var9 = 0; var9 < var7; ++var9)
1391            {
1392                var10 = (WorldRenderer)this.worldRenderersToUpdate.get(var9);
1393    
1394                if (var10 != null)
1395                {
1396                    if (!par2)
1397                    {
1398                        if (var10.distanceToEntitySquared(par1EntityLiving) > 256.0F)
1399                        {
1400                            for (var11 = 0; var11 < var3 && (var5[var11] == null || var4.doCompare(var5[var11], var10) <= 0); ++var11)
1401                            {
1402                                ;
1403                            }
1404    
1405                            --var11;
1406    
1407                            if (var11 > 0)
1408                            {
1409                                var12 = var11;
1410    
1411                                while (true)
1412                                {
1413                                    --var12;
1414    
1415                                    if (var12 == 0)
1416                                    {
1417                                        var5[var11] = var10;
1418                                        continue label136;
1419                                    }
1420    
1421                                    var5[var12 - 1] = var5[var12];
1422                                }
1423                            }
1424    
1425                            continue;
1426                        }
1427                    }
1428                    else if (!var10.isInFrustum)
1429                    {
1430                        continue;
1431                    }
1432    
1433                    if (var6 == null)
1434                    {
1435                        var6 = new ArrayList();
1436                    }
1437    
1438                    ++var8;
1439                    var6.add(var10);
1440                    this.worldRenderersToUpdate.set(var9, (Object)null);
1441                }
1442            }
1443    
1444            this.theWorld.theProfiler.endSection();
1445            this.theWorld.theProfiler.startSection("sort");
1446    
1447            if (var6 != null)
1448            {
1449                if (var6.size() > 1)
1450                {
1451                    Collections.sort(var6, var4);
1452                }
1453    
1454                for (var9 = var6.size() - 1; var9 >= 0; --var9)
1455                {
1456                    var10 = (WorldRenderer)var6.get(var9);
1457                    var10.updateRenderer();
1458                    var10.needsUpdate = false;
1459                }
1460            }
1461    
1462            this.theWorld.theProfiler.endSection();
1463            var9 = 0;
1464            this.theWorld.theProfiler.startSection("rebuild");
1465            int var16;
1466    
1467            for (var16 = var3 - 1; var16 >= 0; --var16)
1468            {
1469                WorldRenderer var17 = var5[var16];
1470    
1471                if (var17 != null)
1472                {
1473                    if (!var17.isInFrustum && var16 != var3 - 1)
1474                    {
1475                        var5[var16] = null;
1476                        var5[0] = null;
1477                        break;
1478                    }
1479    
1480                    var5[var16].updateRenderer();
1481                    var5[var16].needsUpdate = false;
1482                    ++var9;
1483                }
1484            }
1485    
1486            this.theWorld.theProfiler.endSection();
1487            this.theWorld.theProfiler.startSection("cleanup");
1488            var16 = 0;
1489            var11 = 0;
1490    
1491            for (var12 = this.worldRenderersToUpdate.size(); var16 != var12; ++var16)
1492            {
1493                WorldRenderer var13 = (WorldRenderer)this.worldRenderersToUpdate.get(var16);
1494    
1495                if (var13 != null)
1496                {
1497                    boolean var14 = false;
1498    
1499                    for (int var15 = 0; var15 < var3 && !var14; ++var15)
1500                    {
1501                        if (var13 == var5[var15])
1502                        {
1503                            var14 = true;
1504                        }
1505                    }
1506    
1507                    if (!var14)
1508                    {
1509                        if (var11 != var16)
1510                        {
1511                            this.worldRenderersToUpdate.set(var11, var13);
1512                        }
1513    
1514                        ++var11;
1515                    }
1516                }
1517            }
1518    
1519            this.theWorld.theProfiler.endSection();
1520            this.theWorld.theProfiler.startSection("trim");
1521    
1522            while (true)
1523            {
1524                --var16;
1525    
1526                if (var16 < var11)
1527                {
1528                    this.theWorld.theProfiler.endSection();
1529                    return var7 == var8 + var9;
1530                }
1531    
1532                this.worldRenderersToUpdate.remove(var16);
1533            }
1534        }
1535    
1536        public void drawBlockBreaking(EntityPlayer par1EntityPlayer, MovingObjectPosition par2MovingObjectPosition, int par3, ItemStack par4ItemStack, float par5)
1537        {
1538            Tessellator var6 = Tessellator.instance;
1539            GL11.glEnable(GL11.GL_BLEND);
1540            GL11.glEnable(GL11.GL_ALPHA_TEST);
1541            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
1542            GL11.glColor4f(1.0F, 1.0F, 1.0F, (MathHelper.sin((float)Minecraft.getSystemTime() / 100.0F) * 0.2F + 0.4F) * 0.5F);
1543    
1544            if (par3 != 0 && par4ItemStack != null)
1545            {
1546                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
1547                float var7 = MathHelper.sin((float)Minecraft.getSystemTime() / 100.0F) * 0.2F + 0.8F;
1548                GL11.glColor4f(var7, var7, var7, MathHelper.sin((float)Minecraft.getSystemTime() / 200.0F) * 0.2F + 0.5F);
1549                int var8 = this.renderEngine.getTexture("/terrain.png");
1550                GL11.glBindTexture(GL11.GL_TEXTURE_2D, var8);
1551            }
1552    
1553            GL11.glDisable(GL11.GL_BLEND);
1554            GL11.glDisable(GL11.GL_ALPHA_TEST);
1555        }
1556    
1557        public void drawBlockDamageTexture(Tessellator par1Tessellator, EntityPlayer par2EntityPlayer, float par3)
1558        {
1559            drawBlockDamageTexture(par1Tessellator, (EntityLiving)par2EntityPlayer, par3);
1560        }
1561    
1562        public void drawBlockDamageTexture(Tessellator par1Tessellator, EntityLiving par2EntityPlayer, float par3)
1563        {
1564            double var4 = par2EntityPlayer.lastTickPosX + (par2EntityPlayer.posX - par2EntityPlayer.lastTickPosX) * (double)par3;
1565            double var6 = par2EntityPlayer.lastTickPosY + (par2EntityPlayer.posY - par2EntityPlayer.lastTickPosY) * (double)par3;
1566            double var8 = par2EntityPlayer.lastTickPosZ + (par2EntityPlayer.posZ - par2EntityPlayer.lastTickPosZ) * (double)par3;
1567    
1568            if (!this.damagedBlocks.isEmpty())
1569            {
1570                GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_SRC_COLOR);
1571                int var10 = this.renderEngine.getTexture("/terrain.png");
1572                GL11.glBindTexture(GL11.GL_TEXTURE_2D, var10);
1573                GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F);
1574                GL11.glPushMatrix();
1575                GL11.glDisable(GL11.GL_ALPHA_TEST);
1576                GL11.glPolygonOffset(-3.0F, -3.0F);
1577                GL11.glEnable(GL11.GL_POLYGON_OFFSET_FILL);
1578                GL11.glEnable(GL11.GL_ALPHA_TEST);
1579                par1Tessellator.startDrawingQuads();
1580                par1Tessellator.setTranslation(-var4, -var6, -var8);
1581                par1Tessellator.disableColor();
1582                Iterator var11 = this.damagedBlocks.values().iterator();
1583    
1584                while (var11.hasNext())
1585                {
1586                    DestroyBlockProgress var12 = (DestroyBlockProgress)var11.next();
1587                    double var13 = (double)var12.getPartialBlockX() - var4;
1588                    double var15 = (double)var12.getPartialBlockY() - var6;
1589                    double var17 = (double)var12.getPartialBlockZ() - var8;
1590    
1591                    if (var13 * var13 + var15 * var15 + var17 * var17 > 1024.0D)
1592                    {
1593                        var11.remove();
1594                    }
1595                    else
1596                    {
1597                        int var19 = this.theWorld.getBlockId(var12.getPartialBlockX(), var12.getPartialBlockY(), var12.getPartialBlockZ());
1598                        Block var20 = var19 > 0 ? Block.blocksList[var19] : null;
1599    
1600                        if (var20 == null)
1601                        {
1602                            var20 = Block.stone;
1603                        }
1604    
1605                        this.globalRenderBlocks.renderBlockUsingTexture(var20, var12.getPartialBlockX(), var12.getPartialBlockY(), var12.getPartialBlockZ(), 240 + var12.getPartialBlockDamage());
1606                    }
1607                }
1608    
1609                par1Tessellator.draw();
1610                par1Tessellator.setTranslation(0.0D, 0.0D, 0.0D);
1611                GL11.glDisable(GL11.GL_ALPHA_TEST);
1612                GL11.glPolygonOffset(0.0F, 0.0F);
1613                GL11.glDisable(GL11.GL_POLYGON_OFFSET_FILL);
1614                GL11.glEnable(GL11.GL_ALPHA_TEST);
1615                GL11.glDepthMask(true);
1616                GL11.glPopMatrix();
1617            }
1618        }
1619    
1620        /**
1621         * Draws the selection box for the player. Args: entityPlayer, rayTraceHit, i, itemStack, partialTickTime
1622         */
1623        public void drawSelectionBox(EntityPlayer par1EntityPlayer, MovingObjectPosition par2MovingObjectPosition, int par3, ItemStack par4ItemStack, float par5)
1624        {
1625            if (par3 == 0 && par2MovingObjectPosition.typeOfHit == EnumMovingObjectType.TILE)
1626            {
1627                GL11.glEnable(GL11.GL_BLEND);
1628                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
1629                GL11.glColor4f(0.0F, 0.0F, 0.0F, 0.4F);
1630                GL11.glLineWidth(2.0F);
1631                GL11.glDisable(GL11.GL_TEXTURE_2D);
1632                GL11.glDepthMask(false);
1633                float var6 = 0.002F;
1634                int var7 = this.theWorld.getBlockId(par2MovingObjectPosition.blockX, par2MovingObjectPosition.blockY, par2MovingObjectPosition.blockZ);
1635    
1636                if (var7 > 0)
1637                {
1638                    Block.blocksList[var7].setBlockBoundsBasedOnState(this.theWorld, par2MovingObjectPosition.blockX, par2MovingObjectPosition.blockY, par2MovingObjectPosition.blockZ);
1639                    double var8 = par1EntityPlayer.lastTickPosX + (par1EntityPlayer.posX - par1EntityPlayer.lastTickPosX) * (double)par5;
1640                    double var10 = par1EntityPlayer.lastTickPosY + (par1EntityPlayer.posY - par1EntityPlayer.lastTickPosY) * (double)par5;
1641                    double var12 = par1EntityPlayer.lastTickPosZ + (par1EntityPlayer.posZ - par1EntityPlayer.lastTickPosZ) * (double)par5;
1642                    this.drawOutlinedBoundingBox(Block.blocksList[var7].getSelectedBoundingBoxFromPool(this.theWorld, par2MovingObjectPosition.blockX, par2MovingObjectPosition.blockY, par2MovingObjectPosition.blockZ).expand((double)var6, (double)var6, (double)var6).getOffsetBoundingBox(-var8, -var10, -var12));
1643                }
1644    
1645                GL11.glDepthMask(true);
1646                GL11.glEnable(GL11.GL_TEXTURE_2D);
1647                GL11.glDisable(GL11.GL_BLEND);
1648            }
1649        }
1650    
1651        /**
1652         * Draws lines for the edges of the bounding box.
1653         */
1654        private void drawOutlinedBoundingBox(AxisAlignedBB par1AxisAlignedBB)
1655        {
1656            Tessellator var2 = Tessellator.instance;
1657            var2.startDrawing(3);
1658            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
1659            var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
1660            var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
1661            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
1662            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
1663            var2.draw();
1664            var2.startDrawing(3);
1665            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
1666            var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
1667            var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
1668            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
1669            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
1670            var2.draw();
1671            var2.startDrawing(1);
1672            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
1673            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
1674            var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
1675            var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
1676            var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
1677            var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
1678            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
1679            var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
1680            var2.draw();
1681        }
1682    
1683        /**
1684         * Marks the blocks in the given range for update
1685         */
1686        public void markBlocksForUpdate(int par1, int par2, int par3, int par4, int par5, int par6)
1687        {
1688            int var7 = MathHelper.bucketInt(par1, 16);
1689            int var8 = MathHelper.bucketInt(par2, 16);
1690            int var9 = MathHelper.bucketInt(par3, 16);
1691            int var10 = MathHelper.bucketInt(par4, 16);
1692            int var11 = MathHelper.bucketInt(par5, 16);
1693            int var12 = MathHelper.bucketInt(par6, 16);
1694    
1695            for (int var13 = var7; var13 <= var10; ++var13)
1696            {
1697                int var14 = var13 % this.renderChunksWide;
1698    
1699                if (var14 < 0)
1700                {
1701                    var14 += this.renderChunksWide;
1702                }
1703    
1704                for (int var15 = var8; var15 <= var11; ++var15)
1705                {
1706                    int var16 = var15 % this.renderChunksTall;
1707    
1708                    if (var16 < 0)
1709                    {
1710                        var16 += this.renderChunksTall;
1711                    }
1712    
1713                    for (int var17 = var9; var17 <= var12; ++var17)
1714                    {
1715                        int var18 = var17 % this.renderChunksDeep;
1716    
1717                        if (var18 < 0)
1718                        {
1719                            var18 += this.renderChunksDeep;
1720                        }
1721    
1722                        int var19 = (var18 * this.renderChunksTall + var16) * this.renderChunksWide + var14;
1723                        WorldRenderer var20 = this.worldRenderers[var19];
1724    
1725                        if (var20 != null && !var20.needsUpdate)
1726                        {
1727                            this.worldRenderersToUpdate.add(var20);
1728                            var20.markDirty();
1729                        }
1730                    }
1731                }
1732            }
1733        }
1734    
1735        /**
1736         * Will mark the block and neighbors that their renderers need an update (could be all the same renderer
1737         * potentially) Args: x, y, z
1738         */
1739        public void markBlockNeedsUpdate(int par1, int par2, int par3)
1740        {
1741            this.markBlocksForUpdate(par1 - 1, par2 - 1, par3 - 1, par1 + 1, par2 + 1, par3 + 1);
1742        }
1743    
1744        /**
1745         * As of mc 1.2.3 this method has exactly the same signature and does exactly the same as markBlockNeedsUpdate
1746         */
1747        public void markBlockNeedsUpdate2(int par1, int par2, int par3)
1748        {
1749            this.markBlocksForUpdate(par1 - 1, par2 - 1, par3 - 1, par1 + 1, par2 + 1, par3 + 1);
1750        }
1751    
1752        /**
1753         * Called across all registered IWorldAccess instances when a block range is invalidated. Args: minX, minY, minZ,
1754         * maxX, maxY, maxZ
1755         */
1756        public void markBlockRangeNeedsUpdate(int par1, int par2, int par3, int par4, int par5, int par6)
1757        {
1758            this.markBlocksForUpdate(par1 - 1, par2 - 1, par3 - 1, par4 + 1, par5 + 1, par6 + 1);
1759        }
1760    
1761        /**
1762         * Checks all renderers that previously weren't in the frustum and 1/16th of those that previously were in the
1763         * frustum for frustum clipping Args: frustum, partialTickTime
1764         */
1765        public void clipRenderersByFrustum(ICamera par1ICamera, float par2)
1766        {
1767            for (int var3 = 0; var3 < this.worldRenderers.length; ++var3)
1768            {
1769                if (!this.worldRenderers[var3].skipAllRenderPasses() && (!this.worldRenderers[var3].isInFrustum || (var3 + this.frustumCheckOffset & 15) == 0))
1770                {
1771                    this.worldRenderers[var3].updateInFrustum(par1ICamera);
1772                }
1773            }
1774    
1775            ++this.frustumCheckOffset;
1776        }
1777    
1778        /**
1779         * Plays the specified record. Arg: recordName, x, y, z
1780         */
1781        public void playRecord(String par1Str, int par2, int par3, int par4)
1782        {
1783            ItemRecord var5 = ItemRecord.func_90042_d(par1Str);
1784    
1785            if (par1Str != null && var5 != null)
1786            {
1787                this.mc.ingameGUI.setRecordPlayingMessage(var5.func_90043_g());
1788            }
1789    
1790            this.mc.sndManager.playStreaming(par1Str, (float)par2, (float)par3, (float)par4);
1791        }
1792    
1793        /**
1794         * Plays the specified sound. Arg: soundName, x, y, z, volume, pitch
1795         */
1796        public void playSound(String par1Str, double par2, double par4, double par6, float par8, float par9) {}
1797    
1798        public void func_85102_a(EntityPlayer par1EntityPlayer, String par2Str, double par3, double par5, double par7, float par9, float par10) {}
1799    
1800        /**
1801         * Spawns a particle. Arg: particleType, x, y, z, velX, velY, velZ
1802         */
1803        public void spawnParticle(String par1Str, double par2, double par4, double par6, double par8, double par10, double par12)
1804        {
1805            try
1806            {
1807                this.func_72726_b(par1Str, par2, par4, par6, par8, par10, par12);
1808            }
1809            catch (Throwable var17)
1810            {
1811                CrashReport var15 = CrashReport.func_85055_a(var17, "Exception while adding particle");
1812                CrashReportCategory var16 = var15.func_85058_a("Particle being added");
1813                var16.addCrashSection("Name", par1Str);
1814                var16.addCrashSectionCallable("Position", new CallableParticlePositionInfo(this, par2, par4, par6));
1815                throw new ReportedException(var15);
1816            }
1817        }
1818    
1819        public EntityFX func_72726_b(String par1Str, double par2, double par4, double par6, double par8, double par10, double par12)
1820        {
1821            if (this.mc != null && this.mc.renderViewEntity != null && this.mc.effectRenderer != null)
1822            {
1823                int var14 = this.mc.gameSettings.particleSetting;
1824    
1825                if (var14 == 1 && this.theWorld.rand.nextInt(3) == 0)
1826                {
1827                    var14 = 2;
1828                }
1829    
1830                double var15 = this.mc.renderViewEntity.posX - par2;
1831                double var17 = this.mc.renderViewEntity.posY - par4;
1832                double var19 = this.mc.renderViewEntity.posZ - par6;
1833                EntityFX var21 = null;
1834                Object effectObject = null;
1835    
1836                if (par1Str.equals("hugeexplosion"))
1837                {
1838                    this.mc.effectRenderer.addEffect(var21 = new EntityHugeExplodeFX(this.theWorld, par2, par4, par6, par8, par10, par12));
1839                }
1840                else if (par1Str.equals("largeexplode"))
1841                {
1842                    this.mc.effectRenderer.addEffect(var21 = new EntityLargeExplodeFX(this.renderEngine, this.theWorld, par2, par4, par6, par8, par10, par12));
1843                }
1844    
1845                if (var21 != null)
1846                {
1847                    return (EntityFX)var21;
1848                }
1849                else
1850                {
1851                    double var22 = 16.0D;
1852    
1853                    if (var15 * var15 + var17 * var17 + var19 * var19 > var22 * var22)
1854                    {
1855                        return null;
1856                    }
1857                    else if (var14 > 1)
1858                    {
1859                        return null;
1860                    }
1861                    else
1862                    {
1863                        if (par1Str.equals("bubble"))
1864                        {
1865                            var21 = new EntityBubbleFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1866                        }
1867                        else if (par1Str.equals("suspended"))
1868                        {
1869                            var21 = new EntitySuspendFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1870                        }
1871                        else if (par1Str.equals("depthsuspend"))
1872                        {
1873                            var21 = new EntityAuraFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1874                        }
1875                        else if (par1Str.equals("townaura"))
1876                        {
1877                            var21 = new EntityAuraFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1878                        }
1879                        else if (par1Str.equals("crit"))
1880                        {
1881                            var21 = new EntityCritFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1882                        }
1883                        else if (par1Str.equals("magicCrit"))
1884                        {
1885                            var21 = new EntityCritFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1886                            ((EntityFX)var21).setRBGColorF(((EntityFX)var21).getRedColorF() * 0.3F, ((EntityFX)var21).getGreenColorF() * 0.8F, ((EntityFX)var21).getBlueColorF());
1887                            ((EntityFX)var21).setParticleTextureIndex(((EntityFX)var21).getParticleTextureIndex() + 1);
1888                        }
1889                        else if (par1Str.equals("smoke"))
1890                        {
1891                            var21 = new EntitySmokeFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1892                        }
1893                        else if (par1Str.equals("mobSpell"))
1894                        {
1895                            var21 = new EntitySpellParticleFX(this.theWorld, par2, par4, par6, 0.0D, 0.0D, 0.0D);
1896                            ((EntityFX)var21).setRBGColorF((float)par8, (float)par10, (float)par12);
1897                        }
1898                        else if (par1Str.equals("mobSpellAmbient"))
1899                        {
1900                            var21 = new EntitySpellParticleFX(this.theWorld, par2, par4, par6, 0.0D, 0.0D, 0.0D);
1901                            ((EntityFX)var21).func_82338_g(0.15F);
1902                            ((EntityFX)var21).setRBGColorF((float)par8, (float)par10, (float)par12);
1903                        }
1904                        else if (par1Str.equals("spell"))
1905                        {
1906                            var21 = new EntitySpellParticleFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1907                        }
1908                        else if (par1Str.equals("instantSpell"))
1909                        {
1910                            var21 = new EntitySpellParticleFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1911                            ((EntitySpellParticleFX)var21).func_70589_b(144);
1912                        }
1913                        else if (par1Str.equals("witchMagic"))
1914                        {
1915                            var21 = new EntitySpellParticleFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1916                            ((EntitySpellParticleFX)var21).func_70589_b(144);
1917                            float var24 = this.theWorld.rand.nextFloat() * 0.5F + 0.35F;
1918                            ((EntityFX)var21).setRBGColorF(1.0F * var24, 0.0F * var24, 1.0F * var24);
1919                        }
1920                        else if (par1Str.equals("note"))
1921                        {
1922                            var21 = new EntityNoteFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1923                        }
1924                        else if (par1Str.equals("portal"))
1925                        {
1926                            var21 = new EntityPortalFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1927                        }
1928                        else if (par1Str.equals("enchantmenttable"))
1929                        {
1930                            var21 = new EntityEnchantmentTableParticleFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1931                        }
1932                        else if (par1Str.equals("explode"))
1933                        {
1934                            var21 = new EntityExplodeFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1935                        }
1936                        else if (par1Str.equals("flame"))
1937                        {
1938                            var21 = new EntityFlameFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1939                        }
1940                        else if (par1Str.equals("lava"))
1941                        {
1942                            var21 = new EntityLavaFX(this.theWorld, par2, par4, par6);
1943                        }
1944                        else if (par1Str.equals("footstep"))
1945                        {
1946                            var21 = new EntityFootStepFX(this.renderEngine, this.theWorld, par2, par4, par6);
1947                        }
1948                        else if (par1Str.equals("splash"))
1949                        {
1950                            var21 = new EntitySplashFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1951                        }
1952                        else if (par1Str.equals("largesmoke"))
1953                        {
1954                            var21 = new EntitySmokeFX(this.theWorld, par2, par4, par6, par8, par10, par12, 2.5F);
1955                        }
1956                        else if (par1Str.equals("cloud"))
1957                        {
1958                            var21 = new EntityCloudFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1959                        }
1960                        else if (par1Str.equals("reddust"))
1961                        {
1962                            var21 = new EntityReddustFX(this.theWorld, par2, par4, par6, (float)par8, (float)par10, (float)par12);
1963                        }
1964                        else if (par1Str.equals("snowballpoof"))
1965                        {
1966                            var21 = new EntityBreakingFX(this.theWorld, par2, par4, par6, Item.snowball);
1967                            effectObject = Item.snowball;
1968                        }
1969                        else if (par1Str.equals("dripWater"))
1970                        {
1971                            var21 = new EntityDropParticleFX(this.theWorld, par2, par4, par6, Material.water);
1972                        }
1973                        else if (par1Str.equals("dripLava"))
1974                        {
1975                            var21 = new EntityDropParticleFX(this.theWorld, par2, par4, par6, Material.lava);
1976                        }
1977                        else if (par1Str.equals("snowshovel"))
1978                        {
1979                            var21 = new EntitySnowShovelFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1980                        }
1981                        else if (par1Str.equals("slime"))
1982                        {
1983                            var21 = new EntityBreakingFX(this.theWorld, par2, par4, par6, Item.slimeBall);
1984                            effectObject = Item.slimeBall;
1985                        }
1986                        else if (par1Str.equals("heart"))
1987                        {
1988                            var21 = new EntityHeartFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1989                        }
1990                        else if (par1Str.equals("angryVillager"))
1991                        {
1992                            var21 = new EntityHeartFX(this.theWorld, par2, par4 + 0.5D, par6, par8, par10, par12);
1993                            ((EntityFX)var21).setParticleTextureIndex(81);
1994                            ((EntityFX)var21).setRBGColorF(1.0F, 1.0F, 1.0F);
1995                        }
1996                        else if (par1Str.equals("happyVillager"))
1997                        {
1998                            var21 = new EntityAuraFX(this.theWorld, par2, par4, par6, par8, par10, par12);
1999                            ((EntityFX)var21).setParticleTextureIndex(82);
2000                            ((EntityFX)var21).setRBGColorF(1.0F, 1.0F, 1.0F);
2001                        }
2002                        else if (par1Str.startsWith("iconcrack_"))
2003                        {
2004                            int var27 = Integer.parseInt(par1Str.substring(par1Str.indexOf("_") + 1));
2005                            var21 = new EntityBreakingFX(this.theWorld, par2, par4, par6, par8, par10, par12, Item.itemsList[var27]);
2006                            effectObject = Item.itemsList[var27];
2007                        }
2008                        else if (par1Str.startsWith("tilecrack_"))
2009                        {
2010                            String[] var28 = par1Str.split("_", 3);
2011                            int var25 = Integer.parseInt(var28[1]);
2012                            int var26 = Integer.parseInt(var28[2]);
2013                            var21 = (new EntityDiggingFX(this.theWorld, par2, par4, par6, par8, par10, par12, Block.blocksList[var25], 0, var26)).func_90019_g(var26);
2014                            effectObject = Block.blocksList[var25];
2015                        }
2016    
2017                        if (var21 != null)
2018                        {
2019                            this.mc.effectRenderer.addEffect((EntityFX)var21, effectObject);
2020                        }
2021    
2022                        return (EntityFX)var21;
2023                    }
2024                }
2025            }
2026            else
2027            {
2028                return null;
2029            }
2030        }
2031    
2032        /**
2033         * Start the skin for this entity downloading, if necessary, and increment its reference counter
2034         */
2035        public void obtainEntitySkin(Entity par1Entity)
2036        {
2037            par1Entity.updateCloak();
2038    
2039            if (par1Entity.skinUrl != null)
2040            {
2041                this.renderEngine.obtainImageData(par1Entity.skinUrl, new ImageBufferDownload());
2042            }
2043    
2044            if (par1Entity.cloakUrl != null)
2045            {
2046                this.renderEngine.obtainImageData(par1Entity.cloakUrl, new ImageBufferDownload());
2047            }
2048        }
2049    
2050        /**
2051         * Decrement the reference counter for this entity's skin image data
2052         */
2053        public void releaseEntitySkin(Entity par1Entity)
2054        {
2055            if (par1Entity.skinUrl != null)
2056            {
2057                this.renderEngine.releaseImageData(par1Entity.skinUrl);
2058            }
2059    
2060            if (par1Entity.cloakUrl != null)
2061            {
2062                this.renderEngine.releaseImageData(par1Entity.cloakUrl);
2063            }
2064        }
2065    
2066        public void func_72728_f()
2067        {
2068            GLAllocation.deleteDisplayLists(this.glRenderListBase);
2069        }
2070    
2071        public void func_82746_a(int par1, int par2, int par3, int par4, int par5)
2072        {
2073            Random var6 = this.theWorld.rand;
2074    
2075            switch (par1)
2076            {
2077                case 1013:
2078                case 1018:
2079                    if (this.mc.renderViewEntity != null)
2080                    {
2081                        double var7 = (double)par2 - this.mc.renderViewEntity.posX;
2082                        double var9 = (double)par3 - this.mc.renderViewEntity.posY;
2083                        double var11 = (double)par4 - this.mc.renderViewEntity.posZ;
2084                        double var13 = Math.sqrt(var7 * var7 + var9 * var9 + var11 * var11);
2085                        double var15 = this.mc.renderViewEntity.posX;
2086                        double var17 = this.mc.renderViewEntity.posY;
2087                        double var19 = this.mc.renderViewEntity.posZ;
2088    
2089                        if (var13 > 0.0D)
2090                        {
2091                            var15 += var7 / var13 * 2.0D;
2092                            var17 += var9 / var13 * 2.0D;
2093                            var19 += var11 / var13 * 2.0D;
2094                        }
2095    
2096                        if (par1 == 1013)
2097                        {
2098                            this.theWorld.playSound(var15, var17, var19, "mob.wither.spawn", 1.0F, 1.0F);
2099                        }
2100                        else if (par1 == 1018)
2101                        {
2102                            this.theWorld.playSound(var15, var17, var19, "mob.enderdragon.end", 5.0F, 1.0F);
2103                        }
2104                    }
2105                default:
2106            }
2107        }
2108    
2109        /**
2110         * Plays a pre-canned sound effect along with potentially auxiliary data-driven one-shot behaviour (particles, etc).
2111         */
2112        public void playAuxSFX(EntityPlayer par1EntityPlayer, int par2, int par3, int par4, int par5, int par6)
2113        {
2114            Random var7 = this.theWorld.rand;
2115            double var8;
2116            double var10;
2117            double var12;
2118            String var14;
2119            int var15;
2120            int var20;
2121            double var23;
2122            double var25;
2123            double var27;
2124            double var29;
2125            double var39;
2126    
2127            switch (par2)
2128            {
2129                case 1000:
2130                    this.theWorld.playSound((double)par3, (double)par4, (double)par5, "random.click", 1.0F, 1.0F);
2131                    break;
2132                case 1001:
2133                    this.theWorld.playSound((double)par3, (double)par4, (double)par5, "random.click", 1.0F, 1.2F);
2134                    break;
2135                case 1002:
2136                    this.theWorld.playSound((double)par3, (double)par4, (double)par5, "random.bow", 1.0F, 1.2F);
2137                    break;
2138                case 1003:
2139                    if (Math.random() < 0.5D)
2140                    {
2141                        this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "random.door_open", 1.0F, this.theWorld.rand.nextFloat() * 0.1F + 0.9F);
2142                    }
2143                    else
2144                    {
2145                        this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "random.door_close", 1.0F, this.theWorld.rand.nextFloat() * 0.1F + 0.9F);
2146                    }
2147    
2148                    break;
2149                case 1004:
2150                    this.theWorld.playSound((double)((float)par3 + 0.5F), (double)((float)par4 + 0.5F), (double)((float)par5 + 0.5F), "random.fizz", 0.5F, 2.6F + (var7.nextFloat() - var7.nextFloat()) * 0.8F);
2151                    break;
2152                case 1005:
2153                    if (Item.itemsList[par6] instanceof ItemRecord)
2154                    {
2155                        this.theWorld.playRecord(((ItemRecord)Item.itemsList[par6]).recordName, par3, par4, par5);
2156                    }
2157                    else
2158                    {
2159                        this.theWorld.playRecord((String)null, par3, par4, par5);
2160                    }
2161    
2162                    break;
2163                case 1007:
2164                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.ghast.charge", 10.0F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2165                    break;
2166                case 1008:
2167                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.ghast.fireball", 10.0F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2168                    break;
2169                case 1009:
2170                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.ghast.fireball", 2.0F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2171                    break;
2172                case 1010:
2173                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.zombie.wood", 2.0F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2174                    break;
2175                case 1011:
2176                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.zombie.metal", 2.0F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2177                    break;
2178                case 1012:
2179                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.zombie.woodbreak", 2.0F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2180                    break;
2181                case 1014:
2182                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.wither.shoot", 2.0F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2183                    break;
2184                case 1015:
2185                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.bat.takeoff", 0.05F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2186                    break;
2187                case 1016:
2188                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.zombie.infect", 2.0F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2189                    break;
2190                case 1017:
2191                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "mob.zombie.unfect", 2.0F, (var7.nextFloat() - var7.nextFloat()) * 0.2F + 1.0F);
2192                    break;
2193                case 1020:
2194                    this.theWorld.playSound((double)((float)par3 + 0.5F), (double)((float)par4 + 0.5F), (double)((float)par5 + 0.5F), "random.anvil_break", 1.0F, this.theWorld.rand.nextFloat() * 0.1F + 0.9F);
2195                    break;
2196                case 1021:
2197                    this.theWorld.playSound((double)((float)par3 + 0.5F), (double)((float)par4 + 0.5F), (double)((float)par5 + 0.5F), "random.anvil_use", 1.0F, this.theWorld.rand.nextFloat() * 0.1F + 0.9F);
2198                    break;
2199                case 1022:
2200                    this.theWorld.playSound((double)((float)par3 + 0.5F), (double)((float)par4 + 0.5F), (double)((float)par5 + 0.5F), "random.anvil_land", 0.3F, this.theWorld.rand.nextFloat() * 0.1F + 0.9F);
2201                    break;
2202                case 2000:
2203                    int var33 = par6 % 3 - 1;
2204                    int var9 = par6 / 3 % 3 - 1;
2205                    var10 = (double)par3 + (double)var33 * 0.6D + 0.5D;
2206                    var12 = (double)par4 + 0.5D;
2207                    double var34 = (double)par5 + (double)var9 * 0.6D + 0.5D;
2208    
2209                    for (int var35 = 0; var35 < 10; ++var35)
2210                    {
2211                        double var37 = var7.nextDouble() * 0.2D + 0.01D;
2212                        double var38 = var10 + (double)var33 * 0.01D + (var7.nextDouble() - 0.5D) * (double)var9 * 0.5D;
2213                        var39 = var12 + (var7.nextDouble() - 0.5D) * 0.5D;
2214                        var23 = var34 + (double)var9 * 0.01D + (var7.nextDouble() - 0.5D) * (double)var33 * 0.5D;
2215                        var25 = (double)var33 * var37 + var7.nextGaussian() * 0.01D;
2216                        var27 = -0.03D + var7.nextGaussian() * 0.01D;
2217                        var29 = (double)var9 * var37 + var7.nextGaussian() * 0.01D;
2218                        this.spawnParticle("smoke", var38, var39, var23, var25, var27, var29);
2219                    }
2220    
2221                    return;
2222                case 2001:
2223                    var20 = par6 & 4095;
2224    
2225                    if (var20 > 0)
2226                    {
2227                        Block var40 = Block.blocksList[var20];
2228                        this.mc.sndManager.playSound(var40.stepSound.getBreakSound(), (float)par3 + 0.5F, (float)par4 + 0.5F, (float)par5 + 0.5F, (var40.stepSound.getVolume() + 1.0F) / 2.0F, var40.stepSound.getPitch() * 0.8F);
2229                    }
2230    
2231                    this.mc.effectRenderer.addBlockDestroyEffects(par3, par4, par5, par6 & 4095, par6 >> 12 & 255);
2232                    break;
2233                case 2002:
2234                    var8 = (double)par3;
2235                    var10 = (double)par4;
2236                    var12 = (double)par5;
2237                    var14 = "iconcrack_" + Item.potion.shiftedIndex;
2238    
2239                    for (var15 = 0; var15 < 8; ++var15)
2240                    {
2241                        this.spawnParticle(var14, var8, var10, var12, var7.nextGaussian() * 0.15D, var7.nextDouble() * 0.2D, var7.nextGaussian() * 0.15D);
2242                    }
2243    
2244                    var15 = Item.potion.getColorFromDamage(par6);
2245                    float var16 = (float)(var15 >> 16 & 255) / 255.0F;
2246                    float var17 = (float)(var15 >> 8 & 255) / 255.0F;
2247                    float var18 = (float)(var15 >> 0 & 255) / 255.0F;
2248                    String var19 = "spell";
2249    
2250                    if (Item.potion.isEffectInstant(par6))
2251                    {
2252                        var19 = "instantSpell";
2253                    }
2254    
2255                    for (var20 = 0; var20 < 100; ++var20)
2256                    {
2257                        var39 = var7.nextDouble() * 4.0D;
2258                        var23 = var7.nextDouble() * Math.PI * 2.0D;
2259                        var25 = Math.cos(var23) * var39;
2260                        var27 = 0.01D + var7.nextDouble() * 0.5D;
2261                        var29 = Math.sin(var23) * var39;
2262                        EntityFX var31 = this.func_72726_b(var19, var8 + var25 * 0.1D, var10 + 0.3D, var12 + var29 * 0.1D, var25, var27, var29);
2263    
2264                        if (var31 != null)
2265                        {
2266                            float var32 = 0.75F + var7.nextFloat() * 0.25F;
2267                            var31.setRBGColorF(var16 * var32, var17 * var32, var18 * var32);
2268                            var31.multiplyVelocity((float)var39);
2269                        }
2270                    }
2271    
2272                    this.theWorld.playSound((double)par3 + 0.5D, (double)par4 + 0.5D, (double)par5 + 0.5D, "random.glass", 1.0F, this.theWorld.rand.nextFloat() * 0.1F + 0.9F);
2273                    break;
2274                case 2003:
2275                    var8 = (double)par3 + 0.5D;
2276                    var10 = (double)par4;
2277                    var12 = (double)par5 + 0.5D;
2278                    var14 = "iconcrack_" + Item.eyeOfEnder.shiftedIndex;
2279    
2280                    for (var15 = 0; var15 < 8; ++var15)
2281                    {
2282                        this.spawnParticle(var14, var8, var10, var12, var7.nextGaussian() * 0.15D, var7.nextDouble() * 0.2D, var7.nextGaussian() * 0.15D);
2283                    }
2284    
2285                    for (double var36 = 0.0D; var36 < (Math.PI * 2D); var36 += 0.15707963267948966D)
2286                    {
2287                        this.spawnParticle("portal", var8 + Math.cos(var36) * 5.0D, var10 - 0.4D, var12 + Math.sin(var36) * 5.0D, Math.cos(var36) * -5.0D, 0.0D, Math.sin(var36) * -5.0D);
2288                        this.spawnParticle("portal", var8 + Math.cos(var36) * 5.0D, var10 - 0.4D, var12 + Math.sin(var36) * 5.0D, Math.cos(var36) * -7.0D, 0.0D, Math.sin(var36) * -7.0D);
2289                    }
2290    
2291                    return;
2292                case 2004:
2293                    for (int var21 = 0; var21 < 20; ++var21)
2294                    {
2295                        double var22 = (double)par3 + 0.5D + ((double)this.theWorld.rand.nextFloat() - 0.5D) * 2.0D;
2296                        double var24 = (double)par4 + 0.5D + ((double)this.theWorld.rand.nextFloat() - 0.5D) * 2.0D;
2297                        double var26 = (double)par5 + 0.5D + ((double)this.theWorld.rand.nextFloat() - 0.5D) * 2.0D;
2298                        this.theWorld.spawnParticle("smoke", var22, var24, var26, 0.0D, 0.0D, 0.0D);
2299                        this.theWorld.spawnParticle("flame", var22, var24, var26, 0.0D, 0.0D, 0.0D);
2300                    }
2301            }
2302        }
2303    
2304        /**
2305         * Starts (or continues) destroying a block with given ID at the given coordinates for the given partially destroyed
2306         * value
2307         */
2308        public void destroyBlockPartially(int par1, int par2, int par3, int par4, int par5)
2309        {
2310            if (par5 >= 0 && par5 < 10)
2311            {
2312                DestroyBlockProgress var6 = (DestroyBlockProgress)this.damagedBlocks.get(Integer.valueOf(par1));
2313    
2314                if (var6 == null || var6.getPartialBlockX() != par2 || var6.getPartialBlockY() != par3 || var6.getPartialBlockZ() != par4)
2315                {
2316                    var6 = new DestroyBlockProgress(par1, par2, par3, par4);
2317                    this.damagedBlocks.put(Integer.valueOf(par1), var6);
2318                }
2319    
2320                var6.setPartialBlockDamage(par5);
2321                var6.setCloudUpdateTick(this.cloudTickCounter);
2322            }
2323            else
2324            {
2325                this.damagedBlocks.remove(Integer.valueOf(par1));
2326            }
2327        }
2328    }