diff --git a/pom.xml b/pom.xml
index eb6f46f8c..9c6b5c5fc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -83,7 +83,7 @@
org.polydev
gaea
- 1.4.0
+ 1.5.7
diff --git a/src/main/java/com/dfsek/terra/Terra.java b/src/main/java/com/dfsek/terra/Terra.java
index f2f674247..99e40b31f 100644
--- a/src/main/java/com/dfsek/terra/Terra.java
+++ b/src/main/java/com/dfsek/terra/Terra.java
@@ -1,75 +1,13 @@
package com.dfsek.terra;
import com.dfsek.terra.config.ConfigUtil;
-import com.dfsek.terra.config.WorldConfig;
-import com.dfsek.terra.math.NoiseFunction2;
-import com.dfsek.terra.math.NoiseFunction3;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.polydev.gaea.math.parsii.eval.Expression;
-import org.polydev.gaea.math.parsii.eval.Function;
-import org.polydev.gaea.math.parsii.eval.Parser;
-
-import java.util.List;
public class Terra extends JavaPlugin {
-
- static {
- Parser.registerFunction("floor", new Function() {
- @Override
- public int getNumberOfArguments() {
- return 1;
- }
-
- @Override
- public double eval(List list) {
- return Math.floor(list.get(0).evaluate());
- }
-
- @Override
- public boolean isNaturalFunction() {
- return true;
- }
- });
- Parser.registerFunction("ceil", new Function() {
- @Override
- public int getNumberOfArguments() {
- return 1;
- }
-
- @Override
- public double eval(List list) {
- return Math.ceil(list.get(0).evaluate());
- }
-
- @Override
- public boolean isNaturalFunction() {
- return true;
- }
- });
- Parser.registerFunction("round", new Function() {
- @Override
- public int getNumberOfArguments() {
- return 1;
- }
-
- @Override
- public double eval(List list) {
- return Math.round(list.get(0).evaluate());
- }
-
- @Override
- public boolean isNaturalFunction() {
- return true;
- }
- });
- Parser.registerFunction("noise2", new NoiseFunction2());
- Parser.registerFunction("noise3", new NoiseFunction3());
- }
-
private static FileConfiguration config;
private static Terra instance;
diff --git a/src/main/java/com/dfsek/terra/TerraCommand.java b/src/main/java/com/dfsek/terra/TerraCommand.java
index 7e7a5979d..c5d97ca7e 100644
--- a/src/main/java/com/dfsek/terra/TerraCommand.java
+++ b/src/main/java/com/dfsek/terra/TerraCommand.java
@@ -8,21 +8,45 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
+import org.polydev.gaea.profiler.WorldProfiler;
public class TerraCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
- if(args.length == 1) {
- switch(args[0]) {
- case "reload":
- ConfigUtil.loadConfig(Terra.getInstance());
- sender.sendMessage("Reloaded Terra config.");
- break;
- case "biome":
- if(!(sender instanceof Player)) return false;
- sender.sendMessage("You are in " + ((UserDefinedBiome) TerraBiomeGrid.fromWorld(((Player) sender).getWorld()).getBiome(((Player) sender).getLocation())).getConfig().getFriendlyName());
+ switch(args[0]) {
+ case "reload":
+ ConfigUtil.loadConfig(Terra.getInstance());
+ sender.sendMessage("Reloaded Terra config.");
+ break;
+ case "biome":
+ if(!(sender instanceof Player)) return false;
+ sender.sendMessage("You are in " + ((UserDefinedBiome) TerraBiomeGrid.fromWorld(((Player) sender).getWorld()).getBiome(((Player) sender).getLocation())).getConfig().getFriendlyName());
+ case "profile":
+ if(! (sender instanceof Player)) {
+ sender.sendMessage("Command is for players only.");
+ return true;
+ }
+ Player p = (Player) sender;
+ if(p.getWorld().getGenerator() instanceof TerraChunkGenerator) {
+ WorldProfiler profile = TerraProfiler.fromWorld(p.getWorld());
+ if(args.length > 1 && "query".equals(args[1])) {
+ sender.sendMessage(profile.getResultsFormatted());
+ return true;
+ } else if(args.length > 1 && "reset".equals(args[1])) {
+ profile.reset();
+ sender.sendMessage("Profiler has been reset.");
+ return true;
+ } else if(args.length > 1 && "start".equals(args[1])) {
+ profile.setProfiling(true);
+ sender.sendMessage("Profiler has started.");
+ return true;
+ } else if(args.length > 1 && "stop".equals(args[1])) {
+ profile.setProfiling(false);
+ sender.sendMessage("Profiler has stopped.");
+ return true;
+ }
+ } else sender.sendMessage("World is not a Terra world!");
}
- }
return true;
}
}
diff --git a/src/main/java/com/dfsek/terra/TerraProfiler.java b/src/main/java/com/dfsek/terra/TerraProfiler.java
new file mode 100644
index 000000000..c7844f6b2
--- /dev/null
+++ b/src/main/java/com/dfsek/terra/TerraProfiler.java
@@ -0,0 +1,30 @@
+package com.dfsek.terra;
+
+import org.bukkit.World;
+import org.polydev.gaea.profiler.DataType;
+import org.polydev.gaea.profiler.Measurement;
+import org.polydev.gaea.profiler.WorldProfiler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TerraProfiler extends WorldProfiler {
+ private static final Map profilerMap = new HashMap<>();
+ public TerraProfiler(World w) {
+ super(w);
+ this.addMeasurement(new Measurement(2500000, DataType.PERIOD_MILLISECONDS), "TotalChunkGenTime")
+ .addMeasurement(new Measurement(2500000, DataType.PERIOD_MILLISECONDS), "ChunkBaseGenTime")
+ .addMeasurement(new Measurement(2000000, DataType.PERIOD_MILLISECONDS), "BiomeSetTime")
+ .addMeasurement(new Measurement(25000000, DataType.PERIOD_MILLISECONDS), "TreeGenTime")
+ .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "FaunaTime");
+ profilerMap.put(w, this);
+ }
+ public static TerraProfiler fromWorld(World w) {
+ if(w.getGenerator() instanceof TerraChunkGenerator) {
+ if(profilerMap.containsKey(w)) return profilerMap.get(w);
+ TerraProfiler p = new TerraProfiler(w);
+ profilerMap.put(w, p);
+ return p;
+ } else throw new IllegalArgumentException("Attempted to instantiate/fetch Profiler for non-Terra world!");
+ }
+}
diff --git a/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java b/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java
index afdec9f27..0a5dda37e 100644
--- a/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java
+++ b/src/main/java/com/dfsek/terra/biome/UserDefinedBiome.java
@@ -2,14 +2,18 @@ package com.dfsek.terra.biome;
import com.dfsek.terra.config.BiomeConfig;
import com.dfsek.terra.config.ConfigUtil;
+import org.bukkit.Bukkit;
+import org.bukkit.block.data.BlockData;
import org.bukkit.configuration.file.FileConfiguration;
import org.polydev.gaea.biome.Biome;
import org.polydev.gaea.biome.BiomeTerrain;
import org.polydev.gaea.biome.Decorator;
+import org.polydev.gaea.math.ProbabilityCollection;
import org.polydev.gaea.math.parsii.eval.Parser;
import org.polydev.gaea.math.parsii.eval.Scope;
import org.polydev.gaea.math.parsii.tokenizer.ParseException;
import org.polydev.gaea.structures.features.Feature;
+import org.polydev.gaea.tree.Tree;
import org.polydev.gaea.world.BlockPalette;
import java.util.Collections;
@@ -24,16 +28,27 @@ public class UserDefinedBiome implements Biome {
private final UserDefinedDecorator decorator;
public UserDefinedBiome(BiomeConfig config) throws ParseException {
this.config = config;
- Scope s = Scope.create();
TreeMap paletteMap = new TreeMap<>();
- for(Map.Entry e : config.getConfigurationSection("palette").getValues(false).entrySet()) {
- paletteMap.put((Integer) e.getValue(), ConfigUtil.getPalette(e.getKey()).getPalette());
+ for(Map, ?> e : config.getMapList("palette")) {
+ for(Map.Entry, ?> entry : e.entrySet()) {
+ try {
+ if(((String) entry.getKey()).startsWith("BLOCK:")) {
+ try {
+ paletteMap.put((Integer) entry.getValue(), new BlockPalette().addBlockData(new ProbabilityCollection().add(Bukkit.createBlockData((String) entry.getKey()), 1), 1));
+ } catch(IllegalArgumentException ex) {
+ Bukkit.getLogger().severe("SEVERE configuration error for BlockPalettes in biome" + config.getFriendlyName() + ", ID: " + config.getBiomeID() + ". BlockData " + entry.getKey() + " is invalid!");
+ }
+ }
+ else paletteMap.put((Integer) entry.getValue(), ConfigUtil.getPalette((String) entry.getKey()).getPalette());
+ } catch(ClassCastException ex) {
+ Bukkit.getLogger().severe("SEVERE configuration error for BlockPalettes in biome" + config.getFriendlyName() + ", ID: " + config.getBiomeID());
+ }
+ }
}
-
this.decorator = new UserDefinedDecorator(config);
- gen = new UserDefinedGenerator(s, Parser.parse(Objects.requireNonNull(config.getString("noise-equation")), s), Collections.emptyList(), paletteMap);
+ gen = new UserDefinedGenerator(Objects.requireNonNull(config.getString("noise-equation")), Collections.emptyList(), paletteMap);
}
public BiomeConfig getConfig() {
diff --git a/src/main/java/com/dfsek/terra/biome/UserDefinedGenerator.java b/src/main/java/com/dfsek/terra/biome/UserDefinedGenerator.java
index 5e73cf150..8baf1772c 100644
--- a/src/main/java/com/dfsek/terra/biome/UserDefinedGenerator.java
+++ b/src/main/java/com/dfsek/terra/biome/UserDefinedGenerator.java
@@ -1,12 +1,15 @@
package com.dfsek.terra.biome;
+import com.dfsek.terra.Terra;
import com.dfsek.terra.math.NoiseFunction2;
import com.dfsek.terra.math.NoiseFunction3;
import org.polydev.gaea.biome.BiomeTerrain;
import org.polydev.gaea.math.FastNoise;
import org.polydev.gaea.math.parsii.eval.Expression;
+import org.polydev.gaea.math.parsii.eval.Parser;
import org.polydev.gaea.math.parsii.eval.Scope;
import org.polydev.gaea.math.parsii.eval.Variable;
+import org.polydev.gaea.math.parsii.tokenizer.ParseException;
import org.polydev.gaea.world.BlockPalette;
import java.util.List;
@@ -16,19 +19,26 @@ import java.util.TreeMap;
public class UserDefinedGenerator extends BiomeTerrain {
private final Expression noiseExp;
private final List vars;
- private final Variable xVar;
- private final Variable yVar;
- private final Variable zVar;
+ private final Scope s = new Scope();
+ private final Variable xVar = s.getVariable("x");;
+ private final Variable yVar = s.getVariable("y");
+ private final Variable zVar = s.getVariable("z");;
private final TreeMap paletteMap;
+ private final NoiseFunction2 n2 = new NoiseFunction2();
+ private final NoiseFunction3 n3 = new NoiseFunction3();
+ private final Parser p = new Parser();
+ {
+ p.registerFunction("noise2", n2);
+ p.registerFunction("noise3", n3);
+ }
+
+ private static final Object noiseLock = new Object();
- public UserDefinedGenerator(Scope s, Expression e, List v, TreeMap p) {
- this.noiseExp = e;
+ public UserDefinedGenerator(String e, List v, TreeMap pa) throws ParseException {
this.vars = v;
- this.paletteMap = p;
- this.xVar = s.getVariable("x");
- this.yVar = s.getVariable("y");
- this.zVar = s.getVariable("z");
+ this.paletteMap = pa;
+ this.noiseExp = p.parse(e, s);
}
/**
* Gets the 2D noise at a pair of coordinates using the provided FastNoise instance.
@@ -40,12 +50,14 @@ public class UserDefinedGenerator extends BiomeTerrain {
*/
@Override
public double getNoise(FastNoise gen, int x, int z) {
- xVar.setValue(x);
- yVar.setValue(0);
- zVar.setValue(z);
- NoiseFunction2.setNoise(gen);
- NoiseFunction3.setNoise(gen);
- return noiseExp.evaluate();
+ synchronized(noiseLock) {
+ xVar.setValue(x);
+ yVar.setValue(0);
+ zVar.setValue(z);
+ n2.setNoise(gen, false);
+ n3.setNoise(gen, false);
+ return noiseExp.evaluate();
+ }
}
/**
@@ -59,12 +71,14 @@ public class UserDefinedGenerator extends BiomeTerrain {
*/
@Override
public double getNoise(FastNoise gen, int x, int y, int z) {
- xVar.setValue(x);
- yVar.setValue(y);
- zVar.setValue(z);
- NoiseFunction2.setNoise(gen);
- NoiseFunction3.setNoise(gen);
- return noiseExp.evaluate();
+ synchronized(noiseLock) {
+ xVar.setValue(x);
+ yVar.setValue(y);
+ zVar.setValue(z);
+ n2.setNoise(gen, false);
+ n3.setNoise(gen, false);
+ return noiseExp.evaluate();
+ }
}
/**
diff --git a/src/main/java/com/dfsek/terra/config/BiomeConfig.java b/src/main/java/com/dfsek/terra/config/BiomeConfig.java
index 8ceab9707..dfad80417 100644
--- a/src/main/java/com/dfsek/terra/config/BiomeConfig.java
+++ b/src/main/java/com/dfsek/terra/config/BiomeConfig.java
@@ -39,6 +39,7 @@ public class BiomeConfig extends YamlConfiguration {
if(!contains("name")) throw new InvalidConfigurationException("Biome Name unspecified!");
this.friendlyName = getString("name");
if(!contains("vanilla")) throw new InvalidConfigurationException("Vanila Biome unspecified!");
+ if(!contains("palette")) throw new InvalidConfigurationException("Palette unspecified!");
try {
this.vanillaBiome = org.bukkit.block.Biome.valueOf(getString("vanilla"));
} catch(IllegalArgumentException e) {
diff --git a/src/main/java/com/dfsek/terra/config/WorldConfig.java b/src/main/java/com/dfsek/terra/config/WorldConfig.java
index bf85947eb..b6dab4143 100644
--- a/src/main/java/com/dfsek/terra/config/WorldConfig.java
+++ b/src/main/java/com/dfsek/terra/config/WorldConfig.java
@@ -66,9 +66,9 @@ public class WorldConfig {
}
seaLevel = config.getInt("sea-level", 63);
- zoneFreq = config.getInt("frequencies.zone", 1536);
- freq1 = config.getInt("frequencies.grid-1", 256);
- freq2 = config.getInt("frequencies.grid-2", 512);
+ zoneFreq = 1f/config.getInt("frequencies.zone", 1536);
+ freq1 = 1f/config.getInt("frequencies.grid-1", 256);
+ freq2 = 1f/config.getInt("frequencies.grid-2", 512);
try (Stream paths = Files.walk(Paths.get(main.getDataFolder() + File.separator + "grids"))) {
paths
diff --git a/src/main/java/com/dfsek/terra/math/NoiseFunction2.java b/src/main/java/com/dfsek/terra/math/NoiseFunction2.java
index d2349eaf4..94d1416fa 100644
--- a/src/main/java/com/dfsek/terra/math/NoiseFunction2.java
+++ b/src/main/java/com/dfsek/terra/math/NoiseFunction2.java
@@ -7,7 +7,7 @@ import org.polydev.gaea.math.parsii.eval.Function;
import java.util.List;
public class NoiseFunction2 implements Function {
- private static FastNoise gen = new FastNoise();
+ private FastNoise gen;
@Override
public int getNumberOfArguments() {
@@ -19,16 +19,12 @@ public class NoiseFunction2 implements Function {
return gen.getSimplexFractal((float) list.get(0).evaluate(), (float) list.get(1).evaluate());
}
+ public void setNoise(FastNoise gen, boolean override) {
+ if(this.gen == null || override) this.gen = gen;
+ }
+
@Override
public boolean isNaturalFunction() {
return true;
}
-
- public static void setNoise(FastNoise gen) {
- NoiseFunction2.gen = gen;
- }
-
- public static FastNoise getNoise() {
- return gen;
- }
}
diff --git a/src/main/java/com/dfsek/terra/math/NoiseFunction3.java b/src/main/java/com/dfsek/terra/math/NoiseFunction3.java
index e368cb749..a1c5ac416 100644
--- a/src/main/java/com/dfsek/terra/math/NoiseFunction3.java
+++ b/src/main/java/com/dfsek/terra/math/NoiseFunction3.java
@@ -7,8 +7,7 @@ import org.polydev.gaea.math.parsii.eval.Function;
import java.util.List;
public class NoiseFunction3 implements Function {
- private static FastNoise gen = new FastNoise();
-
+ private FastNoise gen;
@Override
public int getNumberOfArguments() {
return 3;
@@ -19,16 +18,12 @@ public class NoiseFunction3 implements Function {
return gen.getSimplexFractal((float) list.get(0).evaluate(), (float) list.get(1).evaluate(), (float) list.get(2).evaluate());
}
+ public void setNoise(FastNoise gen, boolean override) {
+ if(this.gen == null || override) this.gen = gen;
+ }
+
@Override
public boolean isNaturalFunction() {
return true;
}
-
- public static void setNoise(FastNoise gen) {
- NoiseFunction3.gen = gen;
- }
-
- public static FastNoise getNoise() {
- return gen;
- }
}
diff --git a/src/main/java/com/dfsek/terra/population/FaunaPopulator.java b/src/main/java/com/dfsek/terra/population/FaunaPopulator.java
index a7672abee..1770fe96e 100644
--- a/src/main/java/com/dfsek/terra/population/FaunaPopulator.java
+++ b/src/main/java/com/dfsek/terra/population/FaunaPopulator.java
@@ -1,5 +1,7 @@
package com.dfsek.terra.population;
+import com.dfsek.terra.Terra;
+import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.biome.TerraBiomeGrid;
import org.bukkit.Chunk;
import org.bukkit.World;
@@ -7,6 +9,7 @@ import org.bukkit.block.Block;
import org.bukkit.generator.BlockPopulator;
import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.biome.Biome;
+import org.polydev.gaea.profiler.ProfileFuture;
import org.polydev.gaea.world.Fauna;
import java.util.Random;
@@ -14,16 +17,19 @@ import java.util.Random;
public class FaunaPopulator extends BlockPopulator {
@Override
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
+ ProfileFuture fauna = TerraProfiler.fromWorld(world).measure("FaunaTime");
for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) {
Biome biome = TerraBiomeGrid.fromWorld(world).getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z);
if(biome.getDecorator().getFaunaChance() <= 0 || random.nextInt(100) > biome.getDecorator().getFaunaChance())
continue;
- Block highest = Fauna.getHighestValidSpawnAt(chunk, x, z);
+ Fauna item = biome.getDecorator().getFauna().get(random);
+ Block highest = item.getHighestValidSpawnAt(chunk, x, z);
try {
- if(highest != null) biome.getDecorator().getFauna().get(random).plant(highest.getLocation());
+ if(highest != null) item.plant(highest.getLocation());
} catch(NullPointerException ignored) {}
}
}
+ if(fauna!=null) fauna.complete();
}
}
diff --git a/src/main/java/com/dfsek/terra/population/TreePopulator.java b/src/main/java/com/dfsek/terra/population/TreePopulator.java
index 602bd8ffb..ab8020c3c 100644
--- a/src/main/java/com/dfsek/terra/population/TreePopulator.java
+++ b/src/main/java/com/dfsek/terra/population/TreePopulator.java
@@ -1,6 +1,7 @@
package com.dfsek.terra.population;
import com.dfsek.terra.Terra;
+import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.biome.TerraBiomeGrid;
import com.dfsek.terra.biome.UserDefinedDecorator;
import org.bukkit.Chunk;
@@ -10,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.biome.Biome;
import org.polydev.gaea.population.GaeaBlockPopulator;
import org.polydev.gaea.population.PopulationManager;
+import org.polydev.gaea.profiler.ProfileFuture;
import org.polydev.gaea.util.WorldUtil;
import java.util.Random;
@@ -22,6 +24,7 @@ public class TreePopulator extends GaeaBlockPopulator {
@Override
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
+ ProfileFuture tree = TerraProfiler.fromWorld(world).measure("TreeGenTime");
int x = random.nextInt(16); // Decrease chances of chunk-crossing trees
int z = random.nextInt(16);
Location origin = chunk.getBlock(x, 0, z).getLocation();
@@ -41,5 +44,6 @@ public class TreePopulator extends GaeaBlockPopulator {
x = random.nextInt(16); // Decrease chances of chunk-crossing trees
z = random.nextInt(16);
}
+ if(tree!=null) tree.complete();
}
}