Skip to content

Commit

Permalink
Merge pull request #531 from EngineHub/wiz/misc-fixes
Browse files Browse the repository at this point in the history
* Make a few more selection commands usable from console.
* Use persistent leaves for garden patch generator (/pumpkins)
* Make lrbuild tool use history.
* Add -n flag to //paste to select without pasting.
  • Loading branch information
wizjany committed Nov 10, 2019
2 parents 1fbb7a7 + fc5c625 commit 23a3929
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 73 deletions.
Expand Up @@ -140,6 +140,8 @@ public void paste(Actor actor, World world, LocalSession session, EditSession ed
boolean atOrigin, boolean atOrigin,
@Switch(name = 's', desc = "Select the region after pasting") @Switch(name = 's', desc = "Select the region after pasting")
boolean selectPasted, boolean selectPasted,
@Switch(name = 'n', desc = "No paste, select only. (Implies -s)")
boolean onlySelect,
@Switch(name = 'e', desc = "Paste entities if available") @Switch(name = 'e', desc = "Paste entities if available")
boolean pasteEntities, boolean pasteEntities,
@Switch(name = 'b', desc = "Paste biomes if available") @Switch(name = 'b', desc = "Paste biomes if available")
Expand All @@ -151,19 +153,23 @@ public void paste(Actor actor, World world, LocalSession session, EditSession ed
ClipboardHolder holder = session.getClipboard(); ClipboardHolder holder = session.getClipboard();
Clipboard clipboard = holder.getClipboard(); Clipboard clipboard = holder.getClipboard();
Region region = clipboard.getRegion(); Region region = clipboard.getRegion();
List<String> messages = Lists.newArrayList();


BlockVector3 to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(actor); BlockVector3 to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(actor);
Operation operation = holder if (!onlySelect) {
.createPaste(editSession) Operation operation = holder
.to(to) .createPaste(editSession)
.ignoreAirBlocks(ignoreAirBlocks) .to(to)
.copyBiomes(pasteBiomes) .ignoreAirBlocks(ignoreAirBlocks)
.copyEntities(pasteEntities) .copyBiomes(pasteBiomes)
.maskSource(sourceMask) .copyEntities(pasteEntities)
.build(); .maskSource(sourceMask)
Operations.completeLegacy(operation); .build();

Operations.completeLegacy(operation);
if (selectPasted) { operation.addStatusMessages(messages);
}

if (selectPasted || onlySelect) {
BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
Vector3 realTo = to.toVector3().add(holder.getTransform().apply(clipboardOffset.toVector3())); Vector3 realTo = to.toVector3().add(holder.getTransform().apply(clipboardOffset.toVector3()));
Vector3 max = realTo.add(holder.getTransform().apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3())); Vector3 max = realTo.add(holder.getTransform().apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3()));
Expand All @@ -173,9 +179,11 @@ public void paste(Actor actor, World world, LocalSession session, EditSession ed
selector.explainRegionAdjust(actor, session); selector.explainRegionAdjust(actor, session);
} }


actor.print("The clipboard has been pasted at " + to); if (onlySelect) {
List<String> messages = Lists.newArrayList(); actor.print("Selected clipboard paste region.");
operation.addStatusMessages(messages); } else {
actor.print("The clipboard has been pasted at " + to);
}
messages.forEach(actor::print); messages.forEach(actor::print);
} }


Expand Down
Expand Up @@ -80,6 +80,7 @@
import org.enginehub.piston.annotation.param.Arg; import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.ArgFlag; import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch; import org.enginehub.piston.annotation.param.Switch;
import org.enginehub.piston.exception.StopExecutionException;


import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
Expand Down Expand Up @@ -206,7 +207,7 @@ public void hpos2(Player player, LocalSession session) throws WorldEditException
) )
@Logging(POSITION) @Logging(POSITION)
@CommandPermissions("worldedit.selection.chunk") @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 = "") @Arg(desc = "The chunk to select", def = "")
BlockVector2 coordinates, BlockVector2 coordinates,
@Switch(name = 's', desc = "Expand your selection to encompass all chunks that are part of it") @Switch(name = 's', desc = "Expand your selection to encompass all chunks that are part of it")
Expand All @@ -215,7 +216,6 @@ public void chunk(Player player, LocalSession session,
boolean useChunkCoordinates) throws WorldEditException { boolean useChunkCoordinates) throws WorldEditException {
final BlockVector3 min; final BlockVector3 min;
final BlockVector3 max; final BlockVector3 max;
final World world = player.getWorld();
if (expandSelection) { if (expandSelection) {
Region region = session.getSelection(world); Region region = session.getSelection(world);


Expand All @@ -225,7 +225,7 @@ public void chunk(Player player, LocalSession session,
min = BlockVector3.at(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16); min = BlockVector3.at(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16);
max = BlockVector3.at(max2D.getBlockX() * 16 + 15, world.getMaxY(), max2D.getBlockZ() * 16 + 15); 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() + ") - (" + min2D.getBlockX() + ", " + min2D.getBlockZ() + ") - ("
+ max2D.getBlockX() + ", " + max2D.getBlockZ() + ")"); + max2D.getBlockX() + ", " + max2D.getBlockZ() + ")");
} else { } else {
Expand All @@ -237,13 +237,17 @@ public void chunk(Player player, LocalSession session,
: ChunkStore.toChunk(coordinates.toBlockVector3()); : ChunkStore.toChunk(coordinates.toBlockVector3());
} else { } else {
// use player loc // 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); min = BlockVector3.at(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16);
max = min.add(15, world.getMaxY(), 15); max = min.add(15, world.getMaxY(), 15);


player.print("Chunk selected: " actor.print("Chunk selected: "
+ min2D.getBlockX() + ", " + min2D.getBlockZ()); + min2D.getBlockX() + ", " + min2D.getBlockZ());
} }


Expand All @@ -253,11 +257,11 @@ public void chunk(Player player, LocalSession session,
} else { } else {
selector = new CuboidRegionSelector(world); selector = new CuboidRegionSelector(world);
} }
selector.selectPrimary(min, ActorSelectorLimits.forActor(player)); selector.selectPrimary(min, ActorSelectorLimits.forActor(actor));
selector.selectSecondary(max, ActorSelectorLimits.forActor(player)); selector.selectSecondary(max, ActorSelectorLimits.forActor(actor));
session.setRegionSelector(world, selector); session.setRegionSelector(world, selector);


session.dispatchCUISelection(player); session.dispatchCUISelection(actor);


} }


Expand Down Expand Up @@ -433,7 +437,7 @@ private BlockVector3[] getChangesForEachDir(int amount, boolean onlyHorizontal,
desc = "Get information about the selection" desc = "Get information about the selection"
) )
@CommandPermissions("worldedit.selection.size") @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") @Switch(name = 'c', desc = "Get clipboard info instead")
boolean clipboardInfo) throws WorldEditException { boolean clipboardInfo) throws WorldEditException {
Region region; Region region;
Expand All @@ -443,23 +447,23 @@ public void size(Player player, LocalSession session,
region = clipboard.getRegion(); region = clipboard.getRegion();


BlockVector3 origin = clipboard.getOrigin(); BlockVector3 origin = clipboard.getOrigin();
player.print("Offset: " + origin); actor.print("Offset: " + origin);
} else { } 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()) { for (String line : session.getRegionSelector(world).getInformationLines()) {
player.print(line); actor.print(line);
} }
} }
BlockVector3 size = region.getMaximumPoint() BlockVector3 size = region.getMaximumPoint()
.subtract(region.getMinimumPoint()) .subtract(region.getMinimumPoint())
.add(1, 1, 1); .add(1, 1, 1);


player.print("Size: " + size); actor.print("Size: " + size);
player.print("Cuboid distance: " + region.getMaximumPoint().distance(region.getMinimumPoint())); actor.print("Cuboid distance: " + region.getMaximumPoint().distance(region.getMinimumPoint()));
player.print("# of blocks: " + region.getArea()); actor.print("# of blocks: " + region.getArea());
} }




Expand All @@ -468,19 +472,19 @@ public void size(Player player, LocalSession session,
desc = "Counts the number of blocks matching a mask" desc = "Counts the number of blocks matching a mask"
) )
@CommandPermissions("worldedit.analysis.count") @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") @Arg(desc = "The mask of blocks to match")
Mask mask) throws WorldEditException { Mask mask) throws WorldEditException {
int count = editSession.countBlocks(session.getSelection(player.getWorld()), mask); int count = editSession.countBlocks(session.getSelection(world), mask);
player.print("Counted: " + count); actor.print("Counted: " + count);
} }


@Command( @Command(
name = "/distr", name = "/distr",
desc = "Get the distribution of blocks in the selection" desc = "Get the distribution of blocks in the selection"
) )
@CommandPermissions("worldedit.analysis.distr") @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") @Switch(name = 'c', desc = "Get the distribution of the clipboard instead")
boolean clipboardDistr, boolean clipboardDistr,
@Switch(name = 'd', desc = "Separate blocks by state") @Switch(name = 'd', desc = "Separate blocks by state")
Expand All @@ -497,28 +501,32 @@ public void distr(Player player, LocalSession session,
Operations.completeBlindly(visitor); Operations.completeBlindly(visitor);
distribution = count.getDistribution(); distribution = count.getDistribution();
} else { } else {
try (EditSession editSession = session.createEditSession(player)) { try (EditSession editSession = session.createEditSession(actor)) {
distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld()), separateStates); distribution = editSession.getBlockDistribution(session.getSelection(world), separateStates);
} }
} }
session.setLastDistribution(distribution); session.setLastDistribution(distribution);
page = 1; page = 1;
} else { } else {
distribution = session.getLastDistribution(); distribution = session.getLastDistribution();
if (distribution == null) { if (distribution == null) {
player.printError("No previous distribution."); actor.printError("No previous distribution.");
return; return;
} }
} }


if (distribution.isEmpty()) { // *Should* always be false if (distribution.isEmpty()) { // *Should* always be false
player.printError("No blocks counted."); actor.printError("No blocks counted.");
return; return;
} }


final int finalPage = page; final int finalPage = page;
WorldEditAsyncCommandBuilder.createAndSendMessage(player, WorldEditAsyncCommandBuilder.createAndSendMessage(actor,
() -> new BlockDistributionResult(distribution, separateStates).create(finalPage), null); () -> {
BlockDistributionResult res = new BlockDistributionResult(distribution, separateStates);
if (!actor.isPlayer()) res.formatForConsole();
return res.create(finalPage);
}, null);
} }


@Command( @Command(
Expand Down
Expand Up @@ -26,6 +26,7 @@
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform; 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.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
Expand Down Expand Up @@ -55,41 +56,56 @@ public boolean canUse(Actor player) {
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) { public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
Location pos = getTargetFace(player); Location pos = getTargetFace(player);
if (pos == null) return false; if (pos == null) return false;
try (EditSession eS = session.createEditSession(player)) { BlockBag bag = session.getBlockBag(player);
eS.disableBuffering();
BlockVector3 blockPoint = pos.toVector().toBlockPoint(); try (EditSession editSession = session.createEditSession(player)) {
BaseBlock applied = secondary.apply(blockPoint); try {
if (applied.getBlockType().getMaterial().isAir()) { editSession.disableBuffering();
eS.setBlock(blockPoint, secondary); BlockVector3 blockPoint = pos.toVector().toBlockPoint();
} else { BaseBlock applied = secondary.apply(blockPoint);
eS.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), secondary); 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;
} catch (MaxChangedBlocksException ignored) {
// one block? eat it
} }
return false; return true;

} }


@Override @Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) { public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
Location pos = getTargetFace(player); Location pos = getTargetFace(player);
if (pos == null) return false; if (pos == null) return false;
try (EditSession eS = session.createEditSession(player)) { BlockBag bag = session.getBlockBag(player);
eS.disableBuffering();
BlockVector3 blockPoint = pos.toVector().toBlockPoint(); try (EditSession editSession = session.createEditSession(player)) {
BaseBlock applied = primary.apply(blockPoint); try {
if (applied.getBlockType().getMaterial().isAir()) { editSession.disableBuffering();
eS.setBlock(blockPoint, primary); BlockVector3 blockPoint = pos.toVector().toBlockPoint();
} else { BaseBlock applied = primary.apply(blockPoint);
eS.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), primary); 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) { private Location getTargetFace(Player player) {
Expand Down
Expand Up @@ -26,7 +26,6 @@
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;


import java.util.Random; import java.util.Random;
Expand All @@ -39,6 +38,7 @@ public class GardenPatchGenerator implements RegionFunction {
private final Random random = new Random(); private final Random random = new Random();
private final EditSession editSession; private final EditSession editSession;
private Pattern plant = getPumpkinPattern(); private Pattern plant = getPumpkinPattern();
private Pattern leafPattern = BlockTypes.OAK_LEAVES.getDefaultState().with(BlockTypes.OAK_LEAVES.getProperty("persistent"), true);
private int affected; private int affected;


/** /**
Expand Down Expand Up @@ -96,7 +96,7 @@ private void placeVine(BlockVector3 basePos, BlockVector3 pos) throws MaxChanged
} }
} }


setBlockIfAir(editSession, pos, BlockTypes.OAK_LEAVES.getDefaultState()); setBlockIfAir(editSession, pos, leafPattern);
affected++; affected++;


int t = random.nextInt(4); int t = random.nextInt(4);
Expand Down Expand Up @@ -166,10 +166,9 @@ public boolean apply(BlockVector3 position) throws WorldEditException {
return false; return false;
} }


BlockState leavesBlock = BlockTypes.OAK_LEAVES.getDefaultState();


if (editSession.getBlock(position).getBlockType().getMaterial().isAir()) { if (editSession.getBlock(position).getBlockType().getMaterial().isAir()) {
editSession.setBlock(position, leavesBlock); editSession.setBlock(position, leafPattern);
} }


placeVine(position, position.add(0, 0, 1)); placeVine(position, position.add(0, 0, 1));
Expand All @@ -193,12 +192,12 @@ public static Pattern getPumpkinPattern() {
* Set a block only if there's no block already there. * Set a block only if there's no block already there.
* *
* @param position the position * @param position the position
* @param block the block to set * @param pattern the pattern to set
* @return if block was changed * @return if block was changed
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
private static <B extends BlockStateHolder<B>> boolean setBlockIfAir(EditSession session, BlockVector3 position, B block) throws MaxChangedBlocksException { private static boolean setBlockIfAir(EditSession session, BlockVector3 position, Pattern pattern) throws MaxChangedBlocksException {
return session.getBlock(position).getBlockType().getMaterial().isAir() && session.setBlock(position, block); return session.getBlock(position).getBlockType().getMaterial().isAir() && session.setBlock(position, pattern);
} }


/** /**
Expand Down

0 comments on commit 23a3929

Please sign in to comment.