mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-30 04:29:05 +00:00
Parallax 2
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
157
src/main/java/com/volmit/iris/gen/parallax/ParallaxChunk.java
Normal file
157
src/main/java/com/volmit/iris/gen/parallax/ParallaxChunk.java
Normal 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];
|
||||
}
|
||||
}
|
||||
128
src/main/java/com/volmit/iris/gen/parallax/ParallaxRegion.java
Normal file
128
src/main/java/com/volmit/iris/gen/parallax/ParallaxRegion.java
Normal 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];
|
||||
}
|
||||
}
|
||||
103
src/main/java/com/volmit/iris/gen/parallax/ParallaxSection.java
Normal file
103
src/main/java/com/volmit/iris/gen/parallax/ParallaxSection.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
121
src/main/java/com/volmit/iris/gen/parallax/ParallaxWorld.java
Normal file
121
src/main/java/com/volmit/iris/gen/parallax/ParallaxWorld.java
Normal 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user