    001    package net.minecraft.block;
    002
    003    import cpw.mods.fml.relauncher.Side;
    004    import cpw.mods.fml.relauncher.SideOnly;
    005    import java.util.Random;
    006    import net.minecraft.block.material.Material;
    007    import net.minecraft.entity.Entity;
    008    import net.minecraft.entity.player.EntityPlayer;
    009    import net.minecraft.util.AxisAlignedBB;
    010    import net.minecraft.world.World;
    011
    012    import net.minecraftforge.common.ForgeDirection;
    013    import net.minecraftforge.common.IPlantable;
    014
    015    public class BlockFarmland extends Block
    016    {
    017        protected BlockFarmland(int par1)
    018        {
    019            super(par1, Material.ground);
    020            this.blockIndexInTexture = 87;
    021            this.setTickRandomly(true);
    022            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F);
    023            this.setLightOpacity(255);
    024        }
    025
    026        /**
    027         * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
    028         * cleared to be reused)
    029         */
    030        public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    031        {
    032            return AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)(par2 + 0), (double)(par3 + 0), (double)(par4 + 0), (double)(par2 + 1), (double)(par3 + 1), (double)(par4 + 1));
    033        }
    034
    035        /**
    036         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
    037         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    038         */
    039        public boolean isOpaqueCube()
    040        {
    041            return false;
    042        }
    043
    044        /**
    045         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    046         */
    047        public boolean renderAsNormalBlock()
    048        {
    049            return false;
    050        }
    051
    052        /**
    053         * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
    054         */
    055        public int getBlockTextureFromSideAndMetadata(int par1, int par2)
    056        {
    057            return par1 == 1 && par2 > 0 ? this.blockIndexInTexture - 1 : (par1 == 1 ? this.blockIndexInTexture : 2);
    058        }
    059
    060        /**
    061         * Ticks the block if it's been scheduled
    062         */
    063        public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    064        {
    065            if (!this.isWaterNearby(par1World, par2, par3, par4) && !par1World.canLightningStrikeAt(par2, par3 + 1, par4))
    066            {
    067                int var6 = par1World.getBlockMetadata(par2, par3, par4);
    068
    069                if (var6 > 0)
    070                {
    071                    par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 - 1);
    072                }
    073                else if (!this.isCropsNearby(par1World, par2, par3, par4))
    074                {
    075                    par1World.setBlockWithNotify(par2, par3, par4, Block.dirt.blockID);
    076                }
    077            }
    078            else
    079            {
    080                par1World.setBlockMetadataWithNotify(par2, par3, par4, 7);
    081            }
    082        }
    083
    084        /**
    085         * Block's chance to react to an entity falling on it.
    086         */
    087        public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6)
    088        {
    089            if (!par1World.isRemote && par1World.rand.nextFloat() < par6 - 0.5F)
    090            {
    091                if (!(par5Entity instanceof EntityPlayer) && !par1World.getGameRules().getGameRuleBooleanValue("mobGriefing"))
    092                {
    093                    return;
    094                }
    095
    096                par1World.setBlockWithNotify(par2, par3, par4, Block.dirt.blockID);
    097            }
    098        }
    099
    100        /**
    101         * returns true if there is at least one cropblock nearby (x-1 to x+1, y+1, z-1 to z+1)
    102         */
    103        private boolean isCropsNearby(World par1World, int par2, int par3, int par4)
    104        {
    105            byte var5 = 0;
    106
    107            for (int var6 = par2 - var5; var6 <= par2 + var5; ++var6)
    108            {
    109                for (int var7 = par4 - var5; var7 <= par4 + var5; ++var7)
    110                {
    111                    int var8 = par1World.getBlockId(var6, par3 + 1, var7);
    112
    113                    Block plant = blocksList[var8];
    114                    if (plant instanceof IPlantable && canSustainPlant(par1World, par2, par3, par4, ForgeDirection.UP, (IPlantable)plant))
    115                    {
    116                        return true;
    117                    }
    118                }
    119            }
    120
    121            return false;
    122        }
    123
    124        /**
    125         * returns true if there's water nearby (x-4 to x+4, y to y+1, k-4 to k+4)
    126         */
    127        private boolean isWaterNearby(World par1World, int par2, int par3, int par4)
    128        {
    129            for (int var5 = par2 - 4; var5 <= par2 + 4; ++var5)
    130            {
    131                for (int var6 = par3; var6 <= par3 + 1; ++var6)
    132                {
    133                    for (int var7 = par4 - 4; var7 <= par4 + 4; ++var7)
    134                    {
    135                        if (par1World.getBlockMaterial(var5, var6, var7) == Material.water)
    136                        {
    137                            return true;
    138                        }
    139                    }
    140                }
    141            }
    142
    143            return false;
    144        }
    145
    146        /**
    147         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
    148         * their own) Args: x, y, z, neighbor blockID
    149         */
    150        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    151        {
    152            super.onNeighborBlockChange(par1World, par2, par3, par4, par5);
    153            Material var6 = par1World.getBlockMaterial(par2, par3 + 1, par4);
    154
    155            if (var6.isSolid())
    156            {
    157                par1World.setBlockWithNotify(par2, par3, par4, Block.dirt.blockID);
    158            }
    159        }
    160
    161        /**
    162         * Returns the ID of the items to drop on destruction.
    163         */
    164        public int idDropped(int par1, Random par2Random, int par3)
    165        {
    166            return Block.dirt.idDropped(0, par2Random, par3);
    167        }
    168
    169        @SideOnly(Side.CLIENT)
    170
    171        /**
    172         * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative)
    173         */
    174        public int idPicked(World par1World, int par2, int par3, int par4)
    175        {
    176            return Block.dirt.blockID;
    177        }
    178    }