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

View File

@@ -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();
}

View File

@@ -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<Biome> getVanillaBiomes();
/**
* Gets the BiomeTerrain instance used to generate the biome.

View File

@@ -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<Biome> 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<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.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<Biome> getVanillaBiomes() {
return vanilla;
}

View File

@@ -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() {

View File

@@ -25,6 +25,7 @@ public class BiomeFactory implements TerraFactory<BiomeTemplate, UserDefinedBiom
generatorBuilder.setInterpolateElevation(template.interpolateElevation());
generatorBuilder.setNoise2d(template.isNoise2d());
generatorBuilder.setBase(template.getNoise2dBase());
generatorBuilder.setBiomeNoise(template.getBiomeNoise());
return new UserDefinedBiome(template.getVanilla(), generatorBuilder, template, pack);

View File

@@ -4,18 +4,20 @@ import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
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.Type;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
@SuppressWarnings("unchecked")
public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollection<Object>> {
@Override
public ProbabilityCollection<Object> load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
ProbabilityCollection<Object> collection = new ProbabilityCollection<>();
if(type instanceof ParameterizedType) {
@@ -33,10 +35,57 @@ public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollec
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);
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);
}
}
}

View File

@@ -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<Biome> 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<Biome> getVanilla() {
return vanilla;
}

View File

@@ -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));
}
}
}

View File

@@ -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<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.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<BlockData> getSlantPalette(int y) {
return slantPalettes.getPalette(y);
}