mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-13 19:26:14 +00:00
Merge pull request #72 from PolyhedralDev/asmparser
Implement Paralithic expression parser
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import com.dfsek.terra.getGitHash
|
||||
|
||||
val versionObj = Version("4", "0", "1", true)
|
||||
val versionObj = Version("4", "1", "0", true)
|
||||
|
||||
allprojects {
|
||||
version = versionObj
|
||||
|
||||
@@ -13,10 +13,11 @@ dependencies {
|
||||
"shadedApi"("org.apache.commons:commons-rng-core:1.3")
|
||||
"shadedApi"("commons-io:commons-io:2.4")
|
||||
|
||||
"shadedApi"("com.scireum:parsii:1.2.1")
|
||||
"shadedApi"("com.dfsek:Paralithic:0.3.2")
|
||||
"shadedApi"("com.dfsek:Tectonic:1.2.3")
|
||||
"shadedApi"("net.jafama:jafama:2.3.2")
|
||||
"shadedApi"("org.yaml:snakeyaml:1.27")
|
||||
"shadedApi"("org.ow2.asm:asm:9.0")
|
||||
|
||||
"compileOnly"("com.googlecode.json-simple:json-simple:1.1")
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.dfsek.terra.api.math.noise.normalizer;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
public class ClampNormalizer extends Normalizer {
|
||||
private final double min;
|
||||
private final double max;
|
||||
|
||||
public ClampNormalizer(NoiseSampler sampler, double min, double max) {
|
||||
super(sampler);
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double normalize(double in) {
|
||||
return FastMath.max(FastMath.min(in, max), min);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.dfsek.terra.api.math.noise.normalizer;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.parsii.noise.NoiseFunction2;
|
||||
import com.dfsek.terra.api.math.parsii.noise.NoiseFunction3;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ExpressionNormalizer extends Normalizer {
|
||||
private final Expression expression;
|
||||
|
||||
public ExpressionNormalizer(NoiseSampler sampler, String eq, Map<String, Double> vars) throws ParseException {
|
||||
super(sampler);
|
||||
Parser p = new Parser();
|
||||
Scope scope = new Scope();
|
||||
scope.addInvocationVariable("in");
|
||||
|
||||
vars.forEach(scope::create);
|
||||
|
||||
p.registerFunction("super2", new NoiseFunction2(sampler));
|
||||
p.registerFunction("super3", new NoiseFunction3(sampler));
|
||||
expression = p.parse(eq);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double normalize(double in) {
|
||||
return expression.evaluate(in);
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,4 @@ public abstract class Normalizer implements NoiseSampler {
|
||||
public double getNoiseSeeded(int seed, double x, double y, double z) {
|
||||
return normalize(sampler.getNoiseSeeded(seed, x, y, z));
|
||||
}
|
||||
|
||||
public enum NormalType {
|
||||
LINEAR, NORMAL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +1,58 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.parsii.defined.UserDefinedFunction;
|
||||
import com.dfsek.terra.api.math.parsii.noise.NoiseFunction2;
|
||||
import com.dfsek.terra.api.math.parsii.noise.NoiseFunction3;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Parser;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.eval.Variable;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Sampler implementation using parsii expression
|
||||
*/
|
||||
public class ExpressionSampler implements NoiseSampler {
|
||||
private final Expression expression;
|
||||
private final Variable x;
|
||||
private final Variable y;
|
||||
private final Variable z;
|
||||
|
||||
public ExpressionSampler(String equation, Scope parent, long seed, Map<String, NoiseSeeded> functions, Map<String, FunctionTemplate> definedFunctions) throws ParseException {
|
||||
Parser parser = new Parser();
|
||||
Scope scope = new Scope().withParent(parent);
|
||||
|
||||
this.x = scope.create("x");
|
||||
this.y = scope.create("y");
|
||||
this.z = scope.create("z");
|
||||
scope.addInvocationVariable("x");
|
||||
scope.addInvocationVariable("y");
|
||||
scope.addInvocationVariable("z");
|
||||
|
||||
functions.forEach((id, noise) -> {
|
||||
switch(noise.getDimensions()) {
|
||||
case 2:
|
||||
parser.registerFunction(id, new NoiseFunction2(seed, noise));
|
||||
parser.registerFunction(id, new NoiseFunction2(noise.apply(seed)));
|
||||
break;
|
||||
case 3:
|
||||
parser.registerFunction(id, new NoiseFunction3(seed, noise));
|
||||
parser.registerFunction(id, new NoiseFunction3(noise.apply(seed)));
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
for(Map.Entry<String, FunctionTemplate> entry : definedFunctions.entrySet()) {
|
||||
String id = entry.getKey();
|
||||
FunctionTemplate fun = entry.getValue();
|
||||
|
||||
Scope functionScope = new Scope().withParent(parent);
|
||||
List<Variable> variables = fun.getArgs().stream().map(functionScope::create).collect(Collectors.toList());
|
||||
|
||||
parser.registerFunction(id, new UserDefinedFunction(parser.parse(fun.getFunction(), functionScope), variables));
|
||||
parser.registerFunction(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), parser, parent));
|
||||
}
|
||||
|
||||
this.expression = parser.parse(equation, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getNoise(double x, double y) {
|
||||
public double getNoise(double x, double y) {
|
||||
return getNoise(x, 0, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getNoise(double x, double y, double z) {
|
||||
this.x.setValue(x);
|
||||
this.y.setValue(y);
|
||||
this.z.setValue(z);
|
||||
return expression.evaluate();
|
||||
public double getNoise(double x, double y, double z) {
|
||||
return expression.evaluate(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.dfsek.terra.api.math.parsii;
|
||||
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Function;
|
||||
|
||||
import java.util.List;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
|
||||
public class BlankFunction implements Function {
|
||||
public class BlankFunction implements DynamicFunction {
|
||||
private final int args;
|
||||
|
||||
public BlankFunction(int args) {
|
||||
@@ -13,17 +11,17 @@ public class BlankFunction implements Function {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfArguments() {
|
||||
public int getArgNumber() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(List<Expression> list) {
|
||||
public double eval(double... d) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNaturalFunction() {
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,44 @@
|
||||
package com.dfsek.terra.api.math.parsii.defined;
|
||||
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Function;
|
||||
import parsii.eval.Variable;
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserDefinedFunction implements Function {
|
||||
public class UserDefinedFunction implements DynamicFunction {
|
||||
private final Expression expression;
|
||||
private final List<Variable> variables;
|
||||
private final int args;
|
||||
|
||||
public UserDefinedFunction(Expression expression, List<Variable> variables) {
|
||||
protected UserDefinedFunction(Expression expression, int args) {
|
||||
this.expression = expression;
|
||||
this.variables = variables;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double eval(double... args) {
|
||||
return expression.evaluate(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfArguments() {
|
||||
return variables.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double eval(List<Expression> args) {
|
||||
for(int i = 0; i < variables.size(); i++) {
|
||||
variables.get(i).setValue(args.get(i).evaluate());
|
||||
}
|
||||
return expression.evaluate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNaturalFunction() {
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArgNumber() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public static UserDefinedFunction newInstance(FunctionTemplate template, Parser parser, Scope parent) throws ParseException {
|
||||
|
||||
Scope functionScope = new Scope().withParent(parent);
|
||||
|
||||
template.getArgs().forEach(functionScope::addInvocationVariable);
|
||||
|
||||
return new UserDefinedFunction(parser.parse(template.getFunction(), functionScope), template.getArgs().size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.dfsek.terra.api.math.parsii.noise;
|
||||
|
||||
import parsii.eval.Function;
|
||||
|
||||
public interface NoiseFunction extends Function {
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
|
||||
public interface NoiseFunction extends DynamicFunction {
|
||||
}
|
||||
|
||||
@@ -1,42 +1,30 @@
|
||||
package com.dfsek.terra.api.math.parsii.noise;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.util.hash.HashMapDoubleDouble;
|
||||
import parsii.eval.Expression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class NoiseFunction2 implements NoiseFunction {
|
||||
private final NoiseSampler gen;
|
||||
private final Cache cache = new Cache();
|
||||
|
||||
public NoiseFunction2(long seed, NoiseSeeded builder) {
|
||||
this.gen = builder.apply(seed);
|
||||
public NoiseFunction2(NoiseSampler gen) {
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfArguments() {
|
||||
public int getArgNumber() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(List<Expression> list) {
|
||||
return cache.get(gen, list.get(0).evaluate(), list.get(1).evaluate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate without cache. For testing.
|
||||
*
|
||||
* @param list Parameters.
|
||||
* @return Result.
|
||||
*/
|
||||
public double evalNoCache(List<Expression> list) {
|
||||
return gen.getNoise(list.get(0).evaluate(), list.get(1).evaluate());
|
||||
public double eval(double... args) {
|
||||
return cache.get(gen, args[0], args[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNaturalFunction() {
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,6 +32,10 @@ public class NoiseFunction2 implements NoiseFunction {
|
||||
private static final long serialVersionUID = 8915092734723467010L;
|
||||
private static final int cacheSize = 384;
|
||||
|
||||
public Cache() {
|
||||
super(cacheSize);
|
||||
}
|
||||
|
||||
public double get(NoiseSampler noise, double x, double z) {
|
||||
double xx = x >= 0 ? x * 2 : x * -2 - 1;
|
||||
double zz = z >= 0 ? z * 2 : z * -2 - 1;
|
||||
@@ -55,7 +47,7 @@ public class NoiseFunction2 implements NoiseFunction {
|
||||
return (value == 4.9E-324D ? addAndReturn(noise.getNoise(x, z), key) : value);
|
||||
}
|
||||
|
||||
private double addAndReturn(double value, double key) {
|
||||
private synchronized double addAndReturn(double value, double key) {
|
||||
this.put(key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -1,30 +1,26 @@
|
||||
package com.dfsek.terra.api.math.parsii.noise;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import parsii.eval.Expression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NoiseFunction3 implements NoiseFunction {
|
||||
private final NoiseSampler gen;
|
||||
|
||||
public NoiseFunction3(long seed, NoiseSeeded builder) {
|
||||
this.gen = builder.apply(seed);
|
||||
public NoiseFunction3(NoiseSampler gen) {
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfArguments() {
|
||||
public int getArgNumber() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(List<Expression> list) {
|
||||
return gen.getNoise(list.get(0).evaluate(), list.get(1).evaluate(), list.get(2).evaluate());
|
||||
public double eval(double... args) {
|
||||
return gen.getNoise(args[0], args[1], args[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNaturalFunction() {
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.Buffer;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.DirectBuffer;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer;
|
||||
import com.dfsek.terra.registry.LootRegistry;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import com.dfsek.terra.registry.config.LootRegistry;
|
||||
import com.dfsek.terra.registry.config.ScriptRegistry;
|
||||
import com.dfsek.terra.world.generation.math.SamplerCache;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.functions.LootFunction;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.LootRegistry;
|
||||
import com.dfsek.terra.registry.config.LootRegistry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.functions.StructureFunction;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import com.dfsek.terra.registry.config.ScriptRegistry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -12,7 +12,7 @@ import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.LootRegistry;
|
||||
import com.dfsek.terra.registry.config.LootRegistry;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.IntermediateBuffer;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import com.dfsek.terra.registry.config.ScriptRegistry;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.dfsek.terra.api.util.seeded;
|
||||
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
|
||||
public interface SourceSeeded extends SeededBuilder<BiomeSource> {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.dfsek.terra.api.util.seeded;
|
||||
|
||||
import com.dfsek.terra.biome.pipeline.stages.Stage;
|
||||
|
||||
public interface StageSeeded extends SeededBuilder<Stage> {
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.dfsek.terra.biome.pipeline;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.util.GlueList;
|
||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.biome.pipeline.stages.Stage;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class BiomePipeline {
|
||||
|
||||
public static final class BiomePipelineBuilder {
|
||||
private final int init;
|
||||
List<SeededBuilder<Stage>> stages = new GlueList<>();
|
||||
List<StageSeeded> stages = new GlueList<>();
|
||||
private int expand;
|
||||
|
||||
public BiomePipelineBuilder(int init) {
|
||||
@@ -60,7 +60,7 @@ public class BiomePipeline {
|
||||
return new BiomePipeline(source, stagesBuilt, expand, init);
|
||||
}
|
||||
|
||||
public BiomePipelineBuilder addStage(SeededBuilder<Stage> stage) {
|
||||
public BiomePipelineBuilder addStage(StageSeeded stage) {
|
||||
stages.add(stage);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,8 @@ public interface BiomeProvider {
|
||||
interface BiomeProviderBuilder {
|
||||
BiomeProvider build(long seed);
|
||||
}
|
||||
|
||||
enum Type {
|
||||
IMAGE, PIPELINE, SINGLE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,16 @@ import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ImageBiomeProvider implements BiomeProvider {
|
||||
public class ImageBiomeProvider implements BiomeProvider, BiomeProvider.BiomeProviderBuilder { // This provider does not need a seed, so it is its own builder.
|
||||
private final Map<Color, TerraBiome> colorBiomeMap = new HashMap<>();
|
||||
private final BufferedImage image;
|
||||
private final int resolution;
|
||||
private final Align align;
|
||||
|
||||
public ImageBiomeProvider(TerraRegistry<TerraBiome> registry, BufferedImage image, int resolution) {
|
||||
public ImageBiomeProvider(TerraRegistry<TerraBiome> registry, BufferedImage image, int resolution, Align align) {
|
||||
this.image = image;
|
||||
this.resolution = resolution;
|
||||
this.align = align;
|
||||
registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome));
|
||||
}
|
||||
|
||||
@@ -26,7 +28,9 @@ public class ImageBiomeProvider implements BiomeProvider {
|
||||
|
||||
@Override
|
||||
public TerraBiome getBiome(int x, int z) {
|
||||
Color color = new Color(image.getRGB(FastMath.floorMod(x / resolution, image.getWidth()), FastMath.floorMod(z / resolution, image.getHeight())));
|
||||
x /= resolution;
|
||||
z /= resolution;
|
||||
Color color = align.getColor(image, x, z);
|
||||
return colorBiomeMap.get(colorBiomeMap.keySet().stream().reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new), (running, element) -> {
|
||||
int d1 = distance(color, running);
|
||||
int d2 = distance(color, element);
|
||||
@@ -34,20 +38,24 @@ public class ImageBiomeProvider implements BiomeProvider {
|
||||
}));
|
||||
}
|
||||
|
||||
public static class ImageBiomeProviderBuilder implements BiomeProviderBuilder {
|
||||
private final BufferedImage image;
|
||||
private final int resolution;
|
||||
private final TerraRegistry<TerraBiome> registry;
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ImageBiomeProviderBuilder(BufferedImage image, int resolution, TerraRegistry<TerraBiome> registry) {
|
||||
this.image = image;
|
||||
this.resolution = resolution;
|
||||
this.registry = registry;
|
||||
}
|
||||
public enum Align {
|
||||
CENTER {
|
||||
@Override
|
||||
public Color getColor(BufferedImage image, int x, int z) {
|
||||
return new Color(image.getRGB(FastMath.floorMod(x - image.getWidth() / 2, image.getWidth()), FastMath.floorMod(z - image.getHeight() / 2, image.getHeight())));
|
||||
}
|
||||
}, NONE {
|
||||
@Override
|
||||
public Color getColor(BufferedImage image, int x, int z) {
|
||||
return new Color(image.getRGB(FastMath.floorMod(x, image.getWidth()), FastMath.floorMod(z, image.getHeight())));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return new ImageBiomeProvider(registry, image, resolution);
|
||||
}
|
||||
public abstract Color getColor(BufferedImage image, int x, int z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.dfsek.terra.biome.provider;
|
||||
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
|
||||
public class SingleBiomeProvider implements BiomeProvider {
|
||||
public class SingleBiomeProvider implements BiomeProvider, BiomeProvider.BiomeProviderBuilder {
|
||||
private final TerraBiome biome;
|
||||
|
||||
public SingleBiomeProvider(TerraBiome biome) {
|
||||
@@ -14,5 +14,8 @@ public class SingleBiomeProvider implements BiomeProvider {
|
||||
return biome;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.dfsek.terra.biome.provider;
|
||||
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.pipeline.BiomeHolder;
|
||||
import com.dfsek.terra.biome.pipeline.BiomePipeline;
|
||||
@@ -17,12 +15,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class StandardBiomeProvider implements BiomeProvider {
|
||||
private final LoadingCache<Vector2, BiomeHolder> holderCache;
|
||||
private final BiomePipeline pipeline;
|
||||
private int resolution = 1;
|
||||
private final int resolution;
|
||||
private final NoiseSampler mutator;
|
||||
private final double noiseAmp;
|
||||
private final int seed;
|
||||
|
||||
protected StandardBiomeProvider(BiomePipeline pipeline, TerraPlugin main, NoiseSampler mutator, double noiseAmp, int seed) {
|
||||
public StandardBiomeProvider(BiomePipeline pipeline, TerraPlugin main, int resolution, NoiseSampler mutator, double noiseAmp, int seed) {
|
||||
this.resolution = resolution;
|
||||
this.mutator = mutator;
|
||||
this.noiseAmp = noiseAmp;
|
||||
this.seed = seed;
|
||||
@@ -53,52 +52,4 @@ public class StandardBiomeProvider implements BiomeProvider {
|
||||
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
|
||||
return holderCache.getUnchecked(new Vector2(fdX, fdZ)).getBiome(x - fdX * pipeline.getSize(), z - fdZ * pipeline.getSize());
|
||||
}
|
||||
|
||||
public int getResolution() {
|
||||
return resolution;
|
||||
}
|
||||
|
||||
public void setResolution(int resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public interface ExceptionalFunction<I, O> {
|
||||
O apply(I in) throws ConfigException;
|
||||
}
|
||||
|
||||
public static final class StandardBiomeProviderBuilder implements BiomeProviderBuilder {
|
||||
private final ExceptionalFunction<Long, BiomePipeline> pipelineBuilder;
|
||||
private final TerraPlugin main;
|
||||
private int resolution = 1;
|
||||
private double noiseAmp = 2;
|
||||
private NoiseSeeded builder;
|
||||
|
||||
public StandardBiomeProviderBuilder(ExceptionalFunction<Long, BiomePipeline> pipelineBuilder, TerraPlugin main) {
|
||||
this.pipelineBuilder = pipelineBuilder;
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
public void setResolution(int resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public void setBlender(NoiseSeeded builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
public void setNoiseAmp(double noiseAmp) {
|
||||
this.noiseAmp = noiseAmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StandardBiomeProvider build(long seed) {
|
||||
try {
|
||||
StandardBiomeProvider provider = new StandardBiomeProvider(pipelineBuilder.apply(seed), main, builder.apply(seed), noiseAmp, (int) seed);
|
||||
provider.setResolution(resolution);
|
||||
return provider;
|
||||
} catch(ConfigException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ public class CarverCache {
|
||||
BiomeProvider provider = main.getWorld(w).getBiomeProvider();
|
||||
if(CarverCache.this.carver.isChunkCarved(w, chunkX, chunkZ, new FastRandom(MathUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed() + CarverCache.this.carver.hashCode())))) {
|
||||
long seed = MathUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed());
|
||||
CarverCache.this.carver.getSeedVar().setValue(seed);
|
||||
Random r = new FastRandom(seed);
|
||||
Worm carving = CarverCache.this.carver.getWorm(seed, new Vector3((chunkX << 4) + r.nextInt(16), CarverCache.this.carver.getConfig().getHeight().get(r), (chunkZ << 4) + r.nextInt(16)));
|
||||
List<Worm.WormPoint> points = new GlueList<>();
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package com.dfsek.terra.carving;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.math.parsii.defined.UserDefinedFunction;
|
||||
@@ -16,18 +20,12 @@ import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
import net.jafama.FastMath;
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Parser;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.eval.Variable;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UserDefinedCarver extends Carver {
|
||||
private final double[] start; // 0, 1, 2 = x, y, z.
|
||||
@@ -40,13 +38,6 @@ public class UserDefinedCarver extends Carver {
|
||||
private final Expression xRad;
|
||||
private final Expression yRad;
|
||||
private final Expression zRad;
|
||||
private final Variable lengthVar;
|
||||
private final Variable position;
|
||||
private final Variable seedVar;
|
||||
|
||||
private final Variable xOrigin;
|
||||
private final Variable yOrigin;
|
||||
private final Variable zOrigin;
|
||||
|
||||
private final Map<World, CarverCache> cacheMap = new ConcurrentHashMap<>();
|
||||
private final TerraPlugin main;
|
||||
@@ -70,33 +61,28 @@ public class UserDefinedCarver extends Carver {
|
||||
functions.forEach((id, noise) -> {
|
||||
switch(noise.getDimensions()) {
|
||||
case 2:
|
||||
p.registerFunction(id, new NoiseFunction2(hash, noise));
|
||||
p.registerFunction(id, new NoiseFunction2(noise.apply(hash)));
|
||||
break;
|
||||
case 3:
|
||||
p.registerFunction(id, new NoiseFunction3(hash, noise));
|
||||
p.registerFunction(id, new NoiseFunction3(noise.apply(hash)));
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
for(Map.Entry<String, FunctionTemplate> entry : definedFunctions.entrySet()) {
|
||||
String id = entry.getKey();
|
||||
FunctionTemplate fun = entry.getValue();
|
||||
|
||||
Scope functionScope = new Scope().withParent(parent);
|
||||
List<Variable> variables = fun.getArgs().stream().map(functionScope::create).collect(Collectors.toList());
|
||||
|
||||
p.registerFunction(id, new UserDefinedFunction(p.parse(fun.getFunction(), functionScope), variables));
|
||||
p.registerFunction(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), p, parent));
|
||||
}
|
||||
|
||||
Scope s = new Scope().withParent(parent);
|
||||
|
||||
lengthVar = s.create("length");
|
||||
position = s.create("position");
|
||||
seedVar = s.create("seed");
|
||||
|
||||
xOrigin = s.create("x");
|
||||
yOrigin = s.create("y");
|
||||
zOrigin = s.create("z");
|
||||
s.addInvocationVariable("x");
|
||||
s.addInvocationVariable("y");
|
||||
s.addInvocationVariable("z");
|
||||
|
||||
s.addInvocationVariable("length");
|
||||
s.addInvocationVariable("position");
|
||||
s.addInvocationVariable("seed");
|
||||
|
||||
|
||||
xRad = p.parse(radii.get(0), s);
|
||||
@@ -108,19 +94,7 @@ public class UserDefinedCarver extends Carver {
|
||||
@Override
|
||||
public Worm getWorm(long l, Vector3 vector) {
|
||||
Random r = new FastRandom(l + hash);
|
||||
return new UserDefinedWorm(length.get(r) / 2, r, vector, topCut, bottomCut);
|
||||
}
|
||||
|
||||
protected Variable getSeedVar() {
|
||||
return seedVar;
|
||||
}
|
||||
|
||||
protected Variable getLengthVar() {
|
||||
return lengthVar;
|
||||
}
|
||||
|
||||
protected Variable getPosition() {
|
||||
return position;
|
||||
return new UserDefinedWorm(length.get(r) / 2, r, vector, topCut, bottomCut, l);
|
||||
}
|
||||
|
||||
public void setStep(double step) {
|
||||
@@ -168,21 +142,21 @@ public class UserDefinedCarver extends Carver {
|
||||
|
||||
private class UserDefinedWorm extends Worm {
|
||||
private final Vector3 direction;
|
||||
private final Vector3 origin;
|
||||
private int steps;
|
||||
private int nextDirection = 0;
|
||||
private double[] currentRotation = new double[3];
|
||||
private final long seed;
|
||||
|
||||
public UserDefinedWorm(int length, Random r, Vector3 origin, int topCut, int bottomCut) {
|
||||
public UserDefinedWorm(int length, Random r, Vector3 origin, int topCut, int bottomCut, long seed) {
|
||||
super(length, r, origin);
|
||||
this.origin = origin;
|
||||
this.seed = seed;
|
||||
super.setTopCut(topCut);
|
||||
super.setBottomCut(bottomCut);
|
||||
direction = new Vector3((r.nextDouble() - 0.5D) * start[0], (r.nextDouble() - 0.5D) * start[1], (r.nextDouble() - 0.5D) * start[2]).normalize().multiply(step);
|
||||
position.setValue(0);
|
||||
lengthVar.setValue(length);
|
||||
xOrigin.setValue(origin.getX());
|
||||
yOrigin.setValue(origin.getY());
|
||||
zOrigin.setValue(origin.getZ());
|
||||
setRadius(new int[] {(int) (xRad.evaluate()), (int) (yRad.evaluate()), (int) (zRad.evaluate())});
|
||||
double[] args = {origin.getX(), origin.getY(), origin.getZ(), length, 0, seed};
|
||||
setRadius(new int[] {(int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args))});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,7 +165,7 @@ public class UserDefinedCarver extends Carver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void step() {
|
||||
public void step() {
|
||||
if(steps == nextDirection) {
|
||||
direction.rotateAroundX(FastMath.toRadians((getRandom().nextGaussian()) * mutate[0] * recalcMagnitude));
|
||||
direction.rotateAroundY(FastMath.toRadians((getRandom().nextGaussian()) * mutate[1] * recalcMagnitude));
|
||||
@@ -202,8 +176,8 @@ public class UserDefinedCarver extends Carver {
|
||||
nextDirection += recalc.get(getRandom());
|
||||
}
|
||||
steps++;
|
||||
position.setValue(steps);
|
||||
setRadius(new int[] {(int) (xRad.evaluate()), (int) (yRad.evaluate()), (int) (zRad.evaluate())});
|
||||
double[] args = {origin.getX(), origin.getY(), origin.getZ(), getLength(), steps, seed};
|
||||
setRadius(new int[] {(int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args))});
|
||||
direction.rotateAroundX(FastMath.toRadians(currentRotation[0] * mutate[0]));
|
||||
direction.rotateAroundY(FastMath.toRadians(currentRotation[1] * mutate[1]));
|
||||
direction.rotateAroundZ(FastMath.toRadians(currentRotation[2] * mutate[2]));
|
||||
|
||||
@@ -6,14 +6,16 @@ import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.GridSpawn;
|
||||
import com.dfsek.terra.api.math.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.Normalizer;
|
||||
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
|
||||
import com.dfsek.terra.api.math.noise.samplers.ImageSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
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.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.ImageBiomeProvider;
|
||||
import com.dfsek.terra.carving.CarverPalette;
|
||||
import com.dfsek.terra.config.loaders.LinkedHashMapLoader;
|
||||
import com.dfsek.terra.config.loaders.MaterialSetLoader;
|
||||
@@ -24,6 +26,9 @@ 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.BiomeProviderBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.SourceBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.StageBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.expander.ExpanderStageTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.BorderListMutatorTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.BorderMutatorTemplate;
|
||||
@@ -31,10 +36,10 @@ import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.Repla
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.ReplaceMutatorTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.SmoothMutatorTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
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;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.ClampNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.LinearNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.NormalNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.palette.CarverPaletteLoader;
|
||||
@@ -75,8 +80,7 @@ public class GenericLoaders implements LoaderRegistrar {
|
||||
.registerLoader(DomainWarpTemplate.class, DomainWarpTemplate::new)
|
||||
.registerLoader(LinearNormalizerTemplate.class, LinearNormalizerTemplate::new)
|
||||
.registerLoader(NormalNormalizerTemplate.class, NormalNormalizerTemplate::new)
|
||||
.registerLoader(FastNoiseTemplate.class, FastNoiseTemplate::new)
|
||||
.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader())
|
||||
.registerLoader(ClampNormalizerTemplate.class, ClampNormalizerTemplate::new)
|
||||
.registerLoader(ReplaceMutatorTemplate.class, ReplaceMutatorTemplate::new)
|
||||
.registerLoader(ExpanderStageTemplate.class, ExpanderStageTemplate::new)
|
||||
.registerLoader(SmoothMutatorTemplate.class, SmoothMutatorTemplate::new)
|
||||
@@ -86,7 +90,12 @@ public class GenericLoaders implements LoaderRegistrar {
|
||||
.registerLoader(FunctionTemplate.class, FunctionTemplate::new)
|
||||
.registerLoader(LinkedHashMap.class, new LinkedHashMapLoader())
|
||||
.registerLoader(CarverPalette.class, new CarverPaletteLoader())
|
||||
.registerLoader(SourceSeeded.class, new SourceBuilderLoader())
|
||||
.registerLoader(StageSeeded.class, new StageBuilderLoader())
|
||||
.registerLoader(BiomeProvider.BiomeProviderBuilder.class, new BiomeProviderBuilderLoader())
|
||||
.registerLoader(ImageSampler.Channel.class, (t, object, cf) -> ImageSampler.Channel.valueOf((String) object))
|
||||
.registerLoader(BiomeProvider.Type.class, (t, object, cf) -> BiomeProvider.Type.valueOf((String) object))
|
||||
.registerLoader(ImageBiomeProvider.Align.class, (t, object, cf) -> ImageBiomeProvider.Align.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))
|
||||
@@ -95,8 +104,6 @@ public class GenericLoaders implements LoaderRegistrar {
|
||||
.registerLoader(FastNoiseLite.RotationType3D.class, (t, object, cf) -> FastNoiseLite.RotationType3D.valueOf((String) object))
|
||||
.registerLoader(FastNoiseLite.CellularReturnType.class, (t, object, cf) -> FastNoiseLite.CellularReturnType.valueOf((String) object))
|
||||
.registerLoader(FastNoiseLite.CellularDistanceFunction.class, (t, object, cf) -> FastNoiseLite.CellularDistanceFunction.valueOf((String) object))
|
||||
.registerLoader(Normalizer.NormalType.class, (t, o, l) -> Normalizer.NormalType.valueOf(o.toString().toUpperCase()))
|
||||
.registerLoader(TerraFlora.Search.class, (t, o, l) -> TerraFlora.Search.valueOf(o.toString()))
|
||||
.registerLoader(Normalizer.NormalType.class, (t, o, l) -> Normalizer.NormalType.valueOf(o.toString().toUpperCase()));
|
||||
.registerLoader(TerraFlora.Search.class, (t, o, l) -> TerraFlora.Search.valueOf(o.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.dfsek.terra.config.builder;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.ConstantSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.ExpressionSampler;
|
||||
@@ -7,8 +9,6 @@ import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
import com.dfsek.terra.world.generation.WorldGenerator;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
@@ -7,7 +8,6 @@ import com.dfsek.terra.config.builder.GeneratorBuilder;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import parsii.eval.Scope;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@@ -35,7 +35,7 @@ public class BiomeFactory implements TerraFactory<BiomeTemplate, TerraBiome> {
|
||||
generatorBuilder.setSlantPalettes(template.getSlantPalette());
|
||||
|
||||
Scope vars = new Scope().withParent(pack.getVarScope());
|
||||
template.getVariables().forEach((id, val) -> vars.create(id).setValue(val));
|
||||
template.getVariables().forEach(vars::create);
|
||||
generatorBuilder.setVarScope(vars);
|
||||
|
||||
generatorBuilder.setInterpolateElevation(template.interpolateElevation());
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.MathUtil;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -3,94 +3,31 @@ 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.core.TerraPlugin;
|
||||
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.BiomePipeline;
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.ImageBiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.SingleBiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.StandardBiomeProvider;
|
||||
import com.dfsek.terra.config.fileloaders.Loader;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.BiomePipelineTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.ImageProviderTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.SingleBiomeProviderTemplate;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProvider.BiomeProviderBuilder> {
|
||||
private final TerraPlugin main;
|
||||
private final TerraRegistry<TerraBiome> biomeRegistry;
|
||||
private final Loader fileLoader;
|
||||
|
||||
public BiomeProviderBuilderLoader(TerraPlugin main, TerraRegistry<TerraBiome> biomeRegistry, Loader fileLoader) {
|
||||
this.main = main;
|
||||
this.biomeRegistry = biomeRegistry;
|
||||
this.fileLoader = fileLoader;
|
||||
public BiomeProviderBuilderLoader() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider.BiomeProviderBuilder load(Type t, Object c, ConfigLoader loader) throws LoadException { // TODO: clean this up
|
||||
Map<String, Object> map = (Map<String, Object>) c;
|
||||
int resolution = (Integer) map.getOrDefault("resolution", 1);
|
||||
|
||||
if(map.get("type").equals("PIPELINE")) {
|
||||
Map<String, Object> pipeline = (Map<String, Object>) map.get("pipeline");
|
||||
|
||||
List<Map<String, Object>> stages = (List<Map<String, Object>>) pipeline.get("stages");
|
||||
|
||||
if(stages == null) throw new LoadException("No pipeline stages defined!");
|
||||
|
||||
int init = (Integer) pipeline.getOrDefault("initial-size", 2);
|
||||
|
||||
StandardBiomeProvider.StandardBiomeProviderBuilder builder = new StandardBiomeProvider.StandardBiomeProviderBuilder(seed -> {
|
||||
BiomePipeline.BiomePipelineBuilder pipelineBuilder = new BiomePipeline.BiomePipelineBuilder(init);
|
||||
|
||||
for(Map<String, Object> stage : stages) {
|
||||
for(Map.Entry<String, Object> entry : stage.entrySet()) {
|
||||
pipelineBuilder.addStage(new StageBuilderLoader().load(SeededBuilder.class, entry, loader));
|
||||
}
|
||||
}
|
||||
|
||||
if(!pipeline.containsKey("source")) throw new LoadException("Biome Source not defined!");
|
||||
SeededBuilder<BiomeSource> source = new SourceBuilderLoader().load(BiomeSource.class, pipeline.get("source"), loader);
|
||||
|
||||
BiomePipeline biomePipeline = pipelineBuilder.build(source.apply(seed), seed);
|
||||
main.getDebugLogger().info("Biome Pipeline scale factor: " + biomePipeline.getSize());
|
||||
return biomePipeline;
|
||||
}, main);
|
||||
|
||||
builder.setResolution(resolution);
|
||||
if(map.containsKey("blend")) {
|
||||
Map<String, Object> blend = (Map<String, Object>) map.get("blend");
|
||||
if(blend.containsKey("amplitude")) builder.setNoiseAmp(Double.parseDouble(blend.get("amplitude").toString()));
|
||||
if(blend.containsKey("noise"))
|
||||
builder.setBlender(loader.loadClass(NoiseSeeded.class, blend.get("noise")));
|
||||
}
|
||||
return builder;
|
||||
} else if(map.get("type").equals("IMAGE")) {
|
||||
Map<String, Object> imageMap = (Map<String, Object>) map.get("image");
|
||||
try {
|
||||
main.getLogger().info("Using image " + imageMap.get("name") + " for biome distribution.");
|
||||
BufferedImage image = ImageIO.read(fileLoader.get(imageMap.get("name").toString()));
|
||||
return new ImageBiomeProvider.ImageBiomeProviderBuilder(image, resolution, biomeRegistry);
|
||||
} catch(IOException e) {
|
||||
throw new LoadException("Failed to load image", e);
|
||||
}
|
||||
} else if(map.get("type").equals("SINGLE")) {
|
||||
return seed -> {
|
||||
try {
|
||||
return new SingleBiomeProvider(loader.loadClass(TerraBiome.class, map.get("biome")));
|
||||
} catch(LoadException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
switch(loader.loadClass(BiomeProvider.Type.class, map.get("type"))) {
|
||||
case IMAGE:
|
||||
return loader.loadClass(ImageProviderTemplate.class, map);
|
||||
case PIPELINE:
|
||||
return loader.loadClass(BiomePipelineTemplate.class, map);
|
||||
case SINGLE:
|
||||
return loader.loadClass(SingleBiomeProviderTemplate.class, map);
|
||||
}
|
||||
|
||||
throw new LoadException("No such biome provider type: " + map.get("type"));
|
||||
|
||||
@@ -5,9 +5,8 @@ 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.api.util.seeded.SourceSeeded;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.biome.pipeline.source.RandomSource;
|
||||
import com.dfsek.terra.config.loaders.Types;
|
||||
|
||||
@@ -15,9 +14,9 @@ import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SourceBuilderLoader implements TypeLoader<SeededBuilder<BiomeSource>> {
|
||||
public class SourceBuilderLoader implements TypeLoader<SourceSeeded> {
|
||||
@Override
|
||||
public SeededBuilder<BiomeSource> load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
public SourceSeeded load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
Map<String, Object> source = (Map<String, Object>) c;
|
||||
|
||||
String type = source.get("type").toString();
|
||||
|
||||
@@ -3,10 +3,9 @@ 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.util.seeded.SeededBuilder;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
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.config.biome.templates.stage.expander.ExpanderStageTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.BorderListMutatorTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.BorderMutatorTemplate;
|
||||
@@ -18,33 +17,40 @@ import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class StageBuilderLoader implements TypeLoader<SeededBuilder<Stage>> {
|
||||
public class StageBuilderLoader implements TypeLoader<StageSeeded> {
|
||||
@Override
|
||||
public SeededBuilder<Stage> load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) c;
|
||||
public StageSeeded load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
Map<String, Object> raw = (Map<String, Object>) c;
|
||||
|
||||
if(raw.size() != 1) throw new LoadException("Illegal stage map size: " + raw.size());
|
||||
|
||||
Map.Entry<String, Object> entry = null;
|
||||
|
||||
for(Map.Entry<String, Object> e : raw.entrySet()) {
|
||||
entry = e;
|
||||
}
|
||||
|
||||
Map<String, Object> mutator = (Map<String, Object>) entry.getValue();
|
||||
|
||||
if(entry.getKey().equals("expand")) {
|
||||
ExpanderStage.Type stageType = loader.loadClass(ExpanderStage.Type.class, mutator.get("type"));
|
||||
if(stageType.equals(ExpanderStage.Type.FRACTAL)) {
|
||||
return loader.loadClass(ExpanderStageTemplate.class, mutator).get();
|
||||
return loader.loadClass(ExpanderStageTemplate.class, mutator);
|
||||
} else throw new LoadException("No such expander \"" + stageType + "\"");
|
||||
} else if(entry.getKey().equals("mutate")) {
|
||||
switch(loader.loadClass(MutatorStage.Type.class, mutator.get("type"))) {
|
||||
case SMOOTH:
|
||||
return loader.loadClass(SmoothMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(SmoothMutatorTemplate.class, mutator);
|
||||
case REPLACE:
|
||||
return loader.loadClass(ReplaceMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(ReplaceMutatorTemplate.class, mutator);
|
||||
case REPLACE_LIST:
|
||||
return loader.loadClass(ReplaceListMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(ReplaceListMutatorTemplate.class, mutator);
|
||||
case BORDER:
|
||||
return loader.loadClass(BorderMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(BorderMutatorTemplate.class, mutator);
|
||||
case BORDER_LIST:
|
||||
return loader.loadClass(BorderListMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(BorderListMutatorTemplate.class, mutator);
|
||||
default:
|
||||
throw new LoadException("No such mutator type \"" + mutator.get("type"));
|
||||
|
||||
}
|
||||
}
|
||||
throw new LoadException("No such mutator \"" + entry.getKey() + "\"");
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
import com.dfsek.terra.biome.pipeline.BiomePipeline;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.StandardBiomeProvider;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
||||
public class BiomePipelineTemplate extends BiomeProviderTemplate {
|
||||
private final TerraPlugin main;
|
||||
@Value("pipeline.initial-size")
|
||||
@Default
|
||||
private int initialSize = 2;
|
||||
|
||||
@Value("pipeline.stages")
|
||||
private List<StageSeeded> stages;
|
||||
|
||||
@Value("pipeline.source")
|
||||
private SourceSeeded source;
|
||||
|
||||
public BiomePipelineTemplate(BiomeRegistry registry, TerraPlugin main) {
|
||||
super(registry);
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
BiomePipeline.BiomePipelineBuilder biomePipelineBuilder = new BiomePipeline.BiomePipelineBuilder(initialSize);
|
||||
stages.forEach(biomePipelineBuilder::addStage);
|
||||
BiomePipeline pipeline = biomePipelineBuilder.build(source.apply(seed), seed);
|
||||
return new StandardBiomeProvider(pipeline, main, resolution, blend.apply(seed), blendAmp, (int) seed);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.ConstantSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
|
||||
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider.BiomeProviderBuilder>, BiomeProvider.BiomeProviderBuilder {
|
||||
protected final BiomeRegistry registry;
|
||||
@Value("resolution")
|
||||
@Default
|
||||
protected int resolution = 1;
|
||||
@Value("blend.noise")
|
||||
@Default
|
||||
protected NoiseSeeded blend = new NoiseSeeded() {
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
return new ConstantSampler(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDimensions() {
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
@Value("blend.amplitude")
|
||||
@Default
|
||||
protected double blendAmp = 0d;
|
||||
@Value("type")
|
||||
BiomeProvider.Type type;
|
||||
|
||||
protected BiomeProviderTemplate(BiomeRegistry registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider.BiomeProviderBuilder get() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.ImageBiomeProvider;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class ImageProviderTemplate extends BiomeProviderTemplate {
|
||||
@Value("image.name")
|
||||
private BufferedImage image;
|
||||
|
||||
@Value("image.align")
|
||||
private ImageBiomeProvider.Align align;
|
||||
|
||||
public ImageProviderTemplate(BiomeRegistry registry) {
|
||||
super(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return new ImageBiomeProvider(registry, image, resolution, align);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.SingleBiomeProvider;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
|
||||
public class SingleBiomeProviderTemplate extends BiomeProviderTemplate {
|
||||
@Value("biome")
|
||||
private TerraBiome biome;
|
||||
|
||||
public SingleBiomeProviderTemplate(BiomeRegistry registry) {
|
||||
super(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return new SingleBiomeProvider(biome);
|
||||
}
|
||||
}
|
||||
@@ -4,14 +4,15 @@ 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.api.util.seeded.StageSeeded;
|
||||
import com.dfsek.terra.biome.pipeline.stages.Stage;
|
||||
|
||||
public abstract class StageTemplate implements ObjectTemplate<SeededBuilder<Stage>>, SeededBuilder<Stage> {
|
||||
public abstract class StageTemplate implements ObjectTemplate<SeededBuilder<Stage>>, StageSeeded {
|
||||
@Value("noise")
|
||||
protected NoiseSeeded noise;
|
||||
|
||||
@Override
|
||||
public SeededBuilder<Stage> get() {
|
||||
public StageSeeded get() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.Normalizer;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.DomainWarpTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.FastNoiseTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.LinearNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.NormalNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.NormalizerTemplate;
|
||||
import com.dfsek.terra.registry.config.NormalizerRegistry;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class NoiseSamplerBuilderLoader implements TypeLoader<NoiseSeeded> {
|
||||
private final NormalizerRegistry normalizerRegistry;
|
||||
|
||||
public NoiseSamplerBuilderLoader(NormalizerRegistry normalizerRegistry) {
|
||||
this.normalizerRegistry = normalizerRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoiseSeeded load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
@@ -31,12 +37,12 @@ public class NoiseSamplerBuilderLoader implements TypeLoader<NoiseSeeded> {
|
||||
case "NOISE":
|
||||
return loader.loadClass(FastNoiseTemplate.class, map).get();
|
||||
case "NORMALIZER":
|
||||
Normalizer.NormalType normalType = loader.loadClass(Normalizer.NormalType.class, map.get("type"));
|
||||
switch(normalType) {
|
||||
case LINEAR:
|
||||
return loader.loadClass(LinearNormalizerTemplate.class, map).get();
|
||||
case NORMAL:
|
||||
return loader.loadClass(NormalNormalizerTemplate.class, map).get();
|
||||
try {
|
||||
NormalizerTemplate<?> normalizerTemplate = normalizerRegistry.get((String) map.get("type")).get();
|
||||
loader.load(normalizerTemplate, new Configuration(map));
|
||||
return normalizerTemplate;
|
||||
} catch(ConfigException e) {
|
||||
throw new LoadException("Unable to load normalizer: ", e);
|
||||
}
|
||||
case "IMAGE": {
|
||||
return loader.loadClass(ImageSamplerTemplate.class, map).get();
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates.normalizer;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.ClampNormalizer;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.LinearNormalizer;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class ClampNormalizerTemplate extends NormalizerTemplate<LinearNormalizer> {
|
||||
@Value("max")
|
||||
private double max;
|
||||
|
||||
@Value("min")
|
||||
private double min;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
return new ClampNormalizer(function.apply(seed), min, max);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.dfsek.terra.config.pack;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.tectonic.abstraction.AbstractConfigLoader;
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
@@ -9,6 +10,7 @@ import com.dfsek.terra.api.LoaderRegistrar;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.structures.loot.LootTable;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
@@ -29,7 +31,11 @@ import com.dfsek.terra.config.fileloaders.Loader;
|
||||
import com.dfsek.terra.config.fileloaders.ZIPLoader;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.config.loaders.config.BufferedImageLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.BiomeProviderBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.BiomePipelineTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.ImageProviderTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.SingleBiomeProviderTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate;
|
||||
import com.dfsek.terra.config.templates.AbstractableTemplate;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
@@ -38,22 +44,22 @@ import com.dfsek.terra.config.templates.OreTemplate;
|
||||
import com.dfsek.terra.config.templates.PaletteTemplate;
|
||||
import com.dfsek.terra.config.templates.StructureTemplate;
|
||||
import com.dfsek.terra.config.templates.TreeTemplate;
|
||||
import com.dfsek.terra.registry.BiomeRegistry;
|
||||
import com.dfsek.terra.registry.CarverRegistry;
|
||||
import com.dfsek.terra.registry.FloraRegistry;
|
||||
import com.dfsek.terra.registry.LootRegistry;
|
||||
import com.dfsek.terra.registry.OreRegistry;
|
||||
import com.dfsek.terra.registry.PaletteRegistry;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import com.dfsek.terra.registry.StructureRegistry;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
import com.dfsek.terra.registry.TreeRegistry;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
import com.dfsek.terra.registry.config.CarverRegistry;
|
||||
import com.dfsek.terra.registry.config.FloraRegistry;
|
||||
import com.dfsek.terra.registry.config.LootRegistry;
|
||||
import com.dfsek.terra.registry.config.NormalizerRegistry;
|
||||
import com.dfsek.terra.registry.config.OreRegistry;
|
||||
import com.dfsek.terra.registry.config.PaletteRegistry;
|
||||
import com.dfsek.terra.registry.config.ScriptRegistry;
|
||||
import com.dfsek.terra.registry.config.StructureRegistry;
|
||||
import com.dfsek.terra.registry.config.TreeRegistry;
|
||||
import com.dfsek.terra.world.generation.math.SamplerCache;
|
||||
import com.dfsek.terra.world.population.items.TerraStructure;
|
||||
import com.dfsek.terra.world.population.items.ores.Ore;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import parsii.eval.Scope;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
@@ -88,6 +94,8 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
|
||||
private final CarverRegistry carverRegistry = new CarverRegistry();
|
||||
|
||||
private final NormalizerRegistry normalizerRegistry = new NormalizerRegistry();
|
||||
|
||||
private final AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader();
|
||||
private final ConfigLoader selfLoader = new ConfigLoader();
|
||||
private final Scope varScope = new Scope();
|
||||
@@ -97,74 +105,98 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
private final TerraPlugin main;
|
||||
private final Loader loader;
|
||||
|
||||
private final BiomeProvider.BiomeProviderBuilder biomeProviderBuilder;
|
||||
|
||||
|
||||
public ConfigPack(File folder, TerraPlugin main) throws ConfigException {
|
||||
this.loader = new FolderLoader(folder.toPath());
|
||||
this.main = main;
|
||||
long l = System.nanoTime();
|
||||
this.samplerCache = new SamplerCache(main);
|
||||
floraRegistry = new FloraRegistry(main);
|
||||
paletteRegistry = new PaletteRegistry(main);
|
||||
treeRegistry = new TreeRegistry(main);
|
||||
register(abstractConfigLoader);
|
||||
register(selfLoader);
|
||||
|
||||
main.register(selfLoader);
|
||||
main.register(abstractConfigLoader);
|
||||
|
||||
File pack = new File(folder, "pack.yml");
|
||||
|
||||
try {
|
||||
selfLoader.load(template, new FileInputStream(pack));
|
||||
} catch(FileNotFoundException e) {
|
||||
throw new FileMissingException("No pack.yml file found in " + folder.getAbsolutePath(), e);
|
||||
this.loader = new FolderLoader(folder.toPath());
|
||||
this.main = main;
|
||||
long l = System.nanoTime();
|
||||
this.samplerCache = new SamplerCache(main);
|
||||
floraRegistry = new FloraRegistry(main);
|
||||
paletteRegistry = new PaletteRegistry(main);
|
||||
treeRegistry = new TreeRegistry(main);
|
||||
register(abstractConfigLoader);
|
||||
register(selfLoader);
|
||||
|
||||
main.register(selfLoader);
|
||||
main.register(abstractConfigLoader);
|
||||
|
||||
File pack = new File(folder, "pack.yml");
|
||||
|
||||
try {
|
||||
selfLoader.load(template, new FileInputStream(pack));
|
||||
|
||||
main.getLogger().info("Loading config pack \"" + template.getID() + "\"");
|
||||
|
||||
load(l, main);
|
||||
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
||||
selfLoader.load(packPostTemplate, new FileInputStream(pack));
|
||||
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
||||
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
||||
} catch(FileNotFoundException e) {
|
||||
throw new FileMissingException("No pack.yml file found in " + folder.getAbsolutePath(), e);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
main.getLogger().severe("Failed to load config pack from folder \"" + folder.getAbsolutePath() + "\"");
|
||||
throw e;
|
||||
}
|
||||
load(l, main);
|
||||
}
|
||||
|
||||
public ConfigPack(ZipFile file, TerraPlugin main) throws ConfigException {
|
||||
this.loader = new ZIPLoader(file);
|
||||
this.main = main;
|
||||
long l = System.nanoTime();
|
||||
this.samplerCache = new SamplerCache(main);
|
||||
floraRegistry = new FloraRegistry(main);
|
||||
paletteRegistry = new PaletteRegistry(main);
|
||||
treeRegistry = new TreeRegistry(main);
|
||||
register(abstractConfigLoader);
|
||||
register(selfLoader);
|
||||
|
||||
main.register(selfLoader);
|
||||
main.register(abstractConfigLoader);
|
||||
|
||||
InputStream stream = null;
|
||||
|
||||
try {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(entry.getName().equals("pack.yml")) stream = file.getInputStream(entry);
|
||||
this.loader = new ZIPLoader(file);
|
||||
this.main = main;
|
||||
long l = System.nanoTime();
|
||||
this.samplerCache = new SamplerCache(main);
|
||||
floraRegistry = new FloraRegistry(main);
|
||||
paletteRegistry = new PaletteRegistry(main);
|
||||
treeRegistry = new TreeRegistry(main);
|
||||
register(abstractConfigLoader);
|
||||
register(selfLoader);
|
||||
|
||||
main.register(selfLoader);
|
||||
main.register(abstractConfigLoader);
|
||||
|
||||
try {
|
||||
ZipEntry pack = null;
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(entry.getName().equals("pack.yml")) pack = entry;
|
||||
}
|
||||
|
||||
if(pack == null) throw new FileMissingException("No pack.yml file found in " + file.getName());
|
||||
|
||||
selfLoader.load(template, file.getInputStream(pack));
|
||||
main.getLogger().info("Loading config pack \"" + template.getID() + "\"");
|
||||
|
||||
load(l, main);
|
||||
|
||||
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
||||
|
||||
selfLoader.load(packPostTemplate, file.getInputStream(pack));
|
||||
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
||||
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
||||
} catch(IOException e) {
|
||||
throw new LoadException("Unable to load pack.yml from ZIP file", e);
|
||||
}
|
||||
} catch(IOException e) {
|
||||
throw new LoadException("Unable to load pack.yml from ZIP file", e);
|
||||
} catch(Exception e) {
|
||||
main.getLogger().severe("Failed to load config pack from ZIP archive \"" + file.getName() + "\"");
|
||||
throw e;
|
||||
}
|
||||
if(stream == null) throw new FileMissingException("No pack.yml file found in " + file.getName());
|
||||
}
|
||||
|
||||
selfLoader.load(template, stream);
|
||||
|
||||
|
||||
load(l, main);
|
||||
|
||||
template.getProviderBuilder().build(0); // Build dummy provider to catch errors at load time.
|
||||
public static <C extends AbstractableTemplate, O> void buildAll(TerraFactory<C, O> factory, TerraRegistry<O> registry, List<C> configTemplates, TerraPlugin main) throws LoadException {
|
||||
for(C template : configTemplates) registry.add(template.getID(), factory.build(template, main));
|
||||
}
|
||||
|
||||
private void load(long start, TerraPlugin main) throws ConfigException {
|
||||
main.packPreLoadCallback(this);
|
||||
for(Map.Entry<String, Double> var : template.getVariables().entrySet()) {
|
||||
varScope.create(var.getKey()).setValue(var.getValue());
|
||||
varScope.create(var.getKey(), var.getValue());
|
||||
}
|
||||
loader.open("structures/data", ".tstructure")
|
||||
.thenNames(ids -> ids.forEach(id -> main.getLogger().severe("Found .tstructure file \"" + id + "\". This file must be updated to the newer .tesf format to work properly. See version 3.0 release notes for instructions.")))
|
||||
.close();
|
||||
|
||||
loader.open("structures/data", ".tesf").thenEntries(entries -> {
|
||||
for(Map.Entry<String, InputStream> entry : entries) {
|
||||
@@ -197,10 +229,6 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
LangUtil.log("config-pack.loaded", Level.INFO, template.getID(), String.valueOf((System.nanoTime() - start) / 1000000D), template.getAuthor(), template.getVersion());
|
||||
}
|
||||
|
||||
public static <C extends AbstractableTemplate, O> void buildAll(TerraFactory<C, O> factory, TerraRegistry<O> registry, List<C> configTemplates, TerraPlugin main) throws LoadException {
|
||||
for(C template : configTemplates) registry.add(template.getID(), factory.build(template, main));
|
||||
}
|
||||
|
||||
public TerraBiome getBiome(String id) {
|
||||
return biomeRegistry.get(id);
|
||||
}
|
||||
@@ -247,7 +275,10 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
.registerLoader(LootTable.class, lootRegistry)
|
||||
.registerLoader(UserDefinedCarver.class, carverRegistry)
|
||||
.registerLoader(BufferedImage.class, new BufferedImageLoader(loader))
|
||||
.registerLoader(BiomeProvider.BiomeProviderBuilder.class, new BiomeProviderBuilderLoader(main, biomeRegistry, loader));
|
||||
.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader(normalizerRegistry))
|
||||
.registerLoader(SingleBiomeProviderTemplate.class, () -> new SingleBiomeProviderTemplate(biomeRegistry))
|
||||
.registerLoader(BiomePipelineTemplate.class, () -> new BiomePipelineTemplate(biomeRegistry, main))
|
||||
.registerLoader(ImageSamplerTemplate.class, () -> new ImageProviderTemplate(biomeRegistry));
|
||||
}
|
||||
|
||||
public ScriptRegistry getScriptRegistry() {
|
||||
@@ -265,4 +296,8 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
public Set<UserDefinedCarver> getCarvers() {
|
||||
return carverRegistry.entries();
|
||||
}
|
||||
|
||||
public BiomeProvider.BiomeProviderBuilder getBiomeProviderBuilder() {
|
||||
return biomeProviderBuilder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.dfsek.terra.config.pack;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
|
||||
public class ConfigPackPostTemplate implements ConfigTemplate {
|
||||
@Value("biomes")
|
||||
private BiomeProvider.BiomeProviderBuilder providerBuilder;
|
||||
|
||||
public BiomeProvider.BiomeProviderBuilder getProviderBuilder() {
|
||||
return providerBuilder;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -67,13 +66,6 @@ public class ConfigPackTemplate implements ConfigTemplate {
|
||||
@Default
|
||||
private String version = "0.1.0";
|
||||
|
||||
@Value("biomes")
|
||||
private BiomeProvider.BiomeProviderBuilder providerBuilder;
|
||||
|
||||
public BiomeProvider.BiomeProviderBuilder getProviderBuilder() {
|
||||
return providerBuilder;
|
||||
}
|
||||
|
||||
public Map<String, FunctionTemplate> getFunctions() {
|
||||
return functions;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.dfsek.terra.config.templates;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.tectonic.annotations.Abstractable;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
@@ -27,17 +30,12 @@ import com.dfsek.terra.world.population.items.TerraStructure;
|
||||
import com.dfsek.terra.world.population.items.flora.FloraLayer;
|
||||
import com.dfsek.terra.world.population.items.ores.OreHolder;
|
||||
import com.dfsek.terra.world.population.items.tree.TreeLayer;
|
||||
import parsii.eval.Parser;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.eval.Variable;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
||||
public class BiomeTemplate extends AbstractableTemplate implements ValidatedConfigTemplate {
|
||||
@@ -344,26 +342,20 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
|
||||
Parser tester = new Parser();
|
||||
Scope testScope = new Scope().withParent(pack.getVarScope());
|
||||
|
||||
variables.forEach((id, val) -> testScope.create(id).setValue(val));
|
||||
variables.forEach(testScope::create);
|
||||
|
||||
testScope.addInvocationVariable("x");
|
||||
testScope.addInvocationVariable("y");
|
||||
testScope.addInvocationVariable("z");
|
||||
|
||||
testScope.create("x");
|
||||
testScope.create("y");
|
||||
testScope.create("z");
|
||||
testScope.create("seed");
|
||||
|
||||
pack.getTemplate().getNoiseBuilderMap().forEach((id, builder) -> tester.registerFunction(id, new BlankFunction(builder.getDimensions()))); // Register dummy functions
|
||||
|
||||
Map<String, FunctionTemplate> testFunctions = new LinkedHashMap<>(pack.getTemplate().getFunctions());
|
||||
testFunctions.putAll(functions);
|
||||
for(Map.Entry<String, FunctionTemplate> entry : testFunctions.entrySet()) {
|
||||
String id = entry.getKey();
|
||||
FunctionTemplate fun = entry.getValue();
|
||||
|
||||
Scope functionScope = new Scope().withParent(testScope);
|
||||
List<Variable> variables = fun.getArgs().stream().map(functionScope::create).collect(Collectors.toList());
|
||||
|
||||
try {
|
||||
tester.registerFunction(id, new UserDefinedFunction(tester.parse(fun.getFunction(), functionScope), variables));
|
||||
tester.registerFunction(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), tester, testScope));
|
||||
} catch(ParseException e) {
|
||||
throw new ValidationException("Invalid function: ", e);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package com.dfsek.terra.registry;
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.dfsek.terra.registry;
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
|
||||
public class CarverRegistry extends TerraRegistry<UserDefinedCarver> {
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.dfsek.terra.registry;
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.block.MaterialData;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
import com.dfsek.terra.util.MaterialSet;
|
||||
import com.dfsek.terra.world.population.items.flora.ConstantFlora;
|
||||
|
||||
@@ -37,7 +38,7 @@ public class FloraRegistry extends TerraRegistry<Flora> {
|
||||
create("minecraft:light_gray_terracotta"), create("minecraft:lime_terracotta"), create("minecraft:magenta_terracotta"),
|
||||
create("minecraft:orange_terracotta"), create("minecraft:pink_terracotta"), create("minecraft:purple_terracotta"),
|
||||
create("minecraft:red_terracotta"), create("minecraft:white_terracotta"), create("minecraft:yellow_terracotta"),
|
||||
create("minecraft:red_sand"), create("minecraft:sand")), Collections.singletonList(data("minecraft:dead_bush"))));
|
||||
create("minecraft:red_sand"), create("minecraft:sand"), create("minecraft:coarse_dirt")), Collections.singletonList(data("minecraft:dead_bush"))));
|
||||
addItem("RED_TULIP", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:red_tulip"))));
|
||||
addItem("ORANGE_TULIP", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:orange_tulip"))));
|
||||
addItem("WHITE_TULIP", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:white_tulip"))));
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.dfsek.terra.registry;
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.api.structures.loot.LootTable;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
|
||||
public class LootRegistry extends TerraRegistry<LootTable> {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.ClampNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.LinearNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.NormalNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.NormalizerTemplate;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class NormalizerRegistry extends TerraRegistry<Supplier<NormalizerTemplate<?>>> {
|
||||
public NormalizerRegistry() {
|
||||
add("LINEAR", LinearNormalizerTemplate::new);
|
||||
add("NORMAL", NormalNormalizerTemplate::new);
|
||||
add("CLAMP", ClampNormalizerTemplate::new);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.dfsek.terra.registry;
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
import com.dfsek.terra.world.population.items.ores.Ore;
|
||||
|
||||
public class OreRegistry extends TerraRegistry<Ore> {
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.dfsek.terra.registry;
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
import com.dfsek.terra.api.world.palette.SinglePalette;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
|
||||
public class PaletteRegistry extends TerraRegistry<Palette<BlockData>> {
|
||||
private final TerraPlugin main;
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.dfsek.terra.registry;
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
|
||||
public class ScriptRegistry extends TerraRegistry<StructureScript> {
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.dfsek.terra.registry;
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
import com.dfsek.terra.world.population.items.TerraStructure;
|
||||
|
||||
public class StructureRegistry extends TerraRegistry<TerraStructure> {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.registry;
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
@@ -14,6 +14,7 @@ import com.dfsek.terra.api.world.tree.fractal.trees.ShatteredTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.SmallShatteredPillar;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.SmallShatteredTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.SpruceTree;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -24,9 +24,10 @@ public class TerraWorld {
|
||||
|
||||
|
||||
public TerraWorld(World w, ConfigPack c, TerraPlugin main) {
|
||||
c.getBiomeRegistry().forEach(biome -> biome.getGenerator(w)); // Load all gens to cache
|
||||
config = c;
|
||||
profiler = new WorldProfiler(w);
|
||||
this.provider = config.getTemplate().getProviderBuilder().build(w.getSeed());
|
||||
this.provider = config.getBiomeProviderBuilder().build(w.getSeed());
|
||||
this.world = w;
|
||||
air = main.getWorldHandle().createBlockData("minecraft:air");
|
||||
safe = true;
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
package biome;
|
||||
|
||||
import com.dfsek.terra.api.math.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
|
||||
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.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.pipeline.BiomePipeline;
|
||||
import com.dfsek.terra.biome.pipeline.expand.FractalExpander;
|
||||
import com.dfsek.terra.biome.pipeline.mutator.BorderMutator;
|
||||
import com.dfsek.terra.biome.pipeline.mutator.ReplaceMutator;
|
||||
import com.dfsek.terra.biome.pipeline.mutator.SmoothMutator;
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.biome.pipeline.source.RandomSource;
|
||||
import com.dfsek.terra.biome.pipeline.stages.ExpanderStage;
|
||||
import com.dfsek.terra.biome.pipeline.stages.MutatorStage;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.StandardBiomeProvider;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BiomeTest {
|
||||
@Test
|
||||
public static void main(String... args) {
|
||||
ProbabilityCollection<TerraBiome> oceanBiomes = new ProbabilityCollection<>();
|
||||
ProbabilityCollection<TerraBiome> landBiomes = new ProbabilityCollection<>();
|
||||
|
||||
|
||||
ProbabilityCollection<TerraBiome> beachBiomes = new ProbabilityCollection<>();
|
||||
|
||||
TestBiome ocean = new TestBiome(Color.BLUE, "OCEAN_TEMP");
|
||||
TestBiome land = new TestBiome(Color.GREEN, "LAND_TEMP");
|
||||
|
||||
TestBiome beach = new TestBiome(Color.YELLOW, "BEACH");
|
||||
beachBiomes.add(beach, 1);
|
||||
|
||||
|
||||
ProbabilityCollection<TerraBiome> climate = new ProbabilityCollection<>();
|
||||
climate.add(ocean, 1);
|
||||
climate.add(land, 2);
|
||||
|
||||
|
||||
oceanBiomes.add(new TestBiome(Color.BLUE, "OCEAN"), 10);
|
||||
oceanBiomes.add(new TestBiome(Color.CYAN, "OCEAN"), 1);
|
||||
|
||||
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);
|
||||
|
||||
FastNoiseLite sourceSampler = new FastNoiseLite(123);
|
||||
sourceSampler.setNoiseType(FastNoiseLite.NoiseType.WhiteNoise);
|
||||
|
||||
BiomeSource source = new RandomSource(climate, sourceSampler);
|
||||
|
||||
|
||||
BiomeProvider provider = new StandardBiomeProvider.StandardBiomeProviderBuilder((seed) -> new BiomePipeline.BiomePipelineBuilder(2)
|
||||
.addStage(s -> new MutatorStage(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(243))))
|
||||
.addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(2))))
|
||||
.addStage(s -> new MutatorStage(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(243))))
|
||||
.addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(2))))
|
||||
.addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(2))))
|
||||
.addStage(s -> new MutatorStage(new SmoothMutator(whiteNoise(3))))
|
||||
.addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(s -> new MutatorStage(new SmoothMutator(whiteNoise(6))))
|
||||
.addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(s -> new MutatorStage(new BorderMutator("OCEAN", "LAND", whiteNoise(1234), beachBiomes)))
|
||||
.addStage(s -> new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(s -> new MutatorStage(new SmoothMutator(whiteNoise(6))))
|
||||
.addStage(s -> new MutatorStage(new SmoothMutator(whiteNoise(6))))
|
||||
.build(source, seed), null).build(0);
|
||||
|
||||
|
||||
int size = 1000;
|
||||
|
||||
|
||||
BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
|
||||
System.out.println(size);
|
||||
|
||||
long s = System.nanoTime();
|
||||
for(int x = 0; x < size; x++) {
|
||||
for(int z = 0; z < size; z++) {
|
||||
image.setRGB(x, z, provider.getBiome(x, z).getColor());
|
||||
}
|
||||
}
|
||||
long e = System.nanoTime();
|
||||
|
||||
double time = e - s;
|
||||
time /= 1000000;
|
||||
System.out.println(time + "ms for " + size + "x" + size);
|
||||
|
||||
JFrame frame = new JFrame("TerraBiome Viewer");
|
||||
|
||||
|
||||
frame.setResizable(false);
|
||||
frame.add(new JLabel(new ImageIcon(image)));
|
||||
frame.pack();
|
||||
|
||||
|
||||
System.out.println("Done");
|
||||
|
||||
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
|
||||
frame.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
private static NoiseSampler whiteNoise(int seed) {
|
||||
FastNoiseLite noiseLite = new FastNoiseLite(seed);
|
||||
noiseLite.setNoiseType(FastNoiseLite.NoiseType.WhiteNoise);
|
||||
return noiseLite;
|
||||
}
|
||||
|
||||
private final static class TestBiome implements TerraBiome {
|
||||
private final Color color;
|
||||
private final Set<String> tags;
|
||||
|
||||
|
||||
private TestBiome(Color color, String... tags) {
|
||||
this.color = color;
|
||||
this.tags = Arrays.stream(tags).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProbabilityCollection<Biome> getVanillaBiomes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generator getGenerator(World w) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor() {
|
||||
return color.getRGB();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,13 +24,18 @@ import com.dfsek.terra.config.PluginConfig;
|
||||
import com.dfsek.terra.config.fileloaders.FolderLoader;
|
||||
import com.dfsek.terra.config.lang.Language;
|
||||
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
|
||||
import com.dfsek.terra.config.loaders.config.BufferedImageLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.BiomeProviderBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.BiomePipelineTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.ImageProviderTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.SingleBiomeProviderTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.templates.AbstractableTemplate;
|
||||
import com.dfsek.terra.debug.DebugLogger;
|
||||
import com.dfsek.terra.registry.BiomeRegistry;
|
||||
import com.dfsek.terra.registry.ConfigRegistry;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
import com.dfsek.terra.registry.config.NormalizerRegistry;
|
||||
import com.dfsek.terra.world.TerraWorld;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -141,12 +146,16 @@ public class DistributionTest {
|
||||
|
||||
BiomeProviderTemplate template = new BiomeProviderTemplate();
|
||||
ConfigLoader pipeLoader = new ConfigLoader()
|
||||
.registerLoader(BiomeProvider.BiomeProviderBuilder.class, new BiomeProviderBuilderLoader(MAIN, biomeRegistry, folderLoader))
|
||||
.registerLoader(BiomeProvider.BiomeProviderBuilder.class, new BiomeProviderBuilderLoader())
|
||||
.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader())
|
||||
.registerLoader(TerraBiome.class, biomeRegistry);
|
||||
.registerLoader(TerraBiome.class, biomeRegistry)
|
||||
.registerLoader(BufferedImage.class, new BufferedImageLoader(folderLoader))
|
||||
.registerLoader(SingleBiomeProviderTemplate.class, () -> new SingleBiomeProviderTemplate(biomeRegistry))
|
||||
.registerLoader(BiomePipelineTemplate.class, () -> new BiomePipelineTemplate(biomeRegistry, MAIN))
|
||||
.registerLoader(ImageProviderTemplate.class, () -> new ImageProviderTemplate(biomeRegistry));
|
||||
new GenericLoaders(null).register(pipeLoader);
|
||||
|
||||
pipeLoader.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader());
|
||||
pipeLoader.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader(new NormalizerRegistry()));
|
||||
|
||||
pipeLoader.load(template, folderLoader.get("pack.yml"));
|
||||
return template.getBiomeProviderBuilder().build(seed);
|
||||
|
||||
@@ -48,7 +48,7 @@ public class ImageTest {
|
||||
};
|
||||
folderLoader.open("biomes", ".yml").then(inputStreams -> ConfigPack.buildAll((template, main) -> template, biomeRegistry, loader.load(inputStreams, TestBiome::new), null));
|
||||
|
||||
return new ImageBiomeProvider(biomeRegistry, ImageIO.read(ImageTest.class.getResourceAsStream("/map.jpg")), 1);
|
||||
return new ImageBiomeProvider(biomeRegistry, ImageIO.read(ImageTest.class.getResourceAsStream("/map.jpg")), 1, ImageBiomeProvider.Align.CENTER);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.dfsek.terra.config.fileloaders.FolderLoader;
|
||||
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
|
||||
import com.dfsek.terra.config.loaders.config.BufferedImageLoader;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
|
||||
import com.dfsek.terra.registry.config.NormalizerRegistry;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -96,7 +97,7 @@ public class NoiseTool {
|
||||
FolderLoader folderLoader = new FolderLoader(Paths.get("./"));
|
||||
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
loader.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader())
|
||||
loader.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader(new NormalizerRegistry()))
|
||||
.registerLoader(BufferedImage.class, new BufferedImageLoader(folderLoader))
|
||||
.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader());
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class TerraCommand extends Command {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "com/dfsek/terra";
|
||||
return "terra";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,13 +9,14 @@ import com.dfsek.terra.api.util.FastRandom;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.registry.TreeRegistry;
|
||||
import com.dfsek.terra.registry.config.TreeRegistry;
|
||||
import com.dfsek.terra.world.TerraWorld;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeType;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
|
||||
@@ -40,7 +41,7 @@ public class CommonListener implements Listener {
|
||||
.add(TreeType.SWAMP, "SWAMP_OAK"))
|
||||
.addTransform(TreeType::toString).build();
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onSaplingGrow(StructureGrowEvent e) {
|
||||
if(e.isCancelled()) return;
|
||||
World bukkit = BukkitAdapter.adapt(e.getWorld());
|
||||
|
||||
@@ -34,7 +34,7 @@ public class TerraBiomeSource extends BiomeSource {
|
||||
super(biomes.stream().collect(Collectors.toList()));
|
||||
this.biomeRegistry = biomes;
|
||||
this.seed = seed;
|
||||
this.grid = pack.getTemplate().getProviderBuilder().build(seed);
|
||||
this.grid = pack.getBiomeProviderBuilder().build(seed);
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user