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