    001package net.minecraft.block;
    002
    003import java.util.Random;
    004import net.minecraft.block.material.Material;
    005import net.minecraft.creativetab.CreativeTabs;
    006import net.minecraft.entity.item.EntityFallingSand;
    007import net.minecraft.world.World;
    008
    009public class BlockSand extends Block
    010{
    011    /** Do blocks fall instantly to where they stop or do they fall over time */
    012    public static boolean fallInstantly = false;
    013
    014    public BlockSand(int par1)
    015    {
    016        super(par1, Material.sand);
    017        this.setCreativeTab(CreativeTabs.tabBlock);
    018    }
    019
    020    public BlockSand(int par1, Material par2Material)
    021    {
    022        super(par1, par2Material);
    023    }
    024
    025    /**
    026     * Called whenever the block is added into the world. Args: world, x, y, z
    027     */
    028    public void onBlockAdded(World par1World, int par2, int par3, int par4)
    029    {
    030        par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World));
    031    }
    032
    033    /**
    034     * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
    035     * their own) Args: x, y, z, neighbor blockID
    036     */
    037    public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    038    {
    039        par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World));
    040    }
    041
    042    /**
    043     * Ticks the block if it's been scheduled
    044     */
    045    public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    046    {
    047        if (!par1World.isRemote)
    048        {
    049            this.tryToFall(par1World, par2, par3, par4);
    050        }
    051    }
    052
    053    /**
    054     * If there is space to fall below will start this block falling
    055     */
    056    private void tryToFall(World par1World, int par2, int par3, int par4)
    057    {
    058        if (canFallBelow(par1World, par2, par3 - 1, par4) && par3 >= 0)
    059        {
    060            byte b0 = 32;
    061
    062            if (!fallInstantly && par1World.checkChunksExist(par2 - b0, par3 - b0, par4 - b0, par2 + b0, par3 + b0, par4 + b0))
    063            {
    064                if (!par1World.isRemote)
    065                {
    066                    EntityFallingSand entityfallingsand = new EntityFallingSand(par1World, (double)((float)par2 + 0.5F), (double)((float)par3 + 0.5F), (double)((float)par4 + 0.5F), this.blockID, par1World.getBlockMetadata(par2, par3, par4));
    067                    this.onStartFalling(entityfallingsand);
    068                    par1World.spawnEntityInWorld(entityfallingsand);
    069                }
    070            }
    071            else
    072            {
    073                par1World.setBlockToAir(par2, par3, par4);
    074
    075                while (canFallBelow(par1World, par2, par3 - 1, par4) && par3 > 0)
    076                {
    077                    --par3;
    078                }
    079
    080                if (par3 > 0)
    081                {
    082                    par1World.setBlock(par2, par3, par4, this.blockID);
    083                }
    084            }
    085        }
    086    }
    087
    088    /**
    089     * Called when the falling block entity for this block is created
    090     */
    091    protected void onStartFalling(EntityFallingSand par1EntityFallingSand) {}
    092
    093    /**
    094     * How many world ticks before ticking
    095     */
    096    public int tickRate(World par1World)
    097    {
    098        return 2;
    099    }
    100
    101    /**
    102     * Checks to see if the sand can fall into the block below it
    103     */
    104    public static boolean canFallBelow(World par0World, int par1, int par2, int par3)
    105    {
    106        int l = par0World.getBlockId(par1, par2, par3);
    107
    108        if (l == 0)
    109        {
    110            return true;
    111        }
    112        else if (l == Block.fire.blockID)
    113        {
    114            return true;
    115        }
    116        else
    117        {
    118            Material material = Block.blocksList[l].blockMaterial;
    119            return material == Material.water ? true : material == Material.lava;
    120        }
    121    }
    122
    123    /**
    124     * Called when the falling block entity for this block hits the ground and turns back into a block
    125     */
    126    public void onFinishFalling(World par1World, int par2, int par3, int par4, int par5) {}
    127}