/** Updates the task */
  @Override
  public void updateTask() {
    EntityLivingBase entitylivingbase = this.attacker.getAttackTarget();
    this.attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F);

    if ((this.longMemory || this.attacker.getEntitySenses().canSee(entitylivingbase))
        && --this.field_75445_i <= 0) {
      this.field_75445_i = failedPathFindingPenalty + 4 + this.attacker.getRNG().nextInt(7);
      this.attacker.getNavigator().tryMoveToEntityLiving(entitylivingbase, this.speedTowardsTarget);
      if (this.attacker.getNavigator().getPath() != null) {
        PathPoint finalPathPoint = this.attacker.getNavigator().getPath().getFinalPathPoint();
        if (finalPathPoint != null
            && entitylivingbase.getDistanceSq(
                    finalPathPoint.xCoord, finalPathPoint.yCoord, finalPathPoint.zCoord)
                < 1) {
          failedPathFindingPenalty = 0;
        } else {
          failedPathFindingPenalty += 10;
        }
      } else {
        failedPathFindingPenalty += 10;
      }
    }

    this.attackTick = Math.max(this.attackTick - 1, 0);
    double d0 =
        (double) (this.attacker.width * 2.0F * this.attacker.width * 2.0F + entitylivingbase.width);

    if (this.attacker.getDistanceSq(
            entitylivingbase.posX, entitylivingbase.boundingBox.minY, entitylivingbase.posZ)
        <= d0) {
      if (this.attackTick <= 0) {
        this.attackTick = 20;

        if (this.attacker.getHeldItem() != null) {
          this.attacker.swingItem();
        }

        this.attacker.attackEntityAsMob(entitylivingbase);
      }
    }
  }
 protected void swingThrower() {
   EntityLivingBase thrower = getThrower();
   if (thrower != null && !thrower.onGround && isInGround()) {
     if (thrower.worldObj.isRemote) {
       // Determine the swing variables on first swing tick:
       float x = dataWatcher.getWatchableObjectFloat(HIT_POS_X);
       float y = dataWatcher.getWatchableObjectFloat(HIT_POS_Y);
       float z = dataWatcher.getWatchableObjectFloat(HIT_POS_Z);
       if (swingTicks == 0 && swingVec == null && thrower.motionY < 0) {
         swingVec =
             Vec3.createVectorHelper(
                     (x - thrower.posX),
                     y - (thrower.posY + thrower.getEyeHeight()),
                     (z - thrower.posZ))
                 .normalize();
         dy = (thrower.getDistance(x, y, z) / 7.0D); // lower divisor gives bigger change in y
         // calculate horizontal distance to find initial swing tick position
         // as distance approaches zero, swing ticks should approach ticks required / 2
         // as distance approaches maxDistance, swing ticks should approach zero
         // this makes sure player's arc is even around pivot point
         double d = Math.min(thrower.getDistance(x, thrower.posY, z), getMaxDistance());
         swingTicks = MathHelper.floor_double(((getMaxDistance() - d) / getMaxDistance()) * 8);
       }
       if (swingVec != null) {
         double sin = Math.sin(10.0D * swingTicks * Math.PI / 180.0D);
         double f = 0.8D; // arbitrary horizontal motion factor
         thrower.motionX = (sin * swingVec.xCoord * f);
         thrower.motionZ = (sin * swingVec.zCoord * f);
         // y motion needs to oscillate twice as quickly, so it goes up on the other side of the
         // swing
         thrower.motionY = dy * -Math.sin(20.0D * swingTicks * Math.PI / 180.0D);
         // check for horizontal collisions that should stop swinging motion
         MovingObjectPosition mop =
             TargetUtils.checkForImpact(worldObj, thrower, this, -(thrower.width / 4.0F), false);
         if (mop != null && mop.typeOfHit != MovingObjectType.MISS) {
           thrower.motionX = -thrower.motionX * 0.15D;
           thrower.motionY = -thrower.motionY * 0.15D;
           thrower.motionZ = -thrower.motionZ * 0.15D;
           swingVec = null;
         }
         ++swingTicks; // increment at end
         if (thrower.fallDistance > 0 && thrower.motionY < 0) {
           // 0.466885F seems to be roughly the amount added each tick while swinging; round for a
           // little extra server-side padding
           PacketDispatcher.sendToServer(new FallDistancePacket(thrower, -0.467F));
           thrower.fallDistance -= 0.467F;
         }
       } else if (swingTicks > 0) {
         // still let player hang there after colliding, but move towards center
         if (thrower.getDistanceSq(x, thrower.posY, z) > 1.0D) {
           double dx = x - thrower.posX;
           double dz = z - thrower.posZ;
           thrower.motionX = 0.15D * dx;
           thrower.motionZ = 0.15D * dz;
         }
         if (thrower.posY < (y - (getMaxDistance() / 2.0D))) {
           thrower.motionY = 0;
         }
         ++swingTicks; // increment at end
         PacketDispatcher.sendToServer(new FallDistancePacket(thrower, 0.0F));
         thrower.fallDistance = 0.0F;
       }
     }
   }
 }
  @Override
  public void updateTask() {
    EntityLivingBase entitylivingbase = attacker.getAttackTarget();
    attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F);
    if ((longMemory && attacker.getHealth() <= 150
            || attacker.getEntitySenses().canSee(entitylivingbase))
        && --findAttemptCount <= 0
        && attacker.getHealth() <= 150) {
      findAttemptCount = failedPathFindingPenalty + 4 + attacker.getRNG().nextInt(7);
      attacker.getNavigator().tryMoveToEntityLiving(entitylivingbase, speedTowardsTarget);
      if (attacker.getNavigator().getPath() != null) {
        PathPoint finalPathPoint = attacker.getNavigator().getPath().getFinalPathPoint();
        if (finalPathPoint != null
            && entitylivingbase.getDistanceSq(
                    finalPathPoint.xCoord, finalPathPoint.yCoord, finalPathPoint.zCoord)
                < 1D) failedPathFindingPenalty = 0;
        else failedPathFindingPenalty += 10;
      } else failedPathFindingPenalty += 10;
    }
    attackTick = Math.max(attackTick - 1, 0);
    double d0 = attacker.width * 1F * attacker.width * 1F + entitylivingbase.width;
    if (attacker.getDistanceSq(
            entitylivingbase.posX, entitylivingbase.boundingBox.minY, entitylivingbase.posZ)
        <= d0)
      if (attackTick <= 0) {
        attackTick = 10;
        attacker.attackEntityAsMob(entitylivingbase);
        entitylivingbase.attackEntityFrom(DamageSource.causeMobDamage(attacker), 4.0F);
        entitylivingbase.addVelocity(
            -MathHelper.sin(attacker.rotationYaw * 3.141593F / 180.0F) * 0.5F,
            0.1D,
            MathHelper.cos(attacker.rotationYaw * 3.141593F / 180.0F) * 0.5F);
      }

    if (attacker.getDistanceSq(
                entitylivingbase.posX, entitylivingbase.boundingBox.minY, entitylivingbase.posZ)
            > d0 + 1D
        && attacker.getDistanceSq(
                entitylivingbase.posX, entitylivingbase.boundingBox.minY, entitylivingbase.posZ)
            < d0 + 256.0D
        && attacker.getHealth() < 150)
      if (attackTick <= 0) {
        ++shouldDo;
        if (shouldDo == 1) attackTick = 40;
        else if (shouldDo <= 2) attackTick = 20;
        else {
          attackTick = 20;
          shouldDo = 0;
        }
        if (shouldDo == 1) {
          Vec3 look = attacker.getLookVec();
          double direction = Math.toRadians(attacker.renderYawOffset);
          EntityPoisonJet jet = new EntityPoisonJet(worldObj, attacker);
          jet.setPosition(
              attacker.posX + -Math.sin(direction) * 3.5D,
              attacker.posY + attacker.height * 0.5,
              attacker.posZ + Math.cos(direction) * 3.5D);
          jet.motionX = look.xCoord * 1.0;
          jet.motionY = look.yCoord * 2.2;
          jet.motionZ = look.zCoord * 1.0;
          worldObj.spawnEntityInWorld(jet);
        }
      }

    if (attacker.getDistanceSq(
                entitylivingbase.posX, entitylivingbase.boundingBox.minY, entitylivingbase.posZ)
            > d0 + 9D
        && attacker.getDistanceSq(
                entitylivingbase.posX, entitylivingbase.boundingBox.minY, entitylivingbase.posZ)
            < d0 + 256.0D
        && attacker.getHealth() > 150) {
      if (attackTick <= 0) {
        ++shouldDo;
        if (shouldDo == 1) attackTick = 200;
        else if (shouldDo <= 2) attackTick = 20;
        else {
          attackTick = 40;
          shouldDo = 0;
        }
        if (shouldDo == 1) {
          Vec3 look = attacker.getLookVec();
          double direction = Math.toRadians(attacker.renderYawOffset);
          EntityTarantulaEgg babyEgg = new EntityTarantulaEgg(worldObj, attacker);
          babyEgg.setPosition(
              attacker.posX + -Math.sin(direction) * 3.5D,
              attacker.posY + attacker.height,
              attacker.posZ + Math.cos(direction) * 3.5D);
          babyEgg.motionX = look.xCoord * 1.0;
          babyEgg.motionY = look.yCoord * 2.2;
          babyEgg.motionZ = look.zCoord * 1.0;
          worldObj.spawnEntityInWorld(babyEgg);
        }

        if (worldObj.rand.nextInt(3) == 1) {
          attackTick = 30;
          attacker.motionY = 0.61999998688697815D;
          jumpAttack = true;
        }
      }
      if (jumpAttack && attacker.motionY == -0.0784000015258789D) {
        areaOfEffect();
        ((EntityTarantulaMiniboss) attacker).spawnBlamParticles();
        jumpAttack = false;
      }
    }
  }