diff --git a/src/main/java/com/sk89q/worldedit/LocalPlayer.java b/src/main/java/com/sk89q/worldedit/LocalPlayer.java index dbcfaa9a1..4fa98c7aa 100644 --- a/src/main/java/com/sk89q/worldedit/LocalPlayer.java +++ b/src/main/java/com/sk89q/worldedit/LocalPlayer.java @@ -456,6 +456,19 @@ public abstract class LocalPlayer { */ public abstract int getItemInHand(); + /** + * Get the Block that the player is holding. + * + * @return the item id of the item the player is holding + */ + public BaseBlock getBlockInHand() throws WorldEditException { + final int typeId = getItemInHand(); + if (!getWorld().isValidBlockType(typeId)) { + throw new NotABlockException(typeId); + } + return new BaseBlock(typeId); + } + /** * Get the name of the player. * diff --git a/src/main/java/com/sk89q/worldedit/NotABlockException.java b/src/main/java/com/sk89q/worldedit/NotABlockException.java new file mode 100644 index 000000000..06d045109 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/NotABlockException.java @@ -0,0 +1,34 @@ +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * 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; + +public class NotABlockException extends WorldEditException { + public NotABlockException() { + super("This item is not a block."); + } + + public NotABlockException(String type) { + super("The item '"+type+"' is not a block."); + } + + public NotABlockException(int typeId) { + super("The item with the ID "+typeId+" is not a block."); + } +} diff --git a/src/main/java/com/sk89q/worldedit/WorldEdit.java b/src/main/java/com/sk89q/worldedit/WorldEdit.java index 95f34f494..c5fe05436 100644 --- a/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -367,7 +367,7 @@ public class WorldEdit { } public BaseBlock getBlock(LocalPlayer player, String arg, boolean allAllowed) - throws UnknownItemException, DisallowedItemException { + throws WorldEditException { return getBlock(player, arg, allAllowed, false); } @@ -384,7 +384,7 @@ public class WorldEdit { */ public BaseBlock getBlock(LocalPlayer player, String arg, boolean allAllowed, boolean allowNoData) - throws UnknownItemException, DisallowedItemException { + throws WorldEditException { BlockType blockType; arg = arg.replace("_", " "); arg = arg.replace(";", "|"); @@ -397,44 +397,67 @@ public class WorldEdit { int data = -1; boolean parseDataValue = true; + if ("hand".equalsIgnoreCase(testID)) { + // Get the block type from the item in the user's hand. + final BaseBlock blockInHand = player.getBlockInHand(); + if (blockInHand.getClass() != BaseBlock.class) { + return blockInHand; + } - // Attempt to parse the item ID or otherwise resolve an item/block - // name to its numeric ID - try { - blockId = Integer.parseInt(testID); + blockId = blockInHand.getId(); blockType = BlockType.fromID(blockId); - } catch (NumberFormatException e) { - blockType = BlockType.lookup(testID); - if (blockType == null) { - int t = server.resolveItem(testID); - if (t > 0) { - blockType = BlockType.fromID(t); // Could be null - blockId = t; + data = blockInHand.getData(); + } else if ("pos1".equalsIgnoreCase(testID)) { + // Get the block type from the "primary position" + final LocalWorld world = player.getWorld(); + final BlockVector primaryPosition = getSession(player).getRegionSelector(world).getPrimaryPosition(); + final BaseBlock blockInHand = world.getBlock(primaryPosition); + if (blockInHand.getClass() != BaseBlock.class) { + return blockInHand; + } + + blockId = blockInHand.getId(); + blockType = BlockType.fromID(blockId); + data = blockInHand.getData(); + } else { + // Attempt to parse the item ID or otherwise resolve an item/block + // name to its numeric ID + try { + blockId = Integer.parseInt(testID); + blockType = BlockType.fromID(blockId); + } catch (NumberFormatException e) { + blockType = BlockType.lookup(testID); + if (blockType == null) { + int t = server.resolveItem(testID); + if (t > 0) { + blockType = BlockType.fromID(t); // Could be null + blockId = t; + } } } - } - if (blockId == -1 && blockType == null) { - // Maybe it's a cloth - ClothColor col = ClothColor.lookup(testID); - if (col == null) { - throw new UnknownItemException(arg); + if (blockId == -1 && blockType == null) { + // Maybe it's a cloth + ClothColor col = ClothColor.lookup(testID); + if (col == null) { + throw new UnknownItemException(arg); + } + + blockType = BlockType.CLOTH; + data = col.getID(); + + // Prevent overriding the data value + parseDataValue = false; } - blockType = BlockType.CLOTH; - data = col.getID(); + // Read block ID + if (blockId == -1) { + blockId = blockType.getID(); + } - // Prevent overriding the data value - parseDataValue = false; - } - - // Read block ID - if (blockId == -1) { - blockId = blockType.getID(); - } - - if (!player.getWorld().isValidBlockType(blockId)) { - throw new UnknownItemException(arg); + if (!player.getWorld().isValidBlockType(blockId)) { + throw new UnknownItemException(arg); + } } if (!allowNoData && data == -1) { @@ -620,12 +643,12 @@ public class WorldEdit { * @throws DisallowedItemException */ public BaseBlock getBlock(LocalPlayer player, String id) - throws UnknownItemException, DisallowedItemException { + throws WorldEditException { return getBlock(player, id, false); } public Set getBlocks(LocalPlayer player, String list, boolean allAllowed, boolean allowNoData) - throws DisallowedItemException, UnknownItemException { + throws WorldEditException { String[] items = list.split(","); Set blocks = new HashSet(); for (String id : items) { @@ -635,12 +658,12 @@ public class WorldEdit { } public Set getBlocks(LocalPlayer player, String list, boolean allAllowed) - throws DisallowedItemException, UnknownItemException { + throws WorldEditException { return getBlocks(player, list, allAllowed, false); } public Set getBlocks(LocalPlayer player, String list) - throws DisallowedItemException, UnknownItemException { + throws WorldEditException { return getBlocks(player, list, false); } @@ -655,7 +678,7 @@ public class WorldEdit { * @throws DisallowedItemException */ public Pattern getBlockPattern(LocalPlayer player, String patternString) - throws UnknownItemException, DisallowedItemException { + throws WorldEditException { String[] items = patternString.split(","); @@ -804,7 +827,7 @@ public class WorldEdit { */ public Set getBlockIDs(LocalPlayer player, String list, boolean allBlocksAllowed) - throws UnknownItemException, DisallowedItemException { + throws WorldEditException { String[] items = list.split(","); Set blocks = new HashSet(); diff --git a/src/main/java/com/sk89q/worldedit/blocks/BlockType.java b/src/main/java/com/sk89q/worldedit/blocks/BlockType.java index 8e99003c4..3eeff5ef9 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/BlockType.java +++ b/src/main/java/com/sk89q/worldedit/blocks/BlockType.java @@ -283,6 +283,39 @@ public enum BlockType { } } + private static Map itemBlockMapping = new HashMap(); + static { + itemBlockMapping.put(ItemID.FLINT_AND_TINDER, new BaseBlock(BlockID.FIRE, -1)); + itemBlockMapping.put(ItemID.STRING, new BaseBlock(BlockID.TRIPWIRE, -1)); + itemBlockMapping.put(ItemID.SEEDS, new BaseBlock(BlockID.CROPS, -1)); + itemBlockMapping.put(ItemID.SIGN, new BaseBlock(BlockID.SIGN_POST, -1)); + itemBlockMapping.put(ItemID.WOODEN_DOOR_ITEM, new BaseBlock(BlockID.WOODEN_DOOR, -1)); + itemBlockMapping.put(ItemID.WATER_BUCKET, new BaseBlock(BlockID.STATIONARY_WATER, -1)); + itemBlockMapping.put(ItemID.LAVA_BUCKET, new BaseBlock(BlockID.STATIONARY_LAVA, -1)); + itemBlockMapping.put(ItemID.IRON_DOOR_ITEM, new BaseBlock(BlockID.IRON_DOOR, -1)); + itemBlockMapping.put(ItemID.REDSTONE_DUST, new BaseBlock(BlockID.REDSTONE_WIRE, -1)); + itemBlockMapping.put(ItemID.SUGAR_CANE_ITEM, new BaseBlock(BlockID.REED, -1)); + itemBlockMapping.put(ItemID.BED_ITEM, new BaseBlock(BlockID.BED, -1)); + itemBlockMapping.put(ItemID.REDSTONE_REPEATER, new BaseBlock(BlockID.REDSTONE_REPEATER_OFF, -1)); + itemBlockMapping.put(ItemID.PUMPKIN_SEEDS, new BaseBlock(BlockID.PUMPKIN_STEM, -1)); + itemBlockMapping.put(ItemID.MELON_SEEDS, new BaseBlock(BlockID.MELON_STEM, -1)); + itemBlockMapping.put(ItemID.NETHER_WART_SEED, new BaseBlock(BlockID.NETHER_WART, -1)); + itemBlockMapping.put(ItemID.BREWING_STAND, new BaseBlock(BlockID.BREWING_STAND, -1)); + itemBlockMapping.put(ItemID.CAULDRON, new BaseBlock(BlockID.CAULDRON, -1)); + itemBlockMapping.put(ItemID.FLOWER_POT, new BaseBlock(BlockID.FLOWER_POT, -1)); + itemBlockMapping.put(ItemID.CARROT, new BaseBlock(BlockID.CARROTS, -1)); + itemBlockMapping.put(ItemID.POTATO, new BaseBlock(BlockID.POTATOES, -1)); + itemBlockMapping.put(ItemID.COMPARATOR, new BaseBlock(BlockID.COMPARATOR_OFF, -1)); + + // These are just for fun: + itemBlockMapping.put(ItemID.BUCKET, new BaseBlock(BlockID.AIR, -1)); // There's nothing in the bucket, what did you expect? + itemBlockMapping.put(ItemID.MILK_BUCKET, new BaseBlock(BlockID.SNOW, -1)); // Whoops, spilled the milk + } + + public static BaseBlock getBlockForItem(int typeId) { + return itemBlockMapping.get(typeId); + } + /** * Get block numeric ID. * diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index b137e6441..7374105e7 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -19,6 +19,8 @@ package com.sk89q.worldedit.bukkit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseBlock; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -49,6 +51,11 @@ public class BukkitPlayer extends LocalPlayer { return itemStack != null ? itemStack.getTypeId() : 0; } + public BaseBlock getBlockInHand() throws WorldEditException { + ItemStack itemStack = player.getItemInHand(); + return BukkitUtil.toBlock(getWorld(), itemStack); + } + @Override public String getName() { return player.getName(); diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitUtil.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitUtil.java index 975906041..cfc9f8c1d 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitUtil.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitUtil.java @@ -21,6 +21,14 @@ package com.sk89q.worldedit.bukkit; import java.util.List; +import com.sk89q.worldedit.NotABlockException; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.blocks.BlockType; +import com.sk89q.worldedit.blocks.ItemID; +import com.sk89q.worldedit.blocks.SkullBlock; +import org.bukkit.DyeColor; import org.bukkit.Server; import org.bukkit.World; import org.bukkit.block.Block; @@ -41,6 +49,8 @@ import com.sk89q.worldedit.bukkit.entity.BukkitEntity; import com.sk89q.worldedit.bukkit.entity.BukkitExpOrb; import com.sk89q.worldedit.bukkit.entity.BukkitItem; import com.sk89q.worldedit.bukkit.entity.BukkitPainting; +import org.bukkit.inventory.ItemStack; +import org.bukkit.material.Dye; public class BukkitUtil { private BukkitUtil() { @@ -153,4 +163,32 @@ public class BukkitUtil { return new BukkitEntity(toLocation(e.getLocation()), e.getType(), e.getUniqueId()); } } + + public static BaseBlock toBlock(LocalWorld world, ItemStack itemStack) throws WorldEditException { + final int typeId = itemStack.getTypeId(); + if (world.isValidBlockType(typeId)) { + return new BaseBlock(typeId, itemStack.getDurability()); + } + + switch (typeId) { + case ItemID.INK_SACK: + final Dye materialData = (Dye) itemStack.getData(); + if (materialData.getColor() == DyeColor.BROWN) { + return new BaseBlock(BlockID.COCOA_PLANT, -1); + } + break; + + case ItemID.HEAD: + return new SkullBlock(0, (byte) itemStack.getDurability()); + + default: + final BaseBlock baseBlock = BlockType.getBlockForItem(typeId); + if (baseBlock != null) { + return baseBlock; + } + break; + } + + throw new NotABlockException(typeId); + } } diff --git a/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java b/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java index b282151cc..f07ec4321 100644 --- a/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java +++ b/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java @@ -33,6 +33,7 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.UnknownItemException; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.commands.InsufficientArgumentsException; import com.sk89q.worldedit.patterns.Pattern; @@ -156,7 +157,7 @@ public class CraftScriptContext extends CraftScriptEnvironment { * @throws DisallowedItemException */ public BaseBlock getBlock(String arg, boolean allAllowed) - throws UnknownItemException, DisallowedItemException { + throws WorldEditException { return controller.getBlock(player, arg, allAllowed); } @@ -169,7 +170,7 @@ public class CraftScriptContext extends CraftScriptEnvironment { * @throws DisallowedItemException */ public BaseBlock getBlock(String id) - throws UnknownItemException, DisallowedItemException { + throws WorldEditException { return controller.getBlock(player, id, false); } @@ -182,7 +183,7 @@ public class CraftScriptContext extends CraftScriptEnvironment { * @throws DisallowedItemException */ public Pattern getBlockPattern(String list) - throws UnknownItemException, DisallowedItemException { + throws WorldEditException { return controller.getBlockPattern(player, list); } @@ -196,7 +197,7 @@ public class CraftScriptContext extends CraftScriptEnvironment { * @throws DisallowedItemException */ public Set getBlockIDs(String list, boolean allBlocksAllowed) - throws UnknownItemException, DisallowedItemException { + throws WorldEditException { return controller.getBlockIDs(player, list, allBlocksAllowed); }