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