//Clamp newHeight within the selection area
public int applyLayers(int[] data) {
        checkNotNull(data);
        BlockVector3 minY = region.getMinimumPoint();
        int originX = minY.getBlockX();
        int originZ = minY.getBlockZ();
        int maxY = region.getMaximumPoint().getBlockY();
        BlockState fillerAir = BlockTypes.AIR.getDefaultState();
        int blocksChanged = 0;
        BlockStateHolder<BlockState> tmpBlock = BlockTypes.AIR.getDefaultState();
        int maxY4 = maxY << 4;
        int index = 0;
        // Apply heightmap
        for (int z = 0; z < height; ++z) {
            int zr = z + originZ;
            for (int x = 0; x < width; ++x) {
                if (this.invalid != null && this.invalid[index]) {
                    continue;
                }
                int curHeight = this.data[index];
                //Clamp newHeight within the selection area
                int newHeight = Math.min(maxY4, data[index++]);
                int curBlock = (curHeight) >> 4;
                int newBlock = (newHeight + 15) >> 4;
                // Offset x,z to be 'real' coordinates
                int xr = x + originX;
                // 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)
                    BlockStateHolder<BlockState> existing = session.getBlock(xr, curBlock, zr);
                    // Skip water/lava
                    if (existing.getBlockType().getMaterial().isMovementBlocker()) {
                        // Grow -- start from 1 below top replacing airblocks
                        for (int setY = newBlock - 1, getY = curBlock; setY >= curBlock; --setY, getY--) {
                            BlockStateHolder<BlockState> get = session.getBlock(xr, getY, zr);
                            if (get != BlockTypes.AIR.getDefaultState()) {
                                tmpBlock = get;
                            }
                            session.setBlock(xr, setY, zr, tmpBlock);
                            ++blocksChanged;
                        }
                        int setData = newHeight & 15;
                        if (setData != 0) {
                            existing = PropertyGroup.LEVEL.set(existing, setData - 1);
                            session.setBlock(xr, newBlock, zr, existing);
                            ++blocksChanged;
                        } else {
                            existing = PropertyGroup.LEVEL.set(existing, 15);
                            session.setBlock(xr, newBlock, zr, existing);
                            ++blocksChanged;
                        }
                    }
                } else if (curHeight > newHeight) {
                    // Fill rest with air
                    for (int y = newBlock + 1; y <= ((curHeight + 15) >> 4); ++y) {
                        session.setBlock(xr, y, zr, fillerAir);
                        ++blocksChanged;
                    }
                    // Set the top block of the column to be the same type
                    // (this could otherwise go wrong with rounding)
                    int setData = newHeight & 15;
                    BlockStateHolder<BlockState> existing = session.getBlock(xr, curBlock, zr);
                    if (setData != 0) {
                        existing = PropertyGroup.LEVEL.set(existing, setData - 1);
                        session.setBlock(xr, newBlock, zr, existing);
                    } else {
                        existing = PropertyGroup.LEVEL.set(existing, 15);
                        session.setBlock(xr, newBlock, zr, existing);
                    }
                    ++blocksChanged;
                }
            }
        }
        return blocksChanged;
    }
}
int curHeight = this.data[index];
//Clamp newHeight within the selection area
int newHeight = Math.min(maxY4, data[index++]);
int curBlock = (curHeight) >> 4;
int maxY4 = maxY << 4;
int index = 0;
// Apply heightmap
for (int z = 0; z < height; ++z) {
int zr = z + originZ;
for (int x = 0; x < width; ++x) {
if (this.invalid != null && this.invalid[index]) {
continue;
}
int curHeight = this.data[index];
//Clamp newHeight within the selection area
int newHeight = Math.min(maxY4, data[index++]);
int curBlock = (curHeight) >> 4;
int newBlock = (newHeight + 15) >> 4;
// Offset x,z to be 'real' coordinates
int xr = x + originX;
// 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)
BlockStateHolder<BlockState> existing = session.getBlock(xr, curBlock, zr);
// Skip water/lava
public int applyLayers(int[] data) {
checkNotNull(data);
BlockVector3 minY = region.getMinimumPoint();
int originX = minY.getBlockX();
int originZ = minY.getBlockZ();
int maxY = region.getMaximumPoint().getBlockY();
BlockState fillerAir = BlockTypes.AIR.getDefaultState();
int blocksChanged = 0;
BlockStateHolder<BlockState> tmpBlock = BlockTypes.AIR.getDefaultState();
int maxY4 = maxY << 4;
int index = 0;
// Apply heightmap
for (int z = 0; z < height; ++z) {
int zr = z + originZ;
for (int x = 0; x < width; ++x) {
if (this.invalid != null && this.invalid[index]) {
continue;
}
int curHeight = this.data[index];
//Clamp newHeight within the selection area
int newHeight = Math.min(maxY4, data[index++]);
int curBlock = (curHeight) >> 4;
int newBlock = (newHeight + 15) >> 4;
// Offset x,z to be 'real' coordinates
int xr = x + originX;
// 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)
BlockStateHolder<BlockState> existing = session.getBlock(xr, curBlock, zr);
// Skip water/lava
if (existing.getBlockType().getMaterial().isMovementBlocker()) {
// Grow -- start from 1 below top replacing airblocks
for (int setY = newBlock - 1, getY = curBlock; setY >= curBlock; --setY, getY--) {
BlockStateHolder<BlockState> get = session.getBlock(xr, getY, zr);
if (get != BlockTypes.AIR.getDefaultState()) {
tmpBlock = get;
}
session.setBlock(xr, setY, zr, tmpBlock);
++blocksChanged;
}