diff --git a/.gitignore b/.gitignore
index b83d22266..1d78542dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
/target/
+
+lib/
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
index eb36f61bc..19169a9be 100644
--- a/dependency-reduced-pom.xml
+++ b/dependency-reduced-pom.xml
@@ -68,6 +68,10 @@
spigot-repo
https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+ volmit
+ http://nexus.volmit.com/content/repositories/volmit
+
@@ -98,6 +102,13 @@
+
+ cb
+ craftbukkit-1.12.2
+ 1
+ system
+ ${project.basedir}/lib/craftbukkit-1.12.2.jar
+
${user.home}\Documents\development\server\plugins\${project.name}.jar
diff --git a/pom.xml b/pom.xml
index 5defd6cd9..d4470ef85 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,6 +76,10 @@
spigot-repo
https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+ volmit
+ http://nexus.volmit.com/content/repositories/volmit
+
@@ -89,5 +93,12 @@
1.12.2-R0.1-SNAPSHOT
provided
+
+ craftbukkit-1.12.2
+ cb
+ 1
+ system
+ ${project.basedir}/lib/craftbukkit-1.12.2.jar
+
\ No newline at end of file
diff --git a/src/main/java/ninja/bytecode/iris/Iris.java b/src/main/java/ninja/bytecode/iris/Iris.java
index b8eba5a43..adc372903 100644
--- a/src/main/java/ninja/bytecode/iris/Iris.java
+++ b/src/main/java/ninja/bytecode/iris/Iris.java
@@ -1,17 +1,33 @@
package ninja.bytecode.iris;
+import java.util.UUID;
+
+import org.bukkit.Bukkit;
+import org.bukkit.GameMode;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.WorldCreator;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.java.JavaPlugin;
import ninja.bytecode.shuriken.execution.TaskExecutor;
-public class Iris extends JavaPlugin
+public class Iris extends JavaPlugin implements Listener
{
public static TaskExecutor executor;
public void onEnable()
{
- executor = new TaskExecutor(-1, Thread.MIN_PRIORITY, "Iris Generator");
+ executor = new TaskExecutor(1, Thread.MIN_PRIORITY, "Iris Generator");
+ getServer().getPluginManager().registerEvents((Listener) this, this);
+ }
+
+ public void onDisable()
+ {
+ executor.close();
}
@Override
@@ -19,4 +35,23 @@ public class Iris extends JavaPlugin
{
return new IrisGenerator();
}
+
+ @EventHandler
+ public void on(PlayerCommandPreprocessEvent e)
+ {
+ if(e.getMessage().toLowerCase().equals("/iris"))
+ {
+ World ww = Bukkit.createWorld(new WorldCreator("iris-worlds/" + UUID.randomUUID().toString())
+ .generator(new IrisGenerator())
+ .seed(0));
+ ww.setSpawnFlags(false, false);
+ ww.setAutoSave(false);
+ ww.setKeepSpawnInMemory(false);
+ ww.setSpawnLocation(0, 256, 0);
+ e.getPlayer().teleport(new Location(ww, 0, 256, 0));
+ e.getPlayer().setFlying(true);
+ e.getPlayer().setGameMode(GameMode.CREATIVE);
+ e.setCancelled(true);
+ }
+ }
}
diff --git a/src/main/java/ninja/bytecode/iris/IrisGenerator.java b/src/main/java/ninja/bytecode/iris/IrisGenerator.java
index e74d1a3bb..0e4b74c35 100644
--- a/src/main/java/ninja/bytecode/iris/IrisGenerator.java
+++ b/src/main/java/ninja/bytecode/iris/IrisGenerator.java
@@ -5,7 +5,9 @@ import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
-import ninja.bytecode.shuriken.math.CNG;
+import ninja.bytecode.iris.gen.GenLayerBase;
+import ninja.bytecode.iris.gen.IGenLayer;
+import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG;
@@ -23,149 +25,45 @@ public class IrisGenerator extends ParallelChunkGenerator
};
private static final MB[] rock = {new MB(Material.STONE), new MB(Material.STONE, 5), new MB(Material.COBBLESTONE),
};
- private double[][][] scatterCache;
- private CNG gen;
- private CNG fracture;
- private CNG basegen;
- private CNG faultline;
- private RNG rng;
+ private GList genLayers;
@Override
public void onInit(World world, Random random)
{
- //@builder
- rng = new RNG(world.getSeed());
- CNG scatter = new CNG(rng.nextRNG(), 1, 1)
- .scale(10);
- basegen = new CNG(rng.nextRNG(), 0.46, 3)
- .scale(0.00295)
- .fractureWith(new CNG(rng.nextRNG(), 1, 2)
- .scale(0.025), 70);
- gen = new CNG(rng.nextRNG(), 0.19D, 4)
- .scale(0.012)
- .amp(0.5)
- .freq(1.1)
- .fractureWith(new CNG(rng.nextRNG(), 1, 2)
- .scale(0.018)
- .fractureWith(new CNG(rng.nextRNG(), 1, 1)
- .scale(0.15), 24), 44);
- fracture = new CNG(rng.nextRNG(), 0.6D, 4)
- .scale(0.118);
- faultline = new CNG(rng.nextRNG(), 1D, 1)
- .scale(0.005)
- .child(new CNG(rng.nextRNG(), 1D, 1)
- .scale(0.012))
- .injectWith(CNG.MULTIPLY)
- .fractureWith(new CNG(rng.nextRNG(), 1, 1)
- .scale(0.07), 200);
- //@done
-
- scatterCache = new double[16][][];
-
- for(int i = 0; i < 16; i++)
- {
- scatterCache[i] = new double[16][];
-
- for(int j = 0; j < 16; j++)
- {
- scatterCache[i][j] = new double[16];
-
- for(int k = 0; k < 16; k++)
- {
- scatterCache[i][j][k] = scatter.noise(i, j, k);
- }
- }
- }
- }
-
- @Override
- public void genColumn(int wx, int wz, int x, int z)
- {
- int height = getHeight(wx, wz);
- MB mb = rock[0];
-
- for(int i = 0; i < Math.max(height, 63); i++)
- {
- int surfdepth = i < height ? height - i : 0;
- double scatter = scatterCache[x][z][i % 16];
-
- if(i == 0)
- {
- mb = bedrock;
- }
-
- else
- {
- if(scatter > 0.4 && i == 2)
- {
- mb = bedrock;
- }
-
- if(scatter > 0.6 && i == 1)
- {
- mb = bedrock;
- }
-
- if(i > height)
- {
- mb = water;
- }
-
- else if(i == height)
- {
- mb = pick(sand, scatter);
- }
-
- else if(i == height + 1 + scatter)
- {
- mb = pick(sandygrass, scatter);
- }
-
- else if(i == height - 1)
- {
- mb = grass;
- }
-
- else if(i > height - ((scatter * 2) + 1))
- {
- mb = pick(earth, scatter);
- }
-
- else
- {
- mb = pick(rock, scatter);
- }
-
- if(mb.data < 0)
- {
- mb = new MB(mb.material, pick(Math.abs(mb.data), scatter));
- }
- }
-
- setBlock(x, i, z, mb.material, mb.data);
- }
+ RNG rng = new RNG(world.getSeed());
+ genLayers = new GList<>();
+ genLayers.add(new GenLayerBase(world, random, rng));
+ System.out.print("Gend");
}
public int getHeight(double dx, double dz)
{
- double fnoise = fracture.noise(dx, dz);
- double fault = faultline.noise(dx, dz);
- dx += (fnoise * 12);
- dz -= (fnoise * 12);
- double base = basegen.noise(dx, dz);
- double noise = base + gen.noise(dx, dz);
+ double noise = 0.5;
+
+ for(IGenLayer i : genLayers)
+ {
+ noise = i.generateLayer(noise, dx, dz);
+ }
+
double n = noise * 250;
n = n > 255 ? 255 : n;
n = n < 0 ? 0 : n;
-
- if(n > 75 && fault > 0.35)
- {
- n += (fault * (n / 19.5));
- }
-
+
return (int) n;
}
+ @Override
+ public void genColumn(final int wx, final int wz)
+ {
+ int height = getHeight(wx, wz);
+ MB mb = rock[0];
+
+ for(int i = 0; i < height; i++)
+ {
+ setBlock(wx, i, wz, mb.material, mb.data);
+ }
+ }
+
public int pick(int max, double noise)
{
return (int) (noise * max);
diff --git a/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java b/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java
index dd93e48ce..304ac0ddf 100644
--- a/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java
+++ b/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java
@@ -6,6 +6,7 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.generator.ChunkGenerator;
+import ninja.bytecode.iris.atomics.AtomicChunkData;
import ninja.bytecode.shuriken.Shuriken;
import ninja.bytecode.shuriken.execution.ChronoLatch;
import ninja.bytecode.shuriken.execution.J;
@@ -18,53 +19,65 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
private int j;
private int wx;
private int wz;
- private ChunkData data;
+ private AtomicChunkData data;
private TaskGroup tg;
private boolean ready = false;
- private ChronoLatch cl = new ChronoLatch(5000);
+ private ChronoLatch cl = new ChronoLatch(1000);
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
{
Shuriken.profiler.start("chunkgen-" + world.getName());
-
- if(!ready)
+ data = new AtomicChunkData(world);
+
+ try
{
- onInit(world, random);
- ready = true;
- }
-
- data = createChunkData(world);
- tg = Iris.executor.startWork();
-
- for(i = 0; i < 16; i++)
- {
- wx = (x * 16) + i;
-
- for(j = 0; j < 16; j++)
+ if(!ready)
{
- wz = (z * 16) + j;
- int a = wx;
- int b = wz;
- int c = i;
- int d = j;
- tg.queue(() -> genColumn(a, b, c, d));
+ onInit(world, random);
+ ready = true;
+ }
+
+ tg = Iris.executor.startWork();
+
+ for(i = 0; i < 16; i++)
+ {
+ wx = (x * 16) + i;
+
+ for(j = 0; j < 16; j++)
+ {
+ wz = (z * 16) + j;
+ int a = wx;
+ int b = wz;
+ tg.queue(() -> genColumn(a, b));
+ }
+ }
+
+ tg.execute();
+ Shuriken.profiler.stop("chunkgen-" + world.getName());
+
+ if(cl.flip())
+ {
+ J.a(() -> System.out.print("Gen: " + F.duration(Shuriken.profiler.getResult("chunkgen-" + world.getName()).getAverage(), 2)));
}
}
- tg.execute();
- Shuriken.profiler.stop("chunkgen-" + world.getName());
-
- if(cl.flip())
+ catch(Throwable e)
{
- J.a(() -> System.out.print("Gen: " + F.duration(Shuriken.profiler.getResult("chunkgen-" + world.getName()).getAverage(), 2)));
+ for(int i = 0; i < 16; i++)
+ {
+ for(int j = 0; j < 16; j++)
+ {
+ data.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA);
+ }
+ }
}
- return data;
+ return data.toChunkData();
}
public abstract void onInit(World world, Random random);
- public abstract void genColumn(int wx, int wz, int x, int z);
+ public abstract void genColumn(int wx, int wz);
@SuppressWarnings("deprecation")
protected void setBlock(int x, int y, int z, Material b)
@@ -83,7 +96,6 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
setBlock(x, y, z, b, (byte) 0);
}
- @SuppressWarnings("deprecation")
protected void setBlock(int x, int y, int z, int b, byte d)
{
data.setBlock(x, y, z, b, d);
diff --git a/src/main/java/ninja/bytecode/iris/atomics/AtomicCharArray.java b/src/main/java/ninja/bytecode/iris/atomics/AtomicCharArray.java
new file mode 100644
index 000000000..82ad0ee79
--- /dev/null
+++ b/src/main/java/ninja/bytecode/iris/atomics/AtomicCharArray.java
@@ -0,0 +1,83 @@
+package ninja.bytecode.iris.atomics;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+
+import sun.misc.Unsafe;
+
+@SuppressWarnings("restriction")
+public class AtomicCharArray implements Serializable
+{
+ private static final long serialVersionUID = 2862133569453604235L;
+ private static final Unsafe unsafe;
+ private static final int base;
+ private static final int shift;
+ volatile char[] array;
+
+ public AtomicCharArray(int var1)
+ {
+ this.array = new char[var1];
+ }
+
+ private long checkedByteOffset(int var1)
+ {
+ if(var1 >= 0 && var1 < this.array.length)
+ {
+ return byteOffset(var1);
+ }
+ else
+ {
+ throw new IndexOutOfBoundsException("index " + var1);
+ }
+ }
+
+ public final char get(int var1)
+ {
+ return this.getRaw(this.checkedByteOffset(var1));
+ }
+
+ private char getRaw(long var1)
+ {
+ return unsafe.getCharVolatile(this.array, var1);
+ }
+
+ public final void set(int var1, char var2)
+ {
+ unsafe.putCharVolatile(this.array, this.checkedByteOffset(var1), var2);
+ }
+
+ private static long byteOffset(int var0)
+ {
+ return ((long) var0 << shift) + (long) base;
+ }
+
+ static
+ {
+ Field f;
+ Unsafe o = null;
+
+ try
+ {
+ f = Unsafe.class.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ o = (Unsafe) f.get(null);
+ }
+
+ catch(Throwable e)
+ {
+ e.printStackTrace();
+ }
+
+ unsafe = o;
+ base = unsafe.arrayBaseOffset(int[].class);
+ int var0 = unsafe.arrayIndexScale(int[].class);
+ if((var0 & var0 - 1) != 0)
+ {
+ throw new Error("data type scale not a power of two");
+ }
+ else
+ {
+ shift = 31 - Integer.numberOfLeadingZeros(var0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ninja/bytecode/iris/atomics/AtomicChunkData.java b/src/main/java/ninja/bytecode/iris/atomics/AtomicChunkData.java
new file mode 100644
index 000000000..27aa7d3aa
--- /dev/null
+++ b/src/main/java/ninja/bytecode/iris/atomics/AtomicChunkData.java
@@ -0,0 +1,359 @@
+package ninja.bytecode.iris.atomics;
+
+import java.lang.reflect.Field;
+
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.craftbukkit.v1_12_R1.generator.CraftChunkData;
+import org.bukkit.generator.ChunkGenerator;
+import org.bukkit.generator.ChunkGenerator.ChunkData;
+import org.bukkit.material.MaterialData;
+
+public final class AtomicChunkData implements ChunkGenerator.ChunkData
+{
+ private static final Field t;
+ private static final int h = 0x1000;
+ private final int maxHeight;
+ private volatile char[] s0;
+ private volatile char[] s1;
+ private volatile char[] s2;
+ private volatile char[] s3;
+ private volatile char[] s4;
+ private volatile char[] s5;
+ private volatile char[] s6;
+ private volatile char[] s7;
+ private volatile char[] s8;
+ private volatile char[] s9;
+ private volatile char[] sA;
+ private volatile char[] sB;
+ private volatile char[] sC;
+ private volatile char[] sD;
+ private volatile char[] sE;
+ private volatile char[] sF;
+ private volatile char[][] m;
+ private World w;
+
+ public AtomicChunkData(World world)
+ {
+ this.maxHeight = world.getMaxHeight();
+ this.w = world;
+ }
+
+ @Override
+ public int getMaxHeight()
+ {
+ return maxHeight;
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setBlock(int x, int y, int z, Material material)
+ {
+ setBlock(x, y, z, material.getId());
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setBlock(int x, int y, int z, MaterialData material)
+ {
+ setBlock(x, y, z, material.getItemTypeId(), material.getData());
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, Material material)
+ {
+ setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.getId());
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, MaterialData material)
+ {
+ setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.getItemTypeId(), material.getData());
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public Material getType(int x, int y, int z)
+ {
+ return Material.getMaterial(getTypeId(x, y, z));
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public MaterialData getTypeAndData(int x, int y, int z)
+ {
+ return getType(x, y, z).getNewData(getData(x, y, z));
+ }
+
+ @Override
+ public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId)
+ {
+ setRegion(xMin, yMin, zMin, xMax, yMax, zMax, blockId, (byte) 0);
+ }
+
+ @Override
+ public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId, int data)
+ {
+ throw new UnsupportedOperationException("AtomicChunkData does not support setting regions");
+ }
+
+ @Override
+ public void setBlock(int x, int y, int z, int blockId)
+ {
+ setBlock(x, y, z, blockId, (byte) 0);
+ }
+
+ @Override
+ public void setBlock(int x, int y, int z, int blockId, byte data)
+ {
+ setBlock(x, y, z, (char) (blockId << 4 | data));
+ }
+
+ @Override
+ public int getTypeId(int x, int y, int z)
+ {
+ if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
+ {
+ return 0;
+ }
+
+ char[] section = getChunkSection(y, false);
+
+ if(section == null)
+ {
+ return 0;
+ }
+
+ else
+ {
+ return section[(y & 0xf) << 8 | z << 4 | x] >> 4;
+ }
+ }
+
+ @Override
+ public byte getData(int x, int y, int z)
+ {
+ if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
+ {
+ return (byte) 0;
+ }
+
+ char[] section = getChunkSection(y, false);
+
+ if(section == null)
+ {
+ return (byte) 0;
+ }
+
+ else
+ {
+ return (byte) (section[(y & 0xf) << 8 | z << 4 | x] & 0xf);
+ }
+ }
+
+ private void setBlock(int x, int y, int z, char type)
+ {
+ if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
+ {
+ return;
+ }
+
+ getChunkSection(y, true)[(y & 0xf) << 8 | z << 4 | x] = type;
+ }
+
+ private char[] getChunkSection(int y, boolean c)
+ {
+ //@done
+ int s = y >> 4;
+
+ if(s == 0)
+ {
+ if(c && s0 == null)
+ {
+ s0 = new char[h];
+ }
+ return s0;
+ }
+ else if(s == 1)
+ {
+ if(c && s1 == null)
+ {
+ s1 = new char[h];
+ }
+ return s1;
+ }
+ else if(s == 2)
+ {
+ if(c && s2 == null)
+ {
+ s2 = new char[h];
+ }
+ return s2;
+ }
+ else if(s == 3)
+ {
+ if(c && s3 == null)
+ {
+ s3 = new char[h];
+ }
+ return s3;
+ }
+ else if(s == 4)
+ {
+ if(c && s4 == null)
+ {
+ s4 = new char[h];
+ }
+ return s4;
+ }
+ else if(s == 5)
+ {
+ if(c && s5 == null)
+ {
+ s5 = new char[h];
+ }
+ return s5;
+ }
+ else if(s == 6)
+ {
+ if(c && s6 == null)
+ {
+ s6 = new char[h];
+ }
+ return s6;
+ }
+ else if(s == 7)
+ {
+ if(c && s7 == null)
+ {
+ s7 = new char[h];
+ }
+ return s7;
+ }
+ else if(s == 8)
+ {
+ if(c && s8 == null)
+ {
+ s8 = new char[h];
+ }
+ return s8;
+ }
+ else if(s == 9)
+ {
+ if(c && s9 == null)
+ {
+ s9 = new char[h];
+ }
+ return s9;
+ }
+ else if(s == 10)
+ {
+ if(c && sA == null)
+ {
+ sA = new char[h];
+ }
+ return sA;
+ }
+ else if(s == 11)
+ {
+ if(c && sB == null)
+ {
+ sB = new char[h];
+ }
+ return sB;
+ }
+ else if(s == 12)
+ {
+ if(c && sC == null)
+ {
+ sC = new char[h];
+ }
+ return sC;
+ }
+ else if(s == 13)
+ {
+ if(c && sD == null)
+ {
+ sD = new char[h];
+ }
+ return sD;
+ }
+ else if(s == 14)
+ {
+ if(c && sE == null)
+ {
+ sE = new char[h];
+ }
+ return sE;
+ }
+ else if(s == 15)
+ {
+ if(c && sF == null)
+ {
+ sF = new char[h];
+ }
+ return sF;
+ }
+
+ else
+ {
+ System.out.print("CANT FIND SECTION: " + s);
+ }
+
+ return null;
+ //@done
+ }
+
+ public ChunkData toChunkData()
+ {
+ ChunkData c = new CraftChunkData(w);
+
+ try
+ {
+ m = (char[][]) t.get(c);
+ m[0] = s0;
+ m[1] = s1;
+ m[2] = s2;
+ m[3] = s3;
+ m[4] = s4;
+ m[5] = s5;
+ m[6] = s6;
+ m[7] = s7;
+ m[8] = s8;
+ m[9] = s9;
+ m[10] = sA;
+ m[11] = sB;
+ m[12] = sC;
+ m[13] = sD;
+ m[14] = sE;
+ m[15] = sF;
+ }
+
+ catch(IllegalArgumentException | IllegalAccessException e)
+ {
+ e.printStackTrace();
+ }
+
+ return c;
+ }
+
+ static
+ {
+ Field x = null;
+
+ try
+ {
+ x = CraftChunkData.class.getDeclaredField("sections");
+ x.setAccessible(true);
+ }
+
+ catch(Throwable e)
+ {
+ e.printStackTrace();
+ }
+
+ t = x;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayer.java b/src/main/java/ninja/bytecode/iris/gen/GenLayer.java
new file mode 100644
index 000000000..f2d376795
--- /dev/null
+++ b/src/main/java/ninja/bytecode/iris/gen/GenLayer.java
@@ -0,0 +1,27 @@
+package ninja.bytecode.iris.gen;
+
+import java.util.Random;
+
+import org.bukkit.World;
+
+import ninja.bytecode.shuriken.math.RNG;
+
+public class GenLayer implements IGenLayer
+{
+ protected RNG rng;
+ protected World world;
+ protected Random random;
+
+ public GenLayer(World world, Random random, RNG rng)
+ {
+ this.world = world;
+ this.random = random;
+ this.rng = rng;
+ }
+
+ @Override
+ public double generateLayer(double noise, double dx, double dz)
+ {
+ return 0;
+ }
+}
diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java
new file mode 100644
index 000000000..a97591328
--- /dev/null
+++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java
@@ -0,0 +1,72 @@
+package ninja.bytecode.iris.gen;
+
+import java.util.Random;
+
+import org.bukkit.World;
+
+import ninja.bytecode.shuriken.math.CNG;
+import ninja.bytecode.shuriken.math.RNG;
+
+public class GenLayerBase extends GenLayer
+{
+ private double[][][] scatterCache;
+ private CNG gen;
+ private CNG fracture;
+ private CNG basegen;
+
+ public GenLayerBase(World world, Random random, RNG rng)
+ {
+ //@builder
+ super(world, random, rng);
+ scatterCache = new double[16][][];
+ CNG scatter = new CNG(rng.nextRNG(), 1, 1)
+ .scale(10);
+ basegen = new CNG(rng.nextRNG(), 0.46, 3)
+ .scale(0.00295)
+ .fractureWith(new CNG(rng.nextRNG(), 1, 2)
+ .scale(0.025), 70);
+ gen = new CNG(rng.nextRNG(), 0.19D, 4)
+ .scale(0.012)
+ .amp(0.5)
+ .freq(1.1)
+ .fractureWith(new CNG(rng.nextRNG(), 1, 2)
+ .scale(0.018)
+ .fractureWith(new CNG(rng.nextRNG(), 1, 1)
+ .scale(0.15), 24), 44);
+ fracture = new CNG(rng.nextRNG(), 0.6D, 4)
+ .scale(0.118);
+// faultline = new CNG(rng.nextRNG(), 1D, 1)
+// .scale(0.005)
+// .child(new CNG(rng.nextRNG(), 1D, 1)
+// .scale(0.012))
+// .injectWith(CNG.MULTIPLY)
+// .fractureWith(new CNG(rng.nextRNG(), 1, 1)
+// .scale(0.07), 200);
+ //@done
+
+ for(int i = 0; i < 16; i++)
+ {
+ scatterCache[i] = new double[16][];
+
+ for(int j = 0; j < 16; j++)
+ {
+ scatterCache[i][j] = new double[16];
+
+ for(int k = 0; k < 16; k++)
+ {
+ scatterCache[i][j][k] = scatter.noise(i, j, k);
+ }
+ }
+ }
+ }
+
+ @Override
+ public double generateLayer(double noise, double dx, double dz)
+ {
+ super.generateLayer(noise, dx, dz);
+ double fnoise = fracture.noise(dx, dz);
+ double fx = dx + (fnoise * 12);
+ double fz = dz - (fnoise * 12);
+ return basegen.noise(fx, fz) + gen.noise(fx, fz);
+ }
+}
diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerFracture.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerFracture.java
new file mode 100644
index 000000000..163cac90d
--- /dev/null
+++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerFracture.java
@@ -0,0 +1,18 @@
+package ninja.bytecode.iris.gen;
+
+import java.util.Random;
+
+import org.bukkit.World;
+
+import ninja.bytecode.shuriken.math.RNG;
+
+public class GenLayerFracture extends GenLayer
+{
+
+ public GenLayerFracture(World world, Random random, RNG rng)
+ {
+ super(world, random, rng);
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/src/main/java/ninja/bytecode/iris/gen/IGenLayer.java b/src/main/java/ninja/bytecode/iris/gen/IGenLayer.java
new file mode 100644
index 000000000..81dcd8593
--- /dev/null
+++ b/src/main/java/ninja/bytecode/iris/gen/IGenLayer.java
@@ -0,0 +1,6 @@
+package ninja.bytecode.iris.gen;
+
+public interface IGenLayer
+{
+ public double generateLayer(double noise, double dx, double dz);
+}