From 0ec0b4202642e503d86a2782633b223111ac77f8 Mon Sep 17 00:00:00 2001 From: sk89q Date: Fri, 26 Nov 2010 19:33:28 -0800 Subject: [PATCH] Added mob spawner support; added 'info' tool. --- src/CuboidClipboard.java | 10 +- src/EditSession.java | 11 +- src/ServerInterface.java | 42 ++++- src/WorldEditListener.java | 30 ++++ src/WorldEditPlayer.java | 9 ++ src/WorldEditSession.java | 3 +- .../worldedit/DisallowedItemException.java | 7 +- .../sk89q/worldedit/InvalidItemException.java | 30 ++++ .../worldedit/blocks/MobSpawnerBlock.java | 153 ++++++++++++++++++ src/com/sk89q/worldedit/data/Chunk.java | 11 ++ 10 files changed, 299 insertions(+), 7 deletions(-) create mode 100644 src/com/sk89q/worldedit/InvalidItemException.java create mode 100644 src/com/sk89q/worldedit/blocks/MobSpawnerBlock.java diff --git a/src/CuboidClipboard.java b/src/CuboidClipboard.java index d73abaef0..6846bda22 100644 --- a/src/CuboidClipboard.java +++ b/src/CuboidClipboard.java @@ -389,18 +389,24 @@ public class CuboidClipboard { BlockVector pt = new BlockVector(x, y, z); BaseBlock block; - if (blocks[index] == 63 || blocks[index] == 68) { + if (blocks[index] == 63 || blocks[index] == 68) { // Signs block = new SignBlock(blocks[index], blockData[index]); if (tileEntitiesMap.containsKey(pt)) { ((TileEntityBlock)block).fromTileEntityNBT( tileEntitiesMap.get(pt)); } - } else if(blocks[index] == 54) { + } else if(blocks[index] == 54) { // Chest block = new ChestBlock(); if (tileEntitiesMap.containsKey(pt)) { ((TileEntityBlock)block).fromTileEntityNBT( tileEntitiesMap.get(pt)); } + } else if(blocks[index] == 52) { // Mob spawner + block = new MobSpawnerBlock(); + if (tileEntitiesMap.containsKey(pt)) { + ((TileEntityBlock)block).fromTileEntityNBT( + tileEntitiesMap.get(pt)); + } } else { block = new BaseBlock(blocks[index], blockData[index]); } diff --git a/src/EditSession.java b/src/EditSession.java index 47e08c691..87408efd7 100755 --- a/src/EditSession.java +++ b/src/EditSession.java @@ -94,7 +94,7 @@ public class EditSession { * @param blockType * @return Whether the block changed */ - private boolean rawSetBlock(Vector pt, BaseBlock block) { + private static boolean rawSetBlock(Vector pt, BaseBlock block) { int y = pt.getBlockY(); if (y < 0 || y > 127) { return false; @@ -132,6 +132,10 @@ public class EditSession { ServerInterface.setChestSlot(pt, i, blankItem, 0); } } + // Mob spawners + } else if (block instanceof MobSpawnerBlock) { + MobSpawnerBlock mobSpawnerblock = (MobSpawnerBlock)block; + ServerInterface.setMobSpawnerType(pt, mobSpawnerblock.getMobType()); } } @@ -229,7 +233,7 @@ public class EditSession { * @param pt * @return BaseBlock */ - public BaseBlock rawGetBlock(Vector pt) { + public static BaseBlock rawGetBlock(Vector pt) { int type = ServerInterface.getBlockType(pt); int data = ServerInterface.getBlockData(pt); @@ -241,6 +245,9 @@ public class EditSession { } else if (type == 54) { Map> items = ServerInterface.getChestContents(pt); return new ChestBlock(data, items); + // Mob spawner + } else if (type == 52) { + return new MobSpawnerBlock(data, ServerInterface.getMobSpawnerType(pt)); } else { return new BaseBlock(type, data); } diff --git a/src/ServerInterface.java b/src/ServerInterface.java index a693e988c..05647436d 100644 --- a/src/ServerInterface.java +++ b/src/ServerInterface.java @@ -24,7 +24,7 @@ import java.util.logging.Level; import java.util.Map; import java.util.HashMap; import java.util.Random; -import java.lang.reflect.Constructor; +import java.lang.reflect.*; import sun.reflect.ReflectionFactory; /** @@ -204,6 +204,46 @@ public class ServerInterface { return true; } + /** + * Checks if a mob type is valid. + * + * @param type + * @return + */ + public static boolean isValidMobType(String type) { + return Mob.isValid(type); + } + + /** + * Set mob spawner mob type. + * + * @param pt + * @param mobType + */ + public static void setMobSpawnerType(Vector pt, String mobType) { + Block block = etc.getServer().getBlockAt( + pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); + block.setSpawnData(mobType); + } + + /** + * Get mob spawner mob type. May return an empty string. + * + * @param pt + * @param mobType + */ + public static String getMobSpawnerType(Vector pt) { + ay o = etc.getMCServer().e.k( + pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); + + if (o != null && o instanceof cf) { + String type = ((cf)o).f; + return type != null ? type : ""; + } + + return ""; + } + /** * Generate a tree at a location. * diff --git a/src/WorldEditListener.java b/src/WorldEditListener.java index 665f26cd2..1fe14d0ec 100755 --- a/src/WorldEditListener.java +++ b/src/WorldEditListener.java @@ -254,7 +254,13 @@ public class WorldEditListener extends PluginListener { text[2] = args0.length > 3 ? args0[3] : ""; text[3] = args0.length > 4 ? args0[4] : ""; return new SignBlock(blockType.getID(), data, text); + } else if (blockType == BlockType.MOB_SPAWNER) { + if (!ServerInterface.isValidMobType(args0[1])) { + throw new InvalidItemException(arg, "Unknown mob type '" + args0[1] + "'"); + } + return new MobSpawnerBlock(data, args0[1]); } + return new BaseBlock(blockType.getID(), data); } @@ -623,6 +629,9 @@ public class WorldEditListener extends PluginListener { } else if (split[1].equalsIgnoreCase("tree")) { session.setTool(WorldEditSession.Tool.TREE); player.print("Tree planting tool equipped. +5 XP"); + } else if (split[1].equalsIgnoreCase("info")) { + session.setTool(WorldEditSession.Tool.INFO); + player.print("Block information tool equipped."); } else { player.printError("Unknown tool."); } @@ -1677,6 +1686,25 @@ public class WorldEditListener extends PluginListener { session.remember(editSession); } + return true; + } else if (player.isHoldingPickAxe() + && session.getTool() == WorldEditSession.Tool.INFO) { + Vector pos = Vector.toBlockPoint(blockClicked.getX(), + blockClicked.getY(), + blockClicked.getZ()); + + BaseBlock block = EditSession.rawGetBlock(pos); + + player.printRaw(Colors.LightPurple + "@" + pos + ": " + Colors.Yellow + + "Type: " + block.getID() + Colors.LightGray + " (" + + BlockType.fromID(block.getID()).getName() + ") " + + Colors.White + + "[" + block.getData() + "]"); + + if (block instanceof MobSpawnerBlock) { + player.printRaw(Colors.Yellow + "Mob Type: " + ((MobSpawnerBlock)block).getMobType()); + } + return true; } @@ -1881,6 +1909,8 @@ public class WorldEditListener extends PluginListener { ply.sendMessage(Colors.Rose + "The edit region has not been fully defined."); } catch (UnknownItemException e3) { ply.sendMessage(Colors.Rose + "Block name '" + e3.getID() + "' was not recognized."); + } catch (InvalidItemException e4) { + ply.sendMessage(Colors.Rose + e4.getMessage()); } catch (DisallowedItemException e4) { ply.sendMessage(Colors.Rose + "Block '" + e4.getID() + "' not allowed (see WorldEdit configuration)."); } catch (MaxChangedBlocksException e5) { diff --git a/src/WorldEditPlayer.java b/src/WorldEditPlayer.java index ce6d402b6..cfaad1ff9 100644 --- a/src/WorldEditPlayer.java +++ b/src/WorldEditPlayer.java @@ -458,6 +458,15 @@ public class WorldEditPlayer { return false; } + /** + * Print a message. + * + * @param msg + */ + public void printRaw(String msg) { + player.sendMessage(msg); + } + /** * Print a WorldEdit message. * diff --git a/src/WorldEditSession.java b/src/WorldEditSession.java index 54406eb4d..204b32a91 100644 --- a/src/WorldEditSession.java +++ b/src/WorldEditSession.java @@ -37,10 +37,11 @@ public class WorldEditSession { SAME_TYPE_AREA }; /** - * List of + * List of tools. */ public static enum Tool { NONE, + INFO, TREE, } diff --git a/src/com/sk89q/worldedit/DisallowedItemException.java b/src/com/sk89q/worldedit/DisallowedItemException.java index 90e8b3198..564c09460 100644 --- a/src/com/sk89q/worldedit/DisallowedItemException.java +++ b/src/com/sk89q/worldedit/DisallowedItemException.java @@ -25,11 +25,16 @@ package com.sk89q.worldedit; */ public class DisallowedItemException extends WorldEditException { private String type; - + public DisallowedItemException(String type) { this.type = type; } + public DisallowedItemException(String type, String message) { + super(message); + this.type = type; + } + public String getID() { return type; } diff --git a/src/com/sk89q/worldedit/InvalidItemException.java b/src/com/sk89q/worldedit/InvalidItemException.java new file mode 100644 index 000000000..7c6eb7508 --- /dev/null +++ b/src/com/sk89q/worldedit/InvalidItemException.java @@ -0,0 +1,30 @@ +// $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; + +/** + * + * @author sk89q + */ +public class InvalidItemException extends DisallowedItemException { + public InvalidItemException(String type, String message) { + super(type, message); + } +} diff --git a/src/com/sk89q/worldedit/blocks/MobSpawnerBlock.java b/src/com/sk89q/worldedit/blocks/MobSpawnerBlock.java new file mode 100644 index 000000000..e086b6861 --- /dev/null +++ b/src/com/sk89q/worldedit/blocks/MobSpawnerBlock.java @@ -0,0 +1,153 @@ +// $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 com.sk89q.worldedit.*; +import com.sk89q.worldedit.data.*; +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import org.jnbt.*; + +/** + * Represents chests. + * + * @author sk89q + */ +public class MobSpawnerBlock extends BaseBlock implements TileEntityBlock { + /** + * Store mob spawn type. + */ + private String mobType; + /** + * Delay until next spawn. + */ + private short delay; + + /** + * Construct the mob spawner block. + * + */ + public MobSpawnerBlock() { + super(52); + this.mobType = "Pig"; + } + + /** + * Construct the mob spawner block. + * + * @param items + */ + public MobSpawnerBlock(String mobType) { + super(52); + this.mobType = mobType; + } + + /** + * Construct the mob spawner block. + * + * @param data + * @param items + */ + public MobSpawnerBlock(int data, String mobType) { + super(52, data); + this.mobType = mobType; + } + + /** + * Get the mob type. + * + * @return + */ + public String getMobType() { + return mobType; + } + + /** + * Set the mob type. + * + * @return + */ + public void setMobType(String mobType) { + this.mobType = mobType; + } + + /** + * @return the delay + */ + public short getDelay() { + return delay; + } + + /** + * @param delay the delay to set + */ + public void setDelay(short delay) { + this.delay = delay; + } + + /** + * Get the tile entity ID. + * + * @return + */ + public String getTileEntityID() { + return "MobSpawner"; + } + + /** + * Store additional tile entity data. Returns true if the data is used. + * + * @return map of values + * @throws DataException + */ + public Map toTileEntityNBT() + throws DataException { + Map values = new HashMap(); + values.put("EntityId", new StringTag("EntityId", mobType)); + values.put("Delay", new ShortTag("Delay", (short)0)); + return values; + } + + /** + * Get additional information from the title entity data. + * + * @param values + * @throws DataException + */ + public void fromTileEntityNBT(Map values) + throws DataException { + if (values == null) { + return; + } + + Tag t = values.get("id"); + if (!(t instanceof StringTag) || !((StringTag)t).getValue().equals("MobSpawner")) { + throw new DataException("'MobSpawner' tile entity expected"); + } + + StringTag mobTypeTag = (StringTag)Chunk.getChildTag(values, "EntityId", StringTag.class); + ShortTag delayTag = (ShortTag)Chunk.getChildTag(values, "Delay", ShortTag.class); + + this.mobType = mobTypeTag.getValue(); + this.delay = delayTag.getValue(); + } +} diff --git a/src/com/sk89q/worldedit/data/Chunk.java b/src/com/sk89q/worldedit/data/Chunk.java index c50e9f856..3b1b6f59d 100644 --- a/src/com/sk89q/worldedit/data/Chunk.java +++ b/src/com/sk89q/worldedit/data/Chunk.java @@ -210,6 +210,17 @@ public class Chunk { ((TileEntityBlock)block).fromTileEntityNBT(tileEntity); } + return block; + // Mob spawners + } else if (id == 52) { + MobSpawnerBlock block = new MobSpawnerBlock(); + + Map tileEntity = getBlockTileEntity(pos); + + if (tileEntity != null) { + ((TileEntityBlock)block).fromTileEntityNBT(tileEntity); + } + return block; } else { return new BaseBlock(id, data);