    001package net.minecraft.block;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.Random;
    006import net.minecraft.block.material.Material;
    007import net.minecraft.entity.Entity;
    008import net.minecraft.entity.player.EntityPlayer;
    009import net.minecraft.util.AxisAlignedBB;
    010import net.minecraft.world.World;
    011
    012import net.minecraftforge.common.ForgeDirection;
    013import net.minecraftforge.common.IPlantable;
    014
    015public 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}