    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005
    006    import java.util.ArrayList;
    007    import java.util.Random;
    008
    009    import net.minecraftforge.common.IShearable;
    010
    011    public class EntitySheep extends EntityAnimal implements IShearable
    012    {
    013        /**
    014         * Holds the RGB table of the sheep colors - in OpenGL glColor3f values - used to render the sheep colored fleece.
    015         */
    016        public static final float[][] fleeceColorTable = new float[][] {{1.0F, 1.0F, 1.0F}, {0.95F, 0.7F, 0.2F}, {0.9F, 0.5F, 0.85F}, {0.6F, 0.7F, 0.95F}, {0.9F, 0.9F, 0.2F}, {0.5F, 0.8F, 0.1F}, {0.95F, 0.7F, 0.8F}, {0.3F, 0.3F, 0.3F}, {0.6F, 0.6F, 0.6F}, {0.3F, 0.6F, 0.7F}, {0.7F, 0.4F, 0.9F}, {0.2F, 0.4F, 0.8F}, {0.5F, 0.4F, 0.3F}, {0.4F, 0.5F, 0.2F}, {0.8F, 0.3F, 0.3F}, {0.1F, 0.1F, 0.1F}};
    017
    018        /**
    019         * Used to control movement as well as wool regrowth. Set to 40 on handleHealthUpdate and counts down with each
    020         * tick.
    021         */
    022        private int sheepTimer;
    023
    024        /** The eat grass AI task for this mob. */
    025        private EntityAIEatGrass aiEatGrass = new EntityAIEatGrass(this);
    026
    027        public EntitySheep(World par1World)
    028        {
    029            super(par1World);
    030            this.texture = "/mob/sheep.png";
    031            this.setSize(0.9F, 1.3F);
    032            float var2 = 0.23F;
    033            this.getNavigator().setAvoidsWater(true);
    034            this.tasks.addTask(0, new EntityAISwimming(this));
    035            this.tasks.addTask(1, new EntityAIPanic(this, 0.38F));
    036            this.tasks.addTask(2, new EntityAIMate(this, var2));
    037            this.tasks.addTask(3, new EntityAITempt(this, 0.25F, Item.wheat.shiftedIndex, false));
    038            this.tasks.addTask(4, new EntityAIFollowParent(this, 0.25F));
    039            this.tasks.addTask(5, this.aiEatGrass);
    040            this.tasks.addTask(6, new EntityAIWander(this, var2));
    041            this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
    042            this.tasks.addTask(8, new EntityAILookIdle(this));
    043        }
    044
    045        /**
    046         * Returns true if the newer Entity AI code should be run
    047         */
    048        protected boolean isAIEnabled()
    049        {
    050            return true;
    051        }
    052
    053        protected void updateAITasks()
    054        {
    055            this.sheepTimer = this.aiEatGrass.func_75362_f();
    056            super.updateAITasks();
    057        }
    058
    059        /**
    060         * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    061         * use this to react to sunlight and start to burn.
    062         */
    063        public void onLivingUpdate()
    064        {
    065            if (this.worldObj.isRemote)
    066            {
    067                this.sheepTimer = Math.max(0, this.sheepTimer - 1);
    068            }
    069
    070            super.onLivingUpdate();
    071        }
    072
    073        public int getMaxHealth()
    074        {
    075            return 8;
    076        }
    077
    078        protected void entityInit()
    079        {
    080            super.entityInit();
    081            this.dataWatcher.addObject(16, new Byte((byte)0));
    082        }
    083
    084        /**
    085         * Drop 0-2 items of this living's type
    086         */
    087        protected void dropFewItems(boolean par1, int par2)
    088        {
    089            if (!this.getSheared())
    090            {
    091                this.entityDropItem(new ItemStack(Block.cloth.blockID, 1, this.getFleeceColor()), 0.0F);
    092            }
    093        }
    094
    095        /**
    096         * Returns the item ID for the item the mob drops on death.
    097         */
    098        protected int getDropItemId()
    099        {
    100            return Block.cloth.blockID;
    101        }
    102
    103        @SideOnly(Side.CLIENT)
    104        public void handleHealthUpdate(byte par1)
    105        {
    106            if (par1 == 10)
    107            {
    108                this.sheepTimer = 40;
    109            }
    110            else
    111            {
    112                super.handleHealthUpdate(par1);
    113            }
    114        }
    115
    116        @SideOnly(Side.CLIENT)
    117        public float func_70894_j(float par1)
    118        {
    119            return this.sheepTimer <= 0 ? 0.0F : (this.sheepTimer >= 4 && this.sheepTimer <= 36 ? 1.0F : (this.sheepTimer < 4 ? ((float)this.sheepTimer - par1) / 4.0F : -((float)(this.sheepTimer - 40) - par1) / 4.0F));
    120        }
    121
    122        @SideOnly(Side.CLIENT)
    123        public float func_70890_k(float par1)
    124        {
    125            if (this.sheepTimer > 4 && this.sheepTimer <= 36)
    126            {
    127                float var2 = ((float)(this.sheepTimer - 4) - par1) / 32.0F;
    128                return ((float)Math.PI / 5F) + ((float)Math.PI * 7F / 100F) * MathHelper.sin(var2 * 28.7F);
    129            }
    130            else
    131            {
    132                return this.sheepTimer > 0 ? ((float)Math.PI / 5F) : this.rotationPitch / (180F / (float)Math.PI);
    133            }
    134        }
    135
    136        /**
    137         * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
    138         */
    139        public boolean interact(EntityPlayer par1EntityPlayer)
    140        {
    141            return super.interact(par1EntityPlayer);
    142        }
    143
    144        /**
    145         * (abstract) Protected helper method to write subclass entity data to NBT.
    146         */
    147        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    148        {
    149            super.writeEntityToNBT(par1NBTTagCompound);
    150            par1NBTTagCompound.setBoolean("Sheared", this.getSheared());
    151            par1NBTTagCompound.setByte("Color", (byte)this.getFleeceColor());
    152        }
    153
    154        /**
    155         * (abstract) Protected helper method to read subclass entity data from NBT.
    156         */
    157        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    158        {
    159            super.readEntityFromNBT(par1NBTTagCompound);
    160            this.setSheared(par1NBTTagCompound.getBoolean("Sheared"));
    161            this.setFleeceColor(par1NBTTagCompound.getByte("Color"));
    162        }
    163
    164        /**
    165         * Returns the sound this mob makes while it's alive.
    166         */
    167        protected String getLivingSound()
    168        {
    169            return "mob.sheep";
    170        }
    171
    172        /**
    173         * Returns the sound this mob makes when it is hurt.
    174         */
    175        protected String getHurtSound()
    176        {
    177            return "mob.sheep";
    178        }
    179
    180        /**
    181         * Returns the sound this mob makes on death.
    182         */
    183        protected String getDeathSound()
    184        {
    185            return "mob.sheep";
    186        }
    187
    188        public int getFleeceColor()
    189        {
    190            return this.dataWatcher.getWatchableObjectByte(16) & 15;
    191        }
    192
    193        public void setFleeceColor(int par1)
    194        {
    195            byte var2 = this.dataWatcher.getWatchableObjectByte(16);
    196            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & 240 | par1 & 15)));
    197        }
    198
    199        /**
    200         * returns true if a sheeps wool has been sheared
    201         */
    202        public boolean getSheared()
    203        {
    204            return (this.dataWatcher.getWatchableObjectByte(16) & 16) != 0;
    205        }
    206
    207        /**
    208         * make a sheep sheared if set to true
    209         */
    210        public void setSheared(boolean par1)
    211        {
    212            byte var2 = this.dataWatcher.getWatchableObjectByte(16);
    213
    214            if (par1)
    215            {
    216                this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 | 16)));
    217            }
    218            else
    219            {
    220                this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & -17)));
    221            }
    222        }
    223
    224        /**
    225         * This method is called when a sheep spawns in the world to select the color of sheep fleece.
    226         */
    227        public static int getRandomFleeceColor(Random par0Random)
    228        {
    229            int var1 = par0Random.nextInt(100);
    230            return var1 < 5 ? 15 : (var1 < 10 ? 7 : (var1 < 15 ? 8 : (var1 < 18 ? 12 : (par0Random.nextInt(500) == 0 ? 6 : 0))));
    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 EntityAnimal spawnBabyAnimal(EntityAnimal par1EntityAnimal)
    237        {
    238            EntitySheep var2 = (EntitySheep)par1EntityAnimal;
    239            EntitySheep var3 = new EntitySheep(this.worldObj);
    240
    241            if (this.rand.nextBoolean())
    242            {
    243                var3.setFleeceColor(this.getFleeceColor());
    244            }
    245            else
    246            {
    247                var3.setFleeceColor(var2.getFleeceColor());
    248            }
    249
    250            return var3;
    251        }
    252
    253        /**
    254         * This function applies the benefits of growing back wool and faster growing up to the acting entity. (This
    255         * function is used in the AIEatGrass)
    256         */
    257        public void eatGrassBonus()
    258        {
    259            this.setSheared(false);
    260
    261            if (this.isChild())
    262            {
    263                int var1 = this.getGrowingAge() + 1200;
    264
    265                if (var1 > 0)
    266                {
    267                    var1 = 0;
    268                }
    269
    270                this.setGrowingAge(var1);
    271            }
    272        }
    273
    274        @Override
    275        public boolean isShearable(ItemStack item, World world, int X, int Y, int Z)
    276        {
    277            return !getSheared() && !isChild();
    278        }
    279
    280        @Override
    281        public ArrayList<ItemStack> onSheared(ItemStack item, World world, int X, int Y, int Z, int fortune)
    282        {
    283            ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
    284            setSheared(true);
    285            int i = 1 + rand.nextInt(3);
    286            for (int j = 0; j < i; j++)
    287            {
    288                ret.add(new ItemStack(Block.cloth.blockID, 1, getFleeceColor()));
    289            }
    290            return ret;
    291        }
    292    }