@Override
  public void onUpdate() {
    // Standard motion
    double mx = motionX;
    double my = motionY;
    double mz = motionZ;

    super.onUpdate();

    if (!bounced) {
      // Reset the drag applied by super
      motionX = mx;
      motionY = my;
      motionZ = mz;
    }

    bounced = false;

    // Returning motion
    if (isReturning()) {
      Entity thrower = worldObj.getEntityByID(getEntityToReturnTo());
      Vector3 motion =
          Vector3.fromEntityCenter(thrower).subtract(Vector3.fromEntityCenter(this)).normalize();
      motionX = motion.x;
      motionY = motion.y;
      motionZ = motion.z;
    }

    // Client FX
    if (worldObj.isRemote && isFire()) {
      double r = 0.1;
      double m = 0.1;
      for (int i = 0; i < 3; i++)
        worldObj.spawnParticle(
            EnumParticleTypes.FLAME,
            posX + r * (Math.random() - 0.5),
            posY + r * (Math.random() - 0.5),
            posZ + r * (Math.random() - 0.5),
            m * (Math.random() - 0.5),
            m * (Math.random() - 0.5),
            m * (Math.random() - 0.5));
    }

    // Server state control
    if (!worldObj.isRemote && (getTimesBounced() >= MAX_BOUNCES || ticksExisted > 60)) {
      EntityLivingBase thrower = getThrower();
      if (thrower == null) {
        dropAndKill();
      } else {
        setEntityToReturnTo(thrower.getEntityId());
        if (getDistanceSqToEntity(thrower) < 2) dropAndKill();
      }
    }
  }