Merge submodule contents for common/addons/biome-provider-pipeline/master

This commit is contained in:
dfsek
2021-11-21 21:09:17 -07:00
34 changed files with 1201 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-2021 Polyhedral Development
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,7 @@
# biome-provider-pipeline
Implements the Biome Pipeline, a procedural biome provider that uses a series
of "stages" to apply "mutations" to a 2D grid of biomes.
This addon registers the `PIPELINE` biome provider type, and all associated
configurations.

View File

@@ -0,0 +1,3 @@
dependencies {
"shadedApi"(project(":common:addons:manifest-addon-loader"))
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeExpander;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.api.util.vector.Vector2;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class BiomeHolderImpl implements BiomeHolder {
private final Vector2 origin;
private final int width;
private final int offset;
private TerraBiome[][] biomes;
public BiomeHolderImpl(int width, Vector2 origin) {
width += 4;
this.width = width;
biomes = new TerraBiome[width][width];
this.origin = origin;
this.offset = 2;
}
private BiomeHolderImpl(TerraBiome[][] biomes, Vector2 origin, int width, int offset) {
this.biomes = biomes;
this.origin = origin;
this.width = width;
this.offset = 2 * offset;
}
@Override
public BiomeHolder expand(BiomeExpander expander, long seed) {
TerraBiome[][] old = biomes;
int newWidth = width * 2 - 1;
biomes = new TerraBiome[newWidth][newWidth];
for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) {
biomes[x * 2][z * 2] = old[x][z];
if(z != width - 1)
biomes[x * 2][z * 2 + 1] = expander.getBetween(x + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z],
old[x][z + 1]);
if(x != width - 1)
biomes[x * 2 + 1][z * 2] = expander.getBetween(x + 1 + origin.getX(), z + origin.getZ(), seed, old[x][z],
old[x + 1][z]);
if(x != width - 1 && z != width - 1)
biomes[x * 2 + 1][z * 2 + 1] = expander.getBetween(x + 1 + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z],
old[x + 1][z + 1], old[x][z + 1], old[x + 1][z]);
}
}
return new BiomeHolderImpl(biomes, origin.setX(origin.getX() * 2 - 1).setZ(origin.getZ() * 2 - 1), newWidth, offset);
}
@Override
public void mutate(BiomeMutator mutator, long seed) {
for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) {
BiomeMutator.ViewPoint viewPoint = new BiomeMutator.ViewPoint(this, x, z);
biomes[x][z] = mutator.mutate(viewPoint, x + origin.getX(), z + origin.getZ(), seed);
}
}
}
@Override
public void fill(BiomeSource source, long seed) {
for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) {
biomes[x][z] = source.getBiome(origin.getX() + x, origin.getZ() + z, seed);
}
}
}
@Override
public TerraBiome getBiome(int x, int z) {
x += offset;
z += offset;
return getBiomeRaw(x, z);
}
@Override
public TerraBiome getBiomeRaw(int x, int z) {
if(x >= width || z >= width || x < 0 || z < 0) return null;
return biomes[x][z];
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline;
import java.util.ArrayList;
import java.util.List;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.api.util.vector.Vector2;
public class BiomePipeline {
private final BiomeSource source;
private final List<Stage> stages;
private final int size;
private final int init;
private BiomePipeline(BiomeSource source, List<Stage> stages, int size, int init) {
this.source = source;
this.stages = stages;
this.size = size;
this.init = init;
}
/**
* Get biomes in a chunk
*
* @param x Chunk X coord
* @param z Chunk Z coord
*
* @return BiomeHolder containing biomes.
*/
public BiomeHolder getBiomes(int x, int z, long seed) {
BiomeHolder holder = new BiomeHolderImpl(init, new Vector2(x * (init - 1), z * (init - 1)));
holder.fill(source, seed);
for(Stage stage : stages) holder = stage.apply(holder, seed);
return holder;
}
public int getSize() {
return size;
}
public static final class BiomePipelineBuilder {
private final int init;
private final List<Stage> stages = new ArrayList<>();
private int expand;
public BiomePipelineBuilder(int init) {
this.init = init;
expand = init;
}
public BiomePipeline build(BiomeSource source) {
for(Stage stage : stages) {
if(stage.isExpansion()) expand = expand * 2 - 1;
}
return new BiomePipeline(source, stages, expand, init);
}
public BiomePipelineBuilder addStage(Stage stage) {
stages.add(stage);
return this;
}
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import java.util.function.Supplier;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.config.BiomePipelineTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.NoiseSourceTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.expander.ExpanderStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderListMutatorTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderMutatorTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceListMutatorTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceMutatorTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.SmoothMutatorTemplate;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
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.registry.CheckedRegistry;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
};
@Inject
private Platform platform;
@Inject
private BaseAddon addon;
@Override
public void initialize() {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY);
providerRegistry.register("PIPELINE", () -> new BiomePipelineTemplate(platform));
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeSource>>> sourceRegistry = event.getPack().getOrCreateRegistry(
SOURCE_REGISTRY_KEY);
sourceRegistry.register("NOISE", NoiseSourceTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(
STAGE_REGISTRY_KEY);
stageRegistry.register("FRACTAL_EXPAND", ExpanderStageTemplate::new);
stageRegistry.register("SMOOTH", SmoothMutatorTemplate::new);
stageRegistry.register("REPLACE", ReplaceMutatorTemplate::new);
stageRegistry.register("REPLACE_LIST", ReplaceListMutatorTemplate::new);
stageRegistry.register("BORDER", BorderMutatorTemplate::new);
stageRegistry.register("BORDER_LIST", BorderListMutatorTemplate::new);
})
.failThrough();
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import net.jafama.FastMath;
import org.jetbrains.annotations.NotNull;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineProvider implements BiomeProvider {
private final LoadingCache<SeededVector, BiomeHolder> holderCache;
private final BiomePipeline pipeline;
private final int resolution;
private final NoiseSampler mutator;
private final double noiseAmp;
public BiomePipelineProvider(BiomePipeline pipeline, Platform platform, int resolution, NoiseSampler mutator, double noiseAmp) {
this.resolution = resolution;
this.mutator = mutator;
this.noiseAmp = noiseAmp;
holderCache = CacheBuilder.newBuilder()
.maximumSize(platform == null ? 32 : platform.getTerraConfig().getProviderCache())
.build(
new CacheLoader<>() {
@Override
public BiomeHolder load(@NotNull SeededVector key) {
return pipeline.getBiomes(key.x, key.z, key.seed);
}
}
);
this.pipeline = pipeline;
}
@Override
public TerraBiome getBiome(int x, int z, long seed) {
x += mutator.getNoiseSeeded(seed + 1, x, z) * noiseAmp;
z += mutator.getNoiseSeeded(seed + 2, x, z) * noiseAmp;
x = FastMath.floorToInt(FastMath.floorDiv(x, resolution));
z = FastMath.floorToInt(FastMath.floorDiv(z, resolution));
int fdX = FastMath.floorDiv(x, pipeline.getSize());
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
return holderCache.getUnchecked(new SeededVector(fdX, fdZ, seed)).getBiome(x - fdX * pipeline.getSize(),
z - fdZ * pipeline.getSize());
}
private static final class SeededVector {
private final int x;
private final int z;
private final long seed;
private SeededVector(int x, int z, long seed) {
this.x = x;
this.z = z;
this.seed = seed;
}
@Override
public int hashCode() {
int result = 0;
result = 31 * result + ((int) (seed ^ (seed >>> 32)));
result = 31 * result + x;
result = 31 * result + z;
return result;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof SeededVector)) return false;
SeededVector that = (SeededVector) obj;
return this.seed == that.seed && this.x == that.x && this.z == that.z;
}
}
}

View File

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.api.world.biome.TerraBiome;
public interface BiomeExpander {
TerraBiome getBetween(double x, double z, long seed, TerraBiome... others);
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.api.world.biome.TerraBiome;
public interface BiomeHolder {
BiomeHolder expand(BiomeExpander expander, long seed);
void mutate(BiomeMutator mutator, long seed);
void fill(BiomeSource source, long seed);
TerraBiome getBiome(int x, int z);
TerraBiome getBiomeRaw(int x, int z);
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.api.world.biome.TerraBiome;
public interface BiomeMutator {
TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed);
class ViewPoint {
private final BiomeHolder biomes;
private final int offX;
private final int offZ;
public ViewPoint(BiomeHolder biomes, int offX, int offZ) {
this.biomes = biomes;
this.offX = offX;
this.offZ = offZ;
}
public TerraBiome getBiome(int x, int z) {
return biomes.getBiomeRaw(x + offX, z + offZ);
}
}
}

View File

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.api;
public interface Stage {
BiomeHolder apply(BiomeHolder in, long seed);
boolean isExpansion();
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import java.util.List;
import com.dfsek.terra.addons.biome.pipeline.BiomePipeline;
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineProvider;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
public class BiomePipelineTemplate extends BiomeProviderTemplate {
private final Platform platform;
@Value("pipeline.initial-size")
@Default
private @Meta int initialSize = 2;
@Value("pipeline.stages")
private @Meta List<@Meta Stage> stages;
@Value("pipeline.source")
private @Meta BiomeSource source;
public BiomePipelineTemplate(Platform platform) {
this.platform = platform;
}
@Override
public BiomeProvider get() {
BiomePipeline.BiomePipelineBuilder biomePipelineBuilder = new BiomePipeline.BiomePipelineBuilder(initialSize);
stages.forEach(biomePipelineBuilder::addStage);
BiomePipeline pipeline = biomePipelineBuilder.build(source);
return new BiomePipelineProvider(pipeline, platform, resolution, blend, blendAmp);
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import java.lang.reflect.AnnotatedType;
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineProvider;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomeProviderLoader implements TypeLoader<BiomeProvider> {
@Override
public BiomeProvider load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
return loader.loadType(BiomePipelineProvider.class, c); // TODO: actually implement this lol
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider> {
@Value("resolution")
@Default
protected @Meta int resolution = 1;
@Value("blend.noise")
@Default
protected @Meta NoiseSampler blend = NoiseSampler.zero();
@Value("blend.amplitude")
@Default
protected @Meta double blendAmp = 0d;
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.addons.biome.pipeline.source.NoiseSource;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class NoiseSourceTemplate extends SourceTemplate {
@Value("noise")
private @Meta NoiseSampler noise;
@Value("biomes")
private @Meta ProbabilityCollection<@Meta TerraBiome> biomes;
@Override
public BiomeSource get() {
return new NoiseSource(biomes, noise);
}
}

View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
public abstract class SourceTemplate implements ObjectTemplate<BiomeSource> {
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config.stage;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
public abstract class StageTemplate implements ObjectTemplate<Stage> {
@Value("noise")
protected @Meta NoiseSampler noise;
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config.stage.expander;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.expand.FractalExpander;
import com.dfsek.terra.addons.biome.pipeline.stages.ExpanderStage;
public class ExpanderStageTemplate extends StageTemplate {
@Override
public Stage get() {
return new ExpanderStage(new FractalExpander(noise));
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
import com.dfsek.tectonic.annotations.Value;
import java.util.Map;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderListMutator;
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
@SuppressWarnings("unused")
public class BorderListMutatorTemplate extends StageTemplate {
@Value("from")
private @Meta String from;
@Value("default-replace")
private @Meta String defaultReplace;
@Value("default-to")
private @Meta ProbabilityCollection<@Meta TerraBiome> defaultTo;
@Value("replace")
private @Meta Map<@Meta TerraBiome, @Meta ProbabilityCollection<@Meta TerraBiome>> replace;
@Override
public Stage get() {
return new MutatorStage(new BorderListMutator(replace, from, defaultReplace, noise, defaultTo));
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderMutator;
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
@SuppressWarnings("unused")
public class BorderMutatorTemplate extends StageTemplate {
@Value("from")
private @Meta String from;
@Value("replace")
private @Meta String replace;
@Value("to")
private @Meta ProbabilityCollection<@Meta TerraBiome> to;
@Override
public Stage get() {
return new MutatorStage(new BorderMutator(from, replace, noise, to));
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
import com.dfsek.tectonic.annotations.Value;
import java.util.Map;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceListMutator;
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
@SuppressWarnings("unused")
public class ReplaceListMutatorTemplate extends StageTemplate {
@Value("default-from")
private @Meta String defaultFrom;
@Value("default-to")
private @Meta ProbabilityCollection<@Meta TerraBiome> defaultTo;
@Value("to")
private @Meta Map<@Meta TerraBiome, @Meta ProbabilityCollection<@Meta TerraBiome>> replace;
@Override
public Stage get() {
return new MutatorStage(new ReplaceListMutator(replace, defaultFrom, defaultTo, noise));
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceMutator;
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
@SuppressWarnings("unused")
public class ReplaceMutatorTemplate extends StageTemplate {
@Value("from")
private @Meta String from;
@Value("to")
private @Meta ProbabilityCollection<@Meta TerraBiome> to;
@Override
public Stage get() {
return new MutatorStage(new ReplaceMutator(from, to, noise));
}
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.mutator.SmoothMutator;
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
public class SmoothMutatorTemplate extends StageTemplate {
@Override
public Stage get() {
return new MutatorStage(new SmoothMutator(noise));
}
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.expand;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeExpander;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class FractalExpander implements BiomeExpander {
private final NoiseSampler sampler;
public FractalExpander(NoiseSampler sampler) {
this.sampler = sampler;
}
@Override
public TerraBiome getBetween(double x, double z, long seed, TerraBiome... others) {
return others[MathUtil.normalizeIndex(sampler.getNoiseSeeded(seed, x, z), others.length)];
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.mutator;
import java.util.Map;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class BorderListMutator implements BiomeMutator {
private final String border;
private final NoiseSampler noiseSampler;
private final ProbabilityCollection<TerraBiome> replaceDefault;
private final String defaultReplace;
private final Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
public BorderListMutator(Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace, String border, String defaultReplace,
NoiseSampler noiseSampler, ProbabilityCollection<TerraBiome> replaceDefault) {
this.border = border;
this.noiseSampler = noiseSampler;
this.replaceDefault = replaceDefault;
this.defaultReplace = defaultReplace;
this.replace = replace;
}
@Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
TerraBiome origin = viewPoint.getBiome(0, 0);
if(origin.getTags().contains(defaultReplace)) {
for(int xi = -1; xi <= 1; xi++) {
for(int zi = -1; zi <= 1; zi++) {
if(xi == 0 && zi == 0) continue;
TerraBiome current = viewPoint.getBiome(xi, zi);
if(current == null) continue;
if(current.getTags().contains(border)) {
if(replace.containsKey(origin)) {
TerraBiome biome = replace.get(origin).get(noiseSampler, x, z, seed);
return biome == null ? origin : biome;
}
TerraBiome biome = replaceDefault.get(noiseSampler, x, z, seed);
return biome == null ? origin : biome;
}
}
}
}
return origin;
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.mutator;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class BorderMutator implements BiomeMutator {
private final String border;
private final NoiseSampler noiseSampler;
private final ProbabilityCollection<TerraBiome> replace;
private final String replaceTag;
public BorderMutator(String border, String replaceTag, NoiseSampler noiseSampler, ProbabilityCollection<TerraBiome> replace) {
this.border = border;
this.noiseSampler = noiseSampler;
this.replace = replace;
this.replaceTag = replaceTag;
}
@Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
TerraBiome origin = viewPoint.getBiome(0, 0);
if(origin.getTags().contains(replaceTag)) {
for(int xi = -1; xi <= 1; xi++) {
for(int zi = -1; zi <= 1; zi++) {
if(xi == 0 && zi == 0) continue;
TerraBiome current = viewPoint.getBiome(xi, zi);
if(current == null) continue;
if(current.getTags().contains(border)) {
TerraBiome biome = replace.get(noiseSampler, x, z, seed);
return biome == null ? origin : biome;
}
}
}
}
return origin;
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.mutator;
import java.util.Map;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class ReplaceListMutator implements BiomeMutator {
private final Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
private final NoiseSampler sampler;
private final ProbabilityCollection<TerraBiome> replaceDefault;
private final String defaultTag;
public ReplaceListMutator(Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace, String defaultTag,
ProbabilityCollection<TerraBiome> replaceDefault, NoiseSampler sampler) {
this.replace = replace;
this.sampler = sampler;
this.defaultTag = defaultTag;
this.replaceDefault = replaceDefault;
}
@Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
TerraBiome center = viewPoint.getBiome(0, 0);
if(replace.containsKey(center)) {
TerraBiome biome = replace.get(center).get(sampler, x, z, seed);
return biome == null ? viewPoint.getBiome(0, 0) : biome;
}
if(viewPoint.getBiome(0, 0).getTags().contains(defaultTag)) {
TerraBiome biome = replaceDefault.get(sampler, x, z, seed);
return biome == null ? viewPoint.getBiome(0, 0) : biome;
}
return center;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.mutator;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class ReplaceMutator implements BiomeMutator {
private final String replaceableTag;
private final ProbabilityCollection<TerraBiome> replace;
private final NoiseSampler sampler;
public ReplaceMutator(String replaceable, ProbabilityCollection<TerraBiome> replace, NoiseSampler sampler) {
this.replaceableTag = replaceable;
this.replace = replace;
this.sampler = sampler;
}
@Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
if(viewPoint.getBiome(0, 0).getTags().contains(replaceableTag)) {
TerraBiome biome = replace.get(sampler, x, z, seed);
return biome == null ? viewPoint.getBiome(0, 0) : biome;
}
return viewPoint.getBiome(0, 0);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.mutator;
import java.util.Objects;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class SmoothMutator implements BiomeMutator {
private final NoiseSampler sampler;
public SmoothMutator(NoiseSampler sampler) {
this.sampler = sampler;
}
@Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
TerraBiome top = viewPoint.getBiome(1, 0);
TerraBiome bottom = viewPoint.getBiome(-1, 0);
TerraBiome left = viewPoint.getBiome(0, 1);
TerraBiome right = viewPoint.getBiome(0, -1);
boolean vert = Objects.equals(top, bottom) && top != null;
boolean horiz = Objects.equals(left, right) && left != null;
if(vert && horiz) {
return MathUtil.normalizeIndex(sampler.getNoiseSeeded(seed, x, z), 2) == 0 ? left : top;
}
if(vert) return top;
if(horiz) return left;
return viewPoint.getBiome(0, 0);
}
}

View File

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.source;
import com.dfsek.terra.api.world.biome.TerraBiome;
public interface BiomeSource {
TerraBiome getBiome(double x, double z, long seed);
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.source;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class NoiseSource implements BiomeSource {
private final ProbabilityCollection<TerraBiome> biomes;
private final NoiseSampler sampler;
public NoiseSource(ProbabilityCollection<TerraBiome> biomes, NoiseSampler sampler) {
this.biomes = biomes;
this.sampler = sampler;
}
@Override
public TerraBiome getBiome(double x, double z, long seed) {
return biomes.get(sampler, x, z, seed);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.stages;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeExpander;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
public class ExpanderStage implements Stage {
private final BiomeExpander expander;
public ExpanderStage(BiomeExpander expander) {
this.expander = expander;
}
@Override
public BiomeHolder apply(BiomeHolder in, long seed) {
return in.expand(expander, seed);
}
@Override
public boolean isExpansion() {
return true;
}
public enum Type {
FRACTAL
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2020-2021 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.stages;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
public class MutatorStage implements Stage {
private final BiomeMutator mutator;
public MutatorStage(BiomeMutator mutator) {
this.mutator = mutator;
}
@Override
public BiomeHolder apply(BiomeHolder in, long seed) {
in.mutate(mutator, seed);
return in;
}
@Override
public boolean isExpansion() {
return false;
}
public enum Type {
REPLACE,
REPLACE_LIST,
BORDER,
BORDER_LIST,
SMOOTH
}
}

View File

@@ -0,0 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
id: biome-provider-pipeline
version: 0.1.0
entrypoints:
- "com.dfsek.terra.addons.biome.pipeline.BiomePipelineAddon"
website:
issues: https://github.com/PolyhedralDev/Terra-biome-provider-pipeline/issues
source: https://github.com/PolyhedralDev/Terra-biome-provider-pipeline
docs: https://github.com/PolyhedralDev/Terra/wiki
license: GNU LGPL v3.0