diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index 1b583aef5..b90fe7786 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -140,6 +140,8 @@ public class ClipboardCommands { boolean atOrigin, @Switch(name = 's', desc = "Select the region after pasting") boolean selectPasted, + @Switch(name = 'n', desc = "No paste, select only. (Implies -s)") + boolean onlySelect, @Switch(name = 'e', desc = "Paste entities if available") boolean pasteEntities, @Switch(name = 'b', desc = "Paste biomes if available") @@ -151,19 +153,23 @@ public class ClipboardCommands { ClipboardHolder holder = session.getClipboard(); Clipboard clipboard = holder.getClipboard(); Region region = clipboard.getRegion(); + List messages = Lists.newArrayList(); BlockVector3 to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(actor); - Operation operation = holder - .createPaste(editSession) - .to(to) - .ignoreAirBlocks(ignoreAirBlocks) - .copyBiomes(pasteBiomes) - .copyEntities(pasteEntities) - .maskSource(sourceMask) - .build(); - Operations.completeLegacy(operation); + if (!onlySelect) { + Operation operation = holder + .createPaste(editSession) + .to(to) + .ignoreAirBlocks(ignoreAirBlocks) + .copyBiomes(pasteBiomes) + .copyEntities(pasteEntities) + .maskSource(sourceMask) + .build(); + Operations.completeLegacy(operation); + operation.addStatusMessages(messages); + } - if (selectPasted) { + if (selectPasted || onlySelect) { BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); Vector3 realTo = to.toVector3().add(holder.getTransform().apply(clipboardOffset.toVector3())); Vector3 max = realTo.add(holder.getTransform().apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3())); @@ -173,9 +179,11 @@ public class ClipboardCommands { selector.explainRegionAdjust(actor, session); } - actor.print("The clipboard has been pasted at " + to); - List messages = Lists.newArrayList(); - operation.addStatusMessages(messages); + if (onlySelect) { + actor.print("Selected clipboard paste region."); + } else { + actor.print("The clipboard has been pasted at " + to); + } messages.forEach(actor::print); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index 431785923..5cf8dc676 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -80,6 +80,7 @@ import org.enginehub.piston.annotation.CommandContainer; import org.enginehub.piston.annotation.param.Arg; import org.enginehub.piston.annotation.param.ArgFlag; import org.enginehub.piston.annotation.param.Switch; +import org.enginehub.piston.exception.StopExecutionException; import java.util.List; import java.util.Optional; @@ -206,7 +207,7 @@ public class SelectionCommands { ) @Logging(POSITION) @CommandPermissions("worldedit.selection.chunk") - public void chunk(Player player, LocalSession session, + public void chunk(Actor actor, World world, LocalSession session, @Arg(desc = "The chunk to select", def = "") BlockVector2 coordinates, @Switch(name = 's', desc = "Expand your selection to encompass all chunks that are part of it") @@ -215,7 +216,6 @@ public class SelectionCommands { boolean useChunkCoordinates) throws WorldEditException { final BlockVector3 min; final BlockVector3 max; - final World world = player.getWorld(); if (expandSelection) { Region region = session.getSelection(world); @@ -225,7 +225,7 @@ public class SelectionCommands { min = BlockVector3.at(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16); max = BlockVector3.at(max2D.getBlockX() * 16 + 15, world.getMaxY(), max2D.getBlockZ() * 16 + 15); - player.print("Chunks selected: (" + actor.print("Chunks selected: (" + min2D.getBlockX() + ", " + min2D.getBlockZ() + ") - (" + max2D.getBlockX() + ", " + max2D.getBlockZ() + ")"); } else { @@ -237,13 +237,17 @@ public class SelectionCommands { : ChunkStore.toChunk(coordinates.toBlockVector3()); } else { // use player loc - min2D = ChunkStore.toChunk(player.getBlockLocation().toVector().toBlockPoint()); + if (actor instanceof Locatable) { + min2D = ChunkStore.toChunk(((Locatable) actor).getBlockLocation().toVector().toBlockPoint()); + } else { + throw new StopExecutionException(TextComponent.of("A player or coordinates are required.")); + } } min = BlockVector3.at(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16); max = min.add(15, world.getMaxY(), 15); - player.print("Chunk selected: " + actor.print("Chunk selected: " + min2D.getBlockX() + ", " + min2D.getBlockZ()); } @@ -253,11 +257,11 @@ public class SelectionCommands { } else { selector = new CuboidRegionSelector(world); } - selector.selectPrimary(min, ActorSelectorLimits.forActor(player)); - selector.selectSecondary(max, ActorSelectorLimits.forActor(player)); + selector.selectPrimary(min, ActorSelectorLimits.forActor(actor)); + selector.selectSecondary(max, ActorSelectorLimits.forActor(actor)); session.setRegionSelector(world, selector); - session.dispatchCUISelection(player); + session.dispatchCUISelection(actor); } @@ -433,7 +437,7 @@ public class SelectionCommands { desc = "Get information about the selection" ) @CommandPermissions("worldedit.selection.size") - public void size(Player player, LocalSession session, + public void size(Actor actor, World world, LocalSession session, @Switch(name = 'c', desc = "Get clipboard info instead") boolean clipboardInfo) throws WorldEditException { Region region; @@ -443,23 +447,23 @@ public class SelectionCommands { region = clipboard.getRegion(); BlockVector3 origin = clipboard.getOrigin(); - player.print("Offset: " + origin); + actor.print("Offset: " + origin); } else { - region = session.getSelection(player.getWorld()); + region = session.getSelection(world); - player.print("Type: " + session.getRegionSelector(player.getWorld()).getTypeName()); + actor.print("Type: " + session.getRegionSelector(world).getTypeName()); - for (String line : session.getRegionSelector(player.getWorld()).getInformationLines()) { - player.print(line); + for (String line : session.getRegionSelector(world).getInformationLines()) { + actor.print(line); } } BlockVector3 size = region.getMaximumPoint() .subtract(region.getMinimumPoint()) .add(1, 1, 1); - player.print("Size: " + size); - player.print("Cuboid distance: " + region.getMaximumPoint().distance(region.getMinimumPoint())); - player.print("# of blocks: " + region.getArea()); + actor.print("Size: " + size); + actor.print("Cuboid distance: " + region.getMaximumPoint().distance(region.getMinimumPoint())); + actor.print("# of blocks: " + region.getArea()); } @@ -468,11 +472,11 @@ public class SelectionCommands { desc = "Counts the number of blocks matching a mask" ) @CommandPermissions("worldedit.analysis.count") - public void count(Player player, LocalSession session, EditSession editSession, + public void count(Actor actor, World world, LocalSession session, EditSession editSession, @Arg(desc = "The mask of blocks to match") Mask mask) throws WorldEditException { - int count = editSession.countBlocks(session.getSelection(player.getWorld()), mask); - player.print("Counted: " + count); + int count = editSession.countBlocks(session.getSelection(world), mask); + actor.print("Counted: " + count); } @Command( @@ -480,7 +484,7 @@ public class SelectionCommands { desc = "Get the distribution of blocks in the selection" ) @CommandPermissions("worldedit.analysis.distr") - public void distr(Player player, LocalSession session, + public void distr(Actor actor, World world, LocalSession session, @Switch(name = 'c', desc = "Get the distribution of the clipboard instead") boolean clipboardDistr, @Switch(name = 'd', desc = "Separate blocks by state") @@ -497,8 +501,8 @@ public class SelectionCommands { Operations.completeBlindly(visitor); distribution = count.getDistribution(); } else { - try (EditSession editSession = session.createEditSession(player)) { - distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld()), separateStates); + try (EditSession editSession = session.createEditSession(actor)) { + distribution = editSession.getBlockDistribution(session.getSelection(world), separateStates); } } session.setLastDistribution(distribution); @@ -506,19 +510,23 @@ public class SelectionCommands { } else { distribution = session.getLastDistribution(); if (distribution == null) { - player.printError("No previous distribution."); + actor.printError("No previous distribution."); return; } } if (distribution.isEmpty()) { // *Should* always be false - player.printError("No blocks counted."); + actor.printError("No blocks counted."); return; } final int finalPage = page; - WorldEditAsyncCommandBuilder.createAndSendMessage(player, - () -> new BlockDistributionResult(distribution, separateStates).create(finalPage), null); + WorldEditAsyncCommandBuilder.createAndSendMessage(actor, + () -> { + BlockDistributionResult res = new BlockDistributionResult(distribution, separateStates); + if (!actor.isPlayer()) res.formatForConsole(); + return res.create(finalPage); + }, null); } @Command( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java index 66366f0e3..f82d6961f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java @@ -26,6 +26,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; @@ -55,41 +56,56 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) { Location pos = getTargetFace(player); if (pos == null) return false; - try (EditSession eS = session.createEditSession(player)) { - eS.disableBuffering(); - BlockVector3 blockPoint = pos.toVector().toBlockPoint(); - BaseBlock applied = secondary.apply(blockPoint); - if (applied.getBlockType().getMaterial().isAir()) { - eS.setBlock(blockPoint, secondary); - } else { - eS.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), secondary); - } - return true; - } catch (MaxChangedBlocksException ignored) { - // one block? eat it - } - return false; + BlockBag bag = session.getBlockBag(player); + try (EditSession editSession = session.createEditSession(player)) { + try { + editSession.disableBuffering(); + BlockVector3 blockPoint = pos.toVector().toBlockPoint(); + BaseBlock applied = secondary.apply(blockPoint); + if (applied.getBlockType().getMaterial().isAir()) { + editSession.setBlock(blockPoint, secondary); + } else { + editSession.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), secondary); + } + } catch (MaxChangedBlocksException ignored) { + } finally { + session.remember(editSession); + } + } finally { + if (bag != null) { + bag.flushChanges(); + } + } + return true; } @Override public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) { Location pos = getTargetFace(player); if (pos == null) return false; - try (EditSession eS = session.createEditSession(player)) { - eS.disableBuffering(); - BlockVector3 blockPoint = pos.toVector().toBlockPoint(); - BaseBlock applied = primary.apply(blockPoint); - if (applied.getBlockType().getMaterial().isAir()) { - eS.setBlock(blockPoint, primary); - } else { - eS.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), primary); + BlockBag bag = session.getBlockBag(player); + + try (EditSession editSession = session.createEditSession(player)) { + try { + editSession.disableBuffering(); + BlockVector3 blockPoint = pos.toVector().toBlockPoint(); + BaseBlock applied = primary.apply(blockPoint); + if (applied.getBlockType().getMaterial().isAir()) { + editSession.setBlock(blockPoint, primary); + } else { + editSession.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), primary); + } + } catch (MaxChangedBlocksException ignored) { + } finally { + session.remember(editSession); + } + } finally { + if (bag != null) { + bag.flushChanges(); } - return true; - } catch (MaxChangedBlocksException ignored) { - // one block? eat it } - return false; + return true; } private Location getTargetFace(Player player) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java index 5d1aa01c5..19f5ed855 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java @@ -26,7 +26,6 @@ import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockTypes; import java.util.Random; @@ -39,6 +38,7 @@ public class GardenPatchGenerator implements RegionFunction { private final Random random = new Random(); private final EditSession editSession; private Pattern plant = getPumpkinPattern(); + private Pattern leafPattern = BlockTypes.OAK_LEAVES.getDefaultState().with(BlockTypes.OAK_LEAVES.getProperty("persistent"), true); private int affected; /** @@ -96,7 +96,7 @@ public class GardenPatchGenerator implements RegionFunction { } } - setBlockIfAir(editSession, pos, BlockTypes.OAK_LEAVES.getDefaultState()); + setBlockIfAir(editSession, pos, leafPattern); affected++; int t = random.nextInt(4); @@ -166,10 +166,9 @@ public class GardenPatchGenerator implements RegionFunction { return false; } - BlockState leavesBlock = BlockTypes.OAK_LEAVES.getDefaultState(); if (editSession.getBlock(position).getBlockType().getMaterial().isAir()) { - editSession.setBlock(position, leavesBlock); + editSession.setBlock(position, leafPattern); } placeVine(position, position.add(0, 0, 1)); @@ -193,12 +192,12 @@ public class GardenPatchGenerator implements RegionFunction { * Set a block only if there's no block already there. * * @param position the position - * @param block the block to set + * @param pattern the pattern to set * @return if block was changed * @throws MaxChangedBlocksException thrown if too many blocks are changed */ - private static > boolean setBlockIfAir(EditSession session, BlockVector3 position, B block) throws MaxChangedBlocksException { - return session.getBlock(position).getBlockType().getMaterial().isAir() && session.setBlock(position, block); + private static boolean setBlockIfAir(EditSession session, BlockVector3 position, Pattern pattern) throws MaxChangedBlocksException { + return session.getBlock(position).getBlockType().getMaterial().isAir() && session.setBlock(position, pattern); } /**