Added new Extent-compatible Clipboard and BlockArrayClipboard classes.

The goal is to replace use of CuboidClipboard with these new classes.

Support for entities, //flip, //rotate, and //distr still needs to be
re-implemented.

DataException was also removed from BaseBlock because The Base(...)
classes should be "dumb" blocks without any validation.
This commit is contained in:
sk89q 2014-06-29 17:47:08 -07:00
parent eee2c5d9f4
commit 09eb36dc5e
21 changed files with 571 additions and 365 deletions

View File

@ -134,7 +134,7 @@ public class DefaultNmsBlock extends NmsBlock {
} }
@Override @Override
public void setNbtData(CompoundTag tag) throws DataException { public void setNbtData(CompoundTag tag) {
if (tag == null) { if (tag == null) {
this.nbtData = null; this.nbtData = null;
} }

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.TileEntityBlock; import com.sk89q.worldedit.blocks.TileEntityBlock;
import com.sk89q.worldedit.world.DataException;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
@ -29,10 +28,7 @@ public class TileEntityBaseBlock extends BaseBlock implements TileEntityBlock {
public TileEntityBaseBlock(int type, int data, TileEntity tile) { public TileEntityBaseBlock(int type, int data, TileEntity tile) {
super(type, data); super(type, data);
try { setNbtData(NBTConverter.fromNative(copyNbtData(tile)));
setNbtData(NBTConverter.fromNative(copyNbtData(tile)));
} catch (DataException ignored) {
}
} }
private static NBTTagCompound copyNbtData(TileEntity tile) { private static NBTTagCompound copyNbtData(TileEntity tile) {

View File

@ -29,6 +29,7 @@ import com.sk89q.worldedit.command.tool.SinglePickaxe;
import com.sk89q.worldedit.command.tool.Tool; import com.sk89q.worldedit.command.tool.Tool;
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.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.inventory.BlockBag; 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.mask.Masks; import com.sk89q.worldedit.function.mask.Masks;
@ -62,7 +63,7 @@ public class LocalSession {
private boolean placeAtPos1 = false; private boolean placeAtPos1 = false;
private LinkedList<EditSession> history = new LinkedList<EditSession>(); private LinkedList<EditSession> history = new LinkedList<EditSession>();
private int historyPointer = 0; private int historyPointer = 0;
private CuboidClipboard clipboard; private Clipboard clipboard;
private boolean toolControl = true; private boolean toolControl = true;
private boolean superPickaxe = false; private boolean superPickaxe = false;
private BlockTool pickaxeMode = new SinglePickaxe(); private BlockTool pickaxeMode = new SinglePickaxe();
@ -326,7 +327,7 @@ public class LocalSession {
* @return clipboard, may be null * @return clipboard, may be null
* @throws EmptyClipboardException * @throws EmptyClipboardException
*/ */
public CuboidClipboard getClipboard() throws EmptyClipboardException { public Clipboard getClipboard() throws EmptyClipboardException {
if (clipboard == null) { if (clipboard == null) {
throw new EmptyClipboardException(); throw new EmptyClipboardException();
} }
@ -338,7 +339,7 @@ public class LocalSession {
* *
* @param clipboard * @param clipboard
*/ */
public void setClipboard(CuboidClipboard clipboard) { public void setClipboard(Clipboard clipboard) {
this.clipboard = clipboard; this.clipboard = clipboard;
} }

View File

@ -100,17 +100,27 @@ public class BaseBlock extends Block implements TileEntityBlock {
* @see #setData(int) * @see #setData(int)
* @see #setNbtData(CompoundTag) * @see #setNbtData(CompoundTag)
*/ */
public BaseBlock(int id, int data, CompoundTag nbtData) throws DataException { public BaseBlock(int id, int data, CompoundTag nbtData) {
setId(id); setId(id);
setData(data); setData(data);
setNbtData(nbtData); setNbtData(nbtData);
} }
/**
* Create a clone of another block.
*
* @param other the other block
*/
public BaseBlock(BaseBlock other) {
this(other.getId(), other.getData(), other.getNbtData());
}
/** /**
* Get the ID of the block. * Get the ID of the block.
* *
* @return ID (between 0 and {@link #MAX_ID}) * @return ID (between 0 and {@link #MAX_ID})
*/ */
@Override
public int getId() { public int getId() {
return id; return id;
} }
@ -138,6 +148,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
* *
* @param id block id (between 0 and {@link #MAX_ID}). * @param id block id (between 0 and {@link #MAX_ID}).
*/ */
@Override
public void setId(int id) { public void setId(int id) {
internalSetId(id); internalSetId(id);
} }
@ -147,6 +158,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
* *
* @return data value (0-15) * @return data value (0-15)
*/ */
@Override
public int getData() { public int getData() {
return data; return data;
} }
@ -175,6 +187,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
* *
* @param data block data value (between 0 and {@link #MAX_DATA}). * @param data block data value (between 0 and {@link #MAX_DATA}).
*/ */
@Override
public void setData(int data) { public void setData(int data) {
internalSetData(data); internalSetData(data);
} }
@ -187,6 +200,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
* @see #setId(int) * @see #setId(int)
* @see #setData(int) * @see #setData(int)
*/ */
@Override
public void setIdAndData(int id, int data) { public void setIdAndData(int id, int data) {
setId(id); setId(id);
setData(data); setData(data);
@ -198,6 +212,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
* *
* @return true if the data value is -1 * @return true if the data value is -1
*/ */
@Override
public boolean hasWildcardData() { public boolean hasWildcardData() {
return getData() == -1; return getData() == -1;
} }
@ -227,7 +242,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
} }
@Override @Override
public void setNbtData(CompoundTag nbtData) throws DataException { public void setNbtData(CompoundTag nbtData) {
this.nbtData = nbtData; this.nbtData = nbtData;
} }

View File

@ -19,17 +19,18 @@
package com.sk89q.worldedit.blocks; package com.sk89q.worldedit.blocks;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.DataException;
import com.sk89q.worldedit.world.storage.InvalidFormatException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* Represents a chest block. * Represents a chest block.
@ -78,7 +79,7 @@ public class ChestBlock extends ContainerBlock {
} }
@Override @Override
public void setNbtData(CompoundTag rootTag) throws DataException { public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) { if (rootTag == null) {
return; return;
} }
@ -87,19 +88,25 @@ public class ChestBlock extends ContainerBlock {
Tag t = values.get("id"); Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Chest")) { if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Chest")) {
throw new DataException("'Chest' tile entity expected"); throw new RuntimeException("'Chest' tile entity expected");
} }
List<CompoundTag> items = new ArrayList<CompoundTag>(); List<CompoundTag> items = new ArrayList<CompoundTag>();
for (Tag tag : NBTUtils.getChildTag(values, "Items", ListTag.class).getValue()) { try {
if (!(tag instanceof CompoundTag)) { for (Tag tag : NBTUtils.getChildTag(values, "Items", ListTag.class).getValue()) {
throw new DataException("CompoundTag expected as child tag of Chest's Items"); if (!(tag instanceof CompoundTag)) {
throw new RuntimeException("CompoundTag expected as child tag of Chest's Items");
}
items.add((CompoundTag) tag);
} }
items.add((CompoundTag) tag); setItems(deserializeInventory(items));
} catch (InvalidFormatException e) {
throw new RuntimeException(e);
} catch (DataException e) {
throw new RuntimeException(e);
} }
setItems(deserializeInventory(items));
} }
} }

View File

@ -19,11 +19,6 @@
package com.sk89q.worldedit.blocks; package com.sk89q.worldedit.blocks;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.NBTUtils;
@ -31,6 +26,11 @@ import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.DataException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* Represents dispensers. * Represents dispensers.
* *
@ -79,27 +79,31 @@ public class DispenserBlock extends ContainerBlock {
} }
@Override @Override
public void setNbtData(CompoundTag rootTag) throws DataException { public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) { try {
return; if (rootTag == null) {
} return;
Map<String, Tag> values = rootTag.getValue();
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Trap")) {
throw new DataException("'Trap' tile entity expected");
}
List<CompoundTag> items = new ArrayList<CompoundTag>();
for (Tag tag : NBTUtils.getChildTag(values, "Items", ListTag.class).getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new DataException("CompoundTag expected as child tag of Trap Items");
} }
items.add((CompoundTag) tag); Map<String, Tag> values = rootTag.getValue();
}
setItems(deserializeInventory(items)); Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Trap")) {
throw new DataException("'Trap' tile entity expected");
}
List<CompoundTag> items = new ArrayList<CompoundTag>();
for (Tag tag : NBTUtils.getChildTag(values, "Items", ListTag.class).getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new DataException("CompoundTag expected as child tag of Trap Items");
}
items.add((CompoundTag) tag);
}
setItems(deserializeInventory(items));
} catch (DataException e) {
throw new RuntimeException(e);
}
} }
} }

View File

@ -19,11 +19,6 @@
package com.sk89q.worldedit.blocks; package com.sk89q.worldedit.blocks;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.NBTUtils;
@ -32,6 +27,11 @@ import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.DataException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* Represents a furnace block. * Represents a furnace block.
* *
@ -125,40 +125,43 @@ public class FurnaceBlock extends ContainerBlock {
} }
@Override @Override
public void setNbtData(CompoundTag rootTag) throws DataException { public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) { if (rootTag == null) {
return; return;
} }
Map<String, Tag> values = rootTag.getValue(); try {
Map<String, Tag> values = rootTag.getValue();
Tag t = values.get("id"); Tag t = values.get("id");
if (!(t instanceof StringTag) if (!(t instanceof StringTag)
|| !((StringTag) t).getValue().equals("Furnace")) { || !((StringTag) t).getValue().equals("Furnace")) {
throw new DataException("'Furnace' tile entity expected"); throw new RuntimeException("'Furnace' tile entity expected");
}
ListTag items = NBTUtils.getChildTag(values, "Items", ListTag.class);
List<CompoundTag> compound = new ArrayList<CompoundTag>();
for (Tag tag : items.getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new DataException(
"CompoundTag expected as child tag of Furnace Items");
} }
compound.add((CompoundTag) tag);
}
setItems(deserializeInventory(compound));
t = values.get("BurnTime"); ListTag items = NBTUtils.getChildTag(values, "Items", ListTag.class);
if (t instanceof ShortTag) {
burnTime = ((ShortTag) t).getValue();
}
t = values.get("CookTime"); List<CompoundTag> compound = new ArrayList<CompoundTag>();
if (t instanceof ShortTag) {
cookTime = ((ShortTag) t).getValue(); for (Tag tag : items.getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new RuntimeException("CompoundTag expected as child tag of Furnace Items");
}
compound.add((CompoundTag) tag);
}
setItems(deserializeInventory(compound));
t = values.get("BurnTime");
if (t instanceof ShortTag) {
burnTime = ((ShortTag) t).getValue();
}
t = values.get("CookTime");
if (t instanceof ShortTag) {
cookTime = ((ShortTag) t).getValue();
}
} catch (DataException e) {
throw new RuntimeException(e);
} }
} }
} }

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.world.DataException;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -88,17 +87,13 @@ public class LazyBlock extends BaseBlock {
public CompoundTag getNbtData() { public CompoundTag getNbtData() {
if (!loaded) { if (!loaded) {
BaseBlock loadedBlock = extent.getBlock(position); BaseBlock loadedBlock = extent.getBlock(position);
try { super.setNbtData(loadedBlock.getNbtData());
super.setNbtData(loadedBlock.getNbtData());
} catch (DataException e) {
throw new RuntimeException(e);
}
} }
return super.getNbtData(); return super.getNbtData();
} }
@Override @Override
public void setNbtData(CompoundTag nbtData) throws DataException { public void setNbtData(CompoundTag nbtData) {
throw new UnsupportedOperationException("This object is immutable"); throw new UnsupportedOperationException("This object is immutable");
} }

View File

@ -19,9 +19,13 @@
package com.sk89q.worldedit.blocks; package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.*; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.MobType; import com.sk89q.worldedit.MobType;
import com.sk89q.worldedit.world.DataException;
import com.sk89q.worldedit.world.storage.InvalidFormatException; import com.sk89q.worldedit.world.storage.InvalidFormatException;
import java.util.HashMap; import java.util.HashMap;
@ -153,7 +157,7 @@ public class MobSpawnerBlock extends BaseBlock implements TileEntityBlock {
} }
@Override @Override
public void setNbtData(CompoundTag rootTag) throws DataException { public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) { if (rootTag == null) {
return; return;
} }
@ -162,11 +166,18 @@ public class MobSpawnerBlock extends BaseBlock implements TileEntityBlock {
Tag t = values.get("id"); Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("MobSpawner")) { if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("MobSpawner")) {
throw new DataException("'MobSpawner' tile entity expected"); throw new RuntimeException("'MobSpawner' tile entity expected");
} }
StringTag mobTypeTag = NBTUtils.getChildTag(values, "EntityId", StringTag.class); StringTag mobTypeTag;
ShortTag delayTag = NBTUtils.getChildTag(values, "Delay", ShortTag.class); ShortTag delayTag;
try {
mobTypeTag = NBTUtils.getChildTag(values, "EntityId", StringTag.class);
delayTag = NBTUtils.getChildTag(values, "Delay", ShortTag.class);
} catch (InvalidFormatException ignored) {
throw new RuntimeException("Invalid mob spawner data: no EntityId and/or no Delay");
}
this.mobType = mobTypeTag.getValue(); this.mobType = mobTypeTag.getValue();
this.delay = delayTag.getValue(); this.delay = delayTag.getValue();

View File

@ -19,14 +19,13 @@
package com.sk89q.worldedit.blocks; package com.sk89q.worldedit.blocks;
import java.util.HashMap;
import java.util.Map;
import com.sk89q.jnbt.ByteTag; import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException;
import java.util.HashMap;
import java.util.Map;
/** /**
* A note block. * A note block.
@ -102,7 +101,7 @@ public class NoteBlock extends BaseBlock implements TileEntityBlock {
} }
@Override @Override
public void setNbtData(CompoundTag rootTag) throws DataException { public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) { if (rootTag == null) {
return; return;
} }
@ -112,9 +111,8 @@ public class NoteBlock extends BaseBlock implements TileEntityBlock {
Tag t; Tag t;
t = values.get("id"); t = values.get("id");
if (!(t instanceof StringTag) if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Music")) {
|| !((StringTag) t).getValue().equals("Music")) { throw new RuntimeException("'Music' tile entity expected");
throw new DataException("'Music' tile entity expected");
} }
t = values.get("note"); t = values.get("note");

View File

@ -19,13 +19,12 @@
package com.sk89q.worldedit.blocks; package com.sk89q.worldedit.blocks;
import java.util.HashMap;
import java.util.Map;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException;
import java.util.HashMap;
import java.util.Map;
/** /**
* Represents a sign block. * Represents a sign block.
@ -104,7 +103,7 @@ public class SignBlock extends BaseBlock implements TileEntityBlock {
} }
@Override @Override
public void setNbtData(CompoundTag rootTag) throws DataException { public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) { if (rootTag == null) {
return; return;
} }
@ -116,9 +115,8 @@ public class SignBlock extends BaseBlock implements TileEntityBlock {
text = new String[] { "", "", "", "" }; text = new String[] { "", "", "", "" };
t = values.get("id"); t = values.get("id");
if (!(t instanceof StringTag) if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Sign")) {
|| !((StringTag) t).getValue().equals("Sign")) { throw new RuntimeException("'Sign' tile entity expected");
throw new DataException("'Sign' tile entity expected");
} }
t = values.get("Text1"); t = values.get("Text1");

View File

@ -19,14 +19,13 @@
package com.sk89q.worldedit.blocks; package com.sk89q.worldedit.blocks;
import java.util.HashMap;
import java.util.Map;
import com.sk89q.jnbt.ByteTag; import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException;
import java.util.HashMap;
import java.util.Map;
/** /**
* A skull block. * A skull block.
@ -165,7 +164,7 @@ public class SkullBlock extends BaseBlock implements TileEntityBlock {
} }
@Override @Override
public void setNbtData(CompoundTag rootTag) throws DataException { public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) { if (rootTag == null) {
return; return;
} }
@ -175,9 +174,8 @@ public class SkullBlock extends BaseBlock implements TileEntityBlock {
Tag t; Tag t;
t = values.get("id"); t = values.get("id");
if (!(t instanceof StringTag) if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Skull")) {
|| !((StringTag) t).getValue().equals("Skull")) { throw new RuntimeException("'Skull' tile entity expected");
throw new DataException("'Skull' tile entity expected");
} }
t = values.get("SkullType"); t = values.get("SkullType");

View File

@ -22,17 +22,31 @@ package com.sk89q.worldedit.command;
import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.worldedit.*; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.LocalWorld.KillFlags; import com.sk89q.worldedit.LocalWorld.KillFlags;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.command.UtilityCommands.FlagContainer; import com.sk89q.worldedit.command.UtilityCommands.FlagContainer;
import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.command.tool.brush.*; import com.sk89q.worldedit.command.tool.brush.ButcherBrush;
import com.sk89q.worldedit.command.tool.brush.ClipboardBrush;
import com.sk89q.worldedit.command.tool.brush.CylinderBrush;
import com.sk89q.worldedit.command.tool.brush.GravityBrush;
import com.sk89q.worldedit.command.tool.brush.HollowCylinderBrush;
import com.sk89q.worldedit.command.tool.brush.HollowSphereBrush;
import com.sk89q.worldedit.command.tool.brush.SmoothBrush;
import com.sk89q.worldedit.command.tool.brush.SphereBrush;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.BlockMask; import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.command.parametric.Optional;
@ -128,14 +142,15 @@ public class BrushCommands {
@CommandPermissions("worldedit.brush.clipboard") @CommandPermissions("worldedit.brush.clipboard")
public void clipboardBrush(Player player, LocalSession session, EditSession editSession, @Switch('a') boolean ignoreAir) throws WorldEditException { public void clipboardBrush(Player player, LocalSession session, EditSession editSession, @Switch('a') boolean ignoreAir) throws WorldEditException {
CuboidClipboard clipboard = session.getClipboard(); Clipboard clipboard = session.getClipboard();
if (clipboard == null) { if (clipboard == null) {
player.printError("Copy something first."); player.printError("Copy something first.");
return; return;
} }
Vector size = clipboard.getSize(); Region region = clipboard.getRegion();
Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint());
worldEdit.checkMaxBrushRadius(size.getBlockX()); worldEdit.checkMaxBrushRadius(size.getBlockX());
worldEdit.checkMaxBrushRadius(size.getBlockY()); worldEdit.checkMaxBrushRadius(size.getBlockY());

View File

@ -21,18 +21,29 @@ package com.sk89q.worldedit.command;
import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging; import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.*; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
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.regions.CuboidRegion; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.annotation.Selection;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.world.World;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT; import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
@ -67,31 +78,16 @@ public class ClipboardCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.clipboard.copy") @CommandPermissions("worldedit.clipboard.copy")
public void copy(Player player, LocalSession session, EditSession editSession, @Switch('e') boolean copyEntities) throws WorldEditException { public void copy(Player player, LocalSession session, EditSession editSession,
Region region = session.getSelection(player.getWorld()); @Selection Region region, @Switch('e') boolean copyEntities) throws WorldEditException {
Vector min = region.getMinimumPoint();
Vector max = region.getMaximumPoint();
Vector pos = session.getPlacementPosition(player);
CuboidClipboard clipboard = new CuboidClipboard(
max.subtract(min).add(Vector.ONE),
min, min.subtract(pos));
if (region instanceof CuboidRegion) {
clipboard.copy(editSession);
} else {
clipboard.copy(editSession, region);
}
if (copyEntities) {
for (LocalEntity entity : player.getWorld().getEntities(region)) {
clipboard.storeEntity(entity);
}
}
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
clipboard.setOffset(region.getMinimumPoint().subtract(session.getPlacementPosition(player)));
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
Operations.completeLegacy(copy);
session.setClipboard(clipboard); session.setClipboard(clipboard);
player.print("Block(s) copied."); player.print(region.getArea() + " block(s) were copied.");
} }
@Command( @Command(
@ -108,36 +104,17 @@ public class ClipboardCommands {
) )
@CommandPermissions("worldedit.clipboard.cut") @CommandPermissions("worldedit.clipboard.cut")
@Logging(REGION) @Logging(REGION)
public void cut(Player player, LocalSession session, EditSession editSession, @Optional("air") BaseBlock block, @Switch('e') boolean copyEntities) throws WorldEditException { public void cut(Player player, LocalSession session, EditSession editSession,
World world = player.getWorld(); @Selection Region region, @Optional("air") Pattern leavePattern, @Switch('e') boolean copyEntities) throws WorldEditException {
Region region = session.getSelection(world);
Vector min = region.getMinimumPoint();
Vector max = region.getMaximumPoint();
Vector pos = session.getPlacementPosition(player);
CuboidClipboard clipboard = new CuboidClipboard(
max.subtract(min).add(Vector.ONE),
min, min.subtract(pos));
if (region instanceof CuboidRegion) {
clipboard.copy(editSession);
} else {
clipboard.copy(editSession, region);
}
if (copyEntities) {
LocalEntity[] entities = world.getEntities(region);
for (LocalEntity entity : entities) {
clipboard.storeEntity(entity);
}
world.killEntities(entities);
}
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
clipboard.setOffset(region.getMinimumPoint().subtract(session.getPlacementPosition(player)));
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
copy.setSourceFunction(new BlockReplace(editSession, leavePattern));
Operations.completeLegacy(copy);
session.setClipboard(clipboard); session.setClipboard(clipboard);
editSession.setBlocks(region, block); player.print(region.getArea() + " block(s) were copied.");
player.print("Block(s) cut.");
} }
@Command( @Command(
@ -156,38 +133,28 @@ public class ClipboardCommands {
) )
@CommandPermissions("worldedit.clipboard.paste") @CommandPermissions("worldedit.clipboard.paste")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void paste(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { public void paste(Player player, LocalSession session, EditSession editSession,
@Switch('a') boolean ignoreAirBlocks, @Switch('o') boolean atOrigin,
@Switch('s') boolean selectPasted) throws WorldEditException {
boolean atOrigin = args.hasFlag('o'); Clipboard clipboard = session.getClipboard();
boolean pasteNoAir = args.hasFlag('a'); Vector to = atOrigin ? clipboard.getRegion().getMinimumPoint(): session.getPlacementPosition(player).add(clipboard.getOffset());
ForwardExtentCopy copy = new ForwardExtentCopy(clipboard, clipboard.getRegion(), editSession, to);
if (ignoreAirBlocks) {
copy.setSourceMask(new ExistingBlockMask(clipboard));
}
Operations.completeLegacy(copy);
CuboidClipboard clipboard = session.getClipboard(); if (selectPasted) {
Region region = clipboard.getRegion();
Vector pos = atOrigin ? session.getClipboard().getOrigin() Vector max = to.add(region.getMaximumPoint().subtract(region.getMinimumPoint()));
: session.getPlacementPosition(player); RegionSelector selector = new CuboidRegionSelector(player.getWorld(), to, max);
session.setRegionSelector(player.getWorld(), selector);
if (atOrigin) { selector.learnChanges();
clipboard.place(editSession, pos, pasteNoAir); selector.explainRegionAdjust(player, session);
clipboard.pasteEntities(pos);
player.findFreePosition();
player.print("Pasted to copy origin. Undo with //undo");
} else {
clipboard.paste(editSession, pos, pasteNoAir, true);
player.findFreePosition();
player.print("Pasted relative to you. Undo with //undo");
} }
if (args.hasFlag('s')) { player.print("The clipboard has been pasted at " + to.add(clipboard.getRegion().getMinimumPoint()));
World world = player.getWorld();
Vector pos2 = pos.add(clipboard.getSize().subtract(1, 1, 1));
if (!atOrigin) {
pos2 = pos2.add(clipboard.getOffset());
pos = pos.add(clipboard.getOffset());
}
session.setRegionSelector(world, new CuboidRegionSelector(world, pos, pos2));
session.getRegionSelector(world).learnChanges();
session.getRegionSelector(world).explainRegionAdjust(player, session);
}
} }
@Command( @Command(
@ -198,17 +165,9 @@ public class ClipboardCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.clipboard.rotate") @CommandPermissions("worldedit.clipboard.rotate")
public void rotate(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { public void rotate(Player player, LocalSession session, EditSession editSession, CommandContext args) throws CommandException {
// TODO: Update for new clipboard
int angle = args.getInteger(0); throw new CommandException("Needs to be re-written again");
if (angle % 90 == 0) {
CuboidClipboard clipboard = session.getClipboard();
clipboard.rotate2D(angle);
player.print("Clipboard rotated by " + angle + " degrees.");
} else {
player.printError("Angles must be divisible by 90 degrees.");
}
} }
@Command( @Command(
@ -224,11 +183,9 @@ public class ClipboardCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.clipboard.flip") @CommandPermissions("worldedit.clipboard.flip")
public void flip(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { public void flip(Player player, LocalSession session, EditSession editSession, CommandContext args) throws CommandException {
CuboidClipboard.FlipDirection dir = worldEdit.getFlipDirection(player, args.argsLength() > 0 ? args.getString(0).toLowerCase() : "me"); // TODO: Update for new clipboard
CuboidClipboard clipboard = session.getClipboard(); throw new CommandException("Needs to be re-written again");
clipboard.flip(dir, args.hasFlag('p'));
player.print("Clipboard flipped.");
} }
@Command( @Command(

View File

@ -19,16 +19,22 @@
package com.sk89q.worldedit.command; package com.sk89q.worldedit.command;
import com.sk89q.minecraft.util.commands.*; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.worldedit.*; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.FilenameResolutionException;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
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.schematic.SchematicFormat; import com.sk89q.worldedit.schematic.SchematicFormat;
import com.sk89q.worldedit.world.DataException;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
@ -64,58 +70,9 @@ public class SchematicCommands {
max = 2 max = 2
) )
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load"}) // TODO: Remove 'clipboard' perm @CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load"}) // TODO: Remove 'clipboard' perm
public void load(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { public void load(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException {
// TODO: Update for new clipboard
LocalConfiguration config = worldEdit.getConfiguration(); throw new CommandException("Needs to be re-written again");
String fileName;
String formatName;
if (args.argsLength() == 1) {
formatName = null;
fileName = args.getString(0);
} else {
formatName = args.getString(0);
fileName = args.getString(1);
}
File dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
File f = worldEdit.getSafeOpenFile(player, dir, fileName, "schematic", "schematic");
if (!f.exists()) {
player.printError("Schematic " + fileName + " does not exist!");
return;
}
SchematicFormat format = formatName == null ? null : SchematicFormat.getFormat(formatName);
if (format == null) {
format = SchematicFormat.getFormat(f);
}
if (format == null) {
player.printError("Unknown schematic format: " + formatName);
return;
}
if (!format.isOfFormat(f) && !args.hasFlag('f')) {
player.printError(fileName + " is not of the " + format.getName() + " schematic format!");
return;
}
try {
String filePath = f.getCanonicalPath();
String dirPath = dir.getCanonicalPath();
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
player.printError("Schematic could not read or it does not exist.");
} else {
session.setClipboard(format.load(f));
WorldEdit.logger.info(player.getName() + " loaded " + filePath);
player.print(fileName + " loaded. Paste it with //paste");
}
} catch (DataException e) {
player.printError("Load error: " + e.getMessage());
} catch (IOException e) {
player.printError("Schematic could not read or it does not exist: " + e.getMessage());
}
} }
@Command( @Command(
@ -129,53 +86,8 @@ public class SchematicCommands {
) )
@CommandPermissions({"worldedit.clipboard.save", "worldedit.schematic.save"}) // TODO: Remove 'clipboard' perm @CommandPermissions({"worldedit.clipboard.save", "worldedit.schematic.save"}) // TODO: Remove 'clipboard' perm
public void save(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException { public void save(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException {
// TODO: Update for new clipboard
LocalConfiguration config = worldEdit.getConfiguration(); throw new CommandException("Needs to be re-written again");
SchematicFormat format;
if (args.argsLength() == 1) {
if (SchematicFormat.getFormats().size() == 1) {
format = SchematicFormat.getFormats().iterator().next();
} else {
player.printError("More than one schematic format is available. Please provide the desired format");
return;
}
} else {
format = SchematicFormat.getFormat(args.getString(0));
if (format == null) {
player.printError("Unknown schematic format: " + args.getString(0));
return;
}
}
String filename = args.getString(args.argsLength() - 1);
File dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
File f = worldEdit.getSafeSaveFile(player, dir, filename, "schematic", "schematic");
if (!dir.exists()) {
if (!dir.mkdir()) {
player.printError("The storage folder could not be created.");
return;
}
}
try {
// Create parent directories
File parent = f.getParentFile();
if (parent != null && !parent.exists()) {
if (!parent.mkdirs()) {
throw new CommandException("Could not create folder for schematics!");
}
}
format.save(session.getClipboard(), f);
WorldEdit.logger.info(player.getName() + " saved " + f.getCanonicalPath());
player.print(filename + " saved.");
} catch (DataException se) {
player.printError("Save error: " + se.getMessage());
} catch (IOException e) {
player.printError("Schematic could not written: " + e.getMessage());
}
} }
@Command( @Command(

View File

@ -19,23 +19,13 @@
package com.sk89q.worldedit.command; package com.sk89q.worldedit.command;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandAlias; import com.sk89q.minecraft.util.commands.CommandAlias;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging; import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
@ -43,18 +33,28 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.world.storage.ChunkStore; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.ConvexPolyhedralRegionSelector; import com.sk89q.worldedit.regions.selector.ConvexPolyhedralRegionSelector;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.regions.selector.CylinderRegionSelector; import com.sk89q.worldedit.regions.selector.CylinderRegionSelector;
import com.sk89q.worldedit.regions.selector.EllipsoidRegionSelector; import com.sk89q.worldedit.regions.selector.EllipsoidRegionSelector;
import com.sk89q.worldedit.regions.selector.ExtendingCuboidRegionSelector; import com.sk89q.worldedit.regions.selector.ExtendingCuboidRegionSelector;
import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector; import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.SphereRegionSelector; import com.sk89q.worldedit.regions.selector.SphereRegionSelector;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.storage.ChunkStore;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
/** /**
* Selection commands. * Selection commands.
@ -584,15 +584,15 @@ public class SelectionCommands {
public void size(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { public void size(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
if (args.hasFlag('c')) { if (args.hasFlag('c')) {
CuboidClipboard clipboard = session.getClipboard(); Clipboard clipboard = session.getClipboard();
Vector size = clipboard.getSize(); Region region = clipboard.getRegion();
Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint());
Vector offset = clipboard.getOffset(); Vector offset = clipboard.getOffset();
player.print("Size: " + size); player.print("Cuboid dimensions (max - min): " + size);
player.print("Offset: " + offset); player.print("Offset: " + offset);
player.print("Cuboid distance: " + size.distance(Vector.ONE)); player.print("Cuboid distance: " + size.distance(Vector.ONE));
player.print("# of blocks: " player.print("# of blocks: " + (int) (size.getX() * size.getY() * size.getZ()));
+ (int) (size.getX() * size.getY() * size.getZ()));
return; return;
} }
@ -610,8 +610,7 @@ public class SelectionCommands {
} }
player.print("Size: " + size); player.print("Size: " + size);
player.print("Cuboid distance: " + region.getMaximumPoint() player.print("Cuboid distance: " + region.getMaximumPoint().distance(region.getMinimumPoint()));
.distance(region.getMinimumPoint()));
player.print("# of blocks: " + region.getArea()); player.print("# of blocks: " + region.getArea());
} }
@ -655,7 +654,7 @@ public class SelectionCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.analysis.distr") @CommandPermissions("worldedit.analysis.distr")
public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException {
int size; int size;
boolean useData = args.hasFlag('d'); boolean useData = args.hasFlag('d');
@ -663,13 +662,8 @@ public class SelectionCommands {
List<Countable<BaseBlock>> distributionData = null; List<Countable<BaseBlock>> distributionData = null;
if (args.hasFlag('c')) { if (args.hasFlag('c')) {
CuboidClipboard clip = session.getClipboard(); // TODO: Update for new clipboard
if (useData) { throw new CommandException("Needs to be re-written again");
distributionData = clip.getBlockDistributionWithData();
} else {
distribution = clip.getBlockDistribution();
}
size = clip.getHeight() * clip.getLength() * clip.getWidth();
} else { } else {
if (useData) { if (useData) {
distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld())); distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld()));

View File

@ -19,24 +19,35 @@
package com.sk89q.worldedit.command.tool.brush; package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.regions.Region;
public class ClipboardBrush implements Brush { public class ClipboardBrush implements Brush {
private CuboidClipboard clipboard; private Clipboard clipboard;
private boolean noAir; private boolean noAir;
public ClipboardBrush(CuboidClipboard clipboard, boolean noAir) { public ClipboardBrush(Clipboard clipboard, boolean noAir) {
this.clipboard = clipboard; this.clipboard = clipboard;
this.noAir = noAir; this.noAir = noAir;
} }
@Override
public void build(EditSession editSession, Vector pos, Pattern mat, double size) throws MaxChangedBlocksException { public void build(EditSession editSession, Vector pos, Pattern mat, double size) throws MaxChangedBlocksException {
clipboard.place(editSession, pos.subtract(clipboard.getSize().divide(2)), noAir); Region region = clipboard.getRegion();
Vector centerOffset = region.getCenter().subtract(region.getMinimumPoint());
ForwardExtentCopy copy = new ForwardExtentCopy(clipboard, clipboard.getRegion(), editSession, pos.subtract(centerOffset));
if (noAir) {
copy.setSourceMask(new ExistingBlockMask(clipboard));
}
Operations.completeLegacy(copy);
} }
} }

View File

@ -0,0 +1,160 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extent.clipboard;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Stores block data as a multi-dimensional array of {@link BaseBlock}s and
* other data as lists or maps.
*/
public class BlockArrayClipboard implements Clipboard {
private final Region region;
private Vector offset = new Vector();
private final BaseBlock[][][] blocks;
private final List<ClipboardEntity> entities = new ArrayList<ClipboardEntity>();
/**
* Create a new instance.
*
* @param region the bounding region
*/
public BlockArrayClipboard(Region region) {
checkNotNull(region);
checkNotNull(offset);
this.region = region.clone();
Vector dimensions = getDimensions();
blocks = new BaseBlock[dimensions.getBlockX()][dimensions.getBlockY()][dimensions.getBlockZ()];
}
@Override
public Region getRegion() {
return region.clone();
}
@Override
public Vector getOffset() {
return offset;
}
@Override
public void setOffset(Vector offset) {
checkNotNull(offset);
this.offset = offset;
}
/**
* Get the dimensions of the copy, which is at minimum (1, 1, 1).
*
* @return the dimensions
*/
private Vector getDimensions() {
return region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
}
@Override
public Vector getMinimumPoint() {
return region.getMinimumPoint();
}
@Override
public Vector getMaximumPoint() {
return region.getMaximumPoint();
}
@Override
public List<Entity> getEntities() {
return new ArrayList<Entity>(entities);
}
@Nullable
@Override
public Entity createEntity(Location location, BaseEntity entity) {
ClipboardEntity ret = new ClipboardEntity(location, entity);
entities.add(ret);
return ret;
}
@Override
public BaseBlock getBlock(Vector position) {
if (region.contains(position)) {
Vector v = position.subtract(region.getMinimumPoint());
BaseBlock block = blocks[v.getBlockX()][v.getBlockY()][v.getBlockZ()];
if (block != null) {
return new BaseBlock(block);
}
}
return new BaseBlock(BlockID.AIR);
}
@Override
public BaseBlock getLazyBlock(Vector position) {
return getBlock(position);
}
@Override
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException {
if (region.contains(position)) {
Vector v = position.subtract(region.getMinimumPoint());
blocks[v.getBlockX()][v.getBlockY()][v.getBlockZ()] = new BaseBlock(block);
return true;
} else {
return false;
}
}
@Nullable
@Override
public Operation commit() {
return null;
}
/**
* Stores entity data.
*/
private class ClipboardEntity extends StoredEntity {
ClipboardEntity(Location location, BaseEntity entity) {
super(location, entity);
}
@Override
public boolean remove() {
return entities.remove(this);
}
}
}

View File

@ -0,0 +1,58 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extent.clipboard;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.regions.Region;
/**
* Specifies an object that implements something suitable as a "clipboard."
*/
public interface Clipboard extends Extent {
/**
* Get the bounding region of this extent.
* </p>
* Implementations should return a copy of the region.
*
* @return the bounding region
*/
Region getRegion();
/**
* Get the offset at which the area was copied from.
* </p>
* The offset is not utilized by clipboards but it can be used
* to store, for example, the relative location from which the copy
* was made.
*
* @return the offset
*/
Vector getOffset();
/**
* Set the offset at which the area was copied from.
*
* @param offset the offset
*/
void setOffset(Vector offset);
}

View File

@ -0,0 +1,76 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extent.clipboard;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An implementation of {@link Entity} that stores a {@link BaseEntity} with it.
* </p>
* Calls to {@link #getState()} return a clone.
*/
abstract class StoredEntity implements Entity {
private final Location location;
private final BaseEntity entity;
/**
* Create a new instance.
*
* @param location the location
* @param entity the entity (which will be copied)
*/
StoredEntity(Location location, BaseEntity entity) {
checkNotNull(location);
checkNotNull(entity);
this.location = location;
this.entity = new BaseEntity(entity);
}
/**
* Get the entity state. This is not a copy.
*
* @return the entity
*/
BaseEntity getEntity() {
return entity;
}
@Override
public BaseEntity getState() {
return new BaseEntity(entity);
}
@Override
public Location getLocation() {
return location;
}
@Override
public Extent getExtent() {
return location.getExtent();
}
}

View File

@ -19,21 +19,18 @@
package com.sk89q.worldedit.function.pattern; package com.sk89q.worldedit.function.pattern;
import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* A pattern that reads from {@link CuboidClipboard}. * A pattern that reads from {@link Clipboard}.
*
* @deprecated May be removed without notice, but there is no direct replacement yet
*/ */
@Deprecated
public class ClipboardPattern extends AbstractPattern { public class ClipboardPattern extends AbstractPattern {
private final CuboidClipboard clipboard; private final Clipboard clipboard;
private final Vector size; private final Vector size;
/** /**
@ -41,10 +38,10 @@ public class ClipboardPattern extends AbstractPattern {
* *
* @param clipboard the clipboard * @param clipboard the clipboard
*/ */
public ClipboardPattern(CuboidClipboard clipboard) { public ClipboardPattern(Clipboard clipboard) {
checkNotNull(clipboard); checkNotNull(clipboard);
this.clipboard = clipboard; this.clipboard = clipboard;
this.size = clipboard.getSize(); this.size = clipboard.getMaximumPoint().subtract(clipboard.getMinimumPoint()).add(1, 1, 1);
} }
@Override @Override
@ -53,7 +50,7 @@ public class ClipboardPattern extends AbstractPattern {
int yp = Math.abs(position.getBlockY()) % size.getBlockY(); int yp = Math.abs(position.getBlockY()) % size.getBlockY();
int zp = Math.abs(position.getBlockZ()) % size.getBlockZ(); int zp = Math.abs(position.getBlockZ()) % size.getBlockZ();
return clipboard.getPoint(new Vector(xp, yp, zp)); return clipboard.getBlock(clipboard.getMinimumPoint().add(new Vector(xp, yp, zp)));
} }
} }