001package net.minecraft.block; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import java.util.Random; 006import net.minecraft.client.renderer.texture.IconRegister; 007import net.minecraft.entity.player.EntityPlayer; 008import net.minecraft.item.Item; 009import net.minecraft.tileentity.TileEntity; 010import net.minecraft.tileentity.TileEntityComparator; 011import net.minecraft.util.Direction; 012import net.minecraft.util.Icon; 013import net.minecraft.world.IBlockAccess; 014import net.minecraft.world.World; 015 016public class BlockComparator extends BlockRedstoneLogic implements ITileEntityProvider 017{ 018 public BlockComparator(int par1, boolean par2) 019 { 020 super(par1, par2); 021 this.isBlockContainer = true; 022 } 023 024 /** 025 * Returns the ID of the items to drop on destruction. 026 */ 027 public int idDropped(int par1, Random par2Random, int par3) 028 { 029 return Item.field_94585_bY.itemID; 030 } 031 032 @SideOnly(Side.CLIENT) 033 034 /** 035 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) 036 */ 037 public int idPicked(World par1World, int par2, int par3, int par4) 038 { 039 return Item.field_94585_bY.itemID; 040 } 041 042 protected int func_94481_j_(int par1) 043 { 044 return 2; 045 } 046 047 protected BlockRedstoneLogic func_94485_e() 048 { 049 return Block.redstoneComparatorActive; 050 } 051 052 protected BlockRedstoneLogic func_94484_i() 053 { 054 return Block.redstoneComparatorIdle; 055 } 056 057 /** 058 * The type of render function that is called for this block 059 */ 060 public int getRenderType() 061 { 062 return 37; 063 } 064 065 @SideOnly(Side.CLIENT) 066 067 /** 068 * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata 069 */ 070 public Icon getBlockTextureFromSideAndMetadata(int par1, int par2) 071 { 072 boolean flag = this.isRepeaterPowered || (par2 & 8) != 0; 073 return par1 == 0 ? (flag ? Block.torchRedstoneActive.getBlockTextureFromSide(par1) : Block.torchRedstoneIdle.getBlockTextureFromSide(par1)) : (par1 == 1 ? (flag ? Block.redstoneComparatorActive.blockIcon : this.blockIcon) : Block.stoneDoubleSlab.getBlockTextureFromSide(1)); 074 } 075 076 protected boolean func_96470_c(int par1) 077 { 078 return this.isRepeaterPowered || (par1 & 8) != 0; 079 } 080 081 protected int func_94480_d(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 082 { 083 return this.func_96475_a_(par1IBlockAccess, par2, par3, par4).func_96100_a(); 084 } 085 086 private int func_94491_m(World par1World, int par2, int par3, int par4, int par5) 087 { 088 return !this.func_94490_c(par5) ? this.getInputStrength(par1World, par2, par3, par4, par5) : Math.max(this.getInputStrength(par1World, par2, par3, par4, par5) - this.func_94482_f(par1World, par2, par3, par4, par5), 0); 089 } 090 091 public boolean func_94490_c(int par1) 092 { 093 return (par1 & 4) == 4; 094 } 095 096 protected boolean func_94478_d(World par1World, int par2, int par3, int par4, int par5) 097 { 098 int i1 = this.getInputStrength(par1World, par2, par3, par4, par5); 099 100 if (i1 >= 15) 101 { 102 return true; 103 } 104 else if (i1 == 0) 105 { 106 return false; 107 } 108 else 109 { 110 int j1 = this.func_94482_f(par1World, par2, par3, par4, par5); 111 return j1 == 0 ? true : i1 >= j1; 112 } 113 } 114 115 /** 116 * Returns the signal strength at one input of the block. Args: world, X, Y, Z, side 117 */ 118 protected int getInputStrength(World par1World, int par2, int par3, int par4, int par5) 119 { 120 int i1 = super.getInputStrength(par1World, par2, par3, par4, par5); 121 int j1 = getDirection(par5); 122 int k1 = par2 + Direction.offsetX[j1]; 123 int l1 = par4 + Direction.offsetZ[j1]; 124 int i2 = par1World.getBlockId(k1, par3, l1); 125 126 if (i2 > 0) 127 { 128 if (Block.blocksList[i2].hasComparatorInputOverride()) 129 { 130 i1 = Block.blocksList[i2].getComparatorInputOverride(par1World, k1, par3, l1, Direction.footInvisibleFaceRemap[j1]); 131 } 132 else if (i1 < 15 && Block.isNormalCube(i2)) 133 { 134 k1 += Direction.offsetX[j1]; 135 l1 += Direction.offsetZ[j1]; 136 i2 = par1World.getBlockId(k1, par3, l1); 137 138 if (i2 > 0 && Block.blocksList[i2].hasComparatorInputOverride()) 139 { 140 i1 = Block.blocksList[i2].getComparatorInputOverride(par1World, k1, par3, l1, Direction.footInvisibleFaceRemap[j1]); 141 } 142 } 143 } 144 145 return i1; 146 } 147 148 public TileEntityComparator func_96475_a_(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 149 { 150 return (TileEntityComparator)par1IBlockAccess.getBlockTileEntity(par2, par3, par4); 151 } 152 153 /** 154 * Called upon block activation (right click on the block.) 155 */ 156 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) 157 { 158 int i1 = par1World.getBlockMetadata(par2, par3, par4); 159 boolean flag = this.isRepeaterPowered | (i1 & 8) != 0; 160 boolean flag1 = !this.func_94490_c(i1); 161 int j1 = flag1 ? 4 : 0; 162 j1 |= flag ? 8 : 0; 163 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, flag1 ? 0.55F : 0.5F); 164 par1World.setBlockMetadataWithNotify(par2, par3, par4, j1 | i1 & 3, 2); 165 this.func_96476_c(par1World, par2, par3, par4, par1World.rand); 166 return true; 167 } 168 169 protected void func_94479_f(World par1World, int par2, int par3, int par4, int par5) 170 { 171 if (!par1World.isBlockTickScheduled(par2, par3, par4, this.blockID)) 172 { 173 int i1 = par1World.getBlockMetadata(par2, par3, par4); 174 int j1 = this.func_94491_m(par1World, par2, par3, par4, i1); 175 int k1 = this.func_96475_a_(par1World, par2, par3, par4).func_96100_a(); 176 177 if (j1 != k1 || this.func_96470_c(i1) != this.func_94478_d(par1World, par2, par3, par4, i1)) 178 { 179 if (this.func_83011_d(par1World, par2, par3, par4, i1)) 180 { 181 par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), -1); 182 } 183 else 184 { 185 par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), 0); 186 } 187 } 188 } 189 } 190 191 private void func_96476_c(World par1World, int par2, int par3, int par4, Random par5Random) 192 { 193 int l = par1World.getBlockMetadata(par2, par3, par4); 194 int i1 = this.func_94491_m(par1World, par2, par3, par4, l); 195 int j1 = this.func_96475_a_(par1World, par2, par3, par4).func_96100_a(); 196 this.func_96475_a_(par1World, par2, par3, par4).func_96099_a(i1); 197 198 if (j1 != i1 || !this.func_94490_c(l)) 199 { 200 boolean flag = this.func_94478_d(par1World, par2, par3, par4, l); 201 boolean flag1 = this.isRepeaterPowered || (l & 8) != 0; 202 203 if (flag1 && !flag) 204 { 205 par1World.setBlockMetadataWithNotify(par2, par3, par4, l & -9, 2); 206 } 207 else if (!flag1 && flag) 208 { 209 par1World.setBlockMetadataWithNotify(par2, par3, par4, l | 8, 2); 210 } 211 212 this.func_94483_i_(par1World, par2, par3, par4); 213 } 214 } 215 216 /** 217 * Ticks the block if it's been scheduled 218 */ 219 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 220 { 221 if (this.isRepeaterPowered) 222 { 223 int l = par1World.getBlockMetadata(par2, par3, par4); 224 par1World.setBlock(par2, par3, par4, this.func_94484_i().blockID, l | 8, 4); 225 } 226 227 this.func_96476_c(par1World, par2, par3, par4, par5Random); 228 } 229 230 /** 231 * Called whenever the block is added into the world. Args: world, x, y, z 232 */ 233 public void onBlockAdded(World par1World, int par2, int par3, int par4) 234 { 235 super.onBlockAdded(par1World, par2, par3, par4); 236 par1World.setBlockTileEntity(par2, par3, par4, this.createNewTileEntity(par1World)); 237 } 238 239 /** 240 * ejects contained items into the world, and notifies neighbours of an update, as appropriate 241 */ 242 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) 243 { 244 super.breakBlock(par1World, par2, par3, par4, par5, par6); 245 par1World.removeBlockTileEntity(par2, par3, par4); 246 this.func_94483_i_(par1World, par2, par3, par4); 247 } 248 249 /** 250 * Called when the block receives a BlockEvent - see World.addBlockEvent. By default, passes it on to the tile 251 * entity at this location. Args: world, x, y, z, blockID, EventID, event parameter 252 */ 253 public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) 254 { 255 super.onBlockEventReceived(par1World, par2, par3, par4, par5, par6); 256 TileEntity tileentity = par1World.getBlockTileEntity(par2, par3, par4); 257 return tileentity != null ? tileentity.receiveClientEvent(par5, par6) : false; 258 } 259 260 /** 261 * Returns a new instance of a block's tile entity class. Called on placing the block. 262 */ 263 public TileEntity createNewTileEntity(World par1World) 264 { 265 return new TileEntityComparator(); 266 } 267 268 @SideOnly(Side.CLIENT) 269 270 /** 271 * When this method is called, your block should register all the icons it needs with the given IconRegister. This 272 * is the only chance you get to register icons. 273 */ 274 public void registerIcons(IconRegister par1IconRegister) 275 { 276 this.blockIcon = par1IconRegister.registerIcon(this.isRepeaterPowered ? "comparator_lit" : "comparator"); 277 } 278}