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 return this.chunkArray[var4][var5].getChunkBlockTileEntity(par1 & 15, par2, par3 & 15); 095 } 096 097 @SideOnly(Side.CLIENT) 098 public float getBrightness(int par1, int par2, int par3, int par4) 099 { 100 int var5 = this.getLightValue(par1, par2, par3); 101 102 if (var5 < par4) 103 { 104 var5 = par4; 105 } 106 107 return this.worldObj.provider.lightBrightnessTable[var5]; 108 } 109 110 @SideOnly(Side.CLIENT) 111 112 /** 113 * Any Light rendered on a 1.8 Block goes through here 114 */ 115 public int getLightBrightnessForSkyBlocks(int par1, int par2, int par3, int par4) 116 { 117 int var5 = this.getSkyBlockTypeBrightness(EnumSkyBlock.Sky, par1, par2, par3); 118 int var6 = this.getSkyBlockTypeBrightness(EnumSkyBlock.Block, par1, par2, par3); 119 120 if (var6 < par4) 121 { 122 var6 = par4; 123 } 124 125 return var5 << 20 | var6 << 4; 126 } 127 128 @SideOnly(Side.CLIENT) 129 130 /** 131 * Returns how bright the block is shown as which is the block's light value looked up in a lookup table (light 132 * values aren't linear for brightness). Args: x, y, z 133 */ 134 public float getLightBrightness(int par1, int par2, int par3) 135 { 136 return this.worldObj.provider.lightBrightnessTable[this.getLightValue(par1, par2, par3)]; 137 } 138 139 @SideOnly(Side.CLIENT) 140 141 /** 142 * Gets the light value of the specified block coords. Args: x, y, z 143 */ 144 public int getLightValue(int par1, int par2, int par3) 145 { 146 return this.getLightValueExt(par1, par2, par3, true); 147 } 148 149 @SideOnly(Side.CLIENT) 150 151 /** 152 * Get light value with flag 153 */ 154 public int getLightValueExt(int par1, int par2, int par3, boolean par4) 155 { 156 if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 <= 30000000) 157 { 158 int var5; 159 int var6; 160 161 if (par4) 162 { 163 var5 = this.getBlockId(par1, par2, par3); 164 165 if (var5 == Block.stoneSingleSlab.blockID || var5 == Block.woodSingleSlab.blockID || var5 == Block.tilledField.blockID || var5 == Block.stairCompactPlanks.blockID || var5 == Block.stairCompactCobblestone.blockID) 166 { 167 var6 = this.getLightValueExt(par1, par2 + 1, par3, false); 168 int var7 = this.getLightValueExt(par1 + 1, par2, par3, false); 169 int var8 = this.getLightValueExt(par1 - 1, par2, par3, false); 170 int var9 = this.getLightValueExt(par1, par2, par3 + 1, false); 171 int var10 = this.getLightValueExt(par1, par2, par3 - 1, false); 172 173 if (var7 > var6) 174 { 175 var6 = var7; 176 } 177 178 if (var8 > var6) 179 { 180 var6 = var8; 181 } 182 183 if (var9 > var6) 184 { 185 var6 = var9; 186 } 187 188 if (var10 > var6) 189 { 190 var6 = var10; 191 } 192 193 return var6; 194 } 195 } 196 197 if (par2 < 0) 198 { 199 return 0; 200 } 201 else if (par2 >= 256) 202 { 203 var5 = 15 - this.worldObj.skylightSubtracted; 204 205 if (var5 < 0) 206 { 207 var5 = 0; 208 } 209 210 return var5; 211 } 212 else 213 { 214 var5 = (par1 >> 4) - this.chunkX; 215 var6 = (par3 >> 4) - this.chunkZ; 216 return this.chunkArray[var5][var6].getBlockLightValue(par1 & 15, par2, par3 & 15, this.worldObj.skylightSubtracted); 217 } 218 } 219 else 220 { 221 return 15; 222 } 223 } 224 225 /** 226 * Returns the block metadata at coords x,y,z 227 */ 228 public int getBlockMetadata(int par1, int par2, int par3) 229 { 230 if (par2 < 0) 231 { 232 return 0; 233 } 234 else if (par2 >= 256) 235 { 236 return 0; 237 } 238 else 239 { 240 int var4 = (par1 >> 4) - this.chunkX; 241 int var5 = (par3 >> 4) - this.chunkZ; 242 return this.chunkArray[var4][var5].getBlockMetadata(par1 & 15, par2, par3 & 15); 243 } 244 } 245 246 /** 247 * Returns the block's material. 248 */ 249 public Material getBlockMaterial(int par1, int par2, int par3) 250 { 251 int var4 = this.getBlockId(par1, par2, par3); 252 return var4 == 0 ? Material.air : Block.blocksList[var4].blockMaterial; 253 } 254 255 @SideOnly(Side.CLIENT) 256 257 /** 258 * Gets the biome for a given set of x/z coordinates 259 */ 260 public BiomeGenBase getBiomeGenForCoords(int par1, int par2) 261 { 262 return this.worldObj.getBiomeGenForCoords(par1, par2); 263 } 264 265 @SideOnly(Side.CLIENT) 266 267 /** 268 * Returns true if the block at the specified coordinates is an opaque cube. Args: x, y, z 269 */ 270 public boolean isBlockOpaqueCube(int par1, int par2, int par3) 271 { 272 Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; 273 return var4 == null ? false : var4.isOpaqueCube(); 274 } 275 276 /** 277 * Indicate if a material is a normal solid opaque cube. 278 */ 279 public boolean isBlockNormalCube(int par1, int par2, int par3) 280 { 281 Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; 282 return var4 == null ? false : var4.blockMaterial.blocksMovement() && var4.renderAsNormalBlock(); 283 } 284 285 @SideOnly(Side.CLIENT) 286 287 /** 288 * Returns true if the block at the given coordinate has a solid (buildable) top surface. 289 */ 290 public boolean doesBlockHaveSolidTopSurface(int par1, int par2, int par3) 291 { 292 Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; 293 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))); 294 } 295 296 @SideOnly(Side.CLIENT) 297 298 /** 299 * Returns true if the block at the specified coordinates is empty 300 */ 301 public boolean isAirBlock(int par1, int par2, int par3) 302 { 303 Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; 304 return var4 == null; 305 } 306 307 @SideOnly(Side.CLIENT) 308 309 /** 310 * Brightness for SkyBlock.Sky is clear white and (through color computing it is assumed) DEPENDENT ON DAYTIME. 311 * Brightness for SkyBlock.Block is yellowish and independent. 312 */ 313 public int getSkyBlockTypeBrightness(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) 314 { 315 if (par3 < 0) 316 { 317 par3 = 0; 318 } 319 320 if (par3 >= 256) 321 { 322 par3 = 255; 323 } 324 325 if (par3 >= 0 && par3 < 256 && par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 <= 30000000) 326 { 327 int var5; 328 int var6; 329 330 if (Block.useNeighborBrightness[this.getBlockId(par2, par3, par4)]) 331 { 332 var5 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3 + 1, par4); 333 var6 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2 + 1, par3, par4); 334 int var7 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2 - 1, par3, par4); 335 int var8 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3, par4 + 1); 336 int var9 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3, par4 - 1); 337 338 if (var6 > var5) 339 { 340 var5 = var6; 341 } 342 343 if (var7 > var5) 344 { 345 var5 = var7; 346 } 347 348 if (var8 > var5) 349 { 350 var5 = var8; 351 } 352 353 if (var9 > var5) 354 { 355 var5 = var9; 356 } 357 358 return var5; 359 } 360 else 361 { 362 var5 = (par2 >> 4) - this.chunkX; 363 var6 = (par4 >> 4) - this.chunkZ; 364 return this.chunkArray[var5][var6].getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15); 365 } 366 } 367 else 368 { 369 return par1EnumSkyBlock.defaultLightValue; 370 } 371 } 372 373 @SideOnly(Side.CLIENT) 374 375 /** 376 * is only used on stairs and tilled fields 377 */ 378 public int getSpecialBlockBrightness(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) 379 { 380 if (par3 < 0) 381 { 382 par3 = 0; 383 } 384 385 if (par3 >= 256) 386 { 387 par3 = 255; 388 } 389 390 if (par3 >= 0 && par3 < 256 && par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 <= 30000000) 391 { 392 int var5 = (par2 >> 4) - this.chunkX; 393 int var6 = (par4 >> 4) - this.chunkZ; 394 return this.chunkArray[var5][var6].getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15); 395 } 396 else 397 { 398 return par1EnumSkyBlock.defaultLightValue; 399 } 400 } 401 402 @SideOnly(Side.CLIENT) 403 404 /** 405 * Returns current world height. 406 */ 407 public int getHeight() 408 { 409 return 256; 410 } 411 }