More SPEED

This commit is contained in:
Daniel Mills 2020-09-11 11:06:32 -04:00
parent be6739ecb8
commit 1618d54b70
18 changed files with 199 additions and 122 deletions

View File

@ -40,9 +40,11 @@ public class CommandIrisMetrics extends MortarCommand
sender.sendMessage("Thread Count: " + C.BOLD + "" + C.WHITE + g.getThreads());
sender.sendMessage("Total : " + C.BOLD + "" + C.WHITE + Form.duration(m.getTotal().getAverage(), 2));
sender.sendMessage(" Terrain : " + C.BOLD + "" + C.WHITE + Form.duration(m.getTerrain().getAverage(), 2));
sender.sendMessage(" Deposits : " + C.BOLD + "" + C.WHITE + Form.duration(m.getDeposits().getAverage(), 2));
sender.sendMessage(" Parallax: " + C.BOLD + "" + C.WHITE + Form.duration(m.getParallax().getAverage(), 2));
sender.sendMessage(" Post : " + C.BOLD + "" + C.WHITE + Form.duration(m.getPost().getAverage(), 2));
sender.sendMessage("Updates : " + C.BOLD + "" + C.WHITE + Form.duration(m.getUpdate().getAverage(), 2));
sender.sendMessage("Lighting : " + C.BOLD + "" + C.WHITE + Form.duration(m.getUpdate().getAverage(), 2));
sender.sendMessage("Spawns : " + C.BOLD + "" + C.WHITE + Form.duration(m.getSpawns().getAverage(), 2));
return true;
}

View File

@ -81,7 +81,10 @@ public abstract class DimensionalTerrainProvider extends ContextualTerrainProvid
public void onInit(RNG masterRandom)
{
if(getDimension().hasSky())
{
getDimension().getSky().setSkyDimension(true);
}
}
public IrisDimension getDimension()

View File

@ -40,7 +40,7 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisTerrainProvider extends PostBlockTerrainProvider implements IrisContext
public class IrisTerrainProvider extends SkyTerrainProvider implements IrisContext
{
private IrisBiome hb = null;
private IrisRegion hr = null;

View File

@ -112,7 +112,7 @@ public abstract class ParallaxTerrainProvider extends TopographicTerrainProvider
@Override
public BlockData get(int x, int y, int z)
{
BlockData b = sampleSliver(x, z).getBlock().get(y);
BlockData b = sampleSliver(x, z).getBlock()[y];
return b == null ? AIR : b;
}

View File

@ -72,7 +72,6 @@ public abstract class ParallelTerrainProvider extends DimensionalTerrainProvider
String key = "c" + x + "," + z;
BiomeMap biomeMap = new BiomeMap();
int ii, jj;
onPreGenerate(random, x, z, terrain, height, biomeMap, map);
for(ii = 0; ii < 16; ii++)
@ -102,8 +101,7 @@ public abstract class ParallelTerrainProvider extends DimensionalTerrainProvider
}
accelerant.waitFor(key);
map.write(terrain, terrain, height);
map.write(terrain, terrain, height, true);
getMetrics().getTerrain().put(p.getMilliseconds());
p = PrecisionStopwatch.start();
onPostGenerate(random, x, z, terrain, height, biomeMap, map);

View File

@ -24,8 +24,6 @@ public abstract class PostBlockTerrainProvider extends ParallaxTerrainProvider i
private String postKey;
private IrisLock postLock;
private PostMasterPatcher patcher;
private int minPhase;
private int maxPhase;
public PostBlockTerrainProvider(TerrainTarget t, String dimensionName, int threads)
{
@ -50,23 +48,21 @@ public abstract class PostBlockTerrainProvider extends ParallaxTerrainProvider i
return;
}
int rx, i, j;
int rx, i;
PrecisionStopwatch p = PrecisionStopwatch.start();
KList<Runnable> q = new KList<>();
for(i = 0; i < 16; i++)
{
rx = (x << 4) + i;
for(j = 0; j < 16; j++)
int rxx = rx;
getAccelerant().queue("post", () ->
{
int rxx = rx;
int rzz = (z << 4) + j;
getAccelerant().queue("post", () ->
for(int j = 0; j < 16; j++)
{
patcher.onPost(rxx, rzz, x, z, terrain, q);
});
}
patcher.onPost(rxx, (z << 4) + j, x, z, terrain, q);
}
});
}
getAccelerant().waitFor("post");

View File

@ -0,0 +1,19 @@
package com.volmit.iris.gen;
import com.volmit.iris.gen.scaffold.TerrainChunk;
import com.volmit.iris.gen.scaffold.TerrainTarget;
import com.volmit.iris.util.RNG;
public abstract class SkyTerrainProvider extends PostBlockTerrainProvider
{
public SkyTerrainProvider(TerrainTarget t, String dimensionName, int threads)
{
super(t, dimensionName, threads);
}
@Override
protected void onGenerate(RNG random, int x, int z, TerrainChunk terrain)
{
super.onGenerate(random, x, z, terrain);
}
}

View File

@ -20,6 +20,7 @@ import com.volmit.iris.object.InferredType;
import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.object.IrisBiomeDecorator;
import com.volmit.iris.object.IrisBiomeGeneratorLink;
import com.volmit.iris.object.IrisDepositGenerator;
import com.volmit.iris.object.IrisDimension;
import com.volmit.iris.object.IrisGenerator;
import com.volmit.iris.object.IrisRegion;
@ -33,6 +34,7 @@ import com.volmit.iris.util.IrisLock;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.M;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG;
import lombok.Data;
@ -286,12 +288,6 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider
// Carve out biomes
KList<CaveResult> caveResults = glCave.genCaves(rx, rz, x, z, sliver);
KList<CaveResult> caveResults1 = glCave.genCaves(rx, rz, x, z, null);
if(caveResults.size() != caveResults1.size())
{
Iris.warn("REAL: " + caveResults.size() + " Guess: " + caveResults1.size());
}
IrisBiome caveBiome = glBiome.generateData(InferredType.CAVE, wx, wz, rx, rz, region);
@ -300,11 +296,16 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider
{
for(CaveResult i : caveResults)
{
if(i.getFloor() < 0 || i.getFloor() > 255 || i.getCeiling() > 255 || i.getCeiling() < 0)
{
continue;
}
if(Iris.biome3d)
{
for(int j = i.getFloor(); j <= i.getCeiling(); j++)
{
sliver.set(j, caveBiome);
sliver.set(j, caveBiome.getGroundBiome(getMasterRandom(), rz, j, rx));
}
}
@ -537,7 +538,41 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider
protected void onPreParallaxPostGenerate(RNG random, int x, int z, TerrainChunk terrain, HeightMap height, BiomeMap biomeMap, AtomicSliverMap map)
{
if(!getDimension().isVanillaCaves())
{
generateDeposits(random.nextParallelRNG(x).nextParallelRNG(z), terrain, x, z);
}
}
public void generateDeposits(RNG rx, TerrainChunk terrain, int x, int z)
{
PrecisionStopwatch p = PrecisionStopwatch.start();
RNG ro = rx.nextParallelRNG((x * x * x) - z);
IrisRegion region = sampleRegion((x * 16) + 7, (z * 16) + 7);
IrisBiome biome = sampleTrueBiome((x * 16) + 7, (z * 16) + 7);
for(IrisDepositGenerator k : getDimension().getDeposits())
{
k.generate(terrain, ro, this, x, z, false);
}
for(IrisDepositGenerator k : region.getDeposits())
{
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{
k.generate(terrain, ro, this, x, z, false);
}
}
for(IrisDepositGenerator k : biome.getDeposits())
{
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{
k.generate(terrain, ro, this, x, z, false);
}
}
p.end();
getMetrics().getDeposits().put(p.getMilliseconds());
}
protected void onPostParallaxPostGenerate(RNG random, int x, int z, TerrainChunk terrain, HeightMap height, BiomeMap biomeMap, AtomicSliverMap map)

View File

@ -11,13 +11,10 @@ import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.bukkit.generator.ChunkGenerator.ChunkData;
import com.volmit.iris.Iris;
import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.util.B;
import com.volmit.iris.util.HeightMap;
import com.volmit.iris.util.IrisLock;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.M;
import lombok.Data;
@ -27,28 +24,26 @@ public class AtomicSliver
{
public static final BlockData AIR = B.getBlockData("AIR");
public static boolean forgetful = false;
private transient KMap<Integer, IrisBiome> truebiome;
private transient KMap<Integer, Biome> biome;
private transient Biome[] biome;
private transient Biome onlyBiome;
private transient IrisLock lock = new IrisLock("Sliver");
private transient int highestBiome = 0;
private transient short highestBiome = 0;
private transient long last = M.ms();
private transient final int x;
private transient final int z;
private transient final byte x;
private transient final byte z;
private transient boolean modified = false;
private KMap<Integer, BlockData> block;
private KSet<Integer> blockUpdates;
private BlockData[] block;
private KList<Byte> blockUpdates;
private int highestBlock = 0;
public AtomicSliver(int x, int z)
{
onlyBiome = null;
this.x = x;
this.z = z;
blockUpdates = new KSet<>();
this.block = new KMap<>();
this.biome = new KMap<>();
this.truebiome = new KMap<>();
this.x = (byte) x;
this.z = (byte) z;
blockUpdates = new KList<>(4);
this.block = new BlockData[256];
this.biome = new Biome[256];
}
public Material getType(int h)
@ -56,29 +51,29 @@ public class AtomicSliver
return get(h).getMaterial();
}
public KSet<Integer> getUpdatables()
public KList<Byte> getUpdatables()
{
return blockUpdates;
}
public void update(int y)
public void update(byte y)
{
if(forgetful)
{
return;
}
blockUpdates.add(y);
blockUpdates.addIfMissing((byte) (y + Byte.MIN_VALUE));
}
public void dontUpdate(int y)
public void dontUpdate(byte y)
{
if(forgetful)
{
return;
}
blockUpdates.remove(y);
blockUpdates.remove(Byte.valueOf((byte) (y + Byte.MIN_VALUE)));
}
public BlockData get(int h)
@ -87,7 +82,7 @@ public class AtomicSliver
{
return null;
}
BlockData b = block.get(h);
BlockData b = block[h];
last = M.ms();
if(b == null)
@ -104,7 +99,7 @@ public class AtomicSliver
{
return null;
}
BlockData b = block.get(h);
BlockData b = block[h];
last = M.ms();
if(b.getMaterial().equals(Material.AIR))
@ -144,16 +139,16 @@ public class AtomicSliver
lock.lock();
modified = true;
block.put(h, d);
block[h] = d;
if(B.isUpdatable(d))
{
update(h);
update((byte) h);
}
else
{
dontUpdate(h);
dontUpdate((byte) h);
}
lock.unlock();
@ -164,30 +159,13 @@ public class AtomicSliver
return getType(h).isSolid();
}
public Biome getBiome(int h)
{
if(!Iris.biome3d)
{
return onlyBiome != null ? onlyBiome : Biome.THE_VOID;
}
last = M.ms();
return biome.containsKey(h) ? biome.get(h) : Biome.THE_VOID;
}
public IrisBiome getTrueBiome(int h)
{
last = M.ms();
return truebiome.get(h);
}
public void set(int h, Biome d)
{
lock.lock();
if(Iris.biome3d)
{
biome.put(h, d);
biome[h] = d;
}
else
@ -196,19 +174,11 @@ public class AtomicSliver
}
modified = true;
highestBiome = h > highestBiome ? h : highestBiome;
highestBiome = (short) (h > highestBiome ? h : highestBiome);
lock.unlock();
}
public void set(int h, IrisBiome d)
{
lock.lock();
modified = true;
truebiome.put(h, d);
lock.unlock();
}
public void write(ChunkData d)
public void write(ChunkData d, boolean skipNull)
{
if(forgetful)
{
@ -219,14 +189,17 @@ public class AtomicSliver
for(int i = 0; i <= highestBlock; i++)
{
if(block.get(i) == null)
if(block[i] == null)
{
d.setBlock(x, i, z, AIR);
if(!skipNull)
{
d.setBlock(x, i, z, AIR);
}
}
else
{
d.setBlock(x, i, z, block.get(i));
d.setBlock(x, i, z, block[i]);
}
}
lock.unlock();
@ -246,9 +219,9 @@ public class AtomicSliver
for(int i = 0; i <= highestBiome; i++)
{
if(biome.get(i) != null)
if(biome[i] != null)
{
d.setBiome(x, i, z, biome.get(i));
d.setBiome(x, i, z, biome[i]);
}
}
@ -265,7 +238,7 @@ public class AtomicSliver
public void read(DataInputStream din) throws IOException
{
lock.lock();
this.block = new KMap<Integer, BlockData>();
this.block = new BlockData[256];
getUpdatables().clear();
// Block Palette
@ -283,13 +256,13 @@ public class AtomicSliver
// Blocks
for(int i = 0; i <= h; i++)
{
block.put(i, palette.get(din.readByte() - Byte.MIN_VALUE).clone());
block[i] = palette.get(din.readByte() - Byte.MIN_VALUE).clone();
}
// Updates
for(int i = 0; i < u; i++)
{
update(din.readByte() - Byte.MIN_VALUE);
update(din.readByte());
}
modified = false;
@ -309,7 +282,7 @@ public class AtomicSliver
for(int i = 0; i <= highestBlock; i++)
{
BlockData dat = block.get(i);
BlockData dat = block[i];
String d = (dat == null ? AIR : dat).getAsString(true);
if(!palette.contains(d))
@ -330,15 +303,15 @@ public class AtomicSliver
// Blocks
for(int i = 0; i <= highestBlock; i++)
{
BlockData dat = block.get(i);
BlockData dat = block[i];
String d = (dat == null ? AIR : dat).getAsString(true);
dos.writeByte(palette.indexOf(d) + Byte.MIN_VALUE);
}
// Updates
for(Integer i : getUpdatables())
for(Byte i : getUpdatables())
{
dos.writeByte(i + Byte.MIN_VALUE);
dos.writeByte(i);
}
lock.unlock();
@ -353,15 +326,15 @@ public class AtomicSliver
lock.lock();
for(int i = 0; i < 256; i++)
{
if(block.get(i) == null || block.get(i).equals(AIR))
if(block[i] == null || block[i].equals(AIR))
{
BlockData b = atomicSliver.block.get(i);
BlockData b = atomicSliver.block[i];
if(b == null || b.equals(AIR))
{
continue;
}
block.put(i, b);
block[i] = b;
}
}
lock.unlock();
@ -375,9 +348,9 @@ public class AtomicSliver
}
lock.lock();
for(int i : block.keySet())
for(int i = 0; i < block.length; i++)
{
BlockData b = block.get(i);
BlockData b = block[i];
if(b != null)
{
if(b.getMaterial().equals(Material.AIR))
@ -402,7 +375,7 @@ public class AtomicSliver
return M.ms() - last > m;
}
public void inject(KSet<Integer> updatables)
public void inject(KList<Byte> updatables)
{
if(forgetful)
{

View File

@ -166,13 +166,13 @@ public class AtomicSliverMap
return slivers[x * 16 + z];
}
public void write(ChunkData data, BiomeGrid grid, HeightMap height)
public void write(ChunkData data, BiomeGrid grid, HeightMap height, boolean skipNull)
{
for(AtomicSliver i : slivers)
{
if(i != null)
{
i.write(data);
i.write(data, skipNull);
i.write(grid);
i.write(height);
}

View File

@ -29,7 +29,7 @@ public class GenLayerCave extends GenLayer
public GenLayerCave(DimensionalTerrainProvider iris, RNG rng)
{
//@NoArgsConstructor
// @NoArgsConstructor
super(iris, rng);
gg = new FastNoiseDouble(324895 * rng.nextParallelRNG(49678).imax());
//@done
@ -86,6 +86,11 @@ public class GenLayerCave extends GenLayer
double distanceTake = 0.0022 * baseWidth;
double caveHeightNoise = layer.getVerticalSlope().get(rng, wxx, wzz);
if(caveHeightNoise > 259 || caveHeightNoise < -1)
{
return;
}
int ceiling = -256;
int floor = 512;

View File

@ -12,7 +12,6 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import com.volmit.iris.Iris;
import com.volmit.iris.gen.IrisTerrainProvider;
import com.volmit.iris.gen.ParallaxTerrainProvider;
import com.volmit.iris.gen.atomics.AtomicSliverMap;
@ -44,23 +43,29 @@ public class GenLayerUpdate extends BlockPopulator
@Override
public void populate(World w, Random r, Chunk c)
{
PrecisionStopwatch p = PrecisionStopwatch.start();
AtomicSliverMap map = gen.getParallaxChunk(c.getX(), c.getZ());
RNG rx = rng.nextParallelRNG(c.getX() + r.nextInt()).nextParallelRNG(c.getZ() + r.nextInt());
generateDeposits(w, rx, c);
if(gen.getDimension().isVanillaCaves())
{
generateDepositsWithVanillaSaftey(w, rx, c);
}
updateBlocks(w, rx, c, map);
spawnInitials(c, rx);
p.end();
gen.getMetrics().getUpdate().put(p.getMilliseconds());
}
public void spawnInitials(Chunk c, RNG rx)
{
PrecisionStopwatch p = PrecisionStopwatch.start();
((IrisTerrainProvider) gen).spawnInitials(c, rx);
p.end();
gen.getMetrics().getSpawns().put(p.getMilliseconds());
}
public void generateDeposits(World w, RNG rx, Chunk c)
public void generateDepositsWithVanillaSaftey(World w, RNG rx, Chunk c)
{
PrecisionStopwatch p = PrecisionStopwatch.start();
int x = c.getX();
int z = c.getZ();
RNG ro = rx.nextParallelRNG((x * x * x) - z);
@ -70,14 +75,14 @@ public class GenLayerUpdate extends BlockPopulator
for(IrisDepositGenerator k : gen.getDimension().getDeposits())
{
k.generate(terrain, ro, gen, x, z);
k.generate(terrain, ro, gen, x, z, true);
}
for(IrisDepositGenerator k : region.getDeposits())
{
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{
k.generate(terrain, ro, gen, x, z);
k.generate(terrain, ro, gen, x, z, true);
}
}
@ -85,19 +90,23 @@ public class GenLayerUpdate extends BlockPopulator
{
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{
k.generate(terrain, ro, gen, x, z);
k.generate(terrain, ro, gen, x, z, true);
}
}
p.end();
gen.getMetrics().getDeposits().put(p.getMilliseconds());
}
private void updateBlocks(World w, RNG rx, Chunk c, AtomicSliverMap map)
{
PrecisionStopwatch p = PrecisionStopwatch.start();
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 16; j++)
{
for(int k : map.getSliver(i, j).getUpdatables())
for(byte kv : map.getSliver(i, j).getUpdatables())
{
byte k = (byte) (kv - Byte.MIN_VALUE);
if(k > 255 || k < 0)
{
continue;
@ -107,6 +116,8 @@ public class GenLayerUpdate extends BlockPopulator
}
}
}
p.end();
gen.getMetrics().getUpdate().put(p.getMilliseconds());
}
public void update(Chunk c, int x, int y, int z, int rx, int rz, RNG rng)
@ -223,9 +234,8 @@ public class GenLayerUpdate extends BlockPopulator
catch(Throwable e)
{
Iris.error("NOT INVENTORY: " + data.getMaterial().name());
}
}
}
}

View File

@ -12,6 +12,8 @@ public class IrisMetrics
private final RollingSequence terrain;
private final RollingSequence post;
private final RollingSequence update;
private final RollingSequence deposits;
private final RollingSequence spawns;
private final RollingSequence total;
private final RollingSequence perSecond;
public int generators = 0;
@ -20,9 +22,11 @@ public class IrisMetrics
public IrisMetrics(int memory)
{
parallax = new RollingSequence(memory);
spawns = new RollingSequence(memory);
terrain = new RollingSequence(memory);
post = new RollingSequence(memory);
update = new RollingSequence(memory);
deposits = new RollingSequence(memory);
total = new RollingSequence(memory);
perSecond = new RollingSequence(5);
}

View File

@ -199,7 +199,7 @@ public class ProjectManager
File packEntry = new File(packs, key);
if(packEntry.exists())
if(packEntry.exists() && packEntry.listFiles().length > 0)
{
sender.sendMessage("Another pack is using the key " + key + ". IMPORT FAILED!");
return;

View File

@ -9,6 +9,7 @@ import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.HeightMap;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
@ -157,7 +158,12 @@ public class IrisDepositGenerator
});
}
public void generate(ChunkData data, RNG rng, TopographicTerrainProvider g, int cx, int cz)
public void generate(ChunkData data, RNG rng, TopographicTerrainProvider g, int cx, int cz, boolean safe)
{
generate(data, rng, g, cx, cz, safe, null);
}
public void generate(ChunkData data, RNG rng, TopographicTerrainProvider g, int cx, int cz, boolean safe, HeightMap he)
{
for(int l = 0; l < rng.i(getMinPerChunk(), getMaxPerChunk()); l++)
{
@ -174,7 +180,7 @@ public class IrisDepositGenerator
int x = rng.i(af, bf);
int z = rng.i(af, bf);
int height = (int) (Math.round(g.getCarvedWaterHeight((cx << 4) + x, (cz << 4) + z))) - 7;
int height = (he != null ? he.getHeight((cx << 4) + x, (cz << 4) + z) : (int) (Math.round(g.getCarvedWaterHeight((cx << 4) + x, (cz << 4) + z)))) - 7;
if(height <= 0)
{
@ -207,14 +213,18 @@ public class IrisDepositGenerator
continue;
}
boolean allow = false;
BlockData b = data.getBlockData(nx, ny, nz);
for(BlockData f : g.getDimension().getRockPalette().getBlockData())
boolean allow = !safe;
if(!allow)
{
if(f.getMaterial().equals(b.getMaterial()))
BlockData b = data.getBlockData(nx, ny, nz);
for(BlockData f : g.getDimension().getRockPalette().getBlockData())
{
allow = true;
break;
if(f.getMaterial().equals(b.getMaterial()))
{
allow = true;
break;
}
}
}

View File

@ -50,6 +50,10 @@ public class IrisDimension extends IrisRegistrant
@Desc("The human readable name of this dimension")
private String name = "A Dimension";
@DontObfuscate
@Desc("Create an inverted dimension in the sky (like the nether)")
private IrisDimension sky = null;
@DontObfuscate
@Desc("Place text on terrain")
@ArrayType(min = 1, type = IrisTextPlacement.class)
@ -307,6 +311,7 @@ public class IrisDimension extends IrisRegistrant
@Desc("Define biome mutations for this dimension")
private KList<IrisBiomeMutation> mutations = new KList<>();
private transient boolean skyDimension = false;
private final transient AtomicCache<ChunkPosition> parallaxSize = new AtomicCache<>();
private final transient AtomicCache<KList<IrisPostBlockFilter>> cacheFilters = new AtomicCache<>();
private final transient AtomicCache<CNG> rockLayerGenerator = new AtomicCache<>();
@ -316,6 +321,11 @@ public class IrisDimension extends IrisRegistrant
private final transient AtomicCache<Double> cosr = new AtomicCache<>();
private final transient AtomicCache<Double> rad = new AtomicCache<>();
public boolean hasSky()
{
return getSky() != null;
}
public static KList<IrisCompatabilityFilter> getDefaultCompatability()
{
KList<IrisCompatabilityFilter> filters = new KList<>();

View File

@ -688,4 +688,15 @@ public class KList<T> extends ArrayList<T> implements List<T>
add(t);
}
}
public void addAllIfMissing(KList<T> t)
{
for(T i : t)
{
if(!contains(i))
{
add(i);
}
}
}
}

View File

@ -80,8 +80,9 @@ public class ParallaxChunk implements Writable
public void injectUpdates(AtomicSliver sliver, int x, int z)
{
for(Integer i : sliver.getUpdatables())
for(Byte b : sliver.getUpdatables())
{
byte i = (byte) (b - Byte.MIN_VALUE);
if(i > 255 || i < 0)
{
Iris.warn("Block Update out of bounds: " + i);