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        /**
216         * Called when the entity is attacked.
217         */
218        public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
219        {
220            if (!this.isDead && !this.worldObj.isRemote)
221            {
222                this.setDead();
223                this.setBeenAttacked();
224                EntityPlayer var3 = null;
225    
226                if (par1DamageSource.getEntity() instanceof EntityPlayer)
227                {
228                    var3 = (EntityPlayer)par1DamageSource.getEntity();
229                }
230    
231                if (var3 != null && var3.capabilities.isCreativeMode)
232                {
233                    return true;
234                }
235    
236                this.dropItemStack();
237            }
238    
239            return true;
240        }
241    
242        /**
243         * Tries to moves the entity by the passed in displacement. Args: x, y, z
244         */
245        public void moveEntity(double par1, double par3, double par5)
246        {
247            if (!this.worldObj.isRemote && !this.isDead && par1 * par1 + par3 * par3 + par5 * par5 > 0.0D)
248            {
249                this.setDead();
250                this.dropItemStack();
251            }
252        }
253    
254        /**
255         * Adds to the current velocity of the entity. Args: x, y, z
256         */
257        public void addVelocity(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         * (abstract) Protected helper method to write subclass entity data to NBT.
268         */
269        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
270        {
271            par1NBTTagCompound.setByte("Direction", (byte)this.field_82332_a);
272            par1NBTTagCompound.setInteger("TileX", this.xPosition);
273            par1NBTTagCompound.setInteger("TileY", this.yPosition);
274            par1NBTTagCompound.setInteger("TileZ", this.zPosition);
275    
276            switch (this.field_82332_a)
277            {
278                case 0:
279                    par1NBTTagCompound.setByte("Dir", (byte)2);
280                    break;
281                case 1:
282                    par1NBTTagCompound.setByte("Dir", (byte)1);
283                    break;
284                case 2:
285                    par1NBTTagCompound.setByte("Dir", (byte)0);
286                    break;
287                case 3:
288                    par1NBTTagCompound.setByte("Dir", (byte)3);
289            }
290        }
291    
292        /**
293         * (abstract) Protected helper method to read subclass entity data from NBT.
294         */
295        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
296        {
297            if (par1NBTTagCompound.hasKey("Direction"))
298            {
299                this.field_82332_a = par1NBTTagCompound.getByte("Direction");
300            }
301            else
302            {
303                switch (par1NBTTagCompound.getByte("Dir"))
304                {
305                    case 0:
306                        this.field_82332_a = 2;
307                        break;
308                    case 1:
309                        this.field_82332_a = 1;
310                        break;
311                    case 2:
312                        this.field_82332_a = 0;
313                        break;
314                    case 3:
315                        this.field_82332_a = 3;
316                }
317            }
318    
319            this.xPosition = par1NBTTagCompound.getInteger("TileX");
320            this.yPosition = par1NBTTagCompound.getInteger("TileY");
321            this.zPosition = par1NBTTagCompound.getInteger("TileZ");
322            this.func_82328_a(this.field_82332_a);
323        }
324    
325        public abstract int func_82329_d();
326    
327        public abstract int func_82330_g();
328    
329        /**
330         * Drop the item currently on this item frame.
331         */
332        public abstract void dropItemStack();
333    }