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