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