001    package net.minecraft.entity.passive;
002    
003    import net.minecraft.entity.EntityAgeable;
004    import net.minecraft.entity.ai.EntityAIControlledByPlayer;
005    import net.minecraft.entity.ai.EntityAIFollowParent;
006    import net.minecraft.entity.ai.EntityAILookIdle;
007    import net.minecraft.entity.ai.EntityAIMate;
008    import net.minecraft.entity.ai.EntityAIPanic;
009    import net.minecraft.entity.ai.EntityAISwimming;
010    import net.minecraft.entity.ai.EntityAITempt;
011    import net.minecraft.entity.ai.EntityAIWander;
012    import net.minecraft.entity.ai.EntityAIWatchClosest;
013    import net.minecraft.entity.effect.EntityLightningBolt;
014    import net.minecraft.entity.monster.EntityPigZombie;
015    import net.minecraft.entity.player.EntityPlayer;
016    import net.minecraft.item.Item;
017    import net.minecraft.item.ItemStack;
018    import net.minecraft.nbt.NBTTagCompound;
019    import net.minecraft.stats.AchievementList;
020    import net.minecraft.world.World;
021    
022    public class EntityPig extends EntityAnimal
023    {
024        /** AI task for player control. */
025        private final EntityAIControlledByPlayer aiControlledByPlayer;
026    
027        public EntityPig(World par1World)
028        {
029            super(par1World);
030            this.texture = "/mob/pig.png";
031            this.setSize(0.9F, 0.9F);
032            this.getNavigator().setAvoidsWater(true);
033            float var2 = 0.25F;
034            this.tasks.addTask(0, new EntityAISwimming(this));
035            this.tasks.addTask(1, new EntityAIPanic(this, 0.38F));
036            this.tasks.addTask(2, this.aiControlledByPlayer = new EntityAIControlledByPlayer(this, 0.34F));
037            this.tasks.addTask(3, new EntityAIMate(this, var2));
038            this.tasks.addTask(4, new EntityAITempt(this, 0.3F, Item.carrotOnAStick.itemID, false));
039            this.tasks.addTask(4, new EntityAITempt(this, 0.3F, Item.carrot.itemID, false));
040            this.tasks.addTask(5, new EntityAIFollowParent(this, 0.28F));
041            this.tasks.addTask(6, new EntityAIWander(this, var2));
042            this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
043            this.tasks.addTask(8, new EntityAILookIdle(this));
044        }
045    
046        /**
047         * Returns true if the newer Entity AI code should be run
048         */
049        public boolean isAIEnabled()
050        {
051            return true;
052        }
053    
054        public int getMaxHealth()
055        {
056            return 10;
057        }
058    
059        protected void updateAITasks()
060        {
061            super.updateAITasks();
062        }
063    
064        /**
065         * returns true if all the conditions for steering the entity are met. For pigs, this is true if it is being ridden
066         * by a player and the player is holding a carrot-on-a-stick
067         */
068        public boolean canBeSteered()
069        {
070            ItemStack var1 = ((EntityPlayer)this.riddenByEntity).getHeldItem();
071            return var1 != null && var1.itemID == Item.carrotOnAStick.itemID;
072        }
073    
074        protected void entityInit()
075        {
076            super.entityInit();
077            this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
078        }
079    
080        /**
081         * (abstract) Protected helper method to write subclass entity data to NBT.
082         */
083        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
084        {
085            super.writeEntityToNBT(par1NBTTagCompound);
086            par1NBTTagCompound.setBoolean("Saddle", this.getSaddled());
087        }
088    
089        /**
090         * (abstract) Protected helper method to read subclass entity data from NBT.
091         */
092        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
093        {
094            super.readEntityFromNBT(par1NBTTagCompound);
095            this.setSaddled(par1NBTTagCompound.getBoolean("Saddle"));
096        }
097    
098        /**
099         * Returns the sound this mob makes while it's alive.
100         */
101        protected String getLivingSound()
102        {
103            return "mob.pig.say";
104        }
105    
106        /**
107         * Returns the sound this mob makes when it is hurt.
108         */
109        protected String getHurtSound()
110        {
111            return "mob.pig.say";
112        }
113    
114        /**
115         * Returns the sound this mob makes on death.
116         */
117        protected String getDeathSound()
118        {
119            return "mob.pig.death";
120        }
121    
122        /**
123         * Plays step sound at given x, y, z for the entity
124         */
125        protected void playStepSound(int par1, int par2, int par3, int par4)
126        {
127            this.playSound("mob.pig.step", 0.15F, 1.0F);
128        }
129    
130        /**
131         * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
132         */
133        public boolean interact(EntityPlayer par1EntityPlayer)
134        {
135            if (super.interact(par1EntityPlayer))
136            {
137                return true;
138            }
139            else if (this.getSaddled() && !this.worldObj.isRemote && (this.riddenByEntity == null || this.riddenByEntity == par1EntityPlayer))
140            {
141                par1EntityPlayer.mountEntity(this);
142                return true;
143            }
144            else
145            {
146                return false;
147            }
148        }
149    
150        /**
151         * Returns the item ID for the item the mob drops on death.
152         */
153        protected int getDropItemId()
154        {
155            return this.isBurning() ? Item.porkCooked.itemID : Item.porkRaw.itemID;
156        }
157    
158        /**
159         * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param
160         * par2 - Level of Looting used to kill this mob.
161         */
162        protected void dropFewItems(boolean par1, int par2)
163        {
164            int var3 = this.rand.nextInt(3) + 1 + this.rand.nextInt(1 + par2);
165    
166            for (int var4 = 0; var4 < var3; ++var4)
167            {
168                if (this.isBurning())
169                {
170                    this.dropItem(Item.porkCooked.itemID, 1);
171                }
172                else
173                {
174                    this.dropItem(Item.porkRaw.itemID, 1);
175                }
176            }
177    
178            if (this.getSaddled())
179            {
180                this.dropItem(Item.saddle.itemID, 1);
181            }
182        }
183    
184        /**
185         * Returns true if the pig is saddled.
186         */
187        public boolean getSaddled()
188        {
189            return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
190        }
191    
192        /**
193         * Set or remove the saddle of the pig.
194         */
195        public void setSaddled(boolean par1)
196        {
197            if (par1)
198            {
199                this.dataWatcher.updateObject(16, Byte.valueOf((byte)1));
200            }
201            else
202            {
203                this.dataWatcher.updateObject(16, Byte.valueOf((byte)0));
204            }
205        }
206    
207        /**
208         * Called when a lightning bolt hits the entity.
209         */
210        public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt)
211        {
212            if (!this.worldObj.isRemote)
213            {
214                EntityPigZombie var2 = new EntityPigZombie(this.worldObj);
215                var2.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch);
216                this.worldObj.spawnEntityInWorld(var2);
217                this.setDead();
218            }
219        }
220    
221        /**
222         * Called when the mob is falling. Calculates and applies fall damage.
223         */
224        protected void fall(float par1)
225        {
226            super.fall(par1);
227    
228            if (par1 > 5.0F && this.riddenByEntity instanceof EntityPlayer)
229            {
230                ((EntityPlayer)this.riddenByEntity).triggerAchievement(AchievementList.flyPig);
231            }
232        }
233    
234        /**
235         * This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
236         */
237        public EntityPig spawnBabyAnimal(EntityAgeable par1EntityAgeable)
238        {
239            return new EntityPig(this.worldObj);
240        }
241    
242        /**
243         * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
244         * the animal type)
245         */
246        public boolean isBreedingItem(ItemStack par1ItemStack)
247        {
248            return par1ItemStack != null && par1ItemStack.itemID == Item.carrot.itemID;
249        }
250    
251        /**
252         * Return the AI task for player control.
253         */
254        public EntityAIControlledByPlayer getAIControlledByPlayer()
255        {
256            return this.aiControlledByPlayer;
257        }
258    
259        public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
260        {
261            return this.spawnBabyAnimal(par1EntityAgeable);
262        }
263    }