Massive biome improvements

This commit is contained in:
Daniel Mills 2020-01-18 07:16:33 -05:00
parent 596c3368e0
commit 1b9c7d48e4
11 changed files with 484 additions and 98 deletions

View File

@ -19,12 +19,13 @@ import ninja.bytecode.shuriken.logging.L;
public class Iris extends JavaPlugin implements Listener public class Iris extends JavaPlugin implements Listener
{ {
public IrisControllerSet controllerSet; public IrisControllerSet controllerSet;
public static Thread primaryThread;
public static Settings settings; public static Settings settings;
public static Iris instance; public static Iris instance;
public void onEnable() public void onEnable()
{ {
primaryThread = Thread.currentThread();
instance = this; instance = this;
controllerSet = new IrisControllerSet(); controllerSet = new IrisControllerSet();
L.consoleConsumer = (s) -> Bukkit.getConsoleSender().sendMessage(s); L.consoleConsumer = (s) -> Bukkit.getConsoleSender().sendMessage(s);

View File

@ -26,8 +26,8 @@ public class Settings
public int hermiteSampleRadius = 4; public int hermiteSampleRadius = 4;
public double horizontalZoom = 2; public double horizontalZoom = 2;
public double heightFracture = 155; public double heightFracture = 155;
public double landScale = 0.45; public double landScale = 0.25;
public double landChance = 0.53; public double landChance = 0.45;
public double biomeEdgeScramble = 0; // 1550D public double biomeEdgeScramble = 0; // 1550D
public double roughness = 1.55; public double roughness = 1.55;
public double heightMultiplier = 0.806; public double heightMultiplier = 0.806;
@ -38,9 +38,9 @@ public class Settings
public int seaLevel = 63; public int seaLevel = 63;
public double caveDensity = 4; public double caveDensity = 4;
public double caveScale = 1.45; public double caveScale = 1.45;
public double biomeScale = 5; public double biomeScale = 0.65;
public boolean flatBedrock = true; public boolean flatBedrock = true;
public boolean genObjects = false; public boolean genObjects = true;
public boolean genCarving = true; public boolean genCarving = true;
public boolean genCaverns = true; public boolean genCaverns = true;
public boolean genCaves = true; public boolean genCaves = true;

View File

@ -8,6 +8,7 @@ import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.BlockPopulator;
import net.minecraft.server.v1_12_R1.CriterionTriggerBredAnimals.b;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.PackController; import ninja.bytecode.iris.controller.PackController;
import ninja.bytecode.iris.generator.genobject.GenObjectDecorator; 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.IrisBiome;
import ninja.bytecode.iris.pack.IrisRegion; import ninja.bytecode.iris.pack.IrisRegion;
import ninja.bytecode.iris.util.AtomicChunkData; import ninja.bytecode.iris.util.AtomicChunkData;
import ninja.bytecode.iris.util.BiomeLayer;
import ninja.bytecode.iris.util.ChunkPlan; import ninja.bytecode.iris.util.ChunkPlan;
import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.MB; 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 @Override
@ -149,8 +144,10 @@ public class IrisGenerator extends ParallelChunkGenerator
int height = computeHeight(wxx, wzx, new ChunkPlan(), biome); int height = computeHeight(wxx, wzx, new ChunkPlan(), biome);
IrisBiome nbiome = height < 63 ? getOcean(real, height) : biome; IrisBiome nbiome = height < 63 ? getOcean(real, height) : biome;
biome = nbiome; biome = nbiome;
int beach = 65;
biome = height > 61 && height < 65 ? frozen ? biome : getBeach(real) : biome; biome = height > 61 && height < 65 ? frozen ? biome : getBeach(real) : biome;
biome = height > 63 && biome.getType().equals(BiomeType.FLUID) ? 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; return biome;
} }

View File

@ -1,7 +1,11 @@
package ninja.bytecode.iris.generator.genobject; package ninja.bytecode.iris.generator.genobject;
import java.lang.Thread.State;
import java.util.Random; 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.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; 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.GMap;
import ninja.bytecode.shuriken.collections.GSet; import ninja.bytecode.shuriken.collections.GSet;
import ninja.bytecode.shuriken.execution.ChronoLatch; import ninja.bytecode.shuriken.execution.ChronoLatch;
import ninja.bytecode.shuriken.execution.J;
import ninja.bytecode.shuriken.logging.L; import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.M;
@ -30,6 +35,7 @@ public class GenObjectDecorator extends BlockPopulator
{ {
private GMap<IrisBiome, GMap<GenObjectGroup, Double>> populationCache; private GMap<IrisBiome, GMap<GenObjectGroup, Double>> populationCache;
private IPlacer placer; private IPlacer placer;
private Executor ex;
private IrisGenerator g; private IrisGenerator g;
private ChronoLatch cl = new ChronoLatch(250); private ChronoLatch cl = new ChronoLatch(250);
@ -37,6 +43,7 @@ public class GenObjectDecorator extends BlockPopulator
{ {
this.g = generator; this.g = generator;
populationCache = new GMap<>(); populationCache = new GMap<>();
ex = Executors.newSingleThreadExecutor();
for(IrisBiome i : generator.getDimension().getBiomes()) for(IrisBiome i : generator.getDimension().getBiomes())
{ {
@ -70,15 +77,15 @@ public class GenObjectDecorator extends BlockPopulator
} }
} }
} }
L.i("Population Cache is " + populationCache.size());
} }
@Override @Override
public void populate(World world, Random rnotusingyou, Chunk source) public void populate(World world, Random rnotusingyou, Chunk source)
{ {
try ex.execute(() -> {
{
Random random = new Random(((source.getX() - 32) * (source.getZ() + 54)) + world.getSeed()); Random random = new Random(((source.getX() - 32) * (source.getZ() + 54)) + world.getSeed());
Iris.getController(TimingsController.class).started("decor");
GSet<IrisBiome> hits = new GSet<>(); GSet<IrisBiome> hits = new GSet<>();
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++) for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
@ -100,21 +107,15 @@ public class GenObjectDecorator extends BlockPopulator
} }
hits.add(biome); hits.add(biome);
populate(world, random, source, biome, objects); populate(world, random, source, biome, objects);
} }
Iris.getController(TimingsController.class).stopped("decor");
}
catch(Throwable e)
{
}
if(Iris.settings.performance.verbose) if(Iris.settings.performance.verbose)
{ {
L.flush(); L.flush();
} }
});
} }
private void populate(World world, Random random, Chunk source, IrisBiome biome, GMap<GenObjectGroup, Double> objects) private void populate(World world, Random random, Chunk source, IrisBiome biome, GMap<GenObjectGroup, Double> objects)
@ -149,12 +150,15 @@ public class GenObjectDecorator extends BlockPopulator
} }
GenObject g = i.getSchematics().get(random.nextInt(i.getSchematics().size())); GenObject g = i.getSchematics().get(random.nextInt(i.getSchematics().size()));
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () ->
{
Location start = g.place(x, b.getY(), z, placer); Location start = g.place(x, b.getY(), z, placer);
if(start != null && Iris.settings.performance.verbose) 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())); 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()));
} }
});
} }
} }
} }

View File

@ -9,8 +9,8 @@ import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.pack.IrisRegion; import ninja.bytecode.iris.pack.IrisRegion;
import ninja.bytecode.iris.util.BiomeLayer;
import ninja.bytecode.iris.util.GenLayer; import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.PolygonGenerator.EnumPolygonGenerator;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GMap;
import ninja.bytecode.shuriken.math.CNG; import ninja.bytecode.shuriken.math.CNG;
@ -19,11 +19,11 @@ import ninja.bytecode.shuriken.math.RNG;
public class GenLayerBiome extends GenLayer public class GenLayerBiome extends GenLayer
{ {
private EnumPolygonGenerator<IrisRegion> regionGenerator;
private GMap<String, IrisRegion> regions; private GMap<String, IrisRegion> regions;
private Function<CNG, CNG> factory; private Function<CNG, CNG> factory;
private CNG fracture; private CNG fracture;
private CNG island; private CNG island;
private BiomeLayer master;
public GenLayerBiome(IrisGenerator iris, World world, Random random, RNG rng, GList<IrisBiome> biomes) public GenLayerBiome(IrisGenerator iris, World world, Random random, RNG rng, GList<IrisBiome> biomes)
{ {
@ -31,12 +31,16 @@ public class GenLayerBiome extends GenLayer
//@builder //@builder
island = new CNG(rng.nextParallelRNG(10334), 1D, 1) island = new CNG(rng.nextParallelRNG(10334), 1D, 1)
.scale(0.003 * Iris.settings.gen.landScale) .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) fracture = new CNG(rng.nextParallelRNG(28), 1D, 4).scale(0.0021)
.fractureWith(new CNG(rng.nextParallelRNG(34), 1D, 2) .fractureWith(new CNG(rng.nextParallelRNG(34), 1D, 2)
.scale(0.01), 12250); .scale(0.01), 12250);
factory = (g) -> g.fractureWith(new CNG(rng.nextParallelRNG(29), 1D, 4) factory = (g) -> g.fractureWith(new CNG(rng.nextParallelRNG(29), 1D, 3)
.scale(0.02), 56); .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 //@done
regions = new GMap<>(); regions = new GMap<>();
@ -60,13 +64,18 @@ public class GenLayerBiome extends GenLayer
i.load(); i.load();
} }
int v = 85034; int m = 0;
regionGenerator = new EnumPolygonGenerator<IrisRegion>(rng.nextParallelRNG(v), 0.00522 * Iris.settings.gen.biomeScale * 0.189, 1, regions.v().toArray(new IrisRegion[regions.v().size()]), factory);
for(IrisRegion i : regions.v()) for(IrisBiome i : iris.getDimension().getBiomes())
{ {
v += 13 - i.getName().length(); i.seal(iris.getRTerrain().nextParallelRNG(3922 - m++));
i.setGen(new EnumPolygonGenerator<IrisBiome>(rng.nextParallelRNG(33 + v), 0.000255 * i.getBiomes().size() * Iris.settings.gen.biomeScale, 1, i.getBiomes().toArray(new IrisBiome[i.getBiomes().size()]), factory)); }
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); return hasHeightBorder(6, range, wx, wz);
} }
public EnumPolygonGenerator<IrisBiome> getRegionGenerator(double xx, double zz)
{
return regionGenerator.getChoice(xx, zz).getGen();
}
public IrisBiome getBiome(double wxx, double wzx) public IrisBiome getBiome(double wxx, double wzx)
{ {
return getBiome(wxx, wzx, false); return getBiome(wxx, wzx, false);
@ -136,7 +140,7 @@ public class GenLayerBiome extends GenLayer
if(real) if(real)
{ {
return getRegionGenerator(x, z).getChoice(x, z); return master.computeBiome(x, z);
} }
IrisBiome cbi = iris.biome("Ocean"); IrisBiome cbi = iris.biome("Ocean");
@ -145,7 +149,7 @@ public class GenLayerBiome extends GenLayer
if(land > landChance) if(land > landChance)
{ {
cbi = getRegionGenerator(x, z).getChoice(x, z); cbi = master.computeBiome(x, z);
} }
else if(land < 0.1) else if(land < 0.1)

View File

@ -48,6 +48,7 @@ public class NMSPlacer extends Placer
public void flush() public void flush()
{ {
J.attempt(() -> {
for(Chunk i : c) for(Chunk i : c)
{ {
NMP.host.relight(i); NMP.host.relight(i);
@ -62,5 +63,6 @@ public class NMSPlacer extends Placer
} }
c.clear(); c.clear();
});
} }
} }

View File

@ -5,6 +5,7 @@ import java.lang.reflect.Field;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import mortar.util.text.C;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.PackController; import ninja.bytecode.iris.controller.PackController;
import ninja.bytecode.iris.generator.layer.BiomeNoiseGenerator; import ninja.bytecode.iris.generator.layer.BiomeNoiseGenerator;
@ -53,6 +54,7 @@ public class IrisBiome
private double genAmplifier; private double genAmplifier;
private double genSwirl; private double genSwirl;
private double genSwirlScale; private double genSwirlScale;
private double rarity;
private boolean cliffs; private boolean cliffs;
private BiomeNoiseGenerator bng; private BiomeNoiseGenerator bng;
private BiomeType type; private BiomeType type;
@ -116,6 +118,7 @@ public class IrisBiome
type = BiomeType.LAND; type = BiomeType.LAND;
cliffs = false; cliffs = false;
genScale = 1; genScale = 1;
rarity = 1;
genAmplifier = 0.35; genAmplifier = 0.35;
genSwirl = 1; genSwirl = 1;
genSwirlScale = 1; genSwirlScale = 1;
@ -239,6 +242,7 @@ public class IrisBiome
J.attempt(() -> genSwirlScale = o.getDouble("genSwirlScale")); J.attempt(() -> genSwirlScale = o.getDouble("genSwirlScale"));
J.attempt(() -> genScale = o.getDouble("genScale")); J.attempt(() -> genScale = o.getDouble("genScale"));
J.attempt(() -> snow = o.getDouble("snow")); J.attempt(() -> snow = o.getDouble("snow"));
J.attempt(() -> rarity = o.getDouble("rarity"));
J.attempt(() -> dirtDepth = o.getInt("subSurfaceDepth")); J.attempt(() -> dirtDepth = o.getInt("subSurfaceDepth"));
J.attempt(() -> dirtDepth = o.getInt("dirtDepth")); J.attempt(() -> dirtDepth = o.getInt("dirtDepth"));
J.attempt(() -> rockDepth = o.getInt("rockDepth")); J.attempt(() -> rockDepth = o.getInt("rockDepth"));
@ -292,6 +296,7 @@ public class IrisBiome
J.attempt(() -> j.put("region", region)); J.attempt(() -> j.put("region", region));
J.attempt(() -> j.put("derivative", realBiome.name().toLowerCase().replaceAll("_", " "))); J.attempt(() -> j.put("derivative", realBiome.name().toLowerCase().replaceAll("_", " ")));
J.attempt(() -> j.put("type", type.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("genHeight", height));
J.attempt(() -> j.put("genScale", genScale)); J.attempt(() -> j.put("genScale", genScale));
J.attempt(() -> j.put("genSwirl", genSwirl)); J.attempt(() -> j.put("genSwirl", genSwirl));
@ -679,6 +684,31 @@ public class IrisBiome
return parent; return parent;
} }
public GList<String> getParents()
{
GList<String> 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() public boolean isScatterSurfaceRock()
{ {
return scatterSurfaceRock; return scatterSurfaceRock;
@ -929,6 +959,84 @@ public class IrisBiome
this.bng = bng; 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 @Override
public int hashCode() public int hashCode()
{ {
@ -955,6 +1063,8 @@ public class IrisBiome
result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((parent == null) ? 0 : parent.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 + ((realBiome == null) ? 0 : realBiome.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode()); result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((rock == null) ? 0 : rock.hashCode()); result = prime * result + ((rock == null) ? 0 : rock.hashCode());
@ -1031,6 +1141,8 @@ public class IrisBiome
} }
else if(!parent.equals(other.parent)) else if(!parent.equals(other.parent))
return false; return false;
if(Double.doubleToLongBits(rarity) != Double.doubleToLongBits(other.rarity))
return false;
if(realBiome != other.realBiome) if(realBiome != other.realBiome)
return false; return false;
if(region == null) if(region == null)

View File

@ -2,7 +2,6 @@ package ninja.bytecode.iris.pack;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.PackController; import ninja.bytecode.iris.controller.PackController;
import ninja.bytecode.iris.util.PolygonGenerator.EnumPolygonGenerator;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.execution.J; import ninja.bytecode.shuriken.execution.J;
import ninja.bytecode.shuriken.json.JSONObject; import ninja.bytecode.shuriken.json.JSONObject;
@ -11,7 +10,6 @@ public class IrisRegion
{ {
private String name; private String name;
private GList<IrisBiome> biomes; private GList<IrisBiome> biomes;
private EnumPolygonGenerator<IrisBiome> gen;
private double rarity; private double rarity;
private boolean frozen; private boolean frozen;
private IrisBiome beach; private IrisBiome beach;
@ -37,16 +35,6 @@ public class IrisRegion
}); });
} }
public EnumPolygonGenerator<IrisBiome> getGen()
{
return gen;
}
public void setGen(EnumPolygonGenerator<IrisBiome> gen)
{
this.gen = gen;
}
public String getName() public String getName()
{ {
return name; return name;
@ -94,7 +82,6 @@ public class IrisRegion
int result = 1; int result = 1;
result = prime * result + ((beach == null) ? 0 : beach.hashCode()); result = prime * result + ((beach == null) ? 0 : beach.hashCode());
result = prime * result + ((biomes == null) ? 0 : biomes.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()); result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp; long temp;
temp = Double.doubleToLongBits(rarity); temp = Double.doubleToLongBits(rarity);
@ -126,13 +113,7 @@ public class IrisRegion
} }
else if(!biomes.equals(other.biomes)) else if(!biomes.equals(other.biomes))
return false; return false;
if(gen == null)
{
if(other.gen != null)
return false;
}
else if(!gen.equals(other.gen))
return false;
if(name == null) if(name == null)
{ {
if(other.name != null) if(other.name != null)

View File

@ -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<BiomeLayer> children;
private EnumPolygonGenerator<BiomeLayer> 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<CNG, CNG> factory)
{
if(gen != null)
{
return;
}
if(children.isEmpty())
{
gen = null;
return;
}
GMap<BiomeLayer, Double> 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<String> 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<String>());
}
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<BiomeLayer> getChildren()
{
return children;
}
public void setChildren(GList<BiomeLayer> 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<CNG, CNG> factory)
{
GMap<String, BiomeLayer> components = new GMap<>();
for(IrisBiome i : g.getDimension().getBiomes())
{
if(i.getType().equals(BiomeType.LAND))
{
components.put(i.getName(), new BiomeLayer(g, i));
}
}
GSet<String> 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;
}
}

View File

@ -8,6 +8,7 @@ import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
import mortar.logic.queue.ChronoLatch;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.ExecutionController; import ninja.bytecode.iris.controller.ExecutionController;
import ninja.bytecode.iris.controller.TimingsController; import ninja.bytecode.iris.controller.TimingsController;
@ -26,6 +27,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
private AtomicChunkData data; private AtomicChunkData data;
private ReentrantLock biomeLock; private ReentrantLock biomeLock;
private TaskGroup tg; private TaskGroup tg;
private ChronoLatch el = new ChronoLatch(5000);
private boolean ready = false; private boolean ready = false;
int cg = 0; int cg = 0;
private RollingSequence rs = new RollingSequence(512); private RollingSequence rs = new RollingSequence(512);
@ -102,6 +104,11 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
data.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA); data.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA);
} }
} }
if(el.flip())
{
e.printStackTrace();
}
} }
return data.toChunkData(); return data.toChunkData();

View File

@ -2,18 +2,23 @@ package ninja.bytecode.iris.util;
import java.util.function.Function; 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.CNG;
import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
public class PolygonGenerator public class PolygonGenerator
{ {
private double[] rarity;
private CNG[] gen; private CNG[] gen;
private int bits; private int bits;
private int possibilities; private int possibilities;
private boolean useRarity;
public PolygonGenerator(RNG rng, int possibilities, double scale, int octaves, Function<CNG, CNG> factory) public PolygonGenerator(RNG rng, int possibilities, double scale, int octaves, Function<CNG, CNG> factory)
{ {
useRarity = false;
bits = 1; bits = 1;
this.possibilities = possibilities; this.possibilities = possibilities;
@ -24,15 +29,27 @@ public class PolygonGenerator
bits++; bits++;
bits = bits > 32 ? 32 : bits; bits = bits > 32 ? 32 : bits;
rarity = new double[possibilities];
gen = new CNG[bits]; gen = new CNG[bits];
for(int i = 0; i < bits; i++) 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]); 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) public boolean hasBorder(int checks, double distance, double... dims)
{ {
int current = getIndex(dims); int current = getIndex(dims);
@ -69,9 +86,13 @@ public class PolygonGenerator
} }
/** /**
* 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 * Returns 0.0 to 1.0 where 0.0 is directly on the border of another region and
* @param x the x * 1.0 is perfectly in the center of a region
* @param z the z *
* @param x
* the x
* @param z
* the z
* @return the closest neighbor threshold. * @return the closest neighbor threshold.
*/ */
public double getClosestNeighbor(double... dim) public double getClosestNeighbor(double... dim)
@ -94,15 +115,29 @@ public class PolygonGenerator
public int getIndex(double... dim) public int getIndex(double... dim)
{ {
int data = 0; int data = 0;
int adjusted = 0;
double[] noise = new double[gen.length];
for(int i = 0; i < gen.length; i++) 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;
} }
if(!useRarity)
{
return data % possibilities; 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<T> extends PolygonGenerator public static class EnumPolygonGenerator<T> extends PolygonGenerator
{ {
private T[] choices; private T[] choices;
@ -113,6 +148,38 @@ public class PolygonGenerator
this.choices = choices; this.choices = choices;
} }
public EnumPolygonGenerator<T> useRarity()
{
super.useRarity();
return this;
}
@SuppressWarnings("unchecked")
public EnumPolygonGenerator(RNG rng, double scale, int octaves, GMap<T, Double> choiceRarities, Function<CNG, CNG> factory)
{
super(rng, choiceRarities.size(), scale / (double) choiceRarities.size(), octaves, factory);
GList<T> 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) public T getChoice(double... dim)
{ {
return choices[super.getIndex(dim)]; return choices[super.getIndex(dim)];