From 961773ce5d63bb349a559060dc09876824e61b77 Mon Sep 17 00:00:00 2001 From: TomyLobo Date: Fri, 1 Nov 2013 19:05:49 +0100 Subject: [PATCH] Added non-cuboid support for //walls and //outline. --- .../java/com/sk89q/worldedit/EditSession.java | 26 +++++++++++++ .../worldedit/commands/RegionCommands.java | 27 +++++++++----- .../sk89q/worldedit/shape/ArbitraryShape.java | 37 ++++++++++++++----- .../sk89q/worldedit/shape/RegionShape.java | 27 ++++++++++++++ 4 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/sk89q/worldedit/shape/RegionShape.java diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java index 0289b99a2..db294e957 100644 --- a/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/src/main/java/com/sk89q/worldedit/EditSession.java @@ -47,6 +47,7 @@ import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.RegionOperationException; import com.sk89q.worldedit.shape.ArbitraryShape; +import com.sk89q.worldedit.shape.RegionShape; import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment; import com.sk89q.worldedit.util.TreeGenerator; @@ -1527,6 +1528,19 @@ public class EditSession { return affected; } + /** + * Make faces of the region + * + * @param region + * @param pattern + * @return number of blocks affected + * @throws MaxChangedBlocksException + */ + public int makeFaces(final Region region, Pattern pattern) throws MaxChangedBlocksException { + return new RegionShape(region).generate(this, pattern, true); + } + + /** * Make walls of the region (as if it was a cuboid if it's not). * @@ -1627,6 +1641,18 @@ public class EditSession { return affected; } + /** + * Make walls of the region + * + * @param region + * @param pattern + * @return number of blocks affected + * @throws MaxChangedBlocksException + */ + public int makeWalls(final Region region, Pattern pattern) throws MaxChangedBlocksException { + return new RegionShape(region).generate(this, pattern, true, true); + } + /** * Overlays a layer of blocks over a cuboid area. * diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java index 405901aa4..b39fc4ef4 100644 --- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java @@ -44,6 +44,7 @@ import com.sk89q.worldedit.filtering.HeightMapFilter; import com.sk89q.worldedit.masks.Mask; import com.sk89q.worldedit.patterns.Pattern; import com.sk89q.worldedit.patterns.SingleBlockPattern; +import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.RegionOperationException; @@ -191,12 +192,15 @@ public class RegionCommands { public void walls(CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { - Pattern pattern = we.getBlockPattern(player, args.getString(0)); - int affected; - if (pattern instanceof SingleBlockPattern) { - affected = editSession.makeCuboidWalls(session.getSelection(player.getWorld()), ((SingleBlockPattern) pattern).getBlock()); + final Pattern pattern = we.getBlockPattern(player, args.getString(0)); + final int affected; + final Region region = session.getSelection(player.getWorld()); + if (!(region instanceof CuboidRegion)) { + affected = editSession.makeWalls(region, pattern); + } else if (pattern instanceof SingleBlockPattern) { + affected = editSession.makeCuboidWalls(region, ((SingleBlockPattern) pattern).getBlock()); } else { - affected = editSession.makeCuboidWalls(session.getSelection(player.getWorld()), pattern); + affected = editSession.makeCuboidWalls(region, pattern); } player.print(affected + " block(s) have been changed."); @@ -214,12 +218,15 @@ public class RegionCommands { public void faces(CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { - Pattern pattern = we.getBlockPattern(player, args.getString(0)); - int affected; - if (pattern instanceof SingleBlockPattern) { - affected = editSession.makeCuboidFaces(session.getSelection(player.getWorld()), ((SingleBlockPattern) pattern).getBlock()); + final Pattern pattern = we.getBlockPattern(player, args.getString(0)); + final int affected; + final Region region = session.getSelection(player.getWorld()); + if (!(region instanceof CuboidRegion)) { + affected = editSession.makeFaces(region, pattern); + } else if (pattern instanceof SingleBlockPattern) { + affected = editSession.makeCuboidFaces(region, ((SingleBlockPattern) pattern).getBlock()); } else { - affected = editSession.makeCuboidFaces(session.getSelection(player.getWorld()), pattern); + affected = editSession.makeCuboidFaces(region, pattern); } player.print(affected + " block(s) have been changed."); diff --git a/src/main/java/com/sk89q/worldedit/shape/ArbitraryShape.java b/src/main/java/com/sk89q/worldedit/shape/ArbitraryShape.java index 7d5abff09..868cb3e0a 100644 --- a/src/main/java/com/sk89q/worldedit/shape/ArbitraryShape.java +++ b/src/main/java/com/sk89q/worldedit/shape/ArbitraryShape.java @@ -34,7 +34,7 @@ import com.sk89q.worldedit.regions.Region; * @author TomyLobo */ public abstract class ArbitraryShape { - private final Region extent; + protected final Region extent; private int cacheOffsetX; private int cacheOffsetY; private int cacheOffsetZ; @@ -148,6 +148,20 @@ public abstract class ArbitraryShape { * @throws MaxChangedBlocksException */ public int generate(EditSession editSession, Pattern pattern, boolean hollow) throws MaxChangedBlocksException { + return generate(editSession, pattern, hollow, false); + } + + /** + * Generates the shape. + * + * @param editSession The EditSession to use. + * @param pattern The pattern to generate default materials from. + * @param hollow Specifies whether to generate a hollow shape. + * @param flat If hollow mode is enabled, disregard blocks above/below + * @return number of affected blocks. + * @throws MaxChangedBlocksException + */ + public int generate(EditSession editSession, Pattern pattern, boolean hollow, boolean flat) throws MaxChangedBlocksException { int affected = 0; for (BlockVector position : getExtent()) { @@ -179,14 +193,6 @@ public abstract class ArbitraryShape { draw = true; break; } - if (!isInsideCached(x, y + 1, z, pattern)) { - draw = true; - break; - } - if (!isInsideCached(x, y - 1, z, pattern)) { - draw = true; - break; - } if (!isInsideCached(x, y, z + 1, pattern)) { draw = true; break; @@ -195,6 +201,19 @@ public abstract class ArbitraryShape { draw = true; break; } + + if (flat) { + break; + } + + if (!isInsideCached(x, y + 1, z, pattern)) { + draw = true; + break; + } + if (!isInsideCached(x, y - 1, z, pattern)) { + draw = true; + break; + } } while (false); if (!draw) { diff --git a/src/main/java/com/sk89q/worldedit/shape/RegionShape.java b/src/main/java/com/sk89q/worldedit/shape/RegionShape.java new file mode 100644 index 000000000..74cafe2b8 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/shape/RegionShape.java @@ -0,0 +1,27 @@ +package com.sk89q.worldedit.shape; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.shape.ArbitraryShape; + +/** + * Generates solid and hollow shapes according to materials returned by the + * {@link #getMaterial} method. + * + * @author TomyLobo + */ +public class RegionShape extends ArbitraryShape { + public RegionShape(Region extent) { + super(extent); + } + + @Override + protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) { + if (!this.extent.contains(new Vector(x, y, z))) { + return null; + } + + return defaultMaterial; + } +}