implement multiple vanilla biomes per custom biome

This commit is contained in:
dfsek
2021-01-14 20:28:52 -07:00
parent c1fdfa94f1
commit d327909389
11 changed files with 103 additions and 17 deletions
@@ -1,5 +1,6 @@
package com.dfsek.terra.api.world.biome; 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.platform.block.BlockData;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
@@ -24,4 +25,6 @@ public interface Generator {
boolean is2d(); boolean is2d();
double get2dBase(); double get2dBase();
NoiseSampler getBiomeNoise();
} }
@@ -1,6 +1,7 @@
package com.dfsek.terra.api.world.biome; 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.Biome;
import com.dfsek.terra.api.platform.world.World; import com.dfsek.terra.api.platform.world.World;
@@ -17,7 +18,7 @@ public interface TerraBiome {
* *
* @return TerraBiome - The Vanilla biome. * @return TerraBiome - The Vanilla biome.
*/ */
Biome getVanillaBiome(); ProbabilityCollection<Biome> getVanillaBiomes();
/** /**
* Gets the BiomeTerrain instance used to generate the biome. * Gets the BiomeTerrain instance used to generate the biome.
@@ -1,5 +1,7 @@
package com.dfsek.terra.biome; 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.platform.world.World;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.Generator;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
@@ -15,7 +17,7 @@ import java.util.Set;
*/ */
public class UserDefinedBiome implements TerraBiome { public class UserDefinedBiome implements TerraBiome {
private final GeneratorBuilder gen; private final GeneratorBuilder gen;
private final com.dfsek.terra.api.platform.world.Biome vanilla; private final ProbabilityCollection<Biome> vanilla;
private final String id; private final String id;
private final BiomeTemplate config; private final BiomeTemplate config;
private final ConfigPack pack; private final ConfigPack pack;
@@ -24,7 +26,7 @@ public class UserDefinedBiome implements TerraBiome {
private final Set<String> tags; private final Set<String> tags;
public UserDefinedBiome(com.dfsek.terra.api.platform.world.Biome vanilla, GeneratorBuilder gen, BiomeTemplate config, ConfigPack pack) { public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, GeneratorBuilder gen, BiomeTemplate config, ConfigPack pack) {
this.vanilla = vanilla; this.vanilla = vanilla;
this.gen = gen; this.gen = gen;
this.id = config.getID(); this.id = config.getID();
@@ -41,7 +43,7 @@ public class UserDefinedBiome implements TerraBiome {
* @return TerraBiome - The Vanilla biome. * @return TerraBiome - The Vanilla biome.
*/ */
@Override @Override
public com.dfsek.terra.api.platform.world.Biome getVanillaBiome() { public ProbabilityCollection<Biome> getVanillaBiomes() {
return vanilla; return vanilla;
} }
@@ -31,9 +31,15 @@ public class GeneratorBuilder {
private double base; private double base;
private NoiseBuilder biomeNoise;
public WorldGenerator build(long seed) { 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() { public boolean isNoise2d() {
@@ -25,6 +25,7 @@ public class BiomeFactory implements TerraFactory<BiomeTemplate, UserDefinedBiom
generatorBuilder.setInterpolateElevation(template.interpolateElevation()); generatorBuilder.setInterpolateElevation(template.interpolateElevation());
generatorBuilder.setNoise2d(template.isNoise2d()); generatorBuilder.setNoise2d(template.isNoise2d());
generatorBuilder.setBase(template.getNoise2dBase()); generatorBuilder.setBase(template.getNoise2dBase());
generatorBuilder.setBiomeNoise(template.getBiomeNoise());
return new UserDefinedBiome(template.getVanilla(), generatorBuilder, template, pack); return new UserDefinedBiome(template.getVanilla(), generatorBuilder, template, pack);
@@ -4,18 +4,20 @@ import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader; import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random;
import java.util.Set;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollection<Object>> { public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollection<Object>> {
@Override @Override
public ProbabilityCollection<Object> load(Type type, Object o, ConfigLoader configLoader) throws LoadException { public ProbabilityCollection<Object> load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
ProbabilityCollection<Object> collection = new ProbabilityCollection<>(); ProbabilityCollection<Object> collection = new ProbabilityCollection<>();
if(type instanceof ParameterizedType) { if(type instanceof ParameterizedType) {
@@ -33,10 +35,57 @@ public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollec
collection.add(configLoader.loadType(generic, entry.getKey()), entry.getValue()); collection.add(configLoader.loadType(generic, entry.getKey()), entry.getValue());
} }
} }
} else throw new LoadException("Malformed Probability Collection: " + o); } else if(o instanceof String) {
return new Singleton<>(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); } else throw new LoadException("Unable to load config! Could not retrieve parameterized type: " + type);
return collection; return collection;
} }
private static final class Singleton<T> extends ProbabilityCollection<T> {
private final T single;
private Singleton(T single) {
this.single = single;
}
@Override
public ProbabilityCollection<T> 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<T> getContents() {
return Collections.singleton(single);
}
}
} }
@@ -5,6 +5,8 @@ import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ValidatedConfigTemplate; import com.dfsek.tectonic.config.ValidatedConfigTemplate;
import com.dfsek.tectonic.exception.ValidationException; 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.math.parsii.BlankFunction;
import com.dfsek.terra.api.platform.TerraPlugin; import com.dfsek.terra.api.platform.TerraPlugin;
import com.dfsek.terra.api.platform.block.BlockData; 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.biome.palette.SinglePalette;
import com.dfsek.terra.carving.UserDefinedCarver; import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.base.ConfigPack; 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.TerraStructure;
import com.dfsek.terra.population.items.flora.FloraLayer; import com.dfsek.terra.population.items.flora.FloraLayer;
import com.dfsek.terra.population.items.ores.OreHolder; import com.dfsek.terra.population.items.ores.OreHolder;
@@ -60,7 +63,13 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
private PaletteHolder slantPalette = null; private PaletteHolder slantPalette = null;
@Value("vanilla") @Value("vanilla")
@Abstractable @Abstractable
private Biome vanilla; private ProbabilityCollection<Biome> vanilla;
@Value("biome-noise")
@Default
@Abstractable
private NoiseBuilder biomeNoise = new NoiseBuilder();
@Value("erode") @Value("erode")
@Abstractable @Abstractable
@Default @Default
@@ -185,9 +194,14 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
public BiomeTemplate(ConfigPack pack, TerraPlugin main) { public BiomeTemplate(ConfigPack pack, TerraPlugin main) {
this.pack = pack; this.pack = pack;
biomeNoise.setType(FastNoiseLite.NoiseType.WhiteNoise);
oceanPalette = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:water")); oceanPalette = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:water"));
} }
public NoiseBuilder getBiomeNoise() {
return biomeNoise;
}
public String getElevationEquation() { public String getElevationEquation() {
return elevationEquation; return elevationEquation;
} }
@@ -220,7 +234,7 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
return slantPalette; return slantPalette;
} }
public Biome getVanilla() { public ProbabilityCollection<Biome> getVanilla() {
return vanilla; return vanilla;
} }
@@ -218,7 +218,7 @@ public class MasterChunkGenerator implements TerraChunkGenerator {
int cz = zOrig + (z << 2); int cz = zOrig + (z << 2);
TerraBiome b = grid.getBiome(cx, cz); 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));
} }
} }
} }
@@ -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.NoiseFunction2;
import com.dfsek.terra.api.math.noise.NoiseFunction3; 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.math.parsii.RandomFunction;
import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.Generator;
@@ -31,14 +32,16 @@ public class WorldGenerator implements Generator {
private final boolean elevationInterpolation; private final boolean elevationInterpolation;
private final boolean noise2d; private final boolean noise2d;
private final double base; private final double base;
private final NoiseSampler biomeNoise;
public WorldGenerator(long seed, String equation, String elevateEquation, Scope vScope, Map<String, NoiseBuilder> noiseBuilders, PaletteHolder palettes, PaletteHolder slantPalettes, boolean elevationInterpolation, boolean noise2d, double base) { public WorldGenerator(long seed, String equation, String elevateEquation, Scope vScope, Map<String, NoiseBuilder> noiseBuilders, PaletteHolder palettes, PaletteHolder slantPalettes, boolean elevationInterpolation, boolean noise2d, double base, NoiseSampler biomeNoise) {
this.palettes = palettes; this.palettes = palettes;
this.slantPalettes = slantPalettes; this.slantPalettes = slantPalettes;
this.elevationInterpolation = elevationInterpolation; this.elevationInterpolation = elevationInterpolation;
this.noise2d = noise2d; this.noise2d = noise2d;
this.base = base; this.base = base;
this.biomeNoise = biomeNoise;
Parser p = new Parser(); Parser p = new Parser();
p.registerFunction("rand", new RandomFunction()); p.registerFunction("rand", new RandomFunction());
@@ -117,6 +120,11 @@ public class WorldGenerator implements Generator {
return base; return base;
} }
@Override
public NoiseSampler getBiomeNoise() {
return biomeNoise;
}
public Palette<BlockData> getSlantPalette(int y) { public Palette<BlockData> getSlantPalette(int y) {
return slantPalettes.getPalette(y); return slantPalettes.getPalette(y);
} }
+6 -4
View File
@@ -3,6 +3,7 @@ package biome;
import com.dfsek.terra.api.math.ProbabilityCollection; import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite; import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
import com.dfsek.terra.api.math.noise.samplers.NoiseSampler; 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.platform.world.World;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.Generator;
import com.dfsek.terra.api.world.biome.TerraBiome; 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.BLUE, "OCEAN"), 10);
oceanBiomes.add(new TestBiome(Color.CYAN, "OCEAN"), 1); 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.ORANGE, "LAND"), 5);
landBiomes.add(new TestBiome(Color.RED, "LAND"), 1); landBiomes.add(new TestBiome(Color.RED, "LAND"), 1);
landBiomes.add(new TestBiome(Color.GRAY, "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) 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 MutatorStage(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(243))))
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(2)))) .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 ExpanderStage(new FractalExpander(whiteNoise(2))))
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(3)))) .addStage(new MutatorStage(new SmoothMutator(whiteNoise(3))))
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4)))) .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)))) .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 @Override
public com.dfsek.terra.api.platform.world.Biome getVanillaBiome() { public ProbabilityCollection<Biome> getVanillaBiomes() {
return null; return null;
} }
@@ -38,7 +38,7 @@ public class BiomeInfoCommand extends WorldCommand {
return true; return true;
} }
sender.sendMessage("TerraBiome info for \"" + b.getID() + "\"."); 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()); sender.sendMessage("Eroded by: " + b.getErode().getConfig().getID());