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