This commit is contained in:
Daniel Mills 2019-10-18 13:56:01 -04:00
parent ba84ac56e9
commit 98a26a40b1
16 changed files with 479 additions and 556 deletions

View File

@ -1,46 +1,63 @@
package ninja.bytecode.iris; package ninja.bytecode.iris;
import java.util.UUID; import java.util.UUID;
import java.util.function.Function;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.WorldCreator; import org.bukkit.WorldCreator;
import org.bukkit.block.Biome;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.java.JavaPlugin; 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.collections.GSet;
import ninja.bytecode.shuriken.execution.J;
import ninja.bytecode.shuriken.execution.TaskExecutor; 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 class Iris extends JavaPlugin implements Listener
{ {
public static TaskExecutor noisePool; public static Profiler profiler;
public static TaskExecutor genPool;
public static IrisGenerator gen; public static IrisGenerator gen;
public static Settings settings; public static Settings settings;
public static Iris instance; public static Iris instance;
public static GMap<String, GMap<String, Function<Vector, Double>>> values;
public void onEnable() public void onEnable()
{ {
profiler = new Profiler(512);
values = new GMap<>();
instance = this; instance = this;
settings = new Settings(); settings = new Settings();
gen = new IrisGenerator(); 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); getServer().getPluginManager().registerEvents((Listener) this, this);
// Debug world regens // Debug world regens
GSet<String> ws = new GSet<>(); GSet<String> ws = new GSet<>();
World w = createIrisWorld(); World w = createIrisWorld();
for(Player i : Bukkit.getOnlinePlayers()) for(Player i : Bukkit.getOnlinePlayers())
{ {
Location m = i.getLocation();
ws.add(i.getWorld().getName()); 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.setFlying(true);
i.setGameMode(GameMode.CREATIVE); i.setGameMode(GameMode.SPECTATOR);
} }
for(String i : ws) 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() public void onDisable()
{ {
noisePool.close(); genPool.close();
} }
@Override @Override
@ -74,6 +112,52 @@ public class Iris extends JavaPlugin implements Listener
wold.setAutoSave(false); wold.setAutoSave(false);
Bukkit.unloadWorld(wold, 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<String, Function<Vector, Double>> 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() private World createIrisWorld()
@ -85,4 +169,14 @@ public class Iris extends JavaPlugin implements Listener
ww.setSpawnLocation(0, 256, 0); ww.setSpawnLocation(0, 256, 0);
return ww; return ww;
} }
public static void v(String w, String t, Function<Vector, Double> d)
{
if(!values.containsKey(w))
{
values.put(w, new GMap<>());
}
values.get(w).put(t, d);
}
} }

View File

@ -1,19 +1,27 @@
package ninja.bytecode.iris; 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 java.util.Random;
import org.bukkit.Chunk; import org.apache.logging.log4j.core.layout.GelfLayout;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.util.Vector; 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.GenLayerBase;
import ninja.bytecode.iris.gen.GenLayerBiome; import ninja.bytecode.iris.gen.GenLayerSuperSample;
import ninja.bytecode.iris.gen.GenLayerDeepOcean;
import ninja.bytecode.iris.gen.IGenLayer; import ninja.bytecode.iris.gen.IGenLayer;
import ninja.bytecode.iris.util.RealBiome;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
public class IrisGenerator extends ParallelChunkGenerator public class IrisGenerator extends ParallelChunkGenerator
@ -23,119 +31,66 @@ public class IrisGenerator extends ParallelChunkGenerator
private MB SAND = new MB(Material.SAND); private MB SAND = new MB(Material.SAND);
private MB BEDROCK = new MB(Material.BEDROCK); private MB BEDROCK = new MB(Material.BEDROCK);
private GList<IGenLayer> genLayers; private GList<IGenLayer> genLayers;
private GenLayerBiome glBiome;
private GenLayerBase glBase; private GenLayerBase glBase;
private GenLayerSuperSample glSuperSample;
private int waterLevel = 127; private int waterLevel = 127;
private GList<Vector> updates = new GList<>(); private GList<Vector> updates = new GList<>();
private String wf;
public void doUpdates(Chunk c)
{
for(Vector i : updates)
{
c.getBlock(i.getBlockX(), i.getBlockY(), i.getBlockZ()).getState().update(true);
}
updates.clear();
}
@Override @Override
public void onInit(World world, Random random) public void onInit(World world, Random random)
{ {
wf = world.getName();
updates = new GList<>(); updates = new GList<>();
genLayers = new GList<>(); genLayers = new GList<>();
RNG rng = new RNG(world.getSeed()); RNG rng = new RNG(world.getSeed());
genLayers.add(glBiome = new GenLayerBiome(world, random, rng.nextRNG())); genLayers.add(glBase = new GenLayerBase(this, world, random, rng.nextRNG()));
genLayers.add(glBase = new GenLayerBase(world, random, rng.nextRNG())); genLayers.add(glSuperSample = new GenLayerSuperSample(this, world, random, rng.nextRNG()));
genLayers.add(new GenLayerDeepOcean(world, random, rng.nextRNG()));
} }
public int getHeight(double dx, double dz) 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) for(IGenLayer i : genLayers)
{ {
noise = i.generateLayer(noise, dx, dz); noise = i.generateLayer(noise, dx, dz);
} }
double n = noise * 250; return M.clip(noise, 0D, 1D);
n = n > 254 ? 254 : n;
n = n < 0 ? 0 : n;
return (int) n;
} }
@Override @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); 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 for(int i = 0; i < height; i++)
if(underwater)
{ {
b = RealBiome.biomes[Biome.OCEAN.ordinal()]; MB mb = new MB(Material.STONE);
}
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;
}
setBlock(x, i, z, mb.material, mb.data); setBlock(x, i, z, mb.material, mb.data);
} }
MB v = b.getSurfaceDecoration(); return Biome.PLAINS;
if(v != null && underwater == b.isWater() && (underwater ? height < 125 : true))
{
setBlock(x, height, z, v.material, v.data);
}
return b.getBiome();
} }
@Override
public List<BlockPopulator> getDefaultPopulators(World world)
{
GList<BlockPopulator> p = new GList<BlockPopulator>();
return p;
}
public int pick(int max, double noise) public int pick(int max, double noise)
{ {
@ -146,4 +101,10 @@ public class IrisGenerator extends ParallelChunkGenerator
{ {
return array[pick(array.length, noise)]; return array[pick(array.length, noise)];
} }
@Override
public void onInitChunk(World world, int x, int z, Random random)
{
}
} }

View File

@ -40,7 +40,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
ready = true; ready = true;
} }
tg = Iris.noisePool.startWork(); tg = Iris.genPool.startWork();
for(i = 0; i < 16; i++) 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(); TaskResult r = tg.execute();
rs.put(r.timeElapsed); rs.put(r.timeElapsed);
Shuriken.profiler.stop("chunkgen-" + world.getName()); Shuriken.profiler.stop("chunkgen-" + world.getName());
if(cl.flip()) 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));
} }
} }
@ -83,6 +84,8 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
public abstract void onInit(World world, Random random); 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); public abstract Biome genColumn(int wx, int wz, int x, int z);
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")

View File

@ -6,4 +6,5 @@ public enum PerformanceMode
UNLIMITED, UNLIMITED,
MATCH_CPU, MATCH_CPU,
HALF_CPU, HALF_CPU,
EXPLICIT,
} }

View File

@ -7,12 +7,42 @@ public class Settings
public static class PerformanceSettings public static class PerformanceSettings
{ {
public int threadCount = -1; public PerformanceMode performanceMode = PerformanceMode.UNLIMITED;
public int threadCount = 4;
public int threadPriority = Thread.MAX_PRIORITY; public int threadPriority = Thread.MAX_PRIORITY;
} }
public static class GeneratorSettings 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; public boolean flatBedrock = false;
} }
} }

View File

@ -13,26 +13,10 @@ import org.bukkit.material.MaterialData;
public final class AtomicChunkData implements ChunkGenerator.ChunkData public final class AtomicChunkData implements ChunkGenerator.ChunkData
{ {
private static final Field t; private static final Field t;
private static final Field[] locks;
private static final Field[] sections; private static final Field[] sections;
private static final int h = 0x1000; private static final int h = 0x1000;
private final int maxHeight; private final int maxHeight;
private static ReentrantLock lock0; private static ReentrantLock[] locks;
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 char[] s0; private char[] s0;
private char[] s1; private char[] s1;
private char[] s2; private char[] s2;
@ -180,18 +164,7 @@ public final class AtomicChunkData implements ChunkGenerator.ChunkData
return; return;
} }
ReentrantLock l = null; ReentrantLock l = locks[y >> 4];
try
{
l = (ReentrantLock) locks[y >> 4].get(null);
}
catch(IllegalArgumentException | IllegalAccessException e)
{
e.printStackTrace();
}
l.lock(); l.lock();
getChunkSection(y, true)[(y & 0xf) << 8 | z << 4 | x] = type; getChunkSection(y, true)[(y & 0xf) << 8 | z << 4 | x] = type;
l.unlock(); l.unlock();
@ -257,16 +230,15 @@ public final class AtomicChunkData implements ChunkGenerator.ChunkData
static static
{ {
Field[] l = new Field[16]; locks = new ReentrantLock[16];
Field[] s = new Field[16]; Field[] s = new Field[16];
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
try try
{ {
l[i] = AtomicChunkData.class.getDeclaredField("lock" + i);
s[i] = AtomicChunkData.class.getDeclaredField("s" + i); s[i] = AtomicChunkData.class.getDeclaredField("s" + i);
locks[i] = new ReentrantLock();
} }
catch(Throwable e) catch(Throwable e)
@ -275,22 +247,8 @@ public final class AtomicChunkData implements ChunkGenerator.ChunkData
} }
} }
locks = l;
sections = s; sections = s;
for(int i = 0; i < 16; i++)
{
try
{
locks[i].set(null, new ReentrantLock());
}
catch(Throwable e)
{
e.printStackTrace();
}
}
Field x = null; Field x = null;
try try

View File

@ -4,6 +4,7 @@ import java.util.Random;
import org.bukkit.World; import org.bukkit.World;
import ninja.bytecode.iris.IrisGenerator;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
public class GenLayer implements IGenLayer public class GenLayer implements IGenLayer
@ -11,12 +12,14 @@ public class GenLayer implements IGenLayer
protected RNG rng; protected RNG rng;
protected World world; protected World world;
protected Random random; 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.world = world;
this.random = random; this.random = random;
this.rng = rng; this.rng = rng;
this.iris = iris;
} }
@Override @Override

View File

@ -4,7 +4,10 @@ import java.util.Random;
import org.bukkit.World; 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.CNG;
import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
public class GenLayerBase extends GenLayer public class GenLayerBase extends GenLayer
@ -12,25 +15,41 @@ public class GenLayerBase extends GenLayer
private double[][][] scatterCache; private double[][][] scatterCache;
private CNG gen; private CNG gen;
private CNG fracture; 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 //@builder
super(world, random, rng); super(iris, world, random, rng);
scatterCache = new double[16][][]; scatterCache = new double[16][][];
CNG scatter = new CNG(rng.nextRNG(), 1, 1) 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) gen = new CNG(rng.nextRNG(), 0.19D, 16)
.scale(0.012) .scale(0.012)
.amp(0.5) .amp(0.5)
.freq(1.1) .freq(1.1)
.fractureWith(new CNG(rng.nextRNG(), 1, 6) .fractureWith(new CNG(rng.nextRNG(), 1, 6)
.scale(0.018) .scale(0.018)
.injectWith(CNG.MULTIPLY) .injectWith(CNG.MULTIPLY)
.child(new CNG(rng.nextRNG(), 0.745, 2) .child(new CNG(rng.nextRNG(), 0.745, 2)
.scale(0.1)) .scale(0.1))
.fractureWith(new CNG(rng.nextRNG(), 1, 3) .fractureWith(new CNG(rng.nextRNG(), 1, 3)
.scale(0.15), 24), 44); .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) fracture = new CNG(rng.nextRNG(), 0.6D, 4)
.scale(0.118); .scale(0.118);
//@done //@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) public int scatterInt(int x, int y, int z, int bound)
{ {
return (int) (scatter(x, y, z) * (double) (bound - 1)); return (int) (scatter(x, y, z) * (double) (bound - 1));
@ -67,11 +91,12 @@ public class GenLayerBase extends GenLayer
} }
@Override @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); double fnoise = fracture.noise(dx, dz);
dx += (fnoise * 44); dx += (fnoise * 44);
dz -= (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))));
} }
} }

View File

@ -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);
}
}

View File

@ -4,6 +4,7 @@ import java.util.Random;
import org.bukkit.World; import org.bukkit.World;
import ninja.bytecode.iris.IrisGenerator;
import ninja.bytecode.shuriken.math.CNG; import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
@ -13,10 +14,10 @@ public class GenLayerDeepOcean extends GenLayer
private CNG cond; private CNG cond;
private double deepHeight = 0.493; private double deepHeight = 0.493;
public GenLayerDeepOcean(World world, Random random, RNG rng) public GenLayerDeepOcean(IrisGenerator iris, World world, Random random, RNG rng)
{ {
//@builder //@builder
super(world, random, rng); super(iris, world, random, rng);
gen = new CNG(rng.nextRNG(), 1D, 4) gen = new CNG(rng.nextRNG(), 1D, 4)
.scale(0.023) .scale(0.023)
.fractureWith(new CNG(rng.nextRNG(), 1D, 1) .fractureWith(new CNG(rng.nextRNG(), 1D, 1)

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -3,318 +3,43 @@ package ninja.bytecode.iris.util;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Biome; 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.MB;
import ninja.bytecode.iris.gen.GenLayerBase; import ninja.bytecode.shuriken.format.F;
import ninja.bytecode.shuriken.collections.GList;
public class RealBiome public class RealBiome
{ {
public static final double a = 0; private Biome b;
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 temperature;
private double humidity;
private double height; private double height;
private boolean modifier; private double humidity;
private boolean river; private MB surface;
private boolean water; private MB dirt;
private boolean beach;
private boolean dimensional;
private GList<MB> surface;
private GList<MB> dirt;
private GList<MB> rock;
private boolean defs;
private boolean defd;
private boolean defr;
public RealBiome(int biomeId, double temperature, double humidity, double height) public RealBiome(Biome b)
{ {
defs = true; this.b = b;
defd = true; BiomeBase base = BiomeBase.a(b.ordinal());
defr = true; surface = toMB(base.q);
this.biomeId = biomeId; dirt = toMB(base.r);
this.temperature = temperature; temperature = base.getTemperature();
this.humidity = humidity; humidity = base.getHumidity();
this.height = height; height = base.j();
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) public String toString()
{ {
GList<RealBiome> b = new GList<>(); 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());
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) @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); int i = Block.getCombinedId(d);
} int j = i & 4095;
int k = i >> 12 & 15;
public Biome getBiome() return new MB(Material.getMaterial(j), k);
{
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<MB> getSurface()
{
return surface;
}
public GList<MB> getDirt()
{
return dirt;
}
public GList<MB> 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;
} }
} }

BIN
voronoi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB