001package net.minecraft.block; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import java.util.Iterator; 006import java.util.List; 007import java.util.Random; 008import net.minecraft.block.material.Material; 009import net.minecraft.entity.Entity; 010import net.minecraft.entity.player.EntityPlayer; 011import net.minecraft.item.Item; 012import net.minecraft.util.AxisAlignedBB; 013import net.minecraft.util.Direction; 014import net.minecraft.world.IBlockAccess; 015import net.minecraft.world.World; 016 017public class BlockTripWire extends Block 018{ 019 public BlockTripWire(int par1) 020 { 021 super(par1, Material.circuits); 022 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.15625F, 1.0F); 023 this.setTickRandomly(true); 024 } 025 026 /** 027 * How many world ticks before ticking 028 */ 029 public int tickRate(World par1World) 030 { 031 return 10; 032 } 033 034 /** 035 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been 036 * cleared to be reused) 037 */ 038 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) 039 { 040 return null; 041 } 042 043 /** 044 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 045 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 046 */ 047 public boolean isOpaqueCube() 048 { 049 return false; 050 } 051 052 /** 053 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 054 */ 055 public boolean renderAsNormalBlock() 056 { 057 return false; 058 } 059 060 @SideOnly(Side.CLIENT) 061 062 /** 063 * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha 064 */ 065 public int getRenderBlockPass() 066 { 067 return 1; 068 } 069 070 /** 071 * The type of render function that is called for this block 072 */ 073 public int getRenderType() 074 { 075 return 30; 076 } 077 078 /** 079 * Returns the ID of the items to drop on destruction. 080 */ 081 public int idDropped(int par1, Random par2Random, int par3) 082 { 083 return Item.silk.itemID; 084 } 085 086 /** 087 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 088 * their own) Args: x, y, z, neighbor blockID 089 */ 090 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 091 { 092 int i1 = par1World.getBlockMetadata(par2, par3, par4); 093 boolean flag = (i1 & 2) == 2; 094 boolean flag1 = !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); 095 096 if (flag != flag1) 097 { 098 this.dropBlockAsItem(par1World, par2, par3, par4, i1, 0); 099 par1World.setBlockToAir(par2, par3, par4); 100 } 101 } 102 103 /** 104 * Updates the blocks bounds based on its current state. Args: world, x, y, z 105 */ 106 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 107 { 108 int l = par1IBlockAccess.getBlockMetadata(par2, par3, par4); 109 boolean flag = (l & 4) == 4; 110 boolean flag1 = (l & 2) == 2; 111 112 if (!flag1) 113 { 114 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.09375F, 1.0F); 115 } 116 else if (!flag) 117 { 118 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); 119 } 120 else 121 { 122 this.setBlockBounds(0.0F, 0.0625F, 0.0F, 1.0F, 0.15625F, 1.0F); 123 } 124 } 125 126 /** 127 * Called whenever the block is added into the world. Args: world, x, y, z 128 */ 129 public void onBlockAdded(World par1World, int par2, int par3, int par4) 130 { 131 int l = par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? 0 : 2; 132 par1World.setBlockMetadataWithNotify(par2, par3, par4, l, 3); 133 this.func_72149_e(par1World, par2, par3, par4, l); 134 } 135 136 /** 137 * ejects contained items into the world, and notifies neighbours of an update, as appropriate 138 */ 139 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) 140 { 141 this.func_72149_e(par1World, par2, par3, par4, par6 | 1); 142 } 143 144 /** 145 * Called when the block is attempted to be harvested 146 */ 147 public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) 148 { 149 if (!par1World.isRemote) 150 { 151 if (par6EntityPlayer.getCurrentEquippedItem() != null && par6EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) 152 { 153 par1World.setBlockMetadataWithNotify(par2, par3, par4, par5 | 8, 4); 154 } 155 } 156 } 157 158 @SideOnly(Side.CLIENT) 159 160 /** 161 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) 162 */ 163 public int idPicked(World par1World, int par2, int par3, int par4) 164 { 165 return Item.silk.itemID; 166 } 167 168 private void func_72149_e(World par1World, int par2, int par3, int par4, int par5) 169 { 170 int i1 = 0; 171 172 while (i1 < 2) 173 { 174 int j1 = 1; 175 176 while (true) 177 { 178 if (j1 < 42) 179 { 180 int k1 = par2 + Direction.offsetX[i1] * j1; 181 int l1 = par4 + Direction.offsetZ[i1] * j1; 182 int i2 = par1World.getBlockId(k1, par3, l1); 183 184 if (i2 == Block.tripWireSource.blockID) 185 { 186 int j2 = par1World.getBlockMetadata(k1, par3, l1) & 3; 187 188 if (j2 == Direction.footInvisibleFaceRemap[i1]) 189 { 190 Block.tripWireSource.func_72143_a(par1World, k1, par3, l1, i2, par1World.getBlockMetadata(k1, par3, l1), true, j1, par5); 191 } 192 } 193 else if (i2 == Block.tripWire.blockID) 194 { 195 ++j1; 196 continue; 197 } 198 } 199 200 ++i1; 201 break; 202 } 203 } 204 } 205 206 /** 207 * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity 208 */ 209 public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) 210 { 211 if (!par1World.isRemote) 212 { 213 if ((par1World.getBlockMetadata(par2, par3, par4) & 1) != 1) 214 { 215 this.updateTripWireState(par1World, par2, par3, par4); 216 } 217 } 218 } 219 220 /** 221 * Ticks the block if it's been scheduled 222 */ 223 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 224 { 225 if (!par1World.isRemote) 226 { 227 if ((par1World.getBlockMetadata(par2, par3, par4) & 1) == 1) 228 { 229 this.updateTripWireState(par1World, par2, par3, par4); 230 } 231 } 232 } 233 234 private void updateTripWireState(World par1World, int par2, int par3, int par4) 235 { 236 int l = par1World.getBlockMetadata(par2, par3, par4); 237 boolean flag = (l & 1) == 1; 238 boolean flag1 = false; 239 List list = par1World.getEntitiesWithinAABBExcludingEntity((Entity)null, AxisAlignedBB.getAABBPool().getAABB((double)par2 + this.minX, (double)par3 + this.minY, (double)par4 + this.minZ, (double)par2 + this.maxX, (double)par3 + this.maxY, (double)par4 + this.maxZ)); 240 241 if (!list.isEmpty()) 242 { 243 Iterator iterator = list.iterator(); 244 245 while (iterator.hasNext()) 246 { 247 Entity entity = (Entity)iterator.next(); 248 249 if (!entity.doesEntityNotTriggerPressurePlate()) 250 { 251 flag1 = true; 252 break; 253 } 254 } 255 } 256 257 if (flag1 && !flag) 258 { 259 l |= 1; 260 } 261 262 if (!flag1 && flag) 263 { 264 l &= -2; 265 } 266 267 if (flag1 != flag) 268 { 269 par1World.setBlockMetadataWithNotify(par2, par3, par4, l, 3); 270 this.func_72149_e(par1World, par2, par3, par4, l); 271 } 272 273 if (flag1) 274 { 275 par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); 276 } 277 } 278 279 @SideOnly(Side.CLIENT) 280 public static boolean func_72148_a(IBlockAccess par0IBlockAccess, int par1, int par2, int par3, int par4, int par5) 281 { 282 int j1 = par1 + Direction.offsetX[par5]; 283 int k1 = par3 + Direction.offsetZ[par5]; 284 int l1 = par0IBlockAccess.getBlockId(j1, par2, k1); 285 boolean flag = (par4 & 2) == 2; 286 int i2; 287 288 if (l1 == Block.tripWireSource.blockID) 289 { 290 i2 = par0IBlockAccess.getBlockMetadata(j1, par2, k1); 291 int j2 = i2 & 3; 292 return j2 == Direction.footInvisibleFaceRemap[par5]; 293 } 294 else if (l1 == Block.tripWire.blockID) 295 { 296 i2 = par0IBlockAccess.getBlockMetadata(j1, par2, k1); 297 boolean flag1 = (i2 & 2) == 2; 298 return flag == flag1; 299 } 300 else 301 { 302 return false; 303 } 304 } 305}