Added non-cuboid support for //walls and //outline.

This commit is contained in:
TomyLobo 2013-11-01 19:05:49 +01:00
parent 6e3d8395df
commit 961773ce5d
4 changed files with 98 additions and 19 deletions

View File

@ -47,6 +47,7 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException; import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.shape.ArbitraryShape; import com.sk89q.worldedit.shape.ArbitraryShape;
import com.sk89q.worldedit.shape.RegionShape;
import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment; import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.TreeGenerator;
@ -1527,6 +1528,19 @@ public class EditSession {
return affected; 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). * Make walls of the region (as if it was a cuboid if it's not).
* *
@ -1627,6 +1641,18 @@ public class EditSession {
return affected; 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. * Overlays a layer of blocks over a cuboid area.
* *

View File

@ -44,6 +44,7 @@ import com.sk89q.worldedit.filtering.HeightMapFilter;
import com.sk89q.worldedit.masks.Mask; import com.sk89q.worldedit.masks.Mask;
import com.sk89q.worldedit.patterns.Pattern; import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern; import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException; import com.sk89q.worldedit.regions.RegionOperationException;
@ -191,12 +192,15 @@ public class RegionCommands {
public void walls(CommandContext args, LocalSession session, LocalPlayer player, public void walls(CommandContext args, LocalSession session, LocalPlayer player,
EditSession editSession) throws WorldEditException { EditSession editSession) throws WorldEditException {
Pattern pattern = we.getBlockPattern(player, args.getString(0)); final Pattern pattern = we.getBlockPattern(player, args.getString(0));
int affected; final int affected;
if (pattern instanceof SingleBlockPattern) { final Region region = session.getSelection(player.getWorld());
affected = editSession.makeCuboidWalls(session.getSelection(player.getWorld()), ((SingleBlockPattern) pattern).getBlock()); if (!(region instanceof CuboidRegion)) {
affected = editSession.makeWalls(region, pattern);
} else if (pattern instanceof SingleBlockPattern) {
affected = editSession.makeCuboidWalls(region, ((SingleBlockPattern) pattern).getBlock());
} else { } else {
affected = editSession.makeCuboidWalls(session.getSelection(player.getWorld()), pattern); affected = editSession.makeCuboidWalls(region, pattern);
} }
player.print(affected + " block(s) have been changed."); player.print(affected + " block(s) have been changed.");
@ -214,12 +218,15 @@ public class RegionCommands {
public void faces(CommandContext args, LocalSession session, LocalPlayer player, public void faces(CommandContext args, LocalSession session, LocalPlayer player,
EditSession editSession) throws WorldEditException { EditSession editSession) throws WorldEditException {
Pattern pattern = we.getBlockPattern(player, args.getString(0)); final Pattern pattern = we.getBlockPattern(player, args.getString(0));
int affected; final int affected;
if (pattern instanceof SingleBlockPattern) { final Region region = session.getSelection(player.getWorld());
affected = editSession.makeCuboidFaces(session.getSelection(player.getWorld()), ((SingleBlockPattern) pattern).getBlock()); if (!(region instanceof CuboidRegion)) {
affected = editSession.makeFaces(region, pattern);
} else if (pattern instanceof SingleBlockPattern) {
affected = editSession.makeCuboidFaces(region, ((SingleBlockPattern) pattern).getBlock());
} else { } else {
affected = editSession.makeCuboidFaces(session.getSelection(player.getWorld()), pattern); affected = editSession.makeCuboidFaces(region, pattern);
} }
player.print(affected + " block(s) have been changed."); player.print(affected + " block(s) have been changed.");

View File

@ -34,7 +34,7 @@ import com.sk89q.worldedit.regions.Region;
* @author TomyLobo * @author TomyLobo
*/ */
public abstract class ArbitraryShape { public abstract class ArbitraryShape {
private final Region extent; protected final Region extent;
private int cacheOffsetX; private int cacheOffsetX;
private int cacheOffsetY; private int cacheOffsetY;
private int cacheOffsetZ; private int cacheOffsetZ;
@ -148,6 +148,20 @@ public abstract class ArbitraryShape {
* @throws MaxChangedBlocksException * @throws MaxChangedBlocksException
*/ */
public int generate(EditSession editSession, Pattern pattern, boolean hollow) 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; int affected = 0;
for (BlockVector position : getExtent()) { for (BlockVector position : getExtent()) {
@ -179,14 +193,6 @@ public abstract class ArbitraryShape {
draw = true; draw = true;
break; 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)) { if (!isInsideCached(x, y, z + 1, pattern)) {
draw = true; draw = true;
break; break;
@ -195,6 +201,19 @@ public abstract class ArbitraryShape {
draw = true; draw = true;
break; 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); } while (false);
if (!draw) { if (!draw) {

View File

@ -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;
}
}