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}