diff --git a/src/main/java/ninja/bytecode/iris/Iris.java b/src/main/java/ninja/bytecode/iris/Iris.java index 4201e6161..cd054a5da 100644 --- a/src/main/java/ninja/bytecode/iris/Iris.java +++ b/src/main/java/ninja/bytecode/iris/Iris.java @@ -1,46 +1,63 @@ package ninja.bytecode.iris; import java.util.UUID; +import java.util.function.Function; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.WorldCreator; +import org.bukkit.block.Biome; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; +import ninja.bytecode.iris.util.RealBiome; +import ninja.bytecode.shuriken.bench.Profiler; +import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GSet; +import ninja.bytecode.shuriken.execution.J; import ninja.bytecode.shuriken.execution.TaskExecutor; +import ninja.bytecode.shuriken.format.F; +import ninja.bytecode.shuriken.math.M; public class Iris extends JavaPlugin implements Listener { - public static TaskExecutor noisePool; + public static Profiler profiler; + public static TaskExecutor genPool; public static IrisGenerator gen; public static Settings settings; public static Iris instance; + public static GMap>> values; public void onEnable() { + profiler = new Profiler(512); + values = new GMap<>(); instance = this; settings = new Settings(); gen = new IrisGenerator(); - noisePool = new TaskExecutor(settings.performance.threadCount, settings.performance.threadPriority, "Iris Noise Generator"); + genPool = new TaskExecutor(getTC(), settings.performance.threadPriority, "Iris Generator"); getServer().getPluginManager().registerEvents((Listener) this, this); - + // Debug world regens GSet ws = new GSet<>(); + World w = createIrisWorld(); for(Player i : Bukkit.getOnlinePlayers()) { + Location m = i.getLocation(); ws.add(i.getWorld().getName()); - i.teleport(new Location(w, 0, 256, 0)); + i.teleport(new Location(w, m.getX(), m.getY(), m.getZ(), m.getYaw(), m.getPitch())); i.setFlying(true); - i.setGameMode(GameMode.CREATIVE); + i.setGameMode(GameMode.SPECTATOR); } for(String i : ws) @@ -49,9 +66,30 @@ public class Iris extends JavaPlugin implements Listener } } + private int getTC() + { + switch(settings.performance.performanceMode) + { + case HALF_CPU: + return Math.max(Runtime.getRuntime().availableProcessors() / 2, 1); + case MATCH_CPU: + return Runtime.getRuntime().availableProcessors(); + case SINGLE_THREADED: + return 1; + case UNLIMITED: + return -1; + case EXPLICIT: + return settings.performance.threadCount; + default: + break; + } + + return Math.max(Runtime.getRuntime().availableProcessors() / 2, 1); + } + public void onDisable() { - noisePool.close(); + genPool.close(); } @Override @@ -74,6 +112,52 @@ public class Iris extends JavaPlugin implements Listener wold.setAutoSave(false); Bukkit.unloadWorld(wold, false); } + + if(e.getMessage().toLowerCase().equals("/iris info")) + { + e.setCancelled(true); + sendInfo(e.getPlayer()); + + for(Biome i : Biome.values()) + { + J.attempt(() -> System.out.print(new RealBiome(i))); + } + } + } + + private void sendInfo(Player player) + { + for(int i = 0; i < 18; i++) + { + player.sendMessage(""); + } + + GMap> w = values.get(player.getWorld().getName()); + for(String i : w.k()) + { + double value = w.get(i).apply(player.getLocation().toVector()); + String p = i.substring(0, 2); + String v = value + ""; + + if(p.startsWith("%")) + { + v = F.pc(value, Integer.valueOf(p.substring(1))); + } + + if(p.startsWith("D")) + { + v = F.f(value, Integer.valueOf(p.substring(1))); + } + + else if(p.startsWith("^")) + { + double c = M.percentRange(value, -11, 37); + double f = 32 + (c * (1.8)); + v = F.f(c, Integer.valueOf(p.substring(1))) + " \u00B0C / " + F.f(f, Integer.valueOf(p.substring(1))) + " \u00B0F"; + } + + player.sendMessage(ChatColor.GREEN + i.substring(2) + ": " + ChatColor.RESET + ChatColor.WHITE + ChatColor.BOLD + v); + } } private World createIrisWorld() @@ -85,4 +169,14 @@ public class Iris extends JavaPlugin implements Listener ww.setSpawnLocation(0, 256, 0); return ww; } + + public static void v(String w, String t, Function d) + { + if(!values.containsKey(w)) + { + values.put(w, new GMap<>()); + } + + values.get(w).put(t, d); + } } diff --git a/src/main/java/ninja/bytecode/iris/IrisGenerator.java b/src/main/java/ninja/bytecode/iris/IrisGenerator.java index e3ba7be12..119efd076 100644 --- a/src/main/java/ninja/bytecode/iris/IrisGenerator.java +++ b/src/main/java/ninja/bytecode/iris/IrisGenerator.java @@ -1,19 +1,27 @@ package ninja.bytecode.iris; +import java.awt.Polygon; +import java.awt.geom.Point2D; +import java.awt.geom.Point2D.Double; +import java.util.List; import java.util.Random; -import org.bukkit.Chunk; +import org.apache.logging.log4j.core.layout.GelfLayout; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Biome; +import org.bukkit.generator.BlockPopulator; import org.bukkit.util.Vector; +import org.bukkit.util.noise.PerlinNoiseGenerator; +import net.minecraft.server.v1_12_R1.GenLayer; +import net.minecraft.server.v1_12_R1.WorldProviderNormal; import ninja.bytecode.iris.gen.GenLayerBase; -import ninja.bytecode.iris.gen.GenLayerBiome; -import ninja.bytecode.iris.gen.GenLayerDeepOcean; +import ninja.bytecode.iris.gen.GenLayerSuperSample; import ninja.bytecode.iris.gen.IGenLayer; -import ninja.bytecode.iris.util.RealBiome; import ninja.bytecode.shuriken.collections.GList; +import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.RNG; public class IrisGenerator extends ParallelChunkGenerator @@ -23,119 +31,66 @@ public class IrisGenerator extends ParallelChunkGenerator private MB SAND = new MB(Material.SAND); private MB BEDROCK = new MB(Material.BEDROCK); private GList genLayers; - private GenLayerBiome glBiome; private GenLayerBase glBase; + private GenLayerSuperSample glSuperSample; private int waterLevel = 127; private GList updates = new GList<>(); - - public void doUpdates(Chunk c) - { - for(Vector i : updates) - { - c.getBlock(i.getBlockX(), i.getBlockY(), i.getBlockZ()).getState().update(true); - } - - updates.clear(); - } + private String wf; @Override public void onInit(World world, Random random) { + wf = world.getName(); updates = new GList<>(); genLayers = new GList<>(); RNG rng = new RNG(world.getSeed()); - genLayers.add(glBiome = new GenLayerBiome(world, random, rng.nextRNG())); - genLayers.add(glBase = new GenLayerBase(world, random, rng.nextRNG())); - genLayers.add(new GenLayerDeepOcean(world, random, rng.nextRNG())); + genLayers.add(glBase = new GenLayerBase(this, world, random, rng.nextRNG())); + genLayers.add(glSuperSample = new GenLayerSuperSample(this, world, random, rng.nextRNG())); } public int getHeight(double dx, double dz) { - double noise = 0.5; + double height = M.clip(glSuperSample.getSuperSampledHeight(dx, dz), 0D, 1D); + + return (int) (height * 253); + } + + public double getRawHeight(double dx, double dz) + { + double noise = 0 + Iris.settings.gen.baseHeight; for(IGenLayer i : genLayers) { noise = i.generateLayer(noise, dx, dz); } - double n = noise * 250; - n = n > 254 ? 254 : n; - n = n < 0 ? 0 : n; - - return (int) n; + return M.clip(noise, 0D, 1D); } @Override - public Biome genColumn(int wx, int wz, int x, int z) + public Biome genColumn(int wxx, int wzx, int x, int z) { + int wx = (int) Math.round((double) wxx * Iris.settings.gen.horizontalZoom); + int wz = (int) Math.round((double) wzx * Iris.settings.gen.horizontalZoom); int height = getHeight(wx, wz); - double temp = glBiome.getTemperature(wx, wz, height); - RealBiome b = glBiome.getBiome(wx, wz, temp, height); - boolean underwater = height < waterLevel; - - // Change biome to ocean / deep ocean if underwater height - if(underwater) + + for(int i = 0; i < height; i++) { - b = RealBiome.biomes[Biome.OCEAN.ordinal()]; - } - - if(height > 122 && height < 128 + (temp * 1.5) + (glBase.scatter(wx, wx * wz, wz) * 3.35)) - { - b = RealBiome.biomes[Biome.BEACHES.ordinal()]; - } - - for(int i = 0; i < Math.max(height, waterLevel); i++) - { - MB mb = AIR; - - // Bedrockify - if(i == 0 || (!Iris.settings.gen.flatBedrock && ((i == 1 && glBase.scatterChance(wx, i, wz, 0.45))))) - { - mb = BEDROCK; - } - - // Surface blocks - else if(i == height - 1) - { - mb = b.surface(wx, i, wz, glBase); - } - - // Dirt Blocks - else if(!underwater && i > height - glBase.scatterInt(wx, i, wz, 12)) - { - mb = b.dirt(wx, i, wz, glBase); - } - - // Create Water blocks - else if(i >= height && underwater) - { - mb = WATER; - } - - // Below Dirt - else - { - mb = b.rock(wx, i, wz, glBase); - } - - if(mb.equals(AIR)) - { - continue; - } + MB mb = new MB(Material.STONE); setBlock(x, i, z, mb.material, mb.data); } - MB v = b.getSurfaceDecoration(); - - if(v != null && underwater == b.isWater() && (underwater ? height < 125 : true)) - { - setBlock(x, height, z, v.material, v.data); - } - - return b.getBiome(); + return Biome.PLAINS; } + @Override + public List getDefaultPopulators(World world) + { + GList p = new GList(); + + return p; + } public int pick(int max, double noise) { @@ -146,4 +101,10 @@ public class IrisGenerator extends ParallelChunkGenerator { return array[pick(array.length, noise)]; } + + @Override + public void onInitChunk(World world, int x, int z, Random random) + { + + } } \ No newline at end of file diff --git a/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java b/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java index d201f339f..ce2bc7a6c 100644 --- a/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java +++ b/src/main/java/ninja/bytecode/iris/ParallelChunkGenerator.java @@ -40,7 +40,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator ready = true; } - tg = Iris.noisePool.startWork(); + tg = Iris.genPool.startWork(); for(i = 0; i < 16; i++) { @@ -57,13 +57,14 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator } } + onInitChunk(world, x, z, random); TaskResult r = tg.execute(); rs.put(r.timeElapsed); Shuriken.profiler.stop("chunkgen-" + world.getName()); if(cl.flip()) { - System.out.print("Avg: " + F.duration(rs.getAverage(), 2) + " " + F.duration(rs.getMax(), 2) + " / " + F.duration(rs.getMedian(), 2) + " / " + F.duration(rs.getMin(), 2)); + System.out.println("Total MS: " + F.duration(rs.getAverage(), 2)); } } @@ -82,6 +83,8 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator } public abstract void onInit(World world, Random random); + + public abstract void onInitChunk(World world, int x, int z, Random random); public abstract Biome genColumn(int wx, int wz, int x, int z); diff --git a/src/main/java/ninja/bytecode/iris/PerformanceMode.java b/src/main/java/ninja/bytecode/iris/PerformanceMode.java index 802cdf5e0..67ec8fdd9 100644 --- a/src/main/java/ninja/bytecode/iris/PerformanceMode.java +++ b/src/main/java/ninja/bytecode/iris/PerformanceMode.java @@ -6,4 +6,5 @@ public enum PerformanceMode UNLIMITED, MATCH_CPU, HALF_CPU, + EXPLICIT, } diff --git a/src/main/java/ninja/bytecode/iris/Settings.java b/src/main/java/ninja/bytecode/iris/Settings.java index 75890a14a..21698b13d 100644 --- a/src/main/java/ninja/bytecode/iris/Settings.java +++ b/src/main/java/ninja/bytecode/iris/Settings.java @@ -4,15 +4,45 @@ public class Settings { public PerformanceSettings performance = new PerformanceSettings(); public GeneratorSettings gen = new GeneratorSettings(); - + public static class PerformanceSettings { - public int threadCount = -1; + public PerformanceMode performanceMode = PerformanceMode.UNLIMITED; + public int threadCount = 4; public int threadPriority = Thread.MAX_PRIORITY; } - + public static class GeneratorSettings { + public double horizontalZoom = 2.125; // 1.856 2.556 + public double heightFracture = 155; + public double heightMultiplier = 1.154; + public double heightExponentBase = 1; + public double heightExponentMultiplier = 1.41; + public double humidityByHeightInfluence = 0.1; + public double temperatureByHeightInfluence = 0.19; + public double temperatureByHeightOffset = 0.25; + public double biomeSoftFracture = 66; + public double biomeSharpFracture = 2; + public double temperatureScale = 1.65; + public double humidityScale = 1.4; + public double heightScale = 1; + public double superHeightScale = 0.65; + public double altBiomeScale = 1; + public double baseHeight = 0.3415; + public double temperatureIgnorance = 1.55; + public double humidityIgnorance = 1.55; + public double heightIgnorance = 1; + public double mountainMultiplier = 1.65; + public double mountainHorizontalZoom = 3.15; + public double mountainSink = 0.0445; + public double superSamplerRadius = 32; + public double superSamplerMultiplier = 1; + public double superSampleOpacity = 1; + public int superSamplerIterations = 9; + public double caveSpread = 3.466; + public double caveChance = 0.03; + public boolean flatBedrock = false; } } diff --git a/src/main/java/ninja/bytecode/iris/atomics/AtomicChunkData.java b/src/main/java/ninja/bytecode/iris/atomics/AtomicChunkData.java index 3626df46d..059fee507 100644 --- a/src/main/java/ninja/bytecode/iris/atomics/AtomicChunkData.java +++ b/src/main/java/ninja/bytecode/iris/atomics/AtomicChunkData.java @@ -13,26 +13,10 @@ import org.bukkit.material.MaterialData; public final class AtomicChunkData implements ChunkGenerator.ChunkData { private static final Field t; - private static final Field[] locks; private static final Field[] sections; private static final int h = 0x1000; private final int maxHeight; - private static ReentrantLock lock0; - private static ReentrantLock lock1; - private static ReentrantLock lock2; - private static ReentrantLock lock3; - private static ReentrantLock lock4; - private static ReentrantLock lock5; - private static ReentrantLock lock6; - private static ReentrantLock lock7; - private static ReentrantLock lock8; - private static ReentrantLock lock9; - private static ReentrantLock lock10; - private static ReentrantLock lock11; - private static ReentrantLock lock12; - private static ReentrantLock lock13; - private static ReentrantLock lock14; - private static ReentrantLock lock15; + private static ReentrantLock[] locks; private char[] s0; private char[] s1; private char[] s2; @@ -180,18 +164,7 @@ public final class AtomicChunkData implements ChunkGenerator.ChunkData return; } - ReentrantLock l = null; - - try - { - l = (ReentrantLock) locks[y >> 4].get(null); - } - - catch(IllegalArgumentException | IllegalAccessException e) - { - e.printStackTrace(); - } - + ReentrantLock l = locks[y >> 4]; l.lock(); getChunkSection(y, true)[(y & 0xf) << 8 | z << 4 | x] = type; l.unlock(); @@ -257,16 +230,15 @@ public final class AtomicChunkData implements ChunkGenerator.ChunkData static { - Field[] l = new Field[16]; + locks = new ReentrantLock[16]; Field[] s = new Field[16]; for(int i = 0; i < 16; i++) { try { - l[i] = AtomicChunkData.class.getDeclaredField("lock" + i); s[i] = AtomicChunkData.class.getDeclaredField("s" + i); - + locks[i] = new ReentrantLock(); } catch(Throwable e) @@ -275,22 +247,8 @@ public final class AtomicChunkData implements ChunkGenerator.ChunkData } } - locks = l; sections = s; - for(int i = 0; i < 16; i++) - { - try - { - locks[i].set(null, new ReentrantLock()); - } - - catch(Throwable e) - { - e.printStackTrace(); - } - } - Field x = null; try diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayer.java b/src/main/java/ninja/bytecode/iris/gen/GenLayer.java index f2d376795..6d7333772 100644 --- a/src/main/java/ninja/bytecode/iris/gen/GenLayer.java +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayer.java @@ -4,6 +4,7 @@ import java.util.Random; import org.bukkit.World; +import ninja.bytecode.iris.IrisGenerator; import ninja.bytecode.shuriken.math.RNG; public class GenLayer implements IGenLayer @@ -11,12 +12,14 @@ public class GenLayer implements IGenLayer protected RNG rng; protected World world; protected Random random; + protected IrisGenerator iris; - public GenLayer(World world, Random random, RNG rng) + public GenLayer(IrisGenerator iris, World world, Random random, RNG rng) { this.world = world; this.random = random; this.rng = rng; + this.iris = iris; } @Override diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java index b63a5fa2c..6584b18e6 100644 --- a/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerBase.java @@ -4,7 +4,10 @@ import java.util.Random; import org.bukkit.World; +import ninja.bytecode.iris.Iris; +import ninja.bytecode.iris.IrisGenerator; import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.RNG; public class GenLayerBase extends GenLayer @@ -12,25 +15,41 @@ public class GenLayerBase extends GenLayer private double[][][] scatterCache; private CNG gen; private CNG fracture; + private CNG hfracture; + private CNG height; + private CNG superheight; - public GenLayerBase(World world, Random random, RNG rng) + public GenLayerBase(IrisGenerator iris, World world, Random random, RNG rng) { //@builder - super(world, random, rng); + super(iris, world, random, rng); scatterCache = new double[16][][]; CNG scatter = new CNG(rng.nextRNG(), 1, 1) - .scale(10); + .scale(10); + hfracture = new CNG(rng.nextRNG(), 1, 2) + .scale(0.0124); gen = new CNG(rng.nextRNG(), 0.19D, 16) - .scale(0.012) - .amp(0.5) - .freq(1.1) - .fractureWith(new CNG(rng.nextRNG(), 1, 6) - .scale(0.018) - .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); + .scale(0.012) + .amp(0.5) + .freq(1.1) + .fractureWith(new CNG(rng.nextRNG(), 1, 6) + .scale(0.018) + .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); + height = new CNG(rng.nextRNG(), 1, 16) + .scale(0.0017601 * Iris.settings.gen.heightScale) + .fractureWith(new CNG(rng.nextRNG(), 1, 6) + .scale(0.0174) + .fractureWith(new CNG(rng.nextRNG(), 1, 1) + .scale(0.0034), 31) + .scale(0.066), 58); + superheight = new CNG(rng.nextRNG(), 1, 6) + .scale(0.0025 * Iris.settings.gen.superHeightScale) + .fractureWith(new CNG(rng.nextRNG(), 1, 1) + .scale(0.021), 250); fracture = new CNG(rng.nextRNG(), 0.6D, 4) .scale(0.118); //@done @@ -51,6 +70,11 @@ public class GenLayerBase extends GenLayer } } + public double getHeight(double x, double z) + { + return M.clip(Math.pow(height.noise(x + (hfracture.noise(x, z) * Iris.settings.gen.heightFracture), z + (hfracture.noise(z, x) * Iris.settings.gen.heightFracture)), Iris.settings.gen.heightExponentBase + (superheight.noise(x, z) * Iris.settings.gen.heightExponentMultiplier)) * Iris.settings.gen.heightMultiplier, 0D, 1D); + } + public int scatterInt(int x, int y, int z, int bound) { return (int) (scatter(x, y, z) * (double) (bound - 1)); @@ -67,11 +91,12 @@ public class GenLayerBase extends GenLayer } @Override - public double generateLayer(double noise, double dx, double dz) + public double generateLayer(double gnoise, double dx, double dz) { + double noise = gnoise + getHeight(dx, dz); double fnoise = fracture.noise(dx, dz); dx += (fnoise * 44); dz -= (fnoise * 44); - return ((noise * 0.5) + (gen.noise(dx, dz) * (0.15 + (noise * 0.65)))) + 0.31; + return ((noise * 0.185) + (gen.noise(dx, dz) * (0.15 + (noise * 0.65)))); } } diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java deleted file mode 100644 index 7a47a88f7..000000000 --- a/src/main/java/ninja/bytecode/iris/gen/GenLayerBiome.java +++ /dev/null @@ -1,97 +0,0 @@ -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 bfracture; - private CNG height; - private CNG superheight; - - public GenLayerBiome(World world, Random random, RNG rng) - { - super(world, random, rng); - //@builder - temperature = new CNG(rng.nextRNG(), 1, 2) - .scale(0.0022) - .fractureWith(new CNG(rng.nextRNG(), 1, 1).scale(0.06), 32); - 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), 32); - bfracture = new CNG(rng.nextRNG(), 1, 1) - .scale(0.524); - superheight = new CNG(rng.nextRNG(), 1, 8) - .scale(0.0004) - .fractureWith(new CNG(rng.nextRNG(), 1, 1).scale(0.021), 250); - height = new CNG(rng.nextRNG(), 1, 8) - .scale(0.0017601) - .fractureWith(new CNG(rng.nextRNG(), 1, 6) - .scale(0.0174) - .fractureWith(new CNG(rng.nextRNG(), 1, 1) - .scale(0.0034), 31) - .scale(0.066), 58); - 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)); - } - - public RealBiome getBiome(double x, double z, double temp, double height) - { - return RealBiome.match(temp * 2, getHumidity(x, z), height, getAlt(x, z)); - } - - private double getAlt(double x, double z) - { - return alt.noise(x, z); - } - - public double getTemperature(double x, double z) - { - return getTemperature(x, z, getHeight(x, z)); - } - - public double getTemperature(double x, double z, double height) - { - return M.clip(temperature.noise(x, z) - (height * 0.19), 0D, 1D); - } - - public double getBFracture(double x, double z) - { - return bfracture.noise(x, z); - } - - 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) * 33), z + (hfracture.noise(z, x) * 33)), 2.31 + superheight.noise(x, z)) * 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/GenLayerDeepOcean.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerDeepOcean.java index ccdd53d21..5b75a179e 100644 --- a/src/main/java/ninja/bytecode/iris/gen/GenLayerDeepOcean.java +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerDeepOcean.java @@ -4,6 +4,7 @@ import java.util.Random; import org.bukkit.World; +import ninja.bytecode.iris.IrisGenerator; import ninja.bytecode.shuriken.math.CNG; import ninja.bytecode.shuriken.math.RNG; @@ -13,10 +14,10 @@ public class GenLayerDeepOcean extends GenLayer private CNG cond; private double deepHeight = 0.493; - public GenLayerDeepOcean(World world, Random random, RNG rng) + public GenLayerDeepOcean(IrisGenerator iris, World world, Random random, RNG rng) { //@builder - super(world, random, rng); + super(iris, world, random, rng); gen = new CNG(rng.nextRNG(), 1D, 4) .scale(0.023) .fractureWith(new CNG(rng.nextRNG(), 1D, 1) 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..8bd2ab007 --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerFracture.java @@ -0,0 +1,48 @@ +package ninja.bytecode.iris.gen; + +import java.util.Random; + +import org.bukkit.World; + +import ninja.bytecode.iris.IrisGenerator; +import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.M; +import ninja.bytecode.shuriken.math.RNG; + +public class GenLayerFracture extends GenLayer +{ + private CNG gen; + private CNG cond; + private double shootHeight = 0.563; + + public GenLayerFracture(IrisGenerator iris, World world, Random random, RNG rng) + { + //@builder + super(iris, world, random, rng); + gen = new CNG(rng.nextRNG(), 1D, 4) + .scale(0.013) + .fractureWith(new CNG(rng.nextRNG(), 1D, 1) + .scale(0.05), 25); + cond = new CNG(rng.nextRNG(), 1D, 4) + .scale(0.018) + .fractureWith(new CNG(rng.nextRNG(), 1D, 1) + .scale(0.025), 9); + //@done + } + + @Override + public double generateLayer(double noise, double dx, double dz) + { + double shootHeight = this.shootHeight + (cond.noise(dx, dz) * 0.035); + + if(noise >= shootHeight) + { + double multiplier = M.rangeScale(0, 0.055, this.shootHeight, 1D, cond.noise(-dx, -dz)); + double on = gen.noise(dx, dz) * multiplier; + + return noise + on; + } + + return noise; + } +} diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerMountains.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerMountains.java new file mode 100644 index 000000000..5293c174a --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerMountains.java @@ -0,0 +1,36 @@ +package ninja.bytecode.iris.gen; + +import java.util.Random; + +import org.bukkit.World; + +import ninja.bytecode.iris.Iris; +import ninja.bytecode.iris.IrisGenerator; +import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.RNG; + +public class GenLayerMountains extends GenLayer +{ + private CNG gen; + + public GenLayerMountains(IrisGenerator iris, World world, Random random, RNG rng) + { + //@builder + super(iris, world, random, rng); + gen = new CNG(rng.nextRNG(), 1D, 2) + .scale(0.0011 * Iris.settings.gen.mountainHorizontalZoom) + .child(new CNG(rng.nextRNG(), 1D, 3).scale(0.00012 * Iris.settings.gen.mountainHorizontalZoom)) + .child(new CNG(rng.nextRNG(), 1D, 4).scale(0.00014 * Iris.settings.gen.mountainHorizontalZoom)) + .child(new CNG(rng.nextRNG(), 1D, 5).scale(0.00015 * Iris.settings.gen.mountainHorizontalZoom)) + .injectWith(CNG.MULTIPLY) + .fractureWith(new CNG(rng.nextRNG(), 1D, 1) + .scale(0.05), 25); + //@done + } + + @Override + public double generateLayer(double noise, double dx, double dz) + { + return noise + (gen.noise(dx, dz) - Iris.settings.gen.mountainSink) * Iris.settings.gen.mountainMultiplier; + } +} diff --git a/src/main/java/ninja/bytecode/iris/gen/GenLayerSuperSample.java b/src/main/java/ninja/bytecode/iris/gen/GenLayerSuperSample.java new file mode 100644 index 000000000..eedb0d27d --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/gen/GenLayerSuperSample.java @@ -0,0 +1,81 @@ +package ninja.bytecode.iris.gen; + +import java.util.Random; + +import org.bukkit.World; + +import ninja.bytecode.iris.Iris; +import ninja.bytecode.iris.IrisGenerator; +import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.M; +import ninja.bytecode.shuriken.math.RNG; + +public class GenLayerSuperSample extends GenLayer +{ + private CNG gen; + private CNG radius; + + public GenLayerSuperSample(IrisGenerator iris, World world, Random random, RNG rng) + { + //@builder + super(iris, world, random, rng); + gen = new CNG(rng.nextRNG(), 1D, 4) + .scale(0.02 * Iris.settings.gen.superSamplerMultiplier); + radius = new CNG(rng.nextRNG(), 1D, 2) + .scale(0.01); + //@done + } + + public double getSuperSampledHeight(double dx, double dz) + { + double ssf = 0; + double height = iris.getRawHeight(dx, dz); + + if(Iris.settings.gen.superSamplerIterations == 0) + { + return height; + } + + double t = 0; + double sig = Iris.settings.gen.superSampleOpacity * radius.noise(dx, dz); + + for(int i = 0; i < Iris.settings.gen.superSamplerIterations; i++) + { + //@builder + double ss = 0; + double mul = Iris.settings.gen.superSamplerRadius; + double[] ssv = new double[] { + getRawHeight(dx, dz, Math.toRadians(getAngle(dx, dz)), mul / (double)(i + 1), true), + getRawHeight(dx, dz, Math.toRadians(getAngle(dx, dz)), mul / (double)(i + 1), false) + }; + //@done + for(double j : ssv) + { + ss += j; + } + + t += (double) (1D / (i + 1)); + ssf += (ss / 2D) / (double) (i + 1); + } + + return (height * (1D - sig)) + ((ssf / t) * sig); + } + + public double getRawHeight(double dx, double dz, double rad, double mult, boolean a) + { + double dax = dx + ((Math.sin(rad) * mult) * (a ? 1 : 1)); + double daz = dz + ((Math.cos(rad) * mult) * (a ? -1 : -1)); + return iris.getRawHeight(dax, daz); + } + + public double getAngle(double x, double z) + { + return M.percentRange(gen.noise(x, z), 0, 365); + } + + @Override + public double generateLayer(double noise, double dx, double dz) + { + return noise; + } +} diff --git a/src/main/java/ninja/bytecode/iris/util/Catalyst12.java b/src/main/java/ninja/bytecode/iris/util/Catalyst12.java new file mode 100644 index 000000000..d84cd19fe --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/util/Catalyst12.java @@ -0,0 +1,54 @@ +package ninja.bytecode.iris.util; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; + +import net.minecraft.server.v1_12_R1.IBlockData; +import ninja.bytecode.iris.Iris; +import ninja.bytecode.iris.MB; +import ninja.bytecode.shuriken.execution.J; + +public class Catalyst12 +{ + public static void waitForChunk(World w, int x, int z) + { + if(!w.isChunkLoaded(x, z)) + { + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> w.loadChunk(x, z, true)); + } + + int i = 0; + while(!w.isChunkLoaded(x, z) && i < 20) + { + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> w.loadChunk(x, z, true)); + J.sleep(50); + i++; + } + } + + @SuppressWarnings("deprecation") + public static void setBlock(Location l, MB m) + { + int x = l.getBlockX(); + int y = l.getBlockY(); + int z = l.getBlockZ(); + net.minecraft.server.v1_12_R1.World w = ((CraftWorld) l.getWorld()).getHandle(); + net.minecraft.server.v1_12_R1.Chunk chunk = w.getChunkAt(x >> 4, z >> 4); + int combined = m.material.getId() + (m.data << 12); + IBlockData ibd = net.minecraft.server.v1_12_R1.Block.getByCombinedId(combined); + + if(chunk.getSections()[y >> 4] == null) + { + chunk.getSections()[y >> 4] = new net.minecraft.server.v1_12_R1.ChunkSection(y >> 4 << 4, chunk.world.worldProvider.m()); + } + + net.minecraft.server.v1_12_R1.ChunkSection sec = chunk.getSections()[y >> 4]; + + synchronized(sec) + { + sec.setType(x & 15, y & 15, z & 15, ibd); + } + } +} \ No newline at end of file diff --git a/src/main/java/ninja/bytecode/iris/util/RealBiome.java b/src/main/java/ninja/bytecode/iris/util/RealBiome.java index 1561ba986..12dbf887f 100644 --- a/src/main/java/ninja/bytecode/iris/util/RealBiome.java +++ b/src/main/java/ninja/bytecode/iris/util/RealBiome.java @@ -3,318 +3,43 @@ package ninja.bytecode.iris.util; import org.bukkit.Material; import org.bukkit.block.Biome; +import net.minecraft.server.v1_12_R1.BiomeBase; +import net.minecraft.server.v1_12_R1.Block; +import net.minecraft.server.v1_12_R1.IBlockData; import ninja.bytecode.iris.MB; -import ninja.bytecode.iris.gen.GenLayerBase; -import ninja.bytecode.shuriken.collections.GList; +import ninja.bytecode.shuriken.format.F; 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 Biome b; 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; + private double humidity; + private MB surface; + private MB dirt; - public RealBiome(int biomeId, double temperature, double humidity, double height) + public RealBiome(Biome b) { - 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; + this.b = b; + BiomeBase base = BiomeBase.a(b.ordinal()); + surface = toMB(base.q); + dirt = toMB(base.r); + temperature = base.getTemperature(); + humidity = base.getHumidity(); + height = base.j(); } - public static RealBiome match(double temperature, double humidity, double height, double d) + public String toString() { - 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))); + return F.capitalizeWords(b.toString().toLowerCase().replaceAll("\\Q_\\E", " ")) + " Temp: " + temperature + " Humidity: " + humidity + " Height: " + height + " Surf: " + F.capitalizeWords(surface.material.toString().replaceAll("_", " ").toLowerCase())+ " Dirt: " + F.capitalizeWords(dirt.material.toString().replaceAll("_", " ").toLowerCase()); } - public double getDistance(double temperature, double humidity, double height) + @SuppressWarnings("deprecation") + public MB toMB(IBlockData d) { - 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; - } - - public MB getSurfaceDecoration() - { - // TODO Auto-generated method stub - return null; + int i = Block.getCombinedId(d); + int j = i & 4095; + int k = i >> 12 & 15; + return new MB(Material.getMaterial(j), k); } } \ No newline at end of file diff --git a/voronoi.png b/voronoi.png new file mode 100644 index 000000000..6f253b4e6 Binary files /dev/null and b/voronoi.png differ