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.shiftedIndex, false));
039            this.tasks.addTask(4, new EntityAITempt(this, 0.3F, Item.carrot.shiftedIndex, 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.shiftedIndex;
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.func_85030_a("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.shiftedIndex : Item.porkRaw.shiftedIndex;
156        }
157    
158        /**
159         * Drop 0-2 items of this living's type
160         */
161        protected void dropFewItems(boolean par1, int par2)
162        {
163            int var3 = this.rand.nextInt(3) + 1 + this.rand.nextInt(1 + par2);
164    
165            for (int var4 = 0; var4 < var3; ++var4)
166            {
167                if (this.isBurning())
168                {
169                    this.dropItem(Item.porkCooked.shiftedIndex, 1);
170                }
171                else
172                {
173                    this.dropItem(Item.porkRaw.shiftedIndex, 1);
174                }
175            }
176    
177            if (this.getSaddled())
178            {
179                this.dropItem(Item.saddle.shiftedIndex, 1);
180            }
181        }
182    
183        /**
184         * Returns true if the pig is saddled.
185         */
186        public boolean getSaddled()
187        {
188            return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
189        }
190    
191        /**
192         * Set or remove the saddle of the pig.
193         */
194        public void setSaddled(boolean par1)
195        {
196            if (par1)
197            {
198                this.dataWatcher.updateObject(16, Byte.valueOf((byte)1));
199            }
200            else
201            {
202                this.dataWatcher.updateObject(16, Byte.valueOf((byte)0));
203            }
204        }
205    
206        /**
207         * Called when a lightning bolt hits the entity.
208         */
209        public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt)
210        {
211            if (!this.worldObj.isRemote)
212            {
213                EntityPigZombie var2 = new EntityPigZombie(this.worldObj);
214                var2.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch);
215                this.worldObj.spawnEntityInWorld(var2);
216                this.setDead();
217            }
218        }
219    
220        /**
221         * Called when the mob is falling. Calculates and applies fall damage.
222         */
223        protected void fall(float par1)
224        {
225            super.fall(par1);
226    
227            if (par1 > 5.0F && this.riddenByEntity instanceof EntityPlayer)
228            {
229                ((EntityPlayer)this.riddenByEntity).triggerAchievement(AchievementList.flyPig);
230            }
231        }
232    
233        /**
234         * This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
235         */
236        public EntityPig spawnBabyAnimal(EntityAgeable par1EntityAgeable)
237        {
238            return new EntityPig(this.worldObj);
239        }
240    
241        /**
242         * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
243         * the animal type)
244         */
245        public boolean isBreedingItem(ItemStack par1ItemStack)
246        {
247            return par1ItemStack != null && par1ItemStack.itemID == Item.carrot.shiftedIndex;
248        }
249    
250        /**
251         * Return the AI task for player control.
252         */
253        public EntityAIControlledByPlayer getAIControlledByPlayer()
254        {
255            return this.aiControlledByPlayer;
256        }
257    
258        public EntityAgeable func_90011_a(EntityAgeable par1EntityAgeable)
259        {
260            return this.spawnBabyAnimal(par1EntityAgeable);
261        }
262    }