001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 import java.util.Iterator; 006 import java.util.Random; 007 import static net.minecraftforge.common.ForgeDirection.*; 008 009 public class BlockChest extends BlockContainer 010 { 011 private Random random = new Random(); 012 013 protected BlockChest(int par1) 014 { 015 super(par1, Material.wood); 016 this.blockIndexInTexture = 26; 017 this.setCreativeTab(CreativeTabs.tabDecorations); 018 } 019 020 /** 021 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 022 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 023 */ 024 public boolean isOpaqueCube() 025 { 026 return false; 027 } 028 029 /** 030 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 031 */ 032 public boolean renderAsNormalBlock() 033 { 034 return false; 035 } 036 037 /** 038 * The type of render function that is called for this block 039 */ 040 public int getRenderType() 041 { 042 return 22; 043 } 044 045 /** 046 * Called whenever the block is added into the world. Args: world, x, y, z 047 */ 048 public void onBlockAdded(World par1World, int par2, int par3, int par4) 049 { 050 super.onBlockAdded(par1World, par2, par3, par4); 051 this.unifyAdjacentChests(par1World, par2, par3, par4); 052 int var5 = par1World.getBlockId(par2, par3, par4 - 1); 053 int var6 = par1World.getBlockId(par2, par3, par4 + 1); 054 int var7 = par1World.getBlockId(par2 - 1, par3, par4); 055 int var8 = par1World.getBlockId(par2 + 1, par3, par4); 056 057 if (var5 == this.blockID) 058 { 059 this.unifyAdjacentChests(par1World, par2, par3, par4 - 1); 060 } 061 062 if (var6 == this.blockID) 063 { 064 this.unifyAdjacentChests(par1World, par2, par3, par4 + 1); 065 } 066 067 if (var7 == this.blockID) 068 { 069 this.unifyAdjacentChests(par1World, par2 - 1, par3, par4); 070 } 071 072 if (var8 == this.blockID) 073 { 074 this.unifyAdjacentChests(par1World, par2 + 1, par3, par4); 075 } 076 } 077 078 /** 079 * Called when the block is placed in the world. 080 */ 081 public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving) 082 { 083 int var6 = par1World.getBlockId(par2, par3, par4 - 1); 084 int var7 = par1World.getBlockId(par2, par3, par4 + 1); 085 int var8 = par1World.getBlockId(par2 - 1, par3, par4); 086 int var9 = par1World.getBlockId(par2 + 1, par3, par4); 087 byte var10 = 0; 088 int var11 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; 089 090 if (var11 == 0) 091 { 092 var10 = 2; 093 } 094 095 if (var11 == 1) 096 { 097 var10 = 5; 098 } 099 100 if (var11 == 2) 101 { 102 var10 = 3; 103 } 104 105 if (var11 == 3) 106 { 107 var10 = 4; 108 } 109 110 if (var6 != this.blockID && var7 != this.blockID && var8 != this.blockID && var9 != this.blockID) 111 { 112 par1World.setBlockMetadataWithNotify(par2, par3, par4, var10); 113 } 114 else 115 { 116 if ((var6 == this.blockID || var7 == this.blockID) && (var10 == 4 || var10 == 5)) 117 { 118 if (var6 == this.blockID) 119 { 120 par1World.setBlockMetadataWithNotify(par2, par3, par4 - 1, var10); 121 } 122 else 123 { 124 par1World.setBlockMetadataWithNotify(par2, par3, par4 + 1, var10); 125 } 126 127 par1World.setBlockMetadataWithNotify(par2, par3, par4, var10); 128 } 129 130 if ((var8 == this.blockID || var9 == this.blockID) && (var10 == 2 || var10 == 3)) 131 { 132 if (var8 == this.blockID) 133 { 134 par1World.setBlockMetadataWithNotify(par2 - 1, par3, par4, var10); 135 } 136 else 137 { 138 par1World.setBlockMetadataWithNotify(par2 + 1, par3, par4, var10); 139 } 140 141 par1World.setBlockMetadataWithNotify(par2, par3, par4, var10); 142 } 143 } 144 } 145 146 /** 147 * Turns the adjacent chests to a double chest. 148 */ 149 public void unifyAdjacentChests(World par1World, int par2, int par3, int par4) 150 { 151 if (!par1World.isRemote) 152 { 153 int var5 = par1World.getBlockId(par2, par3, par4 - 1); 154 int var6 = par1World.getBlockId(par2, par3, par4 + 1); 155 int var7 = par1World.getBlockId(par2 - 1, par3, par4); 156 int var8 = par1World.getBlockId(par2 + 1, par3, par4); 157 boolean var9 = true; 158 int var10; 159 int var11; 160 boolean var12; 161 byte var13; 162 int var14; 163 164 if (var5 != this.blockID && var6 != this.blockID) 165 { 166 if (var7 != this.blockID && var8 != this.blockID) 167 { 168 var13 = 3; 169 170 if (Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var6]) 171 { 172 var13 = 3; 173 } 174 175 if (Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var5]) 176 { 177 var13 = 2; 178 } 179 180 if (Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var8]) 181 { 182 var13 = 5; 183 } 184 185 if (Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var7]) 186 { 187 var13 = 4; 188 } 189 } 190 else 191 { 192 var10 = par1World.getBlockId(var7 == this.blockID ? par2 - 1 : par2 + 1, par3, par4 - 1); 193 var11 = par1World.getBlockId(var7 == this.blockID ? par2 - 1 : par2 + 1, par3, par4 + 1); 194 var13 = 3; 195 var12 = true; 196 197 if (var7 == this.blockID) 198 { 199 var14 = par1World.getBlockMetadata(par2 - 1, par3, par4); 200 } 201 else 202 { 203 var14 = par1World.getBlockMetadata(par2 + 1, par3, par4); 204 } 205 206 if (var14 == 2) 207 { 208 var13 = 2; 209 } 210 211 if ((Block.opaqueCubeLookup[var5] || Block.opaqueCubeLookup[var10]) && !Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var11]) 212 { 213 var13 = 3; 214 } 215 216 if ((Block.opaqueCubeLookup[var6] || Block.opaqueCubeLookup[var11]) && !Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var10]) 217 { 218 var13 = 2; 219 } 220 } 221 } 222 else 223 { 224 var10 = par1World.getBlockId(par2 - 1, par3, var5 == this.blockID ? par4 - 1 : par4 + 1); 225 var11 = par1World.getBlockId(par2 + 1, par3, var5 == this.blockID ? par4 - 1 : par4 + 1); 226 var13 = 5; 227 var12 = true; 228 229 if (var5 == this.blockID) 230 { 231 var14 = par1World.getBlockMetadata(par2, par3, par4 - 1); 232 } 233 else 234 { 235 var14 = par1World.getBlockMetadata(par2, par3, par4 + 1); 236 } 237 238 if (var14 == 4) 239 { 240 var13 = 4; 241 } 242 243 if ((Block.opaqueCubeLookup[var7] || Block.opaqueCubeLookup[var10]) && !Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var11]) 244 { 245 var13 = 5; 246 } 247 248 if ((Block.opaqueCubeLookup[var8] || Block.opaqueCubeLookup[var11]) && !Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var10]) 249 { 250 var13 = 4; 251 } 252 } 253 254 par1World.setBlockMetadataWithNotify(par2, par3, par4, var13); 255 } 256 } 257 258 @SideOnly(Side.CLIENT) 259 260 /** 261 * Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side 262 */ 263 public int getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 264 { 265 return 4; 266 } 267 268 /** 269 * Returns the block texture based on the side being looked at. Args: side 270 */ 271 public int getBlockTextureFromSide(int par1) 272 { 273 return 4; 274 } 275 276 /** 277 * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z 278 */ 279 public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) 280 { 281 int var5 = 0; 282 283 if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID) 284 { 285 ++var5; 286 } 287 288 if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID) 289 { 290 ++var5; 291 } 292 293 if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID) 294 { 295 ++var5; 296 } 297 298 if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID) 299 { 300 ++var5; 301 } 302 303 return var5 > 1 ? false : (this.isThereANeighborChest(par1World, par2 - 1, par3, par4) ? false : (this.isThereANeighborChest(par1World, par2 + 1, par3, par4) ? false : (this.isThereANeighborChest(par1World, par2, par3, par4 - 1) ? false : !this.isThereANeighborChest(par1World, par2, par3, par4 + 1)))); 304 } 305 306 /** 307 * Checks the neighbor blocks to see if there is a chest there. Args: world, x, y, z 308 */ 309 private boolean isThereANeighborChest(World par1World, int par2, int par3, int par4) 310 { 311 return par1World.getBlockId(par2, par3, par4) != this.blockID ? false : (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID ? true : (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID ? true : (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID ? true : par1World.getBlockId(par2, par3, par4 + 1) == this.blockID))); 312 } 313 314 /** 315 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 316 * their own) Args: x, y, z, neighbor blockID 317 */ 318 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 319 { 320 super.onNeighborBlockChange(par1World, par2, par3, par4, par5); 321 TileEntityChest var6 = (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4); 322 323 if (var6 != null) 324 { 325 var6.updateContainingBlockInfo(); 326 } 327 } 328 329 /** 330 * ejects contained items into the world, and notifies neighbours of an update, as appropriate 331 */ 332 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) 333 { 334 TileEntityChest var7 = (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4); 335 336 if (var7 != null) 337 { 338 for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) 339 { 340 ItemStack var9 = var7.getStackInSlot(var8); 341 342 if (var9 != null) 343 { 344 float var10 = this.random.nextFloat() * 0.8F + 0.1F; 345 float var11 = this.random.nextFloat() * 0.8F + 0.1F; 346 EntityItem var14; 347 348 for (float var12 = this.random.nextFloat() * 0.8F + 0.1F; var9.stackSize > 0; par1World.spawnEntityInWorld(var14)) 349 { 350 int var13 = this.random.nextInt(21) + 10; 351 352 if (var13 > var9.stackSize) 353 { 354 var13 = var9.stackSize; 355 } 356 357 var9.stackSize -= var13; 358 var14 = new EntityItem(par1World, (double)((float)par2 + var10), (double)((float)par3 + var11), (double)((float)par4 + var12), new ItemStack(var9.itemID, var13, var9.getItemDamage())); 359 float var15 = 0.05F; 360 var14.motionX = (double)((float)this.random.nextGaussian() * var15); 361 var14.motionY = (double)((float)this.random.nextGaussian() * var15 + 0.2F); 362 var14.motionZ = (double)((float)this.random.nextGaussian() * var15); 363 364 if (var9.hasTagCompound()) 365 { 366 var14.item.setTagCompound((NBTTagCompound)var9.getTagCompound().copy()); 367 } 368 } 369 } 370 } 371 } 372 373 super.breakBlock(par1World, par2, par3, par4, par5, par6); 374 } 375 376 /** 377 * Called upon block activation (right click on the block.) 378 */ 379 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) 380 { 381 Object var10 = (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4); 382 383 if (var10 == null) 384 { 385 return true; 386 } 387 else if (par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN)) 388 { 389 return true; 390 } 391 else if (isOcelotBlockingChest(par1World, par2, par3, par4)) 392 { 393 return true; 394 } 395 else if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID && (par1World.isBlockSolidOnSide(par2 - 1, par3 + 1, par4, DOWN) || isOcelotBlockingChest(par1World, par2 - 1, par3, par4))) 396 { 397 return true; 398 } 399 else if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID && (par1World.isBlockSolidOnSide(par2 + 1, par3 + 1, par4, DOWN) || isOcelotBlockingChest(par1World, par2 + 1, par3, par4))) 400 { 401 return true; 402 } 403 else if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID && (par1World.isBlockSolidOnSide(par2, par3 + 1, par4 - 1, DOWN) || isOcelotBlockingChest(par1World, par2, par3, par4 - 1))) 404 { 405 return true; 406 } 407 else if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID && (par1World.isBlockSolidOnSide(par2, par3 + 1, par4 + 1, DOWN) || isOcelotBlockingChest(par1World, par2, par3, par4 + 1))) 408 { 409 return true; 410 } 411 else 412 { 413 if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID) 414 { 415 var10 = new InventoryLargeChest("container.chestDouble", (TileEntityChest)par1World.getBlockTileEntity(par2 - 1, par3, par4), (IInventory)var10); 416 } 417 418 if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID) 419 { 420 var10 = new InventoryLargeChest("container.chestDouble", (IInventory)var10, (TileEntityChest)par1World.getBlockTileEntity(par2 + 1, par3, par4)); 421 } 422 423 if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID) 424 { 425 var10 = new InventoryLargeChest("container.chestDouble", (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4 - 1), (IInventory)var10); 426 } 427 428 if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID) 429 { 430 var10 = new InventoryLargeChest("container.chestDouble", (IInventory)var10, (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4 + 1)); 431 } 432 433 if (par1World.isRemote) 434 { 435 return true; 436 } 437 else 438 { 439 par5EntityPlayer.displayGUIChest((IInventory)var10); 440 return true; 441 } 442 } 443 } 444 445 /** 446 * Returns a new instance of a block's tile entity class. Called on placing the block. 447 */ 448 public TileEntity createNewTileEntity(World par1World) 449 { 450 return new TileEntityChest(); 451 } 452 453 /** 454 * Looks for a sitting ocelot within certain bounds. Such an ocelot is considered to be blocking access to the 455 * chest. 456 */ 457 public static boolean isOcelotBlockingChest(World par0World, int par1, int par2, int par3) 458 { 459 Iterator var4 = par0World.getEntitiesWithinAABB(EntityOcelot.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)par1, (double)(par2 + 1), (double)par3, (double)(par1 + 1), (double)(par2 + 2), (double)(par3 + 1))).iterator(); 460 EntityOcelot var6; 461 462 do 463 { 464 if (!var4.hasNext()) 465 { 466 return false; 467 } 468 469 EntityOcelot var5 = (EntityOcelot)var4.next(); 470 var6 = (EntityOcelot)var5; 471 } 472 while (!var6.isSitting()); 473 474 return true; 475 } 476 }