From b29ad7ed0c0d43fbf8bb5ab49d6d81f20f5b30e1 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 14 Oct 2019 05:23:50 -0400 Subject: [PATCH] bam --- src/main/java/ninja/bytecode/iris/Iris.java | 55 ++- .../ninja/bytecode/iris/IrisGenerator.java | 85 +++-- .../bytecode/iris/ParallelChunkGenerator.java | 31 +- .../iris/atomics/AtomicChunkData.java | 1 + .../ninja/bytecode/iris/gen/GenLayerBase.java | 43 +-- .../bytecode/iris/gen/GenLayerBiome.java | 78 +++++ .../bytecode/iris/gen/GenLayerDeppOcean.java | 28 ++ .../bytecode/iris/gen/GenLayerFracture.java | 18 - .../ninja/bytecode/iris/gen/GenLayerSnow.java | 37 +++ .../ninja/bytecode/iris/util/RealBiome.java | 314 ++++++++++++++++++ 10 files changed, 608 insertions(+), 82 deletions(-) create mode 100644 src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java create mode 100644 src/main/java/ninja/bytecode/iris/gen/GenLayerDeppOcean.java delete mode 100644 src/main/java/ninja/bytecode/iris/gen/GenLayerFracture.java create mode 100644 src/main/java/ninja/bytecode/iris/gen/GenLayerSnow.java create mode 100644 src/main/java/ninja/bytecode/iris/util/RealBiome.java diff --git a/src/main/java/ninja/bytecode/iris/Iris.java b/src/main/java/ninja/bytecode/iris/Iris.java index adc372903..127cc9d3f 100644 --- a/src/main/java/ninja/bytecode/iris/Iris.java +++ b/src/main/java/ninja/bytecode/iris/Iris.java @@ -7,29 +7,49 @@ import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.WorldCreator; +import org.bukkit.entity.Player; 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.collections.GSet; import ninja.bytecode.shuriken.execution.TaskExecutor; public class Iris extends JavaPlugin implements Listener { - public static TaskExecutor executor; - + public static TaskExecutor noisePool; + public static IrisGenerator gen; + public void onEnable() { - executor = new TaskExecutor(1, Thread.MIN_PRIORITY, "Iris Generator"); + gen = new IrisGenerator(); + noisePool = new TaskExecutor(4, Thread.MIN_PRIORITY, "Iris Generator"); getServer().getPluginManager().registerEvents((Listener) this, this); + + // Debug world regens + GSet ws = new GSet<>(); + World w = createIrisWorld(); + for(Player i : Bukkit.getOnlinePlayers()) + { + ws.add(i.getWorld().getName()); + i.teleport(new Location(w, 0, 256, 0)); + i.setFlying(true); + i.setGameMode(GameMode.CREATIVE); + } + + for(String i : ws) + { + Bukkit.unloadWorld(i, false); + } } - + public void onDisable() { - executor.close(); + noisePool.close(); } - + @Override public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { @@ -41,17 +61,24 @@ public class Iris extends JavaPlugin implements Listener { 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)); + World wold = e.getPlayer().getWorld(); + World w = createIrisWorld(); + e.getPlayer().teleport(new Location(w, 0, 256, 0)); e.getPlayer().setFlying(true); e.getPlayer().setGameMode(GameMode.CREATIVE); e.setCancelled(true); + wold.setAutoSave(false); + Bukkit.unloadWorld(wold, false); } } + + private World createIrisWorld() + { + 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); + return ww; + } } diff --git a/src/main/java/ninja/bytecode/iris/IrisGenerator.java b/src/main/java/ninja/bytecode/iris/IrisGenerator.java index 0e4b74c35..2bdb2eecf 100644 --- a/src/main/java/ninja/bytecode/iris/IrisGenerator.java +++ b/src/main/java/ninja/bytecode/iris/IrisGenerator.java @@ -4,64 +4,103 @@ import java.util.Random; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.Biome; import ninja.bytecode.iris.gen.GenLayerBase; +import ninja.bytecode.iris.gen.GenLayerBiome; import ninja.bytecode.iris.gen.IGenLayer; +import ninja.bytecode.iris.util.RealBiome; import ninja.bytecode.shuriken.collections.GList; -import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.RNG; public class IrisGenerator extends ParallelChunkGenerator { - private static final MB water = new MB(Material.STATIONARY_WATER); - private static final MB bedrock = new MB(Material.BEDROCK); - private static final MB air = new MB(Material.AIR); - private static final MB grass = new MB(Material.GRASS); - private static final MB[] earth = {new MB(Material.DIRT), new MB(Material.DIRT, 1), - }; - private static final MB[] sand = {new MB(Material.SAND), new MB(Material.SAND), new MB(Material.SAND, 1), - }; - private static final MB[] sandygrass = {new MB(Material.GRASS), new MB(Material.SAND, 1), - }; - private static final MB[] rock = {new MB(Material.STONE), new MB(Material.STONE, 5), new MB(Material.COBBLESTONE), - }; private GList genLayers; + private GenLayerBiome glBiome; + private GenLayerBase glBase; + private int waterLevel = 127; @Override public void onInit(World world, Random random) { RNG rng = new RNG(world.getSeed()); genLayers = new GList<>(); - genLayers.add(new GenLayerBase(world, random, rng)); - System.out.print("Gend"); + genLayers.add(glBiome = new GenLayerBiome(world, random, rng)); + genLayers.add(glBase = new GenLayerBase(world, random, rng)); } public int getHeight(double dx, double 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 > 254 ? 254 : n; n = n < 0 ? 0 : n; return (int) n; } @Override - public void genColumn(final int wx, final int wz) + public Biome genColumn(int wx, int wz, int x, int z) { int height = getHeight(wx, wz); - MB mb = rock[0]; - - for(int i = 0; i < height; i++) + RealBiome b = glBiome.getBiome(wx, wz); + boolean underwater = height < waterLevel; + + for(int i = 0; i < Math.max(height, waterLevel); i++) { - setBlock(wx, i, wz, mb.material, mb.data); + MB mb = underwater ? new MB(Material.STATIONARY_WATER) : new MB(Material.AIR); + + if(i > height && underwater) + { + mb = new MB(Material.STATIONARY_WATER); + } + + else if(i == 0 || (i == 1 && glBase.scatterChance(wx, i, wz, 0.45))) + { + mb = new MB(Material.BEDROCK); + } + + else if(i == height - 1) + { + if(underwater) + { + mb = new MB(Material.SAND); + } + + else + { + mb = b.surface(wx, i, wz, glBase); + } + } + + else if(i > height - glBase.scatterInt(wx, i, wz, 12)) + { + if(underwater) + { + mb = new MB(Material.SAND); + } + + else + { + mb = b.dirt(wx, i, wz, glBase); + } + } + + else + { + mb = b.rock(wx, i, wz, glBase); + } + + setBlock(x, i, z, mb.material, mb.data); } + + return b.getBiome(); } public int pick(int max, double noise) diff --git a/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java b/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java index 304ac0ddf..de26a5fcf 100644 --- a/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java +++ b/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java @@ -4,14 +4,16 @@ import java.util.Random; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.Biome; 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; import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup; +import ninja.bytecode.shuriken.execution.TaskExecutor.TaskResult; import ninja.bytecode.shuriken.format.F; +import ninja.bytecode.shuriken.math.RollingSequence; public abstract class ParallelChunkGenerator extends ChunkGenerator { @@ -23,12 +25,13 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator private TaskGroup tg; private boolean ready = false; private ChronoLatch cl = new ChronoLatch(1000); + private RollingSequence rs = new RollingSequence(512); public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) { Shuriken.profiler.start("chunkgen-" + world.getName()); data = new AtomicChunkData(world); - + try { if(!ready) @@ -37,7 +40,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator ready = true; } - tg = Iris.executor.startWork(); + tg = Iris.noisePool.startWork(); for(i = 0; i < 16; i++) { @@ -48,16 +51,25 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator wz = (z * 16) + j; int a = wx; int b = wz; - tg.queue(() -> genColumn(a, b)); + int c = i; + int d = j; + tg.queue(() -> + { + synchronized(biome) + { + biome.setBiome(c, d, genColumn(a, b, c, d)); + } + }); } } - tg.execute(); + TaskResult r = tg.execute(); + rs.put(r.timeElapsed); 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))); + System.out.print("Avg: " + F.duration(rs.getAverage(), 2) + " " + F.duration(rs.getMax(), 2) + " / " + F.duration(rs.getMedian(), 2) + " / " + F.duration(rs.getMin(), 2)); } } @@ -77,7 +89,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator public abstract void onInit(World world, Random random); - public abstract void genColumn(int wx, int wz); + public abstract Biome genColumn(int wx, int wz, int x, int z); @SuppressWarnings("deprecation") protected void setBlock(int x, int y, int z, Material b) @@ -98,6 +110,9 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator protected void setBlock(int x, int y, int z, int b, byte d) { - data.setBlock(x, y, z, b, d); + synchronized(data) + { + data.setBlock(x, y, z, b, d); + } } } \ 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 index 27aa7d3aa..4bd10cc56 100644 --- a/src/main/java/ninja/bytecode/iris/atomics/AtomicChunkData.java +++ b/src/main/java/ninja/bytecode/iris/atomics/AtomicChunkData.java @@ -174,6 +174,7 @@ public final class AtomicChunkData implements ChunkGenerator.ChunkData { s0 = new char[h]; } + return s0; } else if(s == 1) diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java index a97591328..b63a5fa2c 100644 --- a/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java @@ -12,7 +12,6 @@ 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) { @@ -21,27 +20,19 @@ public class GenLayerBase extends GenLayer 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) + gen = new CNG(rng.nextRNG(), 0.19D, 16) .scale(0.012) .amp(0.5) .freq(1.1) - .fractureWith(new CNG(rng.nextRNG(), 1, 2) + .fractureWith(new CNG(rng.nextRNG(), 1, 6) .scale(0.018) - .fractureWith(new CNG(rng.nextRNG(), 1, 1) + .injectWith(CNG.MULTIPLY) + .child(new CNG(rng.nextRNG(), 0.745, 2) + .scale(0.1)) + .fractureWith(new CNG(rng.nextRNG(), 1, 3) .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++) @@ -60,13 +51,27 @@ public class GenLayerBase extends GenLayer } } + public int scatterInt(int x, int y, int z, int bound) + { + return (int) (scatter(x, y, z) * (double) (bound - 1)); + } + + public double scatter(int x, int y, int z) + { + return scatterCache[Math.abs(x) % 16][Math.abs(y) % 16][Math.abs(z) % 16]; + } + + public boolean scatterChance(int x, int y, int z, double chance) + { + return scatter(x, y, z) > chance; + } + @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); + dx += (fnoise * 44); + dz -= (fnoise * 44); + return ((noise * 0.5) + (gen.noise(dx, dz) * (0.15 + (noise * 0.65)))) + 0.31; } } diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java new file mode 100644 index 000000000..f98431547 --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java @@ -0,0 +1,78 @@ +package ninja.bytecode.iris.gen; + +import java.util.Random; + +import org.bukkit.World; + +import ninja.bytecode.iris.util.RealBiome; +import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.M; +import ninja.bytecode.shuriken.math.RNG; + +public class GenLayerBiome extends GenLayer +{ + private CNG temperature; + private CNG humidity; + private CNG hfracture; + private CNG alt; + private CNG height; + private CNG ocean; + + public GenLayerBiome(World world, Random random, RNG rng) + { + super(world, random, rng); + //@builder + temperature = new CNG(rng.nextRNG(), 1, 2) + .scale(0.0018) + .fractureWith(new CNG(rng.nextRNG(), 1, 1).scale(0.06), 23); + hfracture = new CNG(rng.nextRNG(), 1, 2) + .scale(0.0124); + humidity = new CNG(rng.nextRNG(), 1, 2) + .scale(0.0024) + .fractureWith(new CNG(rng.nextRNG(), 1, 1).scale(0.06), 12); + height = new CNG(rng.nextRNG(), 1, 8) + .scale(0.0017601) + .fractureWith(new CNG(rng.nextRNG(), 1, 6) + .scale(0.0574) + .fractureWith(new CNG(rng.nextRNG(), 1, 1), 30) + .scale(0.116), 3); + ocean = new CNG(rng.nextRNG(), 1, 3) + .scale(0.0004601) + .fractureWith(new CNG(rng.nextRNG(), 1, 4).scale(0.016), 499); + alt = new CNG(rng.nextRNG(), 1, 1) + .scale(0.0008) + .fractureWith(new CNG(rng.nextRNG(), 1, 1).scale(0.3), 100); + //@done + } + + public RealBiome getBiome(double x, double z) + { + return RealBiome.match(getTemperature(x, z) * 2, getHumidity(x, z), getHeight(x, z), getAlt(x, z)); + } + + private double getAlt(double x, double z) + { + return alt.noise(x, z); + } + + public double getTemperature(double x, double z) + { + return M.clip(temperature.noise(x, z) - (getHeight(x, z) * 0.45), 0D, 1D); + } + + public double getHumidity(double x, double z) + { + return humidity.noise(x, z); + } + + public double getHeight(double x, double z) + { + return M.clip(Math.pow(height.noise(x + (hfracture.noise(x, z) * 180), z + (hfracture.noise(z, x) * 180)), 3) * 2.654, 0D, 1D); + } + + @Override + public double generateLayer(double noise, double dx, double dz) + { + return getHeight(dx, dz); + } +} diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerDeppOcean.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerDeppOcean.java new file mode 100644 index 000000000..61f098db4 --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerDeppOcean.java @@ -0,0 +1,28 @@ +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 GenLayerDeppOcean extends GenLayer +{ + private CNG gen; + + public GenLayerDeppOcean(World world, Random random, RNG rng) + { + //@builder + super(world, random, rng); + gen = new CNG(rng.nextRNG(), 1D, 4) + .scale(0.012); + //@done + } + + @Override + public double generateLayer(double noise, double dx, double dz) + { + double deeper = gen.noise(dx, dz); + } +} diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerFracture.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerFracture.java deleted file mode 100644 index 163cac90d..000000000 --- a/src/main/java/ninja/bytecode/iris/gen/GenLayerFracture.java +++ /dev/null @@ -1,18 +0,0 @@ -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/GenLayerSnow.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerSnow.java new file mode 100644 index 000000000..091d5e163 --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerSnow.java @@ -0,0 +1,37 @@ +package ninja.bytecode.iris.gen; + +import java.util.Random; + +import org.bukkit.Material; +import org.bukkit.World; + +import ninja.bytecode.iris.MB; +import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.RNG; + +public class GenLayerSnow extends GenLayer +{ + private CNG snow; + + public GenLayerSnow(World world, Random random, RNG rng) + { + super(world, random, rng); + //@builder + snow = new CNG(rng.nextRNG(), 1, 1) + .scale(0.1); + //@done + } + + public MB getSnow(double dx, double dz, double snowChance) + { + int m = (int) ((snowChance * 14) * snow.noise(dx, dz)); + m = m > 7 ? 7 : m; + return new MB(Material.SNOW, m); + } + + @Override + public double generateLayer(double noise, double dx, double dz) + { + return noise; + } +} diff --git a/src/main/java/ninja/bytecode/iris/util/RealBiome.java b/src/main/java/ninja/bytecode/iris/util/RealBiome.java new file mode 100644 index 000000000..fb9277f2c --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/util/RealBiome.java @@ -0,0 +1,314 @@ +package ninja.bytecode.iris.util; + +import org.bukkit.Material; +import org.bukkit.block.Biome; + +import ninja.bytecode.iris.MB; +import ninja.bytecode.iris.gen.GenLayerBase; +import ninja.bytecode.shuriken.collections.GList; + +public class RealBiome +{ + public static final double a = 0; + public static final double h = 0.5; + public static final double t = 0.5; + + //@builder + public static final RealBiome[] biomes = { + new RealBiome(0, 0.5, h, -1).water(), // Ocean + new RealBiome(1, 0.6, 0.4, 0.125), // Plains + new RealBiome(2, 2, 0, 0.125) // Desert + .surface(new MB(Material.SAND)) + .dirt(new MB(Material.SAND), new MB(Material.SAND, 1)) + .rock(new MB(Material.SANDSTONE)), + new RealBiome(3, 0.2, 0.3, 0.56), // Extreme Hills + new RealBiome(4, 0.5, 0.8, a), // Forest + new RealBiome(5, 0.25, 0.8, 0.2), // Taiga + new RealBiome(6, 0.8, 0.9, -0.2), // Swampland + new RealBiome(7, t, h, -0.5).river(), // River + new RealBiome(8, 2, 0, a).dimensional(), // Hell + new RealBiome(9, t, h, a).dimensional(), // The End + new RealBiome(10, 0, 0.5, -1).water(), // Frozen Ocean + new RealBiome(11, 0, 0.5, -0.5).river(), // Frozen River + new RealBiome(12, 0, 0.5, 0.125).surface(new MB(Material.SNOW_BLOCK)), // Ice Plains + new RealBiome(13, 0, 0.5, 0.765) // Ice Mountains + .surface(new MB(Material.SNOW_BLOCK)) + .dirt(new MB(Material.PACKED_ICE)), + new RealBiome(14, 0.9, 1, 0.2).modifier() // Mushroom Island + .surface(new MB(Material.MYCEL)), + new RealBiome(15, 0, 1, 0).modifier() // Mushroom Island Shore + .surface(new MB(Material.MYCEL)), + new RealBiome(16, 0.8, 0.4, 0).beach(), // Beaches + new RealBiome(17, 2, 0, 0.75) // Desert Hills + .surface(new MB(Material.SAND)) + .dirt(new MB(Material.SAND), new MB(Material.SAND, 1)) + .rock(new MB(Material.SANDSTONE)), + new RealBiome(18, 0.6, 0.8, 0.75), // Forest Hills + new RealBiome(19, 0.25, 0.8, 0.75), // Taiga Hills + new RealBiome(20, 0.2, 0.3, 0.8), // Extreme Hills Edge + new RealBiome(21, 0.95, 0.9, a), // Jungle + new RealBiome(22, 0.95, 0.9, 0.75), // Jungle + new RealBiome(23, 0.9, 0.9, 0.15), // Jungle Edge + new RealBiome(24, t, h, -1.8).water(), // Deep Ocean + new RealBiome(25, 0.2, 0.3, 0.1).beach(), // Stone Beach + new RealBiome(26, 0.2, 0.3, 0).beach(), // Cold Beach + new RealBiome(27, 0.5, 0.5, a), // Birch Forest + new RealBiome(28, 0.4, 0.4, 0.25), // Birch Forest Hills + new RealBiome(29, 0.7, 0.8, a), // Roofed Forest + new RealBiome(30, -0.5, 0.4, 0.2), // Cold Taiga + new RealBiome(31, -0.5, 0.4, 0.75), // Cold Taiga Hills + new RealBiome(32, 0.4, 0.8, 0.2), // Redwood Taiga + new RealBiome(33, 0.3, 0.8, 0.75), // Redwood Taiga Hills + new RealBiome(34, 0.2, 0.3, 1), // Extra Hills with Trees + new RealBiome(35, 1.2, 0, 0.125), // Savanna + new RealBiome(36, 1, 0, 0.28), // Savanna Plateau + new RealBiome(37, 2, 0, a), // Mesa + new RealBiome(38, 2, 0, 0.28), // Mesa Plateau F + new RealBiome(39, 2, 0, 0.31), // Mesa Plateau + }; + //@done + + private int biomeId; + private double temperature; + private double humidity; + private double height; + private boolean modifier; + private boolean river; + private boolean water; + private boolean beach; + private boolean dimensional; + private GList surface; + private GList dirt; + private GList rock; + private boolean defs; + private boolean defd; + private boolean defr; + + public RealBiome(int biomeId, double temperature, double humidity, double height) + { + defs = true; + defd = true; + defr = true; + this.biomeId = biomeId; + this.temperature = temperature; + this.humidity = humidity; + this.height = height; + surface = new GList<>(); + dirt = new GList<>(); + rock = new GList<>(); + surface.add(new MB(Material.GRASS)); + dirt.add(new MB(Material.DIRT), new MB(Material.DIRT, 1)); + rock.add(new MB(Material.STONE), new MB(Material.STONE, 5), new MB(Material.COBBLESTONE)); + temperature = temperature > 1 ? 1 : temperature < 0 ? 0 : temperature; + humidity = humidity > 1 ? 1 : humidity < 0 ? 0 : humidity; + height = height > 1 ? 1 : height < 0 ? 0 : height; + } + + public static RealBiome match(double temperature, double humidity, double height, double d) + { + GList b = new GList<>(); + double distance = Double.MAX_VALUE; + + for(RealBiome i : biomes) + { + if(i.modifier) + { + continue; + } + + double dist = i.getDistance(temperature, humidity, height); + if(dist < distance) + { + distance = dist; + b.add(i); + } + } + + return b.get((int) (d * Math.min(b.size(), 3))); + } + + public double getDistance(double temperature, double humidity, double height) + { + return Math.abs((temperature - this.temperature) * 3.5) + Math.abs((humidity - this.humidity) * 2.5) + Math.abs((height - this.height) * 4.8); + } + + public Biome getBiome() + { + return Biome.values()[biomeId]; + } + + public RealBiome surface(MB... mb) + { + if(defs) + { + defs = false; + surface.clear(); + } + this.surface.add(mb); + return this; + } + + public RealBiome dirt(MB... mb) + { + if(defd) + { + defd = false; + dirt.clear(); + } + + this.dirt.add(mb); + return this; + } + + public RealBiome rock(MB... mb) + { + if(defr) + { + defr = false; + rock.clear(); + } + + this.rock.add(mb); + return this; + } + + public RealBiome modifier() + { + modifier = true; + return this; + } + + public RealBiome river() + { + river = true; + return this.modifier(); + } + + public RealBiome water() + { + water = true; + return this.modifier(); + } + + public RealBiome beach() + { + beach = true; + return this.modifier(); + } + + public RealBiome dimensional() + { + dimensional = true; + return this.modifier(); + } + + public MB surface(int x, int y, int z, GenLayerBase glBase) + { + return surface.get(glBase.scatterInt(x, y, z, surface.size())); + } + + public MB dirt(int x, int y, int z, GenLayerBase glBase) + { + return dirt.get(glBase.scatterInt(x, y, z, dirt.size())); + } + + public MB rock(int x, int y, int z, GenLayerBase glBase) + { + return rock.get(glBase.scatterInt(x, y, z, rock.size())); + } + + public static double getA() + { + return a; + } + + public static double getH() + { + return h; + } + + public static double getT() + { + return t; + } + + public static RealBiome[] getBiomes() + { + return biomes; + } + + public int getBiomeId() + { + return biomeId; + } + + public double getTemperature() + { + return temperature; + } + + public double getHumidity() + { + return humidity; + } + + public double getHeight() + { + return height; + } + + public boolean isModifier() + { + return modifier; + } + + public boolean isRiver() + { + return river; + } + + public boolean isWater() + { + return water; + } + + public boolean isBeach() + { + return beach; + } + + public boolean isDimensional() + { + return dimensional; + } + + public GList getSurface() + { + return surface; + } + + public GList getDirt() + { + return dirt; + } + + public GList getRock() + { + return rock; + } + + public boolean isDefs() + { + return defs; + } + + public boolean isDefd() + { + return defd; + } + + public boolean isDefr() + { + return defr; + } +}