@Override
  public void onLivingUpdate() {

    super.onLivingUpdate();

    if (!worldObj.isRemote) {

      opacity.setValue(0.3f);

      boolean isIdle = getAITarget() == null;

      // sync a flag that says if we should be flying or not
      flags.set(FlagKeys.IS_FLYING, shouldBeFlying());
      flags.set(FlagKeys.IS_IDLE, isIdle);

      int sinceIdle = flags.ticksSinceSet(FlagKeys.IS_IDLE);

      boolean headInHand = flags.get(FlagKeys.HEAD_IN_HAND);

      int ticksSinceHeadChange = flags.ticksSinceChange(FlagKeys.HEAD_IN_HAND);

      if (DISABLE_HEAD_ANIMATION) {
        headInHand = false;
      } else {
        // if we're not idle, we dont want the head/hand behaviour
        if (!isIdle) {
          headInHand = false;
        } else {
          if (!headInHand
              && Math.min(sinceIdle, ticksSinceHeadChange)
                  > 50 + (20 * worldObj.rand.nextDouble())) {
            headInHand = true;
          } else if (headInHand && ticksSinceHeadChange > 50) {
            headInHand = false;
          }
        }
      }

      if (flags.get(FlagKeys.IS_FLYING)
          && worldObj.getHeightValue((int) posX, (int) posZ) + 1 > posY) {
        /*
         * Flying up causes the entity onGround to be false, nullifying
         * any movement. There is one option, override the movement
         * methods and implement them ourselves. This does provide the
         * opportunity for the ghost to fly through walls, but does make
         * life harder.
         *
         * Also some research needs to be done regarding how this fits
         * with AI
         */
        motionY = Math.max(motionY, 0.1D); /* Fly over blocks */
      }

      flags.set(FlagKeys.HEAD_IN_HAND, headInHand);
    }

    // send all our data to nearby users
    syncMap.sync(worldObj, this, posX, posY, posZ);
  }
  public EntityGhost(World world) {
    super(world);
    setSize(0.6F, 1.8F);
    setHealth(CompatibilityUtils.getEntityMaxHealth(this));
    setAIMoveSpeed(0.5F);
    this.tasks.addTask(0, new EntityAISwimming(this));
    // this.tasks.addTask(1, new EntityAIDragPlayer(this, 8.0F));
    this.tasks.addTask(
        2, new EntityAIAttackOnCollide(this, EntityPlayer.class, getAIMoveSpeed(), false));
    this.tasks.addTask(3, new EntityAIWander(this, getAIMoveSpeed() * 0.1f));
    this.tasks.addTask(4, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));

    // this.tasks.addTask(4, new EntityAILookIdle(this));
    this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
    this.targetTasks.addTask(
        2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));
    getNavigator().setAvoidsWater(true);

    syncMap.put(SyncKeys.FLAGS, flags);
    syncMap.put(SyncKeys.OPACITY, opacity);
  }