package net.minecraft.entity.item;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.Iterator;
import net.minecraft.block.Block;
import net.minecraft.block.BlockSand;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class EntityFallingSand extends Entity
{
public int blockID;
public int metadata;
/** How long the block has been falling for. */
public int fallTime;
public boolean shouldDropItem;
private boolean isBreakingAnvil;
private boolean isAnvil;
/** Maximum amount of damage dealt to entities hit by falling block */
private int fallHurtMax;
/** Actual damage dealt to entities hit by falling block */
private float fallHurtAmount;
public NBTTagCompound fallingBlockTileEntityData;
public EntityFallingSand(World par1World)
{
super(par1World);
this.fallTime = 0;
this.shouldDropItem = true;
this.isBreakingAnvil = false;
this.isAnvil = false;
this.fallHurtMax = 40;
this.fallHurtAmount = 2.0F;
this.fallingBlockTileEntityData = null;
}
public EntityFallingSand(World par1World, double par2, double par4, double par6, int par8)
{
this(par1World, par2, par4, par6, par8, 0);
}
public EntityFallingSand(World par1World, double par2, double par4, double par6, int par8, int par9)
{
super(par1World);
this.fallTime = 0;
this.shouldDropItem = true;
this.isBreakingAnvil = false;
this.isAnvil = false;
this.fallHurtMax = 40;
this.fallHurtAmount = 2.0F;
this.fallingBlockTileEntityData = null;
this.blockID = par8;
this.metadata = par9;
this.preventEntitySpawning = true;
this.setSize(0.98F, 0.98F);
this.yOffset = this.height / 2.0F;
this.setPosition(par2, par4, par6);
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
this.prevPosX = par2;
this.prevPosY = par4;
this.prevPosZ = par6;
}
/**
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
* prevent them from trampling crops
*/
protected boolean canTriggerWalking()
{
return false;
}
protected void entityInit() {}
/**
* Returns true if other Entities should be prevented from moving through this Entity.
*/
public boolean canBeCollidedWith()
{
return !this.isDead;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
if (this.blockID == 0)
{
this.setDead();
}
else
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
++this.fallTime;
this.motionY -= 0.03999999910593033D;
this.moveEntity(this.motionX, this.motionY, this.motionZ);
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
this.motionZ *= 0.9800000190734863D;
if (!this.worldObj.isRemote)
{
int i = MathHelper.floor_double(this.posX);
int j = MathHelper.floor_double(this.posY);
int k = MathHelper.floor_double(this.posZ);
if (this.fallTime == 1)
{
if (this.worldObj.getBlockId(i, j, k) != this.blockID)
{
this.setDead();
return;
}
this.worldObj.setBlockToAir(i, j, k);
}
if (this.onGround)
{
this.motionX *= 0.699999988079071D;
this.motionZ *= 0.699999988079071D;
this.motionY *= -0.5D;
if (this.worldObj.getBlockId(i, j, k) != Block.pistonMoving.blockID)
{
this.setDead();
if (!this.isBreakingAnvil && this.worldObj.canPlaceEntityOnSide(this.blockID, i, j, k, true, 1, (Entity)null, (ItemStack)null) && !BlockSand.canFallBelow(this.worldObj, i, j - 1, k) && this.worldObj.setBlock(i, j, k, this.blockID, this.metadata, 3))
{
if (Block.blocksList[this.blockID] instanceof BlockSand)
{
((BlockSand)Block.blocksList[this.blockID]).onFinishFalling(this.worldObj, i, j, k, this.metadata);
}
if (this.fallingBlockTileEntityData != null && Block.blocksList[this.blockID] instanceof ITileEntityProvider)
{
TileEntity tileentity = this.worldObj.getBlockTileEntity(i, j, k);
if (tileentity != null)
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
tileentity.writeToNBT(nbttagcompound);
Iterator iterator = this.fallingBlockTileEntityData.getTags().iterator();
while (iterator.hasNext())
{
NBTBase nbtbase = (NBTBase)iterator.next();
if (!nbtbase.getName().equals("x") && !nbtbase.getName().equals("y") && !nbtbase.getName().equals("z"))
{
nbttagcompound.setTag(nbtbase.getName(), nbtbase.copy());
}
}
tileentity.readFromNBT(nbttagcompound);
tileentity.onInventoryChanged();
}
}
}
else if (this.shouldDropItem && !this.isBreakingAnvil)
{
this.entityDropItem(new ItemStack(this.blockID, 1, Block.blocksList[this.blockID].damageDropped(this.metadata)), 0.0F);
}
}
}
else if (this.fallTime > 100 && !this.worldObj.isRemote && (j < 1 || j > 256) || this.fallTime > 600)
{
if (this.shouldDropItem)
{
this.entityDropItem(new ItemStack(this.blockID, 1, Block.blocksList[this.blockID].damageDropped(this.metadata)), 0.0F);
}
this.setDead();
}
}
}
}
/**
* Called when the mob is falling. Calculates and applies fall damage.
*/
protected void fall(float par1)
{
if (this.isAnvil)
{
int i = MathHelper.ceiling_float_int(par1 - 1.0F);
if (i > 0)
{
ArrayList arraylist = new ArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox));
DamageSource damagesource = this.blockID == Block.anvil.blockID ? DamageSource.anvil : DamageSource.fallingBlock;
Iterator iterator = arraylist.iterator();
while (iterator.hasNext())
{
Entity entity = (Entity)iterator.next();
entity.attackEntityFrom(damagesource, Math.min(MathHelper.floor_float((float)i * this.fallHurtAmount), this.fallHurtMax));
}
if (this.blockID == Block.anvil.blockID && (double)this.rand.nextFloat() < 0.05000000074505806D + (double)i * 0.05D)
{
int j = this.metadata >> 2;
int k = this.metadata & 3;
++j;
if (j > 2)
{
this.isBreakingAnvil = true;
}
else
{
this.metadata = k | j << 2;
}
}
}
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
{
par1NBTTagCompound.setByte("Tile", (byte)this.blockID);
par1NBTTagCompound.setInteger("TileID", this.blockID);
par1NBTTagCompound.setByte("Data", (byte)this.metadata);
par1NBTTagCompound.setByte("Time", (byte)this.fallTime);
par1NBTTagCompound.setBoolean("DropItem", this.shouldDropItem);
par1NBTTagCompound.setBoolean("HurtEntities", this.isAnvil);
par1NBTTagCompound.setFloat("FallHurtAmount", this.fallHurtAmount);
par1NBTTagCompound.setInteger("FallHurtMax", this.fallHurtMax);
if (this.fallingBlockTileEntityData != null)
{
par1NBTTagCompound.setCompoundTag("TileEntityData", this.fallingBlockTileEntityData);
}
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
{
if (par1NBTTagCompound.hasKey("TileID"))
{
this.blockID = par1NBTTagCompound.getInteger("TileID");
}
else
{
this.blockID = par1NBTTagCompound.getByte("Tile") & 255;
}
this.metadata = par1NBTTagCompound.getByte("Data") & 255;
this.fallTime = par1NBTTagCompound.getByte("Time") & 255;
if (par1NBTTagCompound.hasKey("HurtEntities"))
{
this.isAnvil = par1NBTTagCompound.getBoolean("HurtEntities");
this.fallHurtAmount = par1NBTTagCompound.getFloat("FallHurtAmount");
this.fallHurtMax = par1NBTTagCompound.getInteger("FallHurtMax");
}
else if (this.blockID == Block.anvil.blockID)
{
this.isAnvil = true;
}
if (par1NBTTagCompound.hasKey("DropItem"))
{
this.shouldDropItem = par1NBTTagCompound.getBoolean("DropItem");
}
if (par1NBTTagCompound.hasKey("TileEntityData"))
{
this.fallingBlockTileEntityData = par1NBTTagCompound.getCompoundTag("TileEntityData");
}
if (this.blockID == 0)
{
this.blockID = Block.sand.blockID;
}
}
public void setIsAnvil(boolean par1)
{
this.isAnvil = par1;
}
public void func_85029_a(CrashReportCategory par1CrashReportCategory)
{
super.func_85029_a(par1CrashReportCategory);
par1CrashReportCategory.addCrashSection("Immitating block ID", Integer.valueOf(this.blockID));
par1CrashReportCategory.addCrashSection("Immitating block data", Integer.valueOf(this.metadata));
}
@SideOnly(Side.CLIENT)
public float getShadowSize()
{
return 0.0F;
}
@SideOnly(Side.CLIENT)
public World getWorld()
{
return this.worldObj;
}
@SideOnly(Side.CLIENT)
/**
* Return whether this entity should be rendered as on fire.
*/
public boolean canRenderOnFire()
{
return false;
}
}