From 6873e45b6fcb43af2e4d2de5f48fdea49dd6625d Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sun, 12 Nov 2017 13:37:27 +1100 Subject: [PATCH] Fix heightmap in height restricted regions --- .../object/brush/heightmap/HeightMap.java | 5 ++-- .../com/sk89q/worldedit/extent/Extent.java | 9 +++--- .../worldedit/math/convolution/HeightMap.java | 30 ++++++++++--------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/boydti/fawe/object/brush/heightmap/HeightMap.java b/core/src/main/java/com/boydti/fawe/object/brush/heightmap/HeightMap.java index 827b11e0..fae7291f 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/heightmap/HeightMap.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/heightmap/HeightMap.java @@ -74,6 +74,7 @@ public interface HeightMap { if (towards) { double sizePow = Math.pow(size, yscale); int targetY = pos.getBlockY(); + int tmpY = targetY; for (int x = -size; x <= size; x++) { int xx = centerX + x; mutablePos.mutX(xx); @@ -97,9 +98,9 @@ public interface HeightMap { } int height; if (layers) { - height = session.getNearestSurfaceLayer(xx, zz, pos.getBlockY(), 0, maxY); + height = tmpY = session.getNearestSurfaceLayer(xx, zz, tmpY, 0, maxY); } else { - height = session.getNearestSurfaceTerrainBlock(xx, zz, pos.getBlockY(), 0, maxY); + height = tmpY = session.getNearestSurfaceTerrainBlock(xx, zz, tmpY, 0, maxY); if (height == -1) continue; } oldData[index] = height; diff --git a/core/src/main/java/com/sk89q/worldedit/extent/Extent.java b/core/src/main/java/com/sk89q/worldedit/extent/Extent.java index 5df7c228..64287e03 100644 --- a/core/src/main/java/com/sk89q/worldedit/extent/Extent.java +++ b/core/src/main/java/com/sk89q/worldedit/extent/Extent.java @@ -7,6 +7,7 @@ import com.boydti.fawe.jnbt.anvil.generator.OreGen; import com.boydti.fawe.jnbt.anvil.generator.Resource; import com.boydti.fawe.jnbt.anvil.generator.SchemGen; import com.boydti.fawe.object.PseudoRandom; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MutableBlockVector; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; @@ -121,21 +122,21 @@ public interface Extent extends InputExtent, OutputExtent { for (int d = 0; d <= clearance; d++) { int y1 = y + d; block = getLazyBlock(x, y1, z); - if (FaweCache.canPassThrough(block.getId(), block.getData()) != state) return y1 - offset; + if (FaweCache.canPassThrough(block.getId(), block.getData()) != state && block != EditSession.nullBlock) return y1 - offset; int y2 = y - d; block = getLazyBlock(x, y2, z); - if (FaweCache.canPassThrough(block.getId(), block.getData()) != state) return y2 + offset; + if (FaweCache.canPassThrough(block.getId(), block.getData()) != state && block != EditSession.nullBlock) return y2 + offset; } if (clearanceAbove != clearanceBelow) { if (clearanceAbove < clearanceBelow) { for (int layer = y - clearance - 1; layer >= minY; layer--) { block = getLazyBlock(x, layer, z); - if (FaweCache.canPassThrough(block.getId(), block.getData()) != state) return layer + offset; + if (FaweCache.canPassThrough(block.getId(), block.getData()) != state && block != EditSession.nullBlock) return layer + offset; } } else { for (int layer = y + clearance + 1; layer <= maxY; layer++) { block = getLazyBlock(x, layer, z); - if (FaweCache.canPassThrough(block.getId(), block.getData()) != state) return layer - offset; + if (FaweCache.canPassThrough(block.getId(), block.getData()) != state && block != EditSession.nullBlock) return layer - offset; } } } diff --git a/core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java b/core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java index fd4a50e9..23f7e83b 100644 --- a/core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java +++ b/core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java @@ -136,6 +136,7 @@ public class HeightMap { // } public int applyLayers(int[] data) throws WorldEditException { + System.out.println("Layers"); checkNotNull(data); Vector minY = region.getMinimumPoint(); @@ -148,6 +149,8 @@ public class HeightMap { int blocksChanged = 0; + BaseBlock tmpBlock = EditSession.nullBlock; + // Apply heightmap int maxY4 = maxY << 4; int index = 0; @@ -160,9 +163,6 @@ public class HeightMap { int newBlock = (newHeight + 7) >> 3; int xr = x + originX; - // We are keeping the topmost blocks so take that in account for the scale - double scale = (double) (curHeight - originY) / (double) (newHeight - originY); - // Depending on growing or shrinking we need to start at the bottom or top if (newHeight > curHeight) { // Set the top block of the column to be the same type (this might go wrong with rounding) @@ -171,9 +171,10 @@ public class HeightMap { // Skip water/lava if (!FaweCache.isLiquidOrGas(existing.getId())) { // Grow -- start from 1 below top replacing airblocks - for (int y = newBlock - 1 - originY; y >= curBlock; --y) { - int copyFrom = (int) (y * scale); - session.setBlock(xr, originY + y, zr, session.getBlock(xr, originY + copyFrom, zr)); + for (int setY = newBlock - 1, getY = curBlock; setY >= curBlock; --setY, getY--) { + BaseBlock get = session.getBlock(xr, getY, zr); + if (get != EditSession.nullBlock) tmpBlock = get; + session.setBlock(xr, setY, zr, tmpBlock); ++blocksChanged; } int setData = newHeight & 7; @@ -213,6 +214,7 @@ public class HeightMap { } public int apply(int[] data) throws WorldEditException { + long start = System.currentTimeMillis(); checkNotNull(data); Vector minY = region.getMinimumPoint(); @@ -225,6 +227,8 @@ public class HeightMap { int blocksChanged = 0; + BaseBlock tmpBlock = EditSession.nullBlock; + // Apply heightmap int index = 0; for (int z = 0; z < height; ++z) { @@ -234,22 +238,21 @@ public class HeightMap { int newHeight = Math.min(maxY, data[index++]); int xr = x + originX; - // We are keeping the topmost blocks so take that in account for the scale - double scale = (double) (curHeight - originY) / (double) (newHeight - originY); - // Depending on growing or shrinking we need to start at the bottom or top if (newHeight > curHeight) { // Set the top block of the column to be the same type (this might go wrong with rounding) BaseBlock existing = session.getBlock(xr, curHeight, zr); + // Skip water/lava if (!FaweCache.isLiquidOrGas(existing.getId())) { - for (int y = curHeight; y <= newHeight - 1 - originY; y++) { - int copyFrom = (int) (y * scale); - session.setBlock(xr, originY + y, zr, session.getBlock(xr, originY + copyFrom, zr)); + int y0 = newHeight - 1; + for (int setY = y0, getY = curHeight - 1; setY >= curHeight; setY--, getY--) { + BaseBlock get = session.getBlock(xr, getY, zr); + if (get != EditSession.nullBlock) tmpBlock = get; + session.setBlock(xr, setY, zr, tmpBlock); ++blocksChanged; } - session.setBlock(xr, newHeight, zr, existing); ++blocksChanged; } @@ -267,7 +270,6 @@ public class HeightMap { } } } - return blocksChanged; }