From f1d9d4bdc7cf4cf2e2547a31d7707c8e05cff526 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 25 Jan 2022 15:22:33 +0000 Subject: [PATCH] Begin to implement extended world heights: - Implemented in Bukkit module (and where required in Core module) --- .../bukkit/generator/BukkitPlotGenerator.java | 7 +++- .../bukkit/listener/BlockEventListener.java | 4 +- .../bukkit/queue/BukkitQueueCoordinator.java | 37 ++++++++--------- .../plotsquared/bukkit/queue/GenChunk.java | 38 +++++++++++++----- .../bukkit/util/BukkitRegionManager.java | 7 +++- .../plotsquared/bukkit/util/BukkitUtil.java | 8 +++- .../plotsquared/bukkit/util/BukkitWorld.java | 40 +++++++++++++++++++ .../plotsquared/bukkit/util/ContentMap.java | 14 +++---- .../com/plotsquared/core/location/World.java | 25 ++++++++++++ .../plotsquared/core/queue/LocalChunk.java | 14 ++++++- .../core/queue/ScopedQueueCoordinator.java | 8 +++- .../com/plotsquared/core/util/ChunkUtil.java | 18 ++++----- 12 files changed, 164 insertions(+), 56 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/generator/BukkitPlotGenerator.java b/Bukkit/src/main/java/com/plotsquared/bukkit/generator/BukkitPlotGenerator.java index f5406ef9a..88492d642 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/generator/BukkitPlotGenerator.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/generator/BukkitPlotGenerator.java @@ -27,6 +27,7 @@ package com.plotsquared.bukkit.generator; import com.plotsquared.bukkit.queue.GenChunk; import com.plotsquared.bukkit.util.BukkitUtil; +import com.plotsquared.bukkit.util.BukkitWorld; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.generator.GeneratorWrapper; import com.plotsquared.core.generator.IndependentPlotGenerator; @@ -159,12 +160,14 @@ public class BukkitPlotGenerator extends ChunkGenerator @NonNull BiomeGrid biome ) { - GenChunk result = new GenChunk(); + int minY = BukkitWorld.getMinWorldHeight(world); + int maxY = BukkitWorld.getMaxWorldHeight(world); + GenChunk result = new GenChunk(minY, maxY); if (this.getPlotGenerator() instanceof SingleWorldGenerator) { if (result.getChunkData() != null) { for (int chunkX = 0; chunkX < 16; chunkX++) { for (int chunkZ = 0; chunkZ < 16; chunkZ++) { - for (int y = 0; y < world.getMaxHeight(); y++) { + for (int y = minY; y < maxY; y++) { biome.setBiome(chunkX, y, chunkZ, Biome.PLAINS); } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java index 616af9922..db6f24e75 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java @@ -354,7 +354,7 @@ public class BlockEventListener implements Listener { Plot plot = area.getPlot(location); if (plot != null) { BukkitPlayer plotPlayer = BukkitUtil.adapt(player); - if (event.getBlock().getY() == 0) { + if (event.getBlock().getY() == area.getMinBuildHeight()) { if (!Permissions .hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL)) { plotPlayer.sendMessage( @@ -649,7 +649,7 @@ public class BlockEventListener implements Listener { event.getBlock().breakNaturally(); } } - if (location.getY() == 0) { + if (location.getY() == area.getMinBuildHeight()) { event.setCancelled(true); return; } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java index 8c418ee88..96ca41f4e 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java @@ -111,8 +111,8 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { public boolean enqueue() { final Clipboard regenClipboard; if (isRegen()) { - BlockVector3 start = BlockVector3.at(getRegenStart()[0] << 4, 0, getRegenStart()[1] << 4); - BlockVector3 end = BlockVector3.at((getRegenEnd()[0] << 4) + 15, 255, (getRegenEnd()[1] << 4) + 15); + BlockVector3 start = BlockVector3.at(getRegenStart()[0] << 4, getWorld().getMinY(), getRegenStart()[1] << 4); + BlockVector3 end = BlockVector3.at((getRegenEnd()[0] << 4) + 15, getWorld().getMaxY(), (getRegenEnd()[1] << 4) + 15); Region region = new CuboidRegion(start, end); regenClipboard = new BlockArrayClipboard(region); regenClipboard.setOrigin(start); @@ -134,7 +134,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { int sx = blockVector2.getX() << 4; int sz = blockVector2.getZ() << 4; if (isRegenChunk) { - for (int layer = 0; layer < 16; layer++) { + for (int layer = (getWorld().getMinY() >> 4); layer < (getWorld().getMaxY() >> 4); layer++) { for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { @@ -170,7 +170,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { int lx = ChunkUtil.getX(j); int lz = ChunkUtil.getZ(j); int x = sx + lx; - int y = ChunkUtil.getY(layer, j); + int y = ChunkUtil.getY(layer + localChunk.getMinSection(), j); int z = sz + lz; boolean edge = Settings.QUEUE.UPDATE_EDGES && isEdge(y >> 4, lx, y & 15, lz, blockVector2, localChunk @@ -295,47 +295,48 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { } private boolean isEdge(int layer, int x, int y, int z, BlockVector2 blockVector2, LocalChunk localChunk) { - if (layer == 0 || layer == localChunk.getBaseblocks().length - 1) { + int layerIndex = (layer - localChunk.getMinSection()); + if (layer == localChunk.getMinSection() || layerIndex == localChunk.getBaseblocks().length - 1) { return false; } if (x == 0) { LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() - 1)); - if (localChunkX == null || localChunkX.getBaseblocks()[layer] == null || - localChunkX.getBaseblocks()[layer][ChunkUtil.getJ(15, y, z)] != null) { + if (localChunkX == null || localChunkX.getBaseblocks()[layerIndex] == null || + localChunkX.getBaseblocks()[layerIndex][ChunkUtil.getJ(15, y, z)] != null) { return true; } } else if (x == 15) { LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() + 1)); - if (localChunkX == null || localChunkX.getBaseblocks()[layer] == null || - localChunkX.getBaseblocks()[layer][ChunkUtil.getJ(0, y, z)] != null) { + if (localChunkX == null || localChunkX.getBaseblocks()[layerIndex] == null || + localChunkX.getBaseblocks()[layerIndex][ChunkUtil.getJ(0, y, z)] != null) { return true; } } if (z == 0) { LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() - 1)); - if (localChunkZ == null || localChunkZ.getBaseblocks()[layer] == null || - localChunkZ.getBaseblocks()[layer][ChunkUtil.getJ(x, y, 15)] != null) { + if (localChunkZ == null || localChunkZ.getBaseblocks()[layerIndex] == null || + localChunkZ.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, y, 15)] != null) { return true; } } else if (z == 15) { LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() + 1)); - if (localChunkZ == null || localChunkZ.getBaseblocks()[layer] == null || - localChunkZ.getBaseblocks()[layer][ChunkUtil.getJ(x, y, 0)] != null) { + if (localChunkZ == null || localChunkZ.getBaseblocks()[layerIndex] == null || + localChunkZ.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, y, 0)] != null) { return true; } } if (y == 0) { - if (localChunk.getBaseblocks()[layer - 1] == null || - localChunk.getBaseblocks()[layer][ChunkUtil.getJ(x, 15, z)] != null) { + if (localChunk.getBaseblocks()[layerIndex - 1] == null || + localChunk.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, 15, z)] != null) { return true; } } else if (y == 15) { - if (localChunk.getBaseblocks()[layer + 1] == null || - localChunk.getBaseblocks()[layer][ChunkUtil.getJ(x, 0, z)] != null) { + if (localChunk.getBaseblocks()[layerIndex + 1] == null || + localChunk.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, 0, z)] != null) { return true; } } - BaseBlock[] baseBlocks = localChunk.getBaseblocks()[layer]; + BaseBlock[] baseBlocks = localChunk.getBaseblocks()[layerIndex]; if (x > 0 && baseBlocks[ChunkUtil.getJ(x - 1, y, z)] == null) { return true; } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/GenChunk.java b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/GenChunk.java index 10da1e0de..fcd8b615b 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/GenChunk.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/GenChunk.java @@ -61,8 +61,28 @@ public class GenChunk extends ScopedQueueCoordinator { public int chunkZ; private ChunkData chunkData = null; + + /** + * Not API. Used as a bridge between P2 and Bukkit {@link Chunk}. + * + * @deprecated Use {@link GenChunk#regenChunk(int, int)} for extended world heights + * @since TODO + */ + @Deprecated(forRemoval = true, since = "TODO") public GenChunk() { - super(null, Location.at("", 0, 0, 0), Location.at("", 15, 255, 15)); + this(0, 255); + } + + /** + * Not API. Used as a bridge between P2 and Bukkit {@link Chunk}. + * + * @param minY minimum world Y, inclusive + * @param maxY maximum world Y, inclusive + * + * @since TODO + */ + public GenChunk(int minY, int maxY) { + super(null, Location.at("", 0, minY, 0), Location.at("", 15, maxY, 15)); this.biomes = Biome.values(); } @@ -117,7 +137,7 @@ public class GenChunk extends ScopedQueueCoordinator { return; } Biome biome = BukkitAdapter.adapt(biomeType); - for (int y = 0; y < 256; y++) { + for (int y = getMin().getY(); y <= getMax().getY(); y++) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { this.biomeGrid.setBiome(x, y, z, biome); @@ -130,7 +150,7 @@ public class GenChunk extends ScopedQueueCoordinator { public void setCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull BlockState block) { if (result != null && pos1.getX() == 0 && pos1.getZ() == 0 && pos2.getX() == 15 && pos2.getZ() == 15) { for (int y = pos1.getY(); y <= pos2.getY(); y++) { - int layer = y >> 4; + int layer = (y - getMin().getY()) >> 4; BlockState[] data = result[layer]; if (data == null) { result[layer] = data = new BlockState[4096]; @@ -164,7 +184,7 @@ public class GenChunk extends ScopedQueueCoordinator { */ public boolean setBiome(int x, int z, @NonNull Biome biome) { if (this.biomeGrid != null) { - for (int y = 0; y < 256; y++) { + for (int y = getMin().getY(); y < getMax().getY(); y++) { this.setBiome(x, y, z, biome); } return true; @@ -197,7 +217,7 @@ public class GenChunk extends ScopedQueueCoordinator { } private void storeCache(final int x, final int y, final int z, final @NonNull BlockState id) { - int i = y >> 4; + int i = (y - getMin().getY()) >> 4; BlockState[] v = this.result[i]; if (v == null) { this.result[i] = v = new BlockState[4096]; @@ -219,7 +239,7 @@ public class GenChunk extends ScopedQueueCoordinator { @Override public @Nullable BlockState getBlock(int x, int y, int z) { - int i = y >> 4; + int i = (y - getMin().getY()) >> 4; if (result == null) { return BukkitBlockUtil.get(chunkData.getType(x, y, z)); } @@ -246,16 +266,16 @@ public class GenChunk extends ScopedQueueCoordinator { @Override public @NonNull Location getMax() { - return Location.at(getWorld().getName(), 15 + (getX() << 4), 255, 15 + (getZ() << 4)); + return Location.at(getWorld().getName(), 15 + (getX() << 4), super.getMax().getY(), 15 + (getZ() << 4)); } @Override public @NonNull Location getMin() { - return Location.at(getWorld().getName(), getX() << 4, 0, getZ() << 4); + return Location.at(getWorld().getName(), getX() << 4, super.getMin().getY(), getZ() << 4); } public @NonNull GenChunk clone() { - GenChunk toReturn = new GenChunk(); + GenChunk toReturn = new GenChunk(getMin().getY(), getMax().getY()); if (this.result != null) { for (int i = 0; i < this.result.length; i++) { BlockState[] matrix = this.result[i]; diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java index 2e78b7508..c36f1db5e 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java @@ -276,7 +276,9 @@ public class BukkitRegionManager extends RegionManager { PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1); BaseBlock[] ids = map.allBlocks.get(plotLoc); if (ids != null) { - for (int y = 0; y < Math.min(128, ids.length); y++) { + int minY = value.getMin().getY(); + for (int yIndex = 0; yIndex < Math.min(128 - minY, ids.length); yIndex++) { + int y = yIndex + minY; BaseBlock id = ids[y]; if (id != null) { value.setBlock(x1, y, z1, id); @@ -284,7 +286,8 @@ public class BukkitRegionManager extends RegionManager { value.setBlock(x1, y, z1, BlockTypes.AIR.getDefaultState()); } } - for (int y = Math.min(128, ids.length); y < ids.length; y++) { + for (int yIndex = Math.min(128 - minY, ids.length); yIndex < ids.length; yIndex++) { + int y = yIndex + minY; BaseBlock id = ids[y]; if (id != null) { value.setBlock(x1, y, z1, id); diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java index 3a46fbb7d..63638d541 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java @@ -246,7 +246,9 @@ public class BukkitUtil extends WorldUtil { final World bukkitWorld = Objects.requireNonNull(getWorld(world)); // Skip top and bottom block int air = 1; - for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) { + int maxY = com.plotsquared.bukkit.util.BukkitWorld.getMaxWorldHeight(bukkitWorld); + int minY = com.plotsquared.bukkit.util.BukkitWorld.getMinWorldHeight(bukkitWorld); + for (int y = maxY - 1; y >= minY; y--) { Block block = bukkitWorld.getBlockAt(x, y, z); Material type = block.getType(); if (type.isSolid()) { @@ -273,7 +275,9 @@ public class BukkitUtil extends WorldUtil { final World bukkitWorld = Objects.requireNonNull(getWorld(world)); // Skip top and bottom block int air = 1; - for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) { + int maxY = com.plotsquared.bukkit.util.BukkitWorld.getMaxWorldHeight(bukkitWorld); + int minY = com.plotsquared.bukkit.util.BukkitWorld.getMinWorldHeight(bukkitWorld); + for (int y = maxY - 1; y >= minY; y--) { Block block = bukkitWorld.getBlockAt(x, y, z); Material type = block.getType(); if (type.isSolid()) { diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitWorld.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitWorld.java index 38a343780..0f2ed2556 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitWorld.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitWorld.java @@ -36,6 +36,18 @@ import java.util.Objects; public class BukkitWorld implements World { private static final Map worldMap = Maps.newHashMap(); + private static final boolean HAS_MIN_Y; + + static { + boolean temp; + try { + org.bukkit.World.class.getMethod("getMinHeight"); + temp = true; + } catch (NoSuchMethodException e) { + temp = false; + } + HAS_MIN_Y = temp; + } private final org.bukkit.World world; @@ -73,6 +85,24 @@ public class BukkitWorld implements World { return bukkitWorld; } + /** + * Get the min world height from a Bukkit {@link org.bukkit.World}. Inclusive + * + * @since TODO + */ + public static int getMinWorldHeight(org.bukkit.World world) { + return HAS_MIN_Y ? world.getMinHeight() : 0; + } + + /** + * Get the max world height from a Bukkit {@link org.bukkit.World}. Exclusive + * + * @since TODO + */ + public static int getMaxWorldHeight(org.bukkit.World world) { + return HAS_MIN_Y ? world.getMaxHeight() : 256; + } + @Override public org.bukkit.World getPlatformWorld() { return this.world; @@ -83,6 +113,16 @@ public class BukkitWorld implements World { return this.world.getName(); } + @Override + public int getMinHeight() { + return getMinWorldHeight(world); + } + + @Override + public int getMaxHeight() { + return getMaxWorldHeight(world); + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/ContentMap.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/ContentMap.java index 0fd8cdcbc..542557492 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/ContentMap.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/ContentMap.java @@ -70,7 +70,7 @@ public class ContentMap { } for (int x = x1; x <= x2; x++) { for (int z = z1; z <= z2; z++) { - saveBlocks(world, 256, x, z, 0, 0); + saveBlocks(world, x, z, 0, 0); } } } @@ -134,13 +134,11 @@ public class ContentMap { this.entities.clear(); } - //todo optimize maxY - void saveBlocks(BukkitWorld world, int maxY, int x, int z, int offsetX, int offsetZ) { - maxY = Math.min(255, maxY); - BaseBlock[] ids = new BaseBlock[maxY + 1]; - for (short y = 0; y <= maxY; y++) { - BaseBlock block = world.getFullBlock(BlockVector3.at(x, y, z)); - ids[y] = block; + private void saveBlocks(BukkitWorld world, int x, int z, int offsetX, int offsetZ) { + BaseBlock[] ids = new BaseBlock[world.getMaxY() - world.getMinY()]; + for (short yIndex = 0; yIndex <= world.getMaxY() - world.getMinY(); yIndex++) { + BaseBlock block = world.getFullBlock(BlockVector3.at(x, yIndex + world.getMinY(), z)); + ids[yIndex] = block; } PlotLoc loc = new PlotLoc(x + offsetX, z + offsetZ); this.allBlocks.put(loc, ids); diff --git a/Core/src/main/java/com/plotsquared/core/location/World.java b/Core/src/main/java/com/plotsquared/core/location/World.java index 6e1c0a5ed..dec73e46b 100644 --- a/Core/src/main/java/com/plotsquared/core/location/World.java +++ b/Core/src/main/java/com/plotsquared/core/location/World.java @@ -58,6 +58,21 @@ public interface World { */ @NonNull String getName(); + /** + * Get the min world height. Inclusive. + * + * @since TODO + */ + int getMinHeight(); + + + /** + * Get the max world height. Exclusive. + * + * @since TODO + */ + int getMaxHeight(); + class NullWorld implements World { private NullWorld() { @@ -74,6 +89,16 @@ public interface World { return ""; } + @Override + public int getMinHeight() { + return 0; + } + + @Override + public int getMaxHeight() { + return 0; + } + @Override public boolean equals(final Object obj) { return obj instanceof NullWorld; diff --git a/Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java b/Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java index d61ff03cc..d6488b347 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java +++ b/Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java @@ -42,6 +42,7 @@ public class LocalChunk { private final QueueCoordinator parent; private final int x; private final int z; + private final int minSection; private final BaseBlock[][] baseblocks; private final BiomeType[][] biomes; @@ -52,8 +53,10 @@ public class LocalChunk { this.parent = parent; this.x = x; this.z = z; - baseblocks = new BaseBlock[16][]; - biomes = new BiomeType[16][]; + this.minSection = parent.getWorld() != null ? (parent.getWorld().getMinY() >> 4) : 0; + int sections = parent.getWorld() != null ? (parent.getWorld().getMaxY() >> 4) - minSection : 16; + baseblocks = new BaseBlock[sections][]; + biomes = new BiomeType[sections][]; } public @NonNull QueueCoordinator getParent() { @@ -68,6 +71,13 @@ public class LocalChunk { return this.z; } + /** + * Get the minimum layer position stored (usually -4 or 0). + */ + public int getMinSection() { + return this.minSection; + } + public @NonNull BaseBlock[][] getBaseblocks() { return this.baseblocks; } diff --git a/Core/src/main/java/com/plotsquared/core/queue/ScopedQueueCoordinator.java b/Core/src/main/java/com/plotsquared/core/queue/ScopedQueueCoordinator.java index ae05eb31d..3b4cb2682 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/ScopedQueueCoordinator.java +++ b/Core/src/main/java/com/plotsquared/core/queue/ScopedQueueCoordinator.java @@ -39,6 +39,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; */ public class ScopedQueueCoordinator extends DelegateQueueCoordinator { + private final Location min; + private final Location max; private final int minX; private final int minY; private final int minZ; @@ -53,6 +55,8 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator { public ScopedQueueCoordinator(@Nullable QueueCoordinator parent, @NonNull Location min, @NonNull Location max) { super(parent); + this.min = min; + this.max = max; this.minX = min.getX(); this.minY = min.getY(); this.minZ = min.getZ(); @@ -112,11 +116,11 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator { } public @NonNull Location getMin() { - return Location.at(this.getWorld().getName(), this.minX, this.minY, this.minZ); + return min; } public @NonNull Location getMax() { - return Location.at(this.getWorld().getName(), this.maxX, this.maxY, this.maxZ); + return max; } } diff --git a/Core/src/main/java/com/plotsquared/core/util/ChunkUtil.java b/Core/src/main/java/com/plotsquared/core/util/ChunkUtil.java index f0b48a231..bdaa2a053 100644 --- a/Core/src/main/java/com/plotsquared/core/util/ChunkUtil.java +++ b/Core/src/main/java/com/plotsquared/core/util/ChunkUtil.java @@ -39,13 +39,13 @@ public class ChunkUtil { * - Used for efficient world generation
*/ private static final short[] x_loc; - private static final short[][] y_loc; + private static final short[] y_loc; private static final short[] z_loc; private static final short[][][] CACHE_J; static { x_loc = new short[4096]; - y_loc = new short[16][4096]; + y_loc = new short[4096]; z_loc = new short[4096]; for (int i = 0; i < 16; i++) { int i4 = i << 4; @@ -55,14 +55,14 @@ public class ChunkUtil { int z1 = a >> 4; int x1 = a - (z1 << 4); x_loc[j] = (short) x1; - y_loc[i][j] = (short) y; + y_loc[j] = (short) y; z_loc[j] = (short) z1; } } - CACHE_J = new short[256][16][16]; + CACHE_J = new short[16][16][16]; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { - for (int y = 0; y < 256; y++) { + for (int y = 0; y < 16; y++) { short j = (short) ((y & 0xF) << 8 | z << 4 | x); CACHE_J[y][x][z] = j; } @@ -83,7 +83,7 @@ public class ChunkUtil { * @return J value for xyz position in Array[4096]. */ public static int getJ(int x, int y, int z) { - return CACHE_J[y][x][z]; + return CACHE_J[y & 15][x & 15][z & 15]; } /** @@ -97,14 +97,14 @@ public class ChunkUtil { } /** - * Gets the y coordinate for specific I and J values for a Chunk 16x16x16x16 layerxyz Array[16][4096]. + * Gets the y coordinate for specific I and J values for a Chunk 16x16x16x16 layerxyz Array[N][4096]. * - * @param i Relative layer of the position in the layerxyz Array[16][4096]. + * @param i Relative layer of the position in the layerxyz Array[16][4096]. May be negative. * @param j Position in the xyz Array[4096]. * @return x coordinate within the chunk */ public static int getY(int i, int j) { - return y_loc[i][j]; + return (i << 4) + y_loc[j]; } /**