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