gt:                 double d1 = this.rand.nextGaussian() * 0.02D;
context: package net.minecraft.entity.passive;
  
  import net.minecraft.block.Block;
  import net.minecraft.entity.EntityAgeable;
  import net.minecraft.entity.player.EntityPlayer;
  import net.minecraft.init.Blocks;
  import net.minecraft.init.Items;
  import net.minecraft.item.ItemStack;
  import net.minecraft.nbt.NBTTagCompound;
  import net.minecraft.util.BlockPos;
  import net.minecraft.util.DamageSource;
  import net.minecraft.util.EnumParticleTypes;
  import net.minecraft.util.MathHelper;
  import net.minecraft.world.World;
  import net.minecraftforge.fml.relauncher.Side;
  import net.minecraftforge.fml.relauncher.SideOnly;
  
  public abstract class EntityAnimal extends EntityAgeable implements IAnimals
  {
      protected Block spawnableBlock = Blocks.grass;
      private int inLove;
      private EntityPlayer playerInLove;
  
      public EntityAnimal(World worldIn)
      {
          super(worldIn);
      }
  
      protected void updateAITasks()
      {
          if (this.getGrowingAge() != 0)
          {
              this.inLove = 0;
          }
  
          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()
      {
          super.onLivingUpdate();
  
          if (this.getGrowingAge() != 0)
          {
              this.inLove = 0;
          }
  
          if (this.inLove > 0)
          {
              --this.inLove;
  
              if (this.inLove % 10 == 0)
              {
                  double d0 = this.rand.nextGaussian() * 0.02D;
                  double d1 = this.rand.nextGaussian() * 0.02D;
                  double d2 = this.rand.nextGaussian() * 0.02D;
                  this.worldObj.spawnParticle(EnumParticleTypes.HEART, this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, d0, d1, d2, new int[0]);
              }
          }
      }
  
      /**
       * Called when the entity is attacked.
       */
      public boolean attackEntityFrom(DamageSource source, float amount)
      {
          if (this.isEntityInvulnerable(source))
          {
              return false;
          }
          else
          {
              this.inLove = 0;
              return super.attackEntityFrom(source, amount);
          }
      }
  
      public float getBlockPathWeight(BlockPos pos)
      {
          return this.worldObj.getBlockState(pos.down()).getBlock() == Blocks.grass ? 10.0F : this.worldObj.getLightBrightness(pos) - 0.5F;
      }
  
      /**
       * (abstract) Protected helper method to write subclass entity data to NBT.
       */
      public void writeEntityToNBT(NBTTagCompound tagCompound)
      {
          super.writeEntityToNBT(tagCompound);
          tagCompound.setInteger("InLove", this.inLove);
      }
  
      /**
       * (abstract) Protected helper method to read subclass entity data from NBT.
       */
      public void readEntityFromNBT(NBTTagCompound tagCompund)
      {
          super.readEntityFromNBT(tagCompund);
          this.inLove = tagCompund.getInteger("InLove");
      }
  
      /**
       * Checks if the entity's current position is a valid location to spawn this entity.
       */
      public boolean getCanSpawnHere()
      {
          int i = MathHelper.floor_double(this.posX);
          int j = MathHelper.floor_double(this.getEntityBoundingBox().minY);
          int k = MathHelper.floor_double(this.posZ);
          BlockPos blockpos = new BlockPos(i, j, k);
          return this.worldObj.getBlockState(blockpos.down()).getBlock() == this.spawnableBlock && this.worldObj.getLight(blockpos) > 8 && super.getCanSpawnHere();
      }
  
      /**
       * Get number of ticks, at least during which the living entity will be silent.
       */
      public int getTalkInterval()
      {
          return 120;
      }
  
      /**
       * Determines if an entity can be despawned, used on idle far away entities
       */
      protected boolean canDespawn()
      {
          return false;
      }
  
      /**
       * Get the experience points the entity currently has.
       */
      protected int getExperiencePoints(EntityPlayer player)
      {
          return 1 + this.worldObj.rand.nextInt(3);
      }
  
      /**
       * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
       * the animal type)
       */
      public boolean isBreedingItem(ItemStack stack)
      {
          return stack == null ? false : stack.getItem() == Items.wheat;
      }
  
      /**
       * 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(EntityPlayer player)
      {
          ItemStack itemstack = player.inventory.getCurrentItem();
  
          if (itemstack != null)
          {
              if (this.isBreedingItem(itemstack) && this.getGrowingAge() == 0 && this.inLove <= 0)
              {
                  this.consumeItemFromStack(player, itemstack);
                  this.setInLove(player);
                  return true;
              }
  
              if (this.isChild() && this.isBreedingItem(itemstack))
              {
                  this.consumeItemFromStack(player, itemstack);
                  this.func_175501_a((int)((float)(-this.getGrowingAge() / 20) * 0.1F), true);
                  return true;
              }
          }
  
          return super.interact(player);
      }
  
      /**
       * Decreases ItemStack size by one
       */
      protected void consumeItemFromStack(EntityPlayer player, ItemStack stack)
      {
          if (!player.capabilities.isCreativeMode)
          {
              --stack.stackSize;
  
              if (stack.stackSize <= 0)
              {
                  player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
              }
          }
      }
  
      public void setInLove(EntityPlayer player)
      {
          this.inLove = 600;
          this.playerInLove = player;
          this.worldObj.setEntityState(this, (byte)18);
      }
  
      public EntityPlayer getPlayerInLove()
      {
          return this.playerInLove;
      }
  
      /**
       * Returns if the entity is currently in 'love mode'.
       */
      public boolean isInLove()
      {
          return this.inLove > 0;
      }
  
      public void resetInLove()
      {
          this.inLove = 0;
      }
  
      /**
       * Returns true if the mob is currently able to mate with the specified mob.
       */
      public boolean canMateWith(EntityAnimal otherAnimal)
      {
          return otherAnimal == this ? false : (otherAnimal.getClass() != this.getClass() ? false : this.isInLove() && otherAnimal.isInLove());
      }
  
      @SideOnly(Side.CLIENT)
      public void handleStatusUpdate(byte id)
      {
          if (id == 18)
          {
              for (int i = 0; i < 7; ++i)
              {
                  double d0 = this.rand.nextGaussian() * 0.02D;
  