    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.field_94343_co;
    050    }
    051
    052    protected BlockRedstoneLogic func_94484_i()
    053    {
    054        return Block.field_94346_cn;
    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.field_94343_co.field_94336_cN : this.field_94336_cN) : 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.ignoreTick(par1World, par2, par3, par4, par5) : Math.max(this.ignoreTick(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.ignoreTick(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    protected int ignoreTick(World par1World, int par2, int par3, int par4, int par5)
    116    {
    117        int i1 = super.ignoreTick(par1World, par2, par3, par4, par5);
    118        int j1 = getDirection(par5);
    119        int k1 = par2 + Direction.offsetX[j1];
    120        int l1 = par4 + Direction.offsetZ[j1];
    121        int i2 = par1World.getBlockId(k1, par3, l1);
    122
    123        if (i2 > 0)
    124        {
    125            if (Block.blocksList[i2].func_96468_q_())
    126            {
    127                i1 = Block.blocksList[i2].func_94328_b_(par1World, k1, par3, l1, Direction.footInvisibleFaceRemap[j1]);
    128            }
    129            else if (i1 < 15 && Block.isNormalCube(i2))
    130            {
    131                k1 += Direction.offsetX[j1];
    132                l1 += Direction.offsetZ[j1];
    133                i2 = par1World.getBlockId(k1, par3, l1);
    134
    135                if (i2 > 0 && Block.blocksList[i2].func_96468_q_())
    136                {
    137                    i1 = Block.blocksList[i2].func_94328_b_(par1World, k1, par3, l1, Direction.footInvisibleFaceRemap[j1]);
    138                }
    139            }
    140        }
    141
    142        return i1;
    143    }
    144
    145    public TileEntityComparator func_96475_a_(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    146    {
    147        return (TileEntityComparator)par1IBlockAccess.getBlockTileEntity(par2, par3, par4);
    148    }
    149
    150    /**
    151     * Called upon block activation (right click on the block.)
    152     */
    153    public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
    154    {
    155        int i1 = par1World.getBlockMetadata(par2, par3, par4);
    156        boolean flag = this.isRepeaterPowered | (i1 & 8) != 0;
    157        boolean flag1 = !this.func_94490_c(i1);
    158        int j1 = flag1 ? 4 : 0;
    159        j1 |= flag ? 8 : 0;
    160        par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, flag1 ? 0.55F : 0.5F);
    161        par1World.setBlockMetadataWithNotify(par2, par3, par4, j1 | i1 & 3, 2);
    162        this.func_96476_c(par1World, par2, par3, par4, par1World.rand);
    163        return true;
    164    }
    165
    166    protected void func_94479_f(World par1World, int par2, int par3, int par4, int par5)
    167    {
    168        if (!par1World.func_94573_a(par2, par3, par4, this.blockID))
    169        {
    170            int i1 = par1World.getBlockMetadata(par2, par3, par4);
    171            int j1 = this.func_94491_m(par1World, par2, par3, par4, i1);
    172            int k1 = this.func_96475_a_(par1World, par2, par3, par4).func_96100_a();
    173
    174            if (j1 != k1 || this.func_96470_c(i1) != this.func_94478_d(par1World, par2, par3, par4, i1))
    175            {
    176                if (this.func_83011_d(par1World, par2, par3, par4, i1))
    177                {
    178                    par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), -1);
    179                }
    180                else
    181                {
    182                    par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), 0);
    183                }
    184            }
    185        }
    186    }
    187
    188    private void func_96476_c(World par1World, int par2, int par3, int par4, Random par5Random)
    189    {
    190        int l = par1World.getBlockMetadata(par2, par3, par4);
    191        int i1 = this.func_94491_m(par1World, par2, par3, par4, l);
    192        int j1 = this.func_96475_a_(par1World, par2, par3, par4).func_96100_a();
    193        this.func_96475_a_(par1World, par2, par3, par4).func_96099_a(i1);
    194
    195        if (j1 != i1 || !this.func_94490_c(l))
    196        {
    197            boolean flag = this.func_94478_d(par1World, par2, par3, par4, l);
    198            boolean flag1 = this.isRepeaterPowered || (l & 8) != 0;
    199
    200            if (flag1 && !flag)
    201            {
    202                par1World.setBlockMetadataWithNotify(par2, par3, par4, l & -9, 2);
    203            }
    204            else if (!flag1 && flag)
    205            {
    206                par1World.setBlockMetadataWithNotify(par2, par3, par4, l | 8, 2);
    207            }
    208
    209            this.func_94483_i_(par1World, par2, par3, par4);
    210        }
    211    }
    212
    213    /**
    214     * Ticks the block if it's been scheduled
    215     */
    216    public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    217    {
    218        if (this.isRepeaterPowered)
    219        {
    220            int l = par1World.getBlockMetadata(par2, par3, par4);
    221            par1World.setBlockAndMetadataWithNotify(par2, par3, par4, this.func_94484_i().blockID, l | 8, 4);
    222        }
    223
    224        this.func_96476_c(par1World, par2, par3, par4, par5Random);
    225    }
    226
    227    /**
    228     * Called whenever the block is added into the world. Args: world, x, y, z
    229     */
    230    public void onBlockAdded(World par1World, int par2, int par3, int par4)
    231    {
    232        super.onBlockAdded(par1World, par2, par3, par4);
    233        par1World.setBlockTileEntity(par2, par3, par4, this.createNewTileEntity(par1World));
    234    }
    235
    236    /**
    237     * ejects contained items into the world, and notifies neighbours of an update, as appropriate
    238     */
    239    public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
    240    {
    241        super.breakBlock(par1World, par2, par3, par4, par5, par6);
    242        par1World.removeBlockTileEntity(par2, par3, par4);
    243        this.func_94483_i_(par1World, par2, par3, par4);
    244    }
    245
    246    /**
    247     * Called when the block receives a BlockEvent - see World.addBlockEvent. By default, passes it on to the tile
    248     * entity at this location. Args: world, x, y, z, blockID, EventID, event parameter
    249     */
    250    public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6)
    251    {
    252        super.onBlockEventReceived(par1World, par2, par3, par4, par5, par6);
    253        TileEntity tileentity = par1World.getBlockTileEntity(par2, par3, par4);
    254        return tileentity != null ? tileentity.receiveClientEvent(par5, par6) : false;
    255    }
    256
    257    /**
    258     * Returns a new instance of a block's tile entity class. Called on placing the block.
    259     */
    260    public TileEntity createNewTileEntity(World par1World)
    261    {
    262        return new TileEntityComparator();
    263    }
    264
    265    @SideOnly(Side.CLIENT)
    266    public void func_94332_a(IconRegister par1IconRegister)
    267    {
    268        this.field_94336_cN = par1IconRegister.func_94245_a(this.isRepeaterPowered ? "comparator_lit" : "comparator");
    269    }
    270}