001 package net.minecraft.block; 002 003 import java.util.Iterator; 004 import java.util.List; 005 import java.util.Random; 006 import net.minecraft.block.material.Material; 007 import net.minecraft.creativetab.CreativeTabs; 008 import net.minecraft.entity.Entity; 009 import net.minecraft.entity.EntityLiving; 010 import net.minecraft.entity.player.EntityPlayer; 011 import net.minecraft.util.AxisAlignedBB; 012 import net.minecraft.world.IBlockAccess; 013 import net.minecraft.world.World; 014 015 public class BlockPressurePlate extends Block 016 { 017 /** The mob type that can trigger this pressure plate. */ 018 private EnumMobType triggerMobType; 019 020 protected BlockPressurePlate(int par1, int par2, EnumMobType par3EnumMobType, Material par4Material) 021 { 022 super(par1, par2, par4Material); 023 this.triggerMobType = par3EnumMobType; 024 this.setCreativeTab(CreativeTabs.tabRedstone); 025 this.setTickRandomly(true); 026 float var5 = 0.0625F; 027 this.setBlockBounds(var5, 0.0F, var5, 1.0F - var5, 0.03125F, 1.0F - var5); 028 } 029 030 /** 031 * How many world ticks before ticking 032 */ 033 public int tickRate() 034 { 035 return 20; 036 } 037 038 /** 039 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been 040 * cleared to be reused) 041 */ 042 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) 043 { 044 return null; 045 } 046 047 /** 048 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 049 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 050 */ 051 public boolean isOpaqueCube() 052 { 053 return false; 054 } 055 056 /** 057 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 058 */ 059 public boolean renderAsNormalBlock() 060 { 061 return false; 062 } 063 064 public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 065 { 066 return true; 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.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) || BlockFence.isIdAFence(par1World.getBlockId(par2, par3 - 1, par4)); 075 } 076 077 /** 078 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 079 * their own) Args: x, y, z, neighbor blockID 080 */ 081 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 082 { 083 boolean var6 = false; 084 085 if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && !BlockFence.isIdAFence(par1World.getBlockId(par2, par3 - 1, par4))) 086 { 087 var6 = true; 088 } 089 090 if (var6) 091 { 092 this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); 093 par1World.setBlockWithNotify(par2, par3, par4, 0); 094 } 095 } 096 097 /** 098 * Ticks the block if it's been scheduled 099 */ 100 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 101 { 102 if (!par1World.isRemote) 103 { 104 if (par1World.getBlockMetadata(par2, par3, par4) != 0) 105 { 106 this.setStateIfMobInteractsWithPlate(par1World, par2, par3, par4); 107 } 108 } 109 } 110 111 /** 112 * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity 113 */ 114 public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) 115 { 116 if (!par1World.isRemote) 117 { 118 if (par1World.getBlockMetadata(par2, par3, par4) != 1) 119 { 120 this.setStateIfMobInteractsWithPlate(par1World, par2, par3, par4); 121 } 122 } 123 } 124 125 /** 126 * Checks if there are mobs on the plate. If a mob is on the plate and it is off, it turns it on, and vice versa. 127 */ 128 private void setStateIfMobInteractsWithPlate(World par1World, int par2, int par3, int par4) 129 { 130 boolean var5 = par1World.getBlockMetadata(par2, par3, par4) == 1; 131 boolean var6 = false; 132 float var7 = 0.125F; 133 List var8 = null; 134 135 if (this.triggerMobType == EnumMobType.everything) 136 { 137 var8 = par1World.getEntitiesWithinAABBExcludingEntity((Entity)null, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)((float)par2 + var7), (double)par3, (double)((float)par4 + var7), (double)((float)(par2 + 1) - var7), (double)par3 + 0.25D, (double)((float)(par4 + 1) - var7))); 138 } 139 140 if (this.triggerMobType == EnumMobType.mobs) 141 { 142 var8 = par1World.getEntitiesWithinAABB(EntityLiving.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)((float)par2 + var7), (double)par3, (double)((float)par4 + var7), (double)((float)(par2 + 1) - var7), (double)par3 + 0.25D, (double)((float)(par4 + 1) - var7))); 143 } 144 145 if (this.triggerMobType == EnumMobType.players) 146 { 147 var8 = par1World.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)((float)par2 + var7), (double)par3, (double)((float)par4 + var7), (double)((float)(par2 + 1) - var7), (double)par3 + 0.25D, (double)((float)(par4 + 1) - var7))); 148 } 149 150 if (!var8.isEmpty()) 151 { 152 Iterator var9 = var8.iterator(); 153 154 while (var9.hasNext()) 155 { 156 Entity var10 = (Entity)var9.next(); 157 158 if (!var10.doesEntityNotTriggerPressurePlate()) 159 { 160 var6 = true; 161 break; 162 } 163 } 164 } 165 166 if (var6 && !var5) 167 { 168 par1World.setBlockMetadataWithNotify(par2, par3, par4, 1); 169 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); 170 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 171 par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); 172 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.click", 0.3F, 0.6F); 173 } 174 175 if (!var6 && var5) 176 { 177 par1World.setBlockMetadataWithNotify(par2, par3, par4, 0); 178 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); 179 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 180 par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); 181 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.click", 0.3F, 0.5F); 182 } 183 184 if (var6) 185 { 186 par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate()); 187 } 188 } 189 190 /** 191 * ejects contained items into the world, and notifies neighbours of an update, as appropriate 192 */ 193 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) 194 { 195 if (par6 > 0) 196 { 197 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); 198 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 199 } 200 201 super.breakBlock(par1World, par2, par3, par4, par5, par6); 202 } 203 204 /** 205 * Updates the blocks bounds based on its current state. Args: world, x, y, z 206 */ 207 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 208 { 209 boolean var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) == 1; 210 float var6 = 0.0625F; 211 212 if (var5) 213 { 214 this.setBlockBounds(var6, 0.0F, var6, 1.0F - var6, 0.03125F, 1.0F - var6); 215 } 216 else 217 { 218 this.setBlockBounds(var6, 0.0F, var6, 1.0F - var6, 0.0625F, 1.0F - var6); 219 } 220 } 221 222 /** 223 * Returns true if the block is emitting indirect/weak redstone power on the specified side. If isBlockNormalCube 224 * returns true, standard redstone propagation rules will apply instead and this will not be called. Args: World, X, 225 * Y, Z, side. Note that the side is reversed - eg it is 1 (up) when checking the bottom of the block. 226 */ 227 public boolean isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 228 { 229 return par1IBlockAccess.getBlockMetadata(par2, par3, par4) > 0; 230 } 231 232 /** 233 * Returns true if the block is emitting direct/strong redstone power on the specified side. Args: World, X, Y, Z, 234 * side. Note that the side is reversed - eg it is 1 (up) when checking the bottom of the block. 235 */ 236 public boolean isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 237 { 238 return par1IBlockAccess.getBlockMetadata(par2, par3, par4) == 0 ? false : par5 == 1; 239 } 240 241 /** 242 * Can this block provide power. Only wire currently seems to have this change based on its state. 243 */ 244 public boolean canProvidePower() 245 { 246 return true; 247 } 248 249 /** 250 * Sets the block's bounds for rendering it as an item 251 */ 252 public void setBlockBoundsForItemRender() 253 { 254 float var1 = 0.5F; 255 float var2 = 0.125F; 256 float var3 = 0.5F; 257 this.setBlockBounds(0.5F - var1, 0.5F - var2, 0.5F - var3, 0.5F + var1, 0.5F + var2, 0.5F + var3); 258 } 259 260 /** 261 * Returns the mobility information of the block, 0 = free, 1 = can't push but can move over, 2 = total immobility 262 * and stop pistons 263 */ 264 public int getMobilityFlag() 265 { 266 return 1; 267 } 268 }