001 package net.minecraft.src; 002 003 import java.util.Random; 004 005 import net.minecraftforge.common.ForgeDirection; 006 007 import static net.minecraftforge.common.ForgeDirection.*; 008 009 public class BlockButton extends Block 010 { 011 protected BlockButton(int par1, int par2) 012 { 013 super(par1, par2, Material.circuits); 014 this.setTickRandomly(true); 015 this.setCreativeTab(CreativeTabs.tabRedstone); 016 } 017 018 /** 019 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been 020 * cleared to be reused) 021 */ 022 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) 023 { 024 return null; 025 } 026 027 /** 028 * How many world ticks before ticking 029 */ 030 public int tickRate() 031 { 032 return 20; 033 } 034 035 /** 036 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 037 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 038 */ 039 public boolean isOpaqueCube() 040 { 041 return false; 042 } 043 044 /** 045 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 046 */ 047 public boolean renderAsNormalBlock() 048 { 049 return false; 050 } 051 052 /** 053 * checks to see if you can place this block can be placed on that side of a block: BlockLever overrides 054 */ 055 public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) 056 { 057 ForgeDirection dir = ForgeDirection.getOrientation(par5); 058 return (dir == NORTH && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH)) || 059 (dir == SOUTH && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) || 060 (dir == WEST && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST)) || 061 (dir == EAST && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST)); 062 } 063 064 /** 065 * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z 066 */ 067 public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) 068 { 069 return (par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST)) || 070 (par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST)) || 071 (par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) || 072 (par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH)); 073 } 074 075 /** 076 * called before onBlockPlacedBy by ItemBlock and ItemReed 077 */ 078 public void updateBlockMetadata(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8) 079 { 080 int var9 = par1World.getBlockMetadata(par2, par3, par4); 081 int var10 = var9 & 8; 082 var9 &= 7; 083 084 ForgeDirection dir = ForgeDirection.getOrientation(par5); 085 086 if (dir == NORTH && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH)) 087 { 088 var9 = 4; 089 } 090 else if (dir == SOUTH && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) 091 { 092 var9 = 3; 093 } 094 else if (dir == WEST && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST)) 095 { 096 var9 = 2; 097 } 098 else if (dir == EAST && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST)) 099 { 100 var9 = 1; 101 } 102 else 103 { 104 var9 = this.getOrientation(par1World, par2, par3, par4); 105 } 106 107 par1World.setBlockMetadataWithNotify(par2, par3, par4, var9 + var10); 108 } 109 110 /** 111 * Get side which this button is facing. 112 */ 113 private int getOrientation(World par1World, int par2, int par3, int par4) 114 { 115 if (par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST)) return 1; 116 if (par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST)) return 2; 117 if (par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) return 3; 118 if (par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH)) return 4; 119 return 1; 120 } 121 122 /** 123 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 124 * their own) Args: x, y, z, neighbor blockID 125 */ 126 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 127 { 128 if (this.redundantCanPlaceBlockAt(par1World, par2, par3, par4)) 129 { 130 int var6 = par1World.getBlockMetadata(par2, par3, par4) & 7; 131 boolean var7 = false; 132 133 if (!par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST) && var6 == 1) 134 { 135 var7 = true; 136 } 137 138 if (!par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST) && var6 == 2) 139 { 140 var7 = true; 141 } 142 143 if (!par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH) && var6 == 3) 144 { 145 var7 = true; 146 } 147 148 if (!par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH) && var6 == 4) 149 { 150 var7 = true; 151 } 152 153 if (var7) 154 { 155 this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); 156 par1World.setBlockWithNotify(par2, par3, par4, 0); 157 } 158 } 159 } 160 161 /** 162 * This method is redundant, check it out... 163 */ 164 private boolean redundantCanPlaceBlockAt(World par1World, int par2, int par3, int par4) 165 { 166 if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) 167 { 168 this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); 169 par1World.setBlockWithNotify(par2, par3, par4, 0); 170 return false; 171 } 172 else 173 { 174 return true; 175 } 176 } 177 178 /** 179 * Updates the blocks bounds based on its current state. Args: world, x, y, z 180 */ 181 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 182 { 183 int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); 184 int var6 = var5 & 7; 185 boolean var7 = (var5 & 8) > 0; 186 float var8 = 0.375F; 187 float var9 = 0.625F; 188 float var10 = 0.1875F; 189 float var11 = 0.125F; 190 191 if (var7) 192 { 193 var11 = 0.0625F; 194 } 195 196 if (var6 == 1) 197 { 198 this.setBlockBounds(0.0F, var8, 0.5F - var10, var11, var9, 0.5F + var10); 199 } 200 else if (var6 == 2) 201 { 202 this.setBlockBounds(1.0F - var11, var8, 0.5F - var10, 1.0F, var9, 0.5F + var10); 203 } 204 else if (var6 == 3) 205 { 206 this.setBlockBounds(0.5F - var10, var8, 0.0F, 0.5F + var10, var9, var11); 207 } 208 else if (var6 == 4) 209 { 210 this.setBlockBounds(0.5F - var10, var8, 1.0F - var11, 0.5F + var10, var9, 1.0F); 211 } 212 } 213 214 /** 215 * Called when the block is clicked by a player. Args: x, y, z, entityPlayer 216 */ 217 public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) 218 { 219 this.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, 0, 0.0F, 0.0F, 0.0F); 220 } 221 222 /** 223 * Called upon block activation (right click on the block.) 224 */ 225 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) 226 { 227 int var10 = par1World.getBlockMetadata(par2, par3, par4); 228 int var11 = var10 & 7; 229 int var12 = 8 - (var10 & 8); 230 231 if (var12 == 0) 232 { 233 return true; 234 } 235 else 236 { 237 par1World.setBlockMetadataWithNotify(par2, par3, par4, var11 + var12); 238 par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4); 239 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, 0.6F); 240 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); 241 242 if (var11 == 1) 243 { 244 par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); 245 } 246 else if (var11 == 2) 247 { 248 par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); 249 } 250 else if (var11 == 3) 251 { 252 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); 253 } 254 else if (var11 == 4) 255 { 256 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); 257 } 258 else 259 { 260 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 261 } 262 263 par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate()); 264 return true; 265 } 266 } 267 268 /** 269 * ejects contained items into the world, and notifies neighbours of an update, as appropriate 270 */ 271 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) 272 { 273 if ((par6 & 8) > 0) 274 { 275 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); 276 int var7 = par6 & 7; 277 278 if (var7 == 1) 279 { 280 par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); 281 } 282 else if (var7 == 2) 283 { 284 par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); 285 } 286 else if (var7 == 3) 287 { 288 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); 289 } 290 else if (var7 == 4) 291 { 292 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); 293 } 294 else 295 { 296 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 297 } 298 } 299 300 super.breakBlock(par1World, par2, par3, par4, par5, par6); 301 } 302 303 /** 304 * Is this block powering the block on the specified side 305 */ 306 public boolean isPoweringTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 307 { 308 return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) > 0; 309 } 310 311 /** 312 * Is this block indirectly powering the block on the specified side 313 */ 314 public boolean isIndirectlyPoweringTo(World par1World, int par2, int par3, int par4, int par5) 315 { 316 int var6 = par1World.getBlockMetadata(par2, par3, par4); 317 318 if ((var6 & 8) == 0) 319 { 320 return false; 321 } 322 else 323 { 324 int var7 = var6 & 7; 325 return var7 == 5 && par5 == 1 ? true : (var7 == 4 && par5 == 2 ? true : (var7 == 3 && par5 == 3 ? true : (var7 == 2 && par5 == 4 ? true : var7 == 1 && par5 == 5))); 326 } 327 } 328 329 /** 330 * Can this block provide power. Only wire currently seems to have this change based on its state. 331 */ 332 public boolean canProvidePower() 333 { 334 return true; 335 } 336 337 /** 338 * Ticks the block if it's been scheduled 339 */ 340 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 341 { 342 if (!par1World.isRemote) 343 { 344 int var6 = par1World.getBlockMetadata(par2, par3, par4); 345 346 if ((var6 & 8) != 0) 347 { 348 par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 & 7); 349 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); 350 int var7 = var6 & 7; 351 352 if (var7 == 1) 353 { 354 par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); 355 } 356 else if (var7 == 2) 357 { 358 par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); 359 } 360 else if (var7 == 3) 361 { 362 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); 363 } 364 else if (var7 == 4) 365 { 366 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); 367 } 368 else 369 { 370 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 371 } 372 373 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, 0.5F); 374 par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4); 375 } 376 } 377 } 378 379 /** 380 * Sets the block's bounds for rendering it as an item 381 */ 382 public void setBlockBoundsForItemRender() 383 { 384 float var1 = 0.1875F; 385 float var2 = 0.125F; 386 float var3 = 0.125F; 387 this.setBlockBounds(0.5F - var1, 0.5F - var2, 0.5F - var3, 0.5F + var1, 0.5F + var2, 0.5F + var3); 388 } 389 }