commit d0f3ae65811b30329712f82acca242ad57aec727 Author: dfsek Date: Sun Oct 17 15:25:45 2021 -0700 Initial commit diff --git a/common/addons/generation-stage-feature/build.gradle.kts b/common/addons/generation-stage-feature/build.gradle.kts new file mode 100644 index 000000000..7d82dc72f --- /dev/null +++ b/common/addons/generation-stage-feature/build.gradle.kts @@ -0,0 +1,2 @@ +dependencies { +} diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/ColumnImpl.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/ColumnImpl.java new file mode 100644 index 000000000..9acdab106 --- /dev/null +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/ColumnImpl.java @@ -0,0 +1,63 @@ +package com.dfsek.terra.addons.generation.feature; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.structure.feature.BinaryColumn; +import com.dfsek.terra.api.world.Column; +import com.dfsek.terra.api.world.World; + +import java.util.function.IntConsumer; + + +public class ColumnImpl implements Column { + private final int x; + private final int z; + private final World world; + + public ColumnImpl(int x, int z, World world) { + this.x = x; + this.z = z; + this.world = world; + } + + @Override + public int getX() { + return x; + } + + @Override + public int getZ() { + return z; + } + + @Override + public BlockState getBlock(int y) { + return world.getBlockData(x, y, z); + } + + @Override + public World getWorld() { + return world; + } + + @Override + public int getMinY() { + return world.getMinHeight(); + } + + @Override + public int getMaxY() { + return world.getMaxHeight(); + } + + @Override + public void forEach(IntConsumer function) { + for(int y = world.getMinHeight(); y < world.getMaxHeight(); y++) { + function.accept(y); + } + } + + @Override + public BinaryColumn newBinaryColumn() { + return new BinaryColumn(getMinY(), getMaxY()); + } +} diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationAddon.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationAddon.java new file mode 100644 index 000000000..8016a58c0 --- /dev/null +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationAddon.java @@ -0,0 +1,44 @@ +package com.dfsek.terra.addons.generation.feature; + +import com.dfsek.terra.addons.generation.feature.config.BiomeFeaturesTemplate; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.addon.TerraAddon; +import com.dfsek.terra.api.addon.annotations.Addon; +import com.dfsek.terra.api.addon.annotations.Author; +import com.dfsek.terra.api.addon.annotations.Version; +import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent; +import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; +import com.dfsek.terra.api.event.functional.FunctionalEventHandler; +import com.dfsek.terra.api.inject.annotations.Inject; +import com.dfsek.terra.api.world.biome.TerraBiome; +import com.dfsek.terra.api.world.generator.GenerationStageProvider; + + +@Addon("generation-stage-feature") +@Version("1.0.0") +@Author("Terra") +public class FeatureGenerationAddon extends TerraAddon { + @Inject + private Platform platform; + + @Override + public void initialize() { + platform.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(this, ConfigPackPreLoadEvent.class) + .then(event -> event.getPack() + .getOrCreateRegistry(GenerationStageProvider.class) + .register("FEATURE", pack -> new FeatureGenerationStage(platform))) + .failThrough(); + + platform.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(this, ConfigurationLoadEvent.class) + .then(event -> { + if(event.is(TerraBiome.class)) { + event.getLoadedObject(TerraBiome.class).getContext().put(event.load(new BiomeFeaturesTemplate()).get()); + } + }) + .failThrough(); + } +} 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 new file mode 100644 index 000000000..0b03ef29e --- /dev/null +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java @@ -0,0 +1,48 @@ +package com.dfsek.terra.addons.generation.feature; + +import com.dfsek.terra.addons.generation.feature.config.BiomeFeatures; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.profiler.ProfileFrame; +import com.dfsek.terra.api.structure.rotation.Rotation; +import com.dfsek.terra.api.util.PopulationUtil; +import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.world.Chunk; +import com.dfsek.terra.api.world.World; +import com.dfsek.terra.api.world.generator.GenerationStage; + + +public class FeatureGenerationStage implements GenerationStage { + private final Platform platform; + + public FeatureGenerationStage(Platform platform) { + this.platform = platform; + } + + @Override + @SuppressWarnings("try") + public void populate(World world, Chunk chunk) { + try(ProfileFrame ignore = platform.getProfiler().profile("feature")) { + int cx = chunk.getX() << 4; + int cz = chunk.getZ() << 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; + ColumnImpl column = new ColumnImpl(tx, tz, world); + world.getBiomeProvider().getBiome(tx, tz, seed).getContext().get(BiomeFeatures.class).getFeatures().forEach(feature -> { + if(feature.getDistributor().matches(tx, tz, seed)) { + feature.getLocator() + .getSuitableCoordinates(column) + .forEach(y -> + feature.getStructure(world, tx, y, tz) + .generate(new Vector3(tx, y, tz), world, PopulationUtil.getRandom(chunk), + Rotation.NONE) + ); + } + }); + } + } + } + } +} diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/BiomeFeatures.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/BiomeFeatures.java new file mode 100644 index 000000000..19fe4d503 --- /dev/null +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/BiomeFeatures.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.generation.feature.config; + +import java.util.List; + +import com.dfsek.terra.api.properties.Properties; +import com.dfsek.terra.api.structure.feature.Feature; + + +public class BiomeFeatures implements Properties { + private final List features; + + public BiomeFeatures(List features) { + this.features = features; + } + + public List getFeatures() { + return features; + } +} diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/BiomeFeaturesTemplate.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/BiomeFeaturesTemplate.java new file mode 100644 index 000000000..9132b7374 --- /dev/null +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/BiomeFeaturesTemplate.java @@ -0,0 +1,23 @@ +package com.dfsek.terra.addons.generation.feature.config; + +import com.dfsek.tectonic.annotations.Default; +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import java.util.Collections; +import java.util.List; + +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.structure.feature.Feature; + + +public class BiomeFeaturesTemplate implements ObjectTemplate { + @Value("features") + @Default + private @Meta List<@Meta Feature> features = Collections.emptyList(); + + @Override + public BiomeFeatures get() { + return new BiomeFeatures(features); + } +}