mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-02 11:26:42 +00:00
Merge pull request #498 from EngineHub/feature/improved-chunk-batching
Buffered extent improvements
This commit is contained in:
@ -23,44 +23,78 @@ import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.util.LocatedBlock;
|
||||
import com.sk89q.worldedit.util.collection.LocatedBlockList;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class GravityBrush implements Brush {
|
||||
|
||||
private final boolean fullHeight;
|
||||
|
||||
|
||||
public GravityBrush(boolean fullHeight) {
|
||||
this.fullHeight = fullHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
final double startY = fullHeight ? editSession.getWorld().getMaxY() : position.getBlockY() + size;
|
||||
for (double x = position.getBlockX() + size; x > position.getBlockX() - size; --x) {
|
||||
for (double z = position.getBlockZ() + size; z > position.getBlockZ() - size; --z) {
|
||||
double y = startY;
|
||||
final List<BlockState> blockTypes = new ArrayList<>();
|
||||
for (; y > position.getBlockY() - size; --y) {
|
||||
final BlockVector3 pt = BlockVector3.at(x, y, z);
|
||||
final BlockState block = editSession.getBlock(pt);
|
||||
if (!block.getBlockType().getMaterial().isAir()) {
|
||||
blockTypes.add(block);
|
||||
editSession.setBlock(pt, BlockTypes.AIR.getDefaultState());
|
||||
double yMax = fullHeight ? editSession.getWorld().getMaxY() : position.getY() + size;
|
||||
double yMin = Math.max(position.getY() - size, 0);
|
||||
LocatedBlockList column = new LocatedBlockList();
|
||||
Set<BlockVector3> removedBlocks = new LinkedHashSet<>();
|
||||
for (double x = position.getX() - size; x <= position.getX() + size; x++) {
|
||||
for (double z = position.getZ() - size; z <= position.getZ() + size; z++) {
|
||||
/*
|
||||
* Algorithm:
|
||||
* 1. Find lowest air block in the selection -> $lowestAir = position
|
||||
* 2. Move the first non-air block above it down to $lowestAir
|
||||
* 3. Add 1 to $lowestAir's y-coord.
|
||||
* 4. If more blocks above current position, repeat from 2
|
||||
*/
|
||||
|
||||
BlockVector3 lowestAir = null;
|
||||
for (double y = yMin; y <= yMax; y++) {
|
||||
BlockVector3 pt = BlockVector3.at(x, y, z);
|
||||
|
||||
BaseBlock block = editSession.getFullBlock(pt);
|
||||
|
||||
if (block.getBlockType().getMaterial().isAir()) {
|
||||
if (lowestAir == null) {
|
||||
// we found the lowest air block
|
||||
lowestAir = pt;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BlockVector3 pt = BlockVector3.at(x, y, z);
|
||||
Collections.reverse(blockTypes);
|
||||
for (int i = 0; i < blockTypes.size();) {
|
||||
if (editSession.getBlock(pt).getBlockType().getMaterial().isAir()) {
|
||||
editSession.setBlock(pt, blockTypes.get(i++));
|
||||
|
||||
if (lowestAir == null) {
|
||||
// no place to move the block to
|
||||
continue;
|
||||
}
|
||||
pt = pt.add(0, 1, 0);
|
||||
|
||||
BlockVector3 newPos = lowestAir;
|
||||
// we know the block above must be air,
|
||||
// since either this block is being moved into it,
|
||||
// or there has been more air before this block
|
||||
lowestAir = lowestAir.add(0, 1, 0);
|
||||
|
||||
removedBlocks.remove(newPos);
|
||||
column.add(newPos, block);
|
||||
removedBlocks.add(pt);
|
||||
}
|
||||
|
||||
for (LocatedBlock block : column) {
|
||||
editSession.setBlock(block.getLocation(), block.getBlock());
|
||||
}
|
||||
|
||||
for (BlockVector3 removedBlock : removedBlocks) {
|
||||
editSession.setBlock(removedBlock, BlockTypes.AIR.getDefaultState());
|
||||
}
|
||||
|
||||
column.clear();
|
||||
removedBlocks.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user