mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-11-04 11:13:45 +01:00 
			
		
		
		
	Begin to implement extended world heights:
- Implemented in Bukkit module (and where required in Core module)
This commit is contained in:
		@@ -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);
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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];
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,18 @@ import java.util.Objects;
 | 
			
		||||
public class BukkitWorld implements World<org.bukkit.World> {
 | 
			
		||||
 | 
			
		||||
    private static final Map<String, BukkitWorld> 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<org.bukkit.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<org.bukkit.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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -58,6 +58,21 @@ public interface World<T> {
 | 
			
		||||
     */
 | 
			
		||||
    @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<T> implements World<T> {
 | 
			
		||||
 | 
			
		||||
        private NullWorld() {
 | 
			
		||||
@@ -74,6 +89,16 @@ public interface World<T> {
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int getMinHeight() {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int getMaxHeight() {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean equals(final Object obj) {
 | 
			
		||||
            return obj instanceof NullWorld;
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -39,13 +39,13 @@ public class ChunkUtil {
 | 
			
		||||
     * - Used for efficient world generation<br>
 | 
			
		||||
     */
 | 
			
		||||
    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];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user