This commit is contained in:
Daniel Mills 2020-07-26 18:02:49 -04:00
parent 279fcad10a
commit a28c08be99
20 changed files with 326 additions and 100 deletions

View File

@ -120,8 +120,7 @@ public class Iris extends JavaPlugin implements BoardProvider
lines.add(ChatColor.GREEN + "Generators" + ChatColor.GRAY + ": " + Form.f(CNG.creates)); lines.add(ChatColor.GREEN + "Generators" + ChatColor.GRAY + ": " + Form.f(CNG.creates));
lines.add(ChatColor.GREEN + "Noise" + ChatColor.GRAY + ": " + Form.f((int) hits.getAverage())); lines.add(ChatColor.GREEN + "Noise" + ChatColor.GRAY + ": " + Form.f((int) hits.getAverage()));
lines.add(ChatColor.GREEN + "Parallax Chunks" + ChatColor.GRAY + ": " + Form.f((int) g.getParallaxMap().getLoadedChunks().size())); lines.add(ChatColor.GREEN + "Parallax Chunks" + ChatColor.GRAY + ": " + Form.f((int) g.getParallaxMap().getLoadedChunks().size()));
lines.add(ChatColor.GREEN + "Objects" + ChatColor.GRAY + ": " + Form.f(Iris.data.getObjectLoader().count())); lines.add(ChatColor.GREEN + "Objects" + ChatColor.GRAY + ": " + Form.f(Iris.data.getObjectLoader().count()) + " (~" + Form.memSize(752 * Iris.data.getObjectLoader().getTotalStorage(), 0) + ")");
lines.add(ChatColor.GREEN + "Objects Nodes" + ChatColor.GRAY + ": " + Form.f(Iris.data.getObjectLoader().getTotalStorage()));
lines.add(ChatColor.GREEN + "Biomes" + ChatColor.GRAY + ": " + Form.f(Iris.data.getBiomeLoader().count())); lines.add(ChatColor.GREEN + "Biomes" + ChatColor.GRAY + ": " + Form.f(Iris.data.getBiomeLoader().count()));
lines.add(ChatColor.GREEN + "Regions" + ChatColor.GRAY + ": " + Form.f(Iris.data.getRegionLoader().count())); lines.add(ChatColor.GREEN + "Regions" + ChatColor.GRAY + ": " + Form.f(Iris.data.getRegionLoader().count()));
lines.add(ChatColor.GREEN + "Height" + ChatColor.GRAY + ": " + (int) g.getTerrainHeight(x, z) + " (" + (int) g.getTerrainWaterHeight(x, z) + ")"); lines.add(ChatColor.GREEN + "Height" + ChatColor.GRAY + ": " + (int) g.getTerrainHeight(x, z) + " (" + (int) g.getTerrainWaterHeight(x, z) + ")");
@ -627,7 +626,9 @@ public class Iris extends JavaPlugin implements BoardProvider
imsg(i, "Creating Iris " + dimm + "..."); imsg(i, "Creating Iris " + dimm + "...");
} }
IrisChunkGenerator gx = new IrisChunkGenerator(dimm, 16); int tc = Math.max(Runtime.getRuntime().availableProcessors(), 4);
IrisChunkGenerator gx = new IrisChunkGenerator(dimm, tc);
info("Generating with " + tc + " threads per chunk");
O<Boolean> done = new O<Boolean>(); O<Boolean> done = new O<Boolean>();
done.set(false); done.set(false);

View File

@ -174,7 +174,6 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
loadQueue.addAll(r.getLandBiomes()); loadQueue.addAll(r.getLandBiomes());
loadQueue.addAll(r.getSeaBiomes()); loadQueue.addAll(r.getSeaBiomes());
loadQueue.addAll(r.getShoreBiomes()); loadQueue.addAll(r.getShoreBiomes());
loadQueue.addAll(r.getCaveBiomes());
loadQueue.addAll(r.getRidgeBiomeKeys()); loadQueue.addAll(r.getRidgeBiomeKeys());
loadQueue.addAll(r.getSpotBiomeKeys()); loadQueue.addAll(r.getSpotBiomeKeys());
} }
@ -248,14 +247,4 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
return res; return res;
} }
public BiomeResult sampleCaveBiome(int x, int y, int z)
{
double wx = getModifiedX(x - y, z + y);
double wz = getModifiedZ(x + y, z - y);
IrisRegion region = glBiome.getRegion(wx, wz);
BiomeResult res = glBiome.generateCaveData(wx, wz, x, z, region);
return res;
}
} }

View File

@ -8,7 +8,7 @@ import ninja.bytecode.iris.object.IrisDimension;
import ninja.bytecode.iris.util.InvertedBiomeGrid; import ninja.bytecode.iris.util.InvertedBiomeGrid;
import ninja.bytecode.iris.util.RNG; import ninja.bytecode.iris.util.RNG;
public abstract class CeilingChunkGenerator extends ParallaxChunkGenerator public abstract class CeilingChunkGenerator extends PostBlockChunkGenerator
{ {
protected boolean generatingCeiling = false; protected boolean generatingCeiling = false;
protected boolean ceilingCached = false; protected boolean ceilingCached = false;

View File

@ -42,6 +42,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
protected boolean initialized; protected boolean initialized;
protected RNG masterRandom; protected RNG masterRandom;
protected ChronoLatch perSecond; protected ChronoLatch perSecond;
protected ChronoLatch tickLatch;
protected ChronoLatch pushLatch; protected ChronoLatch pushLatch;
protected IrisMetrics metrics; protected IrisMetrics metrics;
protected World world; protected World world;
@ -52,6 +53,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
public ContextualChunkGenerator() public ContextualChunkGenerator()
{ {
pushLatch = new ChronoLatch(3000); pushLatch = new ChronoLatch(3000);
tickLatch = new ChronoLatch(650);
perSecond = new ChronoLatch(1000); perSecond = new ChronoLatch(1000);
CNG.creates = 0; CNG.creates = 0;
generated = 0; generated = 0;
@ -120,11 +122,13 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
{ {
if(e.getFrom().getWorld().equals(world) && !e.getTo().getWorld().equals(world)) if(e.getFrom().getWorld().equals(world) && !e.getTo().getWorld().equals(world))
{ {
tick();
onPlayerLeft(e.getPlayer()); onPlayerLeft(e.getPlayer());
} }
if(!e.getFrom().getWorld().equals(world) && e.getTo().getWorld().equals(world)) if(!e.getFrom().getWorld().equals(world) && e.getTo().getWorld().equals(world))
{ {
tick();
onPlayerJoin(e.getPlayer()); onPlayerJoin(e.getPlayer());
} }
} }
@ -134,6 +138,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
{ {
if(e.getPlayer().getWorld().equals(world)) if(e.getPlayer().getWorld().equals(world))
{ {
tick();
onPlayerLeft(e.getPlayer()); onPlayerLeft(e.getPlayer());
} }
} }
@ -143,6 +148,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
{ {
if(e.getPlayer().getWorld().equals(world)) if(e.getPlayer().getWorld().equals(world))
{ {
tick();
onPlayerJoin(e.getPlayer()); onPlayerJoin(e.getPlayer());
} }
} }
@ -152,6 +158,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
{ {
if(e.getWorld().equals(world)) if(e.getWorld().equals(world))
{ {
tick();
onChunkLoaded(e.getChunk()); onChunkLoaded(e.getChunk());
} }
} }
@ -161,6 +168,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
{ {
if(e.getWorld().equals(world)) if(e.getWorld().equals(world))
{ {
tick();
onChunkUnloaded(e.getChunk()); onChunkUnloaded(e.getChunk());
} }
} }

View File

@ -1,5 +1,8 @@
package ninja.bytecode.iris.generator; package ninja.bytecode.iris.generator;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
@ -14,6 +17,8 @@ import ninja.bytecode.iris.util.BiomeResult;
public abstract class DimensionChunkGenerator extends ContextualChunkGenerator public abstract class DimensionChunkGenerator extends ContextualChunkGenerator
{ {
protected final String dimensionName; protected final String dimensionName;
protected static final BlockData AIR = Material.AIR.createBlockData();
protected static final BlockData BEDROCK = Material.BEDROCK.createBlockData();
public DimensionChunkGenerator(String dimensionName) public DimensionChunkGenerator(String dimensionName)
{ {

View File

@ -44,7 +44,7 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
@Override @Override
protected void onTick(int ticks) protected void onTick(int ticks)
{ {
super.onTick(ticks);
} }
@Override @Override

View File

@ -161,7 +161,6 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
getParallaxChunk(x, z).inject(data); getParallaxChunk(x, z).inject(data);
setSliverBuffer(getSliverCache().size()); setSliverBuffer(getSliverCache().size());
getParallaxChunk(x, z).setWorldGenerated(true); getParallaxChunk(x, z).setWorldGenerated(true);
getParallaxMap().clean(x + z);
getSliverCache().clear(); getSliverCache().clear();
getMasterLock().clear(); getMasterLock().clear();
} }
@ -225,7 +224,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
continue; continue;
} }
getTx().queue(key, () -> getAccelerant().queue(key, () ->
{ {
IrisBiome b = sampleTrueBiome((i * 16) + 7, (j * 16) + 7).getBiome(); IrisBiome b = sampleTrueBiome((i * 16) + 7, (j * 16) + 7).getBiome();
IrisRegion r = sampleRegion((i * 16) + 7, (j * 16) + 7); IrisRegion r = sampleRegion((i * 16) + 7, (j * 16) + 7);
@ -267,7 +266,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
} }
} }
getTx().waitFor(key); getAccelerant().waitFor(key);
} }
public void placeObject(IrisObjectPlacement o, int x, int z, RNG rng) public void placeObject(IrisObjectPlacement o, int x, int z, RNG rng)
@ -279,6 +278,13 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
} }
} }
@Override
protected void onTick(int ticks)
{
getParallaxMap().clean(ticks);
Iris.data.getObjectLoader().clean();
}
public AtomicSliver sampleSliver(int x, int z) public AtomicSliver sampleSliver(int x, int z)
{ {
ChunkPosition key = new ChunkPosition(x, z); ChunkPosition key = new ChunkPosition(x, z);

View File

@ -16,7 +16,7 @@ import ninja.bytecode.iris.util.RNG;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public abstract class ParallelChunkGenerator extends BiomeChunkGenerator public abstract class ParallelChunkGenerator extends BiomeChunkGenerator
{ {
private GroupedExecutor tx; private GroupedExecutor accelerant;
private int threads; private int threads;
public ParallelChunkGenerator(String dimensionName, int threads) public ParallelChunkGenerator(String dimensionName, int threads)
@ -28,9 +28,9 @@ public abstract class ParallelChunkGenerator extends BiomeChunkGenerator
public void changeThreadCount(int tc) public void changeThreadCount(int tc)
{ {
threads = tc; threads = tc;
GroupedExecutor e = tx; GroupedExecutor e = accelerant;
tx = new GroupedExecutor(threads, Thread.NORM_PRIORITY, "Iris Generator - " + world.getName()); accelerant = new GroupedExecutor(threads, Thread.NORM_PRIORITY, "Iris Generator - " + world.getName());
Iris.executors.add(tx); Iris.executors.add(accelerant);
if(e != null) if(e != null)
{ {
@ -68,21 +68,21 @@ public abstract class ParallelChunkGenerator extends BiomeChunkGenerator
int wz = (z * 16) + j; int wz = (z * 16) + j;
AtomicSliver sliver = map.getSliver(i, j); AtomicSliver sliver = map.getSliver(i, j);
tx.queue(key, () -> accelerant.queue(key, () ->
{ {
onGenerateColumn(x, z, wx, wz, i, j, sliver, biomeMap); onGenerateColumn(x, z, wx, wz, i, j, sliver, biomeMap);
}); });
} }
} }
tx.waitFor(key); accelerant.waitFor(key);
map.write(data, grid, height); map.write(data, grid, height);
onPostGenerate(random, x, z, data, grid, height, biomeMap); onPostGenerate(random, x, z, data, grid, height, biomeMap);
} }
protected void onClose() protected void onClose()
{ {
tx.close(); accelerant.close();
} }
public void onInit(World world, RNG rng) public void onInit(World world, RNG rng)

View File

@ -0,0 +1,117 @@
package ninja.bytecode.iris.generator;
import java.util.concurrent.locks.ReentrantLock;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.layer.post.PostNippleSmoother;
import ninja.bytecode.iris.layer.post.PostPotholeFiller;
import ninja.bytecode.iris.object.IrisDimension;
import ninja.bytecode.iris.util.IPostBlockAccess;
import ninja.bytecode.iris.util.IrisPostBlockFilter;
import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList;
public abstract class PostBlockChunkGenerator extends ParallaxChunkGenerator implements IPostBlockAccess
{
protected boolean generatingCeiling = false;
protected boolean ceilingCached = false;
protected IrisDimension cacheCeiling = null;
protected IrisDimension cacheFloor = null;
private int currentPostX;
private int currentPostZ;
private ChunkData currentData;
private KList<IrisPostBlockFilter> filters;
private String postKey;
private ReentrantLock lock;
public PostBlockChunkGenerator(String dimensionName, int threads)
{
super(dimensionName, threads);
filters = new KList<>();
postKey = "post-" + dimensionName;
lock = new ReentrantLock();
}
public void onInit(World world, RNG rng)
{
super.onInit(world, rng);
filters.add(new PostNippleSmoother(this));
filters.add(new PostPotholeFiller(this));
}
@Override
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid)
{
super.onGenerate(random, x, z, data, grid);
currentData = data;
currentPostX = x;
currentPostZ = z;
int rx, i, j;
for(i = 0; i < 16; i++)
{
rx = (x * 16) + i;
for(j = 0; j < 16; j++)
{
int rxx = rx;
int rzz = (z * 16) + j;
getAccelerant().queue(postKey, () ->
{
for(IrisPostBlockFilter f : filters)
{
f.onPost(rxx, rzz);
}
});
}
}
getAccelerant().waitFor(postKey);
}
@Override
public BlockData getPostBlock(int x, int y, int z)
{
if(x >> 4 == currentPostX && z >> 4 == currentPostZ)
{
lock.lock();
BlockData d = currentData.getBlockData(x & 15, y, z & 15);
lock.unlock();
return d == null ? AIR : d;
}
return sampleSliver(x, z).get(y);
}
@Override
public void setPostBlock(int x, int y, int z, BlockData d)
{
if(x >> 4 == currentPostX && z >> 4 == currentPostZ)
{
lock.lock();
currentData.setBlock(x & 15, y, z & 15, d);
lock.unlock();
}
else
{
Iris.warn("Post Block Overdraw: " + currentPostX + "," + currentPostZ + " into " + (x >> 4) + ", " + (z >> 4));
}
}
@Override
public int highestTerrainOrFluidBlock(int x, int z)
{
return getHighest(x, z, false);
}
@Override
public int highestTerrainBlock(int x, int z)
{
return getHighest(x, z, true);
}
}

View File

@ -10,13 +10,13 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import ninja.bytecode.iris.layer.GenLayerCave; import ninja.bytecode.iris.layer.GenLayerCave;
import ninja.bytecode.iris.object.DecorationPart; import ninja.bytecode.iris.object.DecorationPart;
import ninja.bytecode.iris.object.InferredType;
import ninja.bytecode.iris.object.IrisBiome; import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.iris.object.IrisBiomeDecorator; import ninja.bytecode.iris.object.IrisBiomeDecorator;
import ninja.bytecode.iris.object.IrisRegion; import ninja.bytecode.iris.object.IrisRegion;
import ninja.bytecode.iris.object.atomics.AtomicSliver; import ninja.bytecode.iris.object.atomics.AtomicSliver;
import ninja.bytecode.iris.util.BiomeMap; import ninja.bytecode.iris.util.BiomeMap;
import ninja.bytecode.iris.util.BiomeResult; import ninja.bytecode.iris.util.BiomeResult;
import ninja.bytecode.iris.util.CaveResult;
import ninja.bytecode.iris.util.HeightMap; import ninja.bytecode.iris.util.HeightMap;
import ninja.bytecode.iris.util.RNG; import ninja.bytecode.iris.util.RNG;
import ninja.bytecode.shuriken.collections.KList; import ninja.bytecode.shuriken.collections.KList;
@ -26,8 +26,6 @@ import ninja.bytecode.shuriken.math.M;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public abstract class TerrainChunkGenerator extends ParallelChunkGenerator public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
{ {
protected static final BlockData AIR = Material.AIR.createBlockData();
protected static final BlockData WEB = Material.COBWEB.createBlockData();
private long lastUpdateRequest = M.ms(); private long lastUpdateRequest = M.ms();
private long lastChunkLoad = M.ms(); private long lastChunkLoad = M.ms();
private GenLayerCave glCave; private GenLayerCave glCave;
@ -77,6 +75,12 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
for(int k = Math.max(height, fluidHeight); k >= 0; k--) for(int k = Math.max(height, fluidHeight); k >= 0; k--)
{ {
if(k == 0)
{
sliver.set(0, BEDROCK);
continue;
}
boolean underwater = k > height && k <= fluidHeight; boolean underwater = k > height && k <= fluidHeight;
if(biomeMap != null) if(biomeMap != null)
@ -109,47 +113,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
} }
} }
KList<CaveResult> r = glCave.genCaves(rx, rz, x, z, sliver); glCave.genCaves(rx, rz, x, z, sliver);
for(CaveResult c : r)
{
if(c.getCeiling() <= 0 || c.getFloor() >= 255 || c.getFloor() >= c.getCeiling())
{
continue;
}
IrisBiome caveBiome = sampleCaveBiome(x, 0, z).getBiome();
if(caveBiome.getLoadKey().equals("default"))
{
continue;
}
KList<BlockData> ceilingLayers = caveBiome.generateLayers(wx + c.getCeiling(), wz + c.getCeiling(), masterRandom, (height - c.getCeiling()) - 1);
KList<BlockData> floorLayers = caveBiome.generateLayers(wx - c.getFloor(), wz - c.getFloor(), masterRandom, c.getFloor());
for(int k = c.getFloor(); k <= c.getCeiling(); k++)
{
if(k >= height || k < 0 || k > 255)
{
continue;
}
sliver.set(k, caveBiome.getGroundBiome(masterRandom, rx, k, rz));
}
for(int k = 0; k < ceilingLayers.size(); k++)
{
sliver.set(k + c.getCeiling(), caveBiome.getGroundBiome(masterRandom, rx, k, rz));
sliver.set(k + c.getCeiling(), ceilingLayers.get(k));
}
for(int k = 0; k < floorLayers.size(); k++)
{
sliver.set(c.getFloor() - k, caveBiome.getGroundBiome(masterRandom, rx, k, rz));
sliver.set(c.getFloor() - k, floorLayers.get(k));
}
}
} }
catch(Throwable e) catch(Throwable e)
@ -230,6 +194,11 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
for(IrisBiomeDecorator i : biome.getDecorators()) for(IrisBiomeDecorator i : biome.getDecorators())
{ {
if(biome.getInferredType().equals(InferredType.SHORE))
{
continue;
}
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(biome.hashCode() + j++), wx, wz); BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(biome.hashCode() + j++), wx, wz);
if(d != null) if(d != null)

View File

@ -20,9 +20,7 @@ public class GenLayerBiome extends GenLayer
private CellGenerator land; private CellGenerator land;
private CellGenerator shore; private CellGenerator shore;
private CellGenerator sea; private CellGenerator sea;
private CellGenerator cave;
private DimensionChunkGenerator iris; private DimensionChunkGenerator iris;
private IrisBiome defaultCave;
public GenLayerBiome(DimensionChunkGenerator iris, RNG rng) public GenLayerBiome(DimensionChunkGenerator iris, RNG rng)
{ {
@ -33,10 +31,6 @@ public class GenLayerBiome extends GenLayer
land = new CellGenerator(rng.nextParallelRNG(9045162)); land = new CellGenerator(rng.nextParallelRNG(9045162));
shore = new CellGenerator(rng.nextParallelRNG(2342812)); shore = new CellGenerator(rng.nextParallelRNG(2342812));
sea = new CellGenerator(rng.nextParallelRNG(6135621)); sea = new CellGenerator(rng.nextParallelRNG(6135621));
cave = new CellGenerator(rng.nextParallelRNG(9985621));
defaultCave = new IrisBiome();
defaultCave.getLayers().clear();
defaultCave.setLoadKey("default");
} }
public IrisRegion getRegion(double bx, double bz) public IrisRegion getRegion(double bx, double bz)
@ -144,18 +138,6 @@ public class GenLayerBiome extends GenLayer
return generateImpureData(rawX, rawZ, InferredType.SHORE, regionData, generatePureShoreData(bx, bz, rawX, rawZ, regionData)); return generateImpureData(rawX, rawZ, InferredType.SHORE, regionData, generatePureShoreData(bx, bz, rawX, rawZ, regionData));
} }
public BiomeResult generateCaveData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
if(regionData.getCaveBiomes().isEmpty())
{
return new BiomeResult(defaultCave, 0);
}
cave.setShuffle(12);
cave.setCellScale(0.6 / iris.getDimension().getCaveBiomeZoom());
return generateBiomeData(bx, bz, regionData, cave, regionData.getCaveBiomes(), InferredType.CAVE);
}
public BiomeResult implode(double bx, double bz, IrisRegion regionData, CellGenerator parentCell, BiomeResult parent) public BiomeResult implode(double bx, double bz, IrisRegion regionData, CellGenerator parentCell, BiomeResult parent)
{ {
return implode(bx, bz, regionData, parentCell, parent, 1); return implode(bx, bz, regionData, parentCell, parent, 1);

View File

@ -0,0 +1,37 @@
package ninja.bytecode.iris.layer.post;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import ninja.bytecode.iris.generator.PostBlockChunkGenerator;
import ninja.bytecode.iris.util.IrisPostBlockFilter;
public class PostNippleSmoother extends IrisPostBlockFilter
{
public PostNippleSmoother(PostBlockChunkGenerator gen)
{
super(gen);
}
@Override
public void onPost(int x, int z)
{
int h = highestTerrainBlock(x, z);
int ha = highestTerrainBlock(x + 1, z);
int hb = highestTerrainBlock(x, z + 1);
int hc = highestTerrainBlock(x - 1, z);
int hd = highestTerrainBlock(x, z - 1);
if(ha == h - 1 && hb == h - 1 && hc == h - 1 && hd == h - 1)
{
BlockData bc = getPostBlock(x, h, z);
BlockData b = getPostBlock(x, h + 1, z);
Material m = bc.getMaterial();
if(m.isSolid())
{
setPostBlock(x, h, z, b);
}
}
}
}

View File

@ -0,0 +1,27 @@
package ninja.bytecode.iris.layer.post;
import ninja.bytecode.iris.generator.PostBlockChunkGenerator;
import ninja.bytecode.iris.util.IrisPostBlockFilter;
public class PostPotholeFiller extends IrisPostBlockFilter
{
public PostPotholeFiller(PostBlockChunkGenerator gen)
{
super(gen);
}
@Override
public void onPost(int x, int z)
{
int h = highestTerrainBlock(x, z);
int ha = highestTerrainBlock(x + 1, z);
int hb = highestTerrainBlock(x, z + 1);
int hc = highestTerrainBlock(x - 1, z);
int hd = highestTerrainBlock(x, z - 1);
if(ha == h + 1 && hb == h + 1 && hc == h + 1 && hd == h + 1)
{
setPostBlock(x, h + 1, z, getPostBlock(x, h, z));
}
}
}

View File

@ -28,6 +28,9 @@ public class IrisBiome extends IrisRegistrant
@Desc("This zooms in the biome colors if multiple derivatives are chosen") @Desc("This zooms in the biome colors if multiple derivatives are chosen")
private double biomeZoom = 1; private double biomeZoom = 1;
@Desc("The rarity of this biome (integer)")
private int rarity = 1;
@Desc("The raw derivative of this biome. This is required or the terrain will not properly generate. Use any vanilla biome type. Look in examples/biome-list.txt") @Desc("The raw derivative of this biome. This is required or the terrain will not properly generate. Use any vanilla biome type. Look in examples/biome-list.txt")
private Biome derivative = Biome.THE_VOID; private Biome derivative = Biome.THE_VOID;

View File

@ -40,9 +40,6 @@ public class IrisRegion extends IrisRegistrant
@Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.")
private KList<String> shoreBiomes = new KList<>(); private KList<String> shoreBiomes = new KList<>();
@Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.")
private KList<String> caveBiomes = new KList<>();
@Desc("Ridge biomes create a vein-like network like rivers through this region") @Desc("Ridge biomes create a vein-like network like rivers through this region")
private KList<IrisRegionRidge> ridgeBiomes = new KList<>(); private KList<IrisRegionRidge> ridgeBiomes = new KList<>();

View File

@ -7,6 +7,7 @@ import java.io.IOException;
import org.bukkit.World; import org.bukkit.World;
import ninja.bytecode.iris.util.ChronoLatch;
import ninja.bytecode.iris.util.ChunkPosition; import ninja.bytecode.iris.util.ChunkPosition;
import ninja.bytecode.shuriken.collections.KMap; import ninja.bytecode.shuriken.collections.KMap;
import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.M;
@ -18,6 +19,7 @@ public class AtomicWorldData
private KMap<ChunkPosition, AtomicRegionData> loadedSections; private KMap<ChunkPosition, AtomicRegionData> loadedSections;
private KMap<ChunkPosition, Long> lastRegion; private KMap<ChunkPosition, Long> lastRegion;
private String prefix; private String prefix;
private ChronoLatch cl = new ChronoLatch(15000);
public AtomicWorldData(World world, String prefix) public AtomicWorldData(World world, String prefix)
{ {
@ -238,6 +240,11 @@ public class AtomicWorldData
public void clean(int j) public void clean(int j)
{ {
if(!cl.flip())
{
return;
}
for(ChunkPosition i : lastRegion.k()) for(ChunkPosition i : lastRegion.k())
{ {
if(M.ms() - lastRegion.get(i) > 60000) if(M.ms() - lastRegion.get(i) > 60000)

View File

@ -0,0 +1,14 @@
package ninja.bytecode.iris.util;
import org.bukkit.block.data.BlockData;
public interface IPostBlockAccess
{
public BlockData getPostBlock(int x, int y, int z);
public void setPostBlock(int x, int y, int z, BlockData d);
public int highestTerrainOrFluidBlock(int x, int z);
public int highestTerrainBlock(int x, int z);
}

View File

@ -0,0 +1,41 @@
package ninja.bytecode.iris.util;
import org.bukkit.block.data.BlockData;
import ninja.bytecode.iris.generator.PostBlockChunkGenerator;
public abstract class IrisPostBlockFilter implements IPostBlockAccess
{
public PostBlockChunkGenerator gen;
public IrisPostBlockFilter(PostBlockChunkGenerator gen)
{
this.gen = gen;
}
public abstract void onPost(int x, int z);
@Override
public BlockData getPostBlock(int x, int y, int z)
{
return gen.getPostBlock(x, y, z);
}
@Override
public void setPostBlock(int x, int y, int z, BlockData d)
{
gen.setPostBlock(x, y, z, d);
}
@Override
public int highestTerrainOrFluidBlock(int x, int z)
{
return gen.highestTerrainOrFluidBlock(x, z);
}
@Override
public int highestTerrainBlock(int x, int z)
{
return gen.highestTerrainBlock(x, z);
}
}

View File

@ -6,13 +6,13 @@ import org.bukkit.util.BlockVector;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.object.IrisObject; import ninja.bytecode.iris.object.IrisObject;
import ninja.bytecode.shuriken.collections.KList;
import ninja.bytecode.shuriken.collections.KMap; import ninja.bytecode.shuriken.collections.KMap;
import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.M;
public class ObjectResourceLoader extends ResourceLoader<IrisObject> public class ObjectResourceLoader extends ResourceLoader<IrisObject>
{ {
private ChunkPosition parallaxSize; private ChunkPosition parallaxSize;
private ChronoLatch useFlip = new ChronoLatch(2863);
private KMap<String, Long> useCache = new KMap<>(); private KMap<String, Long> useCache = new KMap<>();
public ObjectResourceLoader(File root, String folderName, String resourceTypeName) public ObjectResourceLoader(File root, String folderName, String resourceTypeName)
@ -34,25 +34,46 @@ public class ObjectResourceLoader extends ResourceLoader<IrisObject>
public void clean() public void clean()
{ {
if(loadCache.size() > 15 && getTotalStorage() > 20000) if(useFlip.flip())
{ {
unloadLast(30000); if(loadCache.size() > 15 && getTotalStorage() > 20000)
{
unloadLast(30000);
}
} }
} }
public void unloadLast(long age) public void unloadLast(long age)
{ {
KList<String> g = useCache.sortKNumber(); String v = getOldest();
if(!g.isEmpty()) if(v == null)
{ {
String v = g.get(0); return;
}
if(M.ms() - useCache.get(v) > age) if(M.ms() - useCache.get(v) > age)
{
unload(v);
}
}
private String getOldest()
{
long min = M.ms();
String v = null;
for(String i : useCache.k())
{
long t = useCache.get(i);
if(t < min)
{ {
unload(v); min = t;
v = i;
} }
} }
return v;
} }
private void unload(String v) private void unload(String v)

View File

@ -19,6 +19,7 @@ public class ResourceLoader<T extends IrisRegistrant>
protected KMap<String, T> loadCache; protected KMap<String, T> loadCache;
protected KList<File> folderCache; protected KList<File> folderCache;
protected Class<? extends T> objectClass; protected Class<? extends T> objectClass;
protected String cname;
protected ReentrantLock lock; protected ReentrantLock lock;
public ResourceLoader(File root, String folderName, String resourceTypeName, Class<? extends T> objectClass) public ResourceLoader(File root, String folderName, String resourceTypeName, Class<? extends T> objectClass)
@ -26,6 +27,7 @@ public class ResourceLoader<T extends IrisRegistrant>
lock = new ReentrantLock(); lock = new ReentrantLock();
folderMapCache = new KMap<>(); folderMapCache = new KMap<>();
this.objectClass = objectClass; this.objectClass = objectClass;
cname = objectClass.getCanonicalName();
this.resourceTypeName = resourceTypeName; this.resourceTypeName = resourceTypeName;
this.root = root; this.root = root;
this.folderName = folderName; this.folderName = folderName;
@ -60,7 +62,7 @@ public class ResourceLoader<T extends IrisRegistrant>
public T load(String name) public T load(String name)
{ {
String key = name + "-" + objectClass.getCanonicalName(); String key = name + "-" + cname;
if(loadCache.containsKey(key)) if(loadCache.containsKey(key))
{ {