Merge branch 'master' into bukkit

Dieser Commit ist enthalten in:
sk89q 2011-01-08 12:20:49 -08:00
Commit d9ef073aef
22 geänderte Dateien mit 862 neuen und 670 gelöschten Zeilen

Datei anzeigen

@ -1,3 +1,23 @@
2.6:
- Removed 'air' prefix from commands. Now //pasteair is just //paste,
//moveair is just //move, etc.
- Made /worldeditselect permission more encompassing, now including //chunk,
//expand, and //contract.
- Added syntax for //expand <amt> <reverse-amt> <direction> which allows
you to expand in two directions at once. This also works for //contract.
- Added //expand vert|vertical to expand the selection from top to bottom.
- Added /thaw to reverse /snow.
- Fixed WorldEdit not handling ice removal well.
- Fixed some inaccuracy problems regarding player positions caused by a
recent update.
- Fixed the tree generator.
- Code reorganized a little more.
2.5.1:
- Fixed the WorldEdit bridge used by CraftBook and other plugins.
- Fixed issues with permissions where the only reliable permission was
/worldedit.
2.5: 2.5:
- Fixed issues with permissions not being read correctly. - Fixed issues with permissions not being read correctly.
- WorldEdit is now world-aware (not that the Minecraft server is). - WorldEdit is now world-aware (not that the Minecraft server is).

Datei anzeigen

@ -34,15 +34,20 @@ public class HMPlayer extends LocalPlayer {
* Stores the player. * Stores the player.
*/ */
private Player player; private Player player;
/**
* World.
*/
private HMWorld world;
/** /**
* Construct the object. * Construct the object.
* *
* @param player * @param player
*/ */
public HMPlayer(ServerInterface server, Player player) { public HMPlayer(ServerInterface server, HMWorld world, Player player) {
super(server); super(server);
this.player = player; this.player = player;
this.world = world;
} }
/** /**
@ -123,7 +128,7 @@ public class HMPlayer extends LocalPlayer {
* @return point * @return point
*/ */
public WorldVector getPosition() { public WorldVector getPosition() {
return new WorldVector(null, player.getX(), player.getY(), player.getZ()); return new WorldVector(world, player.getX(), player.getY(), player.getZ());
} }
/** /**
@ -132,7 +137,7 @@ public class HMPlayer extends LocalPlayer {
* @return point * @return point
*/ */
public LocalWorld getWorld() { public LocalWorld getWorld() {
return null; return world;
} }
/** /**
@ -163,7 +168,7 @@ public class HMPlayer extends LocalPlayer {
public boolean passThroughForwardWall(int range) { public boolean passThroughForwardWall(int range) {
boolean foundNext = false; boolean foundNext = false;
int searchDist = 0; int searchDist = 0;
HitBlox hitBlox = new HitBlox(player,range, 0.2); HitBlox hitBlox = new HitBlox(player, range, 0.2);
LocalWorld world = getPosition().getWorld(); LocalWorld world = getPosition().getWorld();
Block block; Block block;
while ((block = hitBlox.getNextBlock()) != null) { while ((block = hitBlox.getNextBlock()) != null) {
@ -174,7 +179,7 @@ public class HMPlayer extends LocalPlayer {
if (block.getType() == 0) { if (block.getType() == 0) {
if (foundNext) { if (foundNext) {
Vector v = new Vector(block.getX(), block.getY() - 1, block.getZ()); Vector v = new Vector(block.getX(), block.getY() - 1, block.getZ());
if (server.getBlockType(world, v) == 0) { if (world.getBlockType(v) == 0) {
setPosition(v.add(0.5, 0, 0.5)); setPosition(v.add(0.5, 0, 0.5));
return true; return true;
} }

Datei anzeigen

@ -18,380 +18,12 @@
*/ */
import com.sk89q.worldedit.*; import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseItemStack;
import java.util.logging.Logger;
import java.util.Random;
/** /**
* *
* @author sk89q * @author sk89q
*/ */
public class HMServerInterface extends ServerInterface { public class HMServerInterface extends ServerInterface {
/**
* Logger.
*/
private final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
/**
* Random generator.
*/
private Random random = new Random();
/**
* Set block type.
*
* @param pt
* @param type
* @return
*/
public boolean setBlockType(LocalWorld world, Vector pt, int type) {
// Can't set colored cloth or crash
if ((type >= 21 && type <= 34) || type == 36) {
return false;
}
return etc.getServer().setBlockAt(type, pt.getBlockX(), pt.getBlockY(),
pt.getBlockZ());
}
/**
* Get block type.
*
* @param pt
* @return
*/
public int getBlockType(LocalWorld world, Vector pt) {
return etc.getServer().getBlockIdAt(pt.getBlockX(), pt.getBlockY(),
pt.getBlockZ());
}
/**
* Set block data.
*
* @param pt
* @param data
* @return
*/
public void setBlockData(LocalWorld world, Vector pt, int data) {
etc.getServer().setBlockData(pt.getBlockX(), pt.getBlockY(),
pt.getBlockZ(), data);
}
/**
* Get block data.
*
* @param pt
* @return
*/
public int getBlockData(LocalWorld world, Vector pt) {
return etc.getServer().getBlockData(pt.getBlockX(), pt.getBlockY(),
pt.getBlockZ());
}
/**
* Set sign text.
*
* @param pt
* @param text
*/
public void setSignText(LocalWorld world, Vector pt, String[] text) {
Sign signData = (Sign)etc.getServer().getComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (signData == null) {
return;
}
for (byte i = 0; i < 4; i++) {
signData.setText(i, text[i]);
}
signData.update();
}
/**
* Get sign text.
*
* @param pt
* @return
*/
public String[] getSignText(LocalWorld world, Vector pt) {
Sign signData = (Sign)etc.getServer().getComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (signData == null) {
return new String[]{"", "", "", ""};
}
String[] text = new String[4];
for (byte i = 0; i < 4; i++) {
text[i] = signData.getText(i);
}
return text;
}
/**
* Gets the contents of chests. Will return null if the chest does not
* really exist or it is the second block for a double chest.
*
* @param pt
* @return
*/
public BaseItemStack[] getChestContents(LocalWorld world, Vector pt) {
ComplexBlock cblock = etc.getServer().getOnlyComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
BaseItemStack[] items;
Item[] nativeItems;
if (cblock instanceof Chest) {
Chest chest = (Chest)cblock;
nativeItems = chest.getContents();
} else {
return null;
}
items = new BaseItemStack[nativeItems.length];
for (byte i = 0; i < nativeItems.length; i++) {
Item item = nativeItems[i];
if (item != null) {
items[i] = new BaseItemStack((short)item.getItemId(),
item.getAmount(), (short)item.getDamage());
}
}
return items;
}
/**
* Sets a chest slot.
*
* @param pt
* @param contents
* @return
*/
public boolean setChestContents(LocalWorld world, Vector pt,
BaseItemStack[] contents) {
ComplexBlock cblock = etc.getServer().getOnlyComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (cblock instanceof Chest) {
Chest chest = (Chest)cblock;
Item[] nativeItems = new Item[contents.length];
for (int i = 0; i < contents.length; i++) {
BaseItemStack item = contents[i];
if (item != null) {
Item nativeItem =
new Item(item.getID(), item.getAmount());
nativeItem.setDamage(item.getDamage());
nativeItems[i] = nativeItem;
}
}
setContents(chest, nativeItems);
}
return false;
}
/**
* Clear a chest's contents.
*
* @param pt
*/
public boolean clearChest(LocalWorld world, Vector pt) {
ComplexBlock cblock = etc.getServer().getOnlyComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (cblock instanceof Chest) {
Chest chest = (Chest)cblock;
chest.clearContents();
chest.update();
return true;
}
return false;
}
/**
* Set the contents of an ItemArray.
*
* @param itemArray
* @param contents
*/
private void setContents(ItemArray<?> itemArray, Item[] contents) {
int size = contents.length;
for (int i = 0; i < size; i++) {
if (contents[i] == null) {
itemArray.removeItem(i);
} else {
itemArray.setSlot(contents[i].getItemId(),
contents[i].getAmount(), contents[i].getDamage(), i);
}
}
}
/**
* Checks if a mob type is valid.
*
* @param type
* @return
*/
public boolean isValidMobType(String type) {
return Mob.isValid(type);
}
/**
* Set mob spawner mob type.
*
* @param pt
* @param mobType
*/
public void setMobSpawnerType(LocalWorld world, Vector pt, String mobType) {
ComplexBlock cblock = etc.getServer().getComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (!(cblock instanceof MobSpawner)) {
return;
}
MobSpawner mobSpawner = (MobSpawner)cblock;
mobSpawner.setSpawn(mobType);
mobSpawner.update();
}
/**
* Get mob spawner mob type. May return an empty string.
*
* @param pt
* @param mobType
*/
public String getMobSpawnerType(LocalWorld world, Vector pt) {
try {
return MinecraftServerInterface.getMobSpawnerType(pt);
} catch (Throwable t) {
logger.severe("Failed to get mob spawner type (do you need to update WorldEdit due to a Minecraft update?): "
+ t.getMessage());
return "";
}
}
/**
* Generate a tree at a location.
*
* @param pt
* @return
*/
public boolean generateTree(EditSession editSession, LocalWorld world, Vector pt) {
try {
return MinecraftServerInterface.generateTree(editSession, pt);
} catch (Throwable t) {
logger.severe("Failed to create tree (do you need to update WorldEdit due to a Minecraft update?): "
+ t.getMessage());
return false;
}
}
/**
* Drop an item.
*
* @param pt
* @param type
* @param count
* @param times
*/
public void dropItem(LocalWorld world, 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.
*
* @param pt
* @param type
* @param count
* @param times
*/
public void dropItem(LocalWorld world, Vector pt, int type, int count) {
etc.getServer().dropItem(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(),
type, count);
}
/**
* Drop an item.
*
* @param pt
* @param type
* @param count
* @param times
*/
public void dropItem(LocalWorld world, Vector pt, int type) {
etc.getServer().dropItem(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(),
type, 1);
}
/**
* Simulate a block being mined.
*
* @param pt
*/
public void simulateBlockMine(LocalWorld world, Vector pt) {
int type = getBlockType(world, pt);
//setBlockType(world, pt, 0);
if (type == 1) { dropItem(world, pt, 4); } // Stone
else if (type == 2) { dropItem(world, 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(world, pt, type);
if (random.nextDouble() >= 0.9) {
dropItem(world, pt, 318);
}
}
else if (type == 16) { dropItem(world, pt, 263); } // Coal ore
else if (type == 18) { // Leaves
if (random.nextDouble() > 0.95) {
dropItem(world, pt, 6);
}
}
else if (type == 20) { } // Glass
else if (type == 43) { dropItem(world, 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(world, pt, 5); } // Wooden stairs
else if (type == 55) { dropItem(world, pt, 331); } // Redstone wire
else if (type == 56) { dropItem(world, pt, 264); } // Diamond ore
else if (type == 59) { dropItem(world, pt, 295); } // Crops
else if (type == 60) { dropItem(world, pt, 3); } // Soil
else if (type == 62) { dropItem(world, pt, 61); } // Furnace
else if (type == 63) { dropItem(world, pt, 323); } // Sign post
else if (type == 64) { dropItem(world, pt, 324); } // Wood door
else if (type == 67) { dropItem(world, pt, 4); } // Cobblestone stairs
else if (type == 68) { dropItem(world, pt, 323); } // Wall sign
else if (type == 71) { dropItem(world, pt, 330); } // Iron door
else if (type == 73) { dropItem(world, pt, 331, 1, 4); } // Redstone ore
else if (type == 74) { dropItem(world, pt, 331, 1, 4); } // Glowing redstone ore
else if (type == 75) { dropItem(world, pt, 76); } // Redstone torch
else if (type == 78) { } // Snow
else if (type == 79) { } // Ice
else if (type == 82) { dropItem(world, pt, 337, 1, 4); } // Clay
else if (type == 83) { dropItem(world, pt, 338); } // Reed
else if (type == 89) { dropItem(world, pt, 348); } // Lightstone
else if (type == 90) { } // Portal
else if (type != 0) {
dropItem(world, pt, type);
}
}
/** /**
* Resolves an item name to its ID. * Resolves an item name to its ID.
* *
@ -403,24 +35,12 @@ public class HMServerInterface extends ServerInterface {
} }
/** /**
* Kill mobs in an area. * Checks if a mob type is valid.
* *
* @param origin * @param type
* @param radius
* @return * @return
*/ */
public int killMobs(LocalWorld world, Vector origin, int radius) { public boolean isValidMobType(String type) {
int killed = 0; return Mob.isValid(type);
for (Mob mob : etc.getServer().getMobList()) {
Vector mobPos = new Vector(mob.getX(), mob.getY(), mob.getZ());
if (mob.getHealth() > 0
&& (radius == -1 || mobPos.distance(origin) <= radius)) {
mob.setHealth(0);
killed++;
}
}
return killed;
} }
} }

419
src/HMWorld.java Normale Datei
Datei anzeigen

@ -0,0 +1,419 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
import java.util.Random;
import java.util.logging.Logger;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseItemStack;
/**
* World for hMod.
*
* @author sk89q
*/
public class HMWorld extends LocalWorld {
/**
* Logger.
*/
private final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
/**
* Random generator.
*/
private Random random = new Random();
/**
* Set block type.
*
* @param pt
* @param type
* @return
*/
public boolean setBlockType(Vector pt, int type) {
// Can't set colored cloth or crash
if ((type >= 21 && type <= 34) || type == 36) {
return false;
}
return etc.getServer().setBlockAt(type, pt.getBlockX(), pt.getBlockY(),
pt.getBlockZ());
}
/**
* Get block type.
*
* @param pt
* @return
*/
public int getBlockType(Vector pt) {
return etc.getServer().getBlockIdAt(pt.getBlockX(), pt.getBlockY(),
pt.getBlockZ());
}
/**
* Set block data.
*
* @param pt
* @param data
* @return
*/
public void setBlockData(Vector pt, int data) {
etc.getServer().setBlockData(pt.getBlockX(), pt.getBlockY(),
pt.getBlockZ(), data);
}
/**
* Get block data.
*
* @param pt
* @return
*/
public int getBlockData(Vector pt) {
return etc.getServer().getBlockData(pt.getBlockX(), pt.getBlockY(),
pt.getBlockZ());
}
/**
* Set sign text.
*
* @param pt
* @param text
*/
public void setSignText(Vector pt, String[] text) {
Sign signData = (Sign)etc.getServer().getComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (signData == null) {
return;
}
for (byte i = 0; i < 4; i++) {
signData.setText(i, text[i]);
}
signData.update();
}
/**
* Get sign text.
*
* @param pt
* @return
*/
public String[] getSignText(Vector pt) {
Sign signData = (Sign)etc.getServer().getComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (signData == null) {
return new String[]{"", "", "", ""};
}
String[] text = new String[4];
for (byte i = 0; i < 4; i++) {
text[i] = signData.getText(i);
}
return text;
}
/**
* Gets the contents of chests. Will return null if the chest does not
* really exist or it is the second block for a double chest.
*
* @param pt
* @return
*/
public BaseItemStack[] getChestContents(Vector pt) {
ComplexBlock cblock = etc.getServer().getOnlyComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
BaseItemStack[] items;
Item[] nativeItems;
if (cblock instanceof Chest) {
Chest chest = (Chest)cblock;
nativeItems = chest.getContents();
} else {
return null;
}
items = new BaseItemStack[nativeItems.length];
for (byte i = 0; i < nativeItems.length; i++) {
Item item = nativeItems[i];
if (item != null) {
items[i] = new BaseItemStack((short)item.getItemId(),
item.getAmount(), (short)item.getDamage());
}
}
return items;
}
/**
* Sets a chest slot.
*
* @param pt
* @param contents
* @return
*/
public boolean setChestContents(Vector pt,
BaseItemStack[] contents) {
ComplexBlock cblock = etc.getServer().getOnlyComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (cblock instanceof Chest) {
Chest chest = (Chest)cblock;
Item[] nativeItems = new Item[contents.length];
for (int i = 0; i < contents.length; i++) {
BaseItemStack item = contents[i];
if (item != null) {
Item nativeItem =
new Item(item.getID(), item.getAmount());
nativeItem.setDamage(item.getDamage());
nativeItems[i] = nativeItem;
}
}
setContents(chest, nativeItems);
}
return false;
}
/**
* Clear a chest's contents.
*
* @param pt
*/
public boolean clearChest(Vector pt) {
ComplexBlock cblock = etc.getServer().getOnlyComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (cblock instanceof Chest) {
Chest chest = (Chest)cblock;
chest.clearContents();
chest.update();
return true;
}
return false;
}
/**
* Set the contents of an ItemArray.
*
* @param itemArray
* @param contents
*/
private void setContents(ItemArray<?> itemArray, Item[] contents) {
int size = contents.length;
for (int i = 0; i < size; i++) {
if (contents[i] == null) {
itemArray.removeItem(i);
} else {
itemArray.setSlot(contents[i].getItemId(),
contents[i].getAmount(), contents[i].getDamage(), i);
}
}
}
/**
* Set mob spawner mob type.
*
* @param pt
* @param mobType
*/
public void setMobSpawnerType(Vector pt, String mobType) {
ComplexBlock cblock = etc.getServer().getComplexBlock(
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (!(cblock instanceof MobSpawner)) {
return;
}
MobSpawner mobSpawner = (MobSpawner)cblock;
mobSpawner.setSpawn(mobType);
mobSpawner.update();
}
/**
* Get mob spawner mob type. May return an empty string.
*
* @param pt
* @param mobType
*/
public String getMobSpawnerType(Vector pt) {
try {
return MinecraftServerInterface.getMobSpawnerType(pt);
} catch (Throwable t) {
logger.severe("Failed to get mob spawner type (do you need to update WorldEdit due to a Minecraft update?): "
+ t.getMessage());
return "";
}
}
/**
* Generate a tree at a location.
*
* @param pt
* @return
*/
public boolean generateTree(EditSession editSession, Vector pt) {
try {
return MinecraftServerInterface.generateTree(editSession, pt);
} catch (Throwable t) {
logger.severe("Failed to create tree (do you need to update WorldEdit due to a Minecraft update?): "
+ t.getMessage());
return false;
}
}
/**
* 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.
*
* @param pt
* @param type
* @param count
* @param times
*/
public void dropItem(Vector pt, int type, int count) {
etc.getServer().dropItem(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(),
type, count);
}
/**
* Drop an item.
*
* @param pt
* @param type
* @param count
* @param times
*/
public void dropItem(Vector pt, int type) {
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.
*
* @param origin
* @param radius
* @return
*/
public int killMobs(Vector origin, int radius) {
int killed = 0;
for (Mob mob : etc.getServer().getMobList()) {
Vector mobPos = new Vector(mob.getX(), mob.getY(), mob.getZ());
if (mob.getHealth() > 0
&& (radius == -1 || mobPos.distance(origin) <= radius)) {
mob.setHealth(0);
killed++;
}
}
return killed;
}
@Override
public boolean equals(Object other) {
return other instanceof HMWorld;
}
@Override
public int hashCode() {
return 1;
}
}

Datei anzeigen

@ -39,6 +39,10 @@ public class HMWorldEditListener extends PluginListener {
* will go through. * will go through.
*/ */
private ServerInterface server; private ServerInterface server;
/**
* A copy of a world, not that hMod/MC supports multiple worlds.
*/
private HMWorld world;
/** /**
* Constructs an instance. * Constructs an instance.
@ -50,6 +54,7 @@ public class HMWorldEditListener extends PluginListener {
config = new HMConfiguration(); config = new HMConfiguration();
controller = new WorldEditController(server, config); controller = new WorldEditController(server, config);
world = new HMWorld();
} }
/** /**
@ -83,10 +88,9 @@ public class HMWorldEditListener extends PluginListener {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean onBlockCreate(Player player, Block blockPlaced, public boolean onBlockCreate(Player player, Block blockPlaced,
Block blockClicked, int itemInHand) { Block blockClicked, int itemInHand) {
Vector pos = new Vector(blockClicked.getX(), WorldVector pos = new WorldVector(world, blockClicked.getX(),
blockClicked.getY(), blockClicked.getY(), blockClicked.getZ());
blockClicked.getZ()); return controller.handleBlockRightClick(wrapPlayer(player), pos);
return controller.handleBlockRightClick(wrapPlayer(player), null, pos);
} }
/** /**
@ -99,10 +103,9 @@ public class HMWorldEditListener extends PluginListener {
*/ */
@Override @Override
public boolean onBlockDestroy(Player player, Block blockClicked) { public boolean onBlockDestroy(Player player, Block blockClicked) {
Vector pos = new Vector(blockClicked.getX(), WorldVector pos = new WorldVector(world, blockClicked.getX(),
blockClicked.getY(), blockClicked.getY(), blockClicked.getZ());
blockClicked.getZ()); return controller.handleBlockLeftClick(wrapPlayer(player), pos);
return controller.handleBlockLeftClick(wrapPlayer(player), null, pos);
} }
/** /**
@ -167,6 +170,6 @@ public class HMWorldEditListener extends PluginListener {
* @return * @return
*/ */
private LocalPlayer wrapPlayer(Player player) { private LocalPlayer wrapPlayer(Player player) {
return new HMPlayer(server, player); return new HMPlayer(server, world, player);
} }
} }

Datei anzeigen

@ -62,7 +62,7 @@ public class MinecraftServerInterface {
bt treeGen = new ib(); bt treeGen = new ib();
return treeGen.a(proxy, random, return treeGen.a(proxy, random,
pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); pt.getBlockX(), pt.getBlockY() + 1, pt.getBlockZ());
} }
/** /**

Datei anzeigen

@ -94,7 +94,7 @@ public class WorldEdit extends Plugin {
} }
/** /**
* Get the CraftBook version. * Get the WorldEdit version.
* *
* @return * @return
*/ */
@ -121,4 +121,13 @@ public class WorldEdit extends Plugin {
return version; return version;
} }
/**
* Returns the listener for the WorldEdit bridge.
*
* @return
*/
public HMWorldEditListener getListener() {
return listener;
}
} }

Datei anzeigen

@ -50,10 +50,6 @@ public class EditSession {
*/ */
private static Random prng = new Random(); private static Random prng = new Random();
/**
* Server interface.
*/
private ServerInterface server;
/** /**
* World. * World.
*/ */
@ -62,23 +58,28 @@ public class EditSession {
/** /**
* Stores the original blocks before modification. * Stores the original blocks before modification.
*/ */
private DoubleArrayList<BlockVector, BaseBlock> original = new DoubleArrayList<BlockVector, BaseBlock>( private DoubleArrayList<BlockVector, BaseBlock> original =
new DoubleArrayList<BlockVector, BaseBlock>(
true); true);
/** /**
* Stores the current blocks. * Stores the current blocks.
*/ */
private DoubleArrayList<BlockVector, BaseBlock> current = new DoubleArrayList<BlockVector, BaseBlock>( private DoubleArrayList<BlockVector, BaseBlock> current =
new DoubleArrayList<BlockVector, BaseBlock>(
false); false);
/** /**
* Blocks that should be placed before last. * Blocks that should be placed before last.
*/ */
private DoubleArrayList<BlockVector, BaseBlock> queueAfter = new DoubleArrayList<BlockVector, BaseBlock>( private DoubleArrayList<BlockVector, BaseBlock> queueAfter =
new DoubleArrayList<BlockVector, BaseBlock>(
false); false);
/** /**
* Blocks that should be placed last. * Blocks that should be placed last.
*/ */
private DoubleArrayList<BlockVector, BaseBlock> queueLast = new DoubleArrayList<BlockVector, BaseBlock>( private DoubleArrayList<BlockVector, BaseBlock> queueLast =
new DoubleArrayList<BlockVector, BaseBlock>(
false); false);
/** /**
* The maximum number of blocks to change at a time. If this number is * The maximum number of blocks to change at a time. If this number is
* exceeded, a MaxChangedBlocksException exception will be raised. -1 * exceeded, a MaxChangedBlocksException exception will be raised. -1
@ -112,7 +113,6 @@ public class EditSession {
} }
this.maxBlocks = maxBlocks; this.maxBlocks = maxBlocks;
this.server = server;
this.world = world; this.world = world;
} }
@ -131,7 +131,6 @@ public class EditSession {
this.maxBlocks = maxBlocks; this.maxBlocks = maxBlocks;
this.blockBag = blockBag; this.blockBag = blockBag;
this.server = server;
this.world = world; this.world = world;
} }
@ -144,20 +143,24 @@ public class EditSession {
*/ */
private boolean rawSetBlock(Vector pt, BaseBlock block) { private boolean rawSetBlock(Vector pt, BaseBlock block) {
int y = pt.getBlockY(); int y = pt.getBlockY();
if (y < 0 || y > 127) { if (y < 0 || y > 127) {
return false; return false;
} }
int existing = world.getBlockType(pt);
// Clear the chest so that it doesn't drop items // Clear the chest so that it doesn't drop items
if (server.getBlockType(world, pt) == 54 && blockBag == null) { if (existing == 54 && blockBag == null) {
server.clearChest(world, pt); world.clearChest(pt);
// Ice turns until water so this has to be done first
} else if (existing == BlockID.ICE) {
world.setBlockType(pt, 0);
} }
int id = block.getID(); int id = block.getID();
if (blockBag != null) { if (blockBag != null) {
int existing = server.getBlockType(world, pt);
if (id > 0) { if (id > 0) {
try { try {
blockBag.fetchPlacedBlock(id); blockBag.fetchPlacedBlock(id);
@ -177,25 +180,25 @@ public class EditSession {
} }
} }
boolean result = server.setBlockType(world, pt, id); boolean result = world.setBlockType(pt, id);
if (id != 0) { if (id != 0) {
if (BlockType.usesData(id)) { if (BlockType.usesData(id)) {
server.setBlockData(world, pt, block.getData()); world.setBlockData(pt, block.getData());
} }
// Signs // Signs
if (block instanceof SignBlock) { if (block instanceof SignBlock) {
SignBlock signBlock = (SignBlock) block; SignBlock signBlock = (SignBlock) block;
String[] text = signBlock.getText(); String[] text = signBlock.getText();
server.setSignText(world, pt, text); world.setSignText(pt, text);
// Chests // Chests
} else if (block instanceof ChestBlock && blockBag == null) { } else if (block instanceof ChestBlock && blockBag == null) {
ChestBlock chestBlock = (ChestBlock) block; ChestBlock chestBlock = (ChestBlock) block;
server.setChestContents(world, pt, chestBlock.getItems()); world.setChestContents(pt, chestBlock.getItems());
// Mob spawners // Mob spawners
} else if (block instanceof MobSpawnerBlock) { } else if (block instanceof MobSpawnerBlock) {
MobSpawnerBlock mobSpawnerblock = (MobSpawnerBlock) block; MobSpawnerBlock mobSpawnerblock = (MobSpawnerBlock) block;
server.setMobSpawnerType(world, pt, mobSpawnerblock.getMobType()); world.setMobSpawnerType(pt, mobSpawnerblock.getMobType());
} }
} }
@ -298,21 +301,20 @@ public class EditSession {
* @return BaseBlock * @return BaseBlock
*/ */
public BaseBlock rawGetBlock(Vector pt) { public BaseBlock rawGetBlock(Vector pt) {
int type = server.getBlockType(world, pt); int type = world.getBlockType(pt);
int data = server.getBlockData(world, pt); int data = world.getBlockData(pt);
// Sign // Sign
if (type == 63 || type == 68) { if (type == 63 || type == 68) {
String[] text = server.getSignText(world, pt); String[] text = world.getSignText(pt);
return new SignBlock(type, data, text); return new SignBlock(type, data, text);
// Chest // Chest
} else if (type == 54) { } else if (type == 54) {
BaseItemStack[] items = server.getChestContents(world, pt); BaseItemStack[] items = world.getChestContents(pt);
return new ChestBlock(data, items); return new ChestBlock(data, items);
// Mob spawner // Mob spawner
} else if (type == 52) { } else if (type == 52) {
return new MobSpawnerBlock(data, return new MobSpawnerBlock(data, world.getMobSpawnerType(pt));
server.getMobSpawnerType(world, pt));
} else { } else {
return new BaseBlock(type, data); return new BaseBlock(type, data);
} }
@ -1568,6 +1570,54 @@ public class EditSession {
return affected; return affected;
} }
/**
* Thaw.
*
* @param pos
* @param radius
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
public int thaw(Vector pos, int radius)
throws MaxChangedBlocksException {
int affected = 0;
int radiusSq = (int)Math.pow(radius, 2);
int ox = pos.getBlockX();
int oy = pos.getBlockY();
int oz = pos.getBlockZ();
BaseBlock air = new BaseBlock(0);
BaseBlock water = new BaseBlock(BlockID.STATIONARY_WATER);
for (int x = ox - radius; x <= ox + radius; x++) {
for (int z = oz - radius; z <= oz + radius; z++) {
if ((new Vector(x, oy, z)).distanceSq(pos) > radiusSq) {
continue;
}
for (int y = 127; y >= 1; y--) {
Vector pt = new Vector(x, y, z);
int id = getBlock(pt).getID();
if (id == BlockID.ICE) { // Ice
if (setBlock(pt, water)) {
affected++;
}
} else if (id == BlockID.SNOW) {
if (setBlock(pt, air)) {
affected++;
}
} else if (id != 0) {
break;
}
}
}
}
return affected;
}
/** /**
* Make snow. * Make snow.
* *
@ -1579,6 +1629,7 @@ public class EditSession {
public int simulateSnow(Vector pos, int radius) public int simulateSnow(Vector pos, int radius)
throws MaxChangedBlocksException { throws MaxChangedBlocksException {
int affected = 0; int affected = 0;
int radiusSq = (int)Math.pow(radius, 2);
int ox = pos.getBlockX(); int ox = pos.getBlockX();
int oy = pos.getBlockY(); int oy = pos.getBlockY();
@ -1589,7 +1640,7 @@ public class EditSession {
for (int x = ox - radius; x <= ox + radius; x++) { for (int x = ox - radius; x <= ox + radius; x++) {
for (int z = oz - radius; z <= oz + radius; z++) { for (int z = oz - radius; z <= oz + radius; z++) {
if ((new Vector(x, oy, z)).distance(pos) > radius) { if ((new Vector(x, oy, z)).distanceSq(pos) > radiusSq) {
continue; continue;
} }
@ -1812,8 +1863,7 @@ public class EditSession {
if (pineTree) { if (pineTree) {
makePineTree(new Vector(x, y + 1, z)); makePineTree(new Vector(x, y + 1, z));
} else { } else {
server.generateTree(this, world, world.generateTree(this, new Vector(x, y + 1, z));
new Vector(x, y + 1, z));
} }
affected++; affected++;
break; break;

Datei anzeigen

@ -83,8 +83,7 @@ public abstract class LocalPlayer {
byte free = 0; byte free = 0;
while (y <= 129) { while (y <= 129) {
if (BlockType.canPassThrough(server.getBlockType(world, if (BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
new Vector(x, y, z)))) {
free++; free++;
} else { } else {
free = 0; free = 0;
@ -128,7 +127,7 @@ public abstract class LocalPlayer {
byte spots = 0; byte spots = 0;
while (y <= 129) { while (y <= 129) {
if (BlockType.canPassThrough(server.getBlockType(world, new Vector(x, y, z)))) { if (BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
free++; free++;
} else { } else {
free = 0; free = 0;
@ -137,7 +136,7 @@ public abstract class LocalPlayer {
if (free == 2) { if (free == 2) {
spots++; spots++;
if (spots == 2) { if (spots == 2) {
int type = server.getBlockType(world, new Vector(x, y - 2, z)); int type = world.getBlockType(new Vector(x, y - 2, z));
// Don't get put in lava! // Don't get put in lava!
if (type == 10 || type == 11) { if (type == 10 || type == 11) {
@ -170,7 +169,7 @@ public abstract class LocalPlayer {
byte free = 0; byte free = 0;
while (y >= 1) { while (y >= 1) {
if (BlockType.canPassThrough(server.getBlockType(world, new Vector(x, y, z)))) { if (BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
free++; free++;
} else { } else {
free = 0; free = 0;
@ -181,7 +180,7 @@ public abstract class LocalPlayer {
// lightly and also check to see if there's something to // lightly and also check to see if there's something to
// stand upon // stand upon
while (y >= 0) { while (y >= 0) {
int type = server.getBlockType(world, new Vector(x, y, z)); int type = world.getBlockType(new Vector(x, y, z));
// Don't want to end up in lava // Don't want to end up in lava
if (type != 0 && type != 10 && type != 11) { if (type != 0 && type != 10 && type != 11) {
@ -217,15 +216,15 @@ public abstract class LocalPlayer {
LocalWorld world = getPosition().getWorld(); LocalWorld world = getPosition().getWorld();
// No free space above // No free space above
if (server.getBlockType(world, new Vector(x, y, z)) != 0) { if (world.getBlockType(new Vector(x, y, z)) != 0) {
return false; return false;
} }
while (y <= 127) { while (y <= 127) {
// Found a ceiling! // Found a ceiling!
if (!BlockType.canPassThrough(server.getBlockType(world, new Vector(x, y, z)))) { if (!BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
int platformY = Math.max(initialY, y - 3 - clearance); int platformY = Math.max(initialY, y - 3 - clearance);
server.setBlockType(world, new Vector(x, platformY, z), world.setBlockType(new Vector(x, platformY, z),
BlockType.GLASS.getID()); BlockType.GLASS.getID());
setPosition(new Vector(x + 0.5, platformY + 1, z + 0.5)); setPosition(new Vector(x + 0.5, platformY + 1, z + 0.5));
return true; return true;
@ -253,12 +252,12 @@ public abstract class LocalPlayer {
LocalWorld world = getPosition().getWorld(); LocalWorld world = getPosition().getWorld();
while (y <= 129) { while (y <= 129) {
if (!BlockType.canPassThrough(server.getBlockType(world, new Vector(x, y, z)))) { if (!BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
break; // Hit something break; // Hit something
} else if (y > maxY + 1) { } else if (y > maxY + 1) {
break; break;
} else if (y == maxY + 1) { } else if (y == maxY + 1) {
server.setBlockType(world, new Vector(x, y - 2, z), world.setBlockType(new Vector(x, y - 2, z),
BlockType.GLASS.getID()); BlockType.GLASS.getID());
setPosition(new Vector(x + 0.5, y - 1, z + 0.5)); setPosition(new Vector(x + 0.5, y - 1, z + 0.5));
return true; return true;
@ -276,7 +275,9 @@ public abstract class LocalPlayer {
* @return point * @return point
*/ */
public WorldVector getBlockIn() { public WorldVector getBlockIn() {
return getPosition(); WorldVector pos = getPosition();
return WorldVector.toBlockPoint(pos.getWorld(), pos.getX(),
pos.getY(), pos.getZ());
} }
/** /**
@ -286,7 +287,8 @@ public abstract class LocalPlayer {
*/ */
public WorldVector getBlockOn() { public WorldVector getBlockOn() {
WorldVector pos = getPosition(); WorldVector pos = getPosition();
return new WorldVector(pos.getWorld(), pos.subtract(0, 1, 0)); return WorldVector.toBlockPoint(pos.getWorld(), pos.getX(),
pos.getY() - 1, pos.getZ());
} }
/** /**

Datei anzeigen

@ -19,12 +19,163 @@
package com.sk89q.worldedit; package com.sk89q.worldedit;
import com.sk89q.worldedit.blocks.BaseItemStack;
/** /**
* Represents a world. * Represents a world.
* *
* @author sk89q * @author sk89q
*/ */
public abstract class LocalWorld { public abstract class LocalWorld {
/**
* Set block type.
*
* @param pt
* @param type
* @return
*/
public abstract boolean setBlockType(Vector pt, int type);
/**
* Get block type.
*
* @param pt
* @return
*/
public abstract int getBlockType(Vector pt);
/**
* Set block data.
*
* @param pt
* @param data
* @return
*/
public abstract void setBlockData(Vector pt, int data);
/**
* Get block data.
*
* @param pt
* @return
*/
public abstract int getBlockData(Vector pt);
/**
* Set sign text.
*
* @param pt
* @param text
*/
public abstract void setSignText(Vector pt, String[] text);
/**
* Get sign text.
*
* @param pt
* @return
*/
public abstract String[] getSignText(Vector pt);
/**
* Gets the contents of chests. Will return null if the chest does not
* really exist or it is the second block for a double chest.
*
* @param pt
* @return
*/
public abstract BaseItemStack[] getChestContents(Vector pt);
/**
* Sets a chest slot.
*
* @param pt
* @param contents
* @return
*/
public abstract boolean setChestContents(Vector pt,
BaseItemStack[] contents);
/**
* Clear a chest's contents.
*
* @param pt
*/
public abstract boolean clearChest(Vector pt);
/**
* Set mob spawner mob type.
*
* @param pt
* @param mobType
*/
public abstract void setMobSpawnerType(Vector pt,
String mobType);
/**
* Get mob spawner mob type. May return an empty string.
*
* @param pt
* @param mobType
*/
public abstract String getMobSpawnerType(Vector pt);
/**
* Generate a tree at a location.
*
* @param pt
* @return
*/
public abstract boolean generateTree(EditSession editSession, Vector pt);
/**
* Drop an item.
*
* @param pt
* @param type
* @param count
* @param times
*/
public abstract void dropItem(Vector pt, int type,
int count, int times);
/**
* Drop an item.
*
* @param pt
* @param type
* @param count
* @param times
*/
public abstract void dropItem(Vector pt, int type,
int count);
/**
* Drop an item.
*
* @param pt
* @param type
* @param count
* @param times
*/
public abstract void dropItem(Vector pt, int type);
/**
* Simulate a block being mined.
*
* @param pt
*/
public abstract void simulateBlockMine(Vector pt);
/**
* Kill mobs in an area.
*
* @param origin
* @param radius
* @return
*/
public abstract int killMobs(Vector origin, int radius);
/** /**
* Compare if the other world is equal. * Compare if the other world is equal.
* *

Datei anzeigen

@ -19,162 +19,11 @@
package com.sk89q.worldedit; package com.sk89q.worldedit;
import com.sk89q.worldedit.blocks.BaseItemStack;
/** /**
* *
* @author sk89q * @author sk89q
*/ */
public abstract class ServerInterface { public abstract class ServerInterface {
/**
* Set block type.
*
* @param pt
* @param type
* @return
*/
public abstract boolean setBlockType(LocalWorld world, Vector pt, int type);
/**
* Get block type.
*
* @param pt
* @return
*/
public abstract int getBlockType(LocalWorld world, Vector pt);
/**
* Set block data.
*
* @param pt
* @param data
* @return
*/
public abstract void setBlockData(LocalWorld world, Vector pt, int data);
/**
* Get block data.
*
* @param pt
* @return
*/
public abstract int getBlockData(LocalWorld world, Vector pt);
/**
* Set sign text.
*
* @param pt
* @param text
*/
public abstract void setSignText(LocalWorld world, Vector pt, String[] text);
/**
* Get sign text.
*
* @param pt
* @return
*/
public abstract String[] getSignText(LocalWorld world, Vector pt);
/**
* Gets the contents of chests. Will return null if the chest does not
* really exist or it is the second block for a double chest.
*
* @param pt
* @return
*/
public abstract BaseItemStack[] getChestContents(LocalWorld world, Vector pt);
/**
* Sets a chest slot.
*
* @param pt
* @param contents
* @return
*/
public abstract boolean setChestContents(LocalWorld world, Vector pt,
BaseItemStack[] contents);
/**
* Clear a chest's contents.
*
* @param pt
*/
public abstract boolean clearChest(LocalWorld world, Vector pt);
/**
* Checks if a mob type is valid.
*
* @param type
* @return
*/
public abstract boolean isValidMobType(String type);
/**
* Set mob spawner mob type.
*
* @param pt
* @param mobType
*/
public abstract void setMobSpawnerType(LocalWorld world, Vector pt,
String mobType);
/**
* Get mob spawner mob type. May return an empty string.
*
* @param pt
* @param mobType
*/
public abstract String getMobSpawnerType(LocalWorld world, Vector pt);
/**
* Generate a tree at a location.
*
* @param pt
* @return
*/
public abstract boolean generateTree(EditSession editSession,
LocalWorld world, Vector pt);
/**
* Drop an item.
*
* @param pt
* @param type
* @param count
* @param times
*/
public abstract void dropItem(LocalWorld world, Vector pt, int type,
int count, int times);
/**
* Drop an item.
*
* @param pt
* @param type
* @param count
* @param times
*/
public abstract void dropItem(LocalWorld world, Vector pt, int type,
int count);
/**
* Drop an item.
*
* @param pt
* @param type
* @param count
* @param times
*/
public abstract void dropItem(LocalWorld world, Vector pt, int type);
/**
* Simulate a block being mined.
*
* @param pt
*/
public abstract void simulateBlockMine(LocalWorld world, Vector pt);
/** /**
* Resolves an item name to its ID. * Resolves an item name to its ID.
* *
@ -184,11 +33,10 @@ public abstract class ServerInterface {
public abstract int resolveItem(String name); public abstract int resolveItem(String name);
/** /**
* Kill mobs in an area. * Checks if a mob type is valid.
* *
* @param origin * @param type
* @param radius
* @return * @return
*/ */
public abstract int killMobs(LocalWorld world, Vector origin, int radius); public abstract boolean isValidMobType(String type);
} }

Datei anzeigen

@ -446,6 +446,18 @@ public class Vector {
Math.pow(pt.z - z, 2)); Math.pow(pt.z - z, 2));
} }
/**
* Get the distance away from a point, squared.
*
* @param pt
* @return distance
*/
public double distanceSq(Vector pt) {
return Math.pow(pt.x - x, 2) +
Math.pow(pt.y - y, 2) +
Math.pow(pt.z - z, 2);
}
/** /**
* Checks to see if a vector is contained with another. * Checks to see if a vector is contained with another.
* *

Datei anzeigen

@ -92,8 +92,6 @@ public class WorldEditController {
this.server = server; this.server = server;
this.config = config; this.config = config;
// Note: Commands should only have the phrase 'air' at the end
// for now (see SMWorldEditListener.canUseCommand)
commands.put("//pos1", "Set editing position #1"); commands.put("//pos1", "Set editing position #1");
commands.put("//pos2", "Set editing position #2"); commands.put("//pos2", "Set editing position #2");
commands.put("//hpos1", "Trace editing position #1"); commands.put("//hpos1", "Trace editing position #1");
@ -122,11 +120,8 @@ public class WorldEditController {
commands.put("//copy", "Copies the currently selected region"); commands.put("//copy", "Copies the currently selected region");
commands.put("//cut", "Cuts the currently selected region"); commands.put("//cut", "Cuts the currently selected region");
commands.put("//paste", "<AtOrigin?> - Pastes the clipboard"); commands.put("//paste", "<AtOrigin?> - Pastes the clipboard");
commands.put("//pasteair", "<AtOrigin?> - Pastes the clipboard (with air)");
commands.put("//move", "<Count> <Dir> <LeaveID> - Move the selection"); commands.put("//move", "<Count> <Dir> <LeaveID> - Move the selection");
commands.put("//moveair", "<Count> <Dir> <LeaveID> - Move the selection (with air)");
commands.put("//stack", "<Count> <Dir> - Stacks the selection"); commands.put("//stack", "<Count> <Dir> - Stacks the selection");
commands.put("//stackair", "<Count> <Dir> - Stacks the selection (with air)");
commands.put("//load", "[Filename] - Load .schematic into clipboard"); commands.put("//load", "[Filename] - Load .schematic into clipboard");
commands.put("//save", "[Filename] - Save clipboard to .schematic"); commands.put("//save", "[Filename] - Save clipboard to .schematic");
commands.put("//fill", "[ID] [Radius] <Depth> - Fill a hole"); commands.put("//fill", "[ID] [Radius] <Depth> - Fill a hole");
@ -155,6 +150,7 @@ public class WorldEditController {
commands.put("/forestgen", "<Size> <Density> - Make Notch tree forest"); commands.put("/forestgen", "<Size> <Density> - Make Notch tree forest");
commands.put("/pinegen", "<Size> <Density> - Make an ugly pine tree forest"); commands.put("/pinegen", "<Size> <Density> - Make an ugly pine tree forest");
commands.put("/snow", "<Radius> - Simulate snow cover"); commands.put("/snow", "<Radius> - Simulate snow cover");
commands.put("/thaw", "<Radius> - Unthaw/remove snow");
commands.put("/pumpkins", "<Size> - Make a pumpkin forest"); commands.put("/pumpkins", "<Size> - Make a pumpkin forest");
commands.put("/unstuck", "Go up to the first free spot"); commands.put("/unstuck", "Go up to the first free spot");
commands.put("/ascend", "Go up one level"); commands.put("/ascend", "Go up one level");
@ -437,6 +433,8 @@ public class WorldEditController {
+ joinString(split, " ")); + joinString(split, " "));
} }
LocalWorld world = player.getPosition().getWorld();
// Jump to the first free position // Jump to the first free position
if (split[0].equalsIgnoreCase("/unstuck")) { if (split[0].equalsIgnoreCase("/unstuck")) {
checkArgs(split, 0, 0, split[0]); checkArgs(split, 0, 0, split[0]);
@ -643,7 +641,7 @@ public class WorldEditController {
// Single super pickaxe mode // Single super pickaxe mode
} else if (split[0].equalsIgnoreCase("/single")) { } else if (split[0].equalsIgnoreCase("/single")) {
if (!canUseCommand(player, "//")) { if (!canUseCommand(player, "/")) {
player.printError("You don't have permission for super pickaxe usage."); player.printError("You don't have permission for super pickaxe usage.");
return true; return true;
} }
@ -658,7 +656,7 @@ public class WorldEditController {
} else if (split[0].equalsIgnoreCase("/area") } else if (split[0].equalsIgnoreCase("/area")
|| split[0].equalsIgnoreCase("/recur")) { || split[0].equalsIgnoreCase("/recur")) {
if (!canUseCommand(player, "//")) { if (!canUseCommand(player, "/")) {
player.printError("You don't have permission for super pickaxe usage."); player.printError("You don't have permission for super pickaxe usage.");
return true; return true;
} }
@ -747,8 +745,7 @@ public class WorldEditController {
return true; return true;
// Paste // Paste
} else if (split[0].equalsIgnoreCase("//pasteair") || } else if (split[0].equalsIgnoreCase("//paste")) {
split[0].equalsIgnoreCase("//paste")) {
checkArgs(split, 0, 1, split[0]); checkArgs(split, 0, 1, split[0]);
boolean atOrigin = split.length > 1 boolean atOrigin = split.length > 1
? (split[1].equalsIgnoreCase("true") ? (split[1].equalsIgnoreCase("true")
@ -756,14 +753,12 @@ public class WorldEditController {
: false; : false;
if (atOrigin) { if (atOrigin) {
Vector pos = session.getClipboard().getOrigin(); Vector pos = session.getClipboard().getOrigin();
session.getClipboard().place(editSession, pos, session.getClipboard().place(editSession, pos, false);
split[0].equalsIgnoreCase("//paste"));
player.findFreePosition(); player.findFreePosition();
player.print("Pasted to copy origin. Undo with //undo"); player.print("Pasted to copy origin. Undo with //undo");
} else { } else {
Vector pos = session.getPlacementPosition(player); Vector pos = session.getPlacementPosition(player);
session.getClipboard().paste(editSession, pos, session.getClipboard().paste(editSession, pos, false);
split[0].equalsIgnoreCase("//paste"));
player.findFreePosition(); player.findFreePosition();
player.print("Pasted relative to you. Undo with //undo"); player.print("Pasted relative to you. Undo with //undo");
} }
@ -1217,6 +1212,16 @@ public class WorldEditController {
return true; return true;
// Thaw
} else if (split[0].equalsIgnoreCase("/thaw")) {
checkArgs(split, 0, 1, split[0]);
int size = split.length > 1 ? Math.max(1, Integer.parseInt(split[1])) : 10;
int affected = editSession.thaw(player.getBlockIn(), size);
player.print(affected + " surfaces thawed.");
return true;
// Make pumpkin patches // Make pumpkin patches
} else if (split[0].equalsIgnoreCase("/pumpkins")) { } else if (split[0].equalsIgnoreCase("/pumpkins")) {
checkArgs(split, 0, 1, split[0]); checkArgs(split, 0, 1, split[0]);
@ -1228,8 +1233,7 @@ public class WorldEditController {
return true; return true;
// Move // Move
} else if (split[0].equalsIgnoreCase("//moveair") || } else if (split[0].equalsIgnoreCase("//move")) {
split[0].equalsIgnoreCase("//move")) {
checkArgs(split, 0, 3, split[0]); checkArgs(split, 0, 3, split[0]);
int count = split.length > 1 ? Math.max(1, Integer.parseInt(split[1])) : 1; int count = split.length > 1 ? Math.max(1, Integer.parseInt(split[1])) : 1;
Vector dir = getDirection(player, Vector dir = getDirection(player,
@ -1243,36 +1247,54 @@ public class WorldEditController {
replace = new BaseBlock(0); replace = new BaseBlock(0);
} }
boolean copyAir = split[0].equalsIgnoreCase("//moveair");
int affected = editSession.moveCuboidRegion(session.getRegion(), int affected = editSession.moveCuboidRegion(session.getRegion(),
dir, count, copyAir, replace); dir, count, true, replace);
player.print(affected + " blocks moved."); player.print(affected + " blocks moved.");
return true; return true;
// Stack // Stack
} else if (split[0].equalsIgnoreCase("//stackair") || } else if (split[0].equalsIgnoreCase("//stack")) {
split[0].equalsIgnoreCase("//stack")) {
checkArgs(split, 0, 2, split[0]); checkArgs(split, 0, 2, split[0]);
int count = split.length > 1 ? Math.max(1, Integer.parseInt(split[1])) : 1; int count = split.length > 1 ? Math.max(1, Integer.parseInt(split[1])) : 1;
Vector dir = getDirection(player, Vector dir = getDirection(player,
split.length > 2 ? split[2].toLowerCase() : "me"); split.length > 2 ? split[2].toLowerCase() : "me");
boolean copyAir = split[0].equalsIgnoreCase("//stackair");
int affected = editSession.stackCuboidRegion(session.getRegion(), int affected = editSession.stackCuboidRegion(session.getRegion(),
dir, count, copyAir); dir, count, true);
player.print(affected + " blocks changed. Undo with //undo"); player.print(affected + " blocks changed. Undo with //undo");
return true; return true;
// Expand // Expand
} else if (split[0].equalsIgnoreCase("//expand")) { } else if (split[0].equalsIgnoreCase("//expand")) {
checkArgs(split, 1, 2, split[0]); checkArgs(split, 1, 3, split[0]);
Vector dir; Vector dir;
if (split[1].equals("vert") || split[1].equals("vertical")) {
Region region = session.getRegion();
int oldSize = region.getSize();
region.expand(new Vector(0, 128, 0));
region.expand(new Vector(0, -128, 0));
session.learnRegionChanges();
int newSize = region.getSize();
player.print("Region expanded " + (newSize - oldSize) + " blocks [top-to-bottom].");
return true;
}
int change = Integer.parseInt(split[1]); int change = Integer.parseInt(split[1]);
int reverseChange = 0;
if (split.length == 3) { if (split.length == 3) {
dir = getDirection(player, split[2].toLowerCase()); try {
reverseChange = Integer.parseInt(split[2]) * -1;
dir = getDirection(player, "me");
} catch (NumberFormatException e) {
dir = getDirection(player, split[2].toLowerCase());
}
} else if (split.length == 4) {
reverseChange = Integer.parseInt(split[2]) * -1;
dir = getDirection(player, split[3].toLowerCase());
} else { } else {
dir = getDirection(player, "me"); dir = getDirection(player, "me");
} }
@ -1280,6 +1302,9 @@ public class WorldEditController {
Region region = session.getRegion(); Region region = session.getRegion();
int oldSize = region.getSize(); int oldSize = region.getSize();
region.expand(dir.multiply(change)); region.expand(dir.multiply(change));
if (reverseChange != 0) {
region.expand(dir.multiply(reverseChange));
}
session.learnRegionChanges(); session.learnRegionChanges();
int newSize = region.getSize(); int newSize = region.getSize();
player.print("Region expanded " + (newSize - oldSize) + " blocks."); player.print("Region expanded " + (newSize - oldSize) + " blocks.");
@ -1288,11 +1313,20 @@ public class WorldEditController {
// Contract // Contract
} else if (split[0].equalsIgnoreCase("//contract")) { } else if (split[0].equalsIgnoreCase("//contract")) {
checkArgs(split, 1, 2, split[0]); checkArgs(split, 1, 3, split[0]);
Vector dir; Vector dir;
int change = Integer.parseInt(split[1]); int change = Integer.parseInt(split[1]);
int reverseChange = 0;
if (split.length == 3) { if (split.length == 3) {
dir = getDirection(player, split[2].toLowerCase()); try {
reverseChange = Integer.parseInt(split[2]) * -1;
dir = getDirection(player, "me");
} catch (NumberFormatException e) {
dir = getDirection(player, split[2].toLowerCase());
}
} else if (split.length == 4) {
reverseChange = Integer.parseInt(split[2]) * -1;
dir = getDirection(player, split[3].toLowerCase());
} else { } else {
dir = getDirection(player, "me"); dir = getDirection(player, "me");
} }
@ -1300,6 +1334,9 @@ public class WorldEditController {
Region region = session.getRegion(); Region region = session.getRegion();
int oldSize = region.getSize(); int oldSize = region.getSize();
region.contract(dir.multiply(change)); region.contract(dir.multiply(change));
if (reverseChange != 0) {
region.contract(dir.multiply(reverseChange));
}
session.learnRegionChanges(); session.learnRegionChanges();
int newSize = region.getSize(); int newSize = region.getSize();
player.print("Region contracted " + (oldSize - newSize) + " blocks."); player.print("Region contracted " + (oldSize - newSize) + " blocks.");
@ -1359,7 +1396,7 @@ public class WorldEditController {
Math.max(1, Integer.parseInt(split[1])) : -1; Math.max(1, Integer.parseInt(split[1])) : -1;
Vector origin = session.getPlacementPosition(player); Vector origin = session.getPlacementPosition(player);
int killed = server.killMobs(player.getWorld(), origin, radius); int killed = world.killMobs(origin, radius);
player.print("Killed " + killed + " mobs."); player.print("Killed " + killed + " mobs.");
return true; return true;
@ -1733,7 +1770,7 @@ public class WorldEditController {
* @param player * @param player
*/ */
public void handleArmSwing(LocalPlayer player) { public void handleArmSwing(LocalPlayer player) {
if (!canUseCommand(player, "//")) if (!canUseCommand(player, "/"))
return; return;
} }
@ -1741,22 +1778,20 @@ public class WorldEditController {
* Called on right click. * Called on right click.
* *
* @param player * @param player
* @param world
* @param clicked * @param clicked
* @return false if you want the action to go through * @return false if you want the action to go through
*/ */
public boolean handleBlockRightClick(LocalPlayer player, LocalWorld world, public boolean handleBlockRightClick(LocalPlayer player, WorldVector clicked) {
Vector clicked) {
int itemInHand = player.getItemInHand(); int itemInHand = player.getItemInHand();
// This prevents needless sessions from being created // This prevents needless sessions from being created
if (!hasSession(player) && !(itemInHand == config.wandItem && if (!hasSession(player) && !(itemInHand == config.wandItem &&
canUseCommand(player, "//pos2"))) { return false; } canUseCommand(player, "/pos2"))) { return false; }
LocalSession session = getSession(player); LocalSession session = getSession(player);
if (itemInHand == config.wandItem && session.isToolControlEnabled() if (itemInHand == config.wandItem && session.isToolControlEnabled()
&& canUseCommand(player, "//pos2")) { && canUseCommand(player, "/pos2")) {
session.setPos2(clicked); session.setPos2(clicked);
try { try {
player.print("Second position set to " + clicked player.print("Second position set to " + clicked
@ -1767,8 +1802,7 @@ public class WorldEditController {
return true; return true;
} else if (player.isHoldingPickAxe() && session.getTool() != null) { } else if (player.isHoldingPickAxe() && session.getTool() != null) {
return session.getTool().act(server, config, player, session, return session.getTool().act(server, config, player, session, clicked);
world, clicked);
} }
return false; return false;
@ -1778,15 +1812,13 @@ public class WorldEditController {
* Called on left click. * Called on left click.
* *
* @param player * @param player
* @param world
* @param clicked * @param clicked
* @return false if you want the action to go through * @return false if you want the action to go through
*/ */
public boolean handleBlockLeftClick(LocalPlayer player, public boolean handleBlockLeftClick(LocalPlayer player, WorldVector clicked) {
LocalWorld world, Vector clicked) {
if (!canUseCommand(player, "//pos1") if (!canUseCommand(player, "/pos1")
&& !canUseCommand(player, "//")) { return false; } && !canUseCommand(player, "/")) { return false; }
LocalSession session = getSession(player); LocalSession session = getSession(player);
@ -1818,7 +1850,7 @@ public class WorldEditController {
} else if (player.isHoldingPickAxe() && session.hasSuperPickAxe()) { } else if (player.isHoldingPickAxe() && session.hasSuperPickAxe()) {
if (session.getSuperPickaxeMode() != null) { if (session.getSuperPickaxeMode() != null) {
return session.getSuperPickaxeMode().act(server, config, return session.getSuperPickaxeMode().act(server, config,
player, session, world, clicked); player, session, clicked);
} }
} }
@ -1850,7 +1882,7 @@ public class WorldEditController {
split[0] = split[0].substring(1); split[0] = split[0].substring(1);
} }
if (canUseCommand(player, split[0])) { if (canUseCommand(player, split[0].substring(1))) {
LocalSession session = getSession(player); LocalSession session = getSession(player);
BlockBag blockBag = session.getBlockBag(player); BlockBag blockBag = session.getBlockBag(player);
@ -1961,17 +1993,21 @@ public class WorldEditController {
*/ */
private boolean canUseCommand(LocalPlayer player, String command) { private boolean canUseCommand(LocalPlayer player, String command) {
// Allow the /worldeditselect permission // Allow the /worldeditselect permission
if (command.equalsIgnoreCase("//pos1") if (command.equalsIgnoreCase("/pos1")
|| command.equalsIgnoreCase("//pos2") || command.equalsIgnoreCase("/pos2")
|| command.equalsIgnoreCase("//hpos1") || command.equalsIgnoreCase("/hpos1")
|| command.equalsIgnoreCase("//hpos2")) { || command.equalsIgnoreCase("/hpos2")
|| command.equalsIgnoreCase("/chunk")
|| command.equalsIgnoreCase("/expand")
|| command.equalsIgnoreCase("/contract")
|| command.equalsIgnoreCase("/shift")
|| command.equalsIgnoreCase("toggleeditwand")) {
return player.hasPermission(command) return player.hasPermission(command)
|| player.hasPermission("worldeditselect") || player.hasPermission("worldeditselect")
|| player.hasPermission("worldedit"); || player.hasPermission("worldedit");
} }
return player.hasPermission(command.replace("air", "")) return player.hasPermission("worldedit");
|| player.hasPermission("worldedit");
} }
/** /**

Datei anzeigen

@ -93,6 +93,21 @@ public class WorldVector extends Vector {
return world; return world;
} }
/**
* Get a block point from a point.
*
* @param x
* @param y
* @param z
* @return point
*/
public static WorldVector toBlockPoint(LocalWorld world, double x, double y,
double z) {
return new WorldVector(world, (int)Math.floor(x),
(int)Math.floor(y),
(int)Math.floor(z));
}
/** /**
* Gets a BlockVector version. * Gets a BlockVector version.
* *

Datei anzeigen

@ -38,12 +38,12 @@ public class AreaPickaxe implements SuperPickaxeMode {
@Override @Override
public boolean act(ServerInterface server, LocalConfiguration config, public boolean act(ServerInterface server, LocalConfiguration config,
LocalPlayer player, LocalSession session, LocalWorld world, LocalPlayer player, LocalSession session, WorldVector clicked) {
Vector clicked) { LocalWorld world = clicked.getWorld();
int ox = clicked.getBlockX(); int ox = clicked.getBlockX();
int oy = clicked.getBlockY(); int oy = clicked.getBlockY();
int oz = clicked.getBlockZ(); int oz = clicked.getBlockZ();
int initialType = server.getBlockType(world, clicked); int initialType = world.getBlockType(clicked);
if (initialType == 0) { if (initialType == 0) {
return true; return true;
@ -61,9 +61,9 @@ public class AreaPickaxe implements SuperPickaxeMode {
for (int y = oy - range; y <= oy + range; y++) { for (int y = oy - range; y <= oy + range; y++) {
for (int z = oz - range; z <= oz + range; z++) { for (int z = oz - range; z <= oz + range; z++) {
Vector pos = new Vector(x, y, z); Vector pos = new Vector(x, y, z);
if (server.getBlockType(world, pos) == initialType) { if (world.getBlockType(pos) == initialType) {
if (config.superPickaxeManyDrop) { if (config.superPickaxeManyDrop) {
server.simulateBlockMine(world, pos); world.simulateBlockMine(pos);
} }
editSession.setBlock(pos, air); editSession.setBlock(pos, air);

Datei anzeigen

@ -36,9 +36,9 @@ public class BlockReplacer implements SuperPickaxeMode {
@Override @Override
public boolean act(ServerInterface server, LocalConfiguration config, public boolean act(ServerInterface server, LocalConfiguration config,
LocalPlayer player, LocalSession session, LocalWorld world, LocalPlayer player, LocalSession session, WorldVector clicked) {
Vector clicked) {
LocalWorld world = clicked.getWorld();
EditSession editSession = new EditSession(server, world, -1); EditSession editSession = new EditSession(server, world, -1);
try { try {

Datei anzeigen

@ -31,8 +31,9 @@ public class QueryTool implements SuperPickaxeMode {
@Override @Override
public boolean act(ServerInterface server, LocalConfiguration config, public boolean act(ServerInterface server, LocalConfiguration config,
LocalPlayer player, LocalSession session, LocalWorld world, LocalPlayer player, LocalSession session, WorldVector clicked) {
Vector clicked) {
LocalWorld world = clicked.getWorld();
BaseBlock block = (new EditSession(server, world, 0)).rawGetBlock(clicked); BaseBlock block = (new EditSession(server, world, 0)).rawGetBlock(clicked);
player.print("\u00A79@" + clicked + ": " + "\u00A7e" player.print("\u00A79@" + clicked + ": " + "\u00A7e"

Datei anzeigen

@ -41,9 +41,10 @@ public class RecursivePickaxe implements SuperPickaxeMode {
@Override @Override
public boolean act(ServerInterface server, LocalConfiguration config, public boolean act(ServerInterface server, LocalConfiguration config,
LocalPlayer player, LocalSession session, LocalWorld world, LocalPlayer player, LocalSession session, WorldVector clicked) {
Vector clicked) { LocalWorld world = clicked.getWorld();
int initialType = server.getBlockType(world, clicked);
int initialType = world.getBlockType(clicked);
if (initialType == 0) { if (initialType == 0) {
return true; return true;
@ -95,7 +96,7 @@ public class RecursivePickaxe implements SuperPickaxeMode {
if (editSession.getBlock(pos).getID() == initialType) { if (editSession.getBlock(pos).getID() == initialType) {
if (drop) { if (drop) {
server.simulateBlockMine(world, pos); world.simulateBlockMine(pos);
} }
editSession.setBlock(pos, air); editSession.setBlock(pos, air);
} else { } else {

Datei anzeigen

@ -30,21 +30,21 @@ import com.sk89q.worldedit.blocks.BlockID;
public class SinglePickaxe implements SuperPickaxeMode { public class SinglePickaxe implements SuperPickaxeMode {
@Override @Override
public boolean act(ServerInterface server, LocalConfiguration config, public boolean act(ServerInterface server, LocalConfiguration config,
LocalPlayer player, LocalSession session, LocalWorld world, LocalPlayer player, LocalSession session, WorldVector clicked) {
Vector clicked) { LocalWorld world = clicked.getWorld();
if (server.getBlockType(world, clicked) == BlockID.BEDROCK if (world.getBlockType(clicked) == BlockID.BEDROCK
&& !player.canDestroyBedrock()) { && !player.canDestroyBedrock()) {
return true; return true;
} else if (server.getBlockType(world, clicked) == BlockID.TNT) { } else if (world.getBlockType(clicked) == BlockID.TNT) {
return false; return false;
} }
if (config.superPickaxeDrop) { if (config.superPickaxeDrop) {
server.simulateBlockMine(world, clicked); world.simulateBlockMine(clicked);
} }
server.setBlockType(world, clicked, 0); world.setBlockType(clicked, 0);
return true; return true;
} }

Datei anzeigen

@ -37,6 +37,5 @@ public interface SuperPickaxeMode {
* @return true to deny * @return true to deny
*/ */
public boolean act(ServerInterface server, LocalConfiguration config, public boolean act(ServerInterface server, LocalConfiguration config,
LocalPlayer player, LocalSession session, LocalWorld world, LocalPlayer player, LocalSession session, WorldVector clicked);
Vector clicked);
} }

Datei anzeigen

@ -30,13 +30,14 @@ public class TreePlanter implements SuperPickaxeMode {
@Override @Override
public boolean act(ServerInterface server, LocalConfiguration config, public boolean act(ServerInterface server, LocalConfiguration config,
LocalPlayer player, LocalSession session, LocalWorld world, LocalPlayer player, LocalSession session, WorldVector clicked) {
Vector clicked) {
LocalWorld world = clicked.getWorld();
EditSession editSession = EditSession editSession =
new EditSession(server, world, session.getBlockChangeLimit()); new EditSession(server, world, session.getBlockChangeLimit());
try { try {
if (!server.generateTree(editSession, player.getWorld(), clicked)) { if (!world.generateTree(editSession, clicked)) {
player.printError("Notch won't let you put a tree there."); player.printError("Notch won't let you put a tree there.");
} }
} finally { } finally {

Datei anzeigen

@ -1,5 +1,5 @@
name = WorldEdit name = WorldEdit
version = %version% version = %version%
url = updatr.update.sk89q.com/worldedit.updatr url = updatr.update.sk89q.com/worldedit.updatr
file = github.com/downloads/sk89q/worldedit/worldedit-%version%.zip file = cloud.github.com/downloads/sk89q/worldedit/worldedit-%version%.zip
notes = notes =