mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-29 04:28:21 +01:00
Added palette
This commit is contained in:
parent
00656d96e0
commit
55cddf6b78
@ -42,8 +42,8 @@ public class DynamicChunk extends Chunk {
|
|||||||
private static final int DATA_FORMAT_VERSION = 1;
|
private static final int DATA_FORMAT_VERSION = 1;
|
||||||
|
|
||||||
// WARNING: not thread-safe
|
// WARNING: not thread-safe
|
||||||
protected PaletteStorage blockPalette = new PaletteStorage(15);
|
protected PaletteStorage blockPalette = new PaletteStorage(4);
|
||||||
protected PaletteStorage customBlockPalette = new PaletteStorage(15);
|
protected PaletteStorage customBlockPalette = new PaletteStorage(4);
|
||||||
|
|
||||||
// Used to get all blocks with data (no null)
|
// Used to get all blocks with data (no null)
|
||||||
// Key is still chunk coordinates (see #getBlockIndex)
|
// Key is still chunk coordinates (see #getBlockIndex)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package net.minestom.server.instance.palette;
|
package net.minestom.server.instance.palette;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.shorts.Short2ShortLinkedOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
|
|
||||||
import static net.minestom.server.instance.Chunk.*;
|
import static net.minestom.server.instance.Chunk.*;
|
||||||
@ -7,15 +9,38 @@ import static net.minestom.server.instance.Chunk.*;
|
|||||||
public class PaletteStorage {
|
public class PaletteStorage {
|
||||||
|
|
||||||
private int bitsPerEntry;
|
private int bitsPerEntry;
|
||||||
|
|
||||||
private int valuesPerLong;
|
private int valuesPerLong;
|
||||||
|
|
||||||
private long[][] sectionBlocks = new long[CHUNK_SECTION_COUNT][0];
|
private long[][] sectionBlocks = new long[CHUNK_SECTION_COUNT][0];
|
||||||
|
|
||||||
|
// palette index = block id
|
||||||
|
private Short2ShortLinkedOpenHashMap paletteBlockMap = new Short2ShortLinkedOpenHashMap(CHUNK_SECTION_SIZE, 2);
|
||||||
|
// block id = palette index
|
||||||
|
private Short2ShortOpenHashMap blockPaletteMap = new Short2ShortOpenHashMap(CHUNK_SECTION_SIZE, 2);
|
||||||
|
|
||||||
|
{
|
||||||
|
// Default value
|
||||||
|
this.paletteBlockMap.put((short) 0, (short) 0);
|
||||||
|
this.blockPaletteMap.put((short) 0, (short) 0);
|
||||||
|
}
|
||||||
|
|
||||||
public PaletteStorage(int bitsPerEntry) {
|
public PaletteStorage(int bitsPerEntry) {
|
||||||
this.bitsPerEntry = bitsPerEntry;
|
this.bitsPerEntry = bitsPerEntry;
|
||||||
this.valuesPerLong = Long.SIZE / bitsPerEntry;
|
this.valuesPerLong = Long.SIZE / bitsPerEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private short getPaletteIndex(short blockId) {
|
||||||
|
if (!blockPaletteMap.containsKey(blockId)) {
|
||||||
|
final short paletteIndex = (short) (paletteBlockMap.lastShortKey() + 1);
|
||||||
|
this.paletteBlockMap.put(paletteIndex, blockId);
|
||||||
|
this.blockPaletteMap.put(blockId, paletteIndex);
|
||||||
|
return paletteIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return blockPaletteMap.get(blockId);
|
||||||
|
}
|
||||||
|
|
||||||
public void setBlockAt(int x, int y, int z, short blockId) {
|
public void setBlockAt(int x, int y, int z, short blockId) {
|
||||||
x %= 16;
|
x %= 16;
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
@ -41,6 +66,9 @@ public class PaletteStorage {
|
|||||||
sectionBlocks[section] = new long[getSize()];
|
sectionBlocks[section] = new long[getSize()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Change to palette value
|
||||||
|
blockId = getPaletteIndex(blockId);
|
||||||
|
|
||||||
long[] sectionBlock = sectionBlocks[section];
|
long[] sectionBlock = sectionBlocks[section];
|
||||||
|
|
||||||
long block = sectionBlock[index];
|
long block = sectionBlock[index];
|
||||||
@ -107,6 +135,9 @@ public class PaletteStorage {
|
|||||||
finalValue = value & mask >> bitIndex;
|
finalValue = value & mask >> bitIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Change to palette value
|
||||||
|
final short blockId = paletteBlockMap.get((short) finalValue);
|
||||||
|
|
||||||
//System.out.println("final " + binary(finalValue));
|
//System.out.println("final " + binary(finalValue));
|
||||||
|
|
||||||
|
|
||||||
@ -115,13 +146,12 @@ public class PaletteStorage {
|
|||||||
System.out.println("mask " + binary(mask));
|
System.out.println("mask " + binary(mask));
|
||||||
System.out.println("bin " + binary(blocks[index]));
|
System.out.println("bin " + binary(blocks[index]));
|
||||||
System.out.println("result " + ((blocks[index] >> bitIndex) & mask));*/
|
System.out.println("result " + ((blocks[index] >> bitIndex) & mask));*/
|
||||||
return (short) finalValue;
|
return blockId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getSize() {
|
private int getSize() {
|
||||||
final int blockCount = 16 * 16 * 16; // A whole chunk section
|
final int blockCount = 16 * 16 * 16; // A whole chunk section
|
||||||
final int arraySize = (blockCount + valuesPerLong - 1) / valuesPerLong;
|
final int arraySize = (blockCount + valuesPerLong - 1) / valuesPerLong;
|
||||||
//System.out.println("size " + arraySize);
|
|
||||||
return arraySize;
|
return arraySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +159,10 @@ public class PaletteStorage {
|
|||||||
return bitsPerEntry;
|
return bitsPerEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public short[] getPalette() {
|
||||||
|
return paletteBlockMap.keySet().toShortArray();
|
||||||
|
}
|
||||||
|
|
||||||
public long[][] getSectionBlocks() {
|
public long[][] getSectionBlocks() {
|
||||||
return sectionBlocks;
|
return sectionBlocks;
|
||||||
}
|
}
|
||||||
@ -136,6 +170,8 @@ public class PaletteStorage {
|
|||||||
public PaletteStorage copy() {
|
public PaletteStorage copy() {
|
||||||
PaletteStorage paletteStorage = new PaletteStorage(bitsPerEntry);
|
PaletteStorage paletteStorage = new PaletteStorage(bitsPerEntry);
|
||||||
paletteStorage.sectionBlocks = sectionBlocks.clone();
|
paletteStorage.sectionBlocks = sectionBlocks.clone();
|
||||||
|
paletteStorage.paletteBlockMap.putAll(paletteBlockMap);
|
||||||
|
paletteStorage.blockPaletteMap.putAll(blockPaletteMap);
|
||||||
|
|
||||||
return paletteStorage;
|
return paletteStorage;
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,8 @@ public class ChunkDataPacket implements ServerPacket {
|
|||||||
if (fullChunk || (sections.length == CHUNK_SECTION_COUNT && sections[i] != 0)) {
|
if (fullChunk || (sections.length == CHUNK_SECTION_COUNT && sections[i] != 0)) {
|
||||||
final long[] section = paletteStorage.getSectionBlocks()[i];
|
final long[] section = paletteStorage.getSectionBlocks()[i];
|
||||||
if (section.length > 0) { // section contains at least one block
|
if (section.length > 0) { // section contains at least one block
|
||||||
//if (true) {
|
|
||||||
mask |= 1 << i;
|
mask |= 1 << i;
|
||||||
Utils.writeBlocks(blocks, section, paletteStorage.getBitsPerEntry());
|
Utils.writeBlocks(blocks, paletteStorage.getPalette(), section, paletteStorage.getBitsPerEntry());
|
||||||
} else {
|
} else {
|
||||||
mask |= 0;
|
mask |= 0;
|
||||||
}
|
}
|
||||||
|
@ -116,17 +116,25 @@ public final class Utils {
|
|||||||
70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE,
|
70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE,
|
||||||
0, 5};
|
0, 5};
|
||||||
|
|
||||||
public static void writeBlocks(ByteBuf buffer, long[] blocksId, int bitsPerEntry) {
|
public static void writeBlocks(ByteBuf buffer, short[] palette, long[] blocksId, int bitsPerEntry) {
|
||||||
/*short count = 0;
|
/*short count = 0;
|
||||||
for (short id : blocksId)
|
for (short id : blocksId)
|
||||||
if (id != 0)
|
if (id != 0)
|
||||||
count++;*/
|
count++;*/
|
||||||
|
|
||||||
|
|
||||||
//buffer.writeShort(count);
|
//buffer.writeShort(count);
|
||||||
buffer.writeShort(200);
|
buffer.writeShort(200);
|
||||||
buffer.writeByte((byte) bitsPerEntry);
|
buffer.writeByte((byte) bitsPerEntry);
|
||||||
|
|
||||||
|
// Palette
|
||||||
|
if (bitsPerEntry < 9) {
|
||||||
|
// Palette has to exist
|
||||||
|
writeVarIntBuf(buffer, palette.length);
|
||||||
|
for (short paletteValue : palette) {
|
||||||
|
writeVarIntBuf(buffer, paletteValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final long[] data = blocksId;//encodeBlocksTEST(bitsPerEntry);
|
final long[] data = blocksId;//encodeBlocksTEST(bitsPerEntry);
|
||||||
writeVarIntBuf(buffer, data.length);
|
writeVarIntBuf(buffer, data.length);
|
||||||
for (long datum : data) {
|
for (long datum : data) {
|
||||||
@ -143,8 +151,12 @@ public final class Utils {
|
|||||||
final int arraySize = blockCount / valuesPerLong;
|
final int arraySize = blockCount / valuesPerLong;
|
||||||
|
|
||||||
long[] data = new long[arraySize];
|
long[] data = new long[arraySize];
|
||||||
//data[0] = 0b000000000000001_000000000000001_000000000000001_000000000000001L;
|
data[0] = 0b000000010001L;
|
||||||
//data[1] = 0b000000000000001_000000000000001_000000000000001_000000000000010L;
|
data[1] = 0b000000010001L;
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
|
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
|
||||||
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
|
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
|
||||||
|
@ -47,7 +47,7 @@ public final class ChunkUtils {
|
|||||||
* @return the chunk X or Z based on the argument
|
* @return the chunk X or Z based on the argument
|
||||||
*/
|
*/
|
||||||
public static int getChunkCoordinate(int xz) {
|
public static int getChunkCoordinate(int xz) {
|
||||||
// Assume Chunk.CHUNK_SIZE_X == Chunk.CHUNK_SIZE_Z
|
assert Chunk.CHUNK_SIZE_X == Chunk.CHUNK_SIZE_Z;
|
||||||
return Math.floorDiv(xz, Chunk.CHUNK_SIZE_X);
|
return Math.floorDiv(xz, Chunk.CHUNK_SIZE_X);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import net.minestom.server.instance.Chunk;
|
|||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
import net.minestom.server.instance.InstanceContainer;
|
import net.minestom.server.instance.InstanceContainer;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.block.CustomBlock;
|
||||||
import net.minestom.server.inventory.Inventory;
|
import net.minestom.server.inventory.Inventory;
|
||||||
import net.minestom.server.inventory.InventoryType;
|
import net.minestom.server.inventory.InventoryType;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
@ -124,8 +125,9 @@ public class PlayerInit {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
final short blockStateId = player.getInstance().getBlockStateId(event.getBlockPosition());
|
final short blockStateId = player.getInstance().getBlockStateId(event.getBlockPosition());
|
||||||
|
final CustomBlock customBlock = player.getInstance().getCustomBlock(event.getBlockPosition());
|
||||||
final Block block = Block.fromStateId(blockStateId);
|
final Block block = Block.fromStateId(blockStateId);
|
||||||
player.sendMessage("You clicked at the block " + block);
|
player.sendMessage("You clicked at the block " + block + " " + customBlock);
|
||||||
});
|
});
|
||||||
|
|
||||||
player.addEventCallback(PickupItemEvent.class, event -> {
|
player.addEventCallback(PickupItemEvent.class, event -> {
|
||||||
@ -165,7 +167,7 @@ public class PlayerInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
||||||
player.setGameMode(GameMode.SURVIVAL);
|
player.setGameMode(GameMode.CREATIVE);
|
||||||
if (event.isFirstSpawn()) {
|
if (event.isFirstSpawn()) {
|
||||||
player.teleport(new Position(0, 64f, 0));
|
player.teleport(new Position(0, 64f, 0));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user