9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-30 04:29:05 +00:00

Parallax 2

This commit is contained in:
Daniel Mills
2020-08-22 09:51:54 -04:00
parent ccc7a947cd
commit 2500fa54e4
17 changed files with 1107 additions and 105 deletions

View File

@@ -17,7 +17,6 @@ import com.volmit.iris.object.IrisBiomeMutation;
import com.volmit.iris.object.IrisObjectPlacement;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.object.IrisStructurePlacement;
import com.volmit.iris.object.TileResult;
import com.volmit.iris.util.BiomeMap;
import com.volmit.iris.util.CaveResult;
import com.volmit.iris.util.ChunkPosition;
@@ -27,6 +26,7 @@ import com.volmit.iris.util.IrisLock;
import com.volmit.iris.util.IrisStructureResult;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.NBTInputStream;
import com.volmit.iris.util.NastyRunnable;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG;
@@ -106,7 +106,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
return h;
}
NBTInputStream
return h;
}
@@ -218,61 +218,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
public IrisStructureResult getStructure(int x, int y, int z)
{
IrisBiome b = sampleTrueBiome(x, z).getBiome();
IrisRegion r = sampleRegion(x, z);
RNG ro = getMasterRandom().nextParallelRNG(496888 + (x >> 4) + (z >> 4));
int h = (int) Math.round(getTerrainHeight(x, z));
KList<IrisStructurePlacement> p = new KList<>();
for(IrisStructurePlacement i : r.getStructures())
{
if(i.getHeight() > -1)
{
if(y >= i.getHeight() && y <= i.getHeight() + (i.getStructure(this).getGridHeight() * i.getStructure(this).getMaxLayers()))
{
p.add(i);
}
}
else if(y >= h && y <= i.getStructure(this).getGridHeight() + h)
{
p.add(i);
}
}
for(IrisStructurePlacement i : b.getStructures())
{
if(i.getHeight() > -1)
{
if(y >= i.getHeight() && y <= i.getHeight() + (i.getStructure(this).getGridHeight() * i.getStructure(this).getMaxLayers()))
{
p.add(i);
}
}
else if(y >= h && y <= i.getStructure(this).getGridHeight() + h)
{
p.add(i);
}
}
for(IrisStructurePlacement i : p)
{
if(!i.hasStructure(ro, x, y, z))
{
continue;
}
int hv = (i.getHeight() == -1 ? 0 : i.getHeight()) + (Math.floorDiv(y, i.getStructure(this).getGridHeight()) * i.getStructure(this).getGridHeight());
TileResult tile = i.getStructure(this).getTile(ro, Math.floorDiv(i.gridSize(this), x) * i.gridSize(this), hv, Math.floorDiv(i.gridSize(this), z) * i.gridSize(this));
if(tile != null && tile.getTile() != null)
{
return new IrisStructureResult(tile.getTile(), i.getStructure(this));
}
}
return null;
return getParallaxChunk(x >> 4, z >> 4).getStructure(this, y);
}
protected void onGenerateParallax(RNG random, int x, int z)

View File

@@ -25,24 +25,24 @@ import lombok.Data;
public class AtomicSliver
{
public static final BlockData AIR = B.getBlockData("AIR");
private transient KMap<Integer, IrisBiome> truebiome;
private transient KMap<Integer, Biome> biome;
private transient IrisLock lock = new IrisLock("Sliver");
private transient int highestBiome = 0;
private transient long last = M.ms();
private transient int x;
private transient int z;
private transient boolean modified = false;
private KMap<Integer, BlockData> block;
private KMap<Integer, IrisBiome> truebiome;
private KMap<Integer, Biome> biome;
private KSet<Integer> update;
private IrisLock lock = new IrisLock("Sliver");
private KSet<Integer> blockUpdates;
private int highestBlock = 0;
private int highestBiome = 0;
private long last = M.ms();
private int x;
private int z;
boolean modified = false;
public AtomicSliver(int x, int z)
{
lock.setDisabled(true);
this.x = x;
this.z = z;
update = new KSet<>();
blockUpdates = new KSet<>();
this.block = new KMap<>();
this.biome = new KMap<>();
this.truebiome = new KMap<>();
@@ -55,17 +55,17 @@ public class AtomicSliver
public KSet<Integer> getUpdatables()
{
return update;
return blockUpdates;
}
public void update(int y)
{
update.add(y);
blockUpdates.add(y);
}
public void dontUpdate(int y)
{
update.remove(y);
blockUpdates.remove(y);
}
public BlockData get(int h)
@@ -81,6 +81,19 @@ public class AtomicSliver
return b;
}
public BlockData getOrNull(int h)
{
BlockData b = block.get(h);
last = M.ms();
if(b.getMaterial().equals(Material.AIR))
{
return null;
}
return b;
}
public void set(int h, BlockData d)
{
setSilently(h, d);
@@ -190,6 +203,8 @@ public class AtomicSliver
{
lock.lock();
this.block = new KMap<Integer, BlockData>();
// Block Palette
int h = din.readByte() - Byte.MIN_VALUE;
int p = din.readByte() - Byte.MIN_VALUE;
int u = din.readByte() - Byte.MIN_VALUE;
@@ -202,11 +217,13 @@ public class AtomicSliver
palette.add(B.getBlockData(din.readUTF()));
}
// Blocks
for(int i = 0; i <= h; i++)
{
block.put(i, palette.get(din.readByte() - Byte.MIN_VALUE).clone());
}
// Updates
for(int i = 0; i <= u; i++)
{
update(din.readByte() - Byte.MIN_VALUE);
@@ -220,6 +237,8 @@ public class AtomicSliver
{
lock.lock();
dos.writeByte(highestBlock + Byte.MIN_VALUE);
// Block Palette
KList<String> palette = new KList<>();
for(int i = 0; i <= highestBlock; i++)
@@ -234,13 +253,14 @@ public class AtomicSliver
}
dos.writeByte(palette.size() + Byte.MIN_VALUE);
dos.writeByte(update.size() + Byte.MIN_VALUE);
dos.writeByte(blockUpdates.size() + Byte.MIN_VALUE);
for(String i : palette)
{
dos.writeUTF(i);
}
// Blocks
for(int i = 0; i <= highestBlock; i++)
{
BlockData dat = block.get(i);
@@ -248,6 +268,7 @@ public class AtomicSliver
dos.writeByte(palette.indexOf(d) + Byte.MIN_VALUE);
}
// Updates
for(Integer i : getUpdatables())
{
dos.writeByte(i + Byte.MIN_VALUE);
@@ -296,6 +317,6 @@ public class AtomicSliver
public void inject(KSet<Integer> updatables)
{
update.addAll(updatables);
blockUpdates.addAll(updatables);
}
}

View File

@@ -9,7 +9,13 @@ import java.io.OutputStream;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.bukkit.generator.ChunkGenerator.ChunkData;
import com.volmit.iris.gen.DimensionChunkGenerator;
import com.volmit.iris.object.IrisStructure;
import com.volmit.iris.object.IrisStructureTile;
import com.volmit.iris.util.HeightMap;
import com.volmit.iris.util.IrisStructureResult;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
import lombok.Data;
@@ -17,11 +23,13 @@ import lombok.Data;
public class AtomicSliverMap
{
private final AtomicSliver[] slivers;
private KMap<Integer, String> structures;
private boolean parallaxGenerated;
private boolean worldGenerated;
public AtomicSliverMap()
{
structures = new KMap<>();
parallaxGenerated = false;
worldGenerated = false;
slivers = new AtomicSliver[256];
@@ -43,6 +51,32 @@ public class AtomicSliverMap
}
}
public void setStructure(int y, IrisStructure s, IrisStructureTile t)
{
structures.put(y, s.getLoadKey() + "." + s.getTiles().indexOf(t));
}
public IrisStructureResult getStructure(DimensionChunkGenerator g, int y)
{
String v = structures.get(y);
if(v == null)
{
return null;
}
String[] a = v.split("\\Q.\\E");
IrisStructure s = g.getData().getStructureLoader().load(a[0]);
if(s == null)
{
return null;
}
return new IrisStructureResult(s.getTiles().get(Integer.valueOf(a[1])), s);
}
public void write(OutputStream out) throws IOException
{
DataOutputStream dos = new DataOutputStream(out);
@@ -53,6 +87,33 @@ public class AtomicSliverMap
slivers[i].write(dos);
}
KList<String> structurePalette = new KList<>();
for(Integer i : structures.k())
{
String struct = structures.get(i);
if(!structurePalette.contains(struct))
{
structurePalette.add(struct);
}
}
dos.writeByte(structurePalette.size() + Byte.MIN_VALUE);
for(String i : structurePalette)
{
dos.writeUTF(i);
}
dos.writeByte(structures.size() + Byte.MIN_VALUE);
for(Integer i : structures.k())
{
dos.writeByte(i + Byte.MIN_VALUE);
dos.writeByte(structurePalette.indexOf(structures.get(i)) + Byte.MIN_VALUE);
}
dos.flush();
}
@@ -74,6 +135,21 @@ public class AtomicSliverMap
}
}
int spc = din.readByte() - Byte.MIN_VALUE;
KList<String> spal = new KList<>();
for(int i = 0; i < spc; i++)
{
spal.add(din.readUTF());
}
int smc = din.readByte() - Byte.MIN_VALUE;
structures.clear();
for(int i = 0; i < smc; i++)
{
structures.put(din.readByte() - Byte.MIN_VALUE, spal.get(din.readByte() - Byte.MIN_VALUE));
}
}
public AtomicSliver getSliver(int x, int z)
@@ -122,7 +198,7 @@ public class AtomicSliverMap
for(int j = 0; j < 16; j++)
{
getSliver(i, j).inject(map.getSliver(i, j).getUpdatables());
}
}
}
}
}

View File

@@ -24,7 +24,6 @@ import com.volmit.iris.object.LootMode;
import com.volmit.iris.util.B;
import com.volmit.iris.util.IrisStructureResult;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG;
@@ -81,7 +80,7 @@ public class GenLayerUpdate extends BlockPopulator
}
}
public void injectTables(KSet<IrisLootTable> list, IrisLootReference r)
public void injectTables(KList<IrisLootTable> list, IrisLootReference r)
{
if(r.getMode().equals(LootMode.CLEAR) || r.getMode().equals(LootMode.REPLACE))
{
@@ -91,15 +90,16 @@ public class GenLayerUpdate extends BlockPopulator
list.addAll(r.getLootTables(gen));
}
public KSet<IrisLootTable> getLootTables(Block b)
public KList<IrisLootTable> getLootTables(RNG rng, Block b)
{
int rx = b.getX();
int rz = b.getZ();
IrisRegion region = gen.sampleRegion(rx, rz);
IrisBiome biomeSurface = gen.sampleTrueBiome(rx, rz).getBiome();
IrisBiome biomeUnder = gen.sampleTrueBiome(rx, b.getY(), rz).getBiome();
KSet<IrisLootTable> tables = new KSet<>();
KList<IrisLootTable> tables = new KList<IrisLootTable>();
IrisStructureResult structure = gen.getStructure(rx, b.getY(), rz);
double multiplier = 1D * gen.getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier();
injectTables(tables, gen.getDimension().getLoot());
injectTables(tables, region.getLoot());
injectTables(tables, biomeSurface.getLoot());
@@ -109,20 +109,38 @@ public class GenLayerUpdate extends BlockPopulator
{
injectTables(tables, structure.getStructure().getLoot());
injectTables(tables, structure.getTile().getLoot());
multiplier *= structure.getStructure().getLoot().getMultiplier() * structure.getTile().getLoot().getMultiplier();
}
if(tables.isNotEmpty())
{
int target = (int) Math.round(tables.size() * multiplier);
while(tables.size() < target && tables.isNotEmpty())
{
tables.add(tables.get(rng.i(tables.size() - 1)));
}
while(tables.size() > target && tables.isNotEmpty())
{
tables.remove(rng.i(tables.size() - 1));
}
}
return tables;
}
public void addItems(boolean debug, Inventory inv, RNG rng, KSet<IrisLootTable> tables, InventorySlotType slot, int x, int y, int z)
public void addItems(boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, int x, int y, int z, int mgf)
{
KList<ItemStack> items = new KList<>();
for(int t = 0; t < gen.getDimension().getLootTries(); t++)
{
int b = 4;
for(IrisLootTable i : tables)
{
items.addAll(i.getLoot(debug, rng.nextParallelRNG(345911 * -t), slot, x, y, z));
b++;
items.addAll(i.getLoot(debug, rng.nextParallelRNG(345911 * -t), slot, x, y, z, t + b + b, mgf + b));
}
for(ItemStack i : items)
@@ -135,6 +153,8 @@ public class GenLayerUpdate extends BlockPopulator
break;
}
}
scramble(inv, rng);
}
public void updateStorage(Block b, BlockData data, int rx, int rz, RNG rng)
@@ -148,12 +168,12 @@ public class GenLayerUpdate extends BlockPopulator
if(slot != null)
{
KSet<IrisLootTable> tables = getLootTables(b);
KList<IrisLootTable> tables = getLootTables(rng.nextParallelRNG(4568111), b);
try
{
InventoryHolder m = (InventoryHolder) b.getState();
addItems(false, m.getInventory(), rng, tables, slot, rx, b.getY(), rz);
addItems(false, m.getInventory(), rng, tables, slot, rx, b.getY(), rz, 15);
}
catch(Throwable e)
@@ -164,6 +184,68 @@ public class GenLayerUpdate extends BlockPopulator
}
}
private void scramble(Inventory inventory, RNG rng)
{
KList<ItemStack> v = new KList<>();
for(ItemStack i : inventory.getContents())
{
if(i == null)
{
continue;
}
v.add(i);
}
inventory.clear();
int sz = inventory.getSize();
int tr = 5;
while(v.isNotEmpty())
{
int slot = rng.i(0, sz - 1);
if(inventory.getItem(slot) == null)
{
tr = tr < 5 ? tr + 1 : tr;
int pick = rng.i(0, v.size() - 1);
ItemStack g = v.get(pick);
if(g.getAmount() == 1)
{
v.remove(pick);
inventory.setItem(pick, g);
}
else
{
int portion = rng.i(1, g.getAmount() - 1);
ItemStack port = g.clone();
port.setAmount(portion);
g.setAmount(g.getAmount() - portion);
v.add(g);
inventory.setItem(slot, port);
}
}
else
{
tr--;
}
if(tr <= 0)
{
break;
}
}
for(ItemStack i : v)
{
inventory.addItem(i);
}
}
public void updateLight(Block b, BlockData data)
{
b.setType(Material.AIR, false);

View File

@@ -0,0 +1,157 @@
package com.volmit.iris.gen.parallax;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.ChunkGenerator.ChunkData;
import com.volmit.iris.Iris;
import com.volmit.iris.gen.atomics.AtomicSliver;
import com.volmit.iris.util.Writable;
public class ParallaxChunk implements Writable
{
private static final ParallaxSection EMPTY = new ParallaxSection();
private final ParallaxSection[] sections;
private boolean parallaxGenerated;
private boolean worldGenerated;
public ParallaxChunk(DataInputStream in) throws IOException
{
this();
read(in);
}
public ParallaxChunk()
{
parallaxGenerated = false;
worldGenerated = false;
sections = new ParallaxSection[16];
}
public boolean isParallaxGenerated()
{
return parallaxGenerated;
}
public void setParallaxGenerated(boolean parallaxGenerated)
{
this.parallaxGenerated = parallaxGenerated;
}
public boolean isWorldGenerated()
{
return worldGenerated;
}
public void setWorldGenerated(boolean worldGenerated)
{
this.worldGenerated = worldGenerated;
}
public void export(ChunkData d)
{
for(ParallaxSection i : sections)
{
if(i != null)
{
for(int x = 0; x < 16; x++)
{
for(int y = 0; y < 16; y++)
{
for(int z = 0; z < 16; z++)
{
BlockData b = get(x, y, z);
if(b == null || b.getMaterial().equals(Material.AIR))
{
continue;
}
d.setBlock(x, y, z, b);
}
}
}
}
}
}
public void injectUpdates(AtomicSliver sliver, int x, int z)
{
for(Integer i : sliver.getUpdatables())
{
if(i > 255 || i < 0)
{
Iris.warn("Block Update out of bounds: " + i);
}
getSection(i >> 4, true).update(x, i, z);
}
}
@Override
public void write(DataOutputStream o) throws IOException
{
o.writeBoolean(isParallaxGenerated());
o.writeBoolean(isWorldGenerated());
for(int i = 15; i > 0; i--)
{
ParallaxSection c = sections[i];
if(c != null)
{
o.writeBoolean(true);
c.write(o);
}
else
{
o.writeBoolean(false);
}
}
}
@Override
public void read(DataInputStream i) throws IOException
{
setParallaxGenerated(i.readBoolean());
setWorldGenerated(i.readBoolean());
for(int iv = 15; iv > 0; iv--)
{
if(i.readBoolean())
{
sections[iv] = new ParallaxSection(i);
}
}
}
public BlockData get(int x, int y, int z)
{
return getSection(y >> 4, false).getBlock(x, y & 15, z);
}
public void set(int x, int y, int z, BlockData d)
{
getSection(y >> 4, true).setBlock(x, y & 15, z, d);
}
private final ParallaxSection getSection(int y, boolean create)
{
if(sections[y] == null)
{
if(create)
{
sections[y] = new ParallaxSection();
}
return EMPTY;
}
return sections[y];
}
}

View File

@@ -0,0 +1,128 @@
package com.volmit.iris.gen.parallax;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import org.bukkit.block.data.BlockData;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.util.CustomOutputStream;
import com.volmit.iris.util.M;
import com.volmit.iris.util.Writable;
public class ParallaxRegion implements Writable
{
private static final ParallaxChunk EMPTY = new ParallaxChunk();
private ParallaxChunk[] chunks;
private transient long last;
public ParallaxRegion(File i) throws IOException
{
this();
if(i.exists())
{
FileInputStream in = new FileInputStream(i);
GZIPInputStream vin = new GZIPInputStream(in);
DataInputStream min = new DataInputStream(vin);
read(min);
min.close();
}
}
public ParallaxRegion(DataInputStream i) throws IOException
{
this();
read(i);
}
public ParallaxRegion()
{
last = M.ms();
chunks = new ParallaxChunk[1024];
}
@Override
public void write(DataOutputStream o) throws IOException
{
int c = 0;
for(ParallaxChunk i : chunks)
{
if(i != null)
{
c++;
}
}
o.writeShort(c);
for(int i = 0; i < 1024; i++)
{
ParallaxChunk ch = chunks[i];
if(ch != null)
{
ch.write(o);
}
}
}
public void write(File file) throws IOException
{
file.getParentFile().mkdirs();
FileOutputStream o = new FileOutputStream(file);
CustomOutputStream g = new CustomOutputStream(o, IrisSettings.get().parallaxCompressionLevel);
DataOutputStream d = new DataOutputStream(g);
write(d);
d.close();
}
@Override
public void read(DataInputStream i) throws IOException
{
int v = i.readShort();
for(int b = 0; b < v; b++)
{
chunks[b] = new ParallaxChunk(i);
}
}
public boolean isOlderThan(long time)
{
return M.ms() - time > last;
}
public void set(int x, int y, int z, BlockData d)
{
getChunk(x >> 4, z >> 4, true).set(x & 15, y, z & 15, d);
}
public BlockData get(int x, int y, int z)
{
return getChunk(x >> 4, z >> 4, false).get(x & 15, y, z & 15);
}
private final ParallaxChunk getChunk(int x, int z, boolean create)
{
last = M.ms();
int v = (z << 5) | x;
if(chunks[v] == null)
{
if(create)
{
chunks[v] = new ParallaxChunk();
}
return EMPTY;
}
return chunks[v];
}
}

View File

@@ -0,0 +1,103 @@
package com.volmit.iris.gen.parallax;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.bukkit.block.data.BlockData;
import com.volmit.iris.util.B;
import com.volmit.iris.util.DataPalette;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.Writable;
public class ParallaxSection implements Writable
{
private final DataPalette<BlockData> block;
private final KSet<Short> updates;
public ParallaxSection(DataInputStream in) throws IOException
{
this();
read(in);
}
public ParallaxSection()
{
updates = new KSet<Short>();
this.block = new DataPalette<BlockData>(B.get("AIR"))
{
@Override
public void writeType(BlockData t, DataOutputStream o) throws IOException
{
o.writeUTF(t.getAsString(true));
}
@Override
public BlockData readType(DataInputStream i) throws IOException
{
return B.get(i.readUTF());
}
};
}
public void clearUpdates()
{
updates.clear();
}
public void update(int x, int y, int z)
{
updates.add((short) (y << 8 | z << 4 | x));
}
public void dontUpdate(int x, int y, int z)
{
updates.remove((short) (y << 8 | z << 4 | x));
}
public void setBlock(int x, int y, int z, BlockData d)
{
block.set(x, y, z, d);
if(B.isUpdatable(d))
{
update(x, y, z);
}
else
{
dontUpdate(x, y, z);
}
}
public BlockData getBlock(int x, int y, int z)
{
return block.get(x, y, z);
}
@Override
public void write(DataOutputStream o) throws IOException
{
block.write(o);
o.writeShort(updates.size());
for(Short i : updates)
{
o.writeShort(i);
}
}
@Override
public void read(DataInputStream i) throws IOException
{
block.read(i);
updates.clear();
int m = i.readShort();
for(int v = 0; v < m; v++)
{
updates.add(i.readShort());
}
}
}

View File

@@ -0,0 +1,121 @@
package com.volmit.iris.gen.parallax;
import java.io.File;
import java.io.IOException;
import org.bukkit.block.data.BlockData;
import com.volmit.iris.Iris;
import com.volmit.iris.util.KMap;
public class ParallaxWorld
{
private final KMap<Long, ParallaxRegion> loadedRegions;
private final File dataFolder;
public ParallaxWorld(File dataFolder)
{
loadedRegions = new KMap<>();
this.dataFolder = dataFolder;
}
public void unloadAll()
{
for(long i : loadedRegions.k())
{
try
{
unload(i);
}
catch(IOException e)
{
Iris.error("Failed to save region " + i);
e.printStackTrace();
}
}
}
public void clean(long time)
{
for(long i : loadedRegions.k())
{
ParallaxRegion r = loadedRegions.get(i);
if(r.isOlderThan(time))
{
try
{
unload(i);
}
catch(IOException e)
{
Iris.error("Failed to save region " + i);
e.printStackTrace();
}
break;
}
}
}
private void unload(long i) throws IOException
{
ParallaxRegion r = loadedRegions.get(i);
r.write(new File(dataFolder, i + ".plx"));
loadedRegions.remove(i);
}
public BlockData getBlock(int x, int y, int z)
{
if(y > 255 || y < 0)
{
throw new IllegalArgumentException(y + " exceeds 0-255");
}
return getRegion(x >> 5, z >> 5).get(x & 511, y, z & 511);
}
public void setBlock(int x, int y, int z, BlockData d)
{
if(d == null)
{
throw new IllegalArgumentException("Block data cannot be null");
}
if(y > 255 || y < 0)
{
throw new IllegalArgumentException(y + " exceeds 0-255");
}
getRegion(x >> 5, z >> 5).set(x & 511, y, z & 511, d);
}
public ParallaxRegion getRegion(int x, int z)
{
Long vb = (((long) x) << 32) | (z & 0xffffffffL);
File ff = new File(dataFolder, vb + ".plx");
return loadedRegions.compute(vb, (k, v) ->
{
if(k == null || v == null)
{
try
{
return new ParallaxRegion(ff);
}
catch(IOException e)
{
Iris.error("Failed to load parallax file: " + ff.getAbsolutePath() + " Assuming empty region!");
ff.deleteOnExit();
ff.delete();
return new ParallaxRegion();
}
}
return v;
});
}
}