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}