mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Parallax 2
This commit is contained in:
parent
ccc7a947cd
commit
2500fa54e4
@ -8,7 +8,7 @@ import org.bukkit.inventory.Inventory;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.object.InventorySlotType;
|
import com.volmit.iris.object.InventorySlotType;
|
||||||
import com.volmit.iris.object.IrisLootTable;
|
import com.volmit.iris.object.IrisLootTable;
|
||||||
import com.volmit.iris.util.KSet;
|
import com.volmit.iris.util.KList;
|
||||||
import com.volmit.iris.util.MortarCommand;
|
import com.volmit.iris.util.MortarCommand;
|
||||||
import com.volmit.iris.util.MortarSender;
|
import com.volmit.iris.util.MortarSender;
|
||||||
import com.volmit.iris.util.O;
|
import com.volmit.iris.util.O;
|
||||||
@ -30,9 +30,9 @@ public class CommandIrisLoot extends MortarCommand
|
|||||||
if(sender.isPlayer())
|
if(sender.isPlayer())
|
||||||
{
|
{
|
||||||
Player p = sender.player();
|
Player p = sender.player();
|
||||||
KSet<IrisLootTable> tables = Iris.proj.getCurrentProject().getGlUpdate().getLootTables(p.getLocation().getBlock());
|
KList<IrisLootTable> tables = Iris.proj.getCurrentProject().getGlUpdate().getLootTables(RNG.r, p.getLocation().getBlock());
|
||||||
Inventory inv = Bukkit.createInventory(null, 27 * 2);
|
Inventory inv = Bukkit.createInventory(null, 27 * 2);
|
||||||
Iris.proj.getCurrentProject().getGlUpdate().addItems(true, inv, RNG.r, tables, InventorySlotType.STORAGE, p.getLocation().getBlockX(), p.getLocation().getBlockY(), p.getLocation().getBlockZ());
|
Iris.proj.getCurrentProject().getGlUpdate().addItems(true, inv, RNG.r, tables, InventorySlotType.STORAGE, p.getLocation().getBlockX(), p.getLocation().getBlockY(), p.getLocation().getBlockZ(), 1);
|
||||||
p.openInventory(inv);
|
p.openInventory(inv);
|
||||||
|
|
||||||
for(IrisLootTable i : tables)
|
for(IrisLootTable i : tables)
|
||||||
@ -74,7 +74,7 @@ public class CommandIrisLoot extends MortarCommand
|
|||||||
inv.clear();
|
inv.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Iris.proj.getCurrentProject().getGlUpdate().addItems(true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, p.getLocation().getBlockX(), p.getLocation().getBlockY(), p.getLocation().getBlockZ());
|
Iris.proj.getCurrentProject().getGlUpdate().addItems(true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, p.getLocation().getBlockX(), p.getLocation().getBlockY(), p.getLocation().getBlockZ(), 1);
|
||||||
}, 0, fast ? 5 : 35));
|
}, 0, fast ? 5 : 35));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -17,7 +17,6 @@ import com.volmit.iris.object.IrisBiomeMutation;
|
|||||||
import com.volmit.iris.object.IrisObjectPlacement;
|
import com.volmit.iris.object.IrisObjectPlacement;
|
||||||
import com.volmit.iris.object.IrisRegion;
|
import com.volmit.iris.object.IrisRegion;
|
||||||
import com.volmit.iris.object.IrisStructurePlacement;
|
import com.volmit.iris.object.IrisStructurePlacement;
|
||||||
import com.volmit.iris.object.TileResult;
|
|
||||||
import com.volmit.iris.util.BiomeMap;
|
import com.volmit.iris.util.BiomeMap;
|
||||||
import com.volmit.iris.util.CaveResult;
|
import com.volmit.iris.util.CaveResult;
|
||||||
import com.volmit.iris.util.ChunkPosition;
|
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.IrisStructureResult;
|
||||||
import com.volmit.iris.util.KList;
|
import com.volmit.iris.util.KList;
|
||||||
import com.volmit.iris.util.KMap;
|
import com.volmit.iris.util.KMap;
|
||||||
|
import com.volmit.iris.util.NBTInputStream;
|
||||||
import com.volmit.iris.util.NastyRunnable;
|
import com.volmit.iris.util.NastyRunnable;
|
||||||
import com.volmit.iris.util.PrecisionStopwatch;
|
import com.volmit.iris.util.PrecisionStopwatch;
|
||||||
import com.volmit.iris.util.RNG;
|
import com.volmit.iris.util.RNG;
|
||||||
@ -106,7 +106,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
|
|||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
NBTInputStream
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,61 +218,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
|
|||||||
|
|
||||||
public IrisStructureResult getStructure(int x, int y, int z)
|
public IrisStructureResult getStructure(int x, int y, int z)
|
||||||
{
|
{
|
||||||
IrisBiome b = sampleTrueBiome(x, z).getBiome();
|
return getParallaxChunk(x >> 4, z >> 4).getStructure(this, y);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onGenerateParallax(RNG random, int x, int z)
|
protected void onGenerateParallax(RNG random, int x, int z)
|
||||||
|
@ -25,24 +25,24 @@ import lombok.Data;
|
|||||||
public class AtomicSliver
|
public class AtomicSliver
|
||||||
{
|
{
|
||||||
public static final BlockData AIR = B.getBlockData("AIR");
|
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, BlockData> block;
|
||||||
private KMap<Integer, IrisBiome> truebiome;
|
private KSet<Integer> blockUpdates;
|
||||||
private KMap<Integer, Biome> biome;
|
|
||||||
private KSet<Integer> update;
|
|
||||||
private IrisLock lock = new IrisLock("Sliver");
|
|
||||||
private int highestBlock = 0;
|
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)
|
public AtomicSliver(int x, int z)
|
||||||
{
|
{
|
||||||
lock.setDisabled(true);
|
lock.setDisabled(true);
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
update = new KSet<>();
|
blockUpdates = new KSet<>();
|
||||||
this.block = new KMap<>();
|
this.block = new KMap<>();
|
||||||
this.biome = new KMap<>();
|
this.biome = new KMap<>();
|
||||||
this.truebiome = new KMap<>();
|
this.truebiome = new KMap<>();
|
||||||
@ -55,17 +55,17 @@ public class AtomicSliver
|
|||||||
|
|
||||||
public KSet<Integer> getUpdatables()
|
public KSet<Integer> getUpdatables()
|
||||||
{
|
{
|
||||||
return update;
|
return blockUpdates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(int y)
|
public void update(int y)
|
||||||
{
|
{
|
||||||
update.add(y);
|
blockUpdates.add(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dontUpdate(int y)
|
public void dontUpdate(int y)
|
||||||
{
|
{
|
||||||
update.remove(y);
|
blockUpdates.remove(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockData get(int h)
|
public BlockData get(int h)
|
||||||
@ -81,6 +81,19 @@ public class AtomicSliver
|
|||||||
return b;
|
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)
|
public void set(int h, BlockData d)
|
||||||
{
|
{
|
||||||
setSilently(h, d);
|
setSilently(h, d);
|
||||||
@ -190,6 +203,8 @@ public class AtomicSliver
|
|||||||
{
|
{
|
||||||
lock.lock();
|
lock.lock();
|
||||||
this.block = new KMap<Integer, BlockData>();
|
this.block = new KMap<Integer, BlockData>();
|
||||||
|
|
||||||
|
// Block Palette
|
||||||
int h = din.readByte() - Byte.MIN_VALUE;
|
int h = din.readByte() - Byte.MIN_VALUE;
|
||||||
int p = din.readByte() - Byte.MIN_VALUE;
|
int p = din.readByte() - Byte.MIN_VALUE;
|
||||||
int u = 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()));
|
palette.add(B.getBlockData(din.readUTF()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Blocks
|
||||||
for(int i = 0; i <= h; i++)
|
for(int i = 0; i <= h; i++)
|
||||||
{
|
{
|
||||||
block.put(i, palette.get(din.readByte() - Byte.MIN_VALUE).clone());
|
block.put(i, palette.get(din.readByte() - Byte.MIN_VALUE).clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Updates
|
||||||
for(int i = 0; i <= u; i++)
|
for(int i = 0; i <= u; i++)
|
||||||
{
|
{
|
||||||
update(din.readByte() - Byte.MIN_VALUE);
|
update(din.readByte() - Byte.MIN_VALUE);
|
||||||
@ -220,6 +237,8 @@ public class AtomicSliver
|
|||||||
{
|
{
|
||||||
lock.lock();
|
lock.lock();
|
||||||
dos.writeByte(highestBlock + Byte.MIN_VALUE);
|
dos.writeByte(highestBlock + Byte.MIN_VALUE);
|
||||||
|
|
||||||
|
// Block Palette
|
||||||
KList<String> palette = new KList<>();
|
KList<String> palette = new KList<>();
|
||||||
|
|
||||||
for(int i = 0; i <= highestBlock; i++)
|
for(int i = 0; i <= highestBlock; i++)
|
||||||
@ -234,13 +253,14 @@ public class AtomicSliver
|
|||||||
}
|
}
|
||||||
|
|
||||||
dos.writeByte(palette.size() + Byte.MIN_VALUE);
|
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)
|
for(String i : palette)
|
||||||
{
|
{
|
||||||
dos.writeUTF(i);
|
dos.writeUTF(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Blocks
|
||||||
for(int i = 0; i <= highestBlock; i++)
|
for(int i = 0; i <= highestBlock; i++)
|
||||||
{
|
{
|
||||||
BlockData dat = block.get(i);
|
BlockData dat = block.get(i);
|
||||||
@ -248,6 +268,7 @@ public class AtomicSliver
|
|||||||
dos.writeByte(palette.indexOf(d) + Byte.MIN_VALUE);
|
dos.writeByte(palette.indexOf(d) + Byte.MIN_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Updates
|
||||||
for(Integer i : getUpdatables())
|
for(Integer i : getUpdatables())
|
||||||
{
|
{
|
||||||
dos.writeByte(i + Byte.MIN_VALUE);
|
dos.writeByte(i + Byte.MIN_VALUE);
|
||||||
@ -296,6 +317,6 @@ public class AtomicSliver
|
|||||||
|
|
||||||
public void inject(KSet<Integer> updatables)
|
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.BiomeGrid;
|
||||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
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.HeightMap;
|
||||||
|
import com.volmit.iris.util.IrisStructureResult;
|
||||||
|
import com.volmit.iris.util.KList;
|
||||||
|
import com.volmit.iris.util.KMap;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@ -17,11 +23,13 @@ import lombok.Data;
|
|||||||
public class AtomicSliverMap
|
public class AtomicSliverMap
|
||||||
{
|
{
|
||||||
private final AtomicSliver[] slivers;
|
private final AtomicSliver[] slivers;
|
||||||
|
private KMap<Integer, String> structures;
|
||||||
private boolean parallaxGenerated;
|
private boolean parallaxGenerated;
|
||||||
private boolean worldGenerated;
|
private boolean worldGenerated;
|
||||||
|
|
||||||
public AtomicSliverMap()
|
public AtomicSliverMap()
|
||||||
{
|
{
|
||||||
|
structures = new KMap<>();
|
||||||
parallaxGenerated = false;
|
parallaxGenerated = false;
|
||||||
worldGenerated = false;
|
worldGenerated = false;
|
||||||
slivers = new AtomicSliver[256];
|
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
|
public void write(OutputStream out) throws IOException
|
||||||
{
|
{
|
||||||
DataOutputStream dos = new DataOutputStream(out);
|
DataOutputStream dos = new DataOutputStream(out);
|
||||||
@ -53,6 +87,33 @@ public class AtomicSliverMap
|
|||||||
slivers[i].write(dos);
|
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();
|
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)
|
public AtomicSliver getSliver(int x, int z)
|
||||||
@ -122,7 +198,7 @@ public class AtomicSliverMap
|
|||||||
for(int j = 0; j < 16; j++)
|
for(int j = 0; j < 16; j++)
|
||||||
{
|
{
|
||||||
getSliver(i, j).inject(map.getSliver(i, j).getUpdatables());
|
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.B;
|
||||||
import com.volmit.iris.util.IrisStructureResult;
|
import com.volmit.iris.util.IrisStructureResult;
|
||||||
import com.volmit.iris.util.KList;
|
import com.volmit.iris.util.KList;
|
||||||
import com.volmit.iris.util.KSet;
|
|
||||||
import com.volmit.iris.util.PrecisionStopwatch;
|
import com.volmit.iris.util.PrecisionStopwatch;
|
||||||
import com.volmit.iris.util.RNG;
|
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))
|
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));
|
list.addAll(r.getLootTables(gen));
|
||||||
}
|
}
|
||||||
|
|
||||||
public KSet<IrisLootTable> getLootTables(Block b)
|
public KList<IrisLootTable> getLootTables(RNG rng, Block b)
|
||||||
{
|
{
|
||||||
int rx = b.getX();
|
int rx = b.getX();
|
||||||
int rz = b.getZ();
|
int rz = b.getZ();
|
||||||
IrisRegion region = gen.sampleRegion(rx, rz);
|
IrisRegion region = gen.sampleRegion(rx, rz);
|
||||||
IrisBiome biomeSurface = gen.sampleTrueBiome(rx, rz).getBiome();
|
IrisBiome biomeSurface = gen.sampleTrueBiome(rx, rz).getBiome();
|
||||||
IrisBiome biomeUnder = gen.sampleTrueBiome(rx, b.getY(), 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);
|
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, gen.getDimension().getLoot());
|
||||||
injectTables(tables, region.getLoot());
|
injectTables(tables, region.getLoot());
|
||||||
injectTables(tables, biomeSurface.getLoot());
|
injectTables(tables, biomeSurface.getLoot());
|
||||||
@ -109,20 +109,38 @@ public class GenLayerUpdate extends BlockPopulator
|
|||||||
{
|
{
|
||||||
injectTables(tables, structure.getStructure().getLoot());
|
injectTables(tables, structure.getStructure().getLoot());
|
||||||
injectTables(tables, structure.getTile().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;
|
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<>();
|
KList<ItemStack> items = new KList<>();
|
||||||
|
|
||||||
for(int t = 0; t < gen.getDimension().getLootTries(); t++)
|
for(int t = 0; t < gen.getDimension().getLootTries(); t++)
|
||||||
{
|
{
|
||||||
|
int b = 4;
|
||||||
for(IrisLootTable i : tables)
|
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)
|
for(ItemStack i : items)
|
||||||
@ -135,6 +153,8 @@ public class GenLayerUpdate extends BlockPopulator
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scramble(inv, rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateStorage(Block b, BlockData data, int rx, int rz, RNG 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)
|
if(slot != null)
|
||||||
{
|
{
|
||||||
KSet<IrisLootTable> tables = getLootTables(b);
|
KList<IrisLootTable> tables = getLootTables(rng.nextParallelRNG(4568111), b);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
InventoryHolder m = (InventoryHolder) b.getState();
|
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)
|
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)
|
public void updateLight(Block b, BlockData data)
|
||||||
{
|
{
|
||||||
b.setType(Material.AIR, false);
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import com.volmit.iris.util.ArrayType;
|
|||||||
import com.volmit.iris.util.Desc;
|
import com.volmit.iris.util.Desc;
|
||||||
import com.volmit.iris.util.DontObfuscate;
|
import com.volmit.iris.util.DontObfuscate;
|
||||||
import com.volmit.iris.util.KList;
|
import com.volmit.iris.util.KList;
|
||||||
|
import com.volmit.iris.util.MinNumber;
|
||||||
import com.volmit.iris.util.RegistryListLoot;
|
import com.volmit.iris.util.RegistryListLoot;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -24,6 +25,11 @@ public class IrisLootReference
|
|||||||
@Desc("Add loot table registries here")
|
@Desc("Add loot table registries here")
|
||||||
private KList<String> tables = new KList<>();
|
private KList<String> tables = new KList<>();
|
||||||
|
|
||||||
|
@MinNumber(0)
|
||||||
|
@DontObfuscate
|
||||||
|
@Desc("Increase the chance of loot in this area")
|
||||||
|
private double multiplier = 1D;
|
||||||
|
|
||||||
private transient AtomicCache<KList<IrisLootTable>> tt = new AtomicCache<>();
|
private transient AtomicCache<KList<IrisLootTable>> tt = new AtomicCache<>();
|
||||||
|
|
||||||
public IrisLootReference()
|
public IrisLootReference()
|
||||||
|
@ -27,12 +27,17 @@ public class IrisLootTable extends IrisRegistrant
|
|||||||
@Desc("The rarity as in 1 in X chance")
|
@Desc("The rarity as in 1 in X chance")
|
||||||
private int rarity = 1;
|
private int rarity = 1;
|
||||||
|
|
||||||
|
@MinNumber(1)
|
||||||
|
@DontObfuscate
|
||||||
|
@Desc("The maximum amount of loot that can be picked in this table at a time.")
|
||||||
|
private int maxPicked = 3;
|
||||||
|
|
||||||
@DontObfuscate
|
@DontObfuscate
|
||||||
@Desc("The loot in this table")
|
@Desc("The loot in this table")
|
||||||
@ArrayType(min = 1, type = IrisLoot.class)
|
@ArrayType(min = 1, type = IrisLoot.class)
|
||||||
private KList<IrisLoot> loot = new KList<>();
|
private KList<IrisLoot> loot = new KList<>();
|
||||||
|
|
||||||
public KList<ItemStack> getLoot(boolean debug, RNG rng, InventorySlotType slot, int x, int y, int z)
|
public KList<ItemStack> getLoot(boolean debug, RNG rng, InventorySlotType slot, int x, int y, int z, int gg, int ffs)
|
||||||
{
|
{
|
||||||
KList<ItemStack> lootf = new KList<>();
|
KList<ItemStack> lootf = new KList<>();
|
||||||
|
|
||||||
@ -42,7 +47,7 @@ public class IrisLootTable extends IrisRegistrant
|
|||||||
{
|
{
|
||||||
if(i.getSlotTypes().equals(slot))
|
if(i.getSlotTypes().equals(slot))
|
||||||
{
|
{
|
||||||
ItemStack item = i.get(debug, this, rng.nextParallelRNG(294788 + x + y - z * z + (m * -4125)), x, y, z);
|
ItemStack item = i.get(debug, this, rng, x, y, z);
|
||||||
|
|
||||||
if(item != null)
|
if(item != null)
|
||||||
{
|
{
|
||||||
@ -51,6 +56,11 @@ public class IrisLootTable extends IrisRegistrant
|
|||||||
}
|
}
|
||||||
|
|
||||||
m++;
|
m++;
|
||||||
|
|
||||||
|
if(m > maxPicked)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lootf;
|
return lootf;
|
||||||
|
@ -8,6 +8,7 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -17,6 +18,7 @@ import org.bukkit.block.data.type.Leaves;
|
|||||||
import org.bukkit.util.BlockVector;
|
import org.bukkit.util.BlockVector;
|
||||||
|
|
||||||
import com.volmit.iris.util.B;
|
import com.volmit.iris.util.B;
|
||||||
|
import com.volmit.iris.util.BlockPosition;
|
||||||
import com.volmit.iris.util.ChunkPosition;
|
import com.volmit.iris.util.ChunkPosition;
|
||||||
import com.volmit.iris.util.IObjectPlacer;
|
import com.volmit.iris.util.IObjectPlacer;
|
||||||
import com.volmit.iris.util.KMap;
|
import com.volmit.iris.util.KMap;
|
||||||
@ -127,7 +129,12 @@ public class IrisObject extends IrisRegistrant
|
|||||||
place(x, -1, z, placer, config, rng);
|
place(x, -1, z, placer, config, rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng)
|
public int place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng)
|
||||||
|
{
|
||||||
|
return place(x, yv, z, placer, config, rng, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, Consumer<BlockPosition> listener)
|
||||||
{
|
{
|
||||||
int spinx = rng.imax() / 1000;
|
int spinx = rng.imax() / 1000;
|
||||||
int spiny = rng.imax() / 1000;
|
int spiny = rng.imax() / 1000;
|
||||||
@ -135,7 +142,6 @@ public class IrisObject extends IrisRegistrant
|
|||||||
int rty = config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY();
|
int rty = config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY();
|
||||||
int ty = config.getTranslate().translate(new BlockVector(0, getCenter().getBlockY(), 0), config.getRotation(), spinx, spiny, spinz).getBlockY();
|
int ty = config.getTranslate().translate(new BlockVector(0, getCenter().getBlockY(), 0), config.getRotation(), spinx, spiny, spinz).getBlockY();
|
||||||
int y = -1;
|
int y = -1;
|
||||||
KMap<ChunkPosition, Integer> paintmap = null;
|
|
||||||
|
|
||||||
if(yv < 0)
|
if(yv < 0)
|
||||||
{
|
{
|
||||||
@ -233,7 +239,6 @@ public class IrisObject extends IrisRegistrant
|
|||||||
else if(config.getMode().equals(ObjectPlaceMode.PAINT))
|
else if(config.getMode().equals(ObjectPlaceMode.PAINT))
|
||||||
{
|
{
|
||||||
y = placer.getHighest(x, z, config.isUnderwater()) + rty;
|
y = placer.getHighest(x, z, config.isUnderwater()) + rty;
|
||||||
paintmap = new KMap<>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,18 +258,18 @@ public class IrisObject extends IrisRegistrant
|
|||||||
{
|
{
|
||||||
if(!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z))
|
if(!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z))
|
||||||
{
|
{
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(config.isUnderwater() && y + rty + ty >= placer.getFluidHeight())
|
if(config.isUnderwater() && y + rty + ty >= placer.getFluidHeight())
|
||||||
{
|
{
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!config.getClamp().canPlace(y + rty + ty, y - rty + ty))
|
if(!config.getClamp().canPlace(y + rty + ty, y - rty + ty))
|
||||||
{
|
{
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(config.isBore())
|
if(config.isBore())
|
||||||
@ -309,17 +314,9 @@ public class IrisObject extends IrisRegistrant
|
|||||||
int yy = y + (int) Math.round(i.getY());
|
int yy = y + (int) Math.round(i.getY());
|
||||||
int zz = z + (int) Math.round(i.getZ());
|
int zz = z + (int) Math.round(i.getZ());
|
||||||
|
|
||||||
if(config.getMode().equals(ObjectPlaceMode.PAINT))
|
if(yv < 0 && config.getMode().equals(ObjectPlaceMode.PAINT))
|
||||||
{
|
{
|
||||||
yy = (int) Math.round(i.getY()) + Math.floorDiv(h, 2) + paintmap.compute(new ChunkPosition(xx, zz), (k, v) ->
|
yy = (int) Math.round(i.getY()) + Math.floorDiv(h, 2) + placer.getHighest(xx, zz, config.isUnderwater());
|
||||||
{
|
|
||||||
if(k == null || v == null)
|
|
||||||
{
|
|
||||||
return placer.getHighest(xx, zz, config.isUnderwater());
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(heightmap != null)
|
if(heightmap != null)
|
||||||
@ -347,6 +344,11 @@ public class IrisObject extends IrisRegistrant
|
|||||||
((Waterlogged) data).setWaterlogged(true);
|
((Waterlogged) data).setWaterlogged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(listener != null)
|
||||||
|
{
|
||||||
|
listener.accept(new BlockPosition(xx, yy, zz));
|
||||||
|
}
|
||||||
|
|
||||||
placer.set(xx, yy, zz, data);
|
placer.set(xx, yy, zz, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,6 +375,8 @@ public class IrisObject extends IrisRegistrant
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void place(Location at)
|
public void place(Location at)
|
||||||
|
@ -147,7 +147,7 @@ public class IrisStructurePlacement
|
|||||||
}
|
}
|
||||||
|
|
||||||
o = o != null ? o : load(g, t.getTile().getObjects().get(rnp.nextInt(t.getTile().getObjects().size())));
|
o = o != null ? o : load(g, t.getTile().getObjects().get(rnp.nextInt(t.getTile().getObjects().size())));
|
||||||
o.place(Math.floorDiv(i, s) * s, height == -1 ? -1 : h, Math.floorDiv(j, s) * s, g, t.getPlacement(), rng);
|
o.place(Math.floorDiv(i, s) * s, height == -1 ? -1 : h, Math.floorDiv(j, s) * s, g, t.getPlacement(), rng, (gg) -> g.getParallaxChunk(gg.getChunkX(), gg.getChunkZ()).setStructure(gg.getY(), t.getStructure(), t.getTile()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,6 @@ public class IrisStructureTile
|
|||||||
private KList<String> objects = new KList<>();
|
private KList<String> objects = new KList<>();
|
||||||
|
|
||||||
@RegistryListObject
|
@RegistryListObject
|
||||||
@Required
|
|
||||||
@ArrayType(min = 1, type = IrisRareObject.class)
|
@ArrayType(min = 1, type = IrisRareObject.class)
|
||||||
@DontObfuscate
|
@DontObfuscate
|
||||||
@Desc("List of objects to place centered in this tile but with rarity. These items only place some of the time so specify objects for common stuff too.")
|
@Desc("List of objects to place centered in this tile but with rarity. These items only place some of the time so specify objects for common stuff too.")
|
||||||
|
125
src/main/java/com/volmit/iris/util/DataPalette.java
Normal file
125
src/main/java/com/volmit/iris/util/DataPalette.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package com.volmit.iris.util;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public abstract class DataPalette<T> implements Writable
|
||||||
|
{
|
||||||
|
private static final int DEFAULT_BITS_PER_BLOCK = 4;
|
||||||
|
private static final int CAPACITY = 4096;
|
||||||
|
private int bpb;
|
||||||
|
private NibbleArray data;
|
||||||
|
private KList<T> palette;
|
||||||
|
|
||||||
|
public DataPalette(T defaultValue)
|
||||||
|
{
|
||||||
|
palette = new KList<>();
|
||||||
|
bpb = DEFAULT_BITS_PER_BLOCK;
|
||||||
|
data = new NibbleArray(bpb, CAPACITY);
|
||||||
|
data.setAll(Byte.MIN_VALUE);
|
||||||
|
getPaletteId(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract T readType(DataInputStream i) throws IOException;
|
||||||
|
|
||||||
|
public abstract void writeType(T t, DataOutputStream o) throws IOException;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream o) throws IOException
|
||||||
|
{
|
||||||
|
o.writeByte(bpb + Byte.MIN_VALUE);
|
||||||
|
o.writeByte(palette.size() + Byte.MIN_VALUE);
|
||||||
|
|
||||||
|
for(T i : palette)
|
||||||
|
{
|
||||||
|
writeType(i, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
data.write(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInputStream i) throws IOException
|
||||||
|
{
|
||||||
|
bpb = i.readByte() - Byte.MIN_VALUE;
|
||||||
|
palette = new KList<>();
|
||||||
|
int v = i.readByte() - Byte.MIN_VALUE;
|
||||||
|
|
||||||
|
for(int j = 0; j < v; j++)
|
||||||
|
{
|
||||||
|
palette.add(readType(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
data = new NibbleArray(CAPACITY, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void expand()
|
||||||
|
{
|
||||||
|
if(bpb < 8)
|
||||||
|
{
|
||||||
|
changeBitsPerBlock(bpb + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException("The Data Palette can only handle at most 256 block types per 16x16x16 region. We cannot use more than 8 bits per block!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void optimize()
|
||||||
|
{
|
||||||
|
int targetBits = bpb;
|
||||||
|
int needed = palette.size();
|
||||||
|
|
||||||
|
for(int i = 1; i < bpb; i++)
|
||||||
|
{
|
||||||
|
if(Math.pow(2, i) > needed)
|
||||||
|
{
|
||||||
|
targetBits = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changeBitsPerBlock(targetBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void changeBitsPerBlock(int bits)
|
||||||
|
{
|
||||||
|
bpb = bits;
|
||||||
|
data = new NibbleArray(bpb, CAPACITY, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void set(int x, int y, int z, T d)
|
||||||
|
{
|
||||||
|
data.set(getCoordinateIndex(x, y, z), getPaletteId(d));
|
||||||
|
}
|
||||||
|
|
||||||
|
public final T get(int x, int y, int z)
|
||||||
|
{
|
||||||
|
return palette.get(data.get(getCoordinateIndex(x, y, z)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int getPaletteId(T d)
|
||||||
|
{
|
||||||
|
int index = palette.indexOf(d);
|
||||||
|
|
||||||
|
if(index == -1)
|
||||||
|
{
|
||||||
|
index = palette.size();
|
||||||
|
palette.add(d);
|
||||||
|
|
||||||
|
if(palette.size() > Math.pow(2, bpb))
|
||||||
|
{
|
||||||
|
expand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return index + Byte.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int getCoordinateIndex(int x, int y, int z)
|
||||||
|
{
|
||||||
|
return y << 8 | z << 4 | x;
|
||||||
|
}
|
||||||
|
}
|
212
src/main/java/com/volmit/iris/util/NibbleArray.java
Normal file
212
src/main/java/com/volmit/iris/util/NibbleArray.java
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
package com.volmit.iris.util;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
public class NibbleArray implements Writable
|
||||||
|
{
|
||||||
|
private byte[] data;
|
||||||
|
private int depth;
|
||||||
|
private final int size;
|
||||||
|
private byte mask;
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
public NibbleArray(int capacity, DataInputStream in) throws IOException
|
||||||
|
{
|
||||||
|
size = capacity;
|
||||||
|
read(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NibbleArray(int nibbleDepth, int capacity)
|
||||||
|
{
|
||||||
|
if(nibbleDepth > 8 || nibbleDepth < 1)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
int neededBits = nibbleDepth * capacity;
|
||||||
|
|
||||||
|
size = capacity;
|
||||||
|
depth = nibbleDepth;
|
||||||
|
data = new byte[(neededBits + neededBits % 8) / 8];
|
||||||
|
mask = (byte) maskFor(nibbleDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NibbleArray(int nibbleDepth, int capacity, NibbleArray existing)
|
||||||
|
{
|
||||||
|
if(nibbleDepth > 8 || nibbleDepth < 1)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
int neededBits = nibbleDepth * capacity;
|
||||||
|
size = capacity;
|
||||||
|
depth = nibbleDepth;
|
||||||
|
data = new byte[(neededBits + neededBits % 8) / 8];
|
||||||
|
mask = (byte) maskFor(nibbleDepth);
|
||||||
|
|
||||||
|
for(int i = 0; i < Math.min(size, existing.size()); i++)
|
||||||
|
{
|
||||||
|
set(i, existing.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream o) throws IOException
|
||||||
|
{
|
||||||
|
o.writeByte(depth + Byte.MIN_VALUE);
|
||||||
|
o.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInputStream i) throws IOException
|
||||||
|
{
|
||||||
|
depth = i.readByte() - Byte.MIN_VALUE;
|
||||||
|
int neededBits = depth * size;
|
||||||
|
data = new byte[(neededBits + neededBits % 8) / 8];
|
||||||
|
mask = (byte) maskFor(depth);
|
||||||
|
i.read(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte get(int index)
|
||||||
|
{
|
||||||
|
synchronized(lock)
|
||||||
|
{
|
||||||
|
bitIndex = index * depth;
|
||||||
|
byteIndex = bitIndex >> 3;
|
||||||
|
bitInByte = bitIndex & 7;
|
||||||
|
int value = data[byteIndex] >> bitInByte;
|
||||||
|
|
||||||
|
if(bitInByte + depth > 8)
|
||||||
|
{
|
||||||
|
value |= data[byteIndex + 1] << bitInByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte) (value & mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getAsync(int index)
|
||||||
|
{
|
||||||
|
int bitIndex = index * depth;
|
||||||
|
int byteIndex = bitIndex >> 3;
|
||||||
|
int bitInByte = bitIndex & 7;
|
||||||
|
int value = data[byteIndex] >> bitInByte;
|
||||||
|
|
||||||
|
if(bitInByte + depth > 8)
|
||||||
|
{
|
||||||
|
value |= data[byteIndex + 1] << bitInByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte) (value & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private transient int bitIndex, byteIndex, bitInByte;
|
||||||
|
|
||||||
|
public void set(int index, int nibble)
|
||||||
|
{
|
||||||
|
set(index, (byte) nibble);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(int index, byte nybble)
|
||||||
|
{
|
||||||
|
synchronized(lock)
|
||||||
|
{
|
||||||
|
bitIndex = index * depth;
|
||||||
|
byteIndex = bitIndex >> 3;
|
||||||
|
bitInByte = bitIndex & 7;
|
||||||
|
data[byteIndex] = (byte) (((~(data[byteIndex] & (mask << bitInByte)) & data[byteIndex]) | ((nybble & mask) << bitInByte)) & 0xff);
|
||||||
|
|
||||||
|
if(bitInByte + depth > 8)
|
||||||
|
{
|
||||||
|
data[byteIndex + 1] = (byte) (((~(data[byteIndex + 1] & MASKS[bitInByte + depth - 8]) & data[byteIndex + 1]) | ((nybble & mask) >> (8 - bitInByte))) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toBitsString()
|
||||||
|
{
|
||||||
|
return toBitsString(ByteOrder.BIG_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toBitsString(ByteOrder byteOrder)
|
||||||
|
{
|
||||||
|
StringJoiner joiner = new StringJoiner(" ");
|
||||||
|
|
||||||
|
for(int i = 0; i < data.length; i++)
|
||||||
|
{
|
||||||
|
joiner.add(binaryString(data[i], byteOrder));
|
||||||
|
}
|
||||||
|
|
||||||
|
return joiner.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
Arrays.fill(data, (byte) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAll(byte nibble)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
set(i, nibble);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAll(int nibble)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
set(i, (byte) nibble);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int maskFor(int amountOfBits)
|
||||||
|
{
|
||||||
|
return powerOfTwo(amountOfBits) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int powerOfTwo(int power)
|
||||||
|
{
|
||||||
|
int result = 1;
|
||||||
|
|
||||||
|
for(int i = 0; i < power; i++)
|
||||||
|
{
|
||||||
|
result *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int[] MASKS = new int[8];
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
for(int i = 0; i < MASKS.length; i++)
|
||||||
|
{
|
||||||
|
MASKS[i] = maskFor(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String binaryString(byte b, ByteOrder byteOrder)
|
||||||
|
{
|
||||||
|
String str = String.format("%8s", Integer.toBinaryString(b & 0xff)).replace(' ', '0');
|
||||||
|
|
||||||
|
return byteOrder.equals(ByteOrder.BIG_ENDIAN) ? str : reverse(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String reverse(String str)
|
||||||
|
{
|
||||||
|
return new StringBuilder(str).reverse().toString();
|
||||||
|
}
|
||||||
|
}
|
12
src/main/java/com/volmit/iris/util/Writable.java
Normal file
12
src/main/java/com/volmit/iris/util/Writable.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package com.volmit.iris.util;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface Writable
|
||||||
|
{
|
||||||
|
public void write(DataOutputStream o) throws IOException;
|
||||||
|
|
||||||
|
public void read(DataInputStream i) throws IOException;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user