    001package net.minecraft.block;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.List;
    006import java.util.Random;
    007import net.minecraft.client.renderer.texture.IconRegister;
    008import net.minecraft.command.IEntitySelector;
    009import net.minecraft.entity.Entity;
    010import net.minecraft.entity.item.EntityMinecart;
    011import net.minecraft.inventory.Container;
    012import net.minecraft.inventory.IInventory;
    013import net.minecraft.util.AxisAlignedBB;
    014import net.minecraft.util.Icon;
    015import net.minecraft.world.IBlockAccess;
    016import net.minecraft.world.World;
    017
    018public class BlockDetectorRail extends BlockRailBase
    019{
    020    @SideOnly(Side.CLIENT)
    021    private Icon[] field_100010_b;
    022
    023    public BlockDetectorRail(int par1)
    024    {
    025        super(par1, true);
    026        this.setTickRandomly(true);
    027    }
    028
    029    /**
    030     * How many world ticks before ticking
    031     */
    032    public int tickRate(World par1World)
    033    {
    034        return 20;
    035    }
    036
    037    /**
    038     * Can this block provide power. Only wire currently seems to have this change based on its state.
    039     */
    040    public boolean canProvidePower()
    041    {
    042        return true;
    043    }
    044
    045    /**
    046     * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity
    047     */
    048    public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity)
    049    {
    050        if (!par1World.isRemote)
    051        {
    052            int l = par1World.getBlockMetadata(par2, par3, par4);
    053
    054            if ((l & 8) == 0)
    055            {
    056                this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, l);
    057            }
    058        }
    059    }
    060
    061    /**
    062     * Ticks the block if it's been scheduled
    063     */
    064    public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    065    {
    066        if (!par1World.isRemote)
    067        {
    068            int l = par1World.getBlockMetadata(par2, par3, par4);
    069
    070            if ((l & 8) != 0)
    071            {
    072                this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, l);
    073            }
    074        }
    075    }
    076
    077    /**
    078     * Returns true if the block is emitting indirect/weak redstone power on the specified side. If isBlockNormalCube
    079     * returns true, standard redstone propagation rules will apply instead and this will not be called. Args: World, X,
    080     * Y, Z, side. Note that the side is reversed - eg it is 1 (up) when checking the bottom of the block.
    081     */
    082    public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    083    {
    084        return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0 ? 15 : 0;
    085    }
    086
    087    /**
    088     * Returns true if the block is emitting direct/strong redstone power on the specified side. Args: World, X, Y, Z,
    089     * side. Note that the side is reversed - eg it is 1 (up) when checking the bottom of the block.
    090     */
    091    public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    092    {
    093        return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 0 ? 0 : (par5 == 1 ? 15 : 0);
    094    }
    095
    096    /**
    097     * Update the detector rail power state if a minecart enter, stays or leave the block.
    098     */
    099    private void setStateIfMinecartInteractsWithRail(World par1World, int par2, int par3, int par4, int par5)
    100    {
    101        boolean flag = (par5 & 8) != 0;
    102        boolean flag1 = false;
    103        float f = 0.125F;
    104        List list = par1World.getEntitiesWithinAABB(EntityMinecart.class, AxisAlignedBB.getAABBPool().getAABB((double)((float)par2 + f), (double)par3, (double)((float)par4 + f), (double)((float)(par2 + 1) - f), (double)((float)(par3 + 1) - f), (double)((float)(par4 + 1) - f)));
    105
    106        if (!list.isEmpty())
    107        {
    108            flag1 = true;
    109        }
    110
    111        if (flag1 && !flag)
    112        {
    113            par1World.setBlockMetadataWithNotify(par2, par3, par4, par5 | 8, 3);
    114            par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
    115            par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID);
    116            par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4);
    117        }
    118
    119        if (!flag1 && flag)
    120        {
    121            par1World.setBlockMetadataWithNotify(par2, par3, par4, par5 & 7, 3);
    122            par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
    123            par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID);
    124            par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4);
    125        }
    126
    127        if (flag1)
    128        {
    129            par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World));
    130        }
    131
    132        par1World.func_96440_m(par2, par3, par4, this.blockID);
    133    }
    134
    135    /**
    136     * Called whenever the block is added into the world. Args: world, x, y, z
    137     */
    138    public void onBlockAdded(World par1World, int par2, int par3, int par4)
    139    {
    140        super.onBlockAdded(par1World, par2, par3, par4);
    141        this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4));
    142    }
    143
    144    public boolean func_96468_q_()
    145    {
    146        return true;
    147    }
    148
    149    public int func_94328_b_(World par1World, int par2, int par3, int par4, int par5)
    150    {
    151        if ((par1World.getBlockMetadata(par2, par3, par4) & 8) > 0)
    152        {
    153            float f = 0.125F;
    154            List list = par1World.selectEntitiesWithinAABB(EntityMinecart.class, AxisAlignedBB.getAABBPool().getAABB((double)((float)par2 + f), (double)par3, (double)((float)par4 + f), (double)((float)(par2 + 1) - f), (double)((float)(par3 + 1) - f), (double)((float)(par4 + 1) - f)), IEntitySelector.field_96566_b);
    155
    156            if (list.size() > 0)
    157            {
    158                return Container.func_94526_b((IInventory)list.get(0));
    159            }
    160        }
    161
    162        return 0;
    163    }
    164
    165    @SideOnly(Side.CLIENT)
    166    public void func_94332_a(IconRegister par1IconRegister)
    167    {
    168        this.field_100010_b = new Icon[2];
    169        this.field_100010_b[0] = par1IconRegister.func_94245_a("detectorRail");
    170        this.field_100010_b[1] = par1IconRegister.func_94245_a("detectorRail_on");
    171    }
    172
    173    @SideOnly(Side.CLIENT)
    174
    175    /**
    176     * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
    177     */
    178    public Icon getBlockTextureFromSideAndMetadata(int par1, int par2)
    179    {
    180        return (par2 & 8) != 0 ? this.field_100010_b[1] : this.field_100010_b[0];
    181    }
    182}