/** Returns true if at least one block has changed. */
  public static final boolean genBlob(
      DecoratorFeatureGenerator gen, double x, double y, double z, double rad, Block block) {
    boolean generatedSomething = false;
    double radSq = MathUtil.square(rad + 0.5D);
    int size = MathUtil.ceil(rad),
        ix = MathUtil.floor(x),
        iy = MathUtil.floor(y),
        iz = MathUtil.floor(z);
    List<BlockPosM> locs = new ArrayList<BlockPosM>();

    for (int xx = ix - size; xx <= ix + size; xx++) {
      for (int yy = iy - size; yy <= iy + size; yy++) {
        for (int zz = iz - size; zz <= iz + size; zz++) {
          if (MathUtil.distanceSquared(xx - x, yy - y, zz - z) <= radSq) {
            if (gen.getBlock(xx, yy, zz) != block && gen.setBlock(xx, yy, zz, block)) {
              generatedSomething = true;
              locs.add(new BlockPosM(xx, yy, zz));
            }
          }
        }
      }
    }

    return generatedSomething;
  }
  public <T extends EntityLiving> Consumer<T> spawnOnFloor(final Predicate<BlockInfo> blockFinder) {
    return entity -> {
      final Random rand = entity.worldObj.rand;
      final double posX = area.x1 + rand.nextDouble() * (area.x2 - area.x1);
      final double posZ = area.z1 + rand.nextDouble() * (area.z2 - area.z1);
      final int posY =
          Pos.getTopBlock(
                  entity.worldObj,
                  MathUtil.floor(posX),
                  MathUtil.floor(posZ),
                  area.y1 + rand.nextInt(1 + area.y2 - area.y1),
                  blockFinder)
              .getY();

      entity.setPosition(posX, posY + 1D, posZ);
    };
  }
  public <T extends EntityLiving> IGroupLocationFinder<T> groupOnFloor(
      final double minDistance, final double maxDistance, final Predicate<BlockInfo> blockFinder) {
    return (parentEntity, groupedEntity) -> {
      final Random rand = parentEntity.worldObj.rand;
      final Vec offset =
          Vec.xzRandom(rand)
              .multiplied(minDistance + rand.nextDouble() * (maxDistance - minDistance));
      final double posX = parentEntity.posX + offset.x;
      final double posZ = parentEntity.posZ + offset.z;
      final int posY =
          Pos.getTopBlock(
                  parentEntity.worldObj,
                  MathUtil.floor(posX),
                  MathUtil.floor(posZ),
                  MathUtil.floor(parentEntity.posY + maxDistance),
                  blockFinder)
              .getY();

      groupedEntity.setPosition(posX, posY + 1D, posZ);
    };
  }