    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}