    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        @SideOnly(Side.CLIENT)
    310
    311        /**
    312         * Returns true if the block at the specified coordinates is empty
    313         */
    314        public boolean isAirBlock(int par1, int par2, int par3)
    315        {
    316            Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)];
    317            return var4 == null;
    318        }
    319
    320        @SideOnly(Side.CLIENT)
    321
    322        /**
    323         * Brightness for SkyBlock.Sky is clear white and (through color computing it is assumed) DEPENDENT ON DAYTIME.
    324         * Brightness for SkyBlock.Block is yellowish and independent.
    325         */
    326        public int getSkyBlockTypeBrightness(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4)
    327        {
    328            if (par3 < 0)
    329            {
    330                par3 = 0;
    331            }
    332
    333            if (par3 >= 256)
    334            {
    335                par3 = 255;
    336            }
    337
    338            if (par3 >= 0 && par3 < 256 && par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 <= 30000000)
    339            {
    340                int var5;
    341                int var6;
    342
    343                if (Block.useNeighborBrightness[this.getBlockId(par2, par3, par4)])
    344                {
    345                    var5 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3 + 1, par4);
    346                    var6 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2 + 1, par3, par4);
    347                    int var7 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2 - 1, par3, par4);
    348                    int var8 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3, par4 + 1);
    349                    int var9 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3, par4 - 1);
    350
    351                    if (var6 > var5)
    352                    {
    353                        var5 = var6;
    354                    }
    355
    356                    if (var7 > var5)
    357                    {
    358                        var5 = var7;
    359                    }
    360
    361                    if (var8 > var5)
    362                    {
    363                        var5 = var8;
    364                    }
    365
    366                    if (var9 > var5)
    367                    {
    368                        var5 = var9;
    369                    }
    370
    371                    return var5;
    372                }
    373                else
    374                {
    375                    var5 = (par2 >> 4) - this.chunkX;
    376                    var6 = (par4 >> 4) - this.chunkZ;
    377                    return this.chunkArray[var5][var6].getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15);
    378                }
    379            }
    380            else
    381            {
    382                return par1EnumSkyBlock.defaultLightValue;
    383            }
    384        }
    385
    386        @SideOnly(Side.CLIENT)
    387
    388        /**
    389         * is only used on stairs and tilled fields
    390         */
    391        public int getSpecialBlockBrightness(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4)
    392        {
    393            if (par3 < 0)
    394            {
    395                par3 = 0;
    396            }
    397
    398            if (par3 >= 256)
    399            {
    400                par3 = 255;
    401            }
    402
    403            if (par3 >= 0 && par3 < 256 && par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 <= 30000000)
    404            {
    405                int var5 = (par2 >> 4) - this.chunkX;
    406                int var6 = (par4 >> 4) - this.chunkZ;
    407                return this.chunkArray[var5][var6].getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15);
    408            }
    409            else
    410            {
    411                return par1EnumSkyBlock.defaultLightValue;
    412            }
    413        }
    414
    415        @SideOnly(Side.CLIENT)
    416
    417        /**
    418         * Returns current world height.
    419         */
    420        public int getHeight()
    421        {
    422            return 256;
    423        }
    424    }