diff --git a/pom.xml b/pom.xml
index e6d172e23..1a5ea3402 100644
--- a/pom.xml
+++ b/pom.xml
@@ -95,7 +95,7 @@
org.polydev
gaea
- 1.10.45
+ 1.10.46
me.lucko
diff --git a/src/main/java/com/dfsek/terra/TerraCommand.java b/src/main/java/com/dfsek/terra/TerraCommand.java
index d66b72cfc..80b3fa25d 100644
--- a/src/main/java/com/dfsek/terra/TerraCommand.java
+++ b/src/main/java/com/dfsek/terra/TerraCommand.java
@@ -26,6 +26,7 @@ import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
+import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.profiler.WorldProfiler;
import java.io.File;
@@ -46,7 +47,7 @@ public class TerraCommand implements CommandExecutor, TabExecutor {
return true;
case "biome":
if(! (sender instanceof Player)) return false;
- sender.sendMessage("You are in " + BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(((Player) sender).getWorld()).getBiome(((Player) sender).getLocation())).getFriendlyName());
+ sender.sendMessage("You are in " + BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(((Player) sender).getWorld()).getBiome(((Player) sender).getLocation(), GenerationPhase.POPULATE)).getFriendlyName());
return true;
case "profile":
if(! (sender instanceof Player)) {
diff --git a/src/main/java/com/dfsek/terra/biome/CoordinatePerturb.java b/src/main/java/com/dfsek/terra/biome/CoordinatePerturb.java
new file mode 100644
index 000000000..f28ef145c
--- /dev/null
+++ b/src/main/java/com/dfsek/terra/biome/CoordinatePerturb.java
@@ -0,0 +1,21 @@
+package com.dfsek.terra.biome;
+
+import org.polydev.gaea.math.FastNoise;
+
+public class CoordinatePerturb {
+ private final FastNoise perturbX;
+ private final FastNoise perturbZ;
+ private final int amplitude;
+ public CoordinatePerturb(float frequency, int amplitude, long seed) {
+ perturbX = new FastNoise((int) seed);
+ perturbX.setNoiseType(FastNoise.NoiseType.Simplex);
+ perturbX.setFrequency(frequency);
+ perturbZ = new FastNoise((int) seed+1);
+ perturbZ.setNoiseType(FastNoise.NoiseType.Simplex);
+ perturbZ.setFrequency(frequency);
+ this.amplitude = amplitude;
+ }
+ public int[] getShiftedCoords(int x, int z) {
+ return new int[] {(int) (perturbX.getNoise(x, z)*amplitude+x), (int) (perturbZ.getNoise(x, z)*amplitude+z)};
+ }
+}
diff --git a/src/main/java/com/dfsek/terra/biome/TerraBiomeGrid.java b/src/main/java/com/dfsek/terra/biome/TerraBiomeGrid.java
index 3bd120459..0c267043c 100644
--- a/src/main/java/com/dfsek/terra/biome/TerraBiomeGrid.java
+++ b/src/main/java/com/dfsek/terra/biome/TerraBiomeGrid.java
@@ -7,21 +7,29 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.polydev.gaea.biome.Biome;
import org.polydev.gaea.biome.BiomeGrid;
+import org.polydev.gaea.generation.GenerationPhase;
import java.util.HashMap;
import java.util.Map;
public class TerraBiomeGrid extends BiomeGrid {
private static int failNum = 0;
+ private CoordinatePerturb perturb;
private static final Map grids = new HashMap<>();
private final World w;
private final BiomeZone zone;
+ private final boolean perturbPaletteOnly;
private TerraBiomeGrid(World w, float freq1, float freq2, boolean blank) {
super(w, freq1, freq2);
+ WorldConfig c = WorldConfig.fromWorld(w);
+ if(c.biomeBlend) {
+ perturb = new CoordinatePerturb(c.blendFreq, c.blendAmp, w.getSeed());
+ }
+ perturbPaletteOnly = c.perturbPaletteOnly;
this.w = w;
this.zone = BiomeZone.fromWorld(w);
if(!blank) grids.put(w, this);
@@ -41,9 +49,17 @@ public class TerraBiomeGrid extends BiomeGrid {
}
@Override
- public Biome getBiome(int x, int z) {
+ public Biome getBiome(int x, int z, GenerationPhase phase) {
+ int xp = x;
+ int zp = z;
+ if(perturb != null && (!perturbPaletteOnly || phase.equals(GenerationPhase.PALETTE_APPLY))) {
+ int[] perturbCoords = perturb.getShiftedCoords(x, z);
+ xp = perturbCoords[0];
+ zp = perturbCoords[1];
+ }
+
try {
- return zone.getGrid(x, z).getBiome(x, z);
+ return zone.getGrid(xp, zp).getBiome(xp, zp, phase);
} catch(NullPointerException e) {
if(ConfigUtil.debug) e.printStackTrace();
if(failNum % 256 == 0) Bukkit.getLogger().severe("[Terra] A severe configuration error has prevented Terra from properly generating terrain at coordinates: " + x + ", " + z + ". Please check your configuration for errors. Any config errors will have been reported above.");
@@ -53,8 +69,8 @@ public class TerraBiomeGrid extends BiomeGrid {
}
@Override
- public Biome getBiome(Location l) {
- return getBiome(l.getBlockX(), l.getBlockZ());
+ public Biome getBiome(Location l, GenerationPhase phase) {
+ return getBiome(l.getBlockX(), l.getBlockZ(), phase);
}
public static void invalidate() {
diff --git a/src/main/java/com/dfsek/terra/biome/UserDefinedGrid.java b/src/main/java/com/dfsek/terra/biome/UserDefinedGrid.java
index 3c69dc26f..1f851da47 100644
--- a/src/main/java/com/dfsek/terra/biome/UserDefinedGrid.java
+++ b/src/main/java/com/dfsek/terra/biome/UserDefinedGrid.java
@@ -8,6 +8,8 @@ import org.bukkit.World;
import org.polydev.gaea.biome.Biome;
import org.polydev.gaea.biome.BiomeGrid;
import org.polydev.gaea.biome.NormalizationUtil;
+import org.polydev.gaea.generation.GenerationPhase;
+import org.polydev.gaea.math.Interpolator;
public class UserDefinedGrid extends BiomeGrid {
private final ImageLoader imageLoader;
@@ -26,17 +28,17 @@ public class UserDefinedGrid extends BiomeGrid {
}
@Override
- public Biome getBiome(int x, int z) {
+ public Biome getBiome(int x, int z, GenerationPhase phase) {
if(fromImage) {
double xi = imageLoader.getNoiseVal(x, z, channelX);
double zi = imageLoader.getNoiseVal(x, z, channelZ);
return super.getGrid()[NormalizationUtil.normalize(xi, getSizeX())][NormalizationUtil.normalize(zi, getSizeZ())];
}
- return super.getBiome(x, z);
+ return super.getBiome(x, z, phase);
}
@Override
- public Biome getBiome(Location l) {
- return this.getBiome(l.getBlockX(), l.getBlockZ());
+ public Biome getBiome(Location l, GenerationPhase phase) {
+ return this.getBiome(l.getBlockX(), l.getBlockZ(), phase);
}
}
diff --git a/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java b/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java
index 0b088cba8..8fbcf69f5 100644
--- a/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java
+++ b/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java
@@ -6,6 +6,7 @@ import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.genconfig.BiomeConfig;
import org.bukkit.World;
import org.bukkit.util.Vector;
+import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.world.carving.Carver;
import org.polydev.gaea.world.carving.Worm;
@@ -40,7 +41,7 @@ public class UserDefinedCarver extends Carver {
@Override
public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) {
- return random.nextInt(100) < BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(w).getBiome(chunkX << 4, chunkZ << 4)).getCarverChance(this);
+ return random.nextInt(100) < BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(w).getBiome(chunkX << 4, chunkZ << 4, GenerationPhase.POPULATE)).getCarverChance(this);
}
private class UserDefinedWorm extends Worm {
diff --git a/src/main/java/com/dfsek/terra/config/WorldConfig.java b/src/main/java/com/dfsek/terra/config/WorldConfig.java
index 14322ba58..5c2185d4d 100644
--- a/src/main/java/com/dfsek/terra/config/WorldConfig.java
+++ b/src/main/java/com/dfsek/terra/config/WorldConfig.java
@@ -34,8 +34,11 @@ public class WorldConfig {
public ImageLoader.Channel biomeXChannel;
public ImageLoader.Channel biomeZChannel;
public ImageLoader.Channel zoneChannel;
- public ImageLoader.Channel terrainChannel;
+ public boolean biomeBlend;
public ImageLoader imageLoader;
+ public int blendAmp;
+ public float blendFreq;
+ public boolean perturbPaletteOnly;
public WorldConfig(World w, JavaPlugin main) {
@@ -74,6 +77,12 @@ public class WorldConfig {
freq1 = 1f/config.getInt("frequencies.grid-x", 256);
freq2 = 1f/config.getInt("frequencies.grid-z", 512);
fromImage = config.getBoolean("image.use-image", false);
+ biomeBlend = config.getBoolean("blend.enable", false);
+ blendAmp = config.getInt("blend.amplitude", 8);
+ blendFreq = (float) config.getDouble("blend.frequency", 0.01);
+ perturbPaletteOnly = config.getBoolean("blend.ignore-terrain", true);
+
+
// Load image stuff
try {
diff --git a/src/main/java/com/dfsek/terra/generation/SlabGenerator.java b/src/main/java/com/dfsek/terra/generation/SlabGenerator.java
index 66d1ff293..2624193f3 100644
--- a/src/main/java/com/dfsek/terra/generation/SlabGenerator.java
+++ b/src/main/java/com/dfsek/terra/generation/SlabGenerator.java
@@ -13,6 +13,7 @@ import org.bukkit.block.data.type.Slab;
import org.bukkit.block.data.type.Stairs;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.util.Vector;
+import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.generation.GenerationPopulator;
import org.polydev.gaea.math.ChunkInterpolator;
import org.polydev.gaea.world.palette.Palette;
@@ -32,7 +33,7 @@ public class SlabGenerator extends GenerationPopulator {
for(byte z = 0; z < 16; z++) {
int xi = (chunkX << 4) + x;
int zi = (chunkZ << 4) + z;
- BiomeConfig config = BiomeConfig.fromBiome((UserDefinedBiome) g.getBiome(xi, zi));
+ BiomeConfig config = BiomeConfig.fromBiome((UserDefinedBiome) g.getBiome(xi, zi, GenerationPhase.PALETTE_APPLY));
if(config.getSlabs() == null) continue;
double thresh = config.getSlabThreshold();
for(int y = 0; y < world.getMaxHeight(); y++) {
diff --git a/src/main/java/com/dfsek/terra/generation/UserDefinedGenerator.java b/src/main/java/com/dfsek/terra/generation/UserDefinedGenerator.java
index d1065f5df..a0c363497 100644
--- a/src/main/java/com/dfsek/terra/generation/UserDefinedGenerator.java
+++ b/src/main/java/com/dfsek/terra/generation/UserDefinedGenerator.java
@@ -1,10 +1,14 @@
package com.dfsek.terra.generation;
+import com.dfsek.terra.biome.TerraBiomeGrid;
+import com.dfsek.terra.biome.UserDefinedBiome;
+import com.dfsek.terra.biome.UserDefinedGrid;
import com.dfsek.terra.math.NoiseFunction2;
import com.dfsek.terra.math.NoiseFunction3;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.polydev.gaea.biome.Generator;
+import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.math.FastNoise;
import org.polydev.gaea.math.parsii.eval.Expression;
import org.polydev.gaea.math.parsii.eval.Parser;
@@ -20,9 +24,9 @@ import java.util.TreeMap;
public class UserDefinedGenerator extends Generator {
private final Expression noiseExp;
private final Scope s = new Scope();
- private final Variable xVar = s.getVariable("x");;
+ private final Variable xVar = s.getVariable("x");
private final Variable yVar = s.getVariable("y");
- private final Variable zVar = s.getVariable("z");;
+ private final Variable zVar = s.getVariable("z");
private final TreeMap> paletteMap;
private final NoiseFunction2 n2 = new NoiseFunction2();
private final NoiseFunction3 n3 = new NoiseFunction3();
@@ -51,8 +55,8 @@ public class UserDefinedGenerator extends Generator {
xVar.setValue(x);
yVar.setValue(0);
zVar.setValue(z);
- n2.setNoise(gen, false);
- n3.setNoise(gen, false);
+ n2.setNoise(gen);
+ n3.setNoise(gen);
return noiseExp.evaluate();
}
}
@@ -72,8 +76,8 @@ public class UserDefinedGenerator extends Generator {
xVar.setValue(x);
yVar.setValue(y);
zVar.setValue(z);
- n2.setNoise(gen, false);
- n3.setNoise(gen, false);
+ n2.setNoise(gen);
+ n3.setNoise(gen);
return noiseExp.evaluate();
}
}
diff --git a/src/main/java/com/dfsek/terra/image/DebugFrame.java b/src/main/java/com/dfsek/terra/image/DebugFrame.java
index 8f782c84b..1b1995668 100644
--- a/src/main/java/com/dfsek/terra/image/DebugFrame.java
+++ b/src/main/java/com/dfsek/terra/image/DebugFrame.java
@@ -7,6 +7,7 @@ import com.dfsek.terra.config.WorldConfig;
import com.dfsek.terra.config.genconfig.BiomeConfig;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
+import org.polydev.gaea.generation.GenerationPhase;
import javax.swing.*;
import java.awt.*;
@@ -37,7 +38,7 @@ public class DebugFrame extends JFrame implements ActionListener {
xp = (int) (((double) Math.floorMod(p.getLocation().getBlockX() - (img.getWidth() / 2), x) / x) * getWidth());
zp = (int) (((double) Math.floorMod(p.getLocation().getBlockZ() - (img.getHeight() / 2), z) / z) * getHeight());
}
- String str = BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(p.getWorld()).getBiome(p.getLocation())).getID();
+ String str = BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(p.getWorld()).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);
diff --git a/src/main/java/com/dfsek/terra/math/NoiseFunction2.java b/src/main/java/com/dfsek/terra/math/NoiseFunction2.java
index 94d1416fa..8249aa0aa 100644
--- a/src/main/java/com/dfsek/terra/math/NoiseFunction2.java
+++ b/src/main/java/com/dfsek/terra/math/NoiseFunction2.java
@@ -19,8 +19,8 @@ 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;
+ public void setNoise(FastNoise gen) {
+ this.gen = gen;
}
@Override
diff --git a/src/main/java/com/dfsek/terra/math/NoiseFunction3.java b/src/main/java/com/dfsek/terra/math/NoiseFunction3.java
index a1c5ac416..61963e346 100644
--- a/src/main/java/com/dfsek/terra/math/NoiseFunction3.java
+++ b/src/main/java/com/dfsek/terra/math/NoiseFunction3.java
@@ -18,8 +18,8 @@ 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;
+ public void setNoise(FastNoise gen) {
+ this.gen = gen;
}
@Override
diff --git a/src/main/java/com/dfsek/terra/population/FloraPopulator.java b/src/main/java/com/dfsek/terra/population/FloraPopulator.java
index b5d56ed8d..dfbd2326a 100644
--- a/src/main/java/com/dfsek/terra/population/FloraPopulator.java
+++ b/src/main/java/com/dfsek/terra/population/FloraPopulator.java
@@ -10,6 +10,7 @@ import org.bukkit.World;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.biome.Biome;
+import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.population.GaeaBlockPopulator;
import org.polydev.gaea.profiler.ProfileFuture;
import org.polydev.gaea.world.Flora;
@@ -27,7 +28,7 @@ public class FloraPopulator extends GaeaBlockPopulator {
pop.add(chunk);
for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) {
- UserDefinedBiome biome = (UserDefinedBiome) TerraBiomeGrid.fromWorld(world).getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z);
+ UserDefinedBiome biome = (UserDefinedBiome) TerraBiomeGrid.fromWorld(world).getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, GenerationPhase.POPULATE);
if(biome.getDecorator().getFloraChance() <= 0 || random.nextInt(100) > biome.getDecorator().getFloraChance())
continue;
try {
diff --git a/src/main/java/com/dfsek/terra/population/OrePopulator.java b/src/main/java/com/dfsek/terra/population/OrePopulator.java
index 29350dabb..90c6bbdb5 100644
--- a/src/main/java/com/dfsek/terra/population/OrePopulator.java
+++ b/src/main/java/com/dfsek/terra/population/OrePopulator.java
@@ -11,6 +11,7 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.biome.Biome;
+import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.population.GaeaBlockPopulator;
import org.polydev.gaea.profiler.ProfileFuture;
@@ -22,7 +23,7 @@ public class OrePopulator extends GaeaBlockPopulator {
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
try (ProfileFuture ignored = TerraProfiler.fromWorld(world).measure("OreTime")) {
Location l = chunk.getBlock(8, 0, 0).getLocation();
- Biome b = TerraBiomeGrid.fromWorld(world).getBiome(l.getBlockX(), l.getBlockZ());
+ Biome b = TerraBiomeGrid.fromWorld(world).getBiome(l.getBlockX(), l.getBlockZ(), GenerationPhase.POPULATE);
for(Map.Entry e : BiomeConfig.fromBiome((UserDefinedBiome) b).getOres().entrySet()) {
int num = e.getValue().get(random);
for(int i = 0; i < num; i++) {
diff --git a/src/main/java/com/dfsek/terra/population/TreePopulator.java b/src/main/java/com/dfsek/terra/population/TreePopulator.java
index 6634ae6bd..2bf12b967 100644
--- a/src/main/java/com/dfsek/terra/population/TreePopulator.java
+++ b/src/main/java/com/dfsek/terra/population/TreePopulator.java
@@ -9,6 +9,7 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.polydev.gaea.biome.Biome;
+import org.polydev.gaea.generation.GenerationPhase;
import org.polydev.gaea.population.GaeaBlockPopulator;
import org.polydev.gaea.profiler.ProfileFuture;
import org.polydev.gaea.util.WorldUtil;
@@ -22,14 +23,14 @@ public class TreePopulator extends GaeaBlockPopulator {
int x = random.nextInt(16); // Decrease chances of chunk-crossing trees
int z = random.nextInt(16);
Location origin = chunk.getBlock(x, 0, z).getLocation();
- Biome b = TerraBiomeGrid.fromWorld(world).getBiome(origin);
+ Biome b = TerraBiomeGrid.fromWorld(world).getBiome(origin, GenerationPhase.POPULATE);
if(((UserDefinedDecorator) b.getDecorator()).getTreeChance() < random.nextInt(100)) return;
int numTrees = 0;
for(int i = 0; i < 48; i++) {
int y = WorldUtil.getHighestValidSpawnAt(chunk, x, z);
if(y <= 0) continue;
origin = chunk.getBlock(x, y, z).getLocation().add(0, 1, 0);
- b = TerraBiomeGrid.fromWorld(world).getBiome(origin);
+ b = TerraBiomeGrid.fromWorld(world).getBiome(origin, GenerationPhase.POPULATE);
numTrees++;
try {
b.getDecorator().getTrees().get(random).plant(origin, random, false, Terra.getInstance());