mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Massive biome improvements
This commit is contained in:
parent
596c3368e0
commit
1b9c7d48e4
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<IrisBiome, GMap<GenObjectGroup, Double>> 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<IrisBiome> 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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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()));
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () ->
|
||||
{
|
||||
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()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<IrisRegion> regionGenerator;
|
||||
private GMap<String, IrisRegion> regions;
|
||||
private Function<CNG, CNG> factory;
|
||||
private CNG fracture;
|
||||
private CNG island;
|
||||
private BiomeLayer master;
|
||||
|
||||
public GenLayerBiome(IrisGenerator iris, World world, Random random, RNG rng, GList<IrisBiome> 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<IrisRegion>(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<IrisBiome>(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<IrisBiome> 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)
|
||||
|
@ -48,6 +48,7 @@ public class NMSPlacer extends Placer
|
||||
|
||||
public void flush()
|
||||
{
|
||||
J.attempt(() -> {
|
||||
for(Chunk i : c)
|
||||
{
|
||||
NMP.host.relight(i);
|
||||
@ -62,5 +63,6 @@ public class NMSPlacer extends Placer
|
||||
}
|
||||
|
||||
c.clear();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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<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()
|
||||
{
|
||||
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)
|
||||
|
@ -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<IrisBiome> biomes;
|
||||
private EnumPolygonGenerator<IrisBiome> gen;
|
||||
private double rarity;
|
||||
private boolean frozen;
|
||||
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()
|
||||
{
|
||||
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)
|
||||
|
211
src/main/java/ninja/bytecode/iris/util/BiomeLayer.java
Normal file
211
src/main/java/ninja/bytecode/iris/util/BiomeLayer.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
@ -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();
|
||||
|
@ -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<CNG, CNG> factory)
|
||||
{
|
||||
useRarity = false;
|
||||
bits = 1;
|
||||
this.possibilities = possibilities;
|
||||
|
||||
@ -24,15 +29,27 @@ public class PolygonGenerator
|
||||
|
||||
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]))
|
||||
{
|
||||
@ -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
|
||||
* @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)
|
||||
@ -94,15 +115,29 @@ 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;
|
||||
}
|
||||
|
||||
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<T> extends PolygonGenerator
|
||||
{
|
||||
private T[] choices;
|
||||
@ -113,6 +148,38 @@ public class PolygonGenerator
|
||||
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)
|
||||
{
|
||||
return choices[super.getIndex(dim)];
|
||||
|
Loading…
x
Reference in New Issue
Block a user