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.rotateOpposite[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}