001    package net.minecraft.entity;
002    
003    import java.util.Iterator;
004    import java.util.List;
005    import net.minecraft.block.material.Material;
006    import net.minecraft.entity.player.EntityPlayer;
007    import net.minecraft.nbt.NBTTagCompound;
008    import net.minecraft.util.DamageSource;
009    import net.minecraft.util.Direction;
010    import net.minecraft.util.MathHelper;
011    import net.minecraft.world.World;
012    
013    public 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 var2 = (float)this.func_82329_d();
045            float var3 = (float)this.func_82330_g();
046            float var4 = (float)this.func_82329_d();
047    
048            if (par1 != 2 && par1 != 0)
049            {
050                var2 = 0.5F;
051            }
052            else
053            {
054                var4 = 0.5F;
055                this.rotationYaw = this.prevRotationYaw = (float)(Direction.footInvisibleFaceRemap[par1] * 90);
056            }
057    
058            var2 /= 32.0F;
059            var3 /= 32.0F;
060            var4 /= 32.0F;
061            float var5 = (float)this.xPosition + 0.5F;
062            float var6 = (float)this.yPosition + 0.5F;
063            float var7 = (float)this.zPosition + 0.5F;
064            float var8 = 0.5625F;
065    
066            if (par1 == 2)
067            {
068                var7 -= var8;
069            }
070    
071            if (par1 == 1)
072            {
073                var5 -= var8;
074            }
075    
076            if (par1 == 0)
077            {
078                var7 += var8;
079            }
080    
081            if (par1 == 3)
082            {
083                var5 += var8;
084            }
085    
086            if (par1 == 2)
087            {
088                var5 -= this.func_70517_b(this.func_82329_d());
089            }
090    
091            if (par1 == 1)
092            {
093                var7 += this.func_70517_b(this.func_82329_d());
094            }
095    
096            if (par1 == 0)
097            {
098                var5 += this.func_70517_b(this.func_82329_d());
099            }
100    
101            if (par1 == 3)
102            {
103                var7 -= this.func_70517_b(this.func_82329_d());
104            }
105    
106            var6 += this.func_70517_b(this.func_82330_g());
107            this.setPosition((double)var5, (double)var6, (double)var7);
108            float var9 = -0.03125F;
109            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));
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 var1 = Math.max(1, this.func_82329_d() / 16);
146                int var2 = Math.max(1, this.func_82330_g() / 16);
147                int var3 = this.xPosition;
148                int var4 = this.yPosition;
149                int var5 = this.zPosition;
150    
151                if (this.hangingDirection == 2)
152                {
153                    var3 = MathHelper.floor_double(this.posX - (double)((float)this.func_82329_d() / 32.0F));
154                }
155    
156                if (this.hangingDirection == 1)
157                {
158                    var5 = MathHelper.floor_double(this.posZ - (double)((float)this.func_82329_d() / 32.0F));
159                }
160    
161                if (this.hangingDirection == 0)
162                {
163                    var3 = MathHelper.floor_double(this.posX - (double)((float)this.func_82329_d() / 32.0F));
164                }
165    
166                if (this.hangingDirection == 3)
167                {
168                    var5 = MathHelper.floor_double(this.posZ - (double)((float)this.func_82329_d() / 32.0F));
169                }
170    
171                var4 = MathHelper.floor_double(this.posY - (double)((float)this.func_82330_g() / 32.0F));
172    
173                for (int var6 = 0; var6 < var1; ++var6)
174                {
175                    for (int var7 = 0; var7 < var2; ++var7)
176                    {
177                        Material var8;
178    
179                        if (this.hangingDirection != 2 && this.hangingDirection != 0)
180                        {
181                            var8 = this.worldObj.getBlockMaterial(this.xPosition, var4 + var7, var5 + var6);
182                        }
183                        else
184                        {
185                            var8 = this.worldObj.getBlockMaterial(var3 + var6, var4 + var7, this.zPosition);
186                        }
187    
188                        if (!var8.isSolid())
189                        {
190                            return false;
191                        }
192                    }
193                }
194    
195                List var9 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox);
196                Iterator var10 = var9.iterator();
197                Entity var11;
198    
199                do
200                {
201                    if (!var10.hasNext())
202                    {
203                        return true;
204                    }
205    
206                    var11 = (Entity)var10.next();
207                }
208                while (!(var11 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 var3 = null;
243    
244                    if (par1DamageSource.getEntity() instanceof EntityPlayer)
245                    {
246                        var3 = (EntityPlayer)par1DamageSource.getEntity();
247                    }
248    
249                    if (var3 != null && var3.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    }