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