diff --git a/src/main/java/com/minelittlepony/unicopia/BlockDestructionManager.java b/src/main/java/com/minelittlepony/unicopia/BlockDestructionManager.java index adb2dbef..77887820 100644 --- a/src/main/java/com/minelittlepony/unicopia/BlockDestructionManager.java +++ b/src/main/java/com/minelittlepony/unicopia/BlockDestructionManager.java @@ -14,7 +14,7 @@ public class BlockDestructionManager { public static final int UNSET_DAMAGE = -1; public static final int MAX_DAMAGE = 10; - private final Destruction emptyDestruction = new Destruction(BlockPos.ORIGIN); + private final Destruction emptyDestruction = new Destruction(); private final World world; @@ -36,7 +36,7 @@ public class BlockDestructionManager { public void setBlockDestruction(BlockPos pos, int amount) { synchronized (locker) { - destructions.computeIfAbsent(pos.asLong(), p -> new Destruction(pos)).set(amount); + destructions.computeIfAbsent(pos.asLong(), p -> new Destruction()).set(amount); } } @@ -52,17 +52,25 @@ public class BlockDestructionManager { public void tick() { synchronized (locker) { destructions.long2ObjectEntrySet().removeIf(entry -> entry.getValue().tick()); + + if (world instanceof ServerWorld) { + Long2ObjectMap sent = new Long2ObjectOpenHashMap<>(); + destructions.forEach((p, item) -> { + if (item.dirty) { + sent.put(p.longValue(), (Integer)item.amount); + } + }); + if (!sent.isEmpty()) { + Channel.SERVER_BLOCK_DESTRUCTION.send(world, new MsgBlockDestruction(sent)); + } + } } } private class Destruction { - BlockPos pos; int amount = -1; int age = 50; - - Destruction(BlockPos pos) { - this.pos = pos; - } + boolean dirty; boolean tick() { if (age-- > 0) { @@ -78,9 +86,7 @@ public class BlockDestructionManager { void set(int amount) { this.age = 50; this.amount = amount >= 0 && amount < MAX_DAMAGE ? amount : UNSET_DAMAGE; - if (world instanceof ServerWorld) { - Channel.SERVER_BLOCK_DESTRUCTION.send(world, new MsgBlockDestruction(pos, this.amount)); - } + this.dirty = true; } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/ClientBlockDestructionManager.java b/src/main/java/com/minelittlepony/unicopia/client/ClientBlockDestructionManager.java index 8960b7cc..99965b65 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/ClientBlockDestructionManager.java +++ b/src/main/java/com/minelittlepony/unicopia/client/ClientBlockDestructionManager.java @@ -16,12 +16,12 @@ public class ClientBlockDestructionManager { private final Object locker = new Object(); - public void setBlockDestruction(BlockPos pos, int amount) { + public void setBlockDestruction(long pos, int amount) { synchronized (locker) { if (amount <= 0 || amount > BlockDestructionManager.MAX_DAMAGE) { - destructions.remove(pos.asLong()); + destructions.remove(pos); } else { - destructions.computeIfAbsent(pos.asLong(), p -> new Destruction(pos)).set(amount); + destructions.computeIfAbsent(pos, p -> new Destruction(pos)).set(amount); } } } @@ -52,8 +52,8 @@ public class ClientBlockDestructionManager { BlockBreakingInfo info; - Destruction(BlockPos pos) { - this.info = new BlockBreakingInfo(0, pos); + Destruction(long pos) { + this.info = new BlockBreakingInfo(0, BlockPos.fromLong(pos)); } boolean tick() { diff --git a/src/main/java/com/minelittlepony/unicopia/network/MsgBlockDestruction.java b/src/main/java/com/minelittlepony/unicopia/network/MsgBlockDestruction.java index 0cd2a1ef..a18c3c60 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/MsgBlockDestruction.java +++ b/src/main/java/com/minelittlepony/unicopia/network/MsgBlockDestruction.java @@ -2,35 +2,44 @@ package com.minelittlepony.unicopia.network; import com.minelittlepony.unicopia.client.ClientBlockDestructionManager; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.network.PacketByteBuf; -import net.minecraft.util.math.BlockPos; import net.minecraft.client.MinecraftClient; public class MsgBlockDestruction implements Channel.Packet { - private final BlockPos pos; - - private final int amount; + private final Long2ObjectMap destructions; MsgBlockDestruction(PacketByteBuf buffer) { - pos = buffer.readBlockPos(); - amount = buffer.readByte(); + destructions = new Long2ObjectOpenHashMap<>(); + int size = buffer.readInt(); + for (int i = 0; i < size; i++) { + destructions.put(buffer.readLong(), (Integer)buffer.readInt()); + } } - public MsgBlockDestruction(BlockPos pos, int amount) { - this.pos = pos; - this.amount = amount; + public MsgBlockDestruction(Long2ObjectMap destructions) { + this.destructions = destructions; } @Override public void toBuffer(PacketByteBuf buffer) { - buffer.writeBlockPos(pos); - buffer.writeByte(amount); + buffer.writeInt(destructions.size()); + destructions.forEach((p, i) -> { + buffer.writeLong(p); + buffer.writeInt(i); + }); } @Override public void handle(PacketContext context) { - ((ClientBlockDestructionManager.Source)MinecraftClient.getInstance().worldRenderer).getDestructionManager().setBlockDestruction(pos, amount); + ClientBlockDestructionManager destr = ((ClientBlockDestructionManager.Source)MinecraftClient.getInstance().worldRenderer).getDestructionManager(); + + destructions.forEach((i, d) -> { + destr.setBlockDestruction(i, d); + }); + } }