@Override
  public void process(GeneratingRegion region) {
    // will give funny results for regions that are not exactly chunk sized, but it is better than
    // sinking in the water on spawn
    Vector3i centerChunkPos = new Vector3i(ChunkConstants.CHUNK_REGION.center());
    if (region.getRegion().encompasses(centerChunkPos)) {
      SurfaceHeightFacet facet = region.getRegionFacet(SurfaceHeightFacet.class);
      SeaLevelFacet seaLevelFacet = region.getRegionFacet(SeaLevelFacet.class);
      float seaLevel = seaLevelFacet.getSeaLevel();
      float targetHeight = seaLevel + 1; // one block above the seaLevel

      // update the surface height so that it spikes up to sea level
      Vector2i middlePos = new Vector2i(centerChunkPos.x, centerChunkPos.z);
      for (BaseVector2i pos : facet.getWorldRegion().contents()) {
        float originalValue = facet.getWorld(pos);
        if (seaLevel > originalValue) {
          // the surface is below sea level
          float scaleTowardsSeaLevel =
              (float) pos.gridDistance(middlePos) / (float) (ChunkConstants.SIZE_X / 2);
          if (scaleTowardsSeaLevel < 1f) {
            facet.setWorld(
                pos, TeraMath.lerp(originalValue, targetHeight, 1f - scaleTowardsSeaLevel));
          }
        }
      }
    }
  }
예제 #2
0
  private Optional<Road> tryDirect(
      BaseVector2i posA, BaseVector2i posB, float width, BuildableTerrainFacet terrainFacet) {
    double length = posA.distance(posB);
    int segCount =
        TeraMath.ceilToInt(length / segLength); // ceil avoids division by zero for short distances

    List<Vector2i> segPoints = new ArrayList<>();

    segPoints.add(new Vector2i(posA));
    for (int i = 1; i < segCount; i++) {
      Vector2i pos = BaseVector2i.lerp(posA, posB, (float) i / segCount, RoundingMode.HALF_UP);

      // first and last point receive only half the noise distortion to smoothen the end points
      float applyFactor = (i == 1 || i == segCount - 1) ? 0.5f : 1f;
      pos.x += noiseX.noise(pos.x * smooth, 0, pos.y * smooth) * noiseAmp * applyFactor;
      pos.y += noiseY.noise(pos.x * smooth, 0, pos.y * smooth) * noiseAmp * applyFactor;

      if (!terrainFacet.isPassable(pos)) {
        return Optional.empty();
      }

      segPoints.add(pos);
    }
    segPoints.add(new Vector2i(posB));

    return Optional.of(new Road(segPoints, width));
  }