diff --git a/src/main/java/com/hbm/explosion/ExplosionNukeRayParallelized.java b/src/main/java/com/hbm/explosion/ExplosionNukeRayParallelized.java index e6f01e18c..66b88de95 100644 --- a/src/main/java/com/hbm/explosion/ExplosionNukeRayParallelized.java +++ b/src/main/java/com/hbm/explosion/ExplosionNukeRayParallelized.java @@ -3,7 +3,7 @@ package com.hbm.explosion; import com.hbm.config.BombConfig; import com.hbm.interfaces.IExplosionRay; import com.hbm.main.MainRegistry; -import com.hbm.util.ChunkKey; +import com.hbm.util.SubChunkKey; import com.hbm.util.ConcurrentBitSet; import com.hbm.util.SubChunkSnapshot; import net.minecraft.block.Block; @@ -41,10 +41,10 @@ public class ExplosionNukeRayParallelized implements IExplosionRay { private final ConcurrentMap destructionMap; private final ConcurrentMap accumulatedDamageMap; - private final ConcurrentMap snapshots; + private final ConcurrentMap snapshots; private final BlockingQueue rayQueue; - private final BlockingQueue cacheQueue; + private final BlockingQueue cacheQueue; private final ExecutorService pool; private final CountDownLatch latch; private final Thread latchWatcherThread; @@ -115,7 +115,7 @@ public class ExplosionNukeRayParallelized implements IExplosionRay { final long deadline = System.nanoTime() + (timeBudgetMs * 1_000_000L); while (System.nanoTime() < deadline) { - ChunkKey ck = cacheQueue.poll(); + SubChunkKey ck = cacheQueue.poll(); if (ck == null) break; snapshots.computeIfAbsent(ck, k -> SubChunkSnapshot.getSnapshot(world, k, BombConfig.chunkloading)); } @@ -188,7 +188,7 @@ public class ExplosionNukeRayParallelized implements IExplosionRay { if (bs.isEmpty()) { destructionMap.remove(cp); for (int sy = 0; sy < (WORLD_HEIGHT >> 4); sy++) { - snapshots.remove(new ChunkKey(cp, sy)); + snapshots.remove(new SubChunkKey(cp, sy)); } it.remove(); } @@ -293,7 +293,7 @@ public class ExplosionNukeRayParallelized implements IExplosionRay { continue; } - ChunkKey snapshotKey = new ChunkKey(cp, subY); + SubChunkKey snapshotKey = new SubChunkKey(cp, subY); SubChunkSnapshot snap = snapshots.get(snapshotKey); Block originalBlock; @@ -440,7 +440,7 @@ public class ExplosionNukeRayParallelized implements IExplosionRay { if (y < 0 || y >= WORLD_HEIGHT) break; if (currentRayPosition >= radius - PROCESSING_EPSILON) break; - ChunkKey ck = new ChunkKey(x >> 4, z >> 4, y >> 4); + SubChunkKey ck = new SubChunkKey(x >> 4, z >> 4, y >> 4); SubChunkSnapshot snap = snapshots.get(ck); if (snap == null) { @@ -473,14 +473,14 @@ public class ExplosionNukeRayParallelized implements IExplosionRay { if (damageDealt > 0) { int bitIndex = ((WORLD_HEIGHT - 1 - y) << 8) | ((x & 0xF) << 4) | (z & 0xF); if (BombConfig.explosionAlgorithm == 2) { - ChunkCoordIntPair chunkPos = ck.pos; + ChunkCoordIntPair chunkPos = ck.getPos(); ChunkDamageAccumulator chunkAccumulator = accumulatedDamageMap.computeIfAbsent(chunkPos, k -> new ChunkDamageAccumulator()); chunkAccumulator.addDamage(bitIndex, damageDealt); } else { if (energy > 0) { ConcurrentBitSet bs = destructionMap.computeIfAbsent( - ck.pos, + ck.getPos(), posKey -> new ConcurrentBitSet(BITSET_SIZE) ); bs.set(bitIndex); diff --git a/src/main/java/com/hbm/util/ChunkKey.java b/src/main/java/com/hbm/util/ChunkKey.java deleted file mode 100644 index 4f3bd0ba3..000000000 --- a/src/main/java/com/hbm/util/ChunkKey.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.hbm.util; - -import net.minecraft.world.ChunkCoordIntPair; - -import java.util.Objects; - -/** - * Unique identifier for sub-chunks. - * @author mlbv - */ -public class ChunkKey { - public final ChunkCoordIntPair pos; - public final int subY; - - public ChunkKey(int cx, int cz, int sy) { - this.pos = new ChunkCoordIntPair(cx, cz); - this.subY = sy; - } - - public ChunkKey(ChunkCoordIntPair pos, int sy) { - this.pos = pos; - this.subY = sy; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ChunkKey)) return false; - ChunkKey k = (ChunkKey) o; - return subY == k.subY && pos.equals(k.pos); - } - - @Override - public int hashCode() { - return Objects.hash(pos.chunkXPos, pos.chunkZPos, subY); - } -} diff --git a/src/main/java/com/hbm/util/SubChunkKey.java b/src/main/java/com/hbm/util/SubChunkKey.java new file mode 100644 index 000000000..068bdfef8 --- /dev/null +++ b/src/main/java/com/hbm/util/SubChunkKey.java @@ -0,0 +1,67 @@ +package com.hbm.util; + +import net.minecraft.world.ChunkCoordIntPair; + +/** + * Unique identifier for sub-chunks. + * @author mlbv + */ +public class SubChunkKey { + + private int chunkXPos; + private int chunkZPos; + private int subY; + private int hash; + + public SubChunkKey() { + this(0, 0, 0); + } + + public SubChunkKey(int cx, int cz, int sy) { + this.update(cx, cz, sy); + } + + public SubChunkKey(ChunkCoordIntPair pos, int sy) { + this.update(pos.chunkXPos, pos.chunkZPos, sy); + } + + public SubChunkKey update(int cx, int cz, int sy) { + this.chunkXPos = cx; + this.chunkZPos = cz; + this.subY = sy; + int result = subY; + result = 31 * result + cx; + result = 31 * result + cz; + this.hash = result; + return this; + } + + @Override + public final int hashCode() { + return this.hash; + } + + @Override + public final boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SubChunkKey)) return false; + SubChunkKey k = (SubChunkKey) o; + return this.subY == k.subY && this.chunkXPos == k.chunkXPos && this.chunkZPos == k.chunkZPos; + } + + public int getSubY() { + return subY; + } + + public int getChunkXPos() { + return chunkXPos; + } + + public int getChunkZPos() { + return chunkZPos; + } + + public ChunkCoordIntPair getPos() { + return new ChunkCoordIntPair(this.chunkXPos, this.chunkZPos); + } +} diff --git a/src/main/java/com/hbm/util/SubChunkSnapshot.java b/src/main/java/com/hbm/util/SubChunkSnapshot.java index cd51d125b..6077ca4b4 100644 --- a/src/main/java/com/hbm/util/SubChunkSnapshot.java +++ b/src/main/java/com/hbm/util/SubChunkSnapshot.java @@ -34,19 +34,19 @@ public class SubChunkSnapshot { * @param world * The World instance from which to retrieve the chunk. * @param key - * The ChunkKey identifying the sub-chunk. + * The SubChunkKey identifying the sub-chunk. * @param allowGeneration * Whether to generate chunks. If false, attempting to retrieve a snapshot of a chunk that does not exist will return {@link SubChunkSnapshot#EMPTY}. * @return * A SubChunkSnapshot containing the palette and block data for the sub-chunk, * or {@link SubChunkSnapshot#EMPTY} if the region contains only air. */ - public static SubChunkSnapshot getSnapshot(World world, ChunkKey key, boolean allowGeneration){ - if (!world.getChunkProvider().chunkExists(key.pos.chunkXPos, key.pos.chunkZPos) && !allowGeneration) { + public static SubChunkSnapshot getSnapshot(World world, SubChunkKey key, boolean allowGeneration){ + if (!world.getChunkProvider().chunkExists(key.getChunkXPos(), key.getChunkZPos()) && !allowGeneration) { return SubChunkSnapshot.EMPTY; } - Chunk chunk = world.getChunkProvider().provideChunk(key.pos.chunkXPos, key.pos.chunkZPos); - ExtendedBlockStorage ebs = chunk.getBlockStorageArray()[key.subY]; + Chunk chunk = world.getChunkProvider().provideChunk(key.getChunkXPos(), key.getChunkZPos()); + ExtendedBlockStorage ebs = chunk.getBlockStorageArray()[key.getSubY()]; if (ebs == null || ebs.isEmpty()) return SubChunkSnapshot.EMPTY; short[] data = new short[16 * 16 * 16];