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.comparator.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.comparator.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 getIcon(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.getTileEntityComparator(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.rotateOpposite[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.rotateOpposite[j1]); 141 } 142 } 143 } 144 145 return i1; 146 } 147 148 /** 149 * Returns the blockTileEntity at given coordinates. 150 */ 151 public TileEntityComparator getTileEntityComparator(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 152 { 153 return (TileEntityComparator)par1IBlockAccess.getBlockTileEntity(par2, par3, par4); 154 } 155 156 /** 157 * Called upon block activation (right click on the block.) 158 */ 159 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) 160 { 161 int i1 = par1World.getBlockMetadata(par2, par3, par4); 162 boolean flag = this.isRepeaterPowered | (i1 & 8) != 0; 163 boolean flag1 = !this.func_94490_c(i1); 164 int j1 = flag1 ? 4 : 0; 165 j1 |= flag ? 8 : 0; 166 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, flag1 ? 0.55F : 0.5F); 167 par1World.setBlockMetadataWithNotify(par2, par3, par4, j1 | i1 & 3, 2); 168 this.func_96476_c(par1World, par2, par3, par4, par1World.rand); 169 return true; 170 } 171 172 protected void func_94479_f(World par1World, int par2, int par3, int par4, int par5) 173 { 174 if (!par1World.isBlockTickScheduled(par2, par3, par4, this.blockID)) 175 { 176 int i1 = par1World.getBlockMetadata(par2, par3, par4); 177 int j1 = this.func_94491_m(par1World, par2, par3, par4, i1); 178 int k1 = this.getTileEntityComparator(par1World, par2, par3, par4).func_96100_a(); 179 180 if (j1 != k1 || this.func_96470_c(i1) != this.func_94478_d(par1World, par2, par3, par4, i1)) 181 { 182 if (this.func_83011_d(par1World, par2, par3, par4, i1)) 183 { 184 par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), -1); 185 } 186 else 187 { 188 par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), 0); 189 } 190 } 191 } 192 } 193 194 private void func_96476_c(World par1World, int par2, int par3, int par4, Random par5Random) 195 { 196 int l = par1World.getBlockMetadata(par2, par3, par4); 197 int i1 = this.func_94491_m(par1World, par2, par3, par4, l); 198 int j1 = this.getTileEntityComparator(par1World, par2, par3, par4).func_96100_a(); 199 this.getTileEntityComparator(par1World, par2, par3, par4).func_96099_a(i1); 200 201 if (j1 != i1 || !this.func_94490_c(l)) 202 { 203 boolean flag = this.func_94478_d(par1World, par2, par3, par4, l); 204 boolean flag1 = this.isRepeaterPowered || (l & 8) != 0; 205 206 if (flag1 && !flag) 207 { 208 par1World.setBlockMetadataWithNotify(par2, par3, par4, l & -9, 2); 209 } 210 else if (!flag1 && flag) 211 { 212 par1World.setBlockMetadataWithNotify(par2, par3, par4, l | 8, 2); 213 } 214 215 this.func_94483_i_(par1World, par2, par3, par4); 216 } 217 } 218 219 /** 220 * Ticks the block if it's been scheduled 221 */ 222 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 223 { 224 if (this.isRepeaterPowered) 225 { 226 int l = par1World.getBlockMetadata(par2, par3, par4); 227 par1World.setBlock(par2, par3, par4, this.func_94484_i().blockID, l | 8, 4); 228 } 229 230 this.func_96476_c(par1World, par2, par3, par4, par5Random); 231 } 232 233 /** 234 * Called whenever the block is added into the world. Args: world, x, y, z 235 */ 236 public void onBlockAdded(World par1World, int par2, int par3, int par4) 237 { 238 super.onBlockAdded(par1World, par2, par3, par4); 239 par1World.setBlockTileEntity(par2, par3, par4, this.createNewTileEntity(par1World)); 240 } 241 242 /** 243 * ejects contained items into the world, and notifies neighbours of an update, as appropriate 244 */ 245 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) 246 { 247 super.breakBlock(par1World, par2, par3, par4, par5, par6); 248 par1World.removeBlockTileEntity(par2, par3, par4); 249 this.func_94483_i_(par1World, par2, par3, par4); 250 } 251 252 /** 253 * Called when the block receives a BlockEvent - see World.addBlockEvent. By default, passes it on to the tile 254 * entity at this location. Args: world, x, y, z, blockID, EventID, event parameter 255 */ 256 public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) 257 { 258 super.onBlockEventReceived(par1World, par2, par3, par4, par5, par6); 259 TileEntity tileentity = par1World.getBlockTileEntity(par2, par3, par4); 260 return tileentity != null ? tileentity.receiveClientEvent(par5, par6) : false; 261 } 262 263 /** 264 * Returns a new instance of a block's tile entity class. Called on placing the block. 265 */ 266 public TileEntity createNewTileEntity(World par1World) 267 { 268 return new TileEntityComparator(); 269 } 270 271 @SideOnly(Side.CLIENT) 272 273 /** 274 * When this method is called, your block should register all the icons it needs with the given IconRegister. This 275 * is the only chance you get to register icons. 276 */ 277 public void registerIcons(IconRegister par1IconRegister) 278 { 279 this.blockIcon = par1IconRegister.registerIcon(this.isRepeaterPowered ? "comparator_lit" : "comparator"); 280 } 281}