diff --git a/src/main/java/net/minestom/server/instance/Chunk.java b/src/main/java/net/minestom/server/instance/Chunk.java index 6b26c5f10..56bf3b91a 100644 --- a/src/main/java/net/minestom/server/instance/Chunk.java +++ b/src/main/java/net/minestom/server/instance/Chunk.java @@ -77,28 +77,12 @@ public abstract class Chunk implements Viewable { this.chunkZ = chunkZ; } - public void UNSAFE_setBlock(int x, int y, int z, short blockStateId, Data data) { - setBlock(x, y, z, blockStateId, (short) 0, data, null); - } - - public void UNSAFE_setCustomBlock(int x, int y, int z, short blockStateId, short customBlockId, Data data) { - final CustomBlock customBlock = BLOCK_MANAGER.getCustomBlock(customBlockId); - Check.notNull(customBlock, "The custom block " + customBlockId + " does not exist or isn't registered"); - - UNSAFE_setCustomBlock(x, y, z, blockStateId, customBlock, data); - } - - protected void UNSAFE_setCustomBlock(int x, int y, int z, short blockStateId, CustomBlock customBlock, Data data) { - final UpdateConsumer updateConsumer = customBlock.hasUpdate() ? customBlock::update : null; - setBlock(x, y, z, blockStateId, customBlock.getCustomBlockId(), data, updateConsumer); - } - - public abstract void UNSAFE_removeCustomBlock(int x, int y, int z); - /** * Set a block at a position *
- * WARNING: this method is not thread-safe (in order to bring performance improvement with {@link ChunkBatch} & {@link BlockBatch} + * This is used when the previous block has to be destroyed, meaning that it clears the previous data and update method + *
+ * WARNING: this method is not thread-safe (in order to bring performance improvement with {@link ChunkBatch} & {@link BlockBatch})
* The thread-safe version is {@link InstanceContainer#setSeparateBlocks(int, int, int, short, short, Data)} (or any similar instance methods)
*
* @param x the block X
@@ -109,8 +93,16 @@ public abstract class Chunk implements Viewable {
* @param data the data of the block, can be null
* @param updateConsumer the update method of the block, can be null
*/
- protected abstract void setBlock(int x, int y, int z, short blockStateId, short customId, Data data, UpdateConsumer updateConsumer);
+ public abstract void setBlock(int x, int y, int z, short blockStateId, short customId, Data data, UpdateConsumer updateConsumer);
+ /**
+ * Set the {@link Data} at a position
+ *
+ * @param x the block X
+ * @param y the block Y
+ * @param z the block Z
+ * @param data the new data
+ */
public void setBlockData(int x, int y, int z, Data data) {
final int index = getBlockIndex(x, y, z);
if (data != null) {
@@ -120,12 +112,45 @@ public abstract class Chunk implements Viewable {
}
}
+ /**
+ * Get the block state id at a position
+ *
+ * @param x the block X
+ * @param y the block Y
+ * @param z the block Z
+ * @return the block state id at the position
+ */
public abstract short getBlockStateId(int x, int y, int z);
+ /**
+ * Get the custom block id at a position
+ *
+ * @param x the block X
+ * @param y the block Y
+ * @param z the block Z
+ * @return the custom block id at the position
+ */
public abstract short getCustomBlockId(int x, int y, int z);
- public abstract CustomBlock getCustomBlock(int x, int y, int z);
+ /**
+ * Get the {@link CustomBlock} at a position
+ *
+ * @param x the block X
+ * @param y the block Y
+ * @param z the block Z
+ * @return the {@link CustomBlock} at the position
+ */
+ public CustomBlock getCustomBlock(int x, int y, int z) {
+ final short customBlockId = getCustomBlockId(x, y, z);
+ return customBlockId != 0 ? BLOCK_MANAGER.getCustomBlock(customBlockId) : null;
+ }
+ /**
+ * Get the {@link CustomBlock} at a block index
+ *
+ * @param index the block index
+ * @return the {@link CustomBlock} at the block index
+ */
protected CustomBlock getCustomBlock(int index) {
final int x = ChunkUtils.blockIndexToChunkPositionX(index);
final int y = ChunkUtils.blockIndexToChunkPositionY(index);
@@ -133,25 +158,48 @@ public abstract class Chunk implements Viewable {
return getCustomBlock(x, y, z);
}
+ /**
+ * Change the block state id and the custom block id at a position
+ *
+ * @param x the block X
+ * @param y the block Y
+ * @param z the block Z
+ * @param blockStateId the new block state id
+ * @param customId the new custom block id
+ */
protected abstract void refreshBlockValue(int x, int y, int z, short blockStateId, short customId);
+ /**
+ * Change the block state id at a position (the custom block id stays the same)
+ *
+ * @param x the block X
+ * @param y the block Y
+ * @param z the block Z
+ * @param blockStateId the new block state id
+ */
protected abstract void refreshBlockStateId(int x, int y, int z, short blockStateId);
- protected void refreshBlockValue(int x, int y, int z, short blockStateId) {
- final CustomBlock customBlock = getCustomBlock(x, y, z);
- final short customBlockId = customBlock == null ? 0 : customBlock.getCustomBlockId();
- refreshBlockValue(x, y, z, blockStateId, customBlockId);
- }
-
public Data getData(int x, int y, int z) {
final int index = getBlockIndex(x, y, z);
return getData(index);
}
+ /**
+ * Get the {@link Data} at a block index
+ *
+ * @param index the block index
+ * @return the {@link Data} at the block index
+ */
protected Data getData(int index) {
return blocksData.get(index);
}
+ /**
+ * Execute a tick update for all the updatable blocks in this chunk
+ *
+ * @param time the time of the update in milliseconds
+ * @param instance the instance linked to this chunk
+ */
public synchronized void updateBlocks(long time, Instance instance) {
if (updatableBlocks.isEmpty())
return;
@@ -181,10 +229,20 @@ public abstract class Chunk implements Viewable {
return biomes;
}
+ /**
+ * Get the chunk X
+ *
+ * @return the chunk X
+ */
public int getChunkX() {
return chunkX;
}
+ /**
+ * Get the chunk Z
+ *
+ * @return the chunk Z
+ */
public int getChunkZ() {
return chunkZ;
}
@@ -455,6 +513,14 @@ public abstract class Chunk implements Viewable {
this.loaded = false;
}
+ /**
+ * Get the index of a position, used to store blocks
+ *
+ * @param x the block X
+ * @param y the block Y
+ * @param z the block Z
+ * @return the block index
+ */
protected int getBlockIndex(int x, int y, int z) {
return ChunkUtils.getBlockIndex(x, y, z);
}
diff --git a/src/main/java/net/minestom/server/instance/DynamicChunk.java b/src/main/java/net/minestom/server/instance/DynamicChunk.java
index 88bb8ccb8..1a7bfe00b 100644
--- a/src/main/java/net/minestom/server/instance/DynamicChunk.java
+++ b/src/main/java/net/minestom/server/instance/DynamicChunk.java
@@ -7,7 +7,6 @@ import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap;
import net.minestom.server.data.Data;
import net.minestom.server.data.SerializableData;
import net.minestom.server.entity.pathfinding.PFBlockDescription;
-import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.instance.block.UpdateConsumer;
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
import net.minestom.server.reader.ChunkReader;
@@ -31,19 +30,7 @@ public class DynamicChunk extends Chunk {
}
@Override
- public void UNSAFE_removeCustomBlock(int x, int y, int z) {
- final int index = getBlockIndex(x, y, z);
- this.customBlocksId[index] = 0; // Set to none
- this.blocksData.remove(index);
-
- this.updatableBlocks.remove(index);
- this.updatableBlocksLastUpdate.remove(index);
-
- this.blockEntities.remove(index);
- }
-
- @Override
- protected void setBlock(int x, int y, int z, short blockStateId, short customId, Data data, UpdateConsumer updateConsumer) {
+ public void setBlock(int x, int y, int z, short blockStateId, short customId, Data data, UpdateConsumer updateConsumer) {
{
// Update pathfinder
@@ -121,16 +108,6 @@ public class DynamicChunk extends Chunk {
return customBlocksId[index];
}
- @Override
- public CustomBlock getCustomBlock(int x, int y, int z) {
- final int index = getBlockIndex(x, y, z);
- if (!MathUtils.isBetween(index, 0, blocksStateId.length)) {
- return null; // TODO: custom invalid block
- }
- final short id = customBlocksId[index];
- return id != 0 ? BLOCK_MANAGER.getCustomBlock(id) : null;
- }
-
@Override
protected void refreshBlockValue(int x, int y, int z, short blockStateId, short customId) {
final int blockIndex = getBlockIndex(x, y, z);
diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java
index 447f534f4..785dd5d22 100644
--- a/src/main/java/net/minestom/server/instance/InstanceContainer.java
+++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java
@@ -13,6 +13,7 @@ import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockProvider;
import net.minestom.server.instance.block.CustomBlock;
+import net.minestom.server.instance.block.UpdateConsumer;
import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.network.packet.server.play.BlockChangePacket;
import net.minestom.server.network.packet.server.play.ParticlePacket;
@@ -22,6 +23,7 @@ import net.minestom.server.particle.ParticleCreator;
import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
+import net.minestom.server.utils.block.CustomBlockUtils;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.thread.MinestomThread;
import net.minestom.server.utils.time.TimeUnit;
@@ -135,14 +137,18 @@ public class InstanceContainer extends Instance {
// Change id based on neighbors
blockStateId = executeBlockPlacementRule(blockStateId, blockPosition);
- // Set the block
+ // Retrieve custom block values
+ short customBlockId = 0;
+ UpdateConsumer updateConsumer = null;
if (isCustomBlock) {
+ customBlockId = customBlock.getCustomBlockId();
data = customBlock.createData(this, blockPosition, data);
- chunk.UNSAFE_setCustomBlock(x, y, z, blockStateId, customBlock, data);
- } else {
- chunk.UNSAFE_setBlock(x, y, z, blockStateId, data);
+ updateConsumer = CustomBlockUtils.getCustomBlockUpdate(customBlock);
}
+ // Set the block
+ chunk.setBlock(x, y, z, blockStateId, customBlockId, data, updateConsumer);
+
// Refresh neighbors since a new block has been placed
executeNeighboursBlockPlacementRule(blockPosition);
@@ -197,7 +203,6 @@ public class InstanceContainer extends Instance {
private void callBlockDestroy(Chunk chunk, int index, CustomBlock previousBlock, BlockPosition blockPosition) {
final Data previousData = chunk.getData(index);
previousBlock.onDestroy(this, blockPosition, previousData);
- chunk.UNSAFE_removeCustomBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
}
/**
diff --git a/src/main/java/net/minestom/server/instance/StaticChunk.java b/src/main/java/net/minestom/server/instance/StaticChunk.java
index b12c88267..032c1f3d7 100644
--- a/src/main/java/net/minestom/server/instance/StaticChunk.java
+++ b/src/main/java/net/minestom/server/instance/StaticChunk.java
@@ -3,7 +3,6 @@ package net.minestom.server.instance;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minestom.server.data.Data;
import net.minestom.server.instance.block.BlockProvider;
-import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.instance.block.UpdateConsumer;
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
import net.minestom.server.utils.chunk.ChunkUtils;
@@ -21,12 +20,7 @@ public class StaticChunk extends Chunk {
}
@Override
- public void UNSAFE_removeCustomBlock(int x, int y, int z) {
- //noop
- }
-
- @Override
- protected void setBlock(int x, int y, int z, short blockStateId, short customId, Data data, UpdateConsumer updateConsumer) {
+ public void setBlock(int x, int y, int z, short blockStateId, short customId, Data data, UpdateConsumer updateConsumer) {
//noop
}
@@ -41,12 +35,6 @@ public class StaticChunk extends Chunk {
return 0;
}
- @Override
- public CustomBlock getCustomBlock(int x, int y, int z) {
- //noop
- return null;
- }
-
@Override
protected void refreshBlockValue(int x, int y, int z, short blockStateId, short customId) {
//noop
diff --git a/src/main/java/net/minestom/server/instance/batch/BlockBatch.java b/src/main/java/net/minestom/server/instance/batch/BlockBatch.java
index fb7f3e40b..d37302112 100644
--- a/src/main/java/net/minestom/server/instance/batch/BlockBatch.java
+++ b/src/main/java/net/minestom/server/instance/batch/BlockBatch.java
@@ -4,11 +4,13 @@ import net.minestom.server.data.Data;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.instance.block.CustomBlock;
+import net.minestom.server.utils.block.CustomBlockUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
public class BlockBatch implements InstanceBatch {
@@ -23,23 +25,23 @@ public class BlockBatch implements InstanceBatch {
@Override
public synchronized void setBlockStateId(int x, int y, int z, short blockStateId, Data data) {
final Chunk chunk = this.instance.getChunkAt(x, z);
- addBlockData(chunk, x, y, z, false, blockStateId, (short) 0, data);
+ addBlockData(chunk, x, y, z, blockStateId, (short) 0, data);
}
@Override
public void setCustomBlock(int x, int y, int z, short customBlockId, Data data) {
final Chunk chunk = this.instance.getChunkAt(x, z);
final CustomBlock customBlock = BLOCK_MANAGER.getCustomBlock(customBlockId);
- addBlockData(chunk, x, y, z, true, customBlock.getDefaultBlockStateId(), customBlockId, data);
+ addBlockData(chunk, x, y, z, customBlock.getDefaultBlockStateId(), customBlockId, data);
}
@Override
public synchronized void setSeparateBlocks(int x, int y, int z, short blockStateId, short customBlockId, Data data) {
final Chunk chunk = this.instance.getChunkAt(x, z);
- addBlockData(chunk, x, y, z, true, blockStateId, customBlockId, data);
+ addBlockData(chunk, x, y, z, blockStateId, customBlockId, data);
}
- private void addBlockData(Chunk chunk, int x, int y, int z, boolean customBlock, short blockStateId, short customBlockId, Data data) {
+ private void addBlockData(Chunk chunk, int x, int y, int z, short blockStateId, short customBlockId, Data data) {
List