001 package net.minecraft.block;
002
003 import java.util.Random;
004 import net.minecraft.block.material.Material;
005 import net.minecraft.creativetab.CreativeTabs;
006 import net.minecraft.entity.item.EntityFallingSand;
007 import net.minecraft.world.World;
008
009 public 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, int par2)
015 {
016 super(par1, par2, Material.sand);
017 this.setCreativeTab(CreativeTabs.tabBlock);
018 }
019
020 public BlockSand(int par1, int par2, Material par3Material)
021 {
022 super(par1, par2, par3Material);
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());
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());
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 var8 = 32;
061
062 if (!fallInstantly && par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, par3 + var8, par4 + var8))
063 {
064 if (!par1World.isRemote)
065 {
066 EntityFallingSand var9 = 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(var9);
068 par1World.spawnEntityInWorld(var9);
069 }
070 }
071 else
072 {
073 par1World.setBlockWithNotify(par2, par3, par4, 0);
074
075 while (canFallBelow(par1World, par2, par3 - 1, par4) && par3 > 0)
076 {
077 --par3;
078 }
079
080 if (par3 > 0)
081 {
082 par1World.setBlockWithNotify(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()
097 {
098 return 5;
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 var4 = par0World.getBlockId(par1, par2, par3);
107
108 if (var4 == 0)
109 {
110 return true;
111 }
112 else if (var4 == Block.fire.blockID)
113 {
114 return true;
115 }
116 else
117 {
118 Material var5 = Block.blocksList[var4].blockMaterial;
119 return var5 == Material.water ? true : var5 == 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 }