Merge branch 'biome' into asmparser

# Conflicts:
#	platforms/bukkit/build.gradle.kts
This commit is contained in:
dfsek
2021-02-06 22:28:53 -07:00
32 changed files with 781 additions and 182 deletions

View File

@@ -1,6 +1,6 @@
import com.dfsek.terra.getGitHash
val versionObj = Version("3", "2", "0", true)
val versionObj = Version("4", "0", "0", true)
allprojects {
version = versionObj

View File

@@ -1,4 +0,0 @@
colors:
- 0x000000: 20
- 0xffffff: 3
enable: false

View File

@@ -1,10 +0,0 @@
package com.dfsek.terra.api.math.parsii.defined;
import com.dfsek.terra.api.util.seeded.SeededBuilder;
public class DefinedFunctionTemplate implements SeededBuilder<UserDefinedFunction> {
@Override
public UserDefinedFunction apply(Long aLong) {
return null;
}
}

View File

@@ -65,7 +65,7 @@ public class Vector2 implements Cloneable {
/**
* Add this vector to another.
*
* @param other Vector to increment
* @param other Vector to add
* @return Mutated vector, for chaining.
*/
public Vector2 add(Vector2 other) {

View File

@@ -9,7 +9,7 @@ public interface BiomeGrid extends Handle {
*
* @param x - 0-15
* @param z - 0-15
* @return TerraBiome value
* @return Biome value
*/
@NotNull
Biome getBiome(int x, int z);
@@ -20,7 +20,7 @@ public interface BiomeGrid extends Handle {
* @param x - 0-15
* @param y - 0-255
* @param z - 0-15
* @return TerraBiome value
* @return Biome value
*/
@NotNull
Biome getBiome(int x, int y, int z);
@@ -30,7 +30,7 @@ public interface BiomeGrid extends Handle {
*
* @param x - 0-15
* @param z - 0-15
* @param bio - TerraBiome value
* @param bio - Biome value
*/
void setBiome(int x, int z, @NotNull Biome bio);
@@ -40,7 +40,7 @@ public interface BiomeGrid extends Handle {
* @param x - 0-15
* @param y - 0-255
* @param z - 0-15
* @param bio - TerraBiome value
* @param bio - Biome value
*/
void setBiome(int x, int y, int z, @NotNull Biome bio);
}

View File

@@ -44,9 +44,9 @@ import java.util.concurrent.ExecutionException;
public class StructureScript {
private final Block block;
private final String id;
String tempID;
private final Cache<Location, StructureBuffer> cache;
private final TerraPlugin main;
String tempID;
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, SamplerCache cache) throws ParseException {
Parser parser;
@@ -143,14 +143,12 @@ public class StructureScript {
}
private boolean applyBlock(TerraImplementationArguments arguments) {
synchronized(block) {
try {
return !block.apply(arguments).getLevel().equals(Block.ReturnLevel.FAIL);
} catch(RuntimeException e) {
main.getLogger().severe("Failed to generate structure at " + arguments.getBuffer().getOrigin() + ": " + e.getMessage());
main.getDebugLogger().stack(e);
return false;
}
try {
return !block.apply(arguments).getLevel().equals(Block.ReturnLevel.FAIL);
} catch(RuntimeException e) {
main.getLogger().severe("Failed to generate structure at " + arguments.getBuffer().getOrigin() + ": " + e.getMessage());
main.getDebugLogger().stack(e);
return false;
}
}
}

View File

@@ -0,0 +1,38 @@
package com.dfsek.terra.api.world.carving;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.platform.world.World;
import net.jafama.FastMath;
import java.util.Random;
import java.util.function.BiConsumer;
public abstract class Carver {
private final int minY;
private final int maxY;
private final double sixtyFourSq = FastMath.pow(64, 2);
private int carvingRadius = 4;
public Carver(int minY, int maxY) {
this.minY = minY;
this.maxY = maxY;
}
public abstract void carve(int chunkX, int chunkZ, World w, BiConsumer<Vector3, CarvingType> consumer);
public int getCarvingRadius() {
return carvingRadius;
}
public void setCarvingRadius(int carvingRadius) {
this.carvingRadius = carvingRadius;
}
public abstract Worm getWorm(long seed, Vector3 l);
public abstract boolean isChunkCarved(World w, int chunkX, int chunkZ, Random r);
public enum CarvingType {
CENTER, WALL, TOP, BOTTOM
}
}

View File

@@ -0,0 +1,119 @@
package com.dfsek.terra.api.world.carving;
import com.dfsek.terra.api.math.vector.Vector3;
import net.jafama.FastMath;
import java.util.Random;
import java.util.function.BiConsumer;
public abstract class Worm {
private final Random r;
private final Vector3 origin;
private final Vector3 running;
private final int length;
private int topCut = 0;
private int bottomCut = 0;
private int[] radius = new int[] {0, 0, 0};
public Worm(int length, Random r, Vector3 origin) {
this.r = r;
this.length = length;
this.origin = origin;
this.running = origin;
}
public void setBottomCut(int bottomCut) {
this.bottomCut = bottomCut;
}
public void setTopCut(int topCut) {
this.topCut = topCut;
}
public Vector3 getOrigin() {
return origin;
}
public int getLength() {
return length;
}
public Vector3 getRunning() {
return running;
}
public WormPoint getPoint() {
return new WormPoint(running, radius, topCut, bottomCut);
}
public int[] getRadius() {
return radius;
}
public void setRadius(int[] radius) {
this.radius = radius;
}
public Random getRandom() {
return r;
}
public abstract void step();
public static class WormPoint {
private final Vector3 origin;
private final int topCut;
private final int bottomCut;
private final int[] rad;
public WormPoint(Vector3 origin, int[] rad, int topCut, int bottomCut) {
this.origin = origin;
this.rad = rad;
this.topCut = topCut;
this.bottomCut = bottomCut;
}
private static double ellipseEquation(int x, int y, int z, double xr, double yr, double zr) {
return (FastMath.pow2(x) / FastMath.pow2(xr + 0.5D)) + (FastMath.pow2(y) / FastMath.pow2(yr + 0.5D)) + (FastMath.pow2(z) / FastMath.pow2(zr + 0.5D));
}
public Vector3 getOrigin() {
return origin;
}
public int getRadius(int index) {
return rad[index];
}
public void carve(int chunkX, int chunkZ, BiConsumer<Vector3, Carver.CarvingType> consumer) {
int xRad = getRadius(0);
int yRad = getRadius(1);
int zRad = getRadius(2);
int originX = (chunkX << 4);
int originZ = (chunkZ << 4);
for(int x = -xRad - 1; x <= xRad + 1; x++) {
if(!(FastMath.floorDiv(origin.getBlockX() + x, 16) == chunkX)) continue;
for(int z = -zRad - 1; z <= zRad + 1; z++) {
if(!(FastMath.floorDiv(origin.getBlockZ() + z, 16) == chunkZ)) continue;
for(int y = -yRad - 1; y <= yRad + 1; y++) {
Vector3 position = origin.clone().add(new Vector3(x, y, z));
if(position.getY() < 0 || position.getY() > 255) continue;
double eq = ellipseEquation(x, y, z, xRad, yRad, zRad);
if(eq <= 1 &&
y >= -yRad - 1 + bottomCut && y <= yRad + 1 - topCut) {
consumer.accept(new Vector3(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ), Carver.CarvingType.CENTER);
} else if(eq <= 1.5) {
Carver.CarvingType type = Carver.CarvingType.WALL;
if(y <= -yRad - 1 + bottomCut) {
type = Carver.CarvingType.BOTTOM;
} else if(y >= yRad + 1 - topCut) {
type = Carver.CarvingType.TOP;
}
consumer.accept(new Vector3(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ), type);
}
}
}
}
}
}
}

View File

@@ -9,8 +9,7 @@ import com.dfsek.terra.api.world.biome.Generator;
import java.util.Set;
/**
* Interface to be implemented by a custom generator's TerraBiome enum.<br>
* Represents a custom biome, and contains methods to retrieve information about each type.
* Represents a custom biome
*/
public interface TerraBiome {

View File

@@ -18,14 +18,14 @@ public class StandardBiomeProvider implements BiomeProvider {
private final LoadingCache<Vector2, BiomeHolder> holderCache;
private final BiomePipeline pipeline;
private int resolution = 1;
private final NoiseSampler xSampler;
private final NoiseSampler zSampler;
private final int noiseAmp;
private final NoiseSampler mutator;
private final double noiseAmp;
private final int seed;
protected StandardBiomeProvider(BiomePipeline pipeline, TerraPlugin main, NoiseSampler xSampler, NoiseSampler zSampler, int noiseAmp) {
this.xSampler = xSampler;
this.zSampler = zSampler;
protected StandardBiomeProvider(BiomePipeline pipeline, TerraPlugin main, NoiseSampler mutator, double noiseAmp, int seed) {
this.mutator = mutator;
this.noiseAmp = noiseAmp;
this.seed = seed;
holderCache = CacheBuilder.newBuilder()
.maximumSize(main == null ? 32 : main.getTerraConfig().getProviderCache())
.build(
@@ -41,8 +41,14 @@ public class StandardBiomeProvider implements BiomeProvider {
@Override
public TerraBiome getBiome(int x, int z) {
x = FastMath.floorToInt(FastMath.floorDiv(x, resolution) + xSampler.getNoise(x, z) * noiseAmp);
z = FastMath.floorToInt(FastMath.floorDiv(z, resolution) + zSampler.getNoise(x, z) * noiseAmp);
x += mutator.getNoiseSeeded(seed, x, z) * noiseAmp;
z += mutator.getNoiseSeeded(1 + seed, x, z) * noiseAmp;
x = FastMath.floorToInt(FastMath.floorDiv(x, resolution));
z = FastMath.floorToInt(FastMath.floorDiv(z, resolution));
int fdX = FastMath.floorDiv(x, pipeline.getSize());
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
return holderCache.getUnchecked(new Vector2(fdX, fdZ)).getBiome(x - fdX * pipeline.getSize(), z - fdZ * pipeline.getSize());
@@ -64,7 +70,7 @@ public class StandardBiomeProvider implements BiomeProvider {
private final ExceptionalFunction<Long, BiomePipeline> pipelineBuilder;
private final TerraPlugin main;
private int resolution = 1;
private int noiseAmp = 2;
private double noiseAmp = 2;
private NoiseSeeded builder;
public StandardBiomeProviderBuilder(ExceptionalFunction<Long, BiomePipeline> pipelineBuilder, TerraPlugin main) {
@@ -80,14 +86,14 @@ public class StandardBiomeProvider implements BiomeProvider {
this.builder = builder;
}
public void setNoiseAmp(int noiseAmp) {
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), builder.apply((seed + 1)), noiseAmp);
StandardBiomeProvider provider = new StandardBiomeProvider(pipelineBuilder.apply(seed), main, builder.apply(seed), noiseAmp, (int) seed);
provider.setResolution(resolution);
return provider;
} catch(ConfigException e) {

View File

@@ -0,0 +1,59 @@
package com.dfsek.terra.carving;
import com.dfsek.terra.api.core.TerraPlugin;
import com.dfsek.terra.api.math.MathUtil;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.util.FastRandom;
import com.dfsek.terra.api.util.GlueList;
import com.dfsek.terra.api.world.carving.Worm;
import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.provider.BiomeProvider;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Random;
public class CarverCache {
private final LoadingCache<Long, List<Worm.WormPoint>> cache;
private final UserDefinedCarver carver;
public CarverCache(World w, TerraPlugin main, UserDefinedCarver carver) {
this.carver = carver;
cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getCarverCacheSize())
.build(new CacheLoader<Long, List<Worm.WormPoint>>() {
@Override
public List<Worm.WormPoint> load(@NotNull Long key) {
int chunkX = (int) (key >> 32);
int chunkZ = (int) key.longValue();
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<>();
for(int i = 0; i < carving.getLength(); i++) {
carving.step();
TerraBiome biome = provider.getBiome(carving.getRunning().toLocation(w));
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(CarverCache.this.carver)) { // Stop if we enter a biome this carver is not present in
return new GlueList<>();
}
points.add(carving.getPoint());
}
return points;
}
return new GlueList<>();
}
});
}
public List<Worm.WormPoint> getPoints(int chunkX, int chunkZ) {
return cache.getUnchecked(MathUtil.squash(chunkX, chunkZ));
}
}

View File

@@ -0,0 +1,54 @@
package com.dfsek.terra.carving;
import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.MaterialData;
import com.dfsek.terra.util.MaterialSet;
import java.util.Map;
import java.util.TreeMap;
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
public class CarverPalette {
private final boolean blacklist;
private final MaterialSet replace;
private final TreeMap<Integer, ProbabilityCollection<BlockData>> map = new TreeMap<>();
private ProbabilityCollection<BlockData>[] layers;
public CarverPalette(MaterialSet replaceable, boolean blacklist) {
this.blacklist = blacklist;
this.replace = replaceable;
}
public CarverPalette add(ProbabilityCollection<BlockData> collection, int y) {
map.put(y, collection);
return this;
}
public ProbabilityCollection<BlockData> get(int y) {
return layers[y];
}
public boolean canReplace(MaterialData material) {
return blacklist != replace.contains(material);
}
/**
* Build the palette to an array.
*/
public void build() {
int size = map.lastKey() + 1;
layers = new ProbabilityCollection[size];
for(int y = 0; y < size; y++) {
ProbabilityCollection<BlockData> d = null;
for(Map.Entry<Integer, ProbabilityCollection<BlockData>> e : map.entrySet()) {
if(e.getKey() >= y) {
d = e.getValue();
break;
}
}
if(d == null) throw new IllegalArgumentException("Null collection at Y=" + y);
layers[y] = d;
}
}
}

View File

@@ -0,0 +1,213 @@
package com.dfsek.terra.carving;
import com.dfsek.terra.api.core.TerraPlugin;
import com.dfsek.terra.api.math.Range;
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.math.vector.Vector3;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.util.FastRandom;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.carving.Carver;
import com.dfsek.terra.api.world.carving.Worm;
import com.dfsek.terra.biome.UserDefinedBiome;
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.
private final double[] mutate; // 0, 1, 2 = x, y, z. 3 = radius.
private final Range length;
private final long hash;
private final int topCut;
private final int bottomCut;
private final CarverTemplate config;
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;
private double step = 2;
private Range recalc = new Range(8, 10);
private double recalcMagnitude = 3;
public UserDefinedCarver(Range height, Range length, double[] start, double[] mutate, List<String> radii, Scope parent, long hash, int topCut, int bottomCut, CarverTemplate config, TerraPlugin main, Map<String, NoiseSeeded> functions, Map<String, FunctionTemplate> definedFunctions) throws ParseException {
super(height.getMin(), height.getMax());
this.length = length;
this.start = start;
this.mutate = mutate;
this.hash = hash;
this.topCut = topCut;
this.bottomCut = bottomCut;
this.config = config;
this.main = main;
Parser p = new Parser();
functions.forEach((id, noise) -> {
switch(noise.getDimensions()) {
case 2:
p.registerFunction(id, new NoiseFunction2(hash, noise));
break;
case 3:
p.registerFunction(id, new NoiseFunction3(hash, noise));
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));
}
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");
xRad = p.parse(radii.get(0), s);
yRad = p.parse(radii.get(1), s);
zRad = p.parse(radii.get(2), s);
}
@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;
}
public void setStep(double step) {
this.step = step;
}
public void setRecalc(Range recalc) {
this.recalc = recalc;
}
@Override
public void carve(int chunkX, int chunkZ, World w, BiConsumer<Vector3, CarvingType> consumer) {
synchronized(cacheMap) {
CarverCache cache = cacheMap.computeIfAbsent(w, world -> new CarverCache(world, main, this));
int carvingRadius = getCarvingRadius();
for(int x = chunkX - carvingRadius; x <= chunkX + carvingRadius; x++) {
for(int z = chunkZ - carvingRadius; z <= chunkZ + carvingRadius; z++) {
cache.getPoints(x, z).forEach(point -> {
Vector3 origin = point.getOrigin();
if(FastMath.floorDiv(origin.getBlockX(), 16) != chunkX && FastMath.floorDiv(origin.getBlockZ(), 16) != chunkZ) // We only want to carve this chunk.
return;
point.carve(chunkX, chunkZ, consumer);
});
}
}
}
}
public void setRecalcMagnitude(double recalcMagnitude) {
this.recalcMagnitude = recalcMagnitude;
}
@Override
public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) {
BiomeTemplate conf = ((UserDefinedBiome) main.getWorld(w).getBiomeProvider().getBiome((chunkX << 4) + 8, (chunkZ << 4) + 8)).getConfig();
if(conf.getCarvers().get(this) != null) {
return new FastRandom(random.nextLong() + hash).nextInt(100) < conf.getCarvers().get(this);
}
return false;
}
public CarverTemplate getConfig() {
return config;
}
private class UserDefinedWorm extends Worm {
private final Vector3 direction;
private int steps;
private int nextDirection = 0;
private double[] currentRotation = new double[3];
public UserDefinedWorm(int length, Random r, Vector3 origin, int topCut, int bottomCut) {
super(length, r, origin);
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())});
}
@Override
public WormPoint getPoint() {
return new WormPoint(getRunning().clone(), getRadius(), config.getCutTop(), config.getCutBottom());
}
@Override
public synchronized void step() {
if(steps == nextDirection) {
direction.rotateAroundX(FastMath.toRadians((getRandom().nextGaussian()) * mutate[0] * recalcMagnitude));
direction.rotateAroundY(FastMath.toRadians((getRandom().nextGaussian()) * mutate[1] * recalcMagnitude));
direction.rotateAroundZ(FastMath.toRadians((getRandom().nextGaussian()) * mutate[2] * recalcMagnitude));
currentRotation = new double[] {(getRandom().nextGaussian()) * mutate[0],
(getRandom().nextGaussian()) * mutate[1],
(getRandom().nextGaussian()) * mutate[2]};
nextDirection += recalc.get(getRandom());
}
steps++;
position.setValue(steps);
setRadius(new int[] {(int) (xRad.evaluate()), (int) (yRad.evaluate()), (int) (zRad.evaluate())});
direction.rotateAroundX(FastMath.toRadians(currentRotation[0] * mutate[0]));
direction.rotateAroundY(FastMath.toRadians(currentRotation[1] * mutate[1]));
direction.rotateAroundZ(FastMath.toRadians(currentRotation[2] * mutate[2]));
getRunning().add(direction);
}
}
}

View File

@@ -14,6 +14,8 @@ 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.carving.CarverPalette;
import com.dfsek.terra.config.loaders.LinkedHashMapLoader;
import com.dfsek.terra.config.loaders.MaterialSetLoader;
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.RangeLoader;
@@ -35,6 +37,7 @@ 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.palette.CarverPaletteLoader;
import com.dfsek.terra.config.loaders.palette.PaletteHolderLoader;
import com.dfsek.terra.config.loaders.palette.PaletteLayerLoader;
import com.dfsek.terra.util.MaterialSet;
@@ -45,6 +48,8 @@ import com.dfsek.terra.world.population.items.ores.OreConfig;
import com.dfsek.terra.world.population.items.ores.OreHolder;
import com.dfsek.terra.world.population.items.tree.TreeLayer;
import java.util.LinkedHashMap;
public class GenericLoaders implements LoaderRegistrar {
private final TerraPlugin main;
@@ -79,6 +84,8 @@ public class GenericLoaders implements LoaderRegistrar {
.registerLoader(BorderMutatorTemplate.class, BorderMutatorTemplate::new)
.registerLoader(BorderListMutatorTemplate.class, BorderListMutatorTemplate::new)
.registerLoader(FunctionTemplate.class, FunctionTemplate::new)
.registerLoader(LinkedHashMap.class, new LinkedHashMapLoader())
.registerLoader(CarverPalette.class, new CarverPaletteLoader())
.registerLoader(ImageSampler.Channel.class, (t, object, cf) -> ImageSampler.Channel.valueOf((String) object))
.registerLoader(ExpanderStage.Type.class, (t, object, cf) -> ExpanderStage.Type.valueOf((String) object))
.registerLoader(MutatorStage.Type.class, (t, object, cf) -> MutatorStage.Type.valueOf((String) object))

View File

@@ -9,7 +9,7 @@ import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.templates.BiomeTemplate;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class BiomeFactory implements TerraFactory<BiomeTemplate, TerraBiome> {
@@ -27,7 +27,7 @@ public class BiomeFactory implements TerraFactory<BiomeTemplate, TerraBiome> {
generatorBuilder.setCarvingEquation(template.getCarvingEquation());
generatorBuilder.setNoiseBuilderMap(pack.getTemplate().getNoiseBuilderMap());
Map<String, FunctionTemplate> functions = new HashMap<>(pack.getTemplate().getFunctions());
Map<String, FunctionTemplate> functions = new LinkedHashMap<>(pack.getTemplate().getFunctions()); // linked map to preserve order.
functions.putAll(template.getFunctions());
generatorBuilder.setFunctionTemplateMap(functions);

View File

@@ -0,0 +1,37 @@
package com.dfsek.terra.config.factories;
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;
public class CarverFactory implements TerraFactory<CarverTemplate, UserDefinedCarver> {
private final ConfigPack pack;
public CarverFactory(ConfigPack pack) {
this.pack = pack;
}
@Override
public UserDefinedCarver build(CarverTemplate config, TerraPlugin main) throws LoadException {
double[] start = new double[] {config.getStartX(), config.getStartY(), config.getStartZ()};
double[] mutate = new double[] {config.getMutateX(), config.getMutateY(), config.getMutateZ()};
List<String> radius = Arrays.asList(config.getRadMX(), config.getRadMY(), config.getRadMZ());
long hash = MathUtil.hashToLong(config.getID());
UserDefinedCarver carver;
try {
carver = new UserDefinedCarver(config.getHeight(), config.getLength(), start, mutate, radius, pack.getVarScope(), hash, config.getCutTop(), config.getCutBottom(), config, main, pack.getTemplate().getNoiseBuilderMap(), pack.getTemplate().getFunctions());
} catch(ParseException e) {
throw new LoadException("Unable to parse radius equations", e);
}
carver.setRecalc(config.getRecalc());
carver.setRecalcMagnitude(config.getRecaclulateMagnitude());
return carver;
}
}

View File

@@ -0,0 +1,28 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapLoader implements TypeLoader<LinkedHashMap<Object, Object>> {
@Override
public LinkedHashMap<Object, Object> load(Type t, Object c, ConfigLoader loader) throws LoadException {
Map<String, Object> config = (Map<String, Object>) c;
LinkedHashMap<Object, Object> map = new LinkedHashMap<>();
if(t instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) t;
Type key = pType.getActualTypeArguments()[0];
Type value = pType.getActualTypeArguments()[1];
for(Map.Entry<String, Object> entry : config.entrySet()) {
map.put(loader.loadType(key, entry.getKey()), loader.loadType(value, entry.getValue()));
}
} else throw new LoadException("Unable to load config");
return map;
}
}

View File

@@ -69,7 +69,7 @@ public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProvider.Biom
builder.setResolution(resolution);
if(map.containsKey("blend")) {
Map<String, Object> blend = (Map<String, Object>) map.get("blend");
if(blend.containsKey("amplitude")) builder.setNoiseAmp(Integer.parseInt(blend.get("amplitude").toString()));
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")));
}

View File

@@ -0,0 +1,33 @@
package com.dfsek.terra.config.loaders.palette;
import com.dfsek.tectonic.config.Configuration;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.math.ProbabilityCollection;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.carving.CarverPalette;
import com.dfsek.terra.config.loaders.Types;
import com.dfsek.terra.util.MaterialSet;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
@SuppressWarnings("unchecked")
public class CarverPaletteLoader implements TypeLoader<CarverPalette> {
@Override
public CarverPalette load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
Configuration configuration = new Configuration((Map<String, Object>) o);
CarverPalette palette = new CarverPalette((MaterialSet) configLoader.loadType(MaterialSet.class, configuration.get("replace")), (Boolean) configuration.get("replace-blacklist"));
for(Map<String, Object> map : (List<Map<String, Object>>) configuration.get("layers")) {
ProbabilityCollection<BlockData> layer = (ProbabilityCollection<BlockData>) configLoader.loadType(Types.BLOCK_DATA_PROBABILITY_COLLECTION_TYPE, map.get("materials"));
palette.add(layer, (Integer) map.get("y"));
}
palette.build();
return palette;
}
}

View File

@@ -15,8 +15,10 @@ import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.tree.Tree;
import com.dfsek.terra.biome.TerraBiome;
import com.dfsek.terra.biome.provider.BiomeProvider;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.exception.FileMissingException;
import com.dfsek.terra.config.factories.BiomeFactory;
import com.dfsek.terra.config.factories.CarverFactory;
import com.dfsek.terra.config.factories.FloraFactory;
import com.dfsek.terra.config.factories.OreFactory;
import com.dfsek.terra.config.factories.PaletteFactory;
@@ -31,12 +33,14 @@ import com.dfsek.terra.config.loaders.config.BufferedImageLoader;
import com.dfsek.terra.config.loaders.config.biome.BiomeProviderBuilderLoader;
import com.dfsek.terra.config.templates.AbstractableTemplate;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.config.templates.CarverTemplate;
import com.dfsek.terra.config.templates.FloraTemplate;
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;
@@ -82,6 +86,8 @@ public class ConfigPack implements LoaderRegistrar {
private final ScriptRegistry scriptRegistry = new ScriptRegistry();
private final LootRegistry lootRegistry = new LootRegistry();
private final CarverRegistry carverRegistry = new CarverRegistry();
private final AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader();
private final ConfigLoader selfLoader = new ConfigLoader();
private final Scope varScope = new Scope();
@@ -180,14 +186,13 @@ public class ConfigPack implements LoaderRegistrar {
}).close();
loader
.open("carving", ".yml").then(streams -> buildAll(new CarverFactory(this), carverRegistry, abstractConfigLoader.load(streams, CarverTemplate::new), main)).close()
.open("palettes", ".yml").then(streams -> buildAll(new PaletteFactory(), paletteRegistry, abstractConfigLoader.load(streams, PaletteTemplate::new), main)).close()
.open("ores", ".yml").then(streams -> buildAll(new OreFactory(), oreRegistry, abstractConfigLoader.load(streams, OreTemplate::new), main)).close()
.open("structures/trees", ".yml").then(streams -> buildAll(new TreeFactory(), treeRegistry, abstractConfigLoader.load(streams, TreeTemplate::new), main)).close()
.open("structures/structures", ".yml").then(streams -> buildAll(new StructureFactory(), structureRegistry, abstractConfigLoader.load(streams, StructureTemplate::new), main)).close()
.open("flora", ".yml").then(streams -> buildAll(new FloraFactory(), floraRegistry, abstractConfigLoader.load(streams, FloraTemplate::new), main)).close()
.open("biomes", ".yml").then(streams -> buildAll(new BiomeFactory(this), biomeRegistry, abstractConfigLoader.load(streams, () -> new BiomeTemplate(this, main)), main)).close();
main.packPostLoadCallback(this);
LangUtil.log("config-pack.loaded", Level.INFO, template.getID(), String.valueOf((System.nanoTime() - start) / 1000000D), template.getAuthor(), template.getVersion());
}
@@ -240,6 +245,7 @@ public class ConfigPack implements LoaderRegistrar {
.registerLoader(StructureScript.class, scriptRegistry)
.registerLoader(TerraStructure.class, structureRegistry)
.registerLoader(LootTable.class, lootRegistry)
.registerLoader(UserDefinedCarver.class, carverRegistry)
.registerLoader(BufferedImage.class, new BufferedImageLoader(loader))
.registerLoader(BiomeProvider.BiomeProviderBuilder.class, new BiomeProviderBuilderLoader(main, biomeRegistry, loader));
}
@@ -255,4 +261,8 @@ public class ConfigPack implements LoaderRegistrar {
public SamplerCache getSamplerCache() {
return samplerCache;
}
public Set<UserDefinedCarver> getCarvers() {
return carverRegistry.entries();
}
}

View File

@@ -8,6 +8,7 @@ import com.dfsek.terra.biome.provider.BiomeProvider;
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@SuppressWarnings({"unused", "FieldMayBeFinal"})
@@ -22,9 +23,13 @@ public class ConfigPackTemplate implements ConfigTemplate {
@Default
private Map<String, Double> variables = new HashMap<>();
@Value("beta.carving")
@Default
private boolean betaCarvers = false;
@Value("functions")
@Default
private Map<String, FunctionTemplate> functions = new HashMap<>();
private LinkedHashMap<String, FunctionTemplate> functions = new LinkedHashMap<>();
@Value("structures.locatable")
@Default
@@ -34,22 +39,6 @@ public class ConfigPackTemplate implements ConfigTemplate {
@Default
private int elevationBlend = 4;
@Value("erode.enable")
@Default
private boolean erode = false;
@Value("erode.frequency")
@Default
private double erodeFreq = 0.001D;
@Value("erode.threshold")
@Default
private double erodeThresh = 0.0015D;
@Value("erode.octaves")
@Default
private int erodeOctaves = 5;
@Value("vanilla.mobs")
@Default
private boolean vanillaMobs = true;
@@ -129,22 +118,6 @@ public class ConfigPackTemplate implements ConfigTemplate {
return variables;
}
public boolean isErode() {
return erode;
}
public double getErodeFreq() {
return erodeFreq;
}
public double getErodeThresh() {
return erodeThresh;
}
public int getErodeOctaves() {
return erodeOctaves;
}
public int getElevationBlend() {
return elevationBlend;
}
@@ -152,4 +125,8 @@ public class ConfigPackTemplate implements ConfigTemplate {
public Map<String, String> getLocatable() {
return locatable;
}
public boolean doBetaCarvers() {
return betaCarvers;
}
}

View File

@@ -22,6 +22,7 @@ import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.palette.SinglePalette;
import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
import com.dfsek.terra.config.loaders.config.sampler.templates.FastNoiseTemplate;
import com.dfsek.terra.config.pack.ConfigPack;
@@ -31,6 +32,7 @@ import com.dfsek.terra.world.population.items.ores.OreHolder;
import com.dfsek.terra.world.population.items.tree.TreeLayer;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -55,9 +57,9 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
@Value("functions")
@Default
@Abstractable
private Map<String, FunctionTemplate> functions = new HashMap<>();
private LinkedHashMap<String, FunctionTemplate> functions = new LinkedHashMap<>();
@Value("carving.equation")
@Value("beta.carving.equation")
@Abstractable
@Default
private String carvingEquation = "0";
@@ -183,10 +185,19 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
@Abstractable
private Set<String> tags;
@Value("carving")
@Abstractable
@Default
private Map<UserDefinedCarver, Integer> carvers = new HashMap<>();
public Set<String> getTags() {
return tags;
}
public Map<UserDefinedCarver, Integer> getCarvers() {
return carvers;
}
public Map<String, FunctionTemplate> getFunctions() {
return functions;
}
@@ -340,7 +351,7 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
pack.getTemplate().getNoiseBuilderMap().forEach((id, builder) -> tester.registerFunction(id, new BlankFunction(builder.getDimensions()))); // Register dummy functions
Map<String, FunctionTemplate> testFunctions = new HashMap<>(pack.getTemplate().getFunctions());
Map<String, FunctionTemplate> testFunctions = new LinkedHashMap<>(pack.getTemplate().getFunctions());
testFunctions.putAll(functions);
for(Map.Entry<String, FunctionTemplate> entry : testFunctions.entrySet()) {
String id = entry.getKey();

View File

@@ -1,57 +0,0 @@
package com.dfsek.terra.debug.gui;
import com.dfsek.terra.api.core.TerraPlugin;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
public class DebugFrame extends JFrame implements ActionListener {
private static final long serialVersionUID = 9133084939622854303L;
private final int x;
private final int z;
private final BufferedImage img;
private final TerraPlugin main;
public DebugFrame(BufferedImage image, String s, TerraPlugin main) {
super(s);
this.x = image.getWidth();
this.z = image.getHeight();
this.img = image;
this.main = main;
new Timer(500, this).start();
}
@Override
public void paint(Graphics g) {
super.paintComponents(g);
/*
for(Player p : Bukkit.getOnlinePlayers()) {
int xp = (int) (((double) FastMath.floorMod(p.getLocation().getBlockX() - (img.getWidth() / 2), x) / x) * getWidth());
int zp = (int) (((double) FastMath.floorMod(p.getLocation().getBlockZ() - (img.getHeight() / 2), z) / z) * getHeight());
ImageLoader loader = main.getWorld(p.getWorld()).getConfig().getTemplate().getImageLoader();
if(loader != null && loader.getAlign().equals(ImageLoader.Align.NONE)) {
xp = (int) (((double) FastMath.floorMod(p.getLocation().getBlockX(), x) / x) * getWidth());
zp = (int) (((double) FastMath.floorMod(p.getLocation().getBlockZ(), z) / z) * getHeight());
}
String str = ((UserDefinedBiome) main.getWorld(p.getWorld()).getGrid().getBiome(p.getLocation(), GenerationPhase.POPULATE)).getID();
g.setColor(new Color(255, 255, 255, 128));
g.fillRect(xp + 13, zp - 13, (int) (8 + 8.25 * str.length()), 33);
g.setColor(Color.BLACK);
g.drawString(p.getName(), xp + 15, zp);
g.drawString(str, xp + 15, zp + 15);
g.fillOval(xp, zp, 10, 10);
g.setColor(Color.RED);
g.fillOval(xp + 3, zp + 3, 5, 5);
}
*/
}
@Override
public void actionPerformed(ActionEvent e) {
this.repaint();
}
}

View File

@@ -1,34 +0,0 @@
package com.dfsek.terra.debug.gui;
import com.dfsek.terra.api.core.TerraPlugin;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class DebugGUI extends Thread {
private final BufferedImage img;
private final TerraPlugin main;
public DebugGUI(BufferedImage img, TerraPlugin main) {
this.img = img;
this.main = main;
}
@Override
public void run() {
DebugFrame frame = new DebugFrame(img, "Image2Map DebugLogger GUI", main);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(1000, 1000);
frame.setResizable(false);
ImageIcon imageIcon = new ImageIcon(img.getScaledInstance(1000, 1000, Image.SCALE_SMOOTH));
JLabel jLabel = new JLabel();
jLabel.setIcon(imageIcon);
frame.getContentPane().add(jLabel, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

View File

@@ -0,0 +1,105 @@
package com.dfsek.terra.population;
import com.dfsek.terra.api.core.TerraPlugin;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.MaterialData;
import com.dfsek.terra.api.platform.handle.WorldHandle;
import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.templates.CarverTemplate;
import com.dfsek.terra.profiler.ProfileFuture;
import com.dfsek.terra.util.PopulationUtil;
import com.dfsek.terra.world.TerraWorld;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
public class CavePopulator implements TerraBlockPopulator {
private static final Map<MaterialData, BlockData> shiftStorage = new HashMap<>(); // Persist BlockData created for shifts, to avoid re-calculating each time.
private final TerraPlugin main;
public CavePopulator(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("try")
@Override
public void populate(@NotNull World world, @NotNull Chunk chunk) {
TerraWorld tw = main.getWorld(world);
WorldHandle handle = main.getWorldHandle();
BlockData AIR = handle.createBlockData("minecraft:air");
try(ProfileFuture ignored = tw.getProfiler().measure("CaveTime")) {
Random random = PopulationUtil.getRandom(chunk);
if(!tw.isSafe()) return;
ConfigPack config = tw.getConfig();
for(UserDefinedCarver c : config.getCarvers()) {
CarverTemplate template = c.getConfig();
Map<Location, MaterialData> shiftCandidate = new HashMap<>();
Set<Block> updateNeeded = new HashSet<>();
c.carve(chunk.getX(), chunk.getZ(), world, (v, type) -> {
Block b = chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ());
MaterialData m = handle.getType(b);
switch(type) {
case CENTER:
if(template.getInner().canReplace(m)) {
handle.setBlockData(b, template.getInner().get(v.getBlockY()).get(random), false);
if(template.getUpdate().contains(m)) updateNeeded.add(b);
if(template.getShift().containsKey(m)) shiftCandidate.put(b.getLocation(), m);
}
break;
case WALL:
if(template.getOuter().canReplace(m)) {
handle.setBlockData(b, template.getOuter().get(v.getBlockY()).get(random), false);
if(template.getUpdate().contains(m)) updateNeeded.add(b);
if(template.getShift().containsKey(m)) shiftCandidate.put(b.getLocation(), m);
}
break;
case TOP:
if(template.getTop().canReplace(m)) {
handle.setBlockData(b, template.getTop().get(v.getBlockY()).get(random), false);
if(template.getUpdate().contains(m)) updateNeeded.add(b);
if(template.getShift().containsKey(m)) shiftCandidate.put(b.getLocation(), m);
}
break;
case BOTTOM:
if(template.getBottom().canReplace(m)) {
handle.setBlockData(b, template.getBottom().get(v.getBlockY()).get(random), false);
if(template.getUpdate().contains(m)) updateNeeded.add(b);
if(template.getShift().containsKey(m)) shiftCandidate.put(b.getLocation(), m);
}
break;
}
});
for(Map.Entry<Location, MaterialData> entry : shiftCandidate.entrySet()) {
Location l = entry.getKey();
Location mut = l.clone();
MaterialData orig = handle.getType(l.getBlock());
do mut.subtract(0, 1, 0);
while(mut.getY() > 0 && handle.getType(mut.getBlock()).equals(orig));
try {
if(template.getShift().get(entry.getValue()).contains(mut.getBlock().getType())) {
handle.setBlockData(mut.getBlock(), shiftStorage.computeIfAbsent(entry.getValue(), MaterialData::createBlockData), false);
}
} catch(NullPointerException ignore) {
}
}
for(Block b : updateNeeded) {
BlockData orig = handle.getBlockData(b);
handle.setBlockData(b, AIR, false);
handle.setBlockData(b, orig, true);
}
}
}
}
}

View File

@@ -0,0 +1,6 @@
package com.dfsek.terra.registry;
import com.dfsek.terra.carving.UserDefinedCarver;
public class CarverRegistry extends TerraRegistry<UserDefinedCarver> {
}

View File

@@ -144,7 +144,9 @@ public class MasterChunkGenerator implements TerraChunkGenerator {
}
}
}
carver.carve(world, chunkX, chunkZ, chunk);
if(configPack.getTemplate().doBetaCarvers()) {
carver.carve(world, chunkX, chunkZ, chunk);
}
return chunk;
}
}

View File

@@ -96,9 +96,9 @@ val testWithPaper = task<JavaExec>(name = "testWithPaper") {
"-XX:InitiatingHeapOccupancyPercent=15", "-XX:G1MixedGCLiveThresholdPercent=90",
"-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:SurvivorRatio=32", "-XX:+PerfDisableSharedMem",
"-XX:MaxTenuringThreshold=1", "-Dusing.aikars.flags=https://mcflags.emc.gs",
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear", "-DASMDumpClasses=true")
maxHeapSize = "3G"
minHeapSize = "3G"
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear")
maxHeapSize = "4G"
minHeapSize = "4G"
//args = listOf("nogui")
workingDir = file("${testDir}/")
classpath = files("${testDir}/paper.jar")

View File

@@ -9,6 +9,7 @@ import com.dfsek.terra.bukkit.population.PopulationManager;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.bukkit.world.BukkitBiomeGrid;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.population.CavePopulator;
import com.dfsek.terra.profiler.DataType;
import com.dfsek.terra.profiler.Measurement;
import com.dfsek.terra.world.TerraWorld;
@@ -52,6 +53,7 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
popMan.attach(new OrePopulator(main));
popMan.attach(new TreePopulator(main));
popMan.attach(new FloraPopulator(main));
populators.add(new CavePopulator(main));
populators.add(new StructurePopulator(main));
populators.add(popMan);
}

View File

@@ -25,7 +25,7 @@ command:
biome-found: "Bioom geleë te (%1$s, %2$s)"
unable-to-locate: "Kan bioom nie opspoor nie."
invalid-radius: "Ongeldige radius: \"%s\""
invalid: "Ongeldige TerraBiome-ID: \"%s\""
invalid: "Ongeldige Biome-ID: \"%s\""
in: "Jy is in \"%s\""
ore:
main-menu:

View File

@@ -56,7 +56,7 @@ command:
gui:
main-menu:
- "-------------Terra/image/gui-------------"
- "raw - Öffnet eine GUI mit TerraBiome-Rohdaten"
- "raw - Öffnet eine GUI mit Biome-Rohdaten"
- "step - Daten erneut rendern, um Ränder deutlicher darzustellen"
debug: "Der Debug-Modus muss aktiviert sein, um die Debug-GUI verwenden zu können! Die Debug-GUI ist NICHT PRODUKTIONSSICHER!"
render:

View File

@@ -26,7 +26,7 @@ command:
biome-found: "Located biome at (%1$s, %2$s)"
unable-to-locate: "Unable to locate biome."
invalid-radius: "Invalid radius: \"%s\""
invalid: "Invalid TerraBiome ID: \"%s\""
invalid: "Invalid Biome ID: \"%s\""
in: "You are in \"%s\""
packs:
main: "Currently installed config packs:"
@@ -61,7 +61,7 @@ command:
gui:
main-menu:
- "-------------Terra/image/gui-------------"
- "raw - Open GUI with raw TerraBiome data"
- "raw - Open GUI with raw Biome data"
- "step - Re-render data to show borders more clearly"
debug: "Debug mode must be enabled to use the debug GUI! The debug GUI is NOT PRODUCTION SAFE!"
render: