001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 import java.util.ArrayList; 006 import java.util.Iterator; 007 008 public class EntityFallingSand extends Entity 009 { 010 public int blockID; 011 public int field_70285_b; 012 013 /** How long the block has been falling for. */ 014 public int fallTime; 015 public boolean field_70284_d; 016 private boolean field_82157_e; 017 private boolean field_82155_f; 018 private int field_82156_g; 019 private float field_82158_h; 020 021 public EntityFallingSand(World par1World) 022 { 023 super(par1World); 024 this.fallTime = 0; 025 this.field_70284_d = true; 026 this.field_82157_e = false; 027 this.field_82155_f = false; 028 this.field_82156_g = 20; 029 this.field_82158_h = 2.0F; 030 } 031 032 public EntityFallingSand(World par1World, double par2, double par4, double par6, int par8) 033 { 034 this(par1World, par2, par4, par6, par8, 0); 035 } 036 037 public EntityFallingSand(World par1World, double par2, double par4, double par6, int par8, int par9) 038 { 039 super(par1World); 040 this.fallTime = 0; 041 this.field_70284_d = true; 042 this.field_82157_e = false; 043 this.field_82155_f = false; 044 this.field_82156_g = 20; 045 this.field_82158_h = 2.0F; 046 this.blockID = par8; 047 this.field_70285_b = par9; 048 this.preventEntitySpawning = true; 049 this.setSize(0.98F, 0.98F); 050 this.yOffset = this.height / 2.0F; 051 this.setPosition(par2, par4, par6); 052 this.motionX = 0.0D; 053 this.motionY = 0.0D; 054 this.motionZ = 0.0D; 055 this.prevPosX = par2; 056 this.prevPosY = par4; 057 this.prevPosZ = par6; 058 } 059 060 /** 061 * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to 062 * prevent them from trampling crops 063 */ 064 protected boolean canTriggerWalking() 065 { 066 return false; 067 } 068 069 protected void entityInit() {} 070 071 /** 072 * Returns true if other Entities should be prevented from moving through this Entity. 073 */ 074 public boolean canBeCollidedWith() 075 { 076 return !this.isDead; 077 } 078 079 /** 080 * Called to update the entity's position/logic. 081 */ 082 public void onUpdate() 083 { 084 if (this.blockID == 0) 085 { 086 this.setDead(); 087 } 088 else 089 { 090 this.prevPosX = this.posX; 091 this.prevPosY = this.posY; 092 this.prevPosZ = this.posZ; 093 ++this.fallTime; 094 this.motionY -= 0.03999999910593033D; 095 this.moveEntity(this.motionX, this.motionY, this.motionZ); 096 this.motionX *= 0.9800000190734863D; 097 this.motionY *= 0.9800000190734863D; 098 this.motionZ *= 0.9800000190734863D; 099 100 if (!this.worldObj.isRemote) 101 { 102 int var1 = MathHelper.floor_double(this.posX); 103 int var2 = MathHelper.floor_double(this.posY); 104 int var3 = MathHelper.floor_double(this.posZ); 105 106 if (this.fallTime == 1) 107 { 108 if (this.fallTime == 1 && this.worldObj.getBlockId(var1, var2, var3) == this.blockID) 109 { 110 this.worldObj.setBlockWithNotify(var1, var2, var3, 0); 111 } 112 else 113 { 114 this.setDead(); 115 } 116 } 117 118 if (this.onGround) 119 { 120 this.motionX *= 0.699999988079071D; 121 this.motionZ *= 0.699999988079071D; 122 this.motionY *= -0.5D; 123 124 if (this.worldObj.getBlockId(var1, var2, var3) != Block.pistonMoving.blockID) 125 { 126 this.setDead(); 127 128 if (!this.field_82157_e && this.worldObj.canPlaceEntityOnSide(this.blockID, var1, var2, var3, true, 1, (Entity)null) && !BlockSand.canFallBelow(this.worldObj, var1, var2 - 1, var3) && this.worldObj.setBlockAndMetadataWithNotify(var1, var2, var3, this.blockID, this.field_70285_b)) 129 { 130 if (Block.blocksList[this.blockID] instanceof BlockSand) 131 { 132 ((BlockSand)Block.blocksList[this.blockID]).onFinishFalling(this.worldObj, var1, var2, var3, this.field_70285_b); 133 } 134 } 135 else if (this.field_70284_d && !this.field_82157_e) 136 { 137 this.entityDropItem(new ItemStack(this.blockID, 1, Block.blocksList[this.blockID].damageDropped(this.field_70285_b)), 0.0F); 138 } 139 } 140 } 141 else if (this.fallTime > 100 && !this.worldObj.isRemote && (var2 < 1 || var2 > 256) || this.fallTime > 600) 142 { 143 if (this.field_70284_d) 144 { 145 this.entityDropItem(new ItemStack(this.blockID, 1, Block.blocksList[this.blockID].damageDropped(this.field_70285_b)), 0.0F); 146 } 147 148 this.setDead(); 149 } 150 } 151 } 152 } 153 154 /** 155 * Called when the mob is falling. Calculates and applies fall damage. 156 */ 157 protected void fall(float par1) 158 { 159 if (this.field_82155_f) 160 { 161 int var2 = MathHelper.ceiling_float_int(par1 - 1.0F); 162 163 if (var2 > 0) 164 { 165 ArrayList var3 = new ArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox)); 166 DamageSource var4 = this.blockID == Block.anvil.blockID ? DamageSource.anvil : DamageSource.fallingBlock; 167 Iterator var5 = var3.iterator(); 168 169 while (var5.hasNext()) 170 { 171 Entity var6 = (Entity)var5.next(); 172 var6.attackEntityFrom(var4, Math.min(MathHelper.floor_float((float)var2 * this.field_82158_h), this.field_82156_g)); 173 } 174 175 if (this.blockID == Block.anvil.blockID && (double)this.rand.nextFloat() < 0.05000000074505806D + (double)var2 * 0.05D) 176 { 177 int var7 = this.field_70285_b >> 2; 178 int var8 = this.field_70285_b & 3; 179 ++var7; 180 181 if (var7 > 2) 182 { 183 this.field_82157_e = true; 184 } 185 else 186 { 187 this.field_70285_b = var8 | var7 << 2; 188 } 189 } 190 } 191 } 192 } 193 194 /** 195 * (abstract) Protected helper method to write subclass entity data to NBT. 196 */ 197 protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) 198 { 199 par1NBTTagCompound.setByte("Tile", (byte)this.blockID); 200 par1NBTTagCompound.setByte("Data", (byte)this.field_70285_b); 201 par1NBTTagCompound.setByte("Time", (byte)this.fallTime); 202 par1NBTTagCompound.setBoolean("DropItem", this.field_70284_d); 203 par1NBTTagCompound.setBoolean("HurtEntities", this.field_82155_f); 204 par1NBTTagCompound.setFloat("FallHurtAmount", this.field_82158_h); 205 par1NBTTagCompound.setInteger("FallHurtMax", this.field_82156_g); 206 } 207 208 /** 209 * (abstract) Protected helper method to read subclass entity data from NBT. 210 */ 211 protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) 212 { 213 this.blockID = par1NBTTagCompound.getByte("Tile") & 255; 214 this.field_70285_b = par1NBTTagCompound.getByte("Data") & 255; 215 this.fallTime = par1NBTTagCompound.getByte("Time") & 255; 216 217 if (par1NBTTagCompound.hasKey("HurtEntities")) 218 { 219 this.field_82155_f = par1NBTTagCompound.getBoolean("HurtEntities"); 220 this.field_82158_h = par1NBTTagCompound.getFloat("FallHurtAmount"); 221 this.field_82156_g = par1NBTTagCompound.getInteger("FallHurtMax"); 222 } 223 else if (this.blockID == Block.anvil.blockID) 224 { 225 this.field_82155_f = true; 226 } 227 228 if (par1NBTTagCompound.hasKey("DropItem")) 229 { 230 this.field_70284_d = par1NBTTagCompound.getBoolean("DropItem"); 231 } 232 233 if (this.blockID == 0) 234 { 235 this.blockID = Block.sand.blockID; 236 } 237 } 238 239 @SideOnly(Side.CLIENT) 240 public float getShadowSize() 241 { 242 return 0.0F; 243 } 244 245 @SideOnly(Side.CLIENT) 246 public World getWorld() 247 { 248 return this.worldObj; 249 } 250 251 public void func_82154_e(boolean par1) 252 { 253 this.field_82155_f = par1; 254 } 255 256 /** 257 * Returns true if the entity is on fire. Used by render to add the fire effect on rendering. 258 */ 259 public boolean isBurning() 260 { 261 return false; 262 } 263 }