diff --git a/src/main/java/ninja/bytecode/iris/Iris.java b/src/main/java/ninja/bytecode/iris/Iris.java index a4eff0fd8..6bac636df 100644 --- a/src/main/java/ninja/bytecode/iris/Iris.java +++ b/src/main/java/ninja/bytecode/iris/Iris.java @@ -19,12 +19,13 @@ import ninja.bytecode.shuriken.logging.L; public class Iris extends JavaPlugin implements Listener { public IrisControllerSet controllerSet; - + public static Thread primaryThread; public static Settings settings; public static Iris instance; public void onEnable() { + primaryThread = Thread.currentThread(); instance = this; controllerSet = new IrisControllerSet(); L.consoleConsumer = (s) -> Bukkit.getConsoleSender().sendMessage(s); diff --git a/src/main/java/ninja/bytecode/iris/Settings.java b/src/main/java/ninja/bytecode/iris/Settings.java index 5c26e79dd..58a76b595 100644 --- a/src/main/java/ninja/bytecode/iris/Settings.java +++ b/src/main/java/ninja/bytecode/iris/Settings.java @@ -26,8 +26,8 @@ public class Settings public int hermiteSampleRadius = 4; public double horizontalZoom = 2; public double heightFracture = 155; - public double landScale = 0.45; - public double landChance = 0.53; + public double landScale = 0.25; + public double landChance = 0.45; public double biomeEdgeScramble = 0; // 1550D public double roughness = 1.55; public double heightMultiplier = 0.806; @@ -38,9 +38,9 @@ public class Settings public int seaLevel = 63; public double caveDensity = 4; public double caveScale = 1.45; - public double biomeScale = 5; + public double biomeScale = 0.65; public boolean flatBedrock = true; - public boolean genObjects = false; + public boolean genObjects = true; public boolean genCarving = true; public boolean genCaverns = true; public boolean genCaves = true; diff --git a/src/main/java/ninja/bytecode/iris/generator/IrisGenerator.java b/src/main/java/ninja/bytecode/iris/generator/IrisGenerator.java index ebbcb9a62..998f187f9 100644 --- a/src/main/java/ninja/bytecode/iris/generator/IrisGenerator.java +++ b/src/main/java/ninja/bytecode/iris/generator/IrisGenerator.java @@ -8,6 +8,7 @@ import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.generator.BlockPopulator; +import net.minecraft.server.v1_12_R1.CriterionTriggerBredAnimals.b; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.controller.PackController; import ninja.bytecode.iris.generator.genobject.GenObjectDecorator; @@ -23,6 +24,7 @@ import ninja.bytecode.iris.pack.CompiledDimension; import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisRegion; import ninja.bytecode.iris.util.AtomicChunkData; +import ninja.bytecode.iris.util.BiomeLayer; import ninja.bytecode.iris.util.ChunkPlan; import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.MB; @@ -126,13 +128,6 @@ public class IrisGenerator extends ParallelChunkGenerator } } } - - int m = 0; - - for(IrisBiome i : getDimension().getBiomes()) - { - i.seal(getRTerrain().nextParallelRNG(3922 - m++)); - } } @Override @@ -149,8 +144,10 @@ public class IrisGenerator extends ParallelChunkGenerator int height = computeHeight(wxx, wzx, new ChunkPlan(), biome); IrisBiome nbiome = height < 63 ? getOcean(real, height) : biome; biome = nbiome; + int beach = 65; biome = height > 61 && height < 65 ? frozen ? biome : getBeach(real) : biome; biome = height > 63 && biome.getType().equals(BiomeType.FLUID) ? getBeach(real) : biome; + biome = height >= beach && !biome.getType().equals(BiomeType.LAND) ? real : biome; return biome; } @@ -247,7 +244,7 @@ public class IrisGenerator extends ParallelChunkGenerator boolean frozen = r != null && r.isFrozen(); int height = computeHeight(wxx, wzx, plan, biome); int max = Math.max(height, seaLevel); - + for(int i = 0; i < max; i++) { MB mb = ROCK.get(scatterInt(wzx, i, wxx, ROCK.size())); diff --git a/src/main/java/ninja/bytecode/iris/generator/genobject/GenObjectDecorator.java b/src/main/java/ninja/bytecode/iris/generator/genobject/GenObjectDecorator.java index 9746ba576..1fd31044f 100644 --- a/src/main/java/ninja/bytecode/iris/generator/genobject/GenObjectDecorator.java +++ b/src/main/java/ninja/bytecode/iris/generator/genobject/GenObjectDecorator.java @@ -1,7 +1,11 @@ package ninja.bytecode.iris.generator.genobject; +import java.lang.Thread.State; import java.util.Random; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; @@ -23,6 +27,7 @@ import ninja.bytecode.iris.util.IPlacer; import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GSet; import ninja.bytecode.shuriken.execution.ChronoLatch; +import ninja.bytecode.shuriken.execution.J; import ninja.bytecode.shuriken.logging.L; import ninja.bytecode.shuriken.math.M; @@ -30,6 +35,7 @@ public class GenObjectDecorator extends BlockPopulator { private GMap> populationCache; private IPlacer placer; + private Executor ex; private IrisGenerator g; private ChronoLatch cl = new ChronoLatch(250); @@ -37,6 +43,7 @@ public class GenObjectDecorator extends BlockPopulator { this.g = generator; populationCache = new GMap<>(); + ex = Executors.newSingleThreadExecutor(); for(IrisBiome i : generator.getDimension().getBiomes()) { @@ -70,15 +77,15 @@ public class GenObjectDecorator extends BlockPopulator } } } + + L.i("Population Cache is " + populationCache.size()); } @Override public void populate(World world, Random rnotusingyou, Chunk source) { - try - { + ex.execute(() -> { Random random = new Random(((source.getX() - 32) * (source.getZ() + 54)) + world.getSeed()); - Iris.getController(TimingsController.class).started("decor"); GSet hits = new GSet<>(); for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++) @@ -100,21 +107,15 @@ public class GenObjectDecorator extends BlockPopulator } hits.add(biome); + populate(world, random, source, biome, objects); } - Iris.getController(TimingsController.class).stopped("decor"); - } - - catch(Throwable e) - { - - } - - if(Iris.settings.performance.verbose) - { - L.flush(); - } + if(Iris.settings.performance.verbose) + { + L.flush(); + } + }); } private void populate(World world, Random random, Chunk source, IrisBiome biome, GMap objects) @@ -149,12 +150,15 @@ public class GenObjectDecorator extends BlockPopulator } GenObject g = i.getSchematics().get(random.nextInt(i.getSchematics().size())); - Location start = g.place(x, b.getY(), z, placer); - - if(start != null && Iris.settings.performance.verbose) + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> { - L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + g.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ())); - } + Location start = g.place(x, b.getY(), z, placer); + + if(start != null && Iris.settings.performance.verbose) + { + L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + g.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ())); + } + }); } } } diff --git a/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerBiome.java b/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerBiome.java index bd0dee4ce..eeb7a59d3 100644 --- a/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerBiome.java +++ b/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerBiome.java @@ -9,8 +9,8 @@ import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisRegion; +import ninja.bytecode.iris.util.BiomeLayer; import ninja.bytecode.iris.util.GenLayer; -import ninja.bytecode.iris.util.PolygonGenerator.EnumPolygonGenerator; import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.math.CNG; @@ -19,11 +19,11 @@ import ninja.bytecode.shuriken.math.RNG; public class GenLayerBiome extends GenLayer { - private EnumPolygonGenerator regionGenerator; private GMap regions; private Function factory; private CNG fracture; private CNG island; + private BiomeLayer master; public GenLayerBiome(IrisGenerator iris, World world, Random random, RNG rng, GList biomes) { @@ -31,12 +31,16 @@ public class GenLayerBiome extends GenLayer //@builder island = new CNG(rng.nextParallelRNG(10334), 1D, 1) .scale(0.003 * Iris.settings.gen.landScale) - .fractureWith(new CNG(rng.nextParallelRNG(1211), 1D, 1).scale(0.0001 * Iris.settings.gen.landScale), 600); + .fractureWith(new CNG(rng.nextParallelRNG(1211), 1D, 1) + .scale(0.001 * Iris.settings.gen.landScale), 600); fracture = new CNG(rng.nextParallelRNG(28), 1D, 4).scale(0.0021) .fractureWith(new CNG(rng.nextParallelRNG(34), 1D, 2) .scale(0.01), 12250); - factory = (g) -> g.fractureWith(new CNG(rng.nextParallelRNG(29), 1D, 4) - .scale(0.02), 56); + factory = (g) -> g.fractureWith(new CNG(rng.nextParallelRNG(29), 1D, 3) + .scale(0.005 * Iris.settings.gen.biomeScale), 1024D / Iris.settings.gen.biomeScale) + .fractureWith(new CNG(rng.nextParallelRNG(1212), 1D, 2) + .scale(0.04) + .fractureWith(new CNG(rng.nextParallelRNG(1216), 1D, 3).scale(0.0004), 266), 66); //@done regions = new GMap<>(); @@ -60,13 +64,18 @@ public class GenLayerBiome extends GenLayer i.load(); } - int v = 85034; - regionGenerator = new EnumPolygonGenerator(rng.nextParallelRNG(v), 0.00522 * Iris.settings.gen.biomeScale * 0.189, 1, regions.v().toArray(new IrisRegion[regions.v().size()]), factory); + int m = 0; - for(IrisRegion i : regions.v()) + for(IrisBiome i : iris.getDimension().getBiomes()) { - v += 13 - i.getName().length(); - i.setGen(new EnumPolygonGenerator(rng.nextParallelRNG(33 + v), 0.000255 * i.getBiomes().size() * Iris.settings.gen.biomeScale, 1, i.getBiomes().toArray(new IrisBiome[i.getBiomes().size()]), factory)); + i.seal(iris.getRTerrain().nextParallelRNG(3922 - m++)); + } + + master = BiomeLayer.compile(iris, 0.082 * Iris.settings.gen.biomeScale * 0.189, 1, factory); + + if(Iris.settings.performance.verbose) + { + master.print(2); } } @@ -117,11 +126,6 @@ public class GenLayerBiome extends GenLayer return hasHeightBorder(6, range, wx, wz); } - public EnumPolygonGenerator getRegionGenerator(double xx, double zz) - { - return regionGenerator.getChoice(xx, zz).getGen(); - } - public IrisBiome getBiome(double wxx, double wzx) { return getBiome(wxx, wzx, false); @@ -136,7 +140,7 @@ public class GenLayerBiome extends GenLayer if(real) { - return getRegionGenerator(x, z).getChoice(x, z); + return master.computeBiome(x, z); } IrisBiome cbi = iris.biome("Ocean"); @@ -145,7 +149,7 @@ public class GenLayerBiome extends GenLayer if(land > landChance) { - cbi = getRegionGenerator(x, z).getChoice(x, z); + cbi = master.computeBiome(x, z); } else if(land < 0.1) diff --git a/src/main/java/ninja/bytecode/iris/generator/placer/NMSPlacer.java b/src/main/java/ninja/bytecode/iris/generator/placer/NMSPlacer.java index 543d8c539..f98287dd1 100644 --- a/src/main/java/ninja/bytecode/iris/generator/placer/NMSPlacer.java +++ b/src/main/java/ninja/bytecode/iris/generator/placer/NMSPlacer.java @@ -48,19 +48,21 @@ public class NMSPlacer extends Placer public void flush() { - for(Chunk i : c) - { - NMP.host.relight(i); - - J.a(() -> + J.attempt(() -> { + for(Chunk i : c) { - for(Player j : i.getWorld().getPlayers()) - { - NMP.CHUNK.refreshIgnorePosition(j, i); - } - }); - } + NMP.host.relight(i); - c.clear(); + J.a(() -> + { + for(Player j : i.getWorld().getPlayers()) + { + NMP.CHUNK.refreshIgnorePosition(j, i); + } + }); + } + + c.clear(); + }); } } diff --git a/src/main/java/ninja/bytecode/iris/pack/IrisBiome.java b/src/main/java/ninja/bytecode/iris/pack/IrisBiome.java index 5f3e9d84d..98835e901 100644 --- a/src/main/java/ninja/bytecode/iris/pack/IrisBiome.java +++ b/src/main/java/ninja/bytecode/iris/pack/IrisBiome.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import org.bukkit.Material; import org.bukkit.block.Biome; +import mortar.util.text.C; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.controller.PackController; import ninja.bytecode.iris.generator.layer.BiomeNoiseGenerator; @@ -53,6 +54,7 @@ public class IrisBiome private double genAmplifier; private double genSwirl; private double genSwirlScale; + private double rarity; private boolean cliffs; private BiomeNoiseGenerator bng; private BiomeType type; @@ -116,6 +118,7 @@ public class IrisBiome type = BiomeType.LAND; cliffs = false; genScale = 1; + rarity = 1; genAmplifier = 0.35; genSwirl = 1; genSwirlScale = 1; @@ -239,6 +242,7 @@ public class IrisBiome J.attempt(() -> genSwirlScale = o.getDouble("genSwirlScale")); J.attempt(() -> genScale = o.getDouble("genScale")); J.attempt(() -> snow = o.getDouble("snow")); + J.attempt(() -> rarity = o.getDouble("rarity")); J.attempt(() -> dirtDepth = o.getInt("subSurfaceDepth")); J.attempt(() -> dirtDepth = o.getInt("dirtDepth")); J.attempt(() -> rockDepth = o.getInt("rockDepth")); @@ -292,6 +296,7 @@ public class IrisBiome J.attempt(() -> j.put("region", region)); J.attempt(() -> j.put("derivative", realBiome.name().toLowerCase().replaceAll("_", " "))); J.attempt(() -> j.put("type", type.name().toLowerCase().replaceAll("_", " "))); + J.attempt(() -> j.put("rarity", rarity)); J.attempt(() -> j.put("genHeight", height)); J.attempt(() -> j.put("genScale", genScale)); J.attempt(() -> j.put("genSwirl", genSwirl)); @@ -679,6 +684,31 @@ public class IrisBiome return parent; } + public GList getParents() + { + GList f = new GList<>(); + + if(getParent().trim().isEmpty()) + { + return f; + } + + if(getParent().contains("&")) + { + for(String i : getParent().split("\\Q&\\E")) + { + f.add(i.trim()); + } + } + + else + { + f.add(getParent().trim()); + } + + return f; + } + public boolean isScatterSurfaceRock() { return scatterSurfaceRock; @@ -929,6 +959,84 @@ public class IrisBiome this.bng = bng; } + public double getRarity() + { + return rarity; + } + + public String getRarityString() + { + if(getRarity() <= 0.1) + { + return C.RED + "Literally Everywhere"; + } + + else if(getRarity() < 0.25) + { + return "Overly Abundant"; + } + + else if(getRarity() < 0.4) + { + return "Very Abundant"; + } + + else if(getRarity() < 0.6) + { + return "Abundant"; + } + + else if(getRarity() < 0.75) + { + return "Very Common"; + } + + else if(getRarity() <= 1) + { + return "Common"; + } + + else if(getRarity() <= 2) + { + return "Often"; + } + + else if(getRarity() <= 3) + { + return "Uncommon"; + } + + else if(getRarity() <= 6) + { + return "Rare"; + } + + else if(getRarity() <= 16) + { + return "Very Rare"; + } + + else if(getRarity() <= 50) + { + return "Exceedingly Rare"; + } + + else if(getRarity() <= 100) + { + return "Marvelously Rare"; + } + + else if(getRarity() <= 200) + { + return "Extraordinarily Rare"; + } + + else + { + return "Start Praying"; + } + } + @Override public int hashCode() { @@ -955,6 +1063,8 @@ public class IrisBiome result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((parent == null) ? 0 : parent.hashCode()); + temp = Double.doubleToLongBits(rarity); + result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + ((realBiome == null) ? 0 : realBiome.hashCode()); result = prime * result + ((region == null) ? 0 : region.hashCode()); result = prime * result + ((rock == null) ? 0 : rock.hashCode()); @@ -1031,6 +1141,8 @@ public class IrisBiome } else if(!parent.equals(other.parent)) return false; + if(Double.doubleToLongBits(rarity) != Double.doubleToLongBits(other.rarity)) + return false; if(realBiome != other.realBiome) return false; if(region == null) diff --git a/src/main/java/ninja/bytecode/iris/pack/IrisRegion.java b/src/main/java/ninja/bytecode/iris/pack/IrisRegion.java index bfe2a8213..c1390c91a 100644 --- a/src/main/java/ninja/bytecode/iris/pack/IrisRegion.java +++ b/src/main/java/ninja/bytecode/iris/pack/IrisRegion.java @@ -2,7 +2,6 @@ package ninja.bytecode.iris.pack; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.controller.PackController; -import ninja.bytecode.iris.util.PolygonGenerator.EnumPolygonGenerator; import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.execution.J; import ninja.bytecode.shuriken.json.JSONObject; @@ -11,7 +10,6 @@ public class IrisRegion { private String name; private GList biomes; - private EnumPolygonGenerator gen; private double rarity; private boolean frozen; private IrisBiome beach; @@ -37,16 +35,6 @@ public class IrisRegion }); } - public EnumPolygonGenerator getGen() - { - return gen; - } - - public void setGen(EnumPolygonGenerator gen) - { - this.gen = gen; - } - public String getName() { return name; @@ -94,7 +82,6 @@ public class IrisRegion int result = 1; result = prime * result + ((beach == null) ? 0 : beach.hashCode()); result = prime * result + ((biomes == null) ? 0 : biomes.hashCode()); - result = prime * result + ((gen == null) ? 0 : gen.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); long temp; temp = Double.doubleToLongBits(rarity); @@ -126,13 +113,7 @@ public class IrisRegion } else if(!biomes.equals(other.biomes)) return false; - if(gen == null) - { - if(other.gen != null) - return false; - } - else if(!gen.equals(other.gen)) - return false; + if(name == null) { if(other.name != null) diff --git a/src/main/java/ninja/bytecode/iris/util/BiomeLayer.java b/src/main/java/ninja/bytecode/iris/util/BiomeLayer.java new file mode 100644 index 000000000..9811fc175 --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/util/BiomeLayer.java @@ -0,0 +1,211 @@ +package ninja.bytecode.iris.util; + +import java.util.function.Function; + +import org.bukkit.Material; +import org.bukkit.block.Biome; + +import mortar.lang.collection.GList; +import mortar.lang.collection.GMap; +import mortar.logic.format.F; +import mortar.util.text.C; +import ninja.bytecode.iris.generator.IrisGenerator; +import ninja.bytecode.iris.pack.BiomeType; +import ninja.bytecode.iris.pack.IrisBiome; +import ninja.bytecode.iris.util.PolygonGenerator.EnumPolygonGenerator; +import ninja.bytecode.shuriken.collections.GSet; +import ninja.bytecode.shuriken.logging.L; +import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.RNG; + +public class BiomeLayer +{ + private static final IrisBiome VOID = new IrisBiome("Master", Biome.VOID).height(-1).dirt(MB.of(Material.END_BRICKS)).seal(RNG.r); + private GList children; + private EnumPolygonGenerator gen; + private IrisBiome biome; + private IrisGenerator iris; + + public BiomeLayer(IrisGenerator iris, IrisBiome biome) + { + this.biome = biome == null ? VOID : biome; + this.iris = iris; + this.children = new GList<>(); + } + + private void compile(double scale, int octaves, Function factory) + { + if(gen != null) + { + return; + } + + if(children.isEmpty()) + { + gen = null; + return; + } + + GMap rarities = new GMap<>(); + for(BiomeLayer i : getChildren()) + { + rarities.put(i, i.getBiome().getRarity()); + } + + if(!getBiome().equals(VOID)) + { + rarities.put(this, getBiome().getRarity()); + } + + gen = new EnumPolygonGenerator<>(iris.getRTerrain().nextParallelRNG(1022 + getBiome().getRealBiome().ordinal() + getBiome().hashCode()), scale, octaves, rarities, factory).useRarity(); + + for(BiomeLayer i : getChildren()) + { + i.compile(scale, octaves, factory); + } + } + + private IrisBiome computeBiome(double x, double z, GList f) + { + if(gen != null) + { + BiomeLayer b = gen.getChoice(x, z); + + if(b.biome.equals(biome)) + { + return biome; + } + + if(f.contains(b.getBiome().getName())) + { + f.add("..."); + f.add(b.getBiome().getName()); + L.w(C.YELLOW + "Cyclic Biome Heiarchy Detected! " + C.RED + f.toString(C.GRAY + " -> " + C.RED)); + return b.biome; + } + + f.add(b.getBiome().getName()); + + return b.computeBiome(x, z, f); + } + + return getBiome(); + } + + public IrisBiome computeBiome(double x, double z) + { + return computeBiome(x, z, new GList()); + } + + public void addLayer(IrisBiome biome) + { + addLayer(new BiomeLayer(iris, biome)); + } + + public void addLayer(BiomeLayer layer) + { + getChildren().add(layer); + } + + public IrisBiome getBiome() + { + return biome; + } + + public GList getChildren() + { + return children; + } + + public void setChildren(GList children) + { + this.children = children; + } + + public void print(int indent) + { + print(0, F.repeat(" ", indent)); + } + + private void print(int index, String indent) + { + L.i(C.GRAY + F.repeat(indent, index) + "Layer " + C.DARK_GREEN + getBiome().getName() + C.GRAY + "(" + C.GOLD + getBiome().getRarityString() + C.GRAY + ")" + (getBiome().getGenAmplifier() != 0.35 ? C.DARK_AQUA + " A: " + getBiome().getGenAmplifier() : "") + (getBiome().getHeight() != 0.0 ? C.DARK_RED + " H: " + getBiome().getHeight() : "") + (getBiome().hasCliffs() ? C.DARK_PURPLE + " C: " + getBiome().getCliffChance() + " x " + getBiome().getCliffScale() : "")); + L.flush(); + if(!getBiome().getSchematicGroups().isEmpty()) + { + for(String i : getBiome().getSchematicGroups().k()) + { + String f = ""; + double percent = getBiome().getSchematicGroups().get(i); + + if(percent > 1D) + { + f = (int) percent + " + " + F.pc(percent - (int) percent, percent - (int) percent >= 0.01 ? 0 : 3); + } + + else + { + f = F.pc(percent, percent >= 0.01 ? 0 : 3); + } + + L.i(C.GRAY + F.repeat(indent, index + 1) + "Object " + C.GOLD + i + C.GRAY + " at " + C.GOLD + f + C.GRAY + " (" + F.f(iris.getDimension().getObjectGroup(i).size()) + " variants)"); + } + } + + L.flush(); + for(BiomeLayer i : children) + { + i.print(index + 1, indent); + } + } + + public static BiomeLayer compile(IrisGenerator g, double scale, int octaves, Function factory) + { + GMap components = new GMap<>(); + + for(IrisBiome i : g.getDimension().getBiomes()) + { + if(i.getType().equals(BiomeType.LAND)) + { + components.put(i.getName(), new BiomeLayer(g, i)); + } + } + + GSet deject = new GSet<>(); + + for(String i : components.keySet()) + { + BiomeLayer b = components.get(i); + + for(String j : b.getBiome().getParents()) + { + try + { + components.get(j).addLayer(b); + deject.add(i); + } + + catch(Throwable e) + { + L.w(C.YELLOW + "Cannot find Biome " + C.RED + j + C.YELLOW + " (" + C.WHITE + b.getBiome().getName() + C.YELLOW + "'s so-called 'parent'.)"); + } + } + } + + BiomeLayer master = new BiomeLayer(g, null); + + for(String i : components.k()) + { + if(deject.contains(i)) + { + continue; + } + + master.addLayer(components.get(i)); + } + + master.compile(scale, octaves, factory); + + return master; + } +} diff --git a/src/main/java/ninja/bytecode/iris/util/ParallelChunkGenerator.java b/src/main/java/ninja/bytecode/iris/util/ParallelChunkGenerator.java index 6a976feea..7fc6a7907 100644 --- a/src/main/java/ninja/bytecode/iris/util/ParallelChunkGenerator.java +++ b/src/main/java/ninja/bytecode/iris/util/ParallelChunkGenerator.java @@ -8,6 +8,7 @@ import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.generator.ChunkGenerator; +import mortar.logic.queue.ChronoLatch; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.controller.ExecutionController; import ninja.bytecode.iris.controller.TimingsController; @@ -26,6 +27,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator private AtomicChunkData data; private ReentrantLock biomeLock; private TaskGroup tg; + private ChronoLatch el = new ChronoLatch(5000); private boolean ready = false; int cg = 0; private RollingSequence rs = new RollingSequence(512); @@ -84,7 +86,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator }); } } - + plan.set(onInitChunk(world, x, z, random)); TaskResult r = tg.execute(); onPostChunk(world, x, z, random, data, plan.get()); @@ -102,6 +104,11 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator data.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA); } } + + if(el.flip()) + { + e.printStackTrace(); + } } return data.toChunkData(); diff --git a/src/main/java/ninja/bytecode/iris/util/PolygonGenerator.java b/src/main/java/ninja/bytecode/iris/util/PolygonGenerator.java index 921f46187..628583bd9 100644 --- a/src/main/java/ninja/bytecode/iris/util/PolygonGenerator.java +++ b/src/main/java/ninja/bytecode/iris/util/PolygonGenerator.java @@ -2,18 +2,23 @@ package ninja.bytecode.iris.util; import java.util.function.Function; +import mortar.lang.collection.GList; +import mortar.lang.collection.GMap; import ninja.bytecode.shuriken.math.CNG; import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.RNG; public class PolygonGenerator { + private double[] rarity; private CNG[] gen; private int bits; private int possibilities; + private boolean useRarity; public PolygonGenerator(RNG rng, int possibilities, double scale, int octaves, Function factory) { + useRarity = false; bits = 1; this.possibilities = possibilities; @@ -21,18 +26,30 @@ public class PolygonGenerator { bits++; } - + bits++; bits = bits > 32 ? 32 : bits; + rarity = new double[possibilities]; gen = new CNG[bits]; for(int i = 0; i < bits; i++) { - gen[i] = new CNG(rng.nextParallelRNG(2118 + (i * 3305)), 1D, 1).scale(scale); + gen[i] = new CNG(rng.nextParallelRNG(2118 + (i * 3305)), 1D, 1).scale(scale / possibilities); gen[i] = factory.apply(gen[i]); } } - + + public PolygonGenerator useRarity() + { + useRarity = true; + return this; + } + + public void setRarity(int index, double r) + { + rarity[index] = 1D - Math.pow(0.5, r); + } + public boolean hasBorder(int checks, double distance, double... dims) { int current = getIndex(dims); @@ -42,8 +59,8 @@ public class PolygonGenerator { for(int i = 0; i < checks; i++) { - double dx = M.sin((float)Math.toRadians(ajump * i)); - double dz = M.cos((float)Math.toRadians(ajump * i)); + double dx = M.sin((float) Math.toRadians(ajump * i)); + double dz = M.cos((float) Math.toRadians(ajump * i)); if(current != getIndex((dx * distance) + dims[0], (dz * distance) + dims[1])) { return true; @@ -55,8 +72,8 @@ public class PolygonGenerator { for(int i = 0; i < checks; i++) { - double dx = M.sin((float)Math.toRadians(ajump * i)); - double dz = M.cos((float)Math.toRadians(ajump * i)); + double dx = M.sin((float) Math.toRadians(ajump * i)); + double dz = M.cos((float) Math.toRadians(ajump * i)); double dy = Math.tan(Math.toRadians(ajump * i)); if(current != getIndex((dx * distance) + dims[0], (dz * distance) + dims[1], (dy * distance) + dims[2])) { @@ -67,21 +84,25 @@ public class PolygonGenerator return false; } - + /** - * Returns 0.0 to 1.0 where 0.0 is directly on the border of another region and 1.0 is perfectly in the center of a region - * @param x the x - * @param z the z + * Returns 0.0 to 1.0 where 0.0 is directly on the border of another region and + * 1.0 is perfectly in the center of a region + * + * @param x + * the x + * @param z + * the z * @return the closest neighbor threshold. */ public double getClosestNeighbor(double... dim) { double closest = 0.5; - + for(int i = 0; i < gen.length; i++) { double distance = Math.abs(gen[i].noise(dim) - 0.5); - + if(distance < closest) { closest = distance; @@ -94,13 +115,27 @@ public class PolygonGenerator public int getIndex(double... dim) { int data = 0; + int adjusted = 0; + double[] noise = new double[gen.length]; for(int i = 0; i < gen.length; i++) { - data |= gen[i].noise(dim) > 0.5 ? i == 0 ? 1 : 1 << i : 0; + data |= (noise[i] = gen[i].noise(dim)) > 0.5 ? i == 0 ? 1 : 1 << i : 0; } - return data % possibilities; + if(!useRarity) + { + return data % possibilities; + } + + double r = rarity[data % possibilities]; + + for(int i = 0; i < gen.length; i++) + { + adjusted |= noise[i] > r ? i == 0 ? 1 : 1 << i : 0; + } + + return adjusted % possibilities; } public static class EnumPolygonGenerator extends PolygonGenerator @@ -113,6 +148,38 @@ public class PolygonGenerator this.choices = choices; } + public EnumPolygonGenerator useRarity() + { + super.useRarity(); + return this; + } + + @SuppressWarnings("unchecked") + public EnumPolygonGenerator(RNG rng, double scale, int octaves, GMap choiceRarities, Function factory) + { + super(rng, choiceRarities.size(), scale / (double) choiceRarities.size(), octaves, factory); + GList c = choiceRarities.k(); + this.choices = (T[]) c.toArray(); + int m = 0; + + for(T i : c) + { + setRarity(m++, choiceRarities.get(i)); + } + } + + public void setRarity(T t, double rarity) + { + for(int i = 0; i < choices.length; i++) + { + if(choices[i].equals(t)) + { + setRarity(i, rarity); + return; + } + } + } + public T getChoice(double... dim) { return choices[super.getIndex(dim)];