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