diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java index 00b60fa6b..4fbc3f2c9 100644 --- a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java @@ -28,10 +28,13 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab private final String profile; - public FeatureGenerationStage(Platform platform, String id) { + private final int resolution; + + public FeatureGenerationStage(Platform platform, String id, int resolution) { this.platform = platform; this.id = id; this.profile = "feature_stage:" + id; + this.resolution = resolution; } @Override @@ -41,34 +44,40 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab int cx = world.centerChunkX() << 4; int cz = world.centerChunkZ() << 4; long seed = world.getSeed(); - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - int tx = cx + x; - int tz = cz + z; - Column column = world.column(tx, tz); - long coordinateSeed = (seed * 31 + tx) * 31 + tz; - + for(int chunkX = 0; chunkX < 16; chunkX += resolution) { + for(int chunkZ = 0; chunkZ < 16; chunkZ += resolution) { + int tx = cx + chunkX; + int tz = cz + chunkZ; world.getBiomeProvider() .getColumn(tx, tz, world) - .forRanges((min, max, biome) -> - biome.getContext() - .get(BiomeFeatures.class) - .getFeatures() - .getOrDefault(this, Collections.emptyList()) - .forEach(feature -> { - platform.getProfiler().push(feature.getID()); - if(feature.getDistributor().matches(tx, tz, seed)) { - feature.getLocator() - .getSuitableCoordinates(column.clamp(min, max)) - .forEach(y -> feature.getStructure(world, tx, y, tz) - .generate(Vector3Int.of(tx, y, tz), - world, - new Random(coordinateSeed * 31 + y), - Rotation.NONE) - ); - } - platform.getProfiler().pop(feature.getID()); - })); + .forRanges((min, max, biome) -> { + for(int subChunkX = 0; subChunkX < resolution; subChunkX++) { + for(int subChunkZ = 0; subChunkZ < resolution; subChunkZ++) { + int x = subChunkX + tx; + int z = subChunkZ + tz; + long coordinateSeed = (seed * 31 + x) * 31 + z; + Column column = world.column(x, z); + biome.getContext() + .get(BiomeFeatures.class) + .getFeatures() + .getOrDefault(this, Collections.emptyList()) + .forEach(feature -> { + platform.getProfiler().push(feature.getID()); + if(feature.getDistributor().matches(x, z, seed)) { + feature.getLocator() + .getSuitableCoordinates(column.clamp(min, max)) + .forEach(y -> feature.getStructure(world, x, y, z) + .generate(Vector3Int.of(x, y, z), + world, + new Random(coordinateSeed * 31 + y), + Rotation.NONE) + ); + } + platform.getProfiler().pop(feature.getID()); + }); + } + } + }); } } platform.getProfiler().pop(profile); diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/FeatureStageTemplate.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/FeatureStageTemplate.java index 1663ceed8..b1604cc1a 100644 --- a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/FeatureStageTemplate.java +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/FeatureStageTemplate.java @@ -1,23 +1,41 @@ package com.dfsek.terra.addons.generation.feature.config; +import com.dfsek.tectonic.api.config.template.ValidatedConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Default; import com.dfsek.tectonic.api.config.template.annotations.Value; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import com.dfsek.tectonic.api.exception.ValidationException; import com.dfsek.terra.addons.generation.feature.FeatureGenerationStage; import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; -public class FeatureStageTemplate implements ObjectTemplate { +public class FeatureStageTemplate implements ObjectTemplate, ValidatedConfigTemplate { private final Platform platform; @Value("id") private String id; + @Value("resolution") + @Default + private int resolution = 4; + public FeatureStageTemplate(Platform platform) { this.platform = platform; } @Override public FeatureGenerationStage get() { - return new FeatureGenerationStage(platform, id); + return new FeatureGenerationStage(platform, id, resolution); + } + + @Override + public boolean validate() throws ValidationException { + if(!(resolution == 1 + || resolution == 2 + || resolution == 4 + || resolution == 8 + || resolution == 16)) throw new ValidationException( + "Resolution must be power of 2 less than or equal to 16 (1, 2, 4, 8, 16), got: " + resolution); + return true; } }