diff --git a/build.xml b/build.xml
index 22a38cc5c..d4b553704 100644
--- a/build.xml
+++ b/build.xml
@@ -20,6 +20,8 @@
+
+
diff --git a/src/HMWorld.java b/src/HMWorld.java
index 63d8390cd..edc9f01a6 100644
--- a/src/HMWorld.java
+++ b/src/HMWorld.java
@@ -17,7 +17,6 @@
* along with this program. If not, see .
*/
-import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sk89q.worldedit.EditSession;
@@ -35,10 +34,6 @@ public class HMWorld extends LocalWorld {
* Logger.
*/
private final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
- /**
- * Random generator.
- */
- private Random random = new Random();
/**
* Set block type.
@@ -304,21 +299,6 @@ public class HMWorld extends LocalWorld {
}
}
- /**
- * Drop an item.
- *
- * @param pt
- * @param type
- * @param count
- * @param times
- */
- public void dropItem(Vector pt, int type, int count, int times) {
- for (int i = 0; i < times; i++) {
- etc.getServer().dropItem(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(),
- type, count);
- }
- }
-
/**
* Drop an item.
*
@@ -344,65 +324,6 @@ public class HMWorld extends LocalWorld {
etc.getServer().dropItem(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(),
type, 1);
}
-
- /**
- * Simulate a block being mined.
- *
- * @param pt
- */
- public void simulateBlockMine(Vector pt) {
- int type = getBlockType(pt);
- //setBlockType(pt, 0);
-
- if (type == 1) { dropItem(pt, 4); } // Stone
- else if (type == 2) { dropItem(pt, 3); } // Grass
- else if (type == 7) { } // Bedrock
- else if (type == 8) { } // Water
- else if (type == 9) { } // Water
- else if (type == 10) { } // Lava
- else if (type == 11) { } // Lava
- else if (type == 13) { // Gravel
- dropItem(pt, type);
-
- if (random.nextDouble() >= 0.9) {
- dropItem(pt, 318);
- }
- }
- else if (type == 16) { dropItem(pt, 263); } // Coal ore
- else if (type == 18) { // Leaves
- if (random.nextDouble() > 0.95) {
- dropItem(pt, 6);
- }
- }
- else if (type == 20) { } // Glass
- else if (type == 43) { dropItem(pt, 44); } // Double step
- else if (type == 47) { } // Bookshelves
- else if (type == 51) { } // Fire
- else if (type == 52) { } // Mob spawner
- else if (type == 53) { dropItem(pt, 5); } // Wooden stairs
- else if (type == 55) { dropItem(pt, 331); } // Redstone wire
- else if (type == 56) { dropItem(pt, 264); } // Diamond ore
- else if (type == 59) { dropItem(pt, 295); } // Crops
- else if (type == 60) { dropItem(pt, 3); } // Soil
- else if (type == 62) { dropItem(pt, 61); } // Furnace
- else if (type == 63) { dropItem(pt, 323); } // Sign post
- else if (type == 64) { dropItem(pt, 324); } // Wood door
- else if (type == 67) { dropItem(pt, 4); } // Cobblestone stairs
- else if (type == 68) { dropItem(pt, 323); } // Wall sign
- else if (type == 71) { dropItem(pt, 330); } // Iron door
- else if (type == 73) { dropItem(pt, 331, 1, 4); } // Redstone ore
- else if (type == 74) { dropItem(pt, 331, 1, 4); } // Glowing redstone ore
- else if (type == 75) { dropItem(pt, 76); } // Redstone torch
- else if (type == 78) { } // Snow
- else if (type == 79) { } // Ice
- else if (type == 82) { dropItem(pt, 337, 1, 4); } // Clay
- else if (type == 83) { dropItem(pt, 338); } // Reed
- else if (type == 89) { dropItem(pt, 348); } // Lightstone
- else if (type == 90) { } // Portal
- else if (type != 0) {
- dropItem(pt, type);
- }
- }
/**
* Kill mobs in an area.
diff --git a/src/com/sk89q/worldedit/LocalWorld.java b/src/com/sk89q/worldedit/LocalWorld.java
index ad0d4e2be..54a1cc993 100644
--- a/src/com/sk89q/worldedit/LocalWorld.java
+++ b/src/com/sk89q/worldedit/LocalWorld.java
@@ -19,6 +19,7 @@
package com.sk89q.worldedit;
+import java.util.Random;
import com.sk89q.worldedit.blocks.BaseItemStack;
/**
@@ -27,6 +28,11 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
* @author sk89q
*/
public abstract class LocalWorld {
+ /**
+ * Random generator.
+ */
+ protected Random random = new Random();
+
/**
* Set block type.
*
@@ -138,14 +144,17 @@ public abstract class LocalWorld {
/**
* Drop an item.
- *
+ *
* @param pt
* @param type
* @param count
* @param times
*/
- public abstract void dropItem(Vector pt, int type,
- int count, int times);
+ public void dropItem(Vector pt, int type, int count, int times) {
+ for (int i = 0; i < times; i++) {
+ dropItem(pt, type, count);
+ }
+ }
/**
* Drop an item.
@@ -173,7 +182,59 @@ public abstract class LocalWorld {
*
* @param pt
*/
- public abstract void simulateBlockMine(Vector pt);
+ public void simulateBlockMine(Vector pt) {
+ int type = getBlockType(pt);
+ //setBlockType(pt, 0);
+
+ if (type == 1) { dropItem(pt, 4); } // Stone
+ else if (type == 2) { dropItem(pt, 3); } // Grass
+ else if (type == 7) { } // Bedrock
+ else if (type == 8) { } // Water
+ else if (type == 9) { } // Water
+ else if (type == 10) { } // Lava
+ else if (type == 11) { } // Lava
+ else if (type == 13) { // Gravel
+ dropItem(pt, type);
+
+ if (random.nextDouble() >= 0.9) {
+ dropItem(pt, 318);
+ }
+ }
+ else if (type == 16) { dropItem(pt, 263); } // Coal ore
+ else if (type == 18) { // Leaves
+ if (random.nextDouble() > 0.95) {
+ dropItem(pt, 6);
+ }
+ }
+ else if (type == 20) { } // Glass
+ else if (type == 43) { dropItem(pt, 44); } // Double step
+ else if (type == 47) { } // Bookshelves
+ else if (type == 51) { } // Fire
+ else if (type == 52) { } // Mob spawner
+ else if (type == 53) { dropItem(pt, 5); } // Wooden stairs
+ else if (type == 55) { dropItem(pt, 331); } // Redstone wire
+ else if (type == 56) { dropItem(pt, 264); } // Diamond ore
+ else if (type == 59) { dropItem(pt, 295); } // Crops
+ else if (type == 60) { dropItem(pt, 3); } // Soil
+ else if (type == 62) { dropItem(pt, 61); } // Furnace
+ else if (type == 63) { dropItem(pt, 323); } // Sign post
+ else if (type == 64) { dropItem(pt, 324); } // Wood door
+ else if (type == 67) { dropItem(pt, 4); } // Cobblestone stairs
+ else if (type == 68) { dropItem(pt, 323); } // Wall sign
+ else if (type == 71) { dropItem(pt, 330); } // Iron door
+ else if (type == 73) { dropItem(pt, 331, 1, 4); } // Redstone ore
+ else if (type == 74) { dropItem(pt, 331, 1, 4); } // Glowing redstone ore
+ else if (type == 75) { dropItem(pt, 76); } // Redstone torch
+ else if (type == 78) { } // Snow
+ else if (type == 79) { } // Ice
+ else if (type == 82) { dropItem(pt, 337, 1, 4); } // Clay
+ else if (type == 83) { dropItem(pt, 338); } // Reed
+ else if (type == 89) { dropItem(pt, 348); } // Lightstone
+ else if (type == 90) { } // Portal
+ else if (type != 0) {
+ dropItem(pt, type);
+ }
+ }
/**
* Kill mobs in an area.
diff --git a/src/com/sk89q/worldedit/bukkit/BukkitWorld.java b/src/com/sk89q/worldedit/bukkit/BukkitWorld.java
index fe62042dd..04be96f16 100644
--- a/src/com/sk89q/worldedit/bukkit/BukkitWorld.java
+++ b/src/com/sk89q/worldedit/bukkit/BukkitWorld.java
@@ -19,6 +19,10 @@
package com.sk89q.worldedit.bukkit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.bukkit.ItemStack;
+import org.bukkit.Location;
import org.bukkit.World;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalWorld;
@@ -26,6 +30,11 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseItemStack;
public class BukkitWorld extends LocalWorld {
+ /**
+ * Logger.
+ */
+ private final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
+
private World world;
public BukkitWorld(World world) {
@@ -100,37 +109,39 @@ public class BukkitWorld extends LocalWorld {
@Override
public boolean generateTree(EditSession editSession, Vector pt) {
- // TODO Auto-generated method stub
- return false;
+ try {
+ return CraftBukkitInterface.generateTree(editSession, pt);
+ } catch (Throwable t) {
+ logger.log(Level.SEVERE,
+ "Failed to create tree (do you need to update WorldEdit " +
+ "due to a Minecraft update?)", t);
+ return false;
+ }
}
@Override
public boolean generateBigTree(EditSession editSession, Vector pt) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public void dropItem(Vector pt, int type, int count, int times) {
- // TODO Auto-generated method stub
-
+ try {
+ return CraftBukkitInterface.generateBigTree(editSession, pt);
+ } catch (Throwable t) {
+ logger.log(Level.SEVERE,
+ "Failed to create tree (do you need to update WorldEdit " +
+ "due to a Minecraft update?)", t);
+ return false;
+ }
}
@Override
public void dropItem(Vector pt, int type, int count) {
- // TODO Auto-generated method stub
+ ItemStack item = new ItemStack(type, count);
+ world.dropItemNaturally(toLocation(pt), item);
}
@Override
public void dropItem(Vector pt, int type) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void simulateBlockMine(Vector pt) {
- // TODO Auto-generated method stub
+ ItemStack item = new ItemStack(type, 1);
+ world.dropItemNaturally(toLocation(pt), item);
}
@@ -139,6 +150,10 @@ public class BukkitWorld extends LocalWorld {
// TODO Auto-generated method stub
return 0;
}
+
+ private Location toLocation(Vector pt) {
+ return new Location(world, pt.getX(), pt.getY(), pt.getZ());
+ }
@Override
public boolean equals(Object other) {
diff --git a/src/com/sk89q/worldedit/bukkit/CraftBukkitInterface.java b/src/com/sk89q/worldedit/bukkit/CraftBukkitInterface.java
new file mode 100644
index 000000000..c26e6f8c4
--- /dev/null
+++ b/src/com/sk89q/worldedit/bukkit/CraftBukkitInterface.java
@@ -0,0 +1,115 @@
+// $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.bukkit;
+
+import java.util.logging.Logger;
+import java.util.logging.Level;
+import java.util.Random;
+import java.lang.reflect.*;
+import net.minecraft.server.WorldGenBigTree;
+import net.minecraft.server.WorldGenTrees;
+import net.minecraft.server.WorldGenerator;
+import sun.reflect.ReflectionFactory;
+import com.sk89q.worldedit.*;
+
+/**
+ *
+ * @author sk89q
+ */
+public class CraftBukkitInterface {
+ /**
+ * Logger.
+ */
+ private static final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
+ /**
+ * Random generator.
+ */
+ private static Random random = new Random();
+ /**
+ * Proxy for the tree generator.
+ */
+ private static WorldSetBlockProxy proxy;
+
+ /**
+ * Perform world generation at a location.
+ *
+ * @param pt
+ * @return
+ */
+ private static boolean performWorldGen(EditSession editSession, Vector pt,
+ WorldGenerator worldGen) {
+ if (proxy == null) {
+ try {
+ proxy = createNoConstructor(WorldSetBlockProxy.class);
+ } catch (Throwable t) {
+ logger.log(Level.WARNING, "setBlock() proxy class failed to construct",
+ t);
+ return false;
+ }
+ }
+ proxy.setEditSession(editSession);
+
+ WorldGenerator gen = worldGen;
+ return gen.a(proxy, random,
+ pt.getBlockX(), pt.getBlockY() + 1, pt.getBlockZ());
+ }
+
+ /**
+ * Generate a tree at a location.
+ *
+ * @param pt
+ * @return
+ */
+ public static boolean generateTree(EditSession editSession, Vector pt) {
+ return performWorldGen(editSession, pt, new WorldGenTrees());
+ }
+
+ /**
+ * Generate a big tree at a location.
+ *
+ * @param pt
+ * @return
+ */
+ public static boolean generateBigTree(EditSession editSession, Vector pt) {
+ return performWorldGen(editSession, pt, new WorldGenBigTree());
+ }
+
+ /**
+ * Instantiate a class without calling its constructor.
+ *
+ * @param
+ * @param clazz
+ * @return
+ * @throws Throwable
+ */
+ @SuppressWarnings("rawtypes")
+ private static T createNoConstructor(Class clazz) throws Throwable {
+ try {
+ ReflectionFactory factory = ReflectionFactory.getReflectionFactory();
+ Constructor objectConstructor = Object.class.getDeclaredConstructor();
+ Constructor c = factory.newConstructorForSerialization(
+ clazz, objectConstructor
+ );
+ return clazz.cast(c.newInstance());
+ } catch (Throwable e) {
+ throw e;
+ }
+ }
+}
diff --git a/src/com/sk89q/worldedit/bukkit/WorldSetBlockProxy.java b/src/com/sk89q/worldedit/bukkit/WorldSetBlockProxy.java
new file mode 100644
index 000000000..2f2617840
--- /dev/null
+++ b/src/com/sk89q/worldedit/bukkit/WorldSetBlockProxy.java
@@ -0,0 +1,92 @@
+package com.sk89q.worldedit.bukkit;
+// $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 net.minecraft.server.World;
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.MaxChangedBlocksException;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+/**
+ * Proxy class to catch calls to set blocks.
+ *
+ * @author sk89q
+ */
+public class WorldSetBlockProxy extends World {
+ /**
+ * Edit session.
+ */
+ private EditSession editSession;
+
+ /**
+ * Constructor that should NOT be called.
+ *
+ * @param editSession
+ */
+ public WorldSetBlockProxy(EditSession editSession) {
+ super(null, "", (long)0, null);
+ throw new IllegalStateException("MinecraftSetBlockProxy constructor called (BAD)");
+ }
+
+ /**
+ * Called to set a block.
+ *
+ * @param x
+ * @param y
+ * @param z
+ * @param blockType
+ * @return
+ */
+ @Override
+ public boolean a(int x, int y, int z, int blockType) {
+ try {
+ return editSession.setBlock(new Vector(x, y, z), new BaseBlock(blockType));
+ } catch (MaxChangedBlocksException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * Called to get a block.
+ *
+ * @param x
+ * @param y
+ * @param z
+ * @return
+ */
+ @Override
+ public int a(int x, int y, int z) {
+ return editSession.getBlock(new Vector(x, y, z)).getID();
+ }
+
+ /**
+ * @return
+ */
+ public EditSession getEditSession() {
+ return editSession;
+ }
+
+ /**
+ * @param editSession
+ */
+ public void setEditSession(EditSession editSession) {
+ this.editSession = editSession;
+ }
+}