From a07f02d4d638d4ac96a0c50234631cac4d84754a Mon Sep 17 00:00:00 2001 From: mcmonkey4eva Date: Sun, 13 Oct 2013 19:39:19 -0700 Subject: [PATCH] Add schematic command + tags --- pom.xml | 10 +- .../java/net/aufdemrand/denizen/Denizen.java | 1 + .../scripts/commands/CommandRegistry.java | 36 +++ .../commands/core/_templateCommand.java | 17 +- .../scripts/commands/entity/EquipCommand.java | 2 +- .../commands/world/SchematicCommand.java | 272 ++++++++++++++++++ src/main/resources/plugin.yml | 2 +- 7 files changed, 328 insertions(+), 12 deletions(-) create mode 100644 src/main/java/net/aufdemrand/denizen/scripts/commands/world/SchematicCommand.java diff --git a/pom.xml b/pom.xml index c40f4cb77f..f84a3be461 100644 --- a/pom.xml +++ b/pom.xml @@ -98,6 +98,12 @@ jar compile + + com.sk89q + worldedit + 5.5.8 + provided + com.sk89q worldguard @@ -118,7 +124,7 @@ jenkins - http://ci.citizensnpcs.com + http://ci.citizensnpcs.co scm:git:git://github.com/aufdemrand/Denizen.git @@ -211,5 +217,5 @@ - http://wiki.citizensnpcs.com/Denizen + http://wiki.citizensnpcs.co/Denizen diff --git a/src/main/java/net/aufdemrand/denizen/Denizen.java b/src/main/java/net/aufdemrand/denizen/Denizen.java index 3f4d35c85a..686d5d2612 100644 --- a/src/main/java/net/aufdemrand/denizen/Denizen.java +++ b/src/main/java/net/aufdemrand/denizen/Denizen.java @@ -166,6 +166,7 @@ public void onEnable() { String directory = URLDecoder.decode(System.getProperty("user.dir")); new File(directory + "/plugins/Denizen/scripts").mkdirs(); new File(directory + "/plugins/Denizen/midi").mkdirs(); + new File(directory + "/plugins/Denizen/schematics").mkdirs(); // Ensure the example Denizen.mid sound file is available if (!new File(directory + "/plugins/Denizen/midi/Denizen.mid").exists()) { diff --git a/src/main/java/net/aufdemrand/denizen/scripts/commands/CommandRegistry.java b/src/main/java/net/aufdemrand/denizen/scripts/commands/CommandRegistry.java index 40140e5c5a..6b70018d1b 100644 --- a/src/main/java/net/aufdemrand/denizen/scripts/commands/CommandRegistry.java +++ b/src/main/java/net/aufdemrand/denizen/scripts/commands/CommandRegistry.java @@ -1800,6 +1800,42 @@ public void registerCoreMembers() { "RUNTASK", "runtask [] (instantly) (queue(:)) (delay:<#>) (define:|...)", 1); + // <--[command] + // @Name Schematic + // @Usage schematic [load/unload/rotate/paste] [name:] (angle:<#>) () (noair) + // @Required 2 + // @Stable unstable + // @Short Loads, edits, or pastes a WorldEdit schematic. + // @Author mcmonkey + // @Description + // Todo + // @Tags + // ].height> + // ].length> + // ].width> + // ].block[]> + // ].origin> + // ].offset> + // ].blocks> + // @Usage + // Use to load a schematic + // - schematic load name:MySchematic + // + // @Usage + // Use to unload a schematic + // - schematic unload name:MySchematic + // + // @Usage + // Use to rotate a loaded schematic + // - schematic rotate name:MySchematic angle:90 + // + // @Usage + // Use to paste a loaded schematic + // - schematic paste name:MySchematic noair + // --> + registerCoreMember(SchematicCommand.class, + "SCHEMATIC", "schematic [load/unload/rotate/paste] [name:] (angle:<#>) () (noair)", 2); + // <--[command] // @Name Scoreboard // @Usage scoreboard [set/remove/show/hide] [] [value:] (priority:<#>) diff --git a/src/main/java/net/aufdemrand/denizen/scripts/commands/core/_templateCommand.java b/src/main/java/net/aufdemrand/denizen/scripts/commands/core/_templateCommand.java index 1dd99dadf6..18eb339a79 100644 --- a/src/main/java/net/aufdemrand/denizen/scripts/commands/core/_templateCommand.java +++ b/src/main/java/net/aufdemrand/denizen/scripts/commands/core/_templateCommand.java @@ -34,13 +34,13 @@ public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) { - // if (!scriptEntry.hasObject("required_integer") - // && arg.matchesPrimitive(aH.PrimitiveType.Integer)) - // scriptEntry.addObject("required_integer", arg.asElement()); + // if (!scriptEntry.hasObject("required_integer") + // && arg.matchesPrimitive(aH.PrimitiveType.Integer)) + // scriptEntry.addObject("required_integer", arg.asElement()); - // if (!scriptEntry.hasObject("required_location") - // && arg.matchesArgumentType(dLocation.class)) - // scriptEntry.addObject("required_location", arg.asType(dLocation.class)); + // if (!scriptEntry.hasObject("required_location") + // && arg.matchesArgumentType(dLocation.class)) + // scriptEntry.addObject("required_location", arg.asType(dLocation.class)); } @@ -58,13 +58,14 @@ public void execute(ScriptEntry scriptEntry) throws CommandExecutionException { // Fetch required objects - // Element required_integer = (Element) scriptEntry.getObject("required_integer"); + // Element required_integer = scriptEntry.getElement("required_integer"); // dLocation required_location = (dLocation) scriptEntry.getObject("required_location"); // Debug the execution - // dB.report(getName(), required_integer.debug() + required_location.debug()); + // dB.report(getName(), required_integer.debug() + // + required_location.debug()); // Do the execution diff --git a/src/main/java/net/aufdemrand/denizen/scripts/commands/entity/EquipCommand.java b/src/main/java/net/aufdemrand/denizen/scripts/commands/entity/EquipCommand.java index 69bcaac406..82f0d4a7a8 100644 --- a/src/main/java/net/aufdemrand/denizen/scripts/commands/entity/EquipCommand.java +++ b/src/main/java/net/aufdemrand/denizen/scripts/commands/entity/EquipCommand.java @@ -25,7 +25,7 @@ * @author David Cernat */ -public class EquipCommand extends AbstractCommand{ +public class EquipCommand extends AbstractCommand { @Override public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException { diff --git a/src/main/java/net/aufdemrand/denizen/scripts/commands/world/SchematicCommand.java b/src/main/java/net/aufdemrand/denizen/scripts/commands/world/SchematicCommand.java new file mode 100644 index 0000000000..626cd6930c --- /dev/null +++ b/src/main/java/net/aufdemrand/denizen/scripts/commands/world/SchematicCommand.java @@ -0,0 +1,272 @@ +package net.aufdemrand.denizen.scripts.commands.world; + +import com.sk89q.worldedit.CuboidClipboard; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.schematic.SchematicFormat; +import net.aufdemrand.denizen.events.ReplaceableTagEvent; +import net.aufdemrand.denizen.exceptions.CommandExecutionException; +import net.aufdemrand.denizen.exceptions.InvalidArgumentsException; +import net.aufdemrand.denizen.objects.*; +import net.aufdemrand.denizen.scripts.ScriptEntry; +import net.aufdemrand.denizen.scripts.commands.AbstractCommand; +import net.aufdemrand.denizen.tags.Attribute; +import net.aufdemrand.denizen.utilities.DenizenAPI; +import net.aufdemrand.denizen.utilities.debugging.dB; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.io.File; +import java.net.URLDecoder; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class SchematicCommand extends AbstractCommand implements Listener { + + @Override + public void onEnable() { + Bukkit.getServer().getPluginManager().registerEvents(this, DenizenAPI.getCurrentInstance()); + } + + + private enum Type { LOAD, UNLOAD, ROTATE, PASTE } + static Map schematics = new ConcurrentHashMap(); + + // TODO: Create schematic from dCuboid + @Override + public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException { + + // - schematic load name:Potato + // - schematic unload name:Potato + // - schematic rotate name:Potato angle:90 + // - schematic paste name:Potato location:x,y,z,world (noair) + // - schematic [load/unload/rotate/paste] [name:] (angle:<#>) () (noair) + + for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) { + + if (!scriptEntry.hasObject("type") + && arg.matchesEnum(Type.values())) + scriptEntry.addObject("type", new Element(arg.raw_value.toUpperCase())); + + else if (!scriptEntry.hasObject("name") + && arg.matchesPrefix("name")) + scriptEntry.addObject("name", arg.asElement()); + + else if (!scriptEntry.hasObject("angle") + && arg.matchesPrimitive(aH.PrimitiveType.Integer)) + scriptEntry.addObject("angle", arg.asElement()); + + else if (!scriptEntry.hasObject("location") + && arg.matchesArgumentType(dLocation.class)) + scriptEntry.addObject("location", arg.asType(dLocation.class)); + + else if (!scriptEntry.hasObject("noair") + && arg.matches("noair")) + scriptEntry.addObject("noair", Element.TRUE); + + else + dB.echoError(dB.Messages.ERROR_UNKNOWN_ARGUMENT, arg.raw_value); + } + + if (!scriptEntry.hasObject("type")) + throw new InvalidArgumentsException(dB.Messages.ERROR_MISSING_OTHER, "type"); + + if (!scriptEntry.hasObject("name")) + throw new InvalidArgumentsException(dB.Messages.ERROR_MISSING_OTHER, "name"); + + } + + + @Override + public void execute(ScriptEntry scriptEntry) throws CommandExecutionException { + + Element angle = scriptEntry.getElement("angle"); + Element type = scriptEntry.getElement("type"); + Element name = scriptEntry.getElement("name"); + Element noair = scriptEntry.getElement("noair"); + dLocation location = (dLocation) scriptEntry.getObject("location"); + + dB.report(getName(), type.debug() + + name.debug() + + (location != null ? location.debug(): "") + + (angle != null ? angle.debug(): "") + + (noair != null ? noair.debug(): "")); + + CuboidClipboard cc; + switch (Type.valueOf(type.asString())) { + case LOAD: + if (schematics.containsKey(name.asString().toUpperCase())) { + dB.echoError("Schematic file " + name.asString() + " is already loaded."); + return; + } + try { + String directory = URLDecoder.decode(System.getProperty("user.dir")); + File f = new File(directory + "/plugins/Denizen/schematics/" + name.asString() + ".schematic"); + if (!f.exists()) { + dB.echoError("Schematic file " + name.asString() + " does not exist."); + return; + } + cc = SchematicFormat.MCEDIT.load(f); + } + catch (Exception ex) { + dB.echoError("Error loading schematic file " + name.asString() + "."); + return; + } + schematics.put(name.asString().toUpperCase(), cc); + break; + case UNLOAD: + if (!schematics.containsKey(name.asString().toUpperCase())) { + dB.echoError("Schematic file " + name.asString() + " is not loaded."); + return; + } + schematics.remove(name.asString().toUpperCase()); + break; + case ROTATE: + if (!schematics.containsKey(name.asString().toUpperCase())) { + dB.echoError("Schematic file " + name.asString() + " is not loaded."); + return; + } + if (angle == null) { + dB.echoError(dB.Messages.ERROR_MISSING_OTHER, "ANGLE"); + return; + } + schematics.get(name.asString().toUpperCase()).rotate2D(angle.asInt()); + break; + case PASTE: + if (!schematics.containsKey(name.asString().toUpperCase())) { + dB.echoError("Schematic file " + name.asString() + " is not loaded."); + return; + } + if (location == null) { + dB.echoError(dB.Messages.ERROR_MISSING_OTHER, "LOCATION"); + return; + } + try { + schematics.get(name.asString().toUpperCase()) + .paste(new EditSession(new BukkitWorld(location.getWorld()), 99999999), + new com.sk89q.worldedit.Vector(location.getX(), location.getY(), location.getZ()), + noair != null); + } + catch (Exception ex) { + dB.echoError("Exception while pasting " + name.asString()); + } + break; + } + } + @EventHandler + public void schematicTags(ReplaceableTagEvent event) { + + if (!event.matches("schematic, schem")) return; + + if (!event.hasNameContext()) { + return; + } + + String id = event.getNameContext().toUpperCase(); + + if (!schematics.containsKey(id)) { + dB.echoError("Schematic file " + id + " is not loaded."); + return; + } + + CuboidClipboard cc = schematics.get(id); + + Attribute attribute = new Attribute(event.raw_tag, event.getScriptEntry()).fulfill(1); + + // + // Check attributes + // + + // <--[tag] + // @attribute ].height> + // @returns Element(Number) + // @description + // Returns the height of the schematic. + // --> + if (attribute.startsWith("height")) { + event.setReplaced(new Element(cc.getHeight()) + .getAttribute(attribute.fulfill(1))); + return; + } + + // <--[tag] + // @attribute ].length> + // @returns Element(Number) + // @description + // Returns the length of the schematic. + // --> + if (attribute.startsWith("length")) { + event.setReplaced(new Element(cc.getLength()) + .getAttribute(attribute.fulfill(1))); + return; + } + + // <--[tag] + // @attribute ].width> + // @returns Element(Number) + // @description + // Returns the width of the schematic. + // --> + if (attribute.startsWith("width")) { + event.setReplaced(new Element(cc.getWidth()) + .getAttribute(attribute.fulfill(1))); + return; + } + + // <--[tag] + // @attribute ].block[]> + // @returns dMaterial + // @description + // Returns the material for the block at the location in the schematic. + // --> + if (attribute.startsWith("block")) { + if (attribute.hasContext(1) && dLocation.matches(attribute.getContext(1))) { + dLocation location = dLocation.valueOf(attribute.getContext(1)); + BaseBlock bb = cc.getBlock(new com.sk89q.worldedit.Vector(location.getX(), location.getY(), location.getZ())); + event.setReplaced(dMaterial.valueOf(bb.getType() + ":" + bb.getData()) // TODO: Better representation of the block + .getAttribute(attribute.fulfill(1))); + return; + } + } + + // <--[tag] + // @attribute ].origin> + // @returns dLocation + // @description + // Returns the origin location of the schematic. + // --> + if (attribute.startsWith("origin")) { + event.setReplaced(new dLocation(Bukkit.getWorlds().get(0), + cc.getOrigin().getX(), cc.getOrigin().getY(), cc.getOrigin().getZ()) + .getAttribute(attribute.fulfill(1))); + return; + } + + // <--[tag] + // @attribute ].offset> + // @returns dLocation + // @description + // Returns the offset location of the schematic. + // --> + if (attribute.startsWith("offset")) { + event.setReplaced(new dLocation(Bukkit.getWorlds().get(0), + cc.getOffset().getX(), cc.getOffset().getY(), cc.getOffset().getZ()) + .getAttribute(attribute.fulfill(1))); + return; + } + + // <--[tag] + // @attribute ].blocks> + // @returns Element(Number) + // @description + // Returns the number of blocks in the schematic. + // --> + if (attribute.startsWith("blocks")) { + event.setReplaced(new Element(cc.getHeight() * cc.getWidth() * cc.getLength()) + .getAttribute(attribute.fulfill(1))); + return; + } + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 314d7dba55..8951557740 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ author: aufdemrand version: ${project.version} (build ${BUILD_NUMBER}) main: net.aufdemrand.denizen.Denizen depend: [Citizens] -softdepend: [Vault, WorldGuard] +softdepend: [Vault, WorldEdit, WorldGuard] commands: denizen: