/** Called to update the entity's position/logic. */
  public void onUpdate() {
    lastTickPosX = posX;
    lastTickPosY = posY;
    lastTickPosZ = posZ;
    super.onUpdate();

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

    if (inGround) {
      int i = worldObj.getBlockId(xTile, yTile, zTile);

      if (i != inTile) {
        inGround = false;
        motionX *= rand.nextFloat() * 0.2F;
        motionY *= rand.nextFloat() * 0.2F;
        motionZ *= rand.nextFloat() * 0.2F;
        ticksInGround = 0;
        ticksInAir = 0;
      } else {
        ticksInGround++;

        if (ticksInGround == 1200) {
          setDead();
        }

        return;
      }
    } else {
      ticksInAir++;
    }

    Vec3D vec3d = Vec3D.createVector(posX, posY, posZ);
    Vec3D vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ);
    MovingObjectPosition movingobjectposition = worldObj.rayTraceBlocks(vec3d, vec3d1);
    vec3d = Vec3D.createVector(posX, posY, posZ);
    vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ);

    if (movingobjectposition != null) {
      vec3d1 =
          Vec3D.createVector(
              movingobjectposition.hitVec.xCoord,
              movingobjectposition.hitVec.yCoord,
              movingobjectposition.hitVec.zCoord);
    }

    if (!worldObj.isRemote) {
      Entity entity = null;
      List list =
          worldObj.getEntitiesWithinAABBExcludingEntity(
              this, boundingBox.addCoord(motionX, motionY, motionZ).expand(1.0D, 1.0D, 1.0D));
      double d = 0.0D;

      for (int k = 0; k < list.size(); k++) {
        Entity entity1 = (Entity) list.get(k);

        if (!entity1.canBeCollidedWith() || entity1 == thrower && ticksInAir < 5) {
          continue;
        }

        float f4 = 0.3F;
        AxisAlignedBB axisalignedbb = entity1.boundingBox.expand(f4, f4, f4);
        MovingObjectPosition movingobjectposition1 =
            axisalignedbb.calculateIntercept(vec3d, vec3d1);

        if (movingobjectposition1 == null) {
          continue;
        }

        double d1 = vec3d.distanceTo(movingobjectposition1.hitVec);

        if (d1 < d || d == 0.0D) {
          entity = entity1;
          d = d1;
        }
      }

      if (entity != null) {
        movingobjectposition = new MovingObjectPosition(entity);
      }
    }

    if (movingobjectposition != null) {
      onImpact(movingobjectposition);
    }

    posX += motionX;
    posY += motionY;
    posZ += motionZ;
    float f = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ);
    rotationYaw = (float) ((Math.atan2(motionX, motionZ) * 180D) / Math.PI);

    for (rotationPitch = (float) ((Math.atan2(motionY, f) * 180D) / Math.PI);
        rotationPitch - prevRotationPitch < -180F;
        prevRotationPitch -= 360F) {}

    for (; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) {}

    for (; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) {}

    for (; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) {}

    rotationPitch = prevRotationPitch + (rotationPitch - prevRotationPitch) * 0.2F;
    rotationYaw = prevRotationYaw + (rotationYaw - prevRotationYaw) * 0.2F;
    float f1 = 0.99F;
    float f2 = func_40075_e();

    if (isInWater()) {
      for (int j = 0; j < 4; j++) {
        float f3 = 0.25F;
        worldObj.spawnParticle(
            "bubble",
            posX - motionX * (double) f3,
            posY - motionY * (double) f3,
            posZ - motionZ * (double) f3,
            motionX,
            motionY,
            motionZ);
      }

      f1 = 0.8F;
    }

    motionX *= f1;
    motionY *= f1;
    motionZ *= f1;
    motionY -= f2;
    setPosition(posX, posY, posZ);
  }