mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-05 23:36:12 +00:00
RV
This commit is contained in:
@@ -1,728 +0,0 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.material.Leaves;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.generator.genobject.GenObjectDecorator;
|
||||
import ninja.bytecode.iris.generator.genobject.PlacedObject;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerBiome;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerCarving;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerCaves;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerCliffs;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerOres;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerSnow;
|
||||
import ninja.bytecode.iris.generator.parallax.ParallaxWorldGenerator;
|
||||
import ninja.bytecode.iris.pack.BiomeType;
|
||||
import ninja.bytecode.iris.pack.CompiledDimension;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.pack.IrisRegion;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.InterpolationMode;
|
||||
import ninja.bytecode.iris.util.IrisInterpolation;
|
||||
import ninja.bytecode.iris.util.IrisMetrics;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.iris.util.NoiseProvider;
|
||||
import ninja.bytecode.iris.util.ObjectMode;
|
||||
import ninja.bytecode.iris.util.SChunkVector;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class IrisGenerator extends ParallaxWorldGenerator
|
||||
{
|
||||
//@builder
|
||||
public static final KList<MB> ROCK = new KList<MB>().add(new MB[] {
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5),
|
||||
MB.of(Material.STONE, 5)
|
||||
});
|
||||
//@done
|
||||
private boolean disposed;
|
||||
private CNG scatter;
|
||||
private CNG beach;
|
||||
private CNG swirl;
|
||||
private MB BEDROCK = new MB(Material.BEDROCK);
|
||||
private GenObjectDecorator god;
|
||||
private GenLayerLayeredNoise glLNoise;
|
||||
private GenLayerBiome glBiome;
|
||||
private GenLayerSnow glSnow;
|
||||
private GenLayerCliffs glCliffs;
|
||||
private GenLayerCaves glCaves;
|
||||
private GenLayerCarving glCarving;
|
||||
private GenLayerOres glOres;
|
||||
private RNG rTerrain;
|
||||
private CompiledDimension dim;
|
||||
private IrisMetrics metrics = new IrisMetrics(0, 512);
|
||||
private int objectHits;
|
||||
|
||||
public IrisGenerator()
|
||||
{
|
||||
this(Iris.pack().getDimension("overworld"));
|
||||
}
|
||||
|
||||
public void hitObject()
|
||||
{
|
||||
objectHits++;
|
||||
}
|
||||
|
||||
public IrisGenerator(CompiledDimension dim)
|
||||
{
|
||||
objectHits = 0;
|
||||
CNG.hits = 0;
|
||||
CNG.creates = 0;
|
||||
this.dim = dim;
|
||||
disposed = false;
|
||||
L.i("Preparing Dimension: " + dim.getName() + " With " + dim.getBiomes().size() + " Biomes...");
|
||||
}
|
||||
|
||||
public int scatterInt(int x, int y, int z, int bound)
|
||||
{
|
||||
return (int) (scatter(x, y, z) * (double) (bound - 1));
|
||||
}
|
||||
|
||||
public double scatter(int x, int y, int z)
|
||||
{
|
||||
return scatter.noise(x, y, z);
|
||||
}
|
||||
|
||||
public boolean scatterChance(int x, int y, int z, double chance)
|
||||
{
|
||||
return scatter(x, y, z) > chance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInit(World world, Random random)
|
||||
{
|
||||
if(disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
random = new Random(world.getSeed());
|
||||
rTerrain = new RNG(world.getSeed());
|
||||
swirl = new CNG(rTerrain.nextParallelRNG(0), 40, 1).scale(0.007);
|
||||
beach = new CNG(rTerrain.nextParallelRNG(0), 3, 1).scale(0.15);
|
||||
glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2));
|
||||
glBiome = new GenLayerBiome(this, world, random, rTerrain.nextParallelRNG(4), dim.getBiomes());
|
||||
glSnow = new GenLayerSnow(this, world, random, rTerrain.nextParallelRNG(5));
|
||||
glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9));
|
||||
glCaves = new GenLayerCaves(this, world, random, rTerrain.nextParallelRNG(10));
|
||||
glCarving = new GenLayerCarving(this, world, random, rTerrain.nextParallelRNG(11));
|
||||
glOres = new GenLayerOres(this, world, random, rTerrain.nextParallelRNG(12));
|
||||
scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10);
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX))
|
||||
{
|
||||
god = new GenObjectDecorator(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkPlan onInitChunk(World world, int x, int z, Random random)
|
||||
{
|
||||
return new ChunkPlan();
|
||||
}
|
||||
|
||||
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
|
||||
{
|
||||
random = new Random(world.getSeed());
|
||||
PrecisionStopwatch s = getMetrics().start();
|
||||
ChunkData d = super.generateChunkData(world, random, x, z, biome);
|
||||
getMetrics().stop("chunk:ms", s);
|
||||
getMetrics().put("noise-hits", CNG.hits);
|
||||
metrics.setGenerators((int) CNG.creates);
|
||||
CNG.hits = 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
public IrisBiome biome(String name)
|
||||
{
|
||||
return getDimension().getBiomeByName(name);
|
||||
}
|
||||
|
||||
public double getOffsetX(double x, double z)
|
||||
{
|
||||
return Math.round((double) x * (Iris.settings.gen.horizontalZoom / 1.90476190476)) + swirl.noise(x, z);
|
||||
}
|
||||
|
||||
public double getOffsetZ(double x, double z)
|
||||
{
|
||||
return Math.round((double) z * (Iris.settings.gen.horizontalZoom / 1.90476190476)) - swirl.noise(z, x);
|
||||
}
|
||||
|
||||
public IrisMetrics getMetrics()
|
||||
{
|
||||
return metrics;
|
||||
}
|
||||
|
||||
public IrisBiome getBeach(IrisBiome biome)
|
||||
{
|
||||
IrisBiome beach = null;
|
||||
IrisRegion region = glBiome.getRegion(biome.getRegionID());
|
||||
|
||||
if(region != null)
|
||||
{
|
||||
beach = region.getBeach();
|
||||
}
|
||||
|
||||
if(beach == null)
|
||||
{
|
||||
beach = biome("Beach");
|
||||
}
|
||||
|
||||
return beach;
|
||||
}
|
||||
|
||||
public int computeHeight(int x, int z, ChunkPlan plan, IrisBiome biome)
|
||||
{
|
||||
return (int) Math.round(M.clip(getANoise((int) x, (int) z, plan, biome), 0D, 1D) * 253);
|
||||
}
|
||||
|
||||
public double getInterpolation(int x, int z, double opacity, ChunkPlan plan)
|
||||
{
|
||||
PrecisionStopwatch s = getMetrics().start();
|
||||
NoiseProvider n = (xf, zf) -> getBiomedHeight((int) Math.round(xf), (int) Math.round(zf), plan);
|
||||
double d = 0;
|
||||
double rad = Iris.settings.gen.interpolationRadius;
|
||||
|
||||
InterpolationMode m = Iris.settings.gen.interpolationMode;
|
||||
|
||||
if(m.equals(InterpolationMode.BILINEAR))
|
||||
{
|
||||
d = IrisInterpolation.getBilinearNoise(x, z, rad, n);
|
||||
}
|
||||
|
||||
else if(m.equals(InterpolationMode.BICUBIC))
|
||||
{
|
||||
d = IrisInterpolation.getBicubicNoise(x, z, rad, n);
|
||||
}
|
||||
|
||||
else if(m.equals(InterpolationMode.HERMITE_BICUBIC))
|
||||
{
|
||||
d = IrisInterpolation.getHermiteNoise(x, z, rad, n);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
d = n.noise(x, z);
|
||||
}
|
||||
|
||||
getMetrics().stop("interpolation:ms:x256:/biome:.", s);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public double getANoise(int x, int z, ChunkPlan plan, IrisBiome biome)
|
||||
{
|
||||
double hv = getInterpolation((int) x, (int) z, 1D, plan);
|
||||
hv += glLNoise.generateLayer(hv * Iris.settings.gen.roughness * 215, (double) x * Iris.settings.gen.roughness * 0.82, (double) z * Iris.settings.gen.roughness * 0.82) * (1.6918 * (hv * 2.35));
|
||||
|
||||
if(biome.hasCliffs())
|
||||
{
|
||||
hv = glCliffs.generateLayer(hv, x, z, biome.getCliffScale(), biome.getCliffChance());
|
||||
}
|
||||
|
||||
return hv;
|
||||
}
|
||||
|
||||
public IrisRegion getRegion(IrisBiome biome)
|
||||
{
|
||||
return glBiome.getRegion(biome.getRegionID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPopulator> getDefaultPopulators(World world)
|
||||
{
|
||||
KList<BlockPopulator> p = new KList<>();
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY) || Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING))
|
||||
{
|
||||
p.add(god = new GenObjectDecorator(this));
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGenParallax(int x, int z, Random random)
|
||||
{
|
||||
try
|
||||
{
|
||||
PrecisionStopwatch s = getMetrics().start();
|
||||
god.populateParallax(x, z, random);
|
||||
String xx = "x" + getParallaxSize().getX() * getParallaxSize().getZ();
|
||||
getMetrics().stop("object:" + xx + ":.:ms:/parallax", s);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private double getObjectHits()
|
||||
{
|
||||
int hits = objectHits;
|
||||
objectHits = 0;
|
||||
return hits;
|
||||
}
|
||||
|
||||
public IrisBiome getBiome(int x, int z)
|
||||
{
|
||||
IrisBiome biome = glBiome.getBiome(x, z);
|
||||
int height = computeHeight((int) x, (int) z, new ChunkPlan(), biome);
|
||||
biome = getBiome((int) x, height, (int) z);
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
private IrisBiome getBiome(int x, int y, int z)
|
||||
{
|
||||
int seaLevel = Iris.settings.gen.seaLevel;
|
||||
boolean land = y >= seaLevel;
|
||||
int beachHeight = land ? 1 + (int) Math.round(seaLevel + beach.noise(x, z) + 1) : seaLevel;
|
||||
boolean beach = y <= beachHeight && land;
|
||||
IrisBiome biome = glBiome.getBiome(x, z);
|
||||
IrisBiome realBiome = glBiome.getBiome(x, z, true);
|
||||
boolean nearAquatic = glBiome.isNearAquatic(x, z);
|
||||
IrisRegion region = getRegion(realBiome);
|
||||
|
||||
// Remove Oceans from biomes above sea level
|
||||
if(land && biome.getType().equals(BiomeType.FLUID))
|
||||
{
|
||||
biome = realBiome;
|
||||
}
|
||||
|
||||
// Add Beaches & Shores
|
||||
if(beach && biome.getType().equals(BiomeType.LAND))
|
||||
{
|
||||
biome = nearAquatic ? region.getBeach() : region.getShore();
|
||||
}
|
||||
|
||||
// // Replace biomes under sea level with lakes
|
||||
if(!land && biome.getType().equals(BiomeType.LAND))
|
||||
{
|
||||
biome = region.getLake();
|
||||
}
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome onGenColumn(int wxxf, int wzxf, int x, int z, ChunkPlan plan, AtomicChunkData data, boolean surfaceOnly)
|
||||
{
|
||||
PrecisionStopwatch s = getMetrics().start();
|
||||
if(disposed)
|
||||
{
|
||||
data.setBlock(x, 0, z, Material.MAGENTA_GLAZED_TERRACOTTA);
|
||||
return Biome.VOID;
|
||||
}
|
||||
|
||||
double wx = getOffsetX(wxxf, wzxf);
|
||||
double wz = getOffsetZ(wxxf, wzxf);
|
||||
int wxx = (int) wx;
|
||||
int wzx = (int) wz;
|
||||
int highest = 0;
|
||||
int seaLevel = Iris.settings.gen.seaLevel;
|
||||
IrisBiome biome = glBiome.getBiome(wxx, wzx);
|
||||
int height = computeHeight(wxx, wzx, plan, biome);
|
||||
int max = Math.max(height, seaLevel);
|
||||
biome = getBiome(wxx, height, wzx);
|
||||
MB FLUID = biome.getFluid();
|
||||
|
||||
for(int i = surfaceOnly ? max > seaLevel ? max - 2 : height - 2 : 0; i < max; i++)
|
||||
{
|
||||
MB mb = ROCK.get(scatterInt(wzx, i, wxx, ROCK.size()));
|
||||
boolean carved = surfaceOnly ? false : glCarving.isCarved(wzx, wxx, x, z, i, data, plan);
|
||||
boolean underwater = i >= height && i < seaLevel;
|
||||
boolean underground = i < height;
|
||||
int dheight = biome.getDirtDepth();
|
||||
int rheight = biome.getRockDepth();
|
||||
boolean dirt = (height - 1) - i < (dheight > 0 ? scatterInt(x, i, z, 4) : 0) + dheight;
|
||||
boolean rocky = i > height - rheight && !dirt;
|
||||
boolean bedrock = i == 0 || !Iris.settings.gen.flatBedrock ? i <= 2 : i < scatterInt(x, i, z, 3);
|
||||
|
||||
if(!carved)
|
||||
{
|
||||
mb = underwater ? FLUID : mb;
|
||||
mb = underground && dirt ? biome.getSubSurface(wxx, i, wzx, rTerrain) : mb;
|
||||
mb = underground && rocky ? biome.getRock(wxx, i, wzx, rTerrain) : mb;
|
||||
mb = bedrock ? BEDROCK : mb;
|
||||
|
||||
if(i == height - 1)
|
||||
{
|
||||
mb = biome.getSurface(wx, wz, rTerrain);
|
||||
}
|
||||
|
||||
highest = i > highest ? i : highest;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
mb = MB.of(Material.AIR);
|
||||
}
|
||||
data.setBlock(x, i, z, mb.material, mb.data);
|
||||
}
|
||||
|
||||
getMetrics().stop("terrain:ms:x256:/chunk:..", s);
|
||||
|
||||
int hw = 0;
|
||||
int hl = 0;
|
||||
|
||||
for(int i = highest; i > 0; i--)
|
||||
{
|
||||
Material t = data.getType(x, i, z);
|
||||
hw = i > seaLevel && hw == 0 && (t.equals(Material.WATER) || t.equals(Material.STATIONARY_WATER)) ? i : hw;
|
||||
hl = hl == 0 && !t.equals(Material.AIR) ? i : hl;
|
||||
}
|
||||
|
||||
plan.setRealHeight(x, z, hl);
|
||||
plan.setRealWaterHeight(x, z, hw == 0 ? seaLevel : hw);
|
||||
plan.setBiome(x, z, biome);
|
||||
|
||||
if(!surfaceOnly)
|
||||
{
|
||||
glCaves.genCaves(wxxf, wzxf, x, z, data, plan);
|
||||
glOres.genOres(wxxf, wzxf, x, z, hl, data, plan);
|
||||
}
|
||||
|
||||
for(int i = highest; i > 0; i--)
|
||||
{
|
||||
Material t = data.getType(x, i, z);
|
||||
hw = i > seaLevel && hw == 0 && (t.equals(Material.WATER) || t.equals(Material.STATIONARY_WATER)) ? i : hw;
|
||||
hl = hl == 0 && !t.equals(Material.AIR) ? i : hl;
|
||||
}
|
||||
|
||||
plan.setRealHeight(x, z, hl);
|
||||
plan.setRealWaterHeight(x, z, hw == 0 ? seaLevel : hw);
|
||||
plan.setBiome(x, z, biome);
|
||||
double time = s.getMilliseconds() * 256D;
|
||||
double atime = getMetrics().get("chunk:ms").getAverage();
|
||||
getMetrics().setParScale(time / atime);
|
||||
getMetrics().put("objects:,:/parallax", getObjectHits());
|
||||
|
||||
return biome.getRealBiome();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDecorateChunk(World world, int cx, int cz, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
int x = 0;
|
||||
int z = 0;
|
||||
int hhx = 0;
|
||||
int v = 0;
|
||||
int borderh = 0;
|
||||
int above = 0;
|
||||
int below = 0;
|
||||
|
||||
for(int f = 0; f < Iris.settings.gen.blockSmoothing; f++)
|
||||
{
|
||||
for(x = 0; x < 16; x++)
|
||||
{
|
||||
for(z = 0; z < 16; z++)
|
||||
{
|
||||
hhx = plan.getRealHeight(x, z);
|
||||
borderh = 0;
|
||||
|
||||
if(x == 0 || x == 15)
|
||||
{
|
||||
borderh++;
|
||||
}
|
||||
|
||||
if(z == 0 || z == 15)
|
||||
{
|
||||
borderh++;
|
||||
}
|
||||
|
||||
if(hhx > Iris.settings.gen.seaLevel - 2)
|
||||
{
|
||||
above = 0;
|
||||
below = 0;
|
||||
|
||||
if(x + 1 <= 15)
|
||||
{
|
||||
v = plan.getRealHeight(x + 1, z);
|
||||
|
||||
if(v > hhx)
|
||||
{
|
||||
above++;
|
||||
}
|
||||
|
||||
else if(v < hhx)
|
||||
{
|
||||
below++;
|
||||
}
|
||||
}
|
||||
|
||||
if(x - 1 >= 0)
|
||||
{
|
||||
v = plan.getRealHeight(x - 1, z);
|
||||
|
||||
if(v > hhx)
|
||||
{
|
||||
above++;
|
||||
}
|
||||
|
||||
else if(v < hhx)
|
||||
{
|
||||
below++;
|
||||
}
|
||||
}
|
||||
|
||||
if(z + 1 <= 15)
|
||||
{
|
||||
v = plan.getRealHeight(x, z + 1);
|
||||
|
||||
if(v > hhx)
|
||||
{
|
||||
above++;
|
||||
}
|
||||
|
||||
else if(v < hhx)
|
||||
{
|
||||
below++;
|
||||
}
|
||||
}
|
||||
|
||||
if(z - 1 >= 0)
|
||||
{
|
||||
v = plan.getRealHeight(x, z - 1);
|
||||
|
||||
if(v > hhx)
|
||||
{
|
||||
above++;
|
||||
}
|
||||
|
||||
else if(v < hhx)
|
||||
{
|
||||
below++;
|
||||
}
|
||||
}
|
||||
|
||||
// Patch Hole
|
||||
if(above >= 4 - borderh)
|
||||
{
|
||||
data.setBlock(x, hhx + 1, z, data.getMB(x, hhx, z));
|
||||
plan.setRealHeight(x, z, hhx + 1);
|
||||
}
|
||||
|
||||
// Remove Nipple
|
||||
else if(below >= 4 - borderh)
|
||||
{
|
||||
data.setBlock(x, hhx - 1, z, data.getMB(x, hhx, z));
|
||||
data.setBlock(x, hhx, z, Material.AIR);
|
||||
plan.setRealHeight(x, z, hhx - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getMetrics().stop("decoration:ms:/chunk:..", p);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void onDecorateColumn(World world, int x, int z, int wx, int wz, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
int h = plan.getRealHeight(x, z);
|
||||
|
||||
if(h < 63)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IrisBiome biome = plan.getBiome(x, z);
|
||||
|
||||
if(biome == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(biome.getSnow() > 0)
|
||||
{
|
||||
double level = glSnow.getHeight(wx, wz) * biome.getSnow();
|
||||
int blocks = (int) level;
|
||||
level -= blocks;
|
||||
int layers = (int) (level * 7D);
|
||||
int snowHeight = blocks + (layers > 0 ? 1 : 0);
|
||||
|
||||
for(int j = 0; j < snowHeight; j++)
|
||||
{
|
||||
data.setBlock(x, h + j + 1, z, j == snowHeight - 1 ? Material.SNOW : Material.SNOW_BLOCK, j == snowHeight - 1 ? (byte) layers : (byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
MB mbx = biome.getScatterChanceSingle(scatter(wx, h, wz), scatter(wz, h, wx));
|
||||
|
||||
if(!mbx.material.equals(Material.AIR))
|
||||
{
|
||||
data.setBlock(x, h + 1, z, mbx.material, mbx.data);
|
||||
|
||||
if(mbx.material.equals(Material.DOUBLE_PLANT))
|
||||
{
|
||||
data.setBlock(x, h + 2, z, mbx.material, (byte) 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(biome.getLush() > 0.33)
|
||||
{
|
||||
double lx = (biome.getLush() > 1 ? 1 : biome.getLush()) - 0.33;
|
||||
double g = glSnow.getHeight(wz, wx);
|
||||
|
||||
if(lx / 1.18D > g)
|
||||
{
|
||||
double gx = glSnow.getHeight(wx * 2.25, wz * 2.25);
|
||||
double gf = glSnow.getHeight(wx * 6.25, wz * 6.25);
|
||||
|
||||
if(gf > gx)
|
||||
{
|
||||
Leaves l = new Leaves(TreeSpecies.values()[(int) (gx * (TreeSpecies.values().length - 1))]);
|
||||
l.setDecaying(false);
|
||||
l.setDecayable(false);
|
||||
data.setBlock(x, h - 1, z, data.getMB(x, h, z));
|
||||
data.setBlock(x, h, z, l.getItemType(), l.getData());
|
||||
|
||||
if(gf - gx > 0.2)
|
||||
{
|
||||
l = new Leaves(TreeSpecies.values()[(int) (gf * (TreeSpecies.values().length - 1))]);
|
||||
l.setDecaying(false);
|
||||
l.setDecayable(false);
|
||||
data.setBlock(x, h + 1, z, l.getItemType(), l.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getMetrics().stop("pardecoration:ms:x256:/chunk:..", p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostChunk(World world, int cx, int cz, Random random, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private double getBiomedHeight(int x, int z, ChunkPlan plan)
|
||||
{
|
||||
double xh = plan.getHeight(x, z);
|
||||
|
||||
if(xh == -1)
|
||||
{
|
||||
IrisBiome biome = glBiome.getBiome(x, z);
|
||||
double h = Iris.settings.gen.baseHeight + biome.getHeight();
|
||||
h += biome.getGenerator().getHeight(x, z) / 2D;
|
||||
plan.setHeight(x, z, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
return xh;
|
||||
}
|
||||
|
||||
public RNG getRTerrain()
|
||||
{
|
||||
return rTerrain;
|
||||
}
|
||||
|
||||
public CompiledDimension getDimension()
|
||||
{
|
||||
return dim;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
if(disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
L.w(C.YELLOW + "Disposed Iris World " + C.RED + getWorld().getName());
|
||||
disposed = true;
|
||||
dim = null;
|
||||
glLNoise = null;
|
||||
glSnow = null;
|
||||
glCliffs = null;
|
||||
god.dispose();
|
||||
}
|
||||
|
||||
public boolean isDisposed()
|
||||
{
|
||||
return disposed;
|
||||
}
|
||||
|
||||
public PlacedObject nearest(Location o, int i)
|
||||
{
|
||||
PlacedObject f = null;
|
||||
double d = Integer.MAX_VALUE;
|
||||
if(god != null)
|
||||
{
|
||||
for(PlacedObject j : god.getHistory())
|
||||
{
|
||||
double dx = Math.abs(NumberConversions.square(j.getX() - o.getX()) + NumberConversions.square(j.getY() - o.getY()) + NumberConversions.square(j.getZ() - o.getZ()));
|
||||
|
||||
if(dx < d)
|
||||
{
|
||||
d = dx;
|
||||
f = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
public PlacedObject randomObject(String string)
|
||||
{
|
||||
return god.randomObject(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SChunkVector getParallaxSize()
|
||||
{
|
||||
return dim.getMaxChunkSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUnload()
|
||||
{
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void inject(CompiledDimension dimension)
|
||||
{
|
||||
this.dim = dimension;
|
||||
onInit(getWorld(), rTerrain);
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
|
||||
public class IrisSample
|
||||
{
|
||||
public MB surface;
|
||||
public int height;
|
||||
public IrisBiome biome;
|
||||
|
||||
public MB getSurface()
|
||||
{
|
||||
return surface;
|
||||
}
|
||||
|
||||
public void setSurface(MB surface)
|
||||
{
|
||||
this.surface = surface;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height)
|
||||
{
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public IrisBiome getBiome()
|
||||
{
|
||||
return biome;
|
||||
}
|
||||
|
||||
public void setBiome(IrisBiome biome)
|
||||
{
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((biome == null) ? 0 : biome.hashCode());
|
||||
result = prime * result + height;
|
||||
result = prime * result + ((surface == null) ? 0 : surface.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(this == obj)
|
||||
return true;
|
||||
if(obj == null)
|
||||
return false;
|
||||
if(getClass() != obj.getClass())
|
||||
return false;
|
||||
IrisSample other = (IrisSample) obj;
|
||||
if(biome == null)
|
||||
{
|
||||
if(other.biome != null)
|
||||
return false;
|
||||
}
|
||||
else if(!biome.equals(other.biome))
|
||||
return false;
|
||||
if(height != other.height)
|
||||
return false;
|
||||
if(surface == null)
|
||||
{
|
||||
if(other.surface != null)
|
||||
return false;
|
||||
}
|
||||
else if(!surface.equals(other.surface))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.api.nms.NMP;
|
||||
import mortar.api.sched.J;
|
||||
import mortar.compute.math.M;
|
||||
import mortar.lang.collection.FinalDouble;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.util.ChronoQueue;
|
||||
import ninja.bytecode.iris.util.ObjectMode;
|
||||
import ninja.bytecode.iris.util.SMCAVector;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
|
||||
public class WorldReactor
|
||||
{
|
||||
private static KList<ChronoQueue> q = new KList<>();
|
||||
private final World world;
|
||||
|
||||
public WorldReactor(World world)
|
||||
{
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public void generateRegionNormal(Player p, boolean force, double mst, Consumer<Double> progress, Runnable done)
|
||||
{
|
||||
for(ChronoQueue i : WorldReactor.q)
|
||||
{
|
||||
i.close();
|
||||
}
|
||||
|
||||
WorldReactor.q.clear();
|
||||
|
||||
ChronoQueue q = new ChronoQueue(mst, 10240);
|
||||
WorldReactor.q.add(q);
|
||||
FinalDouble of = new FinalDouble(0D);
|
||||
FinalDouble max = new FinalDouble(0D);
|
||||
KMap<SMCAVector, Double> d = new KMap<>();
|
||||
int mx = p.getLocation().getChunk().getX();
|
||||
int mz = p.getLocation().getChunk().getZ();
|
||||
for(int xx = p.getLocation().getChunk().getX() - 32; xx < p.getLocation().getChunk().getX() + 32; xx++)
|
||||
{
|
||||
int x = xx;
|
||||
|
||||
for(int zz = p.getLocation().getChunk().getZ() - 32; zz < p.getLocation().getChunk().getZ() + 32; zz++)
|
||||
{
|
||||
int z = zz;
|
||||
|
||||
if(world.isChunkLoaded(x, z) || world.loadChunk(x, z, false))
|
||||
{
|
||||
d.put(new SMCAVector(x, z), Math.sqrt(Math.pow(x - mx, 2) + Math.pow(z - mz, 2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KList<SMCAVector> v = d.k();
|
||||
Collections.sort(v, (a, b) -> (int) (10000 * (d.get(a) - d.get(b))));
|
||||
|
||||
for(SMCAVector i : v)
|
||||
{
|
||||
int x = i.getX();
|
||||
int z = i.getZ();
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX) && world.getGenerator() instanceof IrisGenerator)
|
||||
{
|
||||
IrisGenerator gg = ((IrisGenerator) world.getGenerator());
|
||||
gg.getWorldData().deleteChunk(x, z);
|
||||
}
|
||||
|
||||
max.add(1);
|
||||
q.queue(() ->
|
||||
{
|
||||
world.regenerateChunk(x, z);
|
||||
|
||||
Chunk cc = world.getChunkAt(x, z);
|
||||
NMP.host.relight(cc);
|
||||
of.add(1);
|
||||
|
||||
if(of.get() == max.get())
|
||||
{
|
||||
progress.accept(1D);
|
||||
q.dieSlowly();
|
||||
done.run();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
progress.accept(M.clip(of.get() / max.get(), 0D, 1D));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
J.s(() ->
|
||||
{
|
||||
q.dieSlowly();
|
||||
}, 20);
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.atomics;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class AtomicCharArray implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 2862133569453604235L;
|
||||
private static final Unsafe unsafe;
|
||||
private static final int base;
|
||||
private static final int shift;
|
||||
volatile char[] array;
|
||||
|
||||
public AtomicCharArray(int var1)
|
||||
{
|
||||
this.array = new char[var1];
|
||||
}
|
||||
|
||||
private long checkedByteOffset(int var1)
|
||||
{
|
||||
if(var1 >= 0 && var1 < this.array.length)
|
||||
{
|
||||
return byteOffset(var1);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IndexOutOfBoundsException("index " + var1);
|
||||
}
|
||||
}
|
||||
|
||||
public final char get(int var1)
|
||||
{
|
||||
return this.getRaw(this.checkedByteOffset(var1));
|
||||
}
|
||||
|
||||
private char getRaw(long var1)
|
||||
{
|
||||
return unsafe.getCharVolatile(this.array, var1);
|
||||
}
|
||||
|
||||
public final void set(int var1, char var2)
|
||||
{
|
||||
unsafe.putCharVolatile(this.array, this.checkedByteOffset(var1), var2);
|
||||
}
|
||||
|
||||
private static long byteOffset(int var0)
|
||||
{
|
||||
return ((long) var0 << shift) + (long) base;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
Field f;
|
||||
Unsafe o = null;
|
||||
|
||||
try
|
||||
{
|
||||
f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
o = (Unsafe) f.get(null);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
unsafe = o;
|
||||
base = unsafe.arrayBaseOffset(int[].class);
|
||||
int var0 = unsafe.arrayIndexScale(int[].class);
|
||||
if((var0 & var0 - 1) != 0)
|
||||
{
|
||||
throw new Error("data type scale not a power of two");
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = 31 - Integer.numberOfLeadingZeros(var0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,456 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.atomics;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.generator.CraftChunkData;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import mortar.compute.math.M;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
|
||||
public final class AtomicChunkData implements ChunkGenerator.ChunkData
|
||||
{
|
||||
private static final Field t;
|
||||
private static final Field[] sections;
|
||||
private static final int h = 0x1000;
|
||||
private final int maxHeight;
|
||||
private static ReentrantLock[] locks;
|
||||
private char[] s0;
|
||||
private char[] s1;
|
||||
private char[] s2;
|
||||
private char[] s3;
|
||||
private char[] s4;
|
||||
private char[] s5;
|
||||
private char[] s6;
|
||||
private char[] s7;
|
||||
private char[] s8;
|
||||
private char[] s9;
|
||||
private char[] s10;
|
||||
private char[] s11;
|
||||
private char[] s12;
|
||||
private char[] s13;
|
||||
private char[] s14;
|
||||
private char[] s15;
|
||||
private char[][] m;
|
||||
private World w;
|
||||
private long lastUse;
|
||||
private int bits;
|
||||
|
||||
public AtomicChunkData(World world)
|
||||
{
|
||||
this.maxHeight = world.getMaxHeight();
|
||||
this.w = world;
|
||||
bits = 0;
|
||||
lastUse = M.ms();
|
||||
}
|
||||
|
||||
public long getTimeSinceLastUse()
|
||||
{
|
||||
return M.ms() - lastUse;
|
||||
}
|
||||
|
||||
public void read(InputStream in) throws IOException
|
||||
{
|
||||
read(in, true);
|
||||
}
|
||||
|
||||
public void read(InputStream in, boolean ignoreAir) throws IOException
|
||||
{
|
||||
DataInputStream din = new DataInputStream(in);
|
||||
int bits = din.readInt();
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
int bit = getBit(i);
|
||||
if((bits & bit) == bit)
|
||||
{
|
||||
char[] section = getChunkSection(i << 4, true);
|
||||
|
||||
for(int j = 0; j < section.length; j++)
|
||||
{
|
||||
char c = din.readChar();
|
||||
|
||||
if(c == 0 && ignoreAir)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
section[j] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
din.close();
|
||||
}
|
||||
|
||||
public void write(OutputStream out) throws IOException
|
||||
{
|
||||
DataOutputStream dos = new DataOutputStream(out);
|
||||
dos.writeInt(getDataBits());
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
if(hasDataBit(i))
|
||||
{
|
||||
char[] section = getChunkSection(i << 4, false);
|
||||
for(int j = 0; j < section.length; j++)
|
||||
{
|
||||
dos.writeChar(section[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dos.close();
|
||||
}
|
||||
|
||||
public boolean hasDataBit(int section)
|
||||
{
|
||||
int b = getBit(section);
|
||||
return (bits & b) == b;
|
||||
}
|
||||
|
||||
public void clearDataBits()
|
||||
{
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
public void addDataBit(int section)
|
||||
{
|
||||
bits |= getBit(section);
|
||||
}
|
||||
|
||||
public void removeDataBit(int section)
|
||||
{
|
||||
bits ^= getBit(section);
|
||||
}
|
||||
|
||||
public int getDataBits()
|
||||
{
|
||||
return bits;
|
||||
}
|
||||
|
||||
public int getBit(int index)
|
||||
{
|
||||
return (int) (index < 0 ? -1 : Math.pow(2, index));
|
||||
}
|
||||
|
||||
public int computeDataBits()
|
||||
{
|
||||
int bits = 0;
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
bits |= sections[i].get(this) != null ? getBit(i) : 0;
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight()
|
||||
{
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, Material material)
|
||||
{
|
||||
setBlock(x, y, z, material.getId());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, MaterialData material)
|
||||
{
|
||||
setBlock(x, y, z, material.getItemTypeId(), material.getData());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, Material material)
|
||||
{
|
||||
setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.getId());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, MaterialData material)
|
||||
{
|
||||
setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.getItemTypeId(), material.getData());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public Material getType(int x, int y, int z)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return Material.getMaterial(getTypeId(x, y, z));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public MaterialData getTypeAndData(int x, int y, int z)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return getType(x, y, z).getNewData(getData(x, y, z));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setBlock(int x, int y, int z, Material blockId, byte data)
|
||||
{
|
||||
setBlock(x, y, z, blockId.getId(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
setRegion(xMin, yMin, zMin, xMax, yMax, zMax, blockId, (byte) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId, int data)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
throw new UnsupportedOperationException("AtomicChunkData does not support setting regions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int blockId)
|
||||
{
|
||||
setBlock(x, y, z, blockId, (byte) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int blockId, byte data)
|
||||
{
|
||||
setBlock(x, y, z, (char) (blockId << 4 | data));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public MB getMB(int x, int y, int z)
|
||||
{
|
||||
if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return MB.of(Material.AIR);
|
||||
}
|
||||
|
||||
char[] section = getChunkSection(y, false);
|
||||
|
||||
if(section == null)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return MB.of(Material.AIR);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lastUse = M.ms();
|
||||
char xf = section[(y & 0xf) << 8 | z << 4 | x];
|
||||
return MB.of(Material.getMaterial(xf >> 4), xf & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTypeId(int x, int y, int z)
|
||||
{
|
||||
if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char[] section = getChunkSection(y, false);
|
||||
|
||||
if(section == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return section[(y & 0xf) << 8 | z << 4 | x] >> 4;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getData(int x, int y, int z)
|
||||
{
|
||||
if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return (byte) 0;
|
||||
}
|
||||
|
||||
char[] section = getChunkSection(y, false);
|
||||
|
||||
if(section == null)
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return (byte) 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lastUse = M.ms();
|
||||
return (byte) (section[(y & 0xf) << 8 | z << 4 | x] & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
private void setBlock(int x, int y, int z, char type)
|
||||
{
|
||||
if(x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lastUse = M.ms();
|
||||
ReentrantLock l = locks[y >> 4];
|
||||
l.lock();
|
||||
getChunkSection(y, true)[(y & 0xf) << 8 | z << 4 | x] = type;
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
private char[] getChunkSection(int y, boolean c)
|
||||
{
|
||||
try
|
||||
{
|
||||
int s = y >> 4;
|
||||
Field sf = sections[s];
|
||||
char[] section = (char[]) sf.get(this);
|
||||
|
||||
if(section == null && c)
|
||||
{
|
||||
sf.set(this, new char[h]);
|
||||
section = (char[]) sf.get(this);
|
||||
addDataBit(s);
|
||||
}
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChunkData toChunkData()
|
||||
{
|
||||
ChunkData c = new CraftChunkData(w);
|
||||
|
||||
try
|
||||
{
|
||||
m = (char[][]) t.get(c);
|
||||
m[0] = s0;
|
||||
m[1] = s1;
|
||||
m[2] = s2;
|
||||
m[3] = s3;
|
||||
m[4] = s4;
|
||||
m[5] = s5;
|
||||
m[6] = s6;
|
||||
m[7] = s7;
|
||||
m[8] = s8;
|
||||
m[9] = s9;
|
||||
m[10] = s10;
|
||||
m[11] = s11;
|
||||
m[12] = s12;
|
||||
m[13] = s13;
|
||||
m[14] = s14;
|
||||
m[15] = s15;
|
||||
}
|
||||
|
||||
catch(IllegalArgumentException | IllegalAccessException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
locks = new ReentrantLock[16];
|
||||
Field[] s = new Field[16];
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
s[i] = AtomicChunkData.class.getDeclaredField("s" + i);
|
||||
locks[i] = new ReentrantLock();
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
sections = s;
|
||||
|
||||
Field x = null;
|
||||
|
||||
try
|
||||
{
|
||||
x = CraftChunkData.class.getDeclaredField("sections");
|
||||
x.setAccessible(true);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
t = x;
|
||||
}
|
||||
|
||||
public void inject(AtomicChunkData data)
|
||||
{
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
if(hasDataBit(i))
|
||||
{
|
||||
char[] fromSection = getChunkSection(i << 4, false);
|
||||
char[] toSection = data.getChunkSection(i << 4, true);
|
||||
|
||||
for(int j = 0; j < fromSection.length; j++)
|
||||
{
|
||||
char x = fromSection[j];
|
||||
|
||||
if(x != 0)
|
||||
{
|
||||
toSection[j] = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlock(int x, int y, int z, MB mb)
|
||||
{
|
||||
setBlock(x, y, z, mb.material, mb.data);
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.atomics;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.jnbt.ByteArrayTag;
|
||||
import org.jnbt.CompoundTag;
|
||||
import org.jnbt.NBTInputStream;
|
||||
import org.jnbt.NBTOutputStream;
|
||||
import org.jnbt.Tag;
|
||||
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
|
||||
public class AtomicRegionData
|
||||
{
|
||||
private final World world;
|
||||
private KMap<String, Tag> tag;
|
||||
|
||||
public AtomicRegionData(World world)
|
||||
{
|
||||
this.world = world;
|
||||
tag = new KMap<>();
|
||||
}
|
||||
|
||||
public void read(InputStream in) throws IOException
|
||||
{
|
||||
NBTInputStream nin = new NBTInputStream(in);
|
||||
tag = new KMap<>();
|
||||
tag.putAll(((CompoundTag) nin.readTag()).getValue());
|
||||
nin.close();
|
||||
}
|
||||
|
||||
public void write(OutputStream out) throws IOException
|
||||
{
|
||||
NBTOutputStream nos = new NBTOutputStream(out);
|
||||
nos.writeTag(new CompoundTag("imca", tag));
|
||||
nos.close();
|
||||
}
|
||||
|
||||
public boolean contains(int rx, int rz)
|
||||
{
|
||||
return tag.containsKey(rx + "." + rz);
|
||||
}
|
||||
|
||||
public void delete(int rx, int rz)
|
||||
{
|
||||
tag.remove(rx + "." + rz);
|
||||
}
|
||||
|
||||
public void set(int rx, int rz, AtomicChunkData data) throws IOException
|
||||
{
|
||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
||||
data.write(boas);
|
||||
tag.put(rx + "." + rz, new ByteArrayTag(rx + "." + rz, boas.toByteArray()));
|
||||
}
|
||||
|
||||
public AtomicChunkData get(int rx, int rz) throws IOException
|
||||
{
|
||||
if(!contains(rx, rz))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicChunkData data = new AtomicChunkData(world);
|
||||
ByteArrayTag btag = (ByteArrayTag) tag.get(rx + "." + rz);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(btag.getValue());
|
||||
data.read(in);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
return world;
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.atomics;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.util.SMCAVector;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
|
||||
public class AtomicWorldData
|
||||
{
|
||||
private World world;
|
||||
private KMap<SMCAVector, AtomicRegionData> loadedSections;
|
||||
|
||||
public AtomicWorldData(World world)
|
||||
{
|
||||
this.world = world;
|
||||
loadedSections = new KMap<>();
|
||||
getSubregionFolder().mkdirs();
|
||||
}
|
||||
|
||||
public KList<SMCAVector> getLoadedRegions()
|
||||
{
|
||||
return loadedSections.k();
|
||||
}
|
||||
|
||||
public AtomicRegionData getSubregion(int x, int z) throws IOException
|
||||
{
|
||||
if(!isSectionLoaded(x, z))
|
||||
{
|
||||
loadedSections.put(new SMCAVector(x, z), loadSection(x, z));
|
||||
}
|
||||
|
||||
AtomicRegionData f = loadedSections.get(new SMCAVector(x, z));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
public void saveAll() throws IOException
|
||||
{
|
||||
for(SMCAVector i : loadedSections.keySet())
|
||||
{
|
||||
saveSection(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void unloadAll(boolean save) throws IOException
|
||||
{
|
||||
for(SMCAVector i : loadedSections.keySet())
|
||||
{
|
||||
unloadSection(i, save);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteSection(int x, int z) throws IOException
|
||||
{
|
||||
unloadSection(x, z, false);
|
||||
getSubregionFile(x, z).delete();
|
||||
}
|
||||
|
||||
public boolean isSectionLoaded(int x, int z)
|
||||
{
|
||||
return isSectionLoaded(new SMCAVector(x, z));
|
||||
}
|
||||
|
||||
public boolean isSectionLoaded(SMCAVector s)
|
||||
{
|
||||
return loadedSections.containsKey(s);
|
||||
}
|
||||
|
||||
public boolean unloadSection(int x, int z, boolean save) throws IOException
|
||||
{
|
||||
return unloadSection(new SMCAVector(x, z), save);
|
||||
}
|
||||
|
||||
public boolean unloadSection(SMCAVector s, boolean save) throws IOException
|
||||
{
|
||||
if(!isSectionLoaded(s))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(save)
|
||||
{
|
||||
saveSection(s);
|
||||
}
|
||||
|
||||
loadedSections.remove(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean saveSection(int x, int z) throws IOException
|
||||
{
|
||||
return saveSection(new SMCAVector(x, z));
|
||||
}
|
||||
|
||||
public boolean saveSection(SMCAVector s) throws IOException
|
||||
{
|
||||
if(!isSectionLoaded(s.getX(), s.getZ()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AtomicRegionData data = loadedSections.get(s);
|
||||
FileOutputStream fos = new FileOutputStream(getSubregionFile(s.getX(), s.getZ()));
|
||||
data.write(fos);
|
||||
fos.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
public AtomicRegionData loadSection(int x, int z) throws IOException
|
||||
{
|
||||
if(isSectionLoaded(x, z))
|
||||
{
|
||||
return loadedSections.get(new SMCAVector(x, z));
|
||||
}
|
||||
|
||||
File file = getSubregionFile(x, z);
|
||||
|
||||
if(!file.exists())
|
||||
{
|
||||
return createSection(x, z);
|
||||
}
|
||||
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
AtomicRegionData data = new AtomicRegionData(world);
|
||||
data.read(fin);
|
||||
fin.close();
|
||||
return data;
|
||||
}
|
||||
|
||||
public AtomicRegionData createSection(int x, int z)
|
||||
{
|
||||
if(isSectionLoaded(x, z))
|
||||
{
|
||||
return loadedSections.get(new SMCAVector(x, z));
|
||||
}
|
||||
|
||||
AtomicRegionData data = new AtomicRegionData(world);
|
||||
loadedSections.put(new SMCAVector(x, z), data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public File getSubregionFile(int x, int z)
|
||||
{
|
||||
return new File(getSubregionFolder(), "sr." + x + "." + z + ".smca");
|
||||
}
|
||||
|
||||
public File getSubregionFolder()
|
||||
{
|
||||
return new File(world.getWorldFolder(), "subregion");
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,463 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.genobject;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
|
||||
import mortar.api.sched.S;
|
||||
import mortar.logic.format.F;
|
||||
import mortar.util.text.C;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.parallax.ParallaxCache;
|
||||
import ninja.bytecode.iris.generator.placer.AtomicParallaxPlacer;
|
||||
import ninja.bytecode.iris.generator.placer.BukkitPlacer;
|
||||
import ninja.bytecode.iris.generator.placer.NMSPlacer;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.util.IPlacer;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.iris.util.ObjectMode;
|
||||
import ninja.bytecode.iris.util.SMCAVector;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.collections.KSet;
|
||||
import ninja.bytecode.shuriken.execution.ChronoLatch;
|
||||
import ninja.bytecode.shuriken.execution.J;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenObjectDecorator extends BlockPopulator
|
||||
{
|
||||
private KList<PlacedObject> placeHistory;
|
||||
private KMap<IrisBiome, KList<GenObjectGroup>> orderCache;
|
||||
private KMap<IrisBiome, KMap<GenObjectGroup, Double>> populationCache;
|
||||
private IPlacer placer;
|
||||
private IrisGenerator g;
|
||||
private ChronoLatch cl = new ChronoLatch(250);
|
||||
|
||||
public GenObjectDecorator(IrisGenerator generator)
|
||||
{
|
||||
this.g = generator;
|
||||
placeHistory = new KList<>();
|
||||
populationCache = new KMap<>();
|
||||
orderCache = new KMap<>();
|
||||
|
||||
for(IrisBiome i : generator.getDimension().getBiomes())
|
||||
{
|
||||
KMap<GenObjectGroup, Double> gc = new KMap<>();
|
||||
KMap<Integer, KList<GenObjectGroup>> or = new KMap<>();
|
||||
int ff = 0;
|
||||
for(String j : i.getSchematicGroups().k())
|
||||
{
|
||||
double c = i.getSchematicGroups().get(j);
|
||||
|
||||
try
|
||||
{
|
||||
GenObjectGroup g = generator.getDimension().getObjectGroup(j);
|
||||
ff += g.size();
|
||||
gc.put(g, c);
|
||||
|
||||
if(!or.containsKey(g.getPiority()))
|
||||
{
|
||||
or.put(g.getPiority(), new KList<>());
|
||||
}
|
||||
|
||||
or.get(g.getPiority()).add(g);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
L.f(ChatColor.RED + "Failed to inject " + j + " into GenObjectDecorator");
|
||||
L.ex(e);
|
||||
}
|
||||
}
|
||||
|
||||
if(!gc.isEmpty())
|
||||
{
|
||||
KList<GenObjectGroup> g = new KList<>();
|
||||
for(KList<GenObjectGroup> j : or.v())
|
||||
{
|
||||
g.addAll(j);
|
||||
}
|
||||
|
||||
Collections.sort(g, (a, b) -> a.getPiority() - b.getPiority());
|
||||
orderCache.put(i, g);
|
||||
populationCache.put(i, gc);
|
||||
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.v(C.DARK_GREEN + i.getName() + ": " + C.DARK_AQUA + F.f(ff) + " Objects");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
L.i("Population Cache is " + populationCache.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(World world, Random random, Chunk source)
|
||||
{
|
||||
Runnable m = () ->
|
||||
{
|
||||
try
|
||||
{
|
||||
if(g.isDisposed())
|
||||
{
|
||||
placeHistory.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
KSet<IrisBiome> hits = new KSet<>();
|
||||
int cx = source.getX();
|
||||
int cz = source.getZ();
|
||||
|
||||
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
|
||||
{
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
IrisBiome biome = g.getBiome((int) g.getOffsetX(x, z), (int) g.getOffsetZ(x, z));
|
||||
|
||||
if(hits.contains(biome))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
KMap<GenObjectGroup, Double> objects = populationCache.get(biome);
|
||||
|
||||
if(objects == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hits.add(biome);
|
||||
populate(world, cx, cz, random, biome);
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
|
||||
{
|
||||
J.a(m);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
m.run();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void populate(World world, int cx, int cz, Random random, IrisBiome biome)
|
||||
{
|
||||
for(GenObjectGroup i : orderCache.get(biome))
|
||||
{
|
||||
if(biome.getSchematicGroups().get(i.getName()) == null)
|
||||
{
|
||||
L.w(C.YELLOW + "Cannot find chance for " + C.RED + i.getName() + C.YELLOW + " in Biome " + C.RED + biome.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int j = 0; j < getTries(biome.getSchematicGroups().get(i.getName())); j++)
|
||||
{
|
||||
if(M.r(Iris.settings.gen.objectDensity))
|
||||
{
|
||||
GenObject go = i.getSchematics().get(random.nextInt(i.getSchematics().size()));
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
|
||||
if(i.getWorldChance() >= 0D)
|
||||
{
|
||||
int rngx = (int) Math.floor(x / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
|
||||
int rngz = (int) Math.floor(z / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
|
||||
|
||||
if(new RNG(new SMCAVector(rngx, rngz).hashCode()).nextDouble() < i.getWorldChance())
|
||||
{
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place due to a world chance.");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int by = world.getHighestBlockYAt(x, z);
|
||||
Block b = world.getBlockAt(x, by - 1, z);
|
||||
MB mb = MB.of(b.getType(), b.getData());
|
||||
|
||||
if(!Iris.settings.performance.noObjectFail)
|
||||
{
|
||||
if(!mb.material.isSolid() || !biome.isSurface(mb.material))
|
||||
{
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place in " + C.YELLOW + mb.material.toString().toLowerCase() + C.WHITE + " at " + C.YELLOW + F.f(x) + " " + F.f(by) + " " + F.f(z));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
|
||||
{
|
||||
placer = new NMSPlacer(world);
|
||||
}
|
||||
|
||||
else if(Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING_PHYSICS))
|
||||
{
|
||||
placer = new BukkitPlacer(world, true);
|
||||
}
|
||||
|
||||
else if(Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING))
|
||||
{
|
||||
placer = new BukkitPlacer(world, false);
|
||||
}
|
||||
|
||||
Runnable rx = () ->
|
||||
{
|
||||
Location start = go.place(x, by, z, placer);
|
||||
|
||||
if(start != null)
|
||||
{
|
||||
g.hitObject();
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + go.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ()));
|
||||
}
|
||||
|
||||
if(Iris.settings.performance.debugMode)
|
||||
{
|
||||
placeHistory.add(new PlacedObject(start.getBlockX(), start.getBlockY(), start.getBlockZ(), i.getName() + ":" + go.getName()));
|
||||
|
||||
if(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
while(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
placeHistory.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.QUICK_N_DIRTY))
|
||||
{
|
||||
new S(20)
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
rx.run();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
rx.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(placer != null && cl.flip())
|
||||
{
|
||||
placer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void populateParallax(int cx, int cz, Random random)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(g.isDisposed())
|
||||
{
|
||||
placeHistory.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
ParallaxCache cache = new ParallaxCache(g);
|
||||
KSet<IrisBiome> hits = new KSet<>();
|
||||
|
||||
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
|
||||
{
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
IrisBiome biome = cache.getBiome(x, z);
|
||||
|
||||
if(hits.contains(biome))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
KMap<GenObjectGroup, Double> objects = populationCache.get(biome);
|
||||
|
||||
if(objects == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hits.add(biome);
|
||||
populateParallax(cx, cz, random, biome, cache);
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void populateParallax(int cx, int cz, Random random, IrisBiome biome, ParallaxCache cache)
|
||||
{
|
||||
for(GenObjectGroup i : orderCache.get(biome))
|
||||
{
|
||||
if(biome.getSchematicGroups().get(i.getName()) == null)
|
||||
{
|
||||
L.w(C.YELLOW + "Cannot find chance for " + C.RED + i.getName() + C.YELLOW + " in Biome " + C.RED + biome.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int j = 0; j < getTries(biome.getSchematicGroups().get(i.getName())); j++)
|
||||
{
|
||||
if(M.r(Iris.settings.gen.objectDensity))
|
||||
{
|
||||
if(i.getSchematics().isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GenObject go = i.getSchematics().get(random.nextInt(i.getSchematics().size()));
|
||||
int x = (cx << 4) + random.nextInt(16);
|
||||
int z = (cz << 4) + random.nextInt(16);
|
||||
|
||||
if(i.getWorldChance() >= 0D)
|
||||
{
|
||||
int rngx = (int) Math.floor(x / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
|
||||
int rngz = (int) Math.floor(z / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
|
||||
|
||||
if(new RNG(new SMCAVector(rngx, rngz).hashCode()).nextDouble() < i.getWorldChance())
|
||||
{
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place due to a world chance.");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int by = cache.getHeight(x, z);
|
||||
MB mb = cache.get(x, by, z);
|
||||
|
||||
if(!Iris.settings.performance.noObjectFail)
|
||||
{
|
||||
if(!mb.material.isSolid() || !biome.isSurface(mb.material))
|
||||
{
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place in " + C.YELLOW + mb.material.toString().toLowerCase() + C.WHITE + " at " + C.YELLOW + F.f(x) + " " + F.f(by) + " " + F.f(z));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
placer = new AtomicParallaxPlacer(g, cache);
|
||||
Location start = go.place(x, by, z, placer);
|
||||
|
||||
if(start != null)
|
||||
{
|
||||
g.hitObject();
|
||||
if(Iris.settings.performance.verbose)
|
||||
{
|
||||
L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + go.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ()));
|
||||
}
|
||||
|
||||
if(Iris.settings.performance.debugMode)
|
||||
{
|
||||
placeHistory.add(new PlacedObject(start.getBlockX(), start.getBlockY(), start.getBlockZ(), i.getName() + ":" + go.getName()));
|
||||
|
||||
if(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
while(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
|
||||
{
|
||||
placeHistory.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(placer != null && cl.flip())
|
||||
{
|
||||
placer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public int getTries(double chance)
|
||||
{
|
||||
if(chance <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(Math.floor(chance) == chance)
|
||||
{
|
||||
return (int) chance;
|
||||
}
|
||||
|
||||
int floor = (int) Math.floor(chance);
|
||||
|
||||
if(chance - floor > 0 && M.r(chance - floor))
|
||||
{
|
||||
floor++;
|
||||
}
|
||||
|
||||
return floor;
|
||||
}
|
||||
|
||||
public KList<PlacedObject> getHistory()
|
||||
{
|
||||
return placeHistory;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public PlacedObject randomObject(String string)
|
||||
{
|
||||
KList<PlacedObject> v = new KList<>();
|
||||
|
||||
for(PlacedObject i : placeHistory)
|
||||
{
|
||||
if(i.getF().toLowerCase().replaceAll("\\Q:\\E", "/").startsWith(string.toLowerCase()))
|
||||
{
|
||||
v.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
if(v.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return v.getRandom();
|
||||
}
|
||||
}
|
||||
@@ -1,387 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.genobject;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.util.Direction;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.format.Form;
|
||||
import ninja.bytecode.shuriken.io.IO;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
|
||||
public class GenObjectGroup
|
||||
{
|
||||
private KList<GenObject> schematics;
|
||||
private KList<GenObject> osSchematics;
|
||||
private KList<GenObject> pxSchematics;
|
||||
private KList<String> flags;
|
||||
private String name;
|
||||
private int priority;
|
||||
private double worldChance;
|
||||
private int worldRad;
|
||||
|
||||
public GenObjectGroup(String name)
|
||||
{
|
||||
this.schematics = new KList<>();
|
||||
this.flags = new KList<>();
|
||||
this.name = name;
|
||||
priority = Integer.MIN_VALUE;
|
||||
worldChance = Integer.MIN_VALUE;
|
||||
worldRad = 32;
|
||||
}
|
||||
|
||||
public void read(DataInputStream din) throws IOException
|
||||
{
|
||||
flags.clear();
|
||||
schematics.clear();
|
||||
name = din.readUTF();
|
||||
int fl = din.readInt();
|
||||
int sc = din.readInt();
|
||||
|
||||
for(int i = 0; i < fl; i++)
|
||||
{
|
||||
flags.add(din.readUTF());
|
||||
}
|
||||
|
||||
for(int i = 0; i < sc; i++)
|
||||
{
|
||||
GenObject g = new GenObject(0, 0, 0);
|
||||
g.readDirect(din);
|
||||
schematics.add(g);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(DataOutputStream dos, Consumer<Double> progress) throws IOException
|
||||
{
|
||||
dos.writeUTF(name);
|
||||
dos.writeInt(flags.size());
|
||||
dos.writeInt(schematics.size());
|
||||
|
||||
for(String i : flags)
|
||||
{
|
||||
dos.writeUTF(i);
|
||||
}
|
||||
|
||||
int of = 0;
|
||||
|
||||
if(progress != null)
|
||||
{
|
||||
progress.accept((double) of / (double) schematics.size());
|
||||
}
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
i.writeDirect(dos);
|
||||
of++;
|
||||
|
||||
if(progress != null)
|
||||
{
|
||||
progress.accept((double) of / (double) schematics.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyLushFilter(double factor)
|
||||
{
|
||||
if(flags.contains("no lush"))
|
||||
{
|
||||
L.i(ChatColor.DARK_GREEN + "Skipping Lush Filter for " + ChatColor.GRAY + getName());
|
||||
return;
|
||||
}
|
||||
|
||||
L.i(ChatColor.GREEN + "Applying Lush Filter to " + ChatColor.WHITE + getName());
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
i.applyLushFilter(factor);
|
||||
}
|
||||
}
|
||||
|
||||
public void applySnowFilter(int factor)
|
||||
{
|
||||
if(flags.contains("no snow"))
|
||||
{
|
||||
L.i(ChatColor.DARK_AQUA + "Skipping Snow Filter for " + ChatColor.GRAY + getName());
|
||||
return;
|
||||
}
|
||||
|
||||
L.i(ChatColor.AQUA + "Applying Snow Filter to " + ChatColor.WHITE + getName());
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
i.applySnowFilter(factor);
|
||||
}
|
||||
}
|
||||
|
||||
public GenObjectGroup copy(String suffix)
|
||||
{
|
||||
GenObjectGroup gog = new GenObjectGroup(name + suffix);
|
||||
gog.schematics = new KList<>();
|
||||
gog.flags = flags.copy();
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
GenObject g = i.copy();
|
||||
g.setName(i.getName() + suffix);
|
||||
gog.schematics.add(g);
|
||||
}
|
||||
|
||||
return gog;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public KList<GenObject> getSchematics()
|
||||
{
|
||||
return schematics;
|
||||
}
|
||||
|
||||
public KList<GenObject> getPXSchematics()
|
||||
{
|
||||
if(pxSchematics == null)
|
||||
{
|
||||
pxSchematics = new KList<>();
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
if(!i.isOversized())
|
||||
{
|
||||
pxSchematics.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pxSchematics;
|
||||
}
|
||||
|
||||
public KList<GenObject> getOSSchematics()
|
||||
{
|
||||
if(osSchematics == null)
|
||||
{
|
||||
osSchematics = new KList<>();
|
||||
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
if(i.isOversized())
|
||||
{
|
||||
osSchematics.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pxSchematics;
|
||||
}
|
||||
|
||||
public void setSchematics(KList<GenObject> schematics)
|
||||
{
|
||||
this.schematics = schematics;
|
||||
}
|
||||
|
||||
public KList<String> getFlags()
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
public void setFlags(KList<String> flags)
|
||||
{
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return getSchematics().size();
|
||||
}
|
||||
|
||||
public int getPiority()
|
||||
{
|
||||
if(priority == Integer.MIN_VALUE)
|
||||
{
|
||||
for(String i : flags)
|
||||
{
|
||||
if(i.startsWith("priority "))
|
||||
{
|
||||
priority = Integer.valueOf(i.split("\\Q \\E")[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
public static GenObjectGroup load(String string)
|
||||
{
|
||||
File folder = Iris.pack().loadFolder(string);
|
||||
|
||||
if(folder != null)
|
||||
{
|
||||
GenObjectGroup g = new GenObjectGroup(string);
|
||||
|
||||
for(File i : folder.listFiles())
|
||||
{
|
||||
if(i.getName().endsWith(".ifl"))
|
||||
{
|
||||
try
|
||||
{
|
||||
g.flags.add(IO.readAll(i).split("\\Q\n\\E"));
|
||||
}
|
||||
|
||||
catch(IOException e)
|
||||
{
|
||||
L.ex(e);
|
||||
}
|
||||
}
|
||||
|
||||
if(i.getName().endsWith(".ish"))
|
||||
{
|
||||
try
|
||||
{
|
||||
GenObject s = GenObject.load(i);
|
||||
g.getSchematics().add(s);
|
||||
}
|
||||
|
||||
catch(IOException e)
|
||||
{
|
||||
L.f("Cannot load Schematic: " + string + "/" + i.getName());
|
||||
L.ex(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void processVariants()
|
||||
{
|
||||
for(GenObject i : getSchematics())
|
||||
{
|
||||
i.recalculateMountShift();
|
||||
|
||||
for(String j : flags)
|
||||
{
|
||||
i.computeFlag(j);
|
||||
}
|
||||
}
|
||||
|
||||
if(!flags.contains("no rotation"))
|
||||
{
|
||||
KList<GenObject> inject = new KList<>();
|
||||
for(GenObject i : getSchematics())
|
||||
{
|
||||
for(Direction j : new Direction[] {Direction.S, Direction.E, Direction.W})
|
||||
{
|
||||
GenObject cp = i.copy();
|
||||
GenObject f = cp;
|
||||
f.rotate(Direction.N, j);
|
||||
f.recalculateMountShift();
|
||||
inject.add(f);
|
||||
}
|
||||
}
|
||||
|
||||
getSchematics().add(inject);
|
||||
}
|
||||
|
||||
L.i(ChatColor.LIGHT_PURPLE + "Processed " + ChatColor.WHITE + Form.f(schematics.size()) + ChatColor.LIGHT_PURPLE + " Schematics in " + ChatColor.WHITE + name);
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
for(GenObject i : schematics)
|
||||
{
|
||||
i.dispose();
|
||||
}
|
||||
|
||||
schematics.clear();
|
||||
flags.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((flags == null) ? 0 : flags.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + priority;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(this == obj)
|
||||
return true;
|
||||
if(obj == null)
|
||||
return false;
|
||||
if(getClass() != obj.getClass())
|
||||
return false;
|
||||
GenObjectGroup other = (GenObjectGroup) obj;
|
||||
if(flags == null)
|
||||
{
|
||||
if(other.flags != null)
|
||||
return false;
|
||||
}
|
||||
else if(!flags.equals(other.flags))
|
||||
return false;
|
||||
if(name == null)
|
||||
{
|
||||
if(other.name != null)
|
||||
return false;
|
||||
}
|
||||
else if(!name.equals(other.name))
|
||||
return false;
|
||||
if(priority != other.priority)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public double getWorldChance()
|
||||
{
|
||||
if(worldChance == Integer.MIN_VALUE)
|
||||
{
|
||||
for(String i : flags)
|
||||
{
|
||||
if(i.startsWith("world chance "))
|
||||
{
|
||||
worldChance = Double.valueOf(i.split("\\Q \\E")[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return worldChance;
|
||||
}
|
||||
|
||||
public double getWorldRadius()
|
||||
{
|
||||
if(worldRad == Integer.MIN_VALUE)
|
||||
{
|
||||
for(String i : flags)
|
||||
{
|
||||
if(i.startsWith("world radius "))
|
||||
{
|
||||
worldRad = Integer.valueOf(i.split("\\Q \\E")[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return worldRad;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.genobject;
|
||||
|
||||
public class PlacedObject
|
||||
{
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
private String f;
|
||||
|
||||
public PlacedObject(int x, int y, int z, String f)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
public int getX()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getY()
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y)
|
||||
{
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getZ()
|
||||
{
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(int z)
|
||||
{
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public String getF()
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
public void setF(String f)
|
||||
{
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((f == null) ? 0 : f.hashCode());
|
||||
result = prime * result + x;
|
||||
result = prime * result + y;
|
||||
result = prime * result + z;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(this == obj)
|
||||
return true;
|
||||
if(obj == null)
|
||||
return false;
|
||||
if(getClass() != obj.getClass())
|
||||
return false;
|
||||
PlacedObject other = (PlacedObject) obj;
|
||||
if(f == null)
|
||||
{
|
||||
if(other.f != null)
|
||||
return false;
|
||||
}
|
||||
else if(!f.equals(other.f))
|
||||
return false;
|
||||
if(x != other.x)
|
||||
return false;
|
||||
if(y != other.y)
|
||||
return false;
|
||||
if(z != other.z)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class BiomeNoiseGenerator
|
||||
{
|
||||
protected IrisBiome biome;
|
||||
protected CNG gen;
|
||||
private double block = 1D / 255D;
|
||||
|
||||
public BiomeNoiseGenerator(RNG rng, IrisBiome biome)
|
||||
{
|
||||
this.biome = biome;
|
||||
//@builder
|
||||
gen = new CNG(rng.nextParallelRNG(31289 - biome.getName().length() * biome.getRealBiome().ordinal()), 1D, 1)
|
||||
.scale(0.0025 * biome.getGenScale())
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(2922 * biome.getName().length() - biome.getRealBiome().ordinal()), 1D, 1)
|
||||
.scale(0.0075 * biome.getGenSwirlScale()), 20D * biome.getGenSwirl());
|
||||
//@done
|
||||
}
|
||||
|
||||
public double getHeight(double x, double z)
|
||||
{
|
||||
if(biome.getGenAmplifier() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double r = block * 52;
|
||||
return (gen.noise(x, z) * biome.getGenAmplifier() * r);
|
||||
}
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import mortar.util.text.C;
|
||||
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.Borders;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.iris.util.PolygonGenerator;
|
||||
import ninja.bytecode.shuriken.collections.KList;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerBiome extends GenLayer
|
||||
{
|
||||
private KMap<String, IrisRegion> regions;
|
||||
private Function<CNG, CNG> factory;
|
||||
private CNG fracture;
|
||||
private CNG fuzz;
|
||||
private PolygonGenerator channel;
|
||||
private PolygonGenerator ocean;
|
||||
private BiomeLayer master;
|
||||
|
||||
public GenLayerBiome(IrisGenerator iris, World world, Random random, RNG rng, KList<IrisBiome> biomes)
|
||||
{
|
||||
super(iris, world, random, rng);
|
||||
//@builder
|
||||
channel = new PolygonGenerator(rng.nextParallelRNG(-12), 2, 0.0005, 1, (g)->g.fractureWith(new CNG(rng.nextParallelRNG(34), 1D, 2)
|
||||
.scale(0.01), 30));
|
||||
ocean = new PolygonGenerator(rng.nextParallelRNG(-11), 6, 0.005, 1, (g)->g.fractureWith(new CNG(rng.nextParallelRNG(34), 1D, 2)
|
||||
.scale(0.01), 150));
|
||||
fuzz = new CNG(rng.nextParallelRNG(9112), 1D * 12 * Iris.settings.gen.biomeEdgeFuzzScale, 1).scale(6.5);
|
||||
fracture = new CNG(rng.nextParallelRNG(28), 1D, 4).scale(0.0021 * Iris.settings.gen.biomeEdgeScrambleScale)
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(34), 1D, 2)
|
||||
.scale(0.01), 12250);
|
||||
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 KMap<>();
|
||||
|
||||
for(IrisBiome i : biomes)
|
||||
{
|
||||
if(i.getRegionID().equals("default"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!regions.containsKey(i.getRegionID()))
|
||||
{
|
||||
regions.put(i.getRegionID(), new IrisRegion(i.getRegionID()));
|
||||
}
|
||||
|
||||
regions.get(i.getRegionID()).getBiomes().add(i);
|
||||
}
|
||||
|
||||
for(IrisRegion i : regions.values())
|
||||
{
|
||||
i.load();
|
||||
}
|
||||
|
||||
int m = 0;
|
||||
|
||||
for(IrisBiome i : iris.getDimension().getBiomes())
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public IrisBiome getBiome(double wxx, double wzx)
|
||||
{
|
||||
return getBiome(wxx, wzx, false);
|
||||
}
|
||||
|
||||
public boolean isNearAquatic(int wxx, int wzx)
|
||||
{
|
||||
double wx = Math.round((double) wxx * (Iris.settings.gen.horizontalZoom / 1.90476190476)) * Iris.settings.gen.biomeScale;
|
||||
double wz = Math.round((double) wzx * (Iris.settings.gen.horizontalZoom / 1.90476190476)) * Iris.settings.gen.biomeScale;
|
||||
double xf = wx + ((fracture.noise(wx, wz) / 2D) * 200D * Iris.settings.gen.biomeEdgeScrambleRange);
|
||||
double zf = wz - ((fracture.noise(wz, wx) / 2D) * 200D * Iris.settings.gen.biomeEdgeScrambleRange);
|
||||
double x = xf - fuzz.noise(wx, wz);
|
||||
double z = zf + fuzz.noise(wz, wx);
|
||||
|
||||
if(ocean.getIndex(x, z) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(channel.hasBorder(3, 44, xf, zf))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(Borders.isBorderWithin(x, z, 3, 24D, (x + z) / 100D, (xx, zz) -> ocean.getIndex(xx, zz)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(ocean.getClosestNeighbor(x, z) > 0.2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(channel.getClosestNeighbor(x, z) > 0.2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(channel.hasBorder(3, 7, xf, zf) || channel.hasBorder(3, 3, xf, zf))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public IrisBiome getBiome(double wxx, double wzx, boolean real)
|
||||
{
|
||||
double wx = Math.round((double) wxx * (Iris.settings.gen.horizontalZoom / 1.90476190476)) * Iris.settings.gen.biomeScale;
|
||||
double wz = Math.round((double) wzx * (Iris.settings.gen.horizontalZoom / 1.90476190476)) * Iris.settings.gen.biomeScale;
|
||||
double xf = wx + ((fracture.noise(wx, wz) / 2D) * 200D * Iris.settings.gen.biomeEdgeScrambleRange);
|
||||
double zf = wz - ((fracture.noise(wz, wx) / 2D) * 200D * Iris.settings.gen.biomeEdgeScrambleRange);
|
||||
double x = xf - fuzz.noise(wx, wz);
|
||||
double z = zf + fuzz.noise(wz, wx);
|
||||
IrisBiome biome = master.computeBiome(x, z);
|
||||
|
||||
if(real)
|
||||
{
|
||||
return biome;
|
||||
}
|
||||
|
||||
if(ocean.getIndex(x, z) == 0)
|
||||
{
|
||||
IrisRegion region = getRegion(biome.getRegionID());
|
||||
|
||||
if(region == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Region " + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
if(!Borders.isBorderWithin(x, z, 7, 45, (x / 10D) + (z / 10D), (a, b) -> ocean.getIndex(a, b)))
|
||||
{
|
||||
if(region.getDeepOcean() == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Deep Ocean in Region" + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
return getRegion(biome.getRegionID()).getDeepOcean();
|
||||
}
|
||||
|
||||
if(region.getOcean() == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Ocean in Region" + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
return getRegion(biome.getRegionID()).getOcean();
|
||||
}
|
||||
|
||||
if(channel.hasBorder(3, 44, xf, zf))
|
||||
{
|
||||
IrisRegion region = getRegion(biome.getRegionID());
|
||||
|
||||
if(region == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Region " + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
if(region.getChannel() == null)
|
||||
{
|
||||
L.f(C.YELLOW + "Cannot find Channel in Region" + C.RED + biome.getRegionID());
|
||||
return biome;
|
||||
}
|
||||
|
||||
return getRegion(biome.getRegionID()).getChannel();
|
||||
}
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double noise, double dx, double dz)
|
||||
{
|
||||
return noise;
|
||||
}
|
||||
|
||||
public IrisRegion getRegion(String name)
|
||||
{
|
||||
return regions.get(name);
|
||||
}
|
||||
|
||||
public void compileInfo(BiomeLayer l)
|
||||
{
|
||||
l.compileChildren(0.082 * Iris.settings.gen.biomeScale * 0.189, 1, factory, true);
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.iris.util.IrisInterpolation;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerCarving extends GenLayer
|
||||
{
|
||||
private CNG scram;
|
||||
private CNG cng;
|
||||
private CNG cngh;
|
||||
private CNG cngo;
|
||||
|
||||
public GenLayerCarving(IrisGenerator iris, World world, Random random, RNG rng)
|
||||
{
|
||||
//@builder
|
||||
super(iris, world, random, rng);
|
||||
cng = new CNG(rng.nextParallelRNG(2339234), 1D, 1).scale(0.02);
|
||||
cngh = new CNG(rng.nextParallelRNG(1939234), 1D, 1).scale(0.027);
|
||||
cngo = new CNG(rng.nextParallelRNG(8939234), 1D, 1).scale(0.002);
|
||||
scram = new CNG(rng.nextParallelRNG(2639634), 1D, 1).scale(0.15);
|
||||
|
||||
//@done
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double gnoise, double dx, double dz)
|
||||
{
|
||||
return gnoise;
|
||||
}
|
||||
|
||||
public boolean isCarved(double vwxxf, double vwzxf, int x, int z, double hl, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
double a = cngh.noise(vwxxf, vwzxf);
|
||||
double hmax = 99 + (a * 30);
|
||||
double hmin = 68 + (a * 30);
|
||||
|
||||
if(hl > hmax || hl < hmin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
double wxxf = (scram.noise(vwxxf, vwzxf) * 12) - vwzxf;
|
||||
double wzxf = (scram.noise(vwzxf, vwxxf) * 12) + vwxxf;
|
||||
|
||||
double downrange = M.lerpInverse(hmin, hmax, hl);
|
||||
double opacity = IrisInterpolation.sinCenter(downrange);
|
||||
|
||||
if(cng.noise(wxxf, wzxf, hl / 3) < (opacity / 1.4D) * cngo.noise(wxxf, wzxf))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
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.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.util.Borders;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.iris.util.PolygonGenerator;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerCaves extends GenLayer
|
||||
{
|
||||
private PolygonGenerator g;
|
||||
private CNG gincline;
|
||||
private CNG scram;
|
||||
|
||||
public GenLayerCaves(IrisGenerator iris, World world, Random random, RNG rng)
|
||||
{
|
||||
//@builder
|
||||
super(iris, world, random, rng);
|
||||
g = new PolygonGenerator(rng.nextParallelRNG(1111), 3, 0.024, 8, (c) -> c);
|
||||
gincline = new CNG(rng.nextParallelRNG(1112), 1D, 3).scale(0.00652);
|
||||
scram = new CNG(rng.nextParallelRNG(2639634), 1D, 1).scale(0.15);
|
||||
//@done
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double gnoise, double dx, double dz)
|
||||
{
|
||||
return gnoise;
|
||||
}
|
||||
|
||||
public void genCaves(double vwxxf, double vwzxf, int x, int z, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
PrecisionStopwatch s = PrecisionStopwatch.start();
|
||||
double itr = 2;
|
||||
double level = 8;
|
||||
double incline = 187;
|
||||
double baseWidth = 11;
|
||||
double drop = 41;
|
||||
double wxxf = (scram.noise(vwxxf, vwzxf) * 6) - vwzxf;
|
||||
double wzxf = (scram.noise(vwzxf, vwxxf) * 6) + vwxxf;
|
||||
|
||||
for(double m = 1; m <= itr; m += 0.45)
|
||||
{
|
||||
double w = baseWidth / m;
|
||||
|
||||
if(w < 5)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
int lowest = 325;
|
||||
|
||||
double n = incline * gincline.noise((wxxf + (m * 10000)), (wzxf - (m * 10000)));
|
||||
for(double i = 1; i <= w / 3D; i++)
|
||||
{
|
||||
if(Borders.isBorderWithin((wxxf + (m * 10000)), (wzxf - (m * 10000)), 5, w / 2D / i, (wxxf / 3D) + (wzxf / 3D), (xx, zz) -> g.getIndex(xx, zz)))
|
||||
{
|
||||
int h = (int) ((level + n) - drop);
|
||||
if(dig(x, (int) (h + i), z, data) && h + i < lowest)
|
||||
{
|
||||
lowest = (int) (h + i);
|
||||
}
|
||||
|
||||
if(dig(x, (int) (h - i), z, data) && h - i < lowest)
|
||||
{
|
||||
lowest = (int) (h - i);
|
||||
}
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
if(dig(x, (int) (h), z, data) && h < lowest)
|
||||
{
|
||||
lowest = (int) (h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iris.getMetrics().stop("caves:ms:x256:/chunk:..", s);
|
||||
}
|
||||
|
||||
public boolean dig(int x, int y, int z, AtomicChunkData data)
|
||||
{
|
||||
Material a = data.getType(x, y, z);
|
||||
Material b = data.getType(x, y, z + 1);
|
||||
Material c = data.getType(x, y + 1, z);
|
||||
Material d = data.getType(x + 1, y, z);
|
||||
Material e = data.getType(x, y, z - 1);
|
||||
Material f = data.getType(x, y - 1, z);
|
||||
Material g = data.getType(x - 1, y, z);
|
||||
|
||||
if(can(a) && cann(b) && cann(c) && cann(d) && cann(e) && cann(f) && cann(g))
|
||||
{
|
||||
data.setBlock(x, y, z, Material.AIR);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean cann(Material m)
|
||||
{
|
||||
return m.isSolid() || m.equals(Material.AIR) && !m.equals(Material.BEDROCK);
|
||||
}
|
||||
|
||||
public boolean can(Material m)
|
||||
{
|
||||
return m.isSolid() && !m.equals(Material.BEDROCK);
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerCliffs extends GenLayer
|
||||
{
|
||||
private double block;
|
||||
private CNG gen;
|
||||
private CNG sh;
|
||||
private CNG ch;
|
||||
|
||||
public GenLayerCliffs(IrisGenerator iris, World world, Random random, RNG rng)
|
||||
{
|
||||
//@builder
|
||||
super(iris, world, random, rng);
|
||||
block = 1D / 255D;
|
||||
gen = new CNG(rng.nextParallelRNG(128), 1D, 4).scale(0.02);
|
||||
sh = new CNG(rng.nextParallelRNG(127), 1D, 1).scale(0.00367);
|
||||
ch = new CNG(rng.nextParallelRNG(127), 1D, 1).scale(0.00413);
|
||||
//@done
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double gnoise, double dx, double dz)
|
||||
{
|
||||
return generateLayer(gnoise, dx, dz, 1D, 0.37D);
|
||||
}
|
||||
|
||||
public double generateLayer(double gnoise, double dx, double dz, double cliffs, double chance)
|
||||
{
|
||||
if(gnoise < block * 66)
|
||||
{
|
||||
return gnoise;
|
||||
}
|
||||
|
||||
double shift = 10.25 + (sh.noise(dx, dz) * 2.25) * cliffs;
|
||||
double hits = 183D / shift;
|
||||
double n = gnoise;
|
||||
|
||||
for(int i = (int) hits; i > 0; i--)
|
||||
{
|
||||
if(ch.noise(dx + (i * -1000), dz + (i * 1000)) >= chance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double var = 12.2 * block;
|
||||
double varCombined = 15.45 * block;
|
||||
double sep = (shift / 1.8D) * block;
|
||||
double height = (67 + (i * shift)) * block;
|
||||
double sh = ((gen.noise(dx + dz, dz - dx) - 0.5D) * 2D) * varCombined;
|
||||
double shv = ((gen.noise(dz + dx, dx - dz) - 0.5D) * 2D) * varCombined;
|
||||
double lo = (gen.noise(dx + (i * -1000), dz + (i * 1000)) * var) + height + sh;
|
||||
double hi = (gen.noise(dz + (i * 1000), dx + (i * -1000)) * var) + height + sep + shv;
|
||||
n = n > lo && n < hi ? lo : n;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerLayeredNoise extends GenLayer
|
||||
{
|
||||
private CNG gen;
|
||||
private CNG fract;
|
||||
|
||||
public GenLayerLayeredNoise(IrisGenerator iris, World world, Random random, RNG rng)
|
||||
{
|
||||
//@builder
|
||||
super(iris, world, random, rng);
|
||||
fract = new CNG(rng.nextParallelRNG(16), 1D, 9).scale(0.0181);
|
||||
gen = new CNG(rng.nextParallelRNG(17), 0.19D, 8)
|
||||
.scale(0.012)
|
||||
.amp(0.5)
|
||||
.freq(1.1)
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(18), 1, 5)
|
||||
.scale(0.018)
|
||||
.child(new CNG(rng.nextParallelRNG(19), 0.745, 2)
|
||||
.scale(0.1))
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(20), 1, 3)
|
||||
.scale(0.15), 24), 44);
|
||||
}
|
||||
|
||||
public double getHeight(double x, double z)
|
||||
{
|
||||
return 0.65* gen.noise(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double gnoise, double dx, double dz)
|
||||
{
|
||||
return 0.65 * gen.noise(gnoise, dx + (fract.noise(gnoise, dx, dz) * 333), dz - (fract.noise(dz, dx, gnoise) * 333));
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.Settings.OreSettings;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.iris.util.IrisInterpolation;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerOres extends GenLayer
|
||||
{
|
||||
private CNG ore;
|
||||
|
||||
public GenLayerOres(IrisGenerator iris, World world, Random random, RNG rng)
|
||||
{
|
||||
//@builder
|
||||
super(iris, world, random, rng);
|
||||
ore = new CNG(rng.nextParallelRNG(12944), 1D, 1).scale(0.1);
|
||||
//@done
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double gnoise, double dx, double dz)
|
||||
{
|
||||
return gnoise;
|
||||
}
|
||||
|
||||
public void genOres(double xxf, double zzf, int x, int z, int h, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
PrecisionStopwatch s = PrecisionStopwatch.start();
|
||||
OreSettings o = Iris.settings.ore;
|
||||
|
||||
for(int i = 0; i < h; i++)
|
||||
{
|
||||
if(i >= o.ironMinHeight && i <= o.ironMaxHeight &&
|
||||
ore.noise(xxf + 64, i, zzf - 64) < IrisInterpolation.lerpCenterSinBezier(
|
||||
o.ironMinDispersion,
|
||||
Iris.settings.ore.ironMaxDispersion,
|
||||
M.lerpInverse(o.ironMinHeight, o.ironMaxHeight, i)))
|
||||
{
|
||||
if(!can(data.getType(x, i, z)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
data.setBlock(x, i, z, Material.IRON_ORE);
|
||||
}
|
||||
|
||||
if(i >= o.coalMinHeight && i <= o.coalMaxHeight &&
|
||||
ore.noise(xxf + 128, i, zzf - 128) < IrisInterpolation.lerpCenterSinBezier(
|
||||
o.coalMinDispersion,
|
||||
Iris.settings.ore.coalMaxDispersion,
|
||||
M.lerpInverse(o.coalMinHeight, o.coalMaxHeight, i)))
|
||||
{
|
||||
if(!can(data.getType(x, i, z)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
data.setBlock(x, i, z, Material.COAL_ORE);
|
||||
}
|
||||
|
||||
if(i >= o.goldMinHeight && i <= o.goldMaxHeight &&
|
||||
ore.noise(xxf + 64, i, zzf - 128) < IrisInterpolation.lerpCenterSinBezier(
|
||||
o.goldMinDispersion,
|
||||
Iris.settings.ore.goldMaxDispersion,
|
||||
M.lerpInverse(o.goldMinHeight, o.goldMaxHeight, i)))
|
||||
{
|
||||
if(!can(data.getType(x, i, z)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
data.setBlock(x, i, z, Material.GOLD_ORE);
|
||||
}
|
||||
|
||||
if(i >= o.redstoneMinHeight && i <= o.redstoneMaxHeight &&
|
||||
ore.noise(xxf + 128, i, zzf - 64) < IrisInterpolation.lerpCenterSinBezier(
|
||||
o.redstoneMinDispersion,
|
||||
Iris.settings.ore.redstoneMaxDispersion,
|
||||
M.lerpInverse(o.redstoneMinHeight, o.redstoneMaxHeight, i)))
|
||||
{
|
||||
if(!can(data.getType(x, i, z)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
data.setBlock(x, i, z, Material.REDSTONE_ORE);
|
||||
}
|
||||
|
||||
if(i >= o.lapisMinHeight && i <= o.lapisMaxHeight &&
|
||||
ore.noise(xxf + 256, i, zzf - 64) < IrisInterpolation.lerpCenterSinBezier(
|
||||
o.lapisMinDispersion,
|
||||
Iris.settings.ore.lapisMaxDispersion,
|
||||
M.lerpInverse(o.lapisMinHeight, o.lapisMaxHeight, i)))
|
||||
{
|
||||
if(!can(data.getType(x, i, z)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
data.setBlock(x, i, z, Material.LAPIS_ORE);
|
||||
}
|
||||
|
||||
if(i >= o.diamondMinHeight && i <= o.diamondMaxHeight &&
|
||||
ore.noise(xxf + 64, i, zzf - 256) < IrisInterpolation.lerpCenterSinBezier(
|
||||
o.diamondMinDispersion,
|
||||
Iris.settings.ore.diamondMaxDispersion,
|
||||
M.lerpInverse(o.diamondMinHeight, o.diamondMaxHeight, i)))
|
||||
{
|
||||
if(!can(data.getType(x, i, z)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
data.setBlock(x, i, z, Material.DIAMOND_ORE);
|
||||
}
|
||||
|
||||
if(i >= o.emeraldMinHeight && i <= o.emeraldMaxHeight &&
|
||||
ore.noise(xxf + 128, i, zzf - 256) < IrisInterpolation.lerpCenterSinBezier(
|
||||
o.emeraldMinDispersion,
|
||||
Iris.settings.ore.emeraldMaxDispersion,
|
||||
M.lerpInverse(o.emeraldMinHeight, o.emeraldMaxHeight, i)))
|
||||
{
|
||||
if(!can(data.getType(x, i, z)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
data.setBlock(x, i, z, Material.EMERALD_ORE);
|
||||
}
|
||||
}
|
||||
|
||||
iris.getMetrics().stop("ores:ms:x256:/chunk:..", s);
|
||||
}
|
||||
|
||||
public boolean can(Material m)
|
||||
{
|
||||
return m.equals(Material.STONE) || m.name().endsWith("_ORE");
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerSnow extends GenLayer
|
||||
{
|
||||
private CNG gen;
|
||||
|
||||
public GenLayerSnow(IrisGenerator iris, World world, Random random, RNG rng)
|
||||
{
|
||||
//@builder
|
||||
super(iris, world, random, rng);
|
||||
gen = new CNG(rng.nextParallelRNG(117), 1D, 1)
|
||||
.scale(0.059)
|
||||
.amp(0.5)
|
||||
.freq(1.1)
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(18), 1, 6)
|
||||
.scale(0.018)
|
||||
.child(new CNG(rng.nextParallelRNG(19), 0.745, 2)
|
||||
.scale(0.1))
|
||||
.fractureWith(new CNG(rng.nextParallelRNG(20), 1, 3)
|
||||
.scale(0.15), 24), 44);
|
||||
}
|
||||
|
||||
public double getHeight(double x, double z)
|
||||
{
|
||||
return gen.noise(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double gnoise, double dx, double dz)
|
||||
{
|
||||
return getHeight(dx, dz);
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.parallax;
|
||||
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
|
||||
public class ParallaxAnchor
|
||||
{
|
||||
private final int height;
|
||||
private final int water;
|
||||
private final IrisBiome biome;
|
||||
private final AtomicChunkData data;
|
||||
|
||||
public ParallaxAnchor(int height, int water, IrisBiome biome, AtomicChunkData data)
|
||||
{
|
||||
this.height = height;
|
||||
this.water = water;
|
||||
this.biome = biome;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public AtomicChunkData getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
public int getWater()
|
||||
{
|
||||
return water;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getWaterHeight()
|
||||
{
|
||||
return water;
|
||||
}
|
||||
|
||||
public IrisBiome getBiome()
|
||||
{
|
||||
return biome;
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.parallax;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.pack.IrisBiome;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.iris.util.SMCAVector;
|
||||
import ninja.bytecode.shuriken.collections.KMap;
|
||||
import ninja.bytecode.shuriken.collections.KSet;
|
||||
|
||||
public class ParallaxCache
|
||||
{
|
||||
private KMap<SMCAVector, ChunkPlan> cachePlan;
|
||||
private KMap<SMCAVector, AtomicChunkData> cacheData;
|
||||
private KSet<SMCAVector> contains;
|
||||
private IrisGenerator gen;
|
||||
|
||||
public ParallaxCache(IrisGenerator gen)
|
||||
{
|
||||
this.gen = gen;
|
||||
cacheData = new KMap<>();
|
||||
cachePlan = new KMap<>();
|
||||
contains = new KSet<>();
|
||||
}
|
||||
|
||||
public MB get(int x, int y, int z)
|
||||
{
|
||||
SMCAVector s = new SMCAVector(x, z);
|
||||
SMCAVector c = new SMCAVector(x >> 4, z >> 4);
|
||||
|
||||
if(contains.contains(s) && cacheData.containsKey(c) && cachePlan.containsKey(c) )
|
||||
{
|
||||
return cacheData.get(c).getMB(x & 15, y, z & 15);
|
||||
}
|
||||
|
||||
createData(x, z, s, c);
|
||||
|
||||
return cacheData.get(c).getMB(x & 15, y, z & 15);
|
||||
}
|
||||
|
||||
public IrisBiome getBiome(int x, int z)
|
||||
{
|
||||
SMCAVector s = new SMCAVector(x, z);
|
||||
SMCAVector c = new SMCAVector(x >> 4, z >> 4);
|
||||
|
||||
if(contains.contains(s) && cacheData.containsKey(c) && cachePlan.containsKey(c) )
|
||||
{
|
||||
return cachePlan.get(c).getBiome(x & 15, z & 15);
|
||||
}
|
||||
|
||||
createData(x, z, s, c);
|
||||
|
||||
return cachePlan.get(c).getBiome(x & 15, z & 15);
|
||||
}
|
||||
|
||||
public int getWaterHeight(int x, int z)
|
||||
{
|
||||
SMCAVector s = new SMCAVector(x, z);
|
||||
SMCAVector c = new SMCAVector(x >> 4, z >> 4);
|
||||
|
||||
if(contains.contains(s) && cacheData.containsKey(c) && cachePlan.containsKey(c) )
|
||||
{
|
||||
return cachePlan.get(c).getRealWaterHeight(x & 15, z & 15);
|
||||
}
|
||||
|
||||
createData(x, z, s, c);
|
||||
|
||||
return cachePlan.get(c).getRealWaterHeight(x & 15, z & 15);
|
||||
}
|
||||
|
||||
public int getHeight(int x, int z)
|
||||
{
|
||||
SMCAVector s = new SMCAVector(x, z);
|
||||
SMCAVector c = new SMCAVector(x >> 4, z >> 4);
|
||||
|
||||
if(contains.contains(s) && cacheData.containsKey(c) && cachePlan.containsKey(c) )
|
||||
{
|
||||
return cachePlan.get(c).getRealHeight(x & 15, z & 15);
|
||||
}
|
||||
|
||||
createData(x, z, s, c);
|
||||
|
||||
return cachePlan.get(c).getRealHeight(x & 15, z & 15);
|
||||
}
|
||||
|
||||
private void createData(int x, int z, SMCAVector s, SMCAVector c)
|
||||
{
|
||||
if(!cacheData.containsKey(c))
|
||||
{
|
||||
cacheData.put(c, new AtomicChunkData(gen.getWorld()));
|
||||
}
|
||||
|
||||
if(!cachePlan.containsKey(c))
|
||||
{
|
||||
cachePlan.put(c, new ChunkPlan());
|
||||
}
|
||||
|
||||
gen.computeAnchor(x, z, cachePlan.get(c), cacheData.get(c));
|
||||
contains.add(s);
|
||||
}
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.parallax;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.WorldSaveEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
|
||||
import mortar.api.nms.NMP;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.IrisWorldData;
|
||||
import ninja.bytecode.iris.util.ObjectMode;
|
||||
import ninja.bytecode.iris.util.SChunkVector;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator implements Listener
|
||||
{
|
||||
private World world;
|
||||
private IrisWorldData data;
|
||||
private RNG rMaster;
|
||||
private AtomicChunkData buffer;
|
||||
protected boolean saving;
|
||||
|
||||
@Override
|
||||
public final void init(World world, Random random)
|
||||
{
|
||||
this.world = world;
|
||||
saving = true;
|
||||
buffer = new AtomicChunkData(world);
|
||||
this.data = new IrisWorldData(world);
|
||||
this.rMaster = new RNG(world.getSeed() + 1);
|
||||
onInit(world, rMaster.nextParallelRNG(1));
|
||||
Bukkit.getPluginManager().registerEvents(this, Iris.instance);
|
||||
}
|
||||
|
||||
public void disableSaving()
|
||||
{
|
||||
saving = false;
|
||||
data.disableSaving();
|
||||
}
|
||||
|
||||
public void enableSaving()
|
||||
{
|
||||
saving = true;
|
||||
data.enableSaving();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(ChunkLoadEvent e)
|
||||
{
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX) && e.getWorld().equals(world))
|
||||
{
|
||||
NMP.host.relight(e.getChunk());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(WorldUnloadEvent e)
|
||||
{
|
||||
if(e.getWorld().equals(world))
|
||||
{
|
||||
getWorldData().dispose();
|
||||
onUnload();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(WorldSaveEvent e)
|
||||
{
|
||||
if(!saving)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(e.getWorld().equals(world))
|
||||
{
|
||||
getWorldData().saveAll();
|
||||
}
|
||||
}
|
||||
|
||||
public ParallaxAnchor computeAnchor(int wx, int wz, ChunkPlan heightBuffer, AtomicChunkData data)
|
||||
{
|
||||
onGenColumn(wx, wz, wx & 15, wz & 15, heightBuffer, data, false);
|
||||
|
||||
return new ParallaxAnchor(heightBuffer.getRealHeight(wx & 15, wz & 15), heightBuffer.getRealWaterHeight(wx & 15, wz & 15), heightBuffer.getBiome(wx & 15, wz & 15), data);
|
||||
}
|
||||
|
||||
public ParallaxAnchor computeAnchor(int wx, int wz)
|
||||
{
|
||||
ChunkPlan heightBuffer = new ChunkPlan();
|
||||
onGenColumn(wx, wz, wx & 15, wz & 15, heightBuffer, buffer, false);
|
||||
|
||||
return new ParallaxAnchor(heightBuffer.getRealHeight(wx & 15, wz & 15), heightBuffer.getRealWaterHeight(wx & 15, wz & 15), heightBuffer.getBiome(wx & 15, wz & 15), buffer);
|
||||
}
|
||||
|
||||
public void doGenParallax(int x, int z)
|
||||
{
|
||||
onGenParallax(x, z, getRMaster(x, z, -59328));
|
||||
getWorldData().getChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ChunkPlan initChunk(World world, int x, int z, Random random)
|
||||
{
|
||||
PrecisionStopwatch ps = PrecisionStopwatch.start();
|
||||
TaskGroup g = startWork();
|
||||
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX))
|
||||
{
|
||||
for(int ii = -(getParallaxSize().getX() / 2) - 1; ii < (((getParallaxSize().getX() / 2) + 1)); ii++)
|
||||
{
|
||||
int i = ii;
|
||||
|
||||
for(int jj = -(getParallaxSize().getZ() / 2) - 1; jj < (((getParallaxSize().getZ() / 2) + 1)); jj++)
|
||||
{
|
||||
int j = jj;
|
||||
int cx = x + i;
|
||||
int cz = z + j;
|
||||
|
||||
if(!getWorldData().exists(cx, cz))
|
||||
{
|
||||
g.queue(() ->
|
||||
{
|
||||
onGenParallax(cx, cz, getRMaster(cx, cz, -59328));
|
||||
getWorldData().getChunk(cx, cz);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g.execute();
|
||||
}
|
||||
|
||||
((IrisGenerator) this).getMetrics().put("parallax:ms:/chunk", ps.getMillis());
|
||||
|
||||
return onInitChunk(world, x, z, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void postChunk(World world, int x, int z, Random random, AtomicChunkData data, ChunkPlan plan)
|
||||
{
|
||||
onPostChunk(world, x, z, random, data, plan);
|
||||
getWorldData().inject(x, z, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Biome genColumn(int wx, int wz, int x, int z, ChunkPlan plan, AtomicChunkData data, boolean surface)
|
||||
{
|
||||
return onGenColumn(wx, wz, x, z, plan, data, surface);
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
return world;
|
||||
}
|
||||
|
||||
public IrisWorldData getWorldData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
public RNG getRMaster()
|
||||
{
|
||||
return rMaster;
|
||||
}
|
||||
|
||||
public RNG getRMaster(int x, int z, int signature)
|
||||
{
|
||||
return rMaster.nextParallelRNG((int) (signature + x * z + z + x * 2.12));
|
||||
}
|
||||
|
||||
protected abstract void onUnload();
|
||||
|
||||
protected abstract SChunkVector getParallaxSize();
|
||||
|
||||
public abstract void onGenParallax(int x, int z, Random random);
|
||||
|
||||
public abstract void onInit(World world, Random random);
|
||||
|
||||
public abstract ChunkPlan onInitChunk(World world, int x, int z, Random random);
|
||||
|
||||
public abstract Biome onGenColumn(int wx, int wz, int x, int z, ChunkPlan plan, AtomicChunkData data, boolean surfaceOnly);
|
||||
|
||||
public abstract void onPostChunk(World world, int x, int z, Random random, AtomicChunkData data, ChunkPlan plan);
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.parallax;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
import mortar.util.text.C;
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.ChunkSpliceListener;
|
||||
import ninja.bytecode.shuriken.execution.TaskExecutor;
|
||||
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
|
||||
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskResult;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.RollingSequence;
|
||||
import ninja.bytecode.shuriken.reaction.O;
|
||||
|
||||
public abstract class ParallelChunkGenerator extends ChunkGenerator
|
||||
{
|
||||
private int i;
|
||||
private int j;
|
||||
private int wx;
|
||||
private int wz;
|
||||
private TaskExecutor backupService;
|
||||
private TaskGroup tg;
|
||||
private boolean ready = false;
|
||||
int cg = 0;
|
||||
private RollingSequence rs = new RollingSequence(512);
|
||||
private World world;
|
||||
private ChunkSpliceListener splicer;
|
||||
|
||||
public void setSplicer(ChunkSpliceListener splicer)
|
||||
{
|
||||
this.splicer = splicer;
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
return world;
|
||||
}
|
||||
|
||||
public Biome generateFullColumn(int a, int b, int c, int d, ChunkPlan p, AtomicChunkData data)
|
||||
{
|
||||
return genColumn(a, b, c, d, p, data, false);
|
||||
}
|
||||
|
||||
private TaskGroup work(String n)
|
||||
{
|
||||
if(Iris.instance == null || Iris.exec() == null)
|
||||
{
|
||||
if(backupService == null)
|
||||
{
|
||||
L.f(C.RED + "Cannot contact ExecutionController!" + C.YELLOW + " Did you reload iris?");
|
||||
L.w(C.YELLOW + "Spinning up a temporary backup service until the issue resolves...");
|
||||
backupService = new TaskExecutor(4, Thread.MAX_PRIORITY, "Iris Backup Handover");
|
||||
Iris.instance.reload();
|
||||
}
|
||||
|
||||
return backupService.startWork();
|
||||
}
|
||||
|
||||
else if(backupService != null)
|
||||
{
|
||||
L.i(C.GREEN + "Reconnected to the execution service. Closing backup service now...");
|
||||
backupService.close();
|
||||
}
|
||||
|
||||
return Iris.exec().getExecutor(world, n).startWork();
|
||||
}
|
||||
|
||||
public TaskGroup startParallaxWork()
|
||||
{
|
||||
return work("Parallax");
|
||||
}
|
||||
|
||||
public TaskGroup startWork()
|
||||
{
|
||||
return work("Generator");
|
||||
}
|
||||
|
||||
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
|
||||
{
|
||||
random = new Random(world.getSeed());
|
||||
if(splicer != null)
|
||||
{
|
||||
AtomicChunkData d = splicer.onSpliceAvailable(world, random, x, z, biome);
|
||||
|
||||
if(d != null)
|
||||
{
|
||||
return d.toChunkData();
|
||||
}
|
||||
}
|
||||
|
||||
AtomicChunkData data = new AtomicChunkData(world);
|
||||
|
||||
try
|
||||
{
|
||||
this.world = world;
|
||||
|
||||
if(!ready)
|
||||
{
|
||||
init(world, random);
|
||||
ready = true;
|
||||
}
|
||||
|
||||
tg = startWork();
|
||||
O<ChunkPlan> plan = new O<ChunkPlan>();
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
wx = (x << 4) + i;
|
||||
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
wz = (z << 4) + j;
|
||||
int a = wx;
|
||||
int b = wz;
|
||||
int c = i;
|
||||
int d = j;
|
||||
tg.queue(() ->
|
||||
{
|
||||
Biome f = generateFullColumn(a, b, c, d, plan.get(), data);
|
||||
biome.setBiome(c, d, f);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
plan.set(initChunk(world, x, z, random));
|
||||
TaskResult r = tg.execute();
|
||||
onDecorateChunk(world, x, z, data, plan.get());
|
||||
TaskGroup gd = startWork();
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
wx = (x << 4) + i;
|
||||
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
wz = (z << 4) + j;
|
||||
int a = wx;
|
||||
int b = wz;
|
||||
int c = i;
|
||||
int d = j;
|
||||
gd.queue(() -> onDecorateColumn(world, c, d, a, b, data, plan.get()));
|
||||
}
|
||||
}
|
||||
|
||||
gd.execute();
|
||||
postChunk(world, x, z, random, data, plan.get());
|
||||
rs.put(r.timeElapsed);
|
||||
cg++;
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
try
|
||||
{
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
for(int j = 0; j < 16; j++)
|
||||
{
|
||||
data.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable ex)
|
||||
{
|
||||
|
||||
}
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return data.toChunkData();
|
||||
}
|
||||
|
||||
protected abstract void onDecorateColumn(World world2, int i2, int j2, int wx2, int wz2, AtomicChunkData data, ChunkPlan chunkPlan);
|
||||
|
||||
protected abstract void onDecorateChunk(World world2, int x, int z, AtomicChunkData data, ChunkPlan chunkPlan);
|
||||
|
||||
public abstract void init(World world, Random random);
|
||||
|
||||
public abstract ChunkPlan initChunk(World world, int x, int z, Random random);
|
||||
|
||||
public abstract void postChunk(World world, int x, int z, Random random, AtomicChunkData data, ChunkPlan plan);
|
||||
|
||||
public abstract Biome genColumn(int wx, int wz, int x, int z, ChunkPlan plan, AtomicChunkData data, boolean surfaceOnly);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.placer;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.generator.parallax.ParallaxCache;
|
||||
import ninja.bytecode.iris.util.IrisWorldData;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.iris.util.Placer;
|
||||
|
||||
public class AtomicParallaxPlacer extends Placer
|
||||
{
|
||||
private IrisWorldData data;
|
||||
private ParallaxCache cache;
|
||||
|
||||
public AtomicParallaxPlacer(IrisGenerator g, ParallaxCache cache)
|
||||
{
|
||||
super(g.getWorld());
|
||||
this.data = g.getWorldData();
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MB get(Location l)
|
||||
{
|
||||
return cache.get(l.getBlockX(), l.getBlockY(), l.getBlockZ());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void set(Location l, MB mb)
|
||||
{
|
||||
data.setBlock(l.getBlockX(), l.getBlockY(), l.getBlockZ(), mb.material.getId(), mb.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestY(Location l)
|
||||
{
|
||||
return cache.getHeight(l.getBlockX(), l.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestYUnderwater(Location l)
|
||||
{
|
||||
return cache.getWaterHeight(l.getBlockX(), l.getBlockZ());
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.placer;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.iris.util.Placer;
|
||||
|
||||
public class BukkitPlacer extends Placer
|
||||
{
|
||||
private final boolean applyPhysics;
|
||||
|
||||
public BukkitPlacer(World world, boolean applyPhysics)
|
||||
{
|
||||
super(world);
|
||||
this.applyPhysics = applyPhysics;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public MB get(Location l)
|
||||
{
|
||||
Block b = world.getBlockAt(l);
|
||||
return MB.of(b.getType(), b.getData());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void set(Location l, MB mb)
|
||||
{
|
||||
l.getBlock().setTypeIdAndData(mb.material.getId(), mb.data, applyPhysics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestYUnderwater(Location l)
|
||||
{
|
||||
int y = getHighestY(l);
|
||||
|
||||
while(y > 0)
|
||||
{
|
||||
y--;
|
||||
Block b = l.getWorld().getBlockAt(l.getBlockX(), y, l.getBlockZ());
|
||||
if(!b.isEmpty())
|
||||
{
|
||||
if(b.isLiquid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return y + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestY(Location l)
|
||||
{
|
||||
return world.getHighestBlockYAt(l);
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.placer;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mortar.api.nms.Catalyst;
|
||||
import mortar.api.nms.NMP;
|
||||
import mortar.api.world.MaterialBlock;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.iris.util.Placer;
|
||||
import ninja.bytecode.shuriken.collections.KSet;
|
||||
import ninja.bytecode.shuriken.execution.J;
|
||||
|
||||
public class NMSPlacer extends Placer
|
||||
{
|
||||
private KSet<Chunk> c;
|
||||
|
||||
public NMSPlacer(World world)
|
||||
{
|
||||
super(world);
|
||||
c = new KSet<>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public MB get(Location l)
|
||||
{
|
||||
Block b = world.getBlockAt(l);
|
||||
return MB.of(b.getType(), b.getData());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void set(Location l, MB mb)
|
||||
{
|
||||
Catalyst.host.setBlock(l, new MaterialBlock(mb.material.getId(), mb.data));
|
||||
c.add(l.getChunk());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestY(Location l)
|
||||
{
|
||||
return world.getHighestBlockYAt(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestYUnderwater(Location l)
|
||||
{
|
||||
int y = getHighestY(l);
|
||||
|
||||
while(y > 0)
|
||||
{
|
||||
y--;
|
||||
Block b = l.getWorld().getBlockAt(l.getBlockX(), y, l.getBlockZ());
|
||||
if(!b.isEmpty())
|
||||
{
|
||||
if(b.isLiquid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return y + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
public void flush()
|
||||
{
|
||||
J.attempt(() ->
|
||||
{
|
||||
for(Chunk i : c)
|
||||
{
|
||||
NMP.host.relight(i);
|
||||
|
||||
J.a(() ->
|
||||
{
|
||||
for(Player j : i.getWorld().getPlayers())
|
||||
{
|
||||
NMP.CHUNK.refreshIgnorePosition(j, i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
c.clear();
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user