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 }