Chunk is now a DataContainer

This commit is contained in:
themode 2020-10-03 18:51:33 +02:00
parent f85e7ca4a9
commit 6758cadf7d
4 changed files with 52 additions and 14 deletions

View File

@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.ints.*;
import net.minestom.server.MinecraftServer;
import net.minestom.server.Viewable;
import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.pathfinding.PFColumnarSpace;
import net.minestom.server.event.player.PlayerChunkLoadEvent;
@ -35,7 +36,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;
// TODO light data & API
public abstract class Chunk implements Viewable {
public abstract class Chunk implements Viewable, DataContainer {
protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
protected static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager();
@ -75,6 +76,9 @@ public abstract class Chunk implements Viewable {
protected Set<Player> viewers = new CopyOnWriteArraySet<>();
protected ByteBuf fullDataPacket;
// Data
protected Data data;
public Chunk(Instance instance, Biome[] biomes, int chunkX, int chunkZ) {
this.instance = instance;
this.chunkX = chunkX;
@ -192,18 +196,26 @@ public abstract class Chunk implements Viewable {
*/
protected abstract void refreshBlockStateId(int x, int y, int z, short blockStateId);
public Data getData(int x, int y, int z) {
/**
* Get the {@link Data} at a position
*
* @param x the block X
* @param y the block Y
* @param z the block Z
* @return the {@link Data} at the position, null if none
*/
public Data getBlockData(int x, int y, int z) {
final int index = getBlockIndex(x, y, z);
return getData(index);
return getBlockData(index);
}
/**
* Get the {@link Data} at a block index
*
* @param index the block index
* @return the {@link Data} at the block index
* @return the {@link Data} at the block index, null if none
*/
protected Data getData(int index) {
protected Data getBlockData(int index) {
return blocksData.get(index);
}
@ -233,7 +245,7 @@ public abstract class Chunk implements Viewable {
this.updatableBlocksLastUpdate.put(index, time); // Refresh last update time
final BlockPosition blockPosition = ChunkUtils.getBlockPosition(index, chunkX, chunkZ);
final Data data = getData(index);
final Data data = getBlockData(index);
customBlock.update(instance, blockPosition, data);
}
}
@ -428,6 +440,16 @@ public abstract class Chunk implements Viewable {
return Collections.unmodifiableSet(viewers);
}
@Override
public Data getData() {
return data;
}
@Override
public void setData(Data data) {
this.data = data;
}
/**
* Send the chunk data to {@code player}
*

View File

@ -146,6 +146,15 @@ public class DynamicChunk extends Chunk {
BinaryWriter binaryWriter = new BinaryWriter();
// Chunk data
final boolean hasChunkData = data instanceof SerializableData && !data.isEmpty();
binaryWriter.writeBoolean(hasChunkData);
if (hasChunkData) {
// Get the un-indexed data
final byte[] serializedData = ((SerializableData) data).getSerializedData(typeToIndexMap, false);
binaryWriter.writeBytes(serializedData);
}
// Write the biomes id
for (int i = 0; i < BIOME_COUNT; i++) {
final byte id = (byte) biomes[i].getId();
@ -173,9 +182,9 @@ public class DynamicChunk extends Chunk {
// Data
final Data data = blocksData.get(index);
final boolean hasData = data instanceof SerializableData;
binaryWriter.writeBoolean(hasData);
if (hasData) {
final boolean hasBlockData = data instanceof SerializableData && !data.isEmpty();
binaryWriter.writeBoolean(hasBlockData);
if (hasBlockData) {
// Get the un-indexed data
final byte[] serializedData = ((SerializableData) data).getSerializedData(typeToIndexMap, false);
binaryWriter.writeBytes(serializedData);
@ -214,6 +223,13 @@ public class DynamicChunk extends Chunk {
typeToIndexMap = SerializableData.readDataIndexes(reader);
}
// Chunk data
final boolean hasChunkData = reader.readBoolean();
if (hasChunkData) {
SerializableData serializableData = new SerializableDataImpl();
serializableData.readSerializedData(reader, typeToIndexMap);
}
for (int i = 0; i < BIOME_COUNT; i++) {
final byte id = reader.readByte();
this.biomes[i] = BIOME_MANAGER.getById(id);
@ -233,9 +249,9 @@ public class DynamicChunk extends Chunk {
// Data
SerializableData data = null;
{
final boolean hasData = reader.readBoolean();
final boolean hasBlockData = reader.readBoolean();
// Data deserializer
if (hasData) {
if (hasBlockData) {
// Read the data with the deserialized index map
data = new SerializableDataImpl();
data.readSerializedData(reader, typeToIndexMap);

View File

@ -628,7 +628,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
public Data getBlockData(int x, int y, int z) {
final Chunk chunk = getChunkAt(x, z);
Check.notNull(chunk, "The chunk at " + x + ":" + z + " is not loaded");
return chunk.getData(x, (byte) y, z);
return chunk.getBlockData(x, (byte) y, z);
}
/**

View File

@ -242,7 +242,7 @@ public class InstanceContainer extends Instance {
* @param blockPosition the block position
*/
private void callBlockDestroy(Chunk chunk, int index, CustomBlock previousBlock, BlockPosition blockPosition) {
final Data previousData = chunk.getData(index);
final Data previousData = chunk.getBlockData(index);
previousBlock.onDestroy(this, blockPosition, previousData);
}
@ -259,7 +259,7 @@ public class InstanceContainer extends Instance {
final CustomBlock actualBlock = chunk.getCustomBlock(index);
if (actualBlock == null)
return;
final Data previousData = chunk.getData(index);
final Data previousData = chunk.getBlockData(index);
actualBlock.onPlace(this, blockPosition, previousData);
}