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