From 4708da8e8ff5c7c695b7b8691335db85dae054d8 Mon Sep 17 00:00:00 2001 From: tom lee Date: Mon, 21 Feb 2022 19:18:43 +0800 Subject: [PATCH] Rework block color/shape stuff --- .../com/seibel/lod/core/api/ClientApi.java | 3 +- .../LodBufferBuilderFactory.java | 2 +- .../core/builders/lodBuilding/LodBuilder.java | 111 +++++------------- .../lod/core/objects/BlockBiomeCouple.java | 10 +- .../core/objects/opengl/LodQuadBuilder.java | 6 +- .../com/seibel/lod/core/util/ColorUtil.java | 1 - .../wrapperInterfaces/block/BlockDetail.java | 28 +++++ .../block/IBlockColorSingletonWrapper.java | 35 ------ .../block/IBlockColorWrapper.java | 52 -------- .../block/IBlockShapeWrapper.java | 39 ------ .../chunk/IChunkWrapper.java | 15 ++- 11 files changed, 79 insertions(+), 223 deletions(-) create mode 100644 src/main/java/com/seibel/lod/core/wrapperInterfaces/block/BlockDetail.java delete mode 100644 src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorSingletonWrapper.java delete mode 100644 src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorWrapper.java delete mode 100644 src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockShapeWrapper.java diff --git a/src/main/java/com/seibel/lod/core/api/ClientApi.java b/src/main/java/com/seibel/lod/core/api/ClientApi.java index dcaf6b89e..385bda73c 100644 --- a/src/main/java/com/seibel/lod/core/api/ClientApi.java +++ b/src/main/java/com/seibel/lod/core/api/ClientApi.java @@ -185,7 +185,8 @@ public class ClientApi toBeLoaded.remove(pos); continue; } - //if (!chunk.isLightCorrect()) continue; + if (!chunk.isLightCorrect()) continue; + if (!chunk.doesNearbyChunksExist()) continue; toBeLoaded.remove(pos); generating.add(pos); //ClientApi.LOGGER.info("Lod Generation trying "+pos+". Remining: " +toBeLoaded.size()); diff --git a/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java b/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java index 8dd459aef..a8261da75 100644 --- a/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java +++ b/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java @@ -320,7 +320,7 @@ public class LodBufferBuilderFactory { CompletableFuture allFutures = CompletableFuture .allOf(futuresBuffer.toArray(new CompletableFuture[futuresBuffer.size()])); try { - allFutures.get(60, TimeUnit.SECONDS); + allFutures.get(5, TimeUnit.MINUTES); } catch (TimeoutException te) { ClientApi.LOGGER.error("LodBufferBuilder timed out: ", te); bufferBuilderThreadFactory.dumpAllThreadStacks(); diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java index 427912f06..12cbeeb6e 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java @@ -24,24 +24,21 @@ import java.util.concurrent.Executors; import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.enums.LodDirection; +import com.seibel.lod.core.enums.config.BlocksToAvoid; import com.seibel.lod.core.enums.config.DistanceGenerationMode; import com.seibel.lod.core.objects.lod.LodDimension; import com.seibel.lod.core.objects.lod.LodRegion; import com.seibel.lod.core.objects.lod.LodWorld; -import com.seibel.lod.core.util.ColorUtil; import com.seibel.lod.core.util.DataPointUtil; import com.seibel.lod.core.util.DetailDistanceUtil; import com.seibel.lod.core.util.LevelPosUtil; import com.seibel.lod.core.util.LodThreadFactory; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.SingletonHandler; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorSingletonWrapper; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockShapeWrapper; +import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; @@ -57,7 +54,6 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; public class LodBuilder { private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); - private static final IBlockColorSingletonWrapper BLOCK_COLOR = SingletonHandler.get(IBlockColorSingletonWrapper.class); /** This cannot be final! Different world have different height, and in menu, this causes Null Exceptions*/ @@ -136,7 +132,7 @@ public class LodBuilder } catch (RuntimeException e) { - e.printStackTrace(); + ClientApi.LOGGER.error("LodBuilder Thread Uncaught Exception: ", e); // // if the world changes while LODs are being generated // // they will throw errors as they try to access things that no longer // // exist. @@ -166,6 +162,7 @@ public class LodBuilder if (MC.getWrappedClientWorld() == null) return false; if (!chunk.isLightCorrect()) return false; + if (!chunk.doesNearbyChunksExist()) return false; // generate the LODs @@ -192,6 +189,7 @@ public class LodBuilder } } if (!chunk.isLightCorrect()) return false; + if (!chunk.doesNearbyChunksExist()) return false; if (genAll) { return writeAllLodNodeData(lodDim, region, chunk.getChunkPosX(), chunk.getChunkPosZ(), data, config, override); @@ -199,7 +197,7 @@ public class LodBuilder return writePartialLodNodeData(lodDim, region, chunk.getChunkPosX(), chunk.getChunkPosZ(), data, config, override); } } catch (RuntimeException e) { - ClientApi.LOGGER.error("LodBuilder encountered an error on building lod for chunk {}: {}", chunk ,e); + ClientApi.LOGGER.error("LodBuilder encountered an error on building lod: ", e); return false; } @@ -294,7 +292,7 @@ public class LodBuilder config.distanceGenerationMode)) throw new RuntimeException("data at detail "+ targetLevel+" is still null after writes to it!"); } catch (Exception e) { - e.printStackTrace(); + ClientApi.LOGGER.error("LodBuilder encountered an error on writePartialLodNodeData: ", e); } finally { region.isWriting.decrementAndGet(); } @@ -366,8 +364,8 @@ public class LodBuilder int cy = y+dir.getNormal().y; int cz = z+dir.getNormal().z; if (!chunk.blockPosInsideChunk(cx, cy, cz)) return true; - IBlockShapeWrapper block = chunk.getBlockShapeWrapper(cx, cy, cz); - if (block == null || block.hasNoCollision() || block.isToAvoid() || block.isNonFull() || block.hasNoCollision()) + BlockDetail block = chunk.getBlockDetail(cx, cy, cz); + if (block == null || !block.isFullBlock) return true; } return false; @@ -377,27 +375,24 @@ public class LodBuilder * Find the lowest valid point from the bottom. * Used when creating a vertical LOD. */ - private int determineBottomPointFrom(IChunkWrapper chunk, LodBuilderConfig config, int xAbs, int yAbs, int zAbs, boolean strictEdge) + private int determineBottomPointFrom(IChunkWrapper chunk, LodBuilderConfig builderConfig, int xAbs, int yAbs, int zAbs, boolean strictEdge) { int depth = chunk.getMinBuildHeight(); int colorOfBlock = 0; if (strictEdge) { - IBlockShapeWrapper block = chunk.getBlockShapeWrapper(xAbs, yAbs + 1, zAbs); - if (block != null && !block.isToAvoid() - && ((this.config.client().worldGenerator().getBlocksToAvoid().nonFull && block.isNonFull()) - || (this.config.client().worldGenerator().getBlocksToAvoid().noCollision && block.hasNoCollision()))) - { - colorOfBlock = chunk.getBlockColorWrapper(xAbs, yAbs + 1, zAbs).getColor(); + BlockDetail blockAbove = chunk.getBlockDetail(xAbs, yAbs + 1, zAbs); + if (blockAbove != null && !blockAbove.shouldRender(config.client().worldGenerator().getBlocksToAvoid())) + { // The above block is skipped. Lets use its skipped color for currrent block + colorOfBlock = blockAbove.color; } - if (colorOfBlock == 0) - colorOfBlock = chunk.getBlockColorWrapper(xAbs, yAbs, zAbs).getColor(); + if (colorOfBlock == 0) colorOfBlock = chunk.getBlockDetail(xAbs, yAbs, zAbs).color; } for (int y = yAbs - 1; y >= chunk.getMinBuildHeight(); y--) { if (!isLayerValidLodPoint(chunk, xAbs, y, zAbs) - || (strictEdge && hasCliffFace(chunk, xAbs, y, zAbs) && colorOfBlock != chunk.getBlockColorWrapper(xAbs, y, zAbs).getColor())) + || (strictEdge && hasCliffFace(chunk, xAbs, y, zAbs) && colorOfBlock != chunk.getBlockDetail(xAbs, y, zAbs).color)) { depth = (short) (y + 1); break; @@ -443,16 +438,20 @@ public class LodBuilder } else { - colorInt = getColorForBlock(chunk, x, y, z); + BlockDetail detail = chunk.getBlockDetail(x, y, z); + colorInt = detail == null ? 0 : detail.color; // if we are skipping non-full and non-solid blocks that means we ignore // snow, flowers, etc. Get the above block so we can still get the color // of the snow, flower, etc. that may be above this block int aboveColorInt = 0; - IBlockShapeWrapper block = chunk.getBlockShapeWrapper(x, y + 1, z); - if (block != null && ((config.client().worldGenerator().getBlocksToAvoid().nonFull && block.isNonFull()) - || (config.client().worldGenerator().getBlocksToAvoid().noCollision && block.hasNoCollision()))) - aboveColorInt = getColorForBlock(chunk, x, y + 1, z); + if (chunk.blockPosInsideChunk(x, y+1, z)) { + BlockDetail blockAbove = chunk.getBlockDetail(x, y+1, z); + if (blockAbove != null && !blockAbove.shouldRender(config.client().worldGenerator().getBlocksToAvoid())) + { // The above block is skipped. Lets use its skipped color for currrent block + aboveColorInt = blockAbove.color; + } + } //if (colorInt == 0 && yAbs > 0) // if this block is invisible, check the block below it @@ -544,65 +543,11 @@ public class LodBuilder return blockLight + (skyLight << 4); } - /** Returns a color int for the given block. */ - private int getColorForBlock(IChunkWrapper chunk, int x, int y, int z) - { - int colorOfBlock; - int colorInt; - - IBlockShapeWrapper blockShapeWrapper = chunk.getBlockShapeWrapper(x, y, z); - - if (blockShapeWrapper == null || blockShapeWrapper.isToAvoid()) - return 0; - - IBlockColorWrapper blockColorWrapper; - - if (chunk.isWaterLogged(x, y, z)) - blockColorWrapper = BLOCK_COLOR.getWaterColor(); - else - blockColorWrapper = chunk.getBlockColorWrapper(x, y, z); - - - - colorOfBlock = blockColorWrapper.getColor(); - - - if (blockColorWrapper.hasTint()) - { - IBiomeWrapper biome = chunk.getBiome(x, y, z); - int tintValue; - if (blockColorWrapper.hasGrassTint()) - // grass and green plants - tintValue = biome.getGrassTint(0,0); - else if (blockColorWrapper.hasFolliageTint()) - tintValue = biome.getFolliageTint(); - else - //we can reintroduce this with the wrappers - tintValue = biome.getWaterTint(); - - colorInt = ColorUtil.multiplyRGBcolors(tintValue | 0xFF000000, colorOfBlock); - } - else - colorInt = colorOfBlock; - return colorInt; - } - - /** Is the block at the given blockPos a valid LOD point? */ private boolean isLayerValidLodPoint(IChunkWrapper chunk, int x, int y, int z) { - if (chunk.isWaterLogged(x, y, z)) - return true; - - boolean nonFullAvoidance = config.client().worldGenerator().getBlocksToAvoid().nonFull; - boolean noCollisionAvoidance = config.client().worldGenerator().getBlocksToAvoid().noCollision; - - IBlockShapeWrapper block = chunk.getBlockShapeWrapper(x, y, z); - - return block != null - && !block.isToAvoid() - && !(nonFullAvoidance && block.isNonFull()) - && !(noCollisionAvoidance && block.hasNoCollision()); - + BlocksToAvoid avoid = config.client().worldGenerator().getBlocksToAvoid(); + BlockDetail block = chunk.getBlockDetail(x, y, z); + return block != null && block.shouldRender(avoid); } } diff --git a/src/main/java/com/seibel/lod/core/objects/BlockBiomeCouple.java b/src/main/java/com/seibel/lod/core/objects/BlockBiomeCouple.java index 7224b7ea6..2fda96335 100644 --- a/src/main/java/com/seibel/lod/core/objects/BlockBiomeCouple.java +++ b/src/main/java/com/seibel/lod/core/objects/BlockBiomeCouple.java @@ -1,6 +1,7 @@ package com.seibel.lod.core.objects; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper; +/* +import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; import java.util.Objects; @@ -9,15 +10,15 @@ import java.util.concurrent.ConcurrentMap; public class BlockBiomeCouple { - public static final ConcurrentMap noBiomeIstanceCache = new ConcurrentHashMap<>(); - public static ConcurrentMap> withBiomeIstanceCache = new ConcurrentHashMap<>(); + public static final ConcurrentMap noBiomeIstanceCache = new ConcurrentHashMap<>(); + public static ConcurrentMap> withBiomeIstanceCache = new ConcurrentHashMap<>(); String blockName; String biomeName; String coupleName; IBiomeWrapper biomeColor; - IBlockColorWrapper blockColor; + BlockDetail blockColor; public static void addBlockBiomeToCache(IBlockColorWrapper blockColor){ } @@ -101,3 +102,4 @@ public class BlockBiomeCouple } +*/ \ No newline at end of file diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java b/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java index 3ed74bbf9..4882bed90 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java @@ -16,7 +16,7 @@ public class LodQuadBuilder { static final int MAX_BUFFER_SIZE = (1024 * 1024 * 1); static final int QUAD_BYTE_SIZE = (12 * 6); static final int MAX_QUADS_PER_BUFFER = MAX_BUFFER_SIZE / QUAD_BYTE_SIZE; - static final int MAX_MERGED_QUAD_SIZE = 64; + //static final int MAX_MERGED_QUAD_SIZE = 64; static class Quad { final short x; @@ -87,7 +87,7 @@ public class LodQuadBuilder { { if (dir != o.dir) return false; - if (w0 >= MAX_MERGED_QUAD_SIZE) return false; + //if (w0 >= MAX_MERGED_QUAD_SIZE) return false; switch (dir.getAxis()) { case X: @@ -156,7 +156,7 @@ public class LodQuadBuilder { { if (dir != o.dir) return false; - if (w1 >= MAX_MERGED_QUAD_SIZE) return false; + //if (w1 >= MAX_MERGED_QUAD_SIZE) return false; switch (dir.getAxis()) { case X: diff --git a/src/main/java/com/seibel/lod/core/util/ColorUtil.java b/src/main/java/com/seibel/lod/core/util/ColorUtil.java index e38d84398..92b7f2476 100644 --- a/src/main/java/com/seibel/lod/core/util/ColorUtil.java +++ b/src/main/java/com/seibel/lod/core/util/ColorUtil.java @@ -33,7 +33,6 @@ public class ColorUtil { private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); - public static int rgbToInt(int red, int green, int blue) { return (0xFF << 24) | (red << 16) | (green << 8) | blue; diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/BlockDetail.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/BlockDetail.java new file mode 100644 index 000000000..868a8a771 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/BlockDetail.java @@ -0,0 +1,28 @@ +package com.seibel.lod.core.wrapperInterfaces.block; + +import com.seibel.lod.core.enums.config.BlocksToAvoid; +import com.seibel.lod.core.util.ColorUtil; + +public class BlockDetail +{ + public final int color; + public final boolean isFullBlock; + public final boolean hasNoCollision; + public final boolean hasOnlyNonFullFace; + + public BlockDetail(int c, boolean full, boolean noCol, boolean nonFullFace) { + color = c; + isFullBlock = full; + hasNoCollision = noCol; + hasOnlyNonFullFace = nonFullFace; + } + + public boolean shouldRender(BlocksToAvoid mode) { + return !((mode.noCollision && hasNoCollision) || (mode.nonFull && hasOnlyNonFullFace)); + } + + public String toString() { + return "[color: "+ColorUtil.toString(color)+", isFullBlock: "+isFullBlock + +", hasNoCollision: "+hasNoCollision+", hasOnlyNonFullFace: "+hasOnlyNonFullFace+"]"; + } +} diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorSingletonWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorSingletonWrapper.java deleted file mode 100644 index aeef4ba9d..000000000 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorSingletonWrapper.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of the Distant Horizon mod (formerly the LOD Mod), - * licensed under the GNU GPL v3 License. - * - * Copyright (C) 2020 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.core.wrapperInterfaces.block; - -/** - * Contains methods that would have been static in BlockColorWrapper. - * Since interfaces can't create/implement static methods we have - * to split the object up in two. - * - * @author James Seibel - * @version 11-17-2021 - */ -public interface IBlockColorSingletonWrapper -{ - /** @returns the base color of water (grey) */ - IBlockColorWrapper getWaterColor(); -} - diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorWrapper.java deleted file mode 100644 index 257a688c6..000000000 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorWrapper.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the Distant Horizon mod (formerly the LOD Mod), - * licensed under the GNU GPL v3 License. - * - * Copyright (C) 2020 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.core.wrapperInterfaces.block; - -/** - * @author James Seibel - * @version 11-17-2021 - */ -public interface IBlockColorWrapper -{ - //--------------// - //Colors getters// - //--------------// - - boolean hasColor(); - - String getName(); - - int getColor(); - - - //------------// - //Tint getters// - //------------// - - boolean hasTint(); - - boolean hasGrassTint(); - - boolean hasFolliageTint(); - - boolean hasWaterTint(); - -} - diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockShapeWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockShapeWrapper.java deleted file mode 100644 index 4a3b3448b..000000000 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockShapeWrapper.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the Distant Horizon mod (formerly the LOD Mod), - * licensed under the GNU GPL v3 License. - * - * Copyright (C) 2020 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.core.wrapperInterfaces.block; - -/** - * @author James Seibel - * @version 11-20-2021 - */ -public interface IBlockShapeWrapper -{ - boolean ofBlockToAvoid(); - - //-----------------// - //Avoidance getters// - //-----------------// - - boolean isNonFull(); - - boolean hasNoCollision(); - - boolean isToAvoid(); -} \ No newline at end of file diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java index 66478e61b..5aa7d3c46 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java @@ -19,10 +19,15 @@ package com.seibel.lod.core.wrapperInterfaces.chunk; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockShapeWrapper; +import org.jetbrains.annotations.Nullable; + +import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; + /** * @author James Seibel * @version 11-17-2021 @@ -38,8 +43,8 @@ public interface IChunkWrapper int getHeightMapValue(int xRel, int zRel); IBiomeWrapper getBiome(int x, int y, int z); - IBlockColorWrapper getBlockColorWrapper(int x, int y, int z); - IBlockShapeWrapper getBlockShapeWrapper(int x, int y, int z); + + BlockDetail getBlockDetail(int x, int y, int z); int getChunkPosX(); int getChunkPosZ(); @@ -68,4 +73,6 @@ public interface IChunkWrapper && y>=getMinBuildHeight() && y=getMinZ() && z<=getMaxZ()); } + + boolean doesNearbyChunksExist(); }