diff --git a/src/EditSession.java b/src/EditSession.java
index 99d5a71fe..5a9c46e2f 100755
--- a/src/EditSession.java
+++ b/src/EditSession.java
@@ -17,10 +17,6 @@
* along with this program. If not, see .
*/
-import com.sk89q.worldedit.*;
-import com.sk89q.worldedit.regions.*;
-import com.sk89q.worldedit.blocks.*;
-import com.sk89q.worldedit.patterns.*;
import java.util.Map;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -31,6 +27,11 @@ import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
+import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.regions.*;
+import com.sk89q.worldedit.bags.*;
+import com.sk89q.worldedit.blocks.*;
+import com.sk89q.worldedit.patterns.*;
/**
* This class can wrap all block editing operations into one "edit session" that
@@ -43,6 +44,11 @@ import java.util.Random;
* @author sk89q
*/
public class EditSession {
+ /**
+ * Random number generator.
+ */
+ private static Random prng = new Random();
+
/**
* Stores the original blocks before modification.
*/
@@ -75,9 +81,13 @@ public class EditSession {
*/
private boolean queued = false;
/**
- * Random number generator.
+ * Block bag to use for getting blocks.
*/
- private static Random prng = new Random();
+ private BlockBag blockBag;
+ /**
+ * List of missing blocks;
+ */
+ private Set missingBlocks = new HashSet();
/**
* Construct the object with a maximum number of blocks.
@@ -89,6 +99,17 @@ public class EditSession {
this.maxBlocks = maxBlocks;
}
+ /**
+ * Construct the object with a maximum number of blocks and a block bag.
+ */
+ public EditSession(int maxBlocks, BlockBag blockBag) {
+ if (maxBlocks < -1) {
+ throw new IllegalArgumentException("Max blocks must be >= -1");
+ }
+ this.maxBlocks = maxBlocks;
+ this.blockBag = blockBag;
+ }
+
/**
* Sets a block without changing history.
*
@@ -96,19 +117,41 @@ public class EditSession {
* @param blockType
* @return Whether the block changed
*/
- private static boolean rawSetBlock(Vector pt, BaseBlock block) {
+ private boolean rawSetBlock(Vector pt, BaseBlock block) {
int y = pt.getBlockY();
if (y < 0 || y > 127) {
return false;
}
// Clear the chest so that it doesn't drop items
- if (ServerInterface.getBlockType(pt) == 54) {
+ if (ServerInterface.getBlockType(pt) == 54 && blockBag == null) {
ServerInterface.clearChest(pt);
}
int id = block.getID();
+ if (blockBag != null) {
+ int existing = ServerInterface.getBlockType(pt);
+
+ if (id > 0) {
+ try {
+ blockBag.fetchPlacedBlock(id);
+ } catch (UnplaceableBlockException e) {
+ return false;
+ } catch (BlockBagException e) {
+ missingBlocks.add(id);
+ return false;
+ }
+ }
+
+ if (existing > 0) {
+ try {
+ blockBag.storeDroppedBlock(existing);
+ } catch (BlockBagException e) {
+ }
+ }
+ }
+
boolean result = ServerInterface.setBlockType(pt, id);
if (id != 0) {
if (BlockType.usesData(id)) {
@@ -121,7 +164,7 @@ public class EditSession {
String[] text = signBlock.getText();
ServerInterface.setSignText(pt, text);
// Chests
- } else if (block instanceof ChestBlock) {
+ } else if (block instanceof ChestBlock && blockBag == null) {
ChestBlock chestBlock = (ChestBlock)block;
ServerInterface.setChestContents(pt, chestBlock.getItems());
// Mob spawners
@@ -337,10 +380,14 @@ public class EditSession {
BlockVector pt = (BlockVector)entry.getKey();
rawSetBlock(pt, (BaseBlock)entry.getValue());
}
-
- for (Map.Entry entry : queueLast) {
- BlockVector pt = (BlockVector)entry.getKey();
- rawSetBlock(pt, (BaseBlock)entry.getValue());
+
+ // We don't want to place these blocks if other blocks were missing
+ // because it might cause the items to drop
+ if (blockBag == null || missingBlocks.size() == 0) {
+ for (Map.Entry entry : queueLast) {
+ BlockVector pt = (BlockVector)entry.getKey();
+ rawSetBlock(pt, (BaseBlock)entry.getValue());
+ }
}
queueAfter.clear();
@@ -1897,4 +1944,30 @@ public class EditSession {
}
return minY;
}
+
+ /**
+ * Gets the list of missing blocks and clears the list for the next
+ * operation.
+ *
+ * @return
+ */
+ public Set popMissingBlocks() {
+ Set missingBlocks = this.missingBlocks;
+ this.missingBlocks = new HashSet();
+ return missingBlocks;
+ }
+
+ /**
+ * @return the blockBag
+ */
+ public BlockBag getBlockBag() {
+ return blockBag;
+ }
+
+ /**
+ * @param blockBag the blockBag to set
+ */
+ public void setBlockBag(BlockBag blockBag) {
+ this.blockBag = blockBag;
+ }
}
diff --git a/src/PlayerInventoryBlockBag.java b/src/PlayerInventoryBlockBag.java
new file mode 100644
index 000000000..35f480603
--- /dev/null
+++ b/src/PlayerInventoryBlockBag.java
@@ -0,0 +1,203 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.bags.*;
+
+public class PlayerInventoryBlockBag extends BlockBag {
+ /**
+ * Player instance.
+ */
+ private Player player;
+ /**
+ * The player's inventory;
+ */
+ private Item[] items;
+
+ /**
+ * Construct the object.
+ *
+ * @param player
+ */
+ public PlayerInventoryBlockBag(Player player) {
+ this.player = player;
+ }
+
+ /**
+ * Loads inventory on first use.
+ */
+ private void loadInventory() {
+ if (items == null) {
+ items = player.getInventory().getContents();
+ }
+ }
+
+ /**
+ * Get the player.
+ *
+ * @return
+ */
+ public Player getPlayer() {
+ return player;
+ }
+
+ /**
+ * Get a block.
+ *
+ * @param id
+ */
+ public void fetchBlock(int id) throws BlockBagException {
+ if (id == 0) {
+ throw new IllegalArgumentException("Can't fetch air block");
+ }
+
+ loadInventory();
+
+ boolean found = false;
+
+ for (int slot = 0; slot < items.length; slot++) {
+ Item item = items[slot];
+
+ if (item == null) continue;
+
+ if (item.getItemId() == id) {
+ int amount = item.getAmount();
+
+ // Unlimited
+ if (amount < 0) {
+ return;
+ }
+
+ if (amount > 1) {
+ item.setAmount(amount - 1);
+ found = true;
+ } else {
+ items[slot] = null;
+ found = true;
+ }
+
+ break;
+ }
+ }
+
+ if (found) {
+ } else {
+ throw new OutOfBlocksException();
+ }
+ }
+
+ /**
+ * Store a block.
+ *
+ * @param id
+ */
+ public void storeBlock(int id) throws BlockBagException {
+ if (id == 0) {
+ throw new IllegalArgumentException("Can't store air block");
+ }
+
+ loadInventory();
+
+ boolean found = false;
+ int freeSlot = -1;
+
+ for (int slot = 0; slot < items.length; slot++) {
+ Item item = items[slot];
+
+ // Delay using up a free slot until we know there are no stacks
+ // of this item to merge into
+ if (item == null) {
+ if (freeSlot == -1) {
+ freeSlot = slot;
+ }
+ continue;
+ }
+
+ if (item.getItemId() == id) {
+ int amount = item.getAmount();
+
+ // Unlimited
+ if (amount < 0) {
+ return;
+ }
+
+ if (amount < 64) {
+ item.setAmount(amount + 1);
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found && freeSlot > -1) {
+ items[freeSlot] = new Item(id, 1);
+ found = true;
+ }
+
+ if (found) {
+ } else {
+ throw new OutOfSpaceException(id);
+ }
+ }
+
+ /**
+ * Flush any changes. This is called at the end.
+ */
+ public void flushChanges() {
+ if (items != null) {
+ setContents(player.getInventory(), items);
+ items = null;
+ }
+ }
+
+ /**
+ * Adds a position to be used a source.
+ *
+ * @param pos
+ * @return
+ */
+ public void addSourcePosition(Vector pos) {
+ }
+ /**
+ * Adds a position to be used a source.
+ *
+ * @param pos
+ * @return
+ */
+ public void addSingleSourcePosition(Vector pos) {
+ }
+
+ /**
+ * Set the contents of an ItemArray.
+ *
+ * @param itemArray
+ * @param contents
+ */
+ private static void setContents(Inventory itemArray, Item[] contents) {
+ int size = itemArray.getContentsSize();
+
+ for (int i = 0; i < size; i++) {
+ if (contents[i] == null) {
+ itemArray.removeItem(i);
+ } else {
+ itemArray.setSlot(contents[i], i);
+ }
+ }
+ }
+}
diff --git a/src/ServerInterface.java b/src/ServerInterface.java
index cf0b817d4..3766a569b 100644
--- a/src/ServerInterface.java
+++ b/src/ServerInterface.java
@@ -18,12 +18,8 @@
*/
import com.sk89q.worldedit.*;
-import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
-import com.sk89q.worldedit.blocks.BlockType;
import java.util.logging.Logger;
-import java.util.Map;
-import java.util.HashMap;
import java.util.Random;
/**
@@ -336,6 +332,15 @@ public class ServerInterface {
etc.getServer().dropItem(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(),
type, 1);
}
+
+ /**
+ * Get a block bag for a player.
+ *
+ * @param player
+ */
+ public static PlayerInventoryBlockBag getPlayerBlockBag(WorldEditPlayer player) {
+ return new PlayerInventoryBlockBag(player.getPlayerObject());
+ }
/**
* Simulate a block being mined.
diff --git a/src/WorldEditListener.java b/src/WorldEditListener.java
index cd3943559..aeb8e5e45 100755
--- a/src/WorldEditListener.java
+++ b/src/WorldEditListener.java
@@ -29,6 +29,7 @@ import java.util.logging.Handler;
import java.util.logging.FileHandler;
import java.io.*;
import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.blocks.*;
import com.sk89q.worldedit.data.*;
import com.sk89q.worldedit.filters.*;
@@ -93,6 +94,8 @@ public class WorldEditListener extends PluginListener {
private boolean superPickaxeDrop = true;
private boolean superPickaxeManyDrop = true;
private boolean noDoubleSlash = false;
+ private boolean useInventory = false;
+ private boolean useInventoryOverride = false;
/**
* Construct an instance of the plugin.
@@ -190,6 +193,9 @@ public class WorldEditListener extends PluginListener {
changeLimit = defaultChangeLimit;
}
session.setBlockChangeLimit(changeLimit);
+ session.setUseInventory(useInventory
+ && (!useInventoryOverride
+ || !player.getPlayerObject().canUseCommand("/worldeditunlimited")));
sessions.put(player, session);
return session;
}
@@ -658,8 +664,10 @@ public class WorldEditListener extends PluginListener {
// Undo
} else if (split[0].equalsIgnoreCase("//undo")) {
checkArgs(split, 0, 0, split[0]);
- if (session.undo()) {
+ EditSession undone = session.undo(session.getBlockBag(player));
+ if (undone != null) {
player.print("Undo successful.");
+ flushBlockBag(player, undone);
} else {
player.printError("Nothing to undo.");
}
@@ -668,8 +676,10 @@ public class WorldEditListener extends PluginListener {
// Redo
} else if (split[0].equalsIgnoreCase("//redo")) {
checkArgs(split, 0, 0, split[0]);
- if (session.redo()) {
+ EditSession redone = session.redo(session.getBlockBag(player));
+ if (redone != null) {
player.print("Redo successful.");
+ flushBlockBag(player, redone);
} else {
player.printError("Nothing to redo.");
}
@@ -1967,7 +1977,7 @@ public class WorldEditListener extends PluginListener {
// Legacy /, command
if (split[0].equals("/,")) {
split[0] = "//";
- }
+ }
String searchCmd = split[0].toLowerCase();
@@ -1984,8 +1994,10 @@ public class WorldEditListener extends PluginListener {
if (canUseCommand(ply, split[0])) {
WorldEditPlayer player = new WorldEditPlayer(ply);
WorldEditSession session = getSession(player);
+ BlockBag blockBag = session.getBlockBag(player);
+
EditSession editSession =
- new EditSession(session.getBlockChangeLimit());
+ new EditSession(session.getBlockChangeLimit(), blockBag);
editSession.enableQueue();
long start = System.currentTimeMillis();
@@ -2000,6 +2012,8 @@ public class WorldEditListener extends PluginListener {
long time = System.currentTimeMillis() - start;
ply.sendMessage(Colors.Yellow + (time / 1000.0) + "s elapsed");
}
+
+ flushBlockBag(player, editSession);
}
}
}
@@ -2036,6 +2050,48 @@ public class WorldEditListener extends PluginListener {
return true;
}
+
+ /**
+ * Flush a block bag's changes to a player.
+ *
+ * @param player
+ * @param blockBag
+ * @param editSession
+ */
+ private static void flushBlockBag(WorldEditPlayer player,
+ EditSession editSession) {
+
+ BlockBag blockBag = editSession.getBlockBag();
+
+ if (blockBag != null) {
+ blockBag.flushChanges();
+ }
+
+ Set missingBlocks = editSession.popMissingBlocks();
+
+ if (missingBlocks.size() > 0) {
+ StringBuilder str = new StringBuilder();
+ str.append("Missing these blocks: ");
+ int size = missingBlocks.size();
+ int i = 0;
+
+ for (Integer id : missingBlocks) {
+ BlockType type = BlockType.fromID(id);
+
+ str.append(type != null
+ ? type.getName() + " (" + id + ")"
+ : id.toString());
+
+ i++;
+
+ if (i != size) {
+ str.append(", ");
+ }
+ }
+
+ player.printError(str.toString());
+ }
+ }
/**
* Checks to see if the player can use a command or /worldedit.
@@ -2095,6 +2151,8 @@ public class WorldEditListener extends PluginListener {
superPickaxeDrop = properties.getBoolean("super-pickaxe-drop-items", true);
superPickaxeManyDrop = properties.getBoolean("super-pickaxe-many-drop-items", false);
noDoubleSlash = properties.getBoolean("no-double-slash", false);
+ useInventory = properties.getBoolean("use-inventory", false);
+ useInventoryOverride = properties.getBoolean("use-inventory-override", false);
// Get allowed blocks
allowedBlocks = new HashSet();
diff --git a/src/WorldEditSession.java b/src/WorldEditSession.java
index 204b32a91..6b37658ba 100644
--- a/src/WorldEditSession.java
+++ b/src/WorldEditSession.java
@@ -18,6 +18,7 @@
*/
import com.sk89q.worldedit.snapshots.Snapshot;
+import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.*;
@@ -58,6 +59,7 @@ public class WorldEditSession {
private Tool tool = Tool.NONE;
private int superPickaxeRange = 3;
private int maxBlocksChanged = -1;
+ private boolean useInventory;
private Snapshot snapshot;
/**
@@ -91,14 +93,16 @@ public class WorldEditSession {
*
* @return whether anything was undone
*/
- public boolean undo() {
+ public EditSession undo(BlockBag newBlockBag) {
historyPointer--;
if (historyPointer >= 0) {
- history.get(historyPointer).undo();
- return true;
+ EditSession editSession = history.get(historyPointer);
+ editSession.setBlockBag(newBlockBag);
+ editSession.undo();
+ return editSession;
} else {
historyPointer = 0;
- return false;
+ return null;
}
}
@@ -107,14 +111,16 @@ public class WorldEditSession {
*
* @return whether anything was redone
*/
- public boolean redo() {
+ public EditSession redo(BlockBag newBlockBag) {
if (historyPointer < history.size()) {
- history.get(historyPointer).redo();
+ EditSession editSession = history.get(historyPointer);
+ editSession.setBlockBag(newBlockBag);
+ editSession.redo();
historyPointer++;
- return true;
+ return editSession;
}
- return false;
+ return null;
}
/**
@@ -336,6 +342,19 @@ public class WorldEditSession {
placeAtPos1 = !placeAtPos1;
return placeAtPos1;
}
+
+ /**
+ * Get a block bag for a player.
+ *
+ * @param player
+ * @return
+ */
+ public BlockBag getBlockBag(WorldEditPlayer player) {
+ if (!useInventory) {
+ return null;
+ }
+ return ServerInterface.getPlayerBlockBag(player);
+ }
/**
* @return the snapshotName
@@ -392,4 +411,18 @@ public class WorldEditSession {
public void setTool(Tool tool) {
this.tool = tool;
}
+
+ /**
+ * @return the useInventory
+ */
+ public boolean isUsingInventory() {
+ return useInventory;
+ }
+
+ /**
+ * @param useInventory the useInventory to set
+ */
+ public void setUseInventory(boolean useInventory) {
+ this.useInventory = useInventory;
+ }
}
diff --git a/src/com/sk89q/worldedit/bags/BlockBag.java b/src/com/sk89q/worldedit/bags/BlockBag.java
new file mode 100644
index 000000000..90bf92257
--- /dev/null
+++ b/src/com/sk89q/worldedit/bags/BlockBag.java
@@ -0,0 +1,153 @@
+// $Id$
+/*
+ * CraftBook
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+package com.sk89q.worldedit.bags;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.*;
+
+/**
+ * Represents a source to get blocks from and store removed ones.
+ *
+ * @author sk89q
+ */
+public abstract class BlockBag {
+ /**
+ * Stores a block as if it was mined.
+ *
+ * @param id
+ * @throws BlockBagException
+ */
+ public void storeDroppedBlock(int id) throws BlockBagException {
+ int dropped = BlockType.getDroppedBlock(id);
+ if (dropped > 0) {
+ storeBlock(dropped);
+ }
+ }
+
+ /**
+ * Sets a block as if it was placed by hand.
+ *
+ * @param id
+ * @throws BlockBagException
+ */
+ public void fetchPlacedBlock(int id) throws BlockBagException {
+ try {
+ // Blocks that can't be fetched...
+ if (id == BlockID.BEDROCK
+ || id == BlockID.GOLD_ORE
+ || id == BlockID.IRON_ORE
+ || id == BlockID.COAL_ORE
+ || id == BlockID.DIAMOND_ORE
+ || id == BlockID.LEAVES
+ || id == BlockID.TNT
+ || id == BlockID.MOB_SPAWNER
+ || id == BlockID.CROPS
+ || id == BlockID.REDSTONE_ORE
+ || id == BlockID.GLOWING_REDSTONE_ORE
+ || id == BlockID.SNOW
+ || id == BlockID.LIGHTSTONE
+ || id == BlockID.PORTAL) {
+ throw new UnplaceableBlockException();
+ }
+
+ // Override liquids
+ if (id == BlockID.WATER
+ || id == BlockID.STATIONARY_WATER
+ || id == BlockID.LAVA
+ || id == BlockID.STATIONARY_LAVA) {
+ return;
+ }
+
+ fetchBlock(id);
+ } catch (OutOfBlocksException e) {
+ // Look for cobblestone
+ if (id == BlockID.STONE) {
+ fetchBlock(BlockID.COBBLESTONE);
+ // Look for dirt
+ } else if (id == BlockID.GRASS) {
+ fetchBlock(BlockID.DIRT);
+ // Look for redstone dust
+ } else if (id == BlockID.REDSTONE_WIRE) {
+ fetchBlock(331);
+ // Look for furnace
+ } else if (id == BlockID.BURNING_FURNACE) {
+ fetchBlock(BlockID.FURNACE);
+ // Look for lit redstone torch
+ } else if (id == BlockID.REDSTONE_TORCH_OFF) {
+ fetchBlock(BlockID.REDSTONE_TORCH_ON);
+ // Look for signs
+ } else if (id == BlockID.WALL_SIGN || id == BlockID.SIGN_POST) {
+ fetchBlock(323);
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * Get a block.
+ *
+ * @param id
+ */
+ public abstract void fetchBlock(int id) throws BlockBagException;
+
+ /**
+ * Store a block.
+ *
+ * @param id
+ */
+ public abstract void storeBlock(int id) throws BlockBagException;
+
+ /**
+ * Checks to see if a block exists without removing it.
+ *
+ * @param id
+ * @return whether the block exists
+ */
+ public boolean peekBlock(int id) {
+ try {
+ fetchBlock(id);
+ storeBlock(id);
+ return true;
+ } catch (BlockBagException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Flush any changes. This is called at the end.
+ */
+ public abstract void flushChanges();
+
+ /**
+ * Adds a position to be used a source.
+ *
+ * @param pos
+ * @return
+ */
+ public abstract void addSourcePosition(Vector pos);
+ /**
+ * Adds a position to be used a source.
+ *
+ * @param pos
+ * @return
+ */
+ public abstract void addSingleSourcePosition(Vector pos);
+}
diff --git a/src/com/sk89q/worldedit/bags/BlockBagException.java b/src/com/sk89q/worldedit/bags/BlockBagException.java
new file mode 100644
index 000000000..2792c7b82
--- /dev/null
+++ b/src/com/sk89q/worldedit/bags/BlockBagException.java
@@ -0,0 +1,28 @@
+// $Id$
+/*
+ * CraftBook
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+package com.sk89q.worldedit.bags;
+
+/**
+ *
+ * @author sk89q
+ */
+public class BlockBagException extends Exception {
+ private static final long serialVersionUID = 4672190086028430655L;
+}
diff --git a/src/com/sk89q/worldedit/bags/OutOfBlocksException.java b/src/com/sk89q/worldedit/bags/OutOfBlocksException.java
new file mode 100644
index 000000000..34fe783e9
--- /dev/null
+++ b/src/com/sk89q/worldedit/bags/OutOfBlocksException.java
@@ -0,0 +1,28 @@
+// $Id$
+/*
+ * CraftBook
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+package com.sk89q.worldedit.bags;
+
+/**
+ *
+ * @author sk89q
+ */
+public class OutOfBlocksException extends BlockBagException {
+ private static final long serialVersionUID = 7495899825677689509L;
+}
diff --git a/src/com/sk89q/worldedit/bags/OutOfSpaceException.java b/src/com/sk89q/worldedit/bags/OutOfSpaceException.java
new file mode 100644
index 000000000..46ca23caa
--- /dev/null
+++ b/src/com/sk89q/worldedit/bags/OutOfSpaceException.java
@@ -0,0 +1,48 @@
+// $Id$
+/*
+ * CraftBook
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+package com.sk89q.worldedit.bags;
+
+/**
+ *
+ * @author sk89q
+ */
+public class OutOfSpaceException extends BlockBagException {
+ private static final long serialVersionUID = -2962840237632916821L;
+
+ /**
+ * Stores the block ID.
+ */
+ private int id;
+
+ /**
+ * Construct the object.
+ * @param id
+ */
+ public OutOfSpaceException(int id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the id
+ */
+ public int getID() {
+ return id;
+ }
+}
diff --git a/src/com/sk89q/worldedit/bags/UnplaceableBlockException.java b/src/com/sk89q/worldedit/bags/UnplaceableBlockException.java
new file mode 100644
index 000000000..0513e69fb
--- /dev/null
+++ b/src/com/sk89q/worldedit/bags/UnplaceableBlockException.java
@@ -0,0 +1,30 @@
+// $Id$
+/*
+ * CraftBook
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+package com.sk89q.worldedit.bags;
+
+
+/**
+ *
+ * @author sk89q
+ */
+public class UnplaceableBlockException extends BlockBagException {
+ private static final long serialVersionUID = 7227883966999843526L;
+
+}
diff --git a/src/com/sk89q/worldedit/blocks/BlockID.java b/src/com/sk89q/worldedit/blocks/BlockID.java
new file mode 100644
index 000000000..d62d9cf29
--- /dev/null
+++ b/src/com/sk89q/worldedit/blocks/BlockID.java
@@ -0,0 +1,105 @@
+// $Id$
+/*
+ * CraftBook
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+package com.sk89q.worldedit.blocks;
+
+/**
+ * List of block IDs.
+ *
+ * @author sk89q
+ */
+public final class BlockID {
+ public static final int AIR = 0;
+ public static final int STONE = 1;
+ public static final int GRASS = 2;
+ public static final int DIRT = 3;
+ public static final int COBBLESTONE = 4;
+ public static final int WOOD = 5;
+ public static final int SAPLING = 6;
+ public static final int BEDROCK = 7;
+ public static final int WATER = 8;
+ public static final int STATIONARY_WATER = 9;
+ public static final int LAVA = 10;
+ public static final int STATIONARY_LAVA = 11;
+ public static final int SAND = 12;
+ public static final int GRAVEL = 13;
+ public static final int GOLD_ORE = 14;
+ public static final int IRON_ORE = 15;
+ public static final int COAL_ORE = 16;
+ public static final int LOG = 17;
+ public static final int LEAVES = 18;
+ public static final int SPONGE = 19;
+ public static final int GLASS = 20;
+ public static final int CLOTH = 35;
+ public static final int YELLOW_FLOWER = 37;
+ public static final int RED_FLOWER = 38;
+ public static final int BROWN_MUSHROOM = 39;
+ public static final int RED_MUSHROOM = 40;
+ public static final int GOLD_BLOCK = 41;
+ public static final int IRON_BLOCK = 42;
+ public static final int DOUBLE_STEP = 43;
+ public static final int STEP = 44;
+ public static final int BRICK = 45;
+ public static final int TNT = 46;
+ public static final int BOOKCASE = 47;
+ public static final int MOSSY_COBBLESTONE = 48;
+ public static final int OBSIDIAN = 49;
+ public static final int TORCH = 50;
+ public static final int FIRE = 51;
+ public static final int MOB_SPAWNER = 52;
+ public static final int WOODEN_STAIRS = 53;
+ public static final int CHEST = 54;
+ public static final int REDSTONE_WIRE = 55;
+ public static final int DIAMOND_ORE = 56;
+ public static final int DIAMOND_BLOCK = 57;
+ public static final int WORKBENCH = 58;
+ public static final int CROPS = 59;
+ public static final int SOIL = 60;
+ public static final int FURNACE = 61;
+ public static final int BURNING_FURNACE = 62;
+ public static final int SIGN_POST = 63;
+ public static final int WOODEN_DOOR = 64;
+ public static final int LADDER = 65;
+ public static final int MINECART_TRACKS = 66;
+ public static final int COBBLESTONE_STAIRS = 67;
+ public static final int WALL_SIGN = 68;
+ public static final int LEVER = 69;
+ public static final int STONE_PRESSURE_PLATE = 70;
+ public static final int IRON_DOOR = 71;
+ public static final int WOODEN_PRESSURE_PLATE = 72;
+ public static final int REDSTONE_ORE = 73;
+ public static final int GLOWING_REDSTONE_ORE = 74;
+ public static final int REDSTONE_TORCH_OFF = 75;
+ public static final int REDSTONE_TORCH_ON = 76;
+ public static final int STONE_BUTTON = 77;
+ public static final int SNOW = 78;
+ public static final int ICE = 79;
+ public static final int SNOW_BLOCK = 80;
+ public static final int CACTUS = 81;
+ public static final int CLAY = 82;
+ public static final int REED = 83;
+ public static final int JUKEBOX = 84;
+ public static final int FENCE = 85;
+ public static final int PUMPKIN = 86;
+ public static final int NETHERSTONE = 87;
+ public static final int SLOW_SAND = 88;
+ public static final int LIGHTSTONE = 89;
+ public static final int PORTAL = 90;
+ public static final int JACKOLANTERN = 91;
+}
diff --git a/src/com/sk89q/worldedit/blocks/BlockType.java b/src/com/sk89q/worldedit/blocks/BlockType.java
index 89de10e9c..88298e99c 100644
--- a/src/com/sk89q/worldedit/blocks/BlockType.java
+++ b/src/com/sk89q/worldedit/blocks/BlockType.java
@@ -108,6 +108,83 @@ public enum BlockType {
PORTAL(90, "Portal", "portal"),
LIGHTED_PUMPKIN(91, "Pumpkin (on)", new String[]{"pumpkinlighted", "pumpkinon", "litpumpkin"});
+ /**
+ * Stores a list of dropped blocks for blocks.
+ */
+ private static final Map blockDrops = new HashMap();
+
+ /**
+ * Static constructor.
+ */
+ static {
+ blockDrops.put(1, 4);
+ blockDrops.put(2, 3);
+ blockDrops.put(3, 3);
+ blockDrops.put(4, 4);
+ blockDrops.put(5, 5);
+ blockDrops.put(6, 6);
+ blockDrops.put(7, -1);
+ blockDrops.put(12, 12);
+ blockDrops.put(13, 13);
+ blockDrops.put(14, 14);
+ blockDrops.put(15, 15);
+ blockDrops.put(16, 16);
+ blockDrops.put(17, 17);
+ blockDrops.put(18, 18);
+ blockDrops.put(19, 19);
+ blockDrops.put(20, 20); // Have to drop glass for //undo
+ blockDrops.put(35, 35);
+ blockDrops.put(37, 37);
+ blockDrops.put(38, 38);
+ blockDrops.put(39, 39);
+ blockDrops.put(40, 40);
+ blockDrops.put(41, 41);
+ blockDrops.put(42, 42);
+ blockDrops.put(43, 43);
+ blockDrops.put(44, 44);
+ blockDrops.put(45, 45);
+ blockDrops.put(47, 47);
+ blockDrops.put(48, 48);
+ blockDrops.put(49, 49);
+ blockDrops.put(50, 50);
+ blockDrops.put(53, 53);
+ blockDrops.put(54, 54);
+ blockDrops.put(55, 331);
+ blockDrops.put(56, 56);
+ blockDrops.put(57, 57);
+ blockDrops.put(58, 58);
+ blockDrops.put(59, 295);
+ blockDrops.put(60, 60);
+ blockDrops.put(61, 61);
+ blockDrops.put(62, 61);
+ blockDrops.put(63, 323);
+ blockDrops.put(64, 324);
+ blockDrops.put(65, 65);
+ blockDrops.put(66, 66);
+ blockDrops.put(67, 67);
+ blockDrops.put(68, 323);
+ blockDrops.put(69, 69);
+ blockDrops.put(70, 70);
+ blockDrops.put(71, 330);
+ blockDrops.put(72, 72);
+ blockDrops.put(73, 331);
+ blockDrops.put(74, 331);
+ blockDrops.put(75, 76);
+ blockDrops.put(76, 76);
+ blockDrops.put(77, 77);
+ blockDrops.put(80, 80);
+ blockDrops.put(81, 81);
+ blockDrops.put(82, 82);
+ blockDrops.put(83, 83);
+ blockDrops.put(84, 84);
+ blockDrops.put(85, 85);
+ blockDrops.put(86, 86);
+ blockDrops.put(87, 87);
+ blockDrops.put(88, 88);
+ blockDrops.put(89, 248);
+ blockDrops.put(91, 91);
+ }
+
/**
* Stores a map of the IDs for fast access.
*/
@@ -301,4 +378,20 @@ public enum BlockType {
|| id == 77 // Stone button
|| id == 81; // Cactus
}
+
+ /**
+ * Get the block or item that would have been dropped. If nothing is
+ * dropped, 0 will be returned. If the block should not be destroyed
+ * (i.e. bedrock), -1 will be returned.
+ *
+ * @param id
+ * @return
+ */
+ public static int getDroppedBlock(int id) {
+ Integer dropped = blockDrops.get(id);
+ if (dropped == null) {
+ return 0;
+ }
+ return dropped;
+ }
}
\ No newline at end of file