Fix heightmap in height restricted regions

This commit is contained in:
Jesse Boyd 2017-11-12 13:37:27 +11:00
parent 0bac7251c1
commit 6873e45b6f
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
3 changed files with 24 additions and 20 deletions

View File

@ -74,6 +74,7 @@ public interface HeightMap {
if (towards) { if (towards) {
double sizePow = Math.pow(size, yscale); double sizePow = Math.pow(size, yscale);
int targetY = pos.getBlockY(); int targetY = pos.getBlockY();
int tmpY = targetY;
for (int x = -size; x <= size; x++) { for (int x = -size; x <= size; x++) {
int xx = centerX + x; int xx = centerX + x;
mutablePos.mutX(xx); mutablePos.mutX(xx);
@ -97,9 +98,9 @@ public interface HeightMap {
} }
int height; int height;
if (layers) { if (layers) {
height = session.getNearestSurfaceLayer(xx, zz, pos.getBlockY(), 0, maxY); height = tmpY = session.getNearestSurfaceLayer(xx, zz, tmpY, 0, maxY);
} else { } else {
height = session.getNearestSurfaceTerrainBlock(xx, zz, pos.getBlockY(), 0, maxY); height = tmpY = session.getNearestSurfaceTerrainBlock(xx, zz, tmpY, 0, maxY);
if (height == -1) continue; if (height == -1) continue;
} }
oldData[index] = height; oldData[index] = height;

View File

@ -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.Resource;
import com.boydti.fawe.jnbt.anvil.generator.SchemGen; import com.boydti.fawe.jnbt.anvil.generator.SchemGen;
import com.boydti.fawe.object.PseudoRandom; import com.boydti.fawe.object.PseudoRandom;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MutableBlockVector; import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
@ -121,21 +122,21 @@ public interface Extent extends InputExtent, OutputExtent {
for (int d = 0; d <= clearance; d++) { for (int d = 0; d <= clearance; d++) {
int y1 = y + d; int y1 = y + d;
block = getLazyBlock(x, y1, z); 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; int y2 = y - d;
block = getLazyBlock(x, y2, z); 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) {
if (clearanceAbove < clearanceBelow) { if (clearanceAbove < clearanceBelow) {
for (int layer = y - clearance - 1; layer >= minY; layer--) { for (int layer = y - clearance - 1; layer >= minY; layer--) {
block = getLazyBlock(x, layer, z); 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 { } else {
for (int layer = y + clearance + 1; layer <= maxY; layer++) { for (int layer = y + clearance + 1; layer <= maxY; layer++) {
block = getLazyBlock(x, layer, z); 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;
} }
} }
} }

View File

@ -136,6 +136,7 @@ public class HeightMap {
// } // }
public int applyLayers(int[] data) throws WorldEditException { public int applyLayers(int[] data) throws WorldEditException {
System.out.println("Layers");
checkNotNull(data); checkNotNull(data);
Vector minY = region.getMinimumPoint(); Vector minY = region.getMinimumPoint();
@ -148,6 +149,8 @@ public class HeightMap {
int blocksChanged = 0; int blocksChanged = 0;
BaseBlock tmpBlock = EditSession.nullBlock;
// Apply heightmap // Apply heightmap
int maxY4 = maxY << 4; int maxY4 = maxY << 4;
int index = 0; int index = 0;
@ -160,9 +163,6 @@ public class HeightMap {
int newBlock = (newHeight + 7) >> 3; int newBlock = (newHeight + 7) >> 3;
int xr = x + originX; 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 // Depending on growing or shrinking we need to start at the bottom or top
if (newHeight > curHeight) { if (newHeight > curHeight) {
// Set the top block of the column to be the same type (this might go wrong with rounding) // 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 // Skip water/lava
if (!FaweCache.isLiquidOrGas(existing.getId())) { if (!FaweCache.isLiquidOrGas(existing.getId())) {
// Grow -- start from 1 below top replacing airblocks // Grow -- start from 1 below top replacing airblocks
for (int y = newBlock - 1 - originY; y >= curBlock; --y) { for (int setY = newBlock - 1, getY = curBlock; setY >= curBlock; --setY, getY--) {
int copyFrom = (int) (y * scale); BaseBlock get = session.getBlock(xr, getY, zr);
session.setBlock(xr, originY + y, zr, session.getBlock(xr, originY + copyFrom, zr)); if (get != EditSession.nullBlock) tmpBlock = get;
session.setBlock(xr, setY, zr, tmpBlock);
++blocksChanged; ++blocksChanged;
} }
int setData = newHeight & 7; int setData = newHeight & 7;
@ -213,6 +214,7 @@ public class HeightMap {
} }
public int apply(int[] data) throws WorldEditException { public int apply(int[] data) throws WorldEditException {
long start = System.currentTimeMillis();
checkNotNull(data); checkNotNull(data);
Vector minY = region.getMinimumPoint(); Vector minY = region.getMinimumPoint();
@ -225,6 +227,8 @@ public class HeightMap {
int blocksChanged = 0; int blocksChanged = 0;
BaseBlock tmpBlock = EditSession.nullBlock;
// Apply heightmap // Apply heightmap
int index = 0; int index = 0;
for (int z = 0; z < height; ++z) { for (int z = 0; z < height; ++z) {
@ -234,22 +238,21 @@ public class HeightMap {
int newHeight = Math.min(maxY, data[index++]); int newHeight = Math.min(maxY, data[index++]);
int xr = x + originX; 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 // Depending on growing or shrinking we need to start at the bottom or top
if (newHeight > curHeight) { if (newHeight > curHeight) {
// Set the top block of the column to be the same type (this might go wrong with rounding) // 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); BaseBlock existing = session.getBlock(xr, curHeight, zr);
// Skip water/lava // Skip water/lava
if (!FaweCache.isLiquidOrGas(existing.getId())) { if (!FaweCache.isLiquidOrGas(existing.getId())) {
for (int y = curHeight; y <= newHeight - 1 - originY; y++) { int y0 = newHeight - 1;
int copyFrom = (int) (y * scale); for (int setY = y0, getY = curHeight - 1; setY >= curHeight; setY--, getY--) {
session.setBlock(xr, originY + y, zr, session.getBlock(xr, originY + copyFrom, zr)); BaseBlock get = session.getBlock(xr, getY, zr);
if (get != EditSession.nullBlock) tmpBlock = get;
session.setBlock(xr, setY, zr, tmpBlock);
++blocksChanged; ++blocksChanged;
} }
session.setBlock(xr, newHeight, zr, existing); session.setBlock(xr, newHeight, zr, existing);
++blocksChanged; ++blocksChanged;
} }
@ -267,7 +270,6 @@ public class HeightMap {
} }
} }
} }
return blocksChanged; return blocksChanged;
} }