package game.entity.animal; import java.util.Map; import game.ai.EntityAIEatGrass; import game.ai.EntityAIFollowParent; import game.ai.EntityAILookIdle; import game.ai.EntityAIMate; import game.ai.EntityAIPanic; import game.ai.EntityAISwimming; import game.ai.EntityAITempt; import game.ai.EntityAIWander; import game.ai.EntityAIWatchClosest; import game.biome.Biome; import game.collect.Maps; import game.color.DyeColor; import game.entity.attributes.Attributes; import game.entity.item.EntityItem; import game.entity.npc.EntityNPC; import game.entity.types.EntityAnimal; import game.entity.types.EntityLiving; import game.init.Blocks; import game.init.CraftingRegistry; import game.init.ItemRegistry; import game.init.Items; import game.init.SoundEvent; import game.inventory.Container; import game.inventory.InventoryCrafting; import game.item.Item; import game.item.ItemShears; import game.item.ItemStack; import game.nbt.NBTTagCompound; import game.pathfinding.PathNavigateGround; import game.rng.Random; import game.util.ExtMath; import game.world.World; public class EntitySheep extends EntityAnimal { /** * Internal crafting inventory used to check the result of mixing dyes corresponding to the fleece color when * breeding sheep. */ private final InventoryCrafting inventoryCrafting = new InventoryCrafting(new Container() { public boolean canInteractWith(EntityNPC playerIn) { return false; } }, 2, 1); private static final Map DYE_TO_RGB = Maps.newEnumMap(DyeColor.class); /** * Used to control movement as well as wool regrowth. Set to 40 on handleHealthUpdate and counts down with each * tick. */ private int sheepTimer; private EntityAIEatGrass entityAIEatGrass = new EntityAIEatGrass(this); public static float[] getDyeRgb(DyeColor dyeColor) { return (float[])DYE_TO_RGB.get(dyeColor); } public EntitySheep(World worldIn) { super(worldIn); this.setSize(0.9F, 1.3F); ((PathNavigateGround)this.getNavigator()).setAvoidsWater(true); this.tasks.addTask(0, new EntityAISwimming(this)); this.tasks.addTask(1, new EntityAIPanic(this, 1.25D)); this.tasks.addTask(2, new EntityAIMate(this, 1.0D)); this.tasks.addTask(3, new EntityAITempt(this, 1.1D, Items.wheats, false)); this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D)); this.tasks.addTask(5, this.entityAIEatGrass); this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); this.tasks.addTask(7, new EntityAIWatchClosest(this, null, 6.0F)); this.tasks.addTask(8, new EntityAILookIdle(this)); this.inventoryCrafting.setInventorySlotContents(0, new ItemStack(Items.dye, 1, 0)); this.inventoryCrafting.setInventorySlotContents(1, new ItemStack(Items.dye, 1, 0)); } protected void updateAITasks() { this.sheepTimer = this.entityAIEatGrass.getEatingGrassTimer(); super.updateAITasks(); } /** * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons * use this to react to sunlight and start to burn. */ public void onLivingUpdate() { if (this.worldObj.client) { this.sheepTimer = Math.max(0, this.sheepTimer - 1); } super.onLivingUpdate(); } protected void applyEntityAttributes() { super.applyEntityAttributes(); this.setMaxHealth(8); this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D); } protected void entityInit() { super.entityInit(); this.dataWatcher.addObject(16, (byte)0); } /** * Drop 0-2 items of this living's type * * @param wasRecentlyHit true if this this entity was recently hit by appropriate entity (generally only if player * or tameable) * @param lootingModifier level of enchanment to be applied to this drop */ protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier) { if (!this.getSheared()) { this.entityDropItem(new ItemStack(ItemRegistry.getItemFromBlock(Blocks.wool), 1, this.getFleeceColor().getMetadata()), 0.0F); } // int i = this.rand.roll(2) + this.rand.zrange(1 + lootingModifier); // // for (int j = 0; j < i; ++j) // { // if (this.isBurning()) // { // this.dropItem(Items.cooked_mutton, 1); // } // else // { // this.dropItem(Items.mutton, 1); // } // } } protected Item getDropItem() { return ItemRegistry.getItemFromBlock(Blocks.wool); } public void handleStatusUpdate(byte id) { if (id == 10) { this.sheepTimer = 40; } else { super.handleStatusUpdate(id); } } public float getHeadRotationPointY(float p_70894_1_) { return this.sheepTimer <= 0 ? 0.0F : (this.sheepTimer >= 4 && this.sheepTimer <= 36 ? 1.0F : (this.sheepTimer < 4 ? ((float)this.sheepTimer - p_70894_1_) / 4.0F : -((float)(this.sheepTimer - 40) - p_70894_1_) / 4.0F)); } public float getHeadRotationAngleX(float p_70890_1_) { if (this.sheepTimer > 4 && this.sheepTimer <= 36) { float f = ((float)(this.sheepTimer - 4) - p_70890_1_) / 32.0F; return ((float)Math.PI / 5F) + ((float)Math.PI * 7F / 100F) * ExtMath.sin(f * 28.7F); } else { return this.sheepTimer > 0 ? ((float)Math.PI / 5F) : this.rotPitch / (180F / (float)Math.PI); } } /** * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. */ public boolean interact(EntityNPC player) { ItemStack itemstack = player.inventory.getCurrentItem(); if (itemstack != null && itemstack.getItem() instanceof ItemShears /* && this.worldObj.dimension.getDimensionId() != 2 */ && !this.getSheared() && !this.isChild()) { if (!this.worldObj.client) { this.setSheared(true); int i = this.rand.roll(3); for (int j = 0; j < i; ++j) { EntityItem entityitem = this.entityDropItem(new ItemStack(ItemRegistry.getItemFromBlock(Blocks.wool), 1, this.getFleeceColor().getMetadata()), 1.0F); entityitem.motionY += (double)(this.rand.floatv() * 0.05F); entityitem.motionX += (double)((this.rand.floatv() - this.rand.floatv()) * 0.1F); entityitem.motionZ += (double)((this.rand.floatv() - this.rand.floatv()) * 0.1F); } } itemstack.damageItem(1, player); this.playSound(SoundEvent.CUT, 1.0F, 1.0F); } return super.interact(player); } /** * (abstract) Protected helper method to write subclass entity data to NBT. */ public void writeEntityToNBT(NBTTagCompound tagCompound) { super.writeEntityToNBT(tagCompound); tagCompound.setBoolean("Sheared", this.getSheared()); tagCompound.setByte("Color", (byte)this.getFleeceColor().getMetadata()); } /** * (abstract) Protected helper method to read subclass entity data from NBT. */ public void readEntityFromNBT(NBTTagCompound tagCompund) { super.readEntityFromNBT(tagCompund); this.setSheared(tagCompund.getBoolean("Sheared")); this.setFleeceColor(DyeColor.byMetadata(tagCompund.getByte("Color"))); } /** * Returns the sound this mob makes while it's alive. */ protected SoundEvent getLivingSound() { return SoundEvent.SHEEP_IDLE; } /** * Returns the sound this mob makes when it is hurt. */ protected SoundEvent getHurtSound() { return SoundEvent.SHEEP_IDLE; } /** * Returns the sound this mob makes on death. */ protected SoundEvent getDeathSound() { return SoundEvent.SHEEP_IDLE; } // protected void playStepSound(BlockPos pos, Block blockIn) // { // this.playSound("mob.sheep.step", 0.15F, 1.0F); // } /** * Gets the wool color of this sheep. */ public DyeColor getFleeceColor() { return DyeColor.byMetadata(this.dataWatcher.getWatchableObjectByte(16) & 15); } /** * Sets the wool color of this sheep */ public void setFleeceColor(DyeColor color) { byte b0 = this.dataWatcher.getWatchableObjectByte(16); this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & 240 | color.getMetadata() & 15))); } /** * returns true if a sheeps wool has been sheared */ public boolean getSheared() { return (this.dataWatcher.getWatchableObjectByte(16) & 16) != 0; } /** * make a sheep sheared if set to true */ public void setSheared(boolean sheared) { byte b0 = this.dataWatcher.getWatchableObjectByte(16); if (sheared) { this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 16))); } else { this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -17))); } } private static final DyeColor[] RARE_COLORS = { DyeColor.BLUE, DyeColor.CYAN, DyeColor.GREEN, DyeColor.LIGHT_BLUE, DyeColor.LIME, DyeColor.MAGENTA, DyeColor.ORANGE, DyeColor.PINK, DyeColor.PURPLE, DyeColor.RED }; public static DyeColor getRandomSheepColor(Random random, Biome biome) { if(biome == Biome.snowLand) return DyeColor.WHITE; int i = random.zrange(140); return i < 20 ? DyeColor.BLACK : (i < 30 ? DyeColor.GRAY : (i < 40 ? DyeColor.SILVER : (i < 70 ? DyeColor.BROWN : (i < 120 ? DyeColor.WHITE : (i < 130 ? (random.chance(10) ? RARE_COLORS[i - 120] : DyeColor.WHITE) : (random.chance(500) ? DyeColor.YELLOW : DyeColor.WHITE) ))))); } public EntitySheep createChild(EntityLiving ageable) { EntitySheep entitysheep = (EntitySheep)ageable; EntitySheep entitysheep1 = new EntitySheep(this.worldObj); entitysheep1.setFleeceColor(this.getDyeColorMixFromParents(this, entitysheep)); return entitysheep1; } /** * This function applies the benefits of growing back wool and faster growing up to the acting entity. (This * function is used in the AIEatGrass) */ public void eatGrassBonus() { this.setSheared(false); if (this.isChild() && !this.worldObj.client) { this.grow(60); } } /** * Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called * when entity is reloaded from nbt. Mainly used for initializing attributes and inventory */ public Object onInitialSpawn(Object livingdata) { livingdata = super.onInitialSpawn(livingdata); this.setFleeceColor(getRandomSheepColor(this.worldObj.rand, this.worldObj.getBiomeGenForCoords(this.getPosition()))); return livingdata; } /** * Attempts to mix both parent sheep to come up with a mixed dye color. */ private DyeColor getDyeColorMixFromParents(EntityAnimal father, EntityAnimal mother) { int i = ((EntitySheep)father).getFleeceColor().getDyeDamage(); int j = ((EntitySheep)mother).getFleeceColor().getDyeDamage(); this.inventoryCrafting.getStackInSlot(0).setItemDamage(i); this.inventoryCrafting.getStackInSlot(1).setItemDamage(j); ItemStack itemstack = CraftingRegistry.getMatching(this.inventoryCrafting, ((EntitySheep)father).worldObj); int k; if (itemstack != null && itemstack.getItem() == Items.dye) { k = itemstack.getMetadata(); } else { k = this.worldObj.rand.chance() ? i : j; } return DyeColor.byDyeDamage(k); } public float getEyeHeight() { return 0.95F * this.height; } public int getColor() { return 0xd9d9d9; } static { DYE_TO_RGB.put(DyeColor.WHITE, new float[] {1.0F, 1.0F, 1.0F}); DYE_TO_RGB.put(DyeColor.ORANGE, new float[] {0.85F, 0.5F, 0.2F}); DYE_TO_RGB.put(DyeColor.MAGENTA, new float[] {0.7F, 0.3F, 0.85F}); DYE_TO_RGB.put(DyeColor.LIGHT_BLUE, new float[] {0.4F, 0.6F, 0.85F}); DYE_TO_RGB.put(DyeColor.YELLOW, new float[] {0.9F, 0.9F, 0.2F}); DYE_TO_RGB.put(DyeColor.LIME, new float[] {0.5F, 0.8F, 0.1F}); DYE_TO_RGB.put(DyeColor.PINK, new float[] {0.95F, 0.5F, 0.65F}); DYE_TO_RGB.put(DyeColor.GRAY, new float[] {0.3F, 0.3F, 0.3F}); DYE_TO_RGB.put(DyeColor.SILVER, new float[] {0.6F, 0.6F, 0.6F}); DYE_TO_RGB.put(DyeColor.CYAN, new float[] {0.3F, 0.5F, 0.6F}); DYE_TO_RGB.put(DyeColor.PURPLE, new float[] {0.5F, 0.25F, 0.7F}); DYE_TO_RGB.put(DyeColor.BLUE, new float[] {0.2F, 0.3F, 0.7F}); DYE_TO_RGB.put(DyeColor.BROWN, new float[] {0.4F, 0.3F, 0.2F}); DYE_TO_RGB.put(DyeColor.GREEN, new float[] {0.4F, 0.5F, 0.2F}); DYE_TO_RGB.put(DyeColor.RED, new float[] {0.6F, 0.2F, 0.2F}); DYE_TO_RGB.put(DyeColor.BLACK, new float[] {0.1F, 0.1F, 0.1F}); } }