From ebb25ff41cfae4d8f4f3ac9b7ebf43424b2fb5ef Mon Sep 17 00:00:00 2001 From: sk89q Date: Fri, 15 Oct 2010 00:22:03 -0700 Subject: [PATCH] Now using com.sk89q.worldedit.blocks.BlockType for block type queries. rawSetBlock() now handles changes in block data. WorldEdit.getBlock() now supports specifying data and sign text. --- src/CuboidClipboard.java | 2 +- src/EditSession.java | 22 +- src/WorldEdit.java | 50 +++-- src/com/sk89q/worldedit/blocks/BaseBlock.java | 2 +- src/com/sk89q/worldedit/blocks/BlockType.java | 189 ++++++++++++++++++ 5 files changed, 243 insertions(+), 22 deletions(-) create mode 100644 src/com/sk89q/worldedit/blocks/BlockType.java diff --git a/src/CuboidClipboard.java b/src/CuboidClipboard.java index bb9397dfe..44ccaae82 100644 --- a/src/CuboidClipboard.java +++ b/src/CuboidClipboard.java @@ -233,7 +233,7 @@ public class CuboidClipboard { for (int y = 0; y < height; y++) { for (int z = 0; z < length; z++) { int index = y * width * length + z * width + x; - blocks[index] = (byte)data[x][y][z].getType(); + blocks[index] = (byte)data[x][y][z].getID(); blockData[index] = (byte)data[x][y][z].getData(); // Store TileEntity data diff --git a/src/EditSession.java b/src/EditSession.java index 362281dd7..e36c83493 100644 --- a/src/EditSession.java +++ b/src/EditSession.java @@ -112,7 +112,13 @@ public class EditSession { * @return Whether the block changed */ private boolean rawSetBlock(Vector pt, BaseBlock block) { - boolean result = server.setBlockType(pt, block.getType()); + boolean result = server.setBlockType(pt, block.getID()); + // Changes in block data don't take effect if the block type doesn't + // change, so here's a hack! + if (!result && block.getID() != 0) { + server.setBlockType(pt, 0); + result = server.setBlockType(pt, block.getID()); + } server.setBlockData(pt, block.getData()); // Signs @@ -176,12 +182,12 @@ public class EditSession { */ private boolean smartSetBlock(Vector pt, BaseBlock block) { if (queued) { - if (!block.isAir() && queuedBlocks.contains(block.getType()) + if (!block.isAir() && queuedBlocks.contains(block.getID()) && rawGetBlock(pt.add(0, -1, 0)).isAir()) { queue.put(pt.toBlockVector(), block); - return getBlock(pt).getType() != block.getType(); + return getBlock(pt).getID() != block.getID(); } else if (block.isAir() - && queuedBlocks.contains(rawGetBlock(pt.add(0, 1, 0)).getType())) { + && queuedBlocks.contains(rawGetBlock(pt.add(0, 1, 0)).getID())) { rawSetBlock(pt.add(0, 1, 0), new BaseBlock(0)); // Prevent items from being dropped } } @@ -532,7 +538,7 @@ public class EditSession { for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { Vector pt = new Vector(x, y, z); - int curBlockType = getBlock(pt).getType(); + int curBlockType = getBlock(pt).getID(); if (fromBlockType == -1 && curBlockType != 0 || curBlockType == fromBlockType) { @@ -545,7 +551,7 @@ public class EditSession { } } else { for (Vector pt : region) { - int curBlockType = getBlock(pt).getType(); + int curBlockType = getBlock(pt).getID(); if (fromBlockType == -1 && curBlockType != 0 || curBlockType == fromBlockType) { @@ -706,7 +712,7 @@ public class EditSession { while (!queue.empty()) { BlockVector cur = queue.pop(); - int type = getBlock(cur).getType(); + int type = getBlock(cur).getID(); // Check block type if (type != 8 && type != 9 && type != 10 && type != 11) { @@ -844,7 +850,7 @@ public class EditSession { for (int y = basePos.getBlockY(); y >= basePos.getBlockY() - 10; y--) { // Check if we hit the ground - int t = getBlock(new Vector(x, y, z)).getType(); + int t = getBlock(new Vector(x, y, z)).getID(); if (t == 2 || t == 3) { makePineTree(new Vector(x, y + 1, z)); affected++; diff --git a/src/WorldEdit.java b/src/WorldEdit.java index 2e8cfbe4b..a9835ee73 100644 --- a/src/WorldEdit.java +++ b/src/WorldEdit.java @@ -26,6 +26,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.io.*; import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.*; /** * Plugin base. @@ -166,28 +167,53 @@ public class WorldEdit { /** * Get an item ID from an item name or an item ID number. * - * @param id + * @param arg * @return * @throws UnknownItemException * @throws DisallowedItemException */ - public BaseBlock getBlock(String id, boolean allAllowed) + public BaseBlock getBlock(String arg, boolean allAllowed) throws UnknownItemException, DisallowedItemException { - int foundID; + BlockType blockType; + arg = arg.replace("_", " "); + String[] args0 = arg.split("\\|"); + String[] args1 = args0[0].split(":", 2); + String testID = args1[0]; + + int data; + + try { + data = args1.length > 1 ? Integer.parseInt(args1[1]) : 0; + if (data > 15 || data < 0) { + data = 0; + } + } catch (NumberFormatException e) { + data = 0; + } try { - foundID = Integer.parseInt(id); + blockType = BlockType.fromID(Integer.parseInt(testID)); } catch (NumberFormatException e) { - try { - foundID = etc.getDataSource().getItem(id); - } catch (NumberFormatException e2) { - throw new UnknownItemException(); - } + blockType = BlockType.lookup(testID); + } + + if (blockType == null) { + throw new UnknownItemException(); } // Check if the item is allowed - if (allAllowed || allowedBlocks.isEmpty() || allowedBlocks.contains(foundID)) { - return new BaseBlock(foundID); + if (allAllowed || allowedBlocks.isEmpty() + || allowedBlocks.contains(blockType.getID())) { + if (blockType == BlockType.SIGN_POST + || blockType == BlockType.WALL_SIGN) { + String[] text = new String[4]; + text[0] = args0.length > 1 ? args0[1] : ""; + text[1] = args0.length > 2 ? args0[2] : ""; + text[2] = args0.length > 3 ? args0[3] : ""; + text[3] = args0.length > 4 ? args0[4] : ""; + return new SignBlock(blockType.getID(), data, text); + } + return new BaseBlock(blockType.getID(), data); } throw new DisallowedItemException(); @@ -520,7 +546,7 @@ public class WorldEdit { from = -1; to = getBlock(split[1]); } else { - from = getBlock(split[1]).getType(); + from = getBlock(split[1]).getID(); to = getBlock(split[2]); } diff --git a/src/com/sk89q/worldedit/blocks/BaseBlock.java b/src/com/sk89q/worldedit/blocks/BaseBlock.java index 11c15a124..eb6a59aae 100644 --- a/src/com/sk89q/worldedit/blocks/BaseBlock.java +++ b/src/com/sk89q/worldedit/blocks/BaseBlock.java @@ -56,7 +56,7 @@ public class BaseBlock { /** * @return the type */ - public int getType() { + public int getID() { return (int)type; } diff --git a/src/com/sk89q/worldedit/blocks/BlockType.java b/src/com/sk89q/worldedit/blocks/BlockType.java new file mode 100644 index 000000000..1d8970481 --- /dev/null +++ b/src/com/sk89q/worldedit/blocks/BlockType.java @@ -0,0 +1,189 @@ +// $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 . +*/ + +package com.sk89q.worldedit.blocks; + +import java.util.Map; +import java.util.HashMap; +import java.util.EnumSet; + +/** + * Block types. + * + * @author sk89q + */ +public enum BlockType { + AIR(0, "Air", "air"), + STONE(1, "Stone", new String[]{"stone", "rock"}), + GRASS(2, "Grass", "grass"), + DIRT(3, "Dirt", "dirt"), + COBBLESTONE(4, "Cobblestone", "cobblestone"), + WOOD(5, "Wood", "wood"), + SAPLING(6, "Sapling", "sapling"), + BEDROCK(7, "Bedrock", "bedrock"), + WATER(8, "Water", "watermoving"), + STATIONARY_WATER(9, "Water (stationary)", "water"), + LAVA(10, "Lava", "lavamoving"), + STATIONARY_LAVA(11, "Lava (stationary)", "lava"), + SAND(12, "Sand", "sand"), + GRAVEL(13, "Gravel", "gravel"), + GOLD_ORE(14, "Gold ore", "goldore"), + IRON_ORE(15, "Iron ore", "ironore"), + COAL_ORE(16, "Coal ore", "coalore"), + LOG(17, "Log", "log"), + LEAVES(18, "Leaves", "leaves"), + SPONGE(19, "Sponge", "sponge"), + GLASS(20, "Glass", "glass"), + CLOTH(35, "Cloth", "cloth"), + YELLOW_FLOWER(37, "Yellow flower", "yellowflower"), + RED_FLOWER(38, "Red rose", new String[]{"redflower", "redrose"}), + BROWN_MUSHROOM(39, "Brown mushroom", "brownmushroom"), + RED_MUSHROOM(40, "Red mushroom", "redmushroom"), + GOLD_BLOCK(41, "Gold block", new String[]{"gold", "goldblock"}), + IRON_BLOCK(42, "Iron block", new String[]{"iron", "ironblock"}), + DOUBLE_STEP(43, "Double step", "doublestep"), + STEP(44, "Step", "step"), + BRICK(45, "Brick", "brick"), + TNT(46, "TNT", "tnt"), + BOOKCASE(47, "Bookcase", new String[]{"bookshelf", "bookshelf"}), + MOSSY_COBBLESTONE(48, "Cobblestone (mossy)", "mossycobblestone"), + OBSIDIAN(49, "Obsidian", "obsidian"), + TORCH(50, "Torch", "torch"), + FIRE(51, "Fire", "fire"), + MOB_SPAWNER(52, "Mob spawner", "mobspawner"), + WOODEN_STAIRS(53, "Wooden stairs", "woodstairs"), + CHEST(54, "Chest", "chest"), + REDSTONE_WIRE(55, "Redstone wire", "redstone"), + DIAMOND_ORE(56, "Diamond ore", "diamondore"), + DIAMOND_BLOCK(57, "Diamond block", new String[]{"diamond", "diamondblock"}), + WORKBENCH(58, "Workbench", "workbench"), + CROPS(59, "Crops", "crops"), + SOIL(60, "Soil", "soil"), + FURNACE(61, "Furnace", "furnace"), + BURNING_FURNACE(62, "Furnace (burning)", "burningfurnace"), + SIGN_POST(63, "Sign post", new String[]{"sign", "signpost"}), + WOODEN_DOOR(64, "Wooden door", "wooddoor"), + LADDER(65, "Ladder", "ladder"), + MINECART_TRACKS(66, "Minecart tracks", new String[]{"track", "tracks"}), + COBBLESTONE_STAIRS(67, "Cobblestone stairs", "cobblestonestairs"), + WALL_SIGN(68, "Wall sign", "wallsign"), + LEVER(69, "Lever", "level"), + STONE_PRESSURE_PLATE(70, "Stone pressure plate", "stonepressureplate"), + IRON_DOOR(71, "Iron Door", "irondoor"), + WOODEN_PRESSURE_PLATE(72, "Wooden pressure plate", "woodpressureplate"), + REDSTONE_ORE(73, "Redstone ore", "redstoneore"), + GLOWING_REDSTONE_ORE(74, "Glowing redstone ore", "glowingredstoneore"), + REDSTONE_TORCH_OFF(75, "Redstone torch (off)", + new String[]{"redstonetorch"," redstonetorchon"}), + REDSTONE_TORCH_ON(76, "Redstone torch (on)", "redstonetorchon"), + STONE_BUTTON(77, "Stone Button", "stonebutton"), + SNOW(78, "Snow", "snow"), + ICE(79, "Ice", "ice"), + SNOW_BLOCK(80, "Snow Block", "snowblock"), + CACTUS(81, "Cactus", "cactus"), + CLAY(82, "Clay", "clay"), + REED(83, "Reed", "reed"), + JUKEBOX(84, "Jukebox", "jukebox"), + FENCE(85, "Fence", "fence"); + + /** + * Stores a map of the IDs for fast access. + */ + private static final Map ids = new HashMap(); + /** + * Stores a map of the names for fast access. + */ + private static final Map lookup = new HashMap(); + + private final int id; + private final String name; + private final String[] lookupKeys; + + static { + for(BlockType type : EnumSet.allOf(BlockType.class)) { + ids.put(type.id, type); + for (String key : type.lookupKeys) { + lookup.put(key, type); + } + } + } + + + /** + * Construct the type. + * + * @param id + * @param name + */ + BlockType(int id, String name, String lookupKey) { + this.id = id; + this.name = name; + this.lookupKeys = new String[]{lookupKey}; + } + + /** + * Construct the type. + * + * @param id + * @param name + */ + BlockType(int id, String name, String[] lookupKeys) { + this.id = id; + this.name = name; + this.lookupKeys = lookupKeys; + } + + /** + * Return type from ID. May return null. + * + * @param id + * @return + */ + public static BlockType fromID(int id) { + return ids.get(id); + } + + /** + * Return type from name. May return null. + * + * @param name + * @return + */ + public static BlockType lookup(String name) { + return lookup.get(name.toLowerCase()); + } + + /** + * Get block numeric ID. + * + * @return + */ + public int getID() { + return id; + } + + /** + * Get user-friendly block name. + * + * @return + */ + public String getName() { + return name; + } +} \ No newline at end of file