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

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

View File

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

View File

@ -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<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");
public void setNbtData(CompoundTag rootTag) {
try {
if (rootTag == null) {
return;
}
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;
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<String, Tag> 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<String, Tag> values = rootTag.getValue();
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");
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<CompoundTag> compound = new ArrayList<CompoundTag>();
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.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");
}

View File

@ -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();

View File

@ -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");

View File

@ -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");

View File

@ -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");