    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    }