Schematics

This commit is contained in:
Daniel Mills
2020-01-03 01:05:10 -05:00
parent e2c8b6ae02
commit ec43d2012e
22 changed files with 2092 additions and 227 deletions

View File

@@ -1,5 +1,6 @@
package ninja.bytecode.iris.generator;
import java.io.File;
import java.util.List;
import java.util.Random;
@@ -12,15 +13,19 @@ import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.biome.IrisBiome;
import ninja.bytecode.iris.generator.layer.GenLayerBase;
import ninja.bytecode.iris.generator.layer.GenLayerBiome;
import ninja.bytecode.iris.generator.layer.GenLayerCaves;
import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise;
import ninja.bytecode.iris.generator.layer.GenLayerRidge;
import ninja.bytecode.iris.generator.populator.PopulatorTrees;
import ninja.bytecode.iris.generator.populator.BiomeBiasSchematicPopulator;
import ninja.bytecode.iris.schematic.Schematic;
import ninja.bytecode.iris.util.AtomicChunkData;
import ninja.bytecode.iris.util.ChunkPlan;
import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.ParallelChunkGenerator;
import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.execution.J;
import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG;
@@ -32,8 +37,8 @@ public class IrisGenerator extends ParallelChunkGenerator
private GenLayerLayeredNoise glLNoise;
private GenLayerRidge glRidge;
private GenLayerBiome glBiome;
private GenLayerCaves glCaves;
private RNG rTerrain;
private RNG rScatter;
private World world;
@Override
@@ -45,11 +50,7 @@ public class IrisGenerator extends ParallelChunkGenerator
glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2));
glRidge = new GenLayerRidge(this, world, random, rTerrain.nextParallelRNG(3));
glBiome = new GenLayerBiome(this, world, random, rTerrain.nextParallelRNG(4));
}
public World getWorld()
{
return world;
glCaves = new GenLayerCaves(this, world, random, rTerrain.nextParallelRNG(-1));
}
@Override
@@ -69,8 +70,10 @@ public class IrisGenerator extends ParallelChunkGenerator
hv += glLNoise.generateLayer(hv, wxx, wzx);
hv -= glRidge.generateLayer(hv, wxx, wzx);
int height = (int) Math.round(M.clip(hv, 0D, 1D) * 253);
int max = Math.max(height, seaLevel);
IrisBiome override = null;
for(int i = 0; i < Math.max(height, seaLevel); i++)
for(int i = 0; i < max; i++)
{
MB mb = new MB(Material.STONE);
boolean underwater = i >= height && i < seaLevel;
@@ -88,10 +91,43 @@ public class IrisGenerator extends ParallelChunkGenerator
if(i == height - 1)
{
if(height > 61 && height < glBase.scatterInt(x, i, z, 4) + 65)
{
override = IrisBiome.BEACH;
}
else if(height < 63)
{
if(i < 36)
{
override = IrisBiome.DEEP_OCEAN;
}
else if(i < 50)
{
override = IrisBiome.OCEAN;
}
else
{
override = IrisBiome.LAKE;
}
}
if(override != null)
{
biome = override;
}
mb = biome.getSurface(wx, wz, rTerrain);
}
if(Iris.settings.gen.flatBedrock ? i == 0 : i < glBase.scatterInt(x, i, z, 3))
if(i == 0)
{
mb = BEDROCK;
}
if(Iris.settings.gen.flatBedrock ? i == 1 : i < glBase.scatterInt(x, i, z, 3))
{
mb = BEDROCK;
}
@@ -99,6 +135,13 @@ public class IrisGenerator extends ParallelChunkGenerator
setBlock(x, i, z, mb.material, mb.data);
}
glCaves.genCaves(wxx, wzx, x, z, height, this);
if(override != null)
{
return override.getRealBiome();
}
return biome.getRealBiome();
}
@@ -114,24 +157,73 @@ public class IrisGenerator extends ParallelChunkGenerator
}
@Override
public List<BlockPopulator> getDefaultPopulators(World world)
{
GList<BlockPopulator> p = new GList<>();
int b = 0;
for(IrisBiome i : IrisBiome.getBiomes())
{
b++;
L.i("Processing Populators for Biome " + i.getName());
for(String j : i.getSchematicGroups().keySet())
{
p.add(new BiomeBiasSchematicPopulator(i.getSchematicGroups().get(j), i, loadSchematics(j)));
}
}
J.attempt(() -> p.add(new BiomeBiasSchematicPopulator(5, IrisBiome.JUNGLE, loadSchematics(""))));
L.i("Initialized " + b + " Biomes and " + p.size() + " Populators");
L.flush();
return p;
}
private Schematic[] loadSchematics(String folder)
{
File f = new File(Iris.instance.getDataFolder(), "objects/" + folder);
GList<Schematic> s = new GList<>();
try
{
if(f.exists() && f.isDirectory())
{
for(File i : f.listFiles())
{
if(i.isFile() && i.getName().endsWith(".ish"))
{
s.add(Schematic.load(i));
}
}
}
}
catch(Throwable e)
{
}
return s.toArray(new Schematic[s.size()]);
}
private double getBiomedHeight(int x, int z, ChunkPlan plan)
{
return plan.getHeight(x, z, () -> {
return plan.getHeight(x, z, () ->
{
int wx = (int) Math.round((double) x * Iris.settings.gen.horizontalZoom);
int wz = (int) Math.round((double) z * Iris.settings.gen.horizontalZoom);
IrisBiome biome = glBiome.getBiome(wx * Iris.settings.gen.biomeScale, wz * Iris.settings.gen.biomeScale);
double h = Iris.settings.gen.baseHeight + biome.getHeight();
h += (glBase.getHeight(wx, wz) * biome.getAmp()) - (0.33 * biome.getAmp());
return h;
});
}
@Override
public List<BlockPopulator> getDefaultPopulators(World world)
public World getWorld()
{
GList<BlockPopulator> p = new GList<BlockPopulator>();
p.add(new PopulatorTrees());
return p;
return world;
}
}

View File

@@ -32,6 +32,10 @@ public class IrisBiome
.surface(MB.of(Material.SAND), MB.of(Material.SAND), MB.of(Material.SAND), MB.of(Material.CLAY), MB.of(Material.GRAVEL))
.simplexSurface()
.height(-0.03);
public static final IrisBiome LAKE = new IrisBiome("Lake", Biome.OCEAN)
.surface(MB.of(Material.SAND), MB.of(Material.SAND), MB.of(Material.SAND), MB.of(Material.GRAVEL), MB.of(Material.CLAY), MB.of(Material.GRAVEL))
.simplexSurface()
.height(-0.03);
public static final IrisBiome DEEP_OCEAN = new IrisBiome("Deep Ocean", Biome.DEEP_OCEAN)
.surface(MB.of(Material.SAND), MB.of(Material.CLAY), MB.of(Material.GRAVEL))
.simplexSurface()
@@ -237,7 +241,7 @@ public class IrisBiome
simplexScatter = true;
return this;
}
public IrisBiome scatterSurface()
{
scatterSurface = true;
@@ -312,9 +316,9 @@ public class IrisBiome
});
}
return poly.getChoice(wx * 0.2D, wz * 0.2D);
return poly.getChoice(wx * 0.2D, wz * 0.2D);
}
if(scatterSurface)
{
if(poly == null)
@@ -325,7 +329,7 @@ public class IrisBiome
});
}
return poly.getChoice(wx * 0.2D, wz * 0.2D);
return poly.getChoice(wx * 0.2D, wz * 0.2D);
}
return getSurface().getRandom();
@@ -385,7 +389,12 @@ public class IrisBiome
return null;
}
public static IrisBiome find(Biome biome)
public static GList<IrisBiome> getBiomes()
{
return map.v().remove(IrisBiome.ROAD_GRASSY, IrisBiome.ROAD_GRAVEL, IrisBiome.BEACH, IrisBiome.LAKE, IrisBiome.RIVER);
}
public static IrisBiome findByBiome(Biome biome)
{
if(map.containsKey(biome))
{
@@ -394,4 +403,9 @@ public class IrisBiome
return IrisBiome.PLAINS;
}
public GMap<String, Double> getSchematicGroups()
{
return schematicGroups;
}
}

View File

@@ -33,38 +33,7 @@ public class GenLayerBiome extends GenLayer
riverCheck = new CNG(rng.nextParallelRNG(30), 1D, 2).scale(0.00096);
pathCheck = new CNG(rng.nextParallelRNG(31), 1D, 1).scale(0.00096);
roads = new MaxingGenerator(rng.nextParallelRNG(32), 5, 0.00055, 8, factory);
biomeGenerator = new EnumMaxingGenerator<IrisBiome>(rng.nextParallelRNG(33), 0.00755 * Iris.settings.gen.biomeScale, 1,
new IrisBiome[] {
IrisBiome.HAUNTED_FOREST,
IrisBiome.FOREST_MOUNTAINS,
IrisBiome.DESERT,
IrisBiome.DESERT_HILLS,
IrisBiome.MESA,
IrisBiome.DESERT_COMBINED,
IrisBiome.SAVANNA,
IrisBiome.SAVANNA_HILLS,
IrisBiome.DESERT_RED,
IrisBiome.JUNGLE,
IrisBiome.JUNGLE_HILLS,
IrisBiome.SWAMP,
IrisBiome.OCEAN,
IrisBiome.PLAINS,
IrisBiome.DECAYING_PLAINS,
IrisBiome.FOREST,
IrisBiome.FOREST_HILLS,
IrisBiome.BIRCH_FOREST,
IrisBiome.BIRCH_FOREST_HILLS,
IrisBiome.ROOFED_FOREST,
IrisBiome.TAIGA,
IrisBiome.EXTREME_HILLS,
IrisBiome.EXTREME_HILLS_TREES,
IrisBiome.TAIGA_COLD,
IrisBiome.TAIGA_COLD_HILLS,
IrisBiome.ICE_FLATS,
IrisBiome.ICE_MOUNTAINS,
IrisBiome.REDWOOD_TAIGA,
IrisBiome.REDWOOD_TAIGA_HILLS,
}, factory);
biomeGenerator = new EnumMaxingGenerator<IrisBiome>(rng.nextParallelRNG(33), 0.00755 * Iris.settings.gen.biomeScale, 1, IrisBiome.getBiomes().toArray(new IrisBiome[IrisBiome.getBiomes().size()]), factory);
//@done
}
@@ -72,7 +41,7 @@ public class GenLayerBiome extends GenLayer
{
double x = xx + (fracture.noise(zz, xx) * 1550D);
double z = zz - (fracture.noise(xx, zz) * 1550D);
if(riverCheck.noise(x, z) > 0.75)
{
if(biomeGenerator.hasBorder(3, 3 + Math.pow(riverCheck.noise(x, z), 1.25) * 16, x, z))
@@ -80,24 +49,24 @@ public class GenLayerBiome extends GenLayer
return IrisBiome.RIVER;
}
}
IrisBiome cbi = biomeGenerator.getChoice(x, z);
if(pathCheck.noise(x, z) > 0.33)
{
IrisBiome road = IrisBiome.ROAD_GRAVEL;
if(cbi.getSurface().get(0).material.equals(Material.GRASS))
{
road = IrisBiome.ROAD_GRASSY;
}
if(Math.abs(road.getHeight() - cbi.getHeight()) < 0.0001 && roads.hasBorder(4, 3, xx, zz))
{
return road;
}
}
return cbi;
}

View File

@@ -0,0 +1,78 @@
package ninja.bytecode.iris.generator.layer;
import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.MaxingGenerator;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.RNG;
public class GenLayerCaves extends GenLayer
{
private CNG caveHeight;
private CNG caveGirth;
private CNG caveClamp;
private MaxingGenerator caveVeins;
public GenLayerCaves(IrisGenerator iris, World world, Random random, RNG rng)
{
super(iris, world, random, rng);
caveHeight = new CNG(rng.nextParallelRNG(-100001), 1D, 7).scale(0.00222);
caveGirth = new CNG(rng.nextParallelRNG(-100002), 1D, 12).scale(0.03);
caveClamp = new CNG(rng.nextParallelRNG(-10000), 1D, 3).scale(0.1422);
caveVeins = new MaxingGenerator(rng.nextParallelRNG(-99999), 22, 0.002, 1, (g) -> g.fractureWith(new CNG(rng.nextParallelRNG(-5555), 1D, 4).scale(0.02), 70));
}
public void genCaves(double wxx, double wzx, int x, int z, int s, IrisGenerator g)
{
for(double itr = 0; itr < 0.2; itr += 0.1)
{
double thickness = 0.25 + itr + (0.5 * caveClamp.noise(wxx, wzx));
double size = 3.88D * thickness;
double variance = 8.34D * thickness;
double w = size + (variance * caveGirth.noise(wxx, wzx));
double h = size + (variance * caveGirth.noise(wzx, wxx));
double width = 0;
double height = h;
double elevation = (caveHeight.noise(wxx + (19949D * itr), wzx - (19949D * itr)) * (350)) - 80;
while(width <= w && height > 1D)
{
width+=2;
height-=2;
if(caveVeins.hasBorder(3, width, wxx - (19949D * itr), wzx + (19949D * itr)))
{
double r = (((caveGirth.noise(wxx, wzx, width)) * variance) + height) / 2D;
for(int i = (int) -r; i < r; i++)
{
if(i + height > s)
{
break;
}
Material t = g.getType(x, (int) (elevation + i) - 55, z);
if(t.equals(Material.BEDROCK) || t.equals(Material.WATER) || t.equals(Material.STATIONARY_WATER))
{
continue;
}
g.setBlock(x, (int) (elevation + i) - 55, z, Material.AIR);
}
}
}
}
}
@Override
public double generateLayer(double gnoise, double dx, double dz)
{
return gnoise;
}
}

View File

@@ -0,0 +1,33 @@
package ninja.bytecode.iris.generator.populator;
import java.util.Random;
import org.bukkit.Chunk;
import org.bukkit.World;
import ninja.bytecode.iris.generator.biome.IrisBiome;
import ninja.bytecode.iris.schematic.Schematic;
import ninja.bytecode.iris.util.MB;
public class BiomeBiasSchematicPopulator extends SurfaceBiasSchematicPopulator
{
protected IrisBiome biome;
public BiomeBiasSchematicPopulator(double chance, IrisBiome biome, Schematic... schematics)
{
super(chance, schematics);
this.biome = biome;
for(MB i : biome.getSurface())
{
surface(i.material);
}
}
public void doPopulate(World world, Random random, Chunk source, int wx, int wz)
{
if(world.getBiome(wx, wz).equals(biome.getRealBiome()))
{
super.doPopulate(world, random, source, wx, wz);
}
}
}

View File

@@ -1,67 +0,0 @@
package ninja.bytecode.iris.generator.populator;
import java.util.Random;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.TreeType;
import org.bukkit.World;
import org.bukkit.generator.BlockPopulator;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.biome.IrisBiome;
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
import ninja.bytecode.shuriken.math.RollingSequence;
public class PopulatorTrees extends BlockPopulator
{
public static RollingSequence timings = new RollingSequence(512);
@Override
public void populate(World world, Random random, Chunk source)
{
if(!Iris.settings.gen.doTrees)
{
return;
}
PrecisionStopwatch f = PrecisionStopwatch.start();
int debuff = 0;
for(int i = 0; i < 16; i++)
{
if(debuff > 0)
{
debuff--;
continue;
}
int x = random.nextInt(15) + (source.getX() * 16);
int z = random.nextInt(15) + (source.getZ() * 16);
int y = world.getHighestBlockYAt(x, z);
Location l = new Location(world, x, y, z);
if(!l.getBlock().getType().isSolid())
{
l.getBlock().setType(Material.AIR, false);
}
IrisBiome biome = IrisBiome.find(world.getBiome(x, z));
TreeType tt = biome.getTreeChanceSingle();
if(tt != null)
{
world.generateTree(l, tt);
}
else
{
debuff += 4;
}
}
f.end();
timings.put(f.getMilliseconds());
}
}

View File

@@ -0,0 +1,35 @@
package ninja.bytecode.iris.generator.populator;
import java.util.Random;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import ninja.bytecode.iris.schematic.Schematic;
import ninja.bytecode.iris.util.ChancedPopulator;
public class SchematicPopulator extends ChancedPopulator
{
protected final Schematic[] schematics;
public SchematicPopulator(double chance, Schematic... schematics)
{
super(chance);
this.schematics = schematics;
}
@Override
public void doPopulate(World world, Random random, Chunk source, int wx, int wz)
{
Block b = world.getHighestBlockAt(wx, wz);
if(!b.getRelative(BlockFace.DOWN).getType().isSolid())
{
return;
}
schematics[random.nextInt(schematics.length)].place(world, wx, b.getY() - 1, wz);
}
}

View File

@@ -0,0 +1,44 @@
package ninja.bytecode.iris.generator.populator;
import java.util.Random;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import ninja.bytecode.iris.schematic.Schematic;
import ninja.bytecode.shuriken.collections.GList;
public class SurfaceBiasSchematicPopulator extends SchematicPopulator
{
private GList<Material> bias;
public SurfaceBiasSchematicPopulator(double chance, Schematic... schematics)
{
super(chance, schematics);
this.bias = new GList<>();
}
public SurfaceBiasSchematicPopulator surface(Material mb)
{
bias.add(mb);
return this;
}
@Override
public void doPopulate(World world, Random random, Chunk source, int wx, int wz)
{
Block b = world.getHighestBlockAt(wx, wz);
for(Material i : bias)
{
if(b.getRelative(BlockFace.DOWN).getType().equals(i))
{
schematics[random.nextInt(schematics.length)].place(world, wx, b.getY() - 1, wz);
break;
}
}
}
}