use fancy new tectonic stuff for biome stage loading

This commit is contained in:
dfsek 2021-01-30 15:23:29 -07:00
parent b99fabcf1d
commit 762c3064d9
17 changed files with 222 additions and 112 deletions

View File

@ -19,4 +19,8 @@ public class ExpanderStage implements Stage {
public BiomeHolder apply(BiomeHolder in) {
return in.expand(expander);
}
public enum Type {
FRACTAL
}
}

View File

@ -20,4 +20,8 @@ public class MutatorStage implements Stage {
in.mutate(mutator);
return in;
}
public enum Type {
REPLACE, REPLACE_LIST, BORDER, BORDER_LIST, SMOOTH
}
}

View File

@ -12,6 +12,8 @@ import com.dfsek.terra.api.math.noise.samplers.ImageSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder;
import com.dfsek.terra.biome.pipeline.stages.ExpanderStage;
import com.dfsek.terra.biome.pipeline.stages.MutatorStage;
import com.dfsek.terra.config.loaders.MaterialSetLoader;
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.RangeLoader;
@ -20,6 +22,12 @@ import com.dfsek.terra.config.loaders.config.GridSpawnLoader;
import com.dfsek.terra.config.loaders.config.OreConfigLoader;
import com.dfsek.terra.config.loaders.config.OreHolderLoader;
import com.dfsek.terra.config.loaders.config.TreeLayerLoader;
import com.dfsek.terra.config.loaders.config.biome.templates.ExpanderStageTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.BorderListMutatorTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.BorderMutatorTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.ReplaceListMutatorTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.ReplaceMutatorTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.SmoothMutatorTemplate;
import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
import com.dfsek.terra.config.loaders.config.sampler.templates.DomainWarpTemplate;
import com.dfsek.terra.config.loaders.config.sampler.templates.FastNoiseTemplate;
@ -63,7 +71,15 @@ public class GenericLoaders implements LoaderRegistrar {
.registerLoader(NormalNormalizerTemplate.class, NormalNormalizerTemplate::new)
.registerLoader(FastNoiseTemplate.class, FastNoiseTemplate::new)
.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader())
.registerLoader(ReplaceMutatorTemplate.class, ReplaceMutatorTemplate::new)
.registerLoader(ExpanderStageTemplate.class, ExpanderStageTemplate::new)
.registerLoader(SmoothMutatorTemplate.class, SmoothMutatorTemplate::new)
.registerLoader(ReplaceListMutatorTemplate.class, ReplaceListMutatorTemplate::new)
.registerLoader(BorderMutatorTemplate.class, BorderMutatorTemplate::new)
.registerLoader(BorderListMutatorTemplate.class, BorderListMutatorTemplate::new)
.registerLoader(ImageSampler.Channel.class, (t, object, cf) -> ImageSampler.Channel.valueOf((String) object))
.registerLoader(ExpanderStage.Type.class, (t, object, cf) -> ExpanderStage.Type.valueOf((String) object))
.registerLoader(MutatorStage.Type.class, (t, object, cf) -> MutatorStage.Type.valueOf((String) object))
.registerLoader(FastNoiseLite.NoiseType.class, (t, object, cf) -> FastNoiseLite.NoiseType.valueOf((String) object))
.registerLoader(FastNoiseLite.FractalType.class, (t, object, cf) -> FastNoiseLite.FractalType.valueOf((String) object))
.registerLoader(FastNoiseLite.DomainWarpType.class, (t, object, cf) -> FastNoiseLite.DomainWarpType.valueOf((String) object))

View File

@ -1,52 +0,0 @@
package com.dfsek.terra.config.loaders;
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 java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
@SuppressWarnings("unchecked")
public class SelfProbabilityCollectionLoader<T> implements TypeLoader<ProbabilityCollection<T>> {
@Override
public ProbabilityCollection<T> load(Type type, Object o, ConfigLoader loader) throws LoadException {
ProbabilityCollection<T> collection = new ProbabilityCollection<>();
if(type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) type;
Type generic = pType.getActualTypeArguments()[0];
if(o instanceof Map) {
Map<Object, Integer> map = (Map<Object, Integer>) o;
addItems(loader, collection, generic, map);
} else if(o instanceof List) {
List<Map<Object, Integer>> map = (List<Map<Object, Integer>>) o;
for(Map<Object, Integer> l : map) {
addItems(loader, collection, generic, l);
}
} else if(o instanceof String) {
return new ProbabilityCollection.Singleton<>((T) loader.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 void addItems(ConfigLoader loader, ProbabilityCollection<T> collection, Type generic, Map<Object, Integer> l) throws LoadException {
for(Map.Entry<Object, Integer> entry : l.entrySet()) {
if(entry.getValue() == null) throw new LoadException("No probability defined for entry \"" + entry.getKey() + "\"");
if(entry.getKey().toString().equals("SELF")) {
collection.add(null, entry.getValue()); // hmm maybe replace this with something better later
continue;
}
collection.add((T) loader.loadType(generic, entry.getKey()), entry.getValue());
}
}
}

View File

@ -3,24 +3,18 @@ package com.dfsek.terra.config.loaders.config.biome;
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.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.util.seeded.SeededBuilder;
import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.expand.FractalExpander;
import com.dfsek.terra.biome.pipeline.mutator.BorderListMutator;
import com.dfsek.terra.biome.pipeline.mutator.BorderMutator;
import com.dfsek.terra.biome.pipeline.mutator.ReplaceListMutator;
import com.dfsek.terra.biome.pipeline.mutator.ReplaceMutator;
import com.dfsek.terra.biome.pipeline.mutator.SmoothMutator;
import com.dfsek.terra.biome.pipeline.stages.ExpanderStage;
import com.dfsek.terra.biome.pipeline.stages.MutatorStage;
import com.dfsek.terra.biome.pipeline.stages.Stage;
import com.dfsek.terra.config.loaders.SelfProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.Types;
import com.dfsek.terra.config.loaders.config.biome.templates.ExpanderStageTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.BorderListMutatorTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.BorderMutatorTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.ReplaceListMutatorTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.ReplaceMutatorTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.mutator.SmoothMutatorTemplate;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("unchecked")
@ -30,54 +24,24 @@ public class StageBuilderLoader implements TypeLoader<SeededBuilder<Stage>> {
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) c;
Map<String, Object> mutator = (Map<String, Object>) entry.getValue();
NoiseSeeded mutatorNoise = loader.loadClass(NoiseSeeded.class, mutator.get("noise"));
if(entry.getKey().equals("expand")) {
if(mutator.get("type").equals("FRACTAL"))
return seed -> new ExpanderStage(new FractalExpander(mutatorNoise.apply(seed)));
else throw new LoadException("No such expander \"" + mutator.get("type"));
ExpanderStage.Type stageType = loader.loadClass(ExpanderStage.Type.class, mutator.get("type"));
if(stageType.equals(ExpanderStage.Type.FRACTAL)) {
return loader.loadClass(ExpanderStageTemplate.class, mutator).get();
} else throw new LoadException("No such expander \"" + stageType + "\"");
} else if(entry.getKey().equals("mutate")) {
switch(mutator.get("type").toString()) {
case "SMOOTH": {
return seed -> new MutatorStage(new SmoothMutator(mutatorNoise.apply(new Long(seed))));
}
case "REPLACE": {
String fromTag = mutator.get("from").toString();
ProbabilityCollection<TerraBiome> replaceBiomes = new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("to"), loader);
return seed -> new MutatorStage(new ReplaceMutator(fromTag, replaceBiomes, mutatorNoise.apply(seed)));
}
case "REPLACE_LIST": {
String fromTag = mutator.get("default-from").toString();
ProbabilityCollection<TerraBiome> replaceBiomes = new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("default-to"), loader);
Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace = new HashMap<>();
for(Map.Entry<String, Object> e : ((Map<String, Object>) mutator.get("to")).entrySet()) {
replace.put(loader.loadClass(TerraBiome.class, e.getKey()), new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, e.getValue(), loader));
}
return seed -> new MutatorStage(new ReplaceListMutator(replace, fromTag, replaceBiomes, mutatorNoise.apply(seed)));
}
case "BORDER": {
String fromTag = mutator.get("from").toString();
String replaceTag = mutator.get("replace").toString();
ProbabilityCollection<TerraBiome> replaceBiomes = new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("to"), loader);
return seed -> new MutatorStage(new BorderMutator(fromTag, replaceTag, mutatorNoise.apply(seed), replaceBiomes));
}
case "BORDER_LIST": {
String fromTag = mutator.get("from").toString();
String replaceTag = mutator.get("default-replace").toString();
ProbabilityCollection<TerraBiome> replaceBiomes = new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, mutator.get("default-to"), loader);
Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace = new HashMap<>();
for(Map.Entry<String, Object> e : ((Map<String, Object>) mutator.get("replace")).entrySet()) {
replace.put(loader.loadClass(TerraBiome.class, e.getKey()), new SelfProbabilityCollectionLoader<TerraBiome>().load(Types.TERRA_BIOME_PROBABILITY_COLLECTION_TYPE, e.getValue(), loader));
}
return seed -> new MutatorStage(new BorderListMutator(replace, fromTag, replaceTag, mutatorNoise.apply(seed), replaceBiomes));
}
switch(loader.loadClass(MutatorStage.Type.class, mutator.get("type"))) {
case SMOOTH:
return loader.loadClass(SmoothMutatorTemplate.class, mutator).get();
case REPLACE:
return loader.loadClass(ReplaceMutatorTemplate.class, mutator).get();
case REPLACE_LIST:
return loader.loadClass(ReplaceListMutatorTemplate.class, mutator).get();
case BORDER:
return loader.loadClass(BorderMutatorTemplate.class, mutator).get();
case BORDER_LIST:
return loader.loadClass(BorderListMutatorTemplate.class, mutator).get();
default:
throw new LoadException("No such mutator type \"" + mutator.get("type"));

View File

@ -0,0 +1,12 @@
package com.dfsek.terra.config.loaders.config.biome.templates;
import com.dfsek.terra.biome.pipeline.expand.FractalExpander;
import com.dfsek.terra.biome.pipeline.stages.ExpanderStage;
import com.dfsek.terra.biome.pipeline.stages.Stage;
public class ExpanderStageTemplate extends StageTemplate {
@Override
public Stage apply(Long seed) {
return new ExpanderStage(new FractalExpander(noise.apply(seed)));
}
}

View File

@ -0,0 +1,17 @@
package com.dfsek.terra.config.loaders.config.biome.templates;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.util.seeded.SeededBuilder;
import com.dfsek.terra.biome.pipeline.stages.Stage;
public abstract class StageTemplate implements ObjectTemplate<SeededBuilder<Stage>>, SeededBuilder<Stage> {
@Value("noise")
protected NoiseSeeded noise;
@Override
public SeededBuilder<Stage> get() {
return this;
}
}

View File

@ -0,0 +1,29 @@
package com.dfsek.terra.config.loaders.config.biome.templates.mutator;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.mutator.BiomeMutator;
import com.dfsek.terra.biome.pipeline.mutator.BorderListMutator;
import java.util.Map;
public class BorderListMutatorTemplate extends MutatorStageTemplate {
@Value("from")
private String from;
@Value("default-replace")
private String defaultReplace;
@Value("default-to")
private ProbabilityCollection<TerraBiome> defaultTo;
@Value("replace")
private Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
@Override
public BiomeMutator build(long seed) {
return new BorderListMutator(replace, from, defaultReplace, noise.apply(seed), defaultTo);
}
}

View File

@ -0,0 +1,24 @@
package com.dfsek.terra.config.loaders.config.biome.templates.mutator;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.mutator.BiomeMutator;
import com.dfsek.terra.biome.pipeline.mutator.BorderMutator;
@SuppressWarnings("unused")
public class BorderMutatorTemplate extends MutatorStageTemplate {
@Value("from")
private String from;
@Value("replace")
private String replace;
@Value("to")
private ProbabilityCollection<TerraBiome> to;
@Override
public BiomeMutator build(long seed) {
return new BorderMutator(from, replace, noise.apply(seed), to);
}
}

View File

@ -0,0 +1,15 @@
package com.dfsek.terra.config.loaders.config.biome.templates.mutator;
import com.dfsek.terra.biome.pipeline.mutator.BiomeMutator;
import com.dfsek.terra.biome.pipeline.stages.MutatorStage;
import com.dfsek.terra.biome.pipeline.stages.Stage;
import com.dfsek.terra.config.loaders.config.biome.templates.StageTemplate;
public abstract class MutatorStageTemplate extends StageTemplate {
public abstract BiomeMutator build(long seed);
@Override
public Stage apply(Long seed) {
return new MutatorStage(build(seed));
}
}

View File

@ -0,0 +1,26 @@
package com.dfsek.terra.config.loaders.config.biome.templates.mutator;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.mutator.BiomeMutator;
import com.dfsek.terra.biome.pipeline.mutator.ReplaceListMutator;
import java.util.Map;
@SuppressWarnings("unused")
public class ReplaceListMutatorTemplate extends MutatorStageTemplate {
@Value("default-from")
private String defaultFrom;
@Value("default-to")
private ProbabilityCollection<TerraBiome> defaultTo;
@Value("to")
private Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
@Override
public BiomeMutator build(long seed) {
return new ReplaceListMutator(replace, defaultFrom, defaultTo, noise.apply(seed));
}
}

View File

@ -0,0 +1,21 @@
package com.dfsek.terra.config.loaders.config.biome.templates.mutator;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.pipeline.mutator.BiomeMutator;
import com.dfsek.terra.biome.pipeline.mutator.ReplaceMutator;
@SuppressWarnings("unused")
public class ReplaceMutatorTemplate extends MutatorStageTemplate {
@Value("from")
private String from;
@Value("to")
private ProbabilityCollection<TerraBiome> to;
@Override
public BiomeMutator build(long seed) {
return new ReplaceMutator(from, to, noise.apply(seed));
}
}

View File

@ -0,0 +1,11 @@
package com.dfsek.terra.config.loaders.config.biome.templates.mutator;
import com.dfsek.terra.biome.pipeline.mutator.BiomeMutator;
import com.dfsek.terra.biome.pipeline.mutator.SmoothMutator;
public class SmoothMutatorTemplate extends MutatorStageTemplate {
@Override
public BiomeMutator build(long seed) {
return new SmoothMutator(noise.apply(seed));
}
}

View File

@ -8,6 +8,7 @@ import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
@SuppressWarnings("FieldMayBeFinal")
public abstract class SamplerTemplate<T extends NoiseSampler> implements ValidatedConfigTemplate, ObjectTemplate<NoiseSeeded>, NoiseSeeded {
@Value("dimensions")
@Default

View File

@ -1,6 +1,18 @@
package com.dfsek.terra.registry;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.terra.biome.TerraBiome;
import java.lang.reflect.Type;
public class BiomeRegistry extends TerraRegistry<TerraBiome> {
@Override
public TerraBiome load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
if(o.equals("SELF")) return null;
TerraBiome biome = get((String) o);
if(biome == null)
throw new LoadException("No such " + type.getTypeName() + " matching \"" + o + "\" was found in this registry.");
return biome;
}
}

View File

@ -134,7 +134,7 @@ public class DistributionTest {
FolderLoader folderLoader = new FolderLoader(pack.toPath());
AbstractConfigLoader loader = new AbstractConfigLoader();
new GenericLoaders(null).register(loader);
BiomeRegistry biomeRegistry = new BiomeRegistry();
folderLoader.open("biomes", ".yml").then(inputStreams -> ConfigPack.buildAll((template, main) -> template, biomeRegistry, loader.load(inputStreams, TestBiome::new), MAIN));
@ -145,6 +145,7 @@ public class DistributionTest {
.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader())
.registerLoader(TerraBiome.class, biomeRegistry);
new GenericLoaders(null).register(pipeLoader);
pipeLoader.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader());
pipeLoader.load(template, folderLoader.get("pack.yml"));

View File

@ -3,6 +3,7 @@ package com.dfsek.terra.bukkit.generator;
import com.dfsek.terra.api.core.TerraPlugin;
import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper;
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
import com.dfsek.terra.bukkit.population.PopulationManager;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
@ -23,12 +24,12 @@ import org.jetbrains.annotations.NotNull;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements GeneratorWrapper {
@ -40,6 +41,8 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
private final TerraPlugin main;
private final List<TerraBlockPopulator> populators = new LinkedList<>();
private boolean needsLoad = true;
public BukkitChunkGeneratorWrapper(TerraChunkGenerator delegate) {
@ -49,6 +52,8 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
popMan.attach(new OrePopulator(main));
popMan.attach(new TreePopulator(main));
popMan.attach(new FloraPopulator(main));
populators.add(new StructurePopulator(main));
populators.add(popMan);
}
@ -91,7 +96,7 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
@Override
public @NotNull List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
return Stream.of(new StructurePopulator(main), popMan).map(BukkitPopulatorWrapper::new).collect(Collectors.toList());
return populators.stream().map(BukkitPopulatorWrapper::new).collect(Collectors.toList());
}
@Override