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