mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-22 18:15:39 +01:00
Fix biome palette writing
Co-authored-by: Gerrygames <gecam59@gmail.com>
This commit is contained in:
parent
3feff8e751
commit
e744214ad6
@ -31,6 +31,11 @@ public interface ChunkSection {
|
||||
*/
|
||||
int SIZE = 16 * 16 * 16; // width * depth * height
|
||||
|
||||
/**
|
||||
* Size (dimensions) of biomes in a chunks section.
|
||||
*/
|
||||
int BIOME_SIZE = 4 * 4 * 4;
|
||||
|
||||
static int index(int x, int y, int z) {
|
||||
return y << 8 | z << 4 | x;
|
||||
}
|
||||
|
@ -36,14 +36,14 @@ public class ChunkSectionImpl implements ChunkSection {
|
||||
}
|
||||
|
||||
public ChunkSectionImpl(final boolean holdsLight) {
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl());
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE));
|
||||
if (holdsLight) {
|
||||
this.light = new ChunkSectionLightImpl();
|
||||
}
|
||||
}
|
||||
|
||||
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(expectedPaletteLength));
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE, expectedPaletteLength));
|
||||
if (holdsLight) {
|
||||
this.light = new ChunkSectionLightImpl();
|
||||
}
|
||||
|
@ -24,11 +24,21 @@ package com.viaversion.viaversion.api.minecraft.chunks;
|
||||
|
||||
public interface DataPalette {
|
||||
|
||||
/**
|
||||
* Returns the packet section index of the given coordinates.
|
||||
*
|
||||
* @param x x
|
||||
* @param y y
|
||||
* @param z z
|
||||
* @return packed section index of the given coordinates
|
||||
*/
|
||||
int index(final int x, final int y, final int z);
|
||||
|
||||
/**
|
||||
* Returns the value of the given chunk coordinate.
|
||||
*
|
||||
* @param sectionCoordinate block index within the section
|
||||
* @return block state of the given index
|
||||
* @param sectionCoordinate section index within the section
|
||||
* @return section state of the given index
|
||||
*/
|
||||
int idAt(int sectionCoordinate);
|
||||
|
||||
@ -38,17 +48,17 @@ public interface DataPalette {
|
||||
* @param sectionX section x
|
||||
* @param sectionY section y
|
||||
* @param sectionZ section z
|
||||
* @return block state of the given section coordinate
|
||||
* @return id of the given section coordinate
|
||||
*/
|
||||
default int idAt(final int sectionX, final int sectionY, final int sectionZ) {
|
||||
return idAt(ChunkSection.index(sectionX, sectionY, sectionZ));
|
||||
return idAt(index(sectionX, sectionY, sectionZ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value in the chunk section.
|
||||
* This method does not update non-air blocks count.
|
||||
*
|
||||
* @param sectionCoordinate block index within the section
|
||||
* @param sectionCoordinate section index within the section
|
||||
* @param id id value
|
||||
*/
|
||||
void setIdAt(int sectionCoordinate, int id);
|
||||
@ -63,7 +73,7 @@ public interface DataPalette {
|
||||
* @param id id value
|
||||
*/
|
||||
default void setIdAt(final int sectionX, final int sectionY, final int sectionZ, final int id) {
|
||||
setIdAt(ChunkSection.index(sectionX, sectionY, sectionZ), id);
|
||||
setIdAt(index(sectionX, sectionY, sectionZ), id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,17 +93,17 @@ public interface DataPalette {
|
||||
void setIdByIndex(int index, int id);
|
||||
|
||||
/**
|
||||
* Returns the palette index of the given block index.
|
||||
* Returns the palette index of the given section index.
|
||||
*
|
||||
* @param packedCoordinate block index
|
||||
* @return palette index of the given block index
|
||||
* @param packedCoordinate section index
|
||||
* @return palette index of the given section index
|
||||
*/
|
||||
int paletteIndexAt(int packedCoordinate);
|
||||
|
||||
/**
|
||||
* Sets the index of the given section coordinate.
|
||||
*
|
||||
* @param sectionCoordinate block index
|
||||
* @param sectionCoordinate section index
|
||||
* @param index palette index
|
||||
*/
|
||||
void setPaletteIndexAt(int sectionCoordinate, int index);
|
||||
|
@ -32,22 +32,26 @@ public final class DataPaletteImpl implements DataPalette {
|
||||
private final IntList palette;
|
||||
private final Int2IntMap inversePalette;
|
||||
private final int[] values;
|
||||
private final int sizeBits;
|
||||
|
||||
public DataPaletteImpl() {
|
||||
this.values = new int[ChunkSection.SIZE];
|
||||
palette = new IntArrayList();
|
||||
inversePalette = new Int2IntOpenHashMap();
|
||||
inversePalette.defaultReturnValue(-1);
|
||||
public DataPaletteImpl(final int valuesLength) {
|
||||
this(valuesLength, 8);
|
||||
}
|
||||
|
||||
public DataPaletteImpl(final int expectedPaletteLength) {
|
||||
this.values = new int[ChunkSection.SIZE];
|
||||
public DataPaletteImpl(final int valuesLength, final int expectedPaletteLength) {
|
||||
this.values = new int[valuesLength];
|
||||
sizeBits = Integer.numberOfTrailingZeros(valuesLength) / 3;
|
||||
// Pre-size the palette array/map
|
||||
palette = new IntArrayList(expectedPaletteLength);
|
||||
inversePalette = new Int2IntOpenHashMap(expectedPaletteLength);
|
||||
inversePalette.defaultReturnValue(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int index(final int x, final int y, final int z) {
|
||||
return (y << this.sizeBits | z) << this.sizeBits | x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int idAt(final int sectionCoordinate) {
|
||||
final int index = values[sectionCoordinate];
|
||||
|
@ -24,18 +24,18 @@ package com.viaversion.viaversion.api.minecraft.chunks;
|
||||
|
||||
public enum PaletteType {
|
||||
BLOCKS(ChunkSection.SIZE, 8),
|
||||
BIOMES(4 * 4 * 4, 2);
|
||||
BIOMES(ChunkSection.BIOME_SIZE, 2);
|
||||
|
||||
private final int maxSize;
|
||||
private final int size;
|
||||
private final int highestBitsPerValue;
|
||||
|
||||
PaletteType(final int maxSize, final int highestBitsPerValue) {
|
||||
this.maxSize = maxSize;
|
||||
PaletteType(final int size, final int highestBitsPerValue) {
|
||||
this.size = size;
|
||||
this.highestBitsPerValue = highestBitsPerValue;
|
||||
}
|
||||
|
||||
public int maxSize() {
|
||||
return maxSize;
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public int highestBitsPerValue() {
|
||||
|
@ -52,7 +52,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
|
||||
final DataPaletteImpl palette;
|
||||
if (bitsPerValue == 0) {
|
||||
//TODO Create proper singleton palette Object
|
||||
palette = new DataPaletteImpl(1);
|
||||
palette = new DataPaletteImpl(type.size(), 1);
|
||||
palette.addId(Type.VAR_INT.readPrimitive(buffer));
|
||||
Type.VAR_INT.readPrimitive(buffer); // 0 values length
|
||||
return palette;
|
||||
@ -60,19 +60,19 @@ public final class PaletteType1_18 extends Type<DataPalette> {
|
||||
|
||||
if (bitsPerValue != globalPaletteBits) {
|
||||
final int paletteLength = Type.VAR_INT.readPrimitive(buffer);
|
||||
palette = new DataPaletteImpl(paletteLength);
|
||||
palette = new DataPaletteImpl(type.size(), paletteLength);
|
||||
for (int i = 0; i < paletteLength; i++) {
|
||||
palette.addId(Type.VAR_INT.readPrimitive(buffer));
|
||||
}
|
||||
} else {
|
||||
palette = new DataPaletteImpl();
|
||||
palette = new DataPaletteImpl(type.size());
|
||||
}
|
||||
|
||||
// Read values
|
||||
final long[] values = new long[Type.VAR_INT.readPrimitive(buffer)];
|
||||
if (values.length > 0) {
|
||||
final char valuesPerLong = (char) (64 / bitsPerValue);
|
||||
final int expectedLength = (type.maxSize() + valuesPerLong - 1) / valuesPerLong;
|
||||
final int expectedLength = (type.size() + valuesPerLong - 1) / valuesPerLong;
|
||||
if (values.length != expectedLength) {
|
||||
throw new IllegalStateException("Palette data length (" + values.length + ") does not match expected length (" + expectedLength + ")! bitsPerValue=" + bitsPerValue + ", originalBitsPerValue=" + originalBitsPerValue);
|
||||
}
|
||||
@ -80,7 +80,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = buffer.readLong();
|
||||
}
|
||||
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.maxSize(), values,
|
||||
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.size(), values,
|
||||
bitsPerValue == globalPaletteBits ? palette::setIdAt : palette::setPaletteIndexAt);
|
||||
}
|
||||
return palette;
|
||||
@ -120,7 +120,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
|
||||
}
|
||||
}
|
||||
|
||||
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, type.maxSize(), bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt);
|
||||
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, type.size(), bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt);
|
||||
Type.VAR_INT.writePrimitive(buffer, data.length);
|
||||
for (final long l : data) {
|
||||
buffer.writeLong(l);
|
||||
|
@ -47,7 +47,6 @@ public final class WorldPackets {
|
||||
|
||||
private static final int WIDTH_BITS = 2;
|
||||
private static final int HORIZONTAL_MASK = 3;
|
||||
private static final int BIOMES_PER_CHUNK = 4 * 4 * 4;
|
||||
|
||||
public static void register(final Protocol1_18To1_17_1 protocol) {
|
||||
protocol.registerClientbound(ClientboundPackets1_17_1.BLOCK_ENTITY_DATA, new PacketRemapper() {
|
||||
@ -137,7 +136,7 @@ public final class WorldPackets {
|
||||
sections[i] = section;
|
||||
section.setNonAirBlocksCount(0);
|
||||
|
||||
final DataPaletteImpl blockPalette = new DataPaletteImpl();
|
||||
final DataPaletteImpl blockPalette = new DataPaletteImpl(ChunkSection.SIZE);
|
||||
blockPalette.addId(0);
|
||||
section.addPalette(PaletteType.BLOCKS, blockPalette);
|
||||
} else {
|
||||
@ -149,20 +148,12 @@ public final class WorldPackets {
|
||||
}
|
||||
|
||||
// Fill biome palette
|
||||
final DataPaletteImpl biomePalette = new DataPaletteImpl();
|
||||
final DataPaletteImpl biomePalette = new DataPaletteImpl(ChunkSection.BIOME_SIZE);
|
||||
section.addPalette(PaletteType.BIOMES, biomePalette);
|
||||
for (int biomeIndex = i * BIOMES_PER_CHUNK; biomeIndex < (i * BIOMES_PER_CHUNK) + BIOMES_PER_CHUNK; biomeIndex++) {
|
||||
final int biome = biomeData[biomeIndex];
|
||||
final int minX = (biomeIndex & HORIZONTAL_MASK) << 2;
|
||||
final int minY = ((biomeIndex >> WIDTH_BITS + WIDTH_BITS) << 2) & 15;
|
||||
final int minZ = (biomeIndex >> WIDTH_BITS & HORIZONTAL_MASK) << 2;
|
||||
for (int x = minX; x < minX + 4; x++) {
|
||||
for (int y = minY; y < minY + 4; y++) {
|
||||
for (int z = minZ; z < minZ + 4; z++) {
|
||||
biomePalette.setIdAt(x, y, z, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int offset = i * ChunkSection.BIOME_SIZE;
|
||||
for (int biomeIndex = 0; biomeIndex < ChunkSection.BIOME_SIZE; biomeIndex++) {
|
||||
biomePalette.setIdAt(biomeIndex, biomeData[offset + biomeIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user