    001package net.minecraft.block;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import net.minecraft.block.material.Material;
    006import net.minecraft.creativetab.CreativeTabs;
    007import net.minecraft.entity.EntityLiving;
    008import net.minecraft.entity.player.EntityPlayer;
    009import net.minecraft.util.AxisAlignedBB;
    010import net.minecraft.util.MathHelper;
    011import net.minecraft.world.IBlockAccess;
    012import net.minecraft.world.World;
    013
    014public class BlockFenceGate extends BlockDirectional
    015{
    016    public BlockFenceGate(int par1, int par2)
    017    {
    018        super(par1, par2, Material.wood);
    019        this.setCreativeTab(CreativeTabs.tabRedstone);
    020    }
    021
    022    /**
    023     * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
    024     */
    025    public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
    026    {
    027        return !par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid() ? false : super.canPlaceBlockAt(par1World, par2, par3, par4);
    028    }
    029
    030    /**
    031     * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
    032     * cleared to be reused)
    033     */
    034    public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    035    {
    036        int var5 = par1World.getBlockMetadata(par2, par3, par4);
    037        return isFenceGateOpen(var5) ? null : (var5 != 2 && var5 != 0 ? AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)((float)par2 + 0.375F), (double)par3, (double)par4, (double)((float)par2 + 0.625F), (double)((float)par3 + 1.5F), (double)(par4 + 1)) : AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)par2, (double)par3, (double)((float)par4 + 0.375F), (double)(par2 + 1), (double)((float)par3 + 1.5F), (double)((float)par4 + 0.625F)));
    038    }
    039
    040    /**
    041     * Updates the blocks bounds based on its current state. Args: world, x, y, z
    042     */
    043    public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    044    {
    045        int var5 = getDirection(par1IBlockAccess.getBlockMetadata(par2, par3, par4));
    046
    047        if (var5 != 2 && var5 != 0)
    048        {
    049            this.setBlockBounds(0.375F, 0.0F, 0.0F, 0.625F, 1.0F, 1.0F);
    050        }
    051        else
    052        {
    053            this.setBlockBounds(0.0F, 0.0F, 0.375F, 1.0F, 1.0F, 0.625F);
    054        }
    055    }
    056
    057    /**
    058     * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
    059     * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    060     */
    061    public boolean isOpaqueCube()
    062    {
    063        return false;
    064    }
    065
    066    /**
    067     * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    068     */
    069    public boolean renderAsNormalBlock()
    070    {
    071        return false;
    072    }
    073
    074    public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    075    {
    076        return isFenceGateOpen(par1IBlockAccess.getBlockMetadata(par2, par3, par4));
    077    }
    078
    079    /**
    080     * The type of render function that is called for this block
    081     */
    082    public int getRenderType()
    083    {
    084        return 21;
    085    }
    086
    087    /**
    088     * Called when the block is placed in the world.
    089     */
    090    public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)
    091    {
    092        int var6 = (MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) % 4;
    093        par1World.setBlockMetadataWithNotify(par2, par3, par4, var6);
    094    }
    095
    096    /**
    097     * Called upon block activation (right click on the block.)
    098     */
    099    public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
    100    {
    101        int var10 = par1World.getBlockMetadata(par2, par3, par4);
    102
    103        if (isFenceGateOpen(var10))
    104        {
    105            par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 & -5);
    106        }
    107        else
    108        {
    109            int var11 = (MathHelper.floor_double((double)(par5EntityPlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) % 4;
    110            int var12 = getDirection(var10);
    111
    112            if (var12 == (var11 + 2) % 4)
    113            {
    114                var10 = var11;
    115            }
    116
    117            par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 | 4);
    118        }
    119
    120        par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0);
    121        return true;
    122    }
    123
    124    /**
    125     * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
    126     * their own) Args: x, y, z, neighbor blockID
    127     */
    128    public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    129    {
    130        if (!par1World.isRemote)
    131        {
    132            int var6 = par1World.getBlockMetadata(par2, par3, par4);
    133            boolean var7 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4);
    134
    135            if (var7 || par5 > 0 && Block.blocksList[par5].canProvidePower() || par5 == 0)
    136            {
    137                if (var7 && !isFenceGateOpen(var6))
    138                {
    139                    par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 | 4);
    140                    par1World.playAuxSFXAtEntity((EntityPlayer)null, 1003, par2, par3, par4, 0);
    141                }
    142                else if (!var7 && isFenceGateOpen(var6))
    143                {
    144                    par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 & -5);
    145                    par1World.playAuxSFXAtEntity((EntityPlayer)null, 1003, par2, par3, par4, 0);
    146                }
    147            }
    148        }
    149    }
    150
    151    /**
    152     * Returns if the fence gate is open according to its metadata.
    153     */
    154    public static boolean isFenceGateOpen(int par0)
    155    {
    156        return (par0 & 4) != 0;
    157    }
    158
    159    @SideOnly(Side.CLIENT)
    160
    161    /**
    162     * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
    163     * coordinates.  Args: blockAccess, x, y, z, side
    164     */
    165    public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    166    {
    167        return true;
    168    }
    169}