    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005
    006    public class ChunkCache implements IBlockAccess
    007    {
    008        private int chunkX;
    009        private int chunkZ;
    010        private Chunk[][] chunkArray;
    011
    012        /** set by !chunk.getAreLevelsEmpty */
    013        private boolean hasExtendedLevels;
    014
    015        /** Reference to the World object. */
    016        private World worldObj;
    017
    018        public ChunkCache(World par1World, int par2, int par3, int par4, int par5, int par6, int par7)
    019        {
    020            this.worldObj = par1World;
    021            this.chunkX = par2 >> 4;
    022            this.chunkZ = par4 >> 4;
    023            int var8 = par5 >> 4;
    024            int var9 = par7 >> 4;
    025            this.chunkArray = new Chunk[var8 - this.chunkX + 1][var9 - this.chunkZ + 1];
    026            this.hasExtendedLevels = true;
    027
    028            for (int var10 = this.chunkX; var10 <= var8; ++var10)
    029            {
    030                for (int var11 = this.chunkZ; var11 <= var9; ++var11)
    031                {
    032                    Chunk var12 = par1World.getChunkFromChunkCoords(var10, var11);
    033
    034                    if (var12 != null)
    035                    {
    036                        this.chunkArray[var10 - this.chunkX][var11 - this.chunkZ] = var12;
    037
    038                        if (!var12.getAreLevelsEmpty(par3, par6))
    039                        {
    040                            this.hasExtendedLevels = false;
    041                        }
    042                    }
    043                }
    044            }
    045        }
    046
    047        @SideOnly(Side.CLIENT)
    048
    049        /**
    050         * set by !chunk.getAreLevelsEmpty
    051         */
    052        public boolean extendedLevelsInChunkCache()
    053        {
    054            return this.hasExtendedLevels;
    055        }
    056
    057        /**
    058         * Returns the block ID at coords x,y,z
    059         */
    060        public int getBlockId(int par1, int par2, int par3)
    061        {
    062            if (par2 < 0)
    063            {
    064                return 0;
    065            }
    066            else if (par2 >= 256)
    067            {
    068                return 0;
    069            }
    070            else
    071            {
    072                int var4 = (par1 >> 4) - this.chunkX;
    073                int var5 = (par3 >> 4) - this.chunkZ;
    074
    075                if (var4 >= 0 && var4 < this.chunkArray.length && var5 >= 0 && var5 < this.chunkArray[var4].length)
    076                {
    077                    Chunk var6 = this.chunkArray[var4][var5];
    078                    return var6 == null ? 0 : var6.getBlockID(par1 & 15, par2, par3 & 15);
    079                }
    080                else
    081                {
    082                    return 0;
    083                }
    084            }
    085        }
    086
    087        /**
    088         * Returns the TileEntity associated with a given block in X,Y,Z coordinates, or null if no TileEntity exists
    089         */
    090        public TileEntity getBlockTileEntity(int par1, int par2, int par3)
    091        {
    092            int var4 = (par1 >> 4) - this.chunkX;
    093            int var5 = (par3 >> 4) - this.chunkZ;
    094            if (var4 >= 0 && var4 < this.chunkArray.length && var5 >= 0 && var5 < this.chunkArray[var4].length)
    095            {
    096                Chunk var6 = this.chunkArray[var4][var5];
    097                return var6 == null ? null : var6.getChunkBlockTileEntity(par1 & 15, par2, par3 & 15);
    098            }
    099            else
    100            {
    101                return null;
    102            }
    103        }
    104
    105        @SideOnly(Side.CLIENT)
    106        public float getBrightness(int par1, int par2, int par3, int par4)
    107        {
    108            int var5 = this.getLightValue(par1, par2, par3);
    109
    110            if (var5 < par4)
    111            {
    112                var5 = par4;
    113            }
    114
    115            return this.worldObj.provider.lightBrightnessTable[var5];
    116        }
    117
    118        @SideOnly(Side.CLIENT)
    119
    120        /**
    121         * Any Light rendered on a 1.8 Block goes through here
    122         */
    123        public int getLightBrightnessForSkyBlocks(int par1, int par2, int par3, int par4)
    124        {
    125            int var5 = this.getSkyBlockTypeBrightness(EnumSkyBlock.Sky, par1, par2, par3);
    126            int var6 = this.getSkyBlockTypeBrightness(EnumSkyBlock.Block, par1, par2, par3);
    127
    128            if (var6 < par4)
    129            {
    130                var6 = par4;
    131            }
    132
    133            return var5 << 20 | var6 << 4;
    134        }
    135
    136        @SideOnly(Side.CLIENT)
    137
    138        /**
    139         * Returns how bright the block is shown as which is the block's light value looked up in a lookup table (light
    140         * values aren't linear for brightness). Args: x, y, z
    141         */
    142        public float getLightBrightness(int par1, int par2, int par3)
    143        {
    144            return this.worldObj.provider.lightBrightnessTable[this.getLightValue(par1, par2, par3)];
    145        }
    146
    147        @SideOnly(Side.CLIENT)
    148
    149        /**
    150         * Gets the light value of the specified block coords. Args: x, y, z
    151         */
    152        public int getLightValue(int par1, int par2, int par3)
    153        {
    154            return this.getLightValueExt(par1, par2, par3, true);
    155        }
    156
    157        @SideOnly(Side.CLIENT)
    158
    159        /**
    160         * Get light value with flag
    161         */
    162        public int getLightValueExt(int par1, int par2, int par3, boolean par4)
    163        {
    164            if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 <= 30000000)
    165            {
    166                int var5;
    167                int var6;
    168
    169                if (par4)
    170                {
    171                    var5 = this.getBlockId(par1, par2, par3);
    172
    173                    if (var5 == Block.stoneSingleSlab.blockID || var5 == Block.woodSingleSlab.blockID || var5 == Block.tilledField.blockID || var5 == Block.stairCompactPlanks.blockID || var5 == Block.stairCompactCobblestone.blockID)
    174                    {
    175                        var6 = this.getLightValueExt(par1, par2 + 1, par3, false);
    176                        int var7 = this.getLightValueExt(par1 + 1, par2, par3, false);
    177                        int var8 = this.getLightValueExt(par1 - 1, par2, par3, false);
    178                        int var9 = this.getLightValueExt(par1, par2, par3 + 1, false);
    179                        int var10 = this.getLightValueExt(par1, par2, par3 - 1, false);
    180
    181                        if (var7 > var6)
    182                        {
    183                            var6 = var7;
    184                        }
    185
    186                        if (var8 > var6)
    187                        {
    188                            var6 = var8;
    189                        }
    190
    191                        if (var9 > var6)
    192                        {
    193                            var6 = var9;
    194                        }
    195
    196                        if (var10 > var6)
    197                        {
    198                            var6 = var10;
    199                        }
    200
    201                        return var6;
    202                    }
    203                }
    204
    205                if (par2 < 0)
    206                {
    207                    return 0;
    208                }
    209                else if (par2 >= 256)
    210                {
    211                    var5 = 15 - this.worldObj.skylightSubtracted;
    212
    213                    if (var5 < 0)
    214                    {
    215                        var5 = 0;
    216                    }
    217
    218                    return var5;
    219                }
    220                else
    221                {
    222                    var5 = (par1 >> 4) - this.chunkX;
    223                    var6 = (par3 >> 4) - this.chunkZ;
    224                    return this.chunkArray[var5][var6].getBlockLightValue(par1 & 15, par2, par3 & 15, this.worldObj.skylightSubtracted);
    225                }
    226            }
    227            else
    228            {
    229                return 15;
    230            }
    231        }
    232
    233        /**
    234         * Returns the block metadata at coords x,y,z
    235         */
    236        public int getBlockMetadata(int par1, int par2, int par3)
    237        {
    238            if (par2 < 0)
    239            {
    240                return 0;
    241            }
    242            else if (par2 >= 256)
    243            {
    244                return 0;
    245            }
    246            else
    247            {
    248                int var4 = (par1 >> 4) - this.chunkX;
    249                int var5 = (par3 >> 4) - this.chunkZ;
    250                if (var4 >= 0 && var4 < this.chunkArray.length && var5 >= 0 && var5 < this.chunkArray[var4].length)
    251                {
    252                    Chunk var6 = this.chunkArray[var4][var5];
    253                    return var6 == null ? 0 : var6.getBlockMetadata(par1 & 15, par2, par3 & 15);
    254                }
    255                return 0;
    256            }
    257        }
    258
    259        /**
    260         * Returns the block's material.
    261         */
    262        public Material getBlockMaterial(int par1, int par2, int par3)
    263        {
    264            int var4 = this.getBlockId(par1, par2, par3);
    265            return var4 == 0 ? Material.air : Block.blocksList[var4].blockMaterial;
    266        }
    267
    268        @SideOnly(Side.CLIENT)
    269
    270        /**
    271         * Gets the biome for a given set of x/z coordinates
    272         */
    273        public BiomeGenBase getBiomeGenForCoords(int par1, int par2)
    274        {
    275            return this.worldObj.getBiomeGenForCoords(par1, par2);
    276        }
    277
    278        @SideOnly(Side.CLIENT)
    279
    280        /**
    281         * Returns true if the block at the specified coordinates is an opaque cube. Args: x, y, z
    282         */
    283        public boolean isBlockOpaqueCube(int par1, int par2, int par3)
    284        {
    285            Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)];
    286            return var4 == null ? false : var4.isOpaqueCube();
    287        }
    288
    289        /**
    290         * Indicate if a material is a normal solid opaque cube.
    291         */
    292        public boolean isBlockNormalCube(int par1, int par2, int par3)
    293        {
    294            Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)];
    295            return var4 == null ? false : var4.blockMaterial.blocksMovement() && var4.renderAsNormalBlock();
    296        }
    297
    298        @SideOnly(Side.CLIENT)
    299
    300        /**
    301         * Returns true if the block at the given coordinate has a solid (buildable) top surface.
    302         */
    303        public boolean doesBlockHaveSolidTopSurface(int par1, int par2, int par3)
    304        {
    305            Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)];
    306            return var4 == null ? false : (var4.blockMaterial.isOpaque() && var4.renderAsNormalBlock() ? true : (var4 instanceof BlockStairs ? (this.getBlockMetadata(par1, par2, par3) & 4) == 4 : (var4 instanceof BlockHalfSlab ? (this.getBlockMetadata(par1, par2, par3) & 8) == 8 : false)));
    307        }
    308
    309        /**
    310         * Return the Vec3Pool object for this world.
    311         */
    312        public Vec3Pool getWorldVec3Pool()
    313        {
    314            return this.worldObj.getWorldVec3Pool();
    315        }
    316
    317        @SideOnly(Side.CLIENT)
    318
    319        /**
    320         * Returns true if the block at the specified coordinates is empty
    321         */
    322        public boolean isAirBlock(int par1, int par2, int par3)
    323        {
    324            Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)];
    325            return var4 == null;
    326        }
    327
    328        @SideOnly(Side.CLIENT)
    329
    330        /**
    331         * Brightness for SkyBlock.Sky is clear white and (through color computing it is assumed) DEPENDENT ON DAYTIME.
    332         * Brightness for SkyBlock.Block is yellowish and independent.
    333         */
    334        public int getSkyBlockTypeBrightness(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4)
    335        {
    336            if (par3 < 0)
    337            {
    338                par3 = 0;
    339            }
    340
    341            if (par3 >= 256)
    342            {
    343                par3 = 255;
    344            }
    345
    346            if (par3 >= 0 && par3 < 256 && par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 <= 30000000)
    347            {
    348                int var5;
    349                int var6;
    350
    351                if (Block.useNeighborBrightness[this.getBlockId(par2, par3, par4)])
    352                {
    353                    var5 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3 + 1, par4);
    354                    var6 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2 + 1, par3, par4);
    355                    int var7 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2 - 1, par3, par4);
    356                    int var8 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3, par4 + 1);
    357                    int var9 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3, par4 - 1);
    358
    359                    if (var6 > var5)
    360                    {
    361                        var5 = var6;
    362                    }
    363
    364                    if (var7 > var5)
    365                    {
    366                        var5 = var7;
    367                    }
    368
    369                    if (var8 > var5)
    370                    {
    371                        var5 = var8;
    372                    }
    373
    374                    if (var9 > var5)
    375                    {
    376                        var5 = var9;
    377                    }
    378
    379                    return var5;
    380                }
    381                else
    382                {
    383                    var5 = (par2 >> 4) - this.chunkX;
    384                    var6 = (par4 >> 4) - this.chunkZ;
    385                    return this.chunkArray[var5][var6].getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15);
    386                }
    387            }
    388            else
    389            {
    390                return par1EnumSkyBlock.defaultLightValue;
    391            }
    392        }
    393
    394        @SideOnly(Side.CLIENT)
    395
    396        /**
    397         * is only used on stairs and tilled fields
    398         */
    399        public int getSpecialBlockBrightness(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4)
    400        {
    401            if (par3 < 0)
    402            {
    403                par3 = 0;
    404            }
    405
    406            if (par3 >= 256)
    407            {
    408                par3 = 255;
    409            }
    410
    411            if (par3 >= 0 && par3 < 256 && par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 <= 30000000)
    412            {
    413                int var5 = (par2 >> 4) - this.chunkX;
    414                int var6 = (par4 >> 4) - this.chunkZ;
    415                return this.chunkArray[var5][var6].getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15);
    416            }
    417            else
    418            {
    419                return par1EnumSkyBlock.defaultLightValue;
    420            }
    421        }
    422
    423        @SideOnly(Side.CLIENT)
    424
    425        /**
    426         * Returns current world height.
    427         */
    428        public int getHeight()
    429        {
    430            return 256;
    431        }
    432
    433        /**
    434         * Is this block powering in the specified direction Args: x, y, z, direction
    435         */
    436        public boolean isBlockProvidingPowerTo(int par1, int par2, int par3, int par4)
    437        {
    438            int var5 = this.getBlockId(par1, par2, par3);
    439            return var5 == 0 ? false : Block.blocksList[var5].isIndirectlyPoweringTo(this, par1, par2, par3, par4);
    440        }
    441    }