From d327909389c7efaf56164351992209734796a649 Mon Sep 17 00:00:00 2001 From: dfsek Date: Thu, 14 Jan 2021 20:28:52 -0700 Subject: [PATCH] implement multiple vanilla biomes per custom biome --- .../terra/api/world/biome/Generator.java | 3 + .../terra/api/world/biome/TerraBiome.java | 3 +- .../dfsek/terra/biome/UserDefinedBiome.java | 8 ++- .../config/builder/GeneratorBuilder.java | 8 ++- .../terra/config/factories/BiomeFactory.java | 1 + .../loaders/ProbabilityCollectionLoader.java | 55 ++++++++++++++++++- .../terra/config/templates/BiomeTemplate.java | 18 +++++- .../generation/MasterChunkGenerator.java | 2 +- .../generation/config/WorldGenerator.java | 10 +++- common/src/test/java/biome/BiomeTest.java | 10 ++-- .../command/biome/BiomeInfoCommand.java | 2 +- 11 files changed, 103 insertions(+), 17 deletions(-) diff --git a/common/src/main/java/com/dfsek/terra/api/world/biome/Generator.java b/common/src/main/java/com/dfsek/terra/api/world/biome/Generator.java index 794838860..908bf01f0 100644 --- a/common/src/main/java/com/dfsek/terra/api/world/biome/Generator.java +++ b/common/src/main/java/com/dfsek/terra/api/world/biome/Generator.java @@ -1,5 +1,6 @@ package com.dfsek.terra.api.world.biome; +import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.world.palette.Palette; @@ -24,4 +25,6 @@ public interface Generator { boolean is2d(); double get2dBase(); + + NoiseSampler getBiomeNoise(); } diff --git a/common/src/main/java/com/dfsek/terra/api/world/biome/TerraBiome.java b/common/src/main/java/com/dfsek/terra/api/world/biome/TerraBiome.java index 1b7bad68a..82cb27815 100644 --- a/common/src/main/java/com/dfsek/terra/api/world/biome/TerraBiome.java +++ b/common/src/main/java/com/dfsek/terra/api/world/biome/TerraBiome.java @@ -1,6 +1,7 @@ package com.dfsek.terra.api.world.biome; +import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.platform.world.Biome; import com.dfsek.terra.api.platform.world.World; @@ -17,7 +18,7 @@ public interface TerraBiome { * * @return TerraBiome - The Vanilla biome. */ - Biome getVanillaBiome(); + ProbabilityCollection getVanillaBiomes(); /** * Gets the BiomeTerrain instance used to generate the biome. diff --git a/common/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java b/common/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java index 0caa9a9ed..c0f57197b 100644 --- a/common/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java +++ b/common/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java @@ -1,5 +1,7 @@ package com.dfsek.terra.biome; +import com.dfsek.terra.api.math.ProbabilityCollection; +import com.dfsek.terra.api.platform.world.Biome; import com.dfsek.terra.api.platform.world.World; import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.TerraBiome; @@ -15,7 +17,7 @@ import java.util.Set; */ public class UserDefinedBiome implements TerraBiome { private final GeneratorBuilder gen; - private final com.dfsek.terra.api.platform.world.Biome vanilla; + private final ProbabilityCollection vanilla; private final String id; private final BiomeTemplate config; private final ConfigPack pack; @@ -24,7 +26,7 @@ public class UserDefinedBiome implements TerraBiome { private final Set tags; - public UserDefinedBiome(com.dfsek.terra.api.platform.world.Biome vanilla, GeneratorBuilder gen, BiomeTemplate config, ConfigPack pack) { + public UserDefinedBiome(ProbabilityCollection vanilla, GeneratorBuilder gen, BiomeTemplate config, ConfigPack pack) { this.vanilla = vanilla; this.gen = gen; this.id = config.getID(); @@ -41,7 +43,7 @@ public class UserDefinedBiome implements TerraBiome { * @return TerraBiome - The Vanilla biome. */ @Override - public com.dfsek.terra.api.platform.world.Biome getVanillaBiome() { + public ProbabilityCollection getVanillaBiomes() { return vanilla; } diff --git a/common/src/main/java/com/dfsek/terra/config/builder/GeneratorBuilder.java b/common/src/main/java/com/dfsek/terra/config/builder/GeneratorBuilder.java index 1767ce2f6..c3244bf4d 100644 --- a/common/src/main/java/com/dfsek/terra/config/builder/GeneratorBuilder.java +++ b/common/src/main/java/com/dfsek/terra/config/builder/GeneratorBuilder.java @@ -31,9 +31,15 @@ public class GeneratorBuilder { private double base; + private NoiseBuilder biomeNoise; + public WorldGenerator build(long seed) { - return gens.computeIfAbsent(seed, k -> new WorldGenerator(seed, noiseEquation, elevationEquation, varScope, noiseBuilderMap, palettes, slantPalettes, interpolateElevation, noise2d, base)); + return gens.computeIfAbsent(seed, k -> new WorldGenerator(seed, noiseEquation, elevationEquation, varScope, noiseBuilderMap, palettes, slantPalettes, interpolateElevation, noise2d, base, biomeNoise.build((int) seed))); + } + + public void setBiomeNoise(NoiseBuilder biomeNoise) { + this.biomeNoise = biomeNoise; } public boolean isNoise2d() { diff --git a/common/src/main/java/com/dfsek/terra/config/factories/BiomeFactory.java b/common/src/main/java/com/dfsek/terra/config/factories/BiomeFactory.java index b4d158c9b..69fc23c35 100644 --- a/common/src/main/java/com/dfsek/terra/config/factories/BiomeFactory.java +++ b/common/src/main/java/com/dfsek/terra/config/factories/BiomeFactory.java @@ -25,6 +25,7 @@ public class BiomeFactory implements TerraFactory> { @Override public ProbabilityCollection load(Type type, Object o, ConfigLoader configLoader) throws LoadException { - - ProbabilityCollection collection = new ProbabilityCollection<>(); if(type instanceof ParameterizedType) { @@ -33,10 +35,57 @@ public class ProbabilityCollectionLoader implements TypeLoader(configLoader.loadType(generic, o)); + } else { + throw new LoadException("Malformed Probability Collection: " + o); + } } else throw new LoadException("Unable to load config! Could not retrieve parameterized type: " + type); return collection; } + + private static final class Singleton extends ProbabilityCollection { + private final T single; + + private Singleton(T single) { + this.single = single; + } + + @Override + public ProbabilityCollection add(T item, int probability) { + throw new UnsupportedOperationException(); + } + + @Override + public T get(Random r) { + return single; + } + + @Override + public T get(NoiseSampler n, double x, double y, double z) { + return single; + } + + @Override + public T get(NoiseSampler n, double x, double z) { + return single; + } + + @Override + public int getTotalProbability() { + return 1; + } + + @Override + public int size() { + return 1; + } + + @Override + public Set getContents() { + return Collections.singleton(single); + } + } } diff --git a/common/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java b/common/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java index 0c27a758a..28fcf40b3 100644 --- a/common/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java +++ b/common/src/main/java/com/dfsek/terra/config/templates/BiomeTemplate.java @@ -5,6 +5,8 @@ import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.config.ValidatedConfigTemplate; import com.dfsek.tectonic.exception.ValidationException; +import com.dfsek.terra.api.math.ProbabilityCollection; +import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite; import com.dfsek.terra.api.math.parsii.BlankFunction; import com.dfsek.terra.api.platform.TerraPlugin; import com.dfsek.terra.api.platform.block.BlockData; @@ -16,6 +18,7 @@ import com.dfsek.terra.biome.palette.PaletteHolder; import com.dfsek.terra.biome.palette.SinglePalette; import com.dfsek.terra.carving.UserDefinedCarver; import com.dfsek.terra.config.base.ConfigPack; +import com.dfsek.terra.generation.config.NoiseBuilder; import com.dfsek.terra.population.items.TerraStructure; import com.dfsek.terra.population.items.flora.FloraLayer; import com.dfsek.terra.population.items.ores.OreHolder; @@ -60,7 +63,13 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf private PaletteHolder slantPalette = null; @Value("vanilla") @Abstractable - private Biome vanilla; + private ProbabilityCollection vanilla; + + @Value("biome-noise") + @Default + @Abstractable + private NoiseBuilder biomeNoise = new NoiseBuilder(); + @Value("erode") @Abstractable @Default @@ -185,9 +194,14 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf public BiomeTemplate(ConfigPack pack, TerraPlugin main) { this.pack = pack; + biomeNoise.setType(FastNoiseLite.NoiseType.WhiteNoise); oceanPalette = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:water")); } + public NoiseBuilder getBiomeNoise() { + return biomeNoise; + } + public String getElevationEquation() { return elevationEquation; } @@ -220,7 +234,7 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf return slantPalette; } - public Biome getVanilla() { + public ProbabilityCollection getVanilla() { return vanilla; } diff --git a/common/src/main/java/com/dfsek/terra/generation/MasterChunkGenerator.java b/common/src/main/java/com/dfsek/terra/generation/MasterChunkGenerator.java index e5578da21..5863cf8d3 100644 --- a/common/src/main/java/com/dfsek/terra/generation/MasterChunkGenerator.java +++ b/common/src/main/java/com/dfsek/terra/generation/MasterChunkGenerator.java @@ -218,7 +218,7 @@ public class MasterChunkGenerator implements TerraChunkGenerator { int cz = zOrig + (z << 2); TerraBiome b = grid.getBiome(cx, cz); - biome.setBiome(x << 2, z << 2, b.getVanillaBiome()); + biome.setBiome(x << 2, z << 2, b.getVanillaBiomes().get(b.getGenerator(world).getBiomeNoise(), cx, 0, cz)); } } } diff --git a/common/src/main/java/com/dfsek/terra/generation/config/WorldGenerator.java b/common/src/main/java/com/dfsek/terra/generation/config/WorldGenerator.java index f3faef1e3..232afcfc6 100644 --- a/common/src/main/java/com/dfsek/terra/generation/config/WorldGenerator.java +++ b/common/src/main/java/com/dfsek/terra/generation/config/WorldGenerator.java @@ -2,6 +2,7 @@ package com.dfsek.terra.generation.config; import com.dfsek.terra.api.math.noise.NoiseFunction2; import com.dfsek.terra.api.math.noise.NoiseFunction3; +import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; import com.dfsek.terra.api.math.parsii.RandomFunction; import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.world.biome.Generator; @@ -31,14 +32,16 @@ public class WorldGenerator implements Generator { private final boolean elevationInterpolation; private final boolean noise2d; private final double base; + private final NoiseSampler biomeNoise; - public WorldGenerator(long seed, String equation, String elevateEquation, Scope vScope, Map noiseBuilders, PaletteHolder palettes, PaletteHolder slantPalettes, boolean elevationInterpolation, boolean noise2d, double base) { + public WorldGenerator(long seed, String equation, String elevateEquation, Scope vScope, Map noiseBuilders, PaletteHolder palettes, PaletteHolder slantPalettes, boolean elevationInterpolation, boolean noise2d, double base, NoiseSampler biomeNoise) { this.palettes = palettes; this.slantPalettes = slantPalettes; this.elevationInterpolation = elevationInterpolation; this.noise2d = noise2d; this.base = base; + this.biomeNoise = biomeNoise; Parser p = new Parser(); p.registerFunction("rand", new RandomFunction()); @@ -117,6 +120,11 @@ public class WorldGenerator implements Generator { return base; } + @Override + public NoiseSampler getBiomeNoise() { + return biomeNoise; + } + public Palette getSlantPalette(int y) { return slantPalettes.getPalette(y); } diff --git a/common/src/test/java/biome/BiomeTest.java b/common/src/test/java/biome/BiomeTest.java index fbb3066ab..83f760bd9 100644 --- a/common/src/test/java/biome/BiomeTest.java +++ b/common/src/test/java/biome/BiomeTest.java @@ -3,6 +3,7 @@ package biome; import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite; import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; +import com.dfsek.terra.api.platform.world.Biome; import com.dfsek.terra.api.platform.world.World; import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.TerraBiome; @@ -50,7 +51,7 @@ public class BiomeTest { oceanBiomes.add(new TestBiome(Color.BLUE, "OCEAN"), 10); oceanBiomes.add(new TestBiome(Color.CYAN, "OCEAN"), 1); - landBiomes.add(new TestBiome(Color.GREEN, "LAND"), 20); + landBiomes.add(new TestBiome(Color.GREEN, "LAND"), 8); landBiomes.add(new TestBiome(Color.ORANGE, "LAND"), 5); landBiomes.add(new TestBiome(Color.RED, "LAND"), 1); landBiomes.add(new TestBiome(Color.GRAY, "LAND"), 1); @@ -62,13 +63,14 @@ public class BiomeTest { BiomeProvider provider = new StandardBiomeProvider.StandardBiomeProviderBuilder((seed) -> new BiomePipeline.BiomePipelineBuilder(2) - .addStage(new ExpanderStage(new FractalExpander(whiteNoise(1)))) - .addStage(new MutatorStage(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(243)))) .addStage(new MutatorStage(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(243)))) .addStage(new ExpanderStage(new FractalExpander(whiteNoise(2)))) + .addStage(new MutatorStage(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(243)))) + .addStage(new ExpanderStage(new FractalExpander(whiteNoise(2)))) .addStage(new ExpanderStage(new FractalExpander(whiteNoise(2)))) .addStage(new MutatorStage(new SmoothMutator(whiteNoise(3)))) .addStage(new ExpanderStage(new FractalExpander(whiteNoise(4)))) + .addStage(new MutatorStage(new SmoothMutator(whiteNoise(6)))) .addStage(new ExpanderStage(new FractalExpander(whiteNoise(4)))) .addStage(new ExpanderStage(new FractalExpander(whiteNoise(4)))) .addStage(new ExpanderStage(new FractalExpander(whiteNoise(4)))) @@ -131,7 +133,7 @@ public class BiomeTest { } @Override - public com.dfsek.terra.api.platform.world.Biome getVanillaBiome() { + public ProbabilityCollection getVanillaBiomes() { return null; } diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/command/biome/BiomeInfoCommand.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/command/biome/BiomeInfoCommand.java index 588f04912..7ac34d132 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/command/biome/BiomeInfoCommand.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/command/biome/BiomeInfoCommand.java @@ -38,7 +38,7 @@ public class BiomeInfoCommand extends WorldCommand { return true; } sender.sendMessage("TerraBiome info for \"" + b.getID() + "\"."); - sender.sendMessage("Vanilla biome: " + b.getVanillaBiome()); + sender.sendMessage("Vanilla biome: " + b.getVanillaBiomes()); sender.sendMessage("Eroded by: " + b.getErode().getConfig().getID());