@Override
  protected void updateAITasks() {
    super.updateAITasks();
    if (this.spawnPosition != null
        && (!this.worldObj.isAirBlock(
                this.spawnPosition.posX, this.spawnPosition.posY, this.spawnPosition.posZ)
            || this.spawnPosition.posY < 1)) {
      this.spawnPosition = null;
    }

    if (this.spawnPosition == null
        || this.rand.nextInt(30) == 0
        || this.spawnPosition.getDistanceSquared((int) this.posX, (int) this.posY, (int) this.posZ)
            < 4.0F) {
      this.spawnPosition =
          new ChunkCoordinates(
              (int) this.posX + this.rand.nextInt(7) - this.rand.nextInt(7),
              (int) this.posY + this.rand.nextInt(6) - 2,
              (int) this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7));
    }

    double d0 = (double) this.spawnPosition.posX + 0.01D - this.posX;
    double d1 = (double) this.spawnPosition.posY + 0.1D - this.posY;
    double d2 = (double) this.spawnPosition.posZ + 0.01D - this.posZ;
    double d3 = (double) MathHelper.sqrt_double(d0 * d0 + d1 * d1 + d2 * d2);
    this.motionX += d0 / d3 * 0.05D;
    this.motionY += d1 / d3 * 0.1D;
    this.motionZ += d2 / d3 * 0.05D;
    float f = (float) (Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) - 90.0F;
    float f1 = MathHelper.wrapAngleTo180_float(f - this.rotationYaw);
    this.moveForward = 0.001F;
    this.rotationYaw += f1;
  }
 @Override
 protected void applyEntityAttributes() {
   super.applyEntityAttributes();
   this.getEntityAttribute(SharedMonsterAttributes.maxHealth)
       .setBaseValue(net.divinerpg.entities.base.EntityStats.theWatcherHealth);
   this.getEntityAttribute(SharedMonsterAttributes.movementSpeed)
       .setBaseValue(net.divinerpg.entities.base.EntityStats.theWatcherSpeed);
   this.getEntityAttribute(SharedMonsterAttributes.followRange)
       .setBaseValue(net.divinerpg.entities.base.EntityStats.theWatcherFollowRange);
 }
  @Override
  public void onLivingUpdate() {
    super.onLivingUpdate();
    this.prevAttackCounter = this.attackCounter;
    double var1 = this.waypointX - this.posX;
    double var3 = this.waypointY - this.posY;
    double var5 = this.waypointZ - this.posZ;
    double var7 = (double) MathHelper.sqrt_double(var1 * var1 + var3 * var3 + var5 * var5);

    if (var7 < 1.0D || var7 > 60.0D) {
      this.waypointX = this.posX + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
      this.waypointY = this.posY + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
      this.waypointZ = this.posZ + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
    }

    if (this.courseChangeCooldown-- <= 0) {
      this.courseChangeCooldown += this.rand.nextInt(5) + 2;

      if (this.isCourseTraversable(this.waypointX, this.waypointY, this.waypointZ, var7)) {
        this.motionX += var1 / var7 * 0.1D;
        this.motionY += var3 / var7 * 0.1D;
        this.motionZ += var5 / var7 * 0.1D;
      } else {
        this.waypointX = this.posX;
        this.waypointY = this.posY;
        this.waypointZ = this.posZ;
      }
    }

    if (this.targetedEntity != null && this.targetedEntity.isDead) {
      this.targetedEntity = null;
    }

    if (this.targetedEntity == null || this.aggroCooldown-- <= 0) {
      this.targetedEntity = this.worldObj.getClosestVulnerablePlayerToEntity(this, 100.0D);

      if (this.targetedEntity != null) {
        this.aggroCooldown = 20;
      }
    }

    double var9 = 100.0D;

    if (this.targetedEntity != null
        && this.targetedEntity.getDistanceSqToEntity(this) < var9 * var9) {
      double tx = this.targetedEntity.posX - this.posX;
      double ty = this.targetedEntity.boundingBox.minY - this.posY;
      double tz = this.targetedEntity.posZ - this.posZ;
      this.renderYawOffset =
          this.rotationYaw = -((float) Math.atan2(tx, tz)) * 180.0F / (float) Math.PI;

      if (this.canEntityBeSeen(this.targetedEntity)) {
        if (this.attackCounter == 20) {
          this.worldObj.playSoundAtEntity(this, Sounds.roar.getPrefixedName(), 10.0F, 0.9F);
        }

        ++this.attackCounter;

        if (this.attackCounter == 20) {
          EntityWatcherShot shot = new EntityWatcherShot(this.worldObj, this);
          shot.setThrowableHeading(tx, ty, tz, 1.6f, 12);
          if (!this.worldObj.isRemote) this.worldObj.spawnEntityInWorld(shot);
          this.attackCounter = -40;
        }
      } else if (this.attackCounter > 0) {
        --this.attackCounter;
      }
    } else {
      this.renderYawOffset =
          this.rotationYaw =
              -((float) Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float) Math.PI;

      if (this.attackCounter > 0) {
        --this.attackCounter;
      }
    }
  }
 @Override
 public void onUpdate() {
   super.onUpdate();
   this.motionY *= 0.6000000238418579D;
 }