From 09eb36dc5ea316bc8a06c0a24282020e10f770f0 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 29 Jun 2014 17:47:08 -0700
Subject: [PATCH] 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.
---
.../worldedit/bukkit/DefaultNmsBlock.java | 2 +-
.../worldedit/forge/TileEntityBaseBlock.java | 6 +-
.../com/sk89q/worldedit/LocalSession.java | 7 +-
.../com/sk89q/worldedit/blocks/BaseBlock.java | 19 ++-
.../sk89q/worldedit/blocks/ChestBlock.java | 35 ++--
.../worldedit/blocks/DispenserBlock.java | 52 +++---
.../sk89q/worldedit/blocks/FurnaceBlock.java | 65 +++----
.../com/sk89q/worldedit/blocks/LazyBlock.java | 9 +-
.../worldedit/blocks/MobSpawnerBlock.java | 23 ++-
.../com/sk89q/worldedit/blocks/NoteBlock.java | 14 +-
.../com/sk89q/worldedit/blocks/SignBlock.java | 14 +-
.../sk89q/worldedit/blocks/SkullBlock.java | 14 +-
.../worldedit/command/BrushCommands.java | 23 ++-
.../worldedit/command/ClipboardCommands.java | 151 ++++++-----------
.../worldedit/command/SchematicCommands.java | 118 ++-----------
.../worldedit/command/SelectionCommands.java | 56 +++---
.../command/tool/brush/ClipboardBrush.java | 19 ++-
.../extent/clipboard/BlockArrayClipboard.java | 160 ++++++++++++++++++
.../worldedit/extent/clipboard/Clipboard.java | 58 +++++++
.../extent/clipboard/StoredEntity.java | 76 +++++++++
.../function/pattern/ClipboardPattern.java | 15 +-
21 files changed, 571 insertions(+), 365 deletions(-)
create mode 100644 src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java
create mode 100644 src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java
create mode 100644 src/main/java/com/sk89q/worldedit/extent/clipboard/StoredEntity.java
diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java
index 23d5e64e8..8b738923b 100644
--- a/src/bukkit/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java
+++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java
@@ -134,7 +134,7 @@ public class DefaultNmsBlock extends NmsBlock {
}
@Override
- public void setNbtData(CompoundTag tag) throws DataException {
+ public void setNbtData(CompoundTag tag) {
if (tag == null) {
this.nbtData = null;
}
diff --git a/src/forge/java/com/sk89q/worldedit/forge/TileEntityBaseBlock.java b/src/forge/java/com/sk89q/worldedit/forge/TileEntityBaseBlock.java
index 1a46607a8..a17ac5d43 100644
--- a/src/forge/java/com/sk89q/worldedit/forge/TileEntityBaseBlock.java
+++ b/src/forge/java/com/sk89q/worldedit/forge/TileEntityBaseBlock.java
@@ -21,7 +21,6 @@ package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.TileEntityBlock;
-import com.sk89q.worldedit.world.DataException;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
@@ -29,10 +28,7 @@ public class TileEntityBaseBlock extends BaseBlock implements TileEntityBlock {
public TileEntityBaseBlock(int type, int data, TileEntity tile) {
super(type, data);
- try {
- setNbtData(NBTConverter.fromNative(copyNbtData(tile)));
- } catch (DataException ignored) {
- }
+ setNbtData(NBTConverter.fromNative(copyNbtData(tile)));
}
private static NBTTagCompound copyNbtData(TileEntity tile) {
diff --git a/src/main/java/com/sk89q/worldedit/LocalSession.java b/src/main/java/com/sk89q/worldedit/LocalSession.java
index df38b58a5..17b86f3b4 100644
--- a/src/main/java/com/sk89q/worldedit/LocalSession.java
+++ b/src/main/java/com/sk89q/worldedit/LocalSession.java
@@ -29,6 +29,7 @@ import com.sk89q.worldedit.command.tool.SinglePickaxe;
import com.sk89q.worldedit.command.tool.Tool;
import com.sk89q.worldedit.entity.Player;
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.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
@@ -62,7 +63,7 @@ public class LocalSession {
private boolean placeAtPos1 = false;
private LinkedList history = new LinkedList();
private int historyPointer = 0;
- private CuboidClipboard clipboard;
+ private Clipboard clipboard;
private boolean toolControl = true;
private boolean superPickaxe = false;
private BlockTool pickaxeMode = new SinglePickaxe();
@@ -326,7 +327,7 @@ public class LocalSession {
* @return clipboard, may be null
* @throws EmptyClipboardException
*/
- public CuboidClipboard getClipboard() throws EmptyClipboardException {
+ public Clipboard getClipboard() throws EmptyClipboardException {
if (clipboard == null) {
throw new EmptyClipboardException();
}
@@ -338,7 +339,7 @@ public class LocalSession {
*
* @param clipboard
*/
- public void setClipboard(CuboidClipboard clipboard) {
+ public void setClipboard(Clipboard clipboard) {
this.clipboard = clipboard;
}
diff --git a/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java b/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java
index 497839125..d89ff8e03 100644
--- a/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java
+++ b/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java
@@ -100,17 +100,27 @@ public class BaseBlock extends Block implements TileEntityBlock {
* @see #setData(int)
* @see #setNbtData(CompoundTag)
*/
- public BaseBlock(int id, int data, CompoundTag nbtData) throws DataException {
+ public BaseBlock(int id, int data, CompoundTag nbtData) {
setId(id);
setData(data);
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.
*
* @return ID (between 0 and {@link #MAX_ID})
*/
+ @Override
public int getId() {
return id;
}
@@ -138,6 +148,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
*
* @param id block id (between 0 and {@link #MAX_ID}).
*/
+ @Override
public void setId(int id) {
internalSetId(id);
}
@@ -147,6 +158,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
*
* @return data value (0-15)
*/
+ @Override
public int getData() {
return data;
}
@@ -175,6 +187,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
*
* @param data block data value (between 0 and {@link #MAX_DATA}).
*/
+ @Override
public void setData(int data) {
internalSetData(data);
}
@@ -187,6 +200,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
* @see #setId(int)
* @see #setData(int)
*/
+ @Override
public void setIdAndData(int id, int data) {
setId(id);
setData(data);
@@ -198,6 +212,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
*
* @return true if the data value is -1
*/
+ @Override
public boolean hasWildcardData() {
return getData() == -1;
}
@@ -227,7 +242,7 @@ public class BaseBlock extends Block implements TileEntityBlock {
}
@Override
- public void setNbtData(CompoundTag nbtData) throws DataException {
+ public void setNbtData(CompoundTag nbtData) {
this.nbtData = nbtData;
}
diff --git a/src/main/java/com/sk89q/worldedit/blocks/ChestBlock.java b/src/main/java/com/sk89q/worldedit/blocks/ChestBlock.java
index fcc9f0a32..d5547e661 100644
--- a/src/main/java/com/sk89q/worldedit/blocks/ChestBlock.java
+++ b/src/main/java/com/sk89q/worldedit/blocks/ChestBlock.java
@@ -19,17 +19,18 @@
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.ListTag;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
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.
@@ -78,7 +79,7 @@ public class ChestBlock extends ContainerBlock {
}
@Override
- public void setNbtData(CompoundTag rootTag) throws DataException {
+ public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
@@ -87,19 +88,25 @@ public class ChestBlock extends ContainerBlock {
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Chest")) {
- throw new DataException("'Chest' tile entity expected");
+ throw new RuntimeException("'Chest' tile entity expected");
}
List items = new ArrayList();
-
- for (Tag tag : NBTUtils.getChildTag(values, "Items", ListTag.class).getValue()) {
- if (!(tag instanceof CompoundTag)) {
- throw new DataException("CompoundTag expected as child tag of Chest's Items");
+
+ try {
+ for (Tag tag : NBTUtils.getChildTag(values, "Items", ListTag.class).getValue()) {
+ 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));
}
}
diff --git a/src/main/java/com/sk89q/worldedit/blocks/DispenserBlock.java b/src/main/java/com/sk89q/worldedit/blocks/DispenserBlock.java
index 0608e4935..ea1392924 100644
--- a/src/main/java/com/sk89q/worldedit/blocks/DispenserBlock.java
+++ b/src/main/java/com/sk89q/worldedit/blocks/DispenserBlock.java
@@ -19,11 +19,6 @@
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.ListTag;
import com.sk89q.jnbt.NBTUtils;
@@ -31,6 +26,11 @@ import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
/**
* Represents dispensers.
*
@@ -79,27 +79,31 @@ public class DispenserBlock extends ContainerBlock {
}
@Override
- public void setNbtData(CompoundTag rootTag) throws DataException {
- if (rootTag == null) {
- return;
- }
-
- Map 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 items = new ArrayList();
- 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");
+ public void setNbtData(CompoundTag rootTag) {
+ try {
+ if (rootTag == null) {
+ return;
}
- items.add((CompoundTag) tag);
- }
+ Map 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 items = new ArrayList();
+ 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);
+ }
}
}
diff --git a/src/main/java/com/sk89q/worldedit/blocks/FurnaceBlock.java b/src/main/java/com/sk89q/worldedit/blocks/FurnaceBlock.java
index db4d3e210..24e241dbd 100644
--- a/src/main/java/com/sk89q/worldedit/blocks/FurnaceBlock.java
+++ b/src/main/java/com/sk89q/worldedit/blocks/FurnaceBlock.java
@@ -19,11 +19,6 @@
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.ListTag;
import com.sk89q.jnbt.NBTUtils;
@@ -32,6 +27,11 @@ import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
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.
*
@@ -125,40 +125,43 @@ public class FurnaceBlock extends ContainerBlock {
}
@Override
- public void setNbtData(CompoundTag rootTag) throws DataException {
+ public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
-
- Map values = rootTag.getValue();
- Tag t = values.get("id");
- if (!(t instanceof StringTag)
- || !((StringTag) t).getValue().equals("Furnace")) {
- throw new DataException("'Furnace' tile entity expected");
- }
+ try {
+ Map values = rootTag.getValue();
- ListTag items = NBTUtils.getChildTag(values, "Items", ListTag.class);
-
- List compound = new ArrayList();
-
- for (Tag tag : items.getValue()) {
- if (!(tag instanceof CompoundTag)) {
- throw new DataException(
- "CompoundTag expected as child tag of Furnace Items");
+ Tag t = values.get("id");
+ if (!(t instanceof StringTag)
+ || !((StringTag) t).getValue().equals("Furnace")) {
+ throw new RuntimeException("'Furnace' tile entity expected");
}
- compound.add((CompoundTag) tag);
- }
- setItems(deserializeInventory(compound));
- t = values.get("BurnTime");
- if (t instanceof ShortTag) {
- burnTime = ((ShortTag) t).getValue();
- }
+ ListTag items = NBTUtils.getChildTag(values, "Items", ListTag.class);
- t = values.get("CookTime");
- if (t instanceof ShortTag) {
- cookTime = ((ShortTag) t).getValue();
+ List compound = new ArrayList();
+
+ 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);
}
}
}
diff --git a/src/main/java/com/sk89q/worldedit/blocks/LazyBlock.java b/src/main/java/com/sk89q/worldedit/blocks/LazyBlock.java
index 591744fac..bf9ad5d19 100644
--- a/src/main/java/com/sk89q/worldedit/blocks/LazyBlock.java
+++ b/src/main/java/com/sk89q/worldedit/blocks/LazyBlock.java
@@ -21,7 +21,6 @@ package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.world.DataException;
import com.sk89q.worldedit.extent.Extent;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -88,17 +87,13 @@ public class LazyBlock extends BaseBlock {
public CompoundTag getNbtData() {
if (!loaded) {
BaseBlock loadedBlock = extent.getBlock(position);
- try {
- super.setNbtData(loadedBlock.getNbtData());
- } catch (DataException e) {
- throw new RuntimeException(e);
- }
+ super.setNbtData(loadedBlock.getNbtData());
}
return super.getNbtData();
}
@Override
- public void setNbtData(CompoundTag nbtData) throws DataException {
+ public void setNbtData(CompoundTag nbtData) {
throw new UnsupportedOperationException("This object is immutable");
}
diff --git a/src/main/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java b/src/main/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java
index 0004f4210..ed38b5bc8 100644
--- a/src/main/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java
+++ b/src/main/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java
@@ -19,9 +19,13 @@
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.world.DataException;
import com.sk89q.worldedit.world.storage.InvalidFormatException;
import java.util.HashMap;
@@ -153,7 +157,7 @@ public class MobSpawnerBlock extends BaseBlock implements TileEntityBlock {
}
@Override
- public void setNbtData(CompoundTag rootTag) throws DataException {
+ public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
@@ -162,11 +166,18 @@ public class MobSpawnerBlock extends BaseBlock implements TileEntityBlock {
Tag t = values.get("id");
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);
- ShortTag delayTag = NBTUtils.getChildTag(values, "Delay", ShortTag.class);
+ StringTag mobTypeTag;
+ 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.delay = delayTag.getValue();
diff --git a/src/main/java/com/sk89q/worldedit/blocks/NoteBlock.java b/src/main/java/com/sk89q/worldedit/blocks/NoteBlock.java
index 19d3dc150..32e1cdb18 100644
--- a/src/main/java/com/sk89q/worldedit/blocks/NoteBlock.java
+++ b/src/main/java/com/sk89q/worldedit/blocks/NoteBlock.java
@@ -19,14 +19,13 @@
package com.sk89q.worldedit.blocks;
-import java.util.HashMap;
-import java.util.Map;
-
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
-import com.sk89q.worldedit.world.DataException;
+
+import java.util.HashMap;
+import java.util.Map;
/**
* A note block.
@@ -102,7 +101,7 @@ public class NoteBlock extends BaseBlock implements TileEntityBlock {
}
@Override
- public void setNbtData(CompoundTag rootTag) throws DataException {
+ public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
@@ -112,9 +111,8 @@ public class NoteBlock extends BaseBlock implements TileEntityBlock {
Tag t;
t = values.get("id");
- if (!(t instanceof StringTag)
- || !((StringTag) t).getValue().equals("Music")) {
- throw new DataException("'Music' tile entity expected");
+ if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Music")) {
+ throw new RuntimeException("'Music' tile entity expected");
}
t = values.get("note");
diff --git a/src/main/java/com/sk89q/worldedit/blocks/SignBlock.java b/src/main/java/com/sk89q/worldedit/blocks/SignBlock.java
index 8afff7001..e4d36c0d2 100644
--- a/src/main/java/com/sk89q/worldedit/blocks/SignBlock.java
+++ b/src/main/java/com/sk89q/worldedit/blocks/SignBlock.java
@@ -19,13 +19,12 @@
package com.sk89q.worldedit.blocks;
-import java.util.HashMap;
-import java.util.Map;
-
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
-import com.sk89q.worldedit.world.DataException;
+
+import java.util.HashMap;
+import java.util.Map;
/**
* Represents a sign block.
@@ -104,7 +103,7 @@ public class SignBlock extends BaseBlock implements TileEntityBlock {
}
@Override
- public void setNbtData(CompoundTag rootTag) throws DataException {
+ public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
@@ -116,9 +115,8 @@ public class SignBlock extends BaseBlock implements TileEntityBlock {
text = new String[] { "", "", "", "" };
t = values.get("id");
- if (!(t instanceof StringTag)
- || !((StringTag) t).getValue().equals("Sign")) {
- throw new DataException("'Sign' tile entity expected");
+ if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Sign")) {
+ throw new RuntimeException("'Sign' tile entity expected");
}
t = values.get("Text1");
diff --git a/src/main/java/com/sk89q/worldedit/blocks/SkullBlock.java b/src/main/java/com/sk89q/worldedit/blocks/SkullBlock.java
index 02ab5ac6e..981a339ec 100644
--- a/src/main/java/com/sk89q/worldedit/blocks/SkullBlock.java
+++ b/src/main/java/com/sk89q/worldedit/blocks/SkullBlock.java
@@ -19,14 +19,13 @@
package com.sk89q.worldedit.blocks;
-import java.util.HashMap;
-import java.util.Map;
-
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
-import com.sk89q.worldedit.world.DataException;
+
+import java.util.HashMap;
+import java.util.Map;
/**
* A skull block.
@@ -165,7 +164,7 @@ public class SkullBlock extends BaseBlock implements TileEntityBlock {
}
@Override
- public void setNbtData(CompoundTag rootTag) throws DataException {
+ public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
@@ -175,9 +174,8 @@ public class SkullBlock extends BaseBlock implements TileEntityBlock {
Tag t;
t = values.get("id");
- if (!(t instanceof StringTag)
- || !((StringTag) t).getValue().equals("Skull")) {
- throw new DataException("'Skull' tile entity expected");
+ if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Skull")) {
+ throw new RuntimeException("'Skull' tile entity expected");
}
t = values.get("SkullType");
diff --git a/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/src/main/java/com/sk89q/worldedit/command/BrushCommands.java
index f954e26d8..2d9739dd0 100644
--- a/src/main/java/com/sk89q/worldedit/command/BrushCommands.java
+++ b/src/main/java/com/sk89q/worldedit/command/BrushCommands.java
@@ -22,17 +22,31 @@ package com.sk89q.worldedit.command;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
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.Vector;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.command.UtilityCommands.FlagContainer;
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.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.pattern.BlockPattern;
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.parametric.Optional;
@@ -128,14 +142,15 @@ public class BrushCommands {
@CommandPermissions("worldedit.brush.clipboard")
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) {
player.printError("Copy something first.");
return;
}
- Vector size = clipboard.getSize();
+ Region region = clipboard.getRegion();
+ Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint());
worldEdit.checkMaxBrushRadius(size.getBlockX());
worldEdit.checkMaxBrushRadius(size.getBlockY());
diff --git a/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
index ffc765095..acbb1cfcc 100644
--- a/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
+++ b/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
@@ -21,18 +21,29 @@ package com.sk89q.worldedit.command;
import com.sk89q.minecraft.util.commands.Command;
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.Logging;
-import com.sk89q.worldedit.*;
-import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.EditSession;
+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.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.RegionSelector;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.util.command.binding.Switch;
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.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
@@ -67,31 +78,16 @@ public class ClipboardCommands {
max = 0
)
@CommandPermissions("worldedit.clipboard.copy")
- public void copy(Player player, LocalSession session, EditSession editSession, @Switch('e') boolean copyEntities) throws WorldEditException {
- Region region = session.getSelection(player.getWorld());
- 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);
- }
- }
+ public void copy(Player player, LocalSession session, EditSession editSession,
+ @Selection Region region, @Switch('e') boolean copyEntities) throws WorldEditException {
+ 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);
- player.print("Block(s) copied.");
+ player.print(region.getArea() + " block(s) were copied.");
}
@Command(
@@ -108,36 +104,17 @@ public class ClipboardCommands {
)
@CommandPermissions("worldedit.clipboard.cut")
@Logging(REGION)
- public void cut(Player player, LocalSession session, EditSession editSession, @Optional("air") BaseBlock block, @Switch('e') boolean copyEntities) throws WorldEditException {
- World world = player.getWorld();
-
- 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);
- }
+ public void cut(Player player, LocalSession session, EditSession editSession,
+ @Selection Region region, @Optional("air") Pattern leavePattern, @Switch('e') boolean copyEntities) throws WorldEditException {
+ 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);
- editSession.setBlocks(region, block);
- player.print("Block(s) cut.");
+ player.print(region.getArea() + " block(s) were copied.");
}
@Command(
@@ -156,38 +133,28 @@ public class ClipboardCommands {
)
@CommandPermissions("worldedit.clipboard.paste")
@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');
- boolean pasteNoAir = args.hasFlag('a');
+ Clipboard clipboard = session.getClipboard();
+ 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();
-
- Vector pos = atOrigin ? session.getClipboard().getOrigin()
- : session.getPlacementPosition(player);
-
- if (atOrigin) {
- clipboard.place(editSession, pos, pasteNoAir);
- 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 (selectPasted) {
+ Region region = clipboard.getRegion();
+ Vector max = to.add(region.getMaximumPoint().subtract(region.getMinimumPoint()));
+ RegionSelector selector = new CuboidRegionSelector(player.getWorld(), to, max);
+ session.setRegionSelector(player.getWorld(), selector);
+ selector.learnChanges();
+ selector.explainRegionAdjust(player, session);
}
- if (args.hasFlag('s')) {
- 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);
- }
+ player.print("The clipboard has been pasted at " + to.add(clipboard.getRegion().getMinimumPoint()));
}
@Command(
@@ -198,17 +165,9 @@ public class ClipboardCommands {
max = 1
)
@CommandPermissions("worldedit.clipboard.rotate")
- public void rotate(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
-
- int angle = args.getInteger(0);
-
- 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.");
- }
+ public void rotate(Player player, LocalSession session, EditSession editSession, CommandContext args) throws CommandException {
+ // TODO: Update for new clipboard
+ throw new CommandException("Needs to be re-written again");
}
@Command(
@@ -224,11 +183,9 @@ public class ClipboardCommands {
max = 1
)
@CommandPermissions("worldedit.clipboard.flip")
- public void flip(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
- CuboidClipboard.FlipDirection dir = worldEdit.getFlipDirection(player, args.argsLength() > 0 ? args.getString(0).toLowerCase() : "me");
- CuboidClipboard clipboard = session.getClipboard();
- clipboard.flip(dir, args.hasFlag('p'));
- player.print("Clipboard flipped.");
+ public void flip(Player player, LocalSession session, EditSession editSession, CommandContext args) throws CommandException {
+ // TODO: Update for new clipboard
+ throw new CommandException("Needs to be re-written again");
}
@Command(
diff --git a/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
index 61ea46fb8..6198ddb43 100644
--- a/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
+++ b/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
@@ -19,16 +19,22 @@
package com.sk89q.worldedit.command;
-import com.sk89q.minecraft.util.commands.*;
-import com.sk89q.worldedit.*;
+import com.sk89q.minecraft.util.commands.Command;
+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.extension.platform.Actor;
import com.sk89q.worldedit.schematic.SchematicFormat;
-import com.sk89q.worldedit.world.DataException;
import java.io.File;
import java.io.FileFilter;
-import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
@@ -64,58 +70,9 @@ public class SchematicCommands {
max = 2
)
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load"}) // TODO: Remove 'clipboard' perm
- public void load(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
-
- LocalConfiguration config = worldEdit.getConfiguration();
- 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());
- }
+ public void load(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException {
+ // TODO: Update for new clipboard
+ throw new CommandException("Needs to be re-written again");
}
@Command(
@@ -129,53 +86,8 @@ public class SchematicCommands {
)
@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 {
-
- LocalConfiguration config = worldEdit.getConfiguration();
- 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());
- }
+ // TODO: Update for new clipboard
+ throw new CommandException("Needs to be re-written again");
}
@Command(
diff --git a/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java
index 20cfba116..23e13cc3c 100644
--- a/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java
@@ -19,23 +19,13 @@
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.CommandAlias;
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.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.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
@@ -43,18 +33,28 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockType;
-import com.sk89q.worldedit.world.World;
-import com.sk89q.worldedit.world.storage.ChunkStore;
+import com.sk89q.worldedit.entity.Player;
+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.CuboidRegionSelector;
import com.sk89q.worldedit.regions.selector.CylinderRegionSelector;
import com.sk89q.worldedit.regions.selector.EllipsoidRegionSelector;
import com.sk89q.worldedit.regions.selector.ExtendingCuboidRegionSelector;
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.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.
@@ -584,15 +584,15 @@ public class SelectionCommands {
public void size(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
if (args.hasFlag('c')) {
- CuboidClipboard clipboard = session.getClipboard();
- Vector size = clipboard.getSize();
+ Clipboard clipboard = session.getClipboard();
+ Region region = clipboard.getRegion();
+ Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint());
Vector offset = clipboard.getOffset();
- player.print("Size: " + size);
+ player.print("Cuboid dimensions (max - min): " + size);
player.print("Offset: " + offset);
player.print("Cuboid distance: " + size.distance(Vector.ONE));
- player.print("# of blocks: "
- + (int) (size.getX() * size.getY() * size.getZ()));
+ player.print("# of blocks: " + (int) (size.getX() * size.getY() * size.getZ()));
return;
}
@@ -610,8 +610,7 @@ public class SelectionCommands {
}
player.print("Size: " + size);
- player.print("Cuboid distance: " + region.getMaximumPoint()
- .distance(region.getMinimumPoint()));
+ player.print("Cuboid distance: " + region.getMaximumPoint().distance(region.getMinimumPoint()));
player.print("# of blocks: " + region.getArea());
}
@@ -655,7 +654,7 @@ public class SelectionCommands {
max = 0
)
@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;
boolean useData = args.hasFlag('d');
@@ -663,13 +662,8 @@ public class SelectionCommands {
List> distributionData = null;
if (args.hasFlag('c')) {
- CuboidClipboard clip = session.getClipboard();
- if (useData) {
- distributionData = clip.getBlockDistributionWithData();
- } else {
- distribution = clip.getBlockDistribution();
- }
- size = clip.getHeight() * clip.getLength() * clip.getWidth();
+ // TODO: Update for new clipboard
+ throw new CommandException("Needs to be re-written again");
} else {
if (useData) {
distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld()));
diff --git a/src/main/java/com/sk89q/worldedit/command/tool/brush/ClipboardBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/ClipboardBrush.java
index ef5fffbcc..e200fcb66 100644
--- a/src/main/java/com/sk89q/worldedit/command/tool/brush/ClipboardBrush.java
+++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/ClipboardBrush.java
@@ -19,24 +19,35 @@
package com.sk89q.worldedit.command.tool.brush;
-import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
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.regions.Region;
public class ClipboardBrush implements Brush {
- private CuboidClipboard clipboard;
+ private Clipboard clipboard;
private boolean noAir;
- public ClipboardBrush(CuboidClipboard clipboard, boolean noAir) {
+ public ClipboardBrush(Clipboard clipboard, boolean noAir) {
this.clipboard = clipboard;
this.noAir = noAir;
}
+ @Override
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);
}
}
diff --git a/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java b/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java
new file mode 100644
index 000000000..bce5511aa
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java
@@ -0,0 +1,160 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 .
+ */
+
+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 entities = new ArrayList();
+
+ /**
+ * 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 getEntities() {
+ return new ArrayList(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);
+ }
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java b/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java
new file mode 100644
index 000000000..a8e4f27b6
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java
@@ -0,0 +1,58 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 .
+ */
+
+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.
+ *
+ * Implementations should return a copy of the region.
+ *
+ * @return the bounding region
+ */
+ Region getRegion();
+
+ /**
+ * Get the offset at which the area was copied from.
+ *
+ * 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);
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/extent/clipboard/StoredEntity.java b/src/main/java/com/sk89q/worldedit/extent/clipboard/StoredEntity.java
new file mode 100644
index 000000000..a38d2d412
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/extent/clipboard/StoredEntity.java
@@ -0,0 +1,76 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 .
+ */
+
+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.
+ *
+ * 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();
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java b/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java
index 21df293d5..c16718330 100644
--- a/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java
+++ b/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java
@@ -19,21 +19,18 @@
package com.sk89q.worldedit.function.pattern;
-import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.extent.clipboard.Clipboard;
import static com.google.common.base.Preconditions.checkNotNull;
/**
- * A pattern that reads from {@link CuboidClipboard}.
- *
- * @deprecated May be removed without notice, but there is no direct replacement yet
+ * A pattern that reads from {@link Clipboard}.
*/
-@Deprecated
public class ClipboardPattern extends AbstractPattern {
- private final CuboidClipboard clipboard;
+ private final Clipboard clipboard;
private final Vector size;
/**
@@ -41,10 +38,10 @@ public class ClipboardPattern extends AbstractPattern {
*
* @param clipboard the clipboard
*/
- public ClipboardPattern(CuboidClipboard clipboard) {
+ public ClipboardPattern(Clipboard clipboard) {
checkNotNull(clipboard);
this.clipboard = clipboard;
- this.size = clipboard.getSize();
+ this.size = clipboard.getMaximumPoint().subtract(clipboard.getMinimumPoint()).add(1, 1, 1);
}
@Override
@@ -53,7 +50,7 @@ public class ClipboardPattern extends AbstractPattern {
int yp = Math.abs(position.getBlockY()) % size.getBlockY();
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)));
}
}