@Override
  public void j_() {
    super.j_();
    if (npc == null) return;
    boolean navigating = npc.getNavigator().isNavigating();
    updatePackets(navigating);
    if (gravity
        && !navigating
        && getBukkitEntity() != null
        && Util.isLoaded(getBukkitEntity().getLocation(LOADED_LOCATION))
        && !NMS.inWater(getBukkitEntity())) {
      move(0, -0.2, 0);
      // gravity. also works around an entity.onGround not updating issue
      // (onGround is normally updated by the client)
    }
    if (!npc.data().get("removefromplayerlist", true)) g();
    if (Math.abs(motX) < EPSILON && Math.abs(motY) < EPSILON && Math.abs(motZ) < EPSILON)
      motX = motY = motZ = 0;

    NMS.updateSenses(this);
    if (navigating) {
      Navigation navigation = getNavigation();
      if (!navigation.f()) navigation.e();
      moveOnCurrentHeading();
    } else if (motX != 0 || motZ != 0 || motY != 0) {
      e(0, 0); // is this necessary? it does controllable but sometimes
      // players sink into the ground
    }

    if (noDamageTicks > 0) --noDamageTicks;
    npc.update();
  }
  @Override
  public void A_() {
    super.A_();
    if (npc == null) return;
    if (updateCounter + 1 > Setting.PACKET_UPDATE_DELAY.asInt()) {
      updateEffects = true;
    }
    livingEntityBaseTick();

    boolean navigating = npc.getNavigator().isNavigating();
    updatePackets(navigating);
    if (!navigating
        && getBukkitEntity() != null
        && npc.getTrait(Gravity.class).hasGravity()
        && Util.isLoaded(getBukkitEntity().getLocation(LOADED_LOCATION))) {
      g(0, 0);
    }
    if (Math.abs(motX) < EPSILON && Math.abs(motY) < EPSILON && Math.abs(motZ) < EPSILON) {
      motX = motY = motZ = 0;
    }
    if (navigating) {
      if (!NMSImpl.isNavigationFinished(navigation)) {
        NMSImpl.updateNavigation(navigation);
      }
      moveOnCurrentHeading();
    }
    NMSImpl.updateAI(this);

    if (noDamageTicks > 0) {
      --noDamageTicks;
    }

    npc.update();
  }