    001package net.minecraft.entity;
    002
    003import java.util.Iterator;
    004import java.util.List;
    005import net.minecraft.block.material.Material;
    006import net.minecraft.entity.player.EntityPlayer;
    007import net.minecraft.nbt.NBTTagCompound;
    008import net.minecraft.util.DamageSource;
    009import net.minecraft.util.Direction;
    010import net.minecraft.util.MathHelper;
    011import net.minecraft.world.World;
    012
    013public abstract class EntityHanging extends Entity
    014{
    015    private int tickCounter1;
    016    public int hangingDirection;
    017    public int xPosition;
    018    public int yPosition;
    019    public int zPosition;
    020
    021    public EntityHanging(World par1World)
    022    {
    023        super(par1World);
    024        this.tickCounter1 = 0;
    025        this.hangingDirection = 0;
    026        this.yOffset = 0.0F;
    027        this.setSize(0.5F, 0.5F);
    028    }
    029
    030    public EntityHanging(World par1World, int par2, int par3, int par4, int par5)
    031    {
    032        this(par1World);
    033        this.xPosition = par2;
    034        this.yPosition = par3;
    035        this.zPosition = par4;
    036    }
    037
    038    protected void entityInit() {}
    039
    040    public void setDirection(int par1)
    041    {
    042        this.hangingDirection = par1;
    043        this.prevRotationYaw = this.rotationYaw = (float)(par1 * 90);
    044        float f = (float)this.func_82329_d();
    045        float f1 = (float)this.func_82330_g();
    046        float f2 = (float)this.func_82329_d();
    047
    048        if (par1 != 2 && par1 != 0)
    049        {
    050            f = 0.5F;
    051        }
    052        else
    053        {
    054            f2 = 0.5F;
    055            this.rotationYaw = this.prevRotationYaw = (float)(Direction.footInvisibleFaceRemap[par1] * 90);
    056        }
    057
    058        f /= 32.0F;
    059        f1 /= 32.0F;
    060        f2 /= 32.0F;
    061        float f3 = (float)this.xPosition + 0.5F;
    062        float f4 = (float)this.yPosition + 0.5F;
    063        float f5 = (float)this.zPosition + 0.5F;
    064        float f6 = 0.5625F;
    065
    066        if (par1 == 2)
    067        {
    068            f5 -= f6;
    069        }
    070
    071        if (par1 == 1)
    072        {
    073            f3 -= f6;
    074        }
    075
    076        if (par1 == 0)
    077        {
    078            f5 += f6;
    079        }
    080
    081        if (par1 == 3)
    082        {
    083            f3 += f6;
    084        }
    085
    086        if (par1 == 2)
    087        {
    088            f3 -= this.func_70517_b(this.func_82329_d());
    089        }
    090
    091        if (par1 == 1)
    092        {
    093            f5 += this.func_70517_b(this.func_82329_d());
    094        }
    095
    096        if (par1 == 0)
    097        {
    098            f3 += this.func_70517_b(this.func_82329_d());
    099        }
    100
    101        if (par1 == 3)
    102        {
    103            f5 -= this.func_70517_b(this.func_82329_d());
    104        }
    105
    106        f4 += this.func_70517_b(this.func_82330_g());
    107        this.setPosition((double)f3, (double)f4, (double)f5);
    108        float f7 = -0.03125F;
    109        this.boundingBox.setBounds((double)(f3 - f - f7), (double)(f4 - f1 - f7), (double)(f5 - f2 - f7), (double)(f3 + f + f7), (double)(f4 + f1 + f7), (double)(f5 + f2 + f7));
    110    }
    111
    112    private float func_70517_b(int par1)
    113    {
    114        return par1 == 32 ? 0.5F : (par1 == 64 ? 0.5F : 0.0F);
    115    }
    116
    117    /**
    118     * Called to update the entity's position/logic.
    119     */
    120    public void onUpdate()
    121    {
    122        if (this.tickCounter1++ == 100 && !this.worldObj.isRemote)
    123        {
    124            this.tickCounter1 = 0;
    125
    126            if (!this.isDead && !this.onValidSurface())
    127            {
    128                this.setDead();
    129                this.dropItemStack();
    130            }
    131        }
    132    }
    133
    134    /**
    135     * checks to make sure painting can be placed there
    136     */
    137    public boolean onValidSurface()
    138    {
    139        if (!this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty())
    140        {
    141            return false;
    142        }
    143        else
    144        {
    145            int i = Math.max(1, this.func_82329_d() / 16);
    146            int j = Math.max(1, this.func_82330_g() / 16);
    147            int k = this.xPosition;
    148            int l = this.yPosition;
    149            int i1 = this.zPosition;
    150
    151            if (this.hangingDirection == 2)
    152            {
    153                k = MathHelper.floor_double(this.posX - (double)((float)this.func_82329_d() / 32.0F));
    154            }
    155
    156            if (this.hangingDirection == 1)
    157            {
    158                i1 = MathHelper.floor_double(this.posZ - (double)((float)this.func_82329_d() / 32.0F));
    159            }
    160
    161            if (this.hangingDirection == 0)
    162            {
    163                k = MathHelper.floor_double(this.posX - (double)((float)this.func_82329_d() / 32.0F));
    164            }
    165
    166            if (this.hangingDirection == 3)
    167            {
    168                i1 = MathHelper.floor_double(this.posZ - (double)((float)this.func_82329_d() / 32.0F));
    169            }
    170
    171            l = MathHelper.floor_double(this.posY - (double)((float)this.func_82330_g() / 32.0F));
    172
    173            for (int j1 = 0; j1 < i; ++j1)
    174            {
    175                for (int k1 = 0; k1 < j; ++k1)
    176                {
    177                    Material material;
    178
    179                    if (this.hangingDirection != 2 && this.hangingDirection != 0)
    180                    {
    181                        material = this.worldObj.getBlockMaterial(this.xPosition, l + k1, i1 + j1);
    182                    }
    183                    else
    184                    {
    185                        material = this.worldObj.getBlockMaterial(k + j1, l + k1, this.zPosition);
    186                    }
    187
    188                    if (!material.isSolid())
    189                    {
    190                        return false;
    191                    }
    192                }
    193            }
    194
    195            List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox);
    196            Iterator iterator = list.iterator();
    197            Entity entity;
    198
    199            do
    200            {
    201                if (!iterator.hasNext())
    202                {
    203                    return true;
    204                }
    205
    206                entity = (Entity)iterator.next();
    207            }
    208            while (!(entity instanceof EntityHanging));
    209
    210            return false;
    211        }
    212    }
    213
    214    /**
    215     * Returns true if other Entities should be prevented from moving through this Entity.
    216     */
    217    public boolean canBeCollidedWith()
    218    {
    219        return true;
    220    }
    221
    222    public boolean func_85031_j(Entity par1Entity)
    223    {
    224        return par1Entity instanceof EntityPlayer ? this.attackEntityFrom(DamageSource.causePlayerDamage((EntityPlayer)par1Entity), 0) : false;
    225    }
    226
    227    /**
    228     * Called when the entity is attacked.
    229     */
    230    public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
    231    {
    232        if (this.isEntityInvulnerable())
    233        {
    234            return false;
    235        }
    236        else
    237        {
    238            if (!this.isDead && !this.worldObj.isRemote)
    239            {
    240                this.setDead();
    241                this.setBeenAttacked();
    242                EntityPlayer entityplayer = null;
    243
    244                if (par1DamageSource.getEntity() instanceof EntityPlayer)
    245                {
    246                    entityplayer = (EntityPlayer)par1DamageSource.getEntity();
    247                }
    248
    249                if (entityplayer != null && entityplayer.capabilities.isCreativeMode)
    250                {
    251                    return true;
    252                }
    253
    254                this.dropItemStack();
    255            }
    256
    257            return true;
    258        }
    259    }
    260
    261    /**
    262     * Tries to moves the entity by the passed in displacement. Args: x, y, z
    263     */
    264    public void moveEntity(double par1, double par3, double par5)
    265    {
    266        if (!this.worldObj.isRemote && !this.isDead && par1 * par1 + par3 * par3 + par5 * par5 > 0.0D)
    267        {
    268            this.setDead();
    269            this.dropItemStack();
    270        }
    271    }
    272
    273    /**
    274     * Adds to the current velocity of the entity. Args: x, y, z
    275     */
    276    public void addVelocity(double par1, double par3, double par5)
    277    {
    278        if (!this.worldObj.isRemote && !this.isDead && par1 * par1 + par3 * par3 + par5 * par5 > 0.0D)
    279        {
    280            this.setDead();
    281            this.dropItemStack();
    282        }
    283    }
    284
    285    /**
    286     * (abstract) Protected helper method to write subclass entity data to NBT.
    287     */
    288    public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    289    {
    290        par1NBTTagCompound.setByte("Direction", (byte)this.hangingDirection);
    291        par1NBTTagCompound.setInteger("TileX", this.xPosition);
    292        par1NBTTagCompound.setInteger("TileY", this.yPosition);
    293        par1NBTTagCompound.setInteger("TileZ", this.zPosition);
    294
    295        switch (this.hangingDirection)
    296        {
    297            case 0:
    298                par1NBTTagCompound.setByte("Dir", (byte)2);
    299                break;
    300            case 1:
    301                par1NBTTagCompound.setByte("Dir", (byte)1);
    302                break;
    303            case 2:
    304                par1NBTTagCompound.setByte("Dir", (byte)0);
    305                break;
    306            case 3:
    307                par1NBTTagCompound.setByte("Dir", (byte)3);
    308        }
    309    }
    310
    311    /**
    312     * (abstract) Protected helper method to read subclass entity data from NBT.
    313     */
    314    public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    315    {
    316        if (par1NBTTagCompound.hasKey("Direction"))
    317        {
    318            this.hangingDirection = par1NBTTagCompound.getByte("Direction");
    319        }
    320        else
    321        {
    322            switch (par1NBTTagCompound.getByte("Dir"))
    323            {
    324                case 0:
    325                    this.hangingDirection = 2;
    326                    break;
    327                case 1:
    328                    this.hangingDirection = 1;
    329                    break;
    330                case 2:
    331                    this.hangingDirection = 0;
    332                    break;
    333                case 3:
    334                    this.hangingDirection = 3;
    335            }
    336        }
    337
    338        this.xPosition = par1NBTTagCompound.getInteger("TileX");
    339        this.yPosition = par1NBTTagCompound.getInteger("TileY");
    340        this.zPosition = par1NBTTagCompound.getInteger("TileZ");
    341        this.setDirection(this.hangingDirection);
    342    }
    343
    344    public abstract int func_82329_d();
    345
    346    public abstract int func_82330_g();
    347
    348    /**
    349     * Drop the item currently on this item frame.
    350     */
    351    public abstract void dropItemStack();
    352}