This commit is contained in:
Daniel Mills
2020-03-16 11:55:17 -04:00
parent ba9cb41d47
commit 59f29eb6b4
144 changed files with 1335 additions and 19970 deletions

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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");
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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();
});
}
}