    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}