geforkt von Mirrors/FastAsyncWorldEdit
Added a tool that allows a player to place and remove blocks at a distance.
Dieser Commit ist enthalten in:
Ursprung
1a6bc6f42c
Commit
67a7969cd1
@ -320,6 +320,10 @@ public abstract class LocalPlayer {
|
||||
return (useLastBlock ? tb.getAnyTargetBlock() : tb.getTargetBlock());
|
||||
}
|
||||
|
||||
public WorldVectorFace getBlockTraceFace(int range, boolean useLastBlock) {
|
||||
TargetBlock tb = new TargetBlock(this, range, 0.2);
|
||||
return (useLastBlock ? tb.getAnyTargetBlockFace() : tb.getTargetBlockFace());
|
||||
}
|
||||
/**
|
||||
* Get the point of the block being looked at. May return null.
|
||||
*
|
||||
|
68
src/main/java/com/sk89q/worldedit/VectorFace.java
Normale Datei
68
src/main/java/com/sk89q/worldedit/VectorFace.java
Normale Datei
@ -0,0 +1,68 @@
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
/**
|
||||
* Represents the adjacency of one vector to another. Works similarly to
|
||||
* Bukkit's BlockFace class.
|
||||
*
|
||||
* @author wizjany
|
||||
*/
|
||||
public enum VectorFace {
|
||||
NORTH(-1, 0, 0),
|
||||
EAST(0, 0, -1),
|
||||
SOUTH(1, 0, 0),
|
||||
WEST(0, 0, 1),
|
||||
UP(0, 1, 0),
|
||||
DOWN(0, -1, 0),
|
||||
NORTH_EAST(NORTH, EAST),
|
||||
NORTH_WEST(NORTH, WEST),
|
||||
SOUTH_EAST(SOUTH, EAST),
|
||||
SOUTH_WEST(SOUTH, WEST),
|
||||
ABOVE_NORTH(UP, NORTH),
|
||||
BELOW_NORTH(DOWN, NORTH),
|
||||
ABOVE_SOUTH(UP, SOUTH),
|
||||
BELOW_SOUTH(DOWN, SOUTH),
|
||||
ABOVE_WEST(UP, WEST),
|
||||
BELOW_WEST(DOWN, WEST),
|
||||
ABOVE_EAST(UP, EAST),
|
||||
BELOW_EAST(DOWN, EAST),
|
||||
SELF(0, 0, 0);
|
||||
|
||||
private int modX;
|
||||
private int modY;
|
||||
private int modZ;
|
||||
|
||||
private VectorFace(final int modX, final int modY, final int modZ) {
|
||||
this.modX = modX;
|
||||
this.modY = modY;
|
||||
this.modZ = modZ;
|
||||
}
|
||||
|
||||
private VectorFace(VectorFace face1, VectorFace face2) {
|
||||
this.modX = face1.getModX() + face2.getModX();
|
||||
this.modY = face1.getModY() + face2.getModY();
|
||||
this.modZ = face1.getModZ() + face2.getModZ();
|
||||
}
|
||||
|
||||
public int getModX() {
|
||||
return modX;
|
||||
}
|
||||
|
||||
public int getModZ() {
|
||||
return modZ;
|
||||
}
|
||||
|
||||
public int getModY() {
|
||||
return modY;
|
||||
}
|
||||
|
||||
public static VectorFace fromMods(int modX2, int modY2, int modZ2) {
|
||||
for (VectorFace face : values()) {
|
||||
if (face.getModX() == modX2
|
||||
&& face.getModY() == modY2
|
||||
&& face.getModZ() == modZ2) {
|
||||
return face;
|
||||
}
|
||||
}
|
||||
return VectorFace.SELF;
|
||||
}
|
||||
}
|
148
src/main/java/com/sk89q/worldedit/WorldVectorFace.java
Normale Datei
148
src/main/java/com/sk89q/worldedit/WorldVectorFace.java
Normale Datei
@ -0,0 +1,148 @@
|
||||
// $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/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
/**
|
||||
* A WorldVector that emphasizes one side of the block
|
||||
*/
|
||||
public class WorldVectorFace extends WorldVector {
|
||||
/**
|
||||
* Represents the side.
|
||||
*/
|
||||
private VectorFace face;
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param world
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param face
|
||||
*/
|
||||
public WorldVectorFace(LocalWorld world, double x, double y, double z, VectorFace face) {
|
||||
super(world, x, y, z);
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param world
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param face
|
||||
*/
|
||||
public WorldVectorFace(LocalWorld world, int x, int y, int z, VectorFace face) {
|
||||
super(world, x, y, z);
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param world
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param face
|
||||
*/
|
||||
public WorldVectorFace(LocalWorld world, float x, float y, float z, VectorFace face) {
|
||||
super(world, x, y, z);
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param world
|
||||
* @param pt
|
||||
* @param face
|
||||
*/
|
||||
public WorldVectorFace(LocalWorld world, Vector pt, VectorFace face) {
|
||||
super(world, pt);
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the Vector object.
|
||||
*
|
||||
* @param world
|
||||
* @param face
|
||||
*/
|
||||
public WorldVectorFace(LocalWorld world, VectorFace face) {
|
||||
super(world);
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the face.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public VectorFace getFace() {
|
||||
return face;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WorldVector adjacent to this WorldVectorFace.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public WorldVector getFaceVector() {
|
||||
return new WorldVector(getWorld(),
|
||||
getBlockX() - face.getModX(),
|
||||
getBlockY() - face.getModY(),
|
||||
getBlockZ() - face.getModZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a WorldVectorFace by comparing two vectors. Note that they need not be
|
||||
* adjacent, as only the directions, not distance, will be taken into account.
|
||||
*
|
||||
* @param world the world in which the resulting vector should lie
|
||||
* @param vector the original vector
|
||||
* @param face the direction in which the face should lie
|
||||
* @return
|
||||
*/
|
||||
public static WorldVectorFace getWorldVectorFace(LocalWorld world, Vector vector, Vector face) {
|
||||
if (vector == null || face == null) return null;
|
||||
// check which direction the face is from the vector
|
||||
final int x1 = vector.getBlockX();
|
||||
final int y1 = vector.getBlockY();
|
||||
final int z1 = vector.getBlockZ();
|
||||
int modX = x1 - face.getBlockX();
|
||||
int modY = y1 - face.getBlockY();
|
||||
int modZ = z1 - face.getBlockZ();
|
||||
if (modX > 0) modX = 1;
|
||||
else if (modX < 0) modX = -1;
|
||||
else modX = 0;
|
||||
if (modY > 0) modY = 1;
|
||||
else if (modY < 0) modY = -1;
|
||||
else modY = 0;
|
||||
if (modZ > 0) modZ = 1;
|
||||
else if (modZ < 0) modZ = -1;
|
||||
else modZ = 0;
|
||||
// construct new vector
|
||||
return new WorldVectorFace(world, x1, y1, z1, VectorFace.fromMods(modX, modY, modZ));
|
||||
}
|
||||
|
||||
}
|
@ -192,4 +192,24 @@ public class ToolCommands {
|
||||
session.setTool(player.getItemInHand(), new DistanceWand());
|
||||
player.print("Far wand tool bound to " + ItemType.toHeldName(player.getItemInHand()) + ".");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"lrbuild", "/lrbuild"},
|
||||
usage = "<leftclick block> <rightclick block>",
|
||||
desc = "Long-range building tool",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions({"worldedit.tool.lrbuild"})
|
||||
public static void longrangebuildtool(CommandContext args, WorldEdit we,
|
||||
LocalSession session, LocalPlayer player, EditSession editSession)
|
||||
throws WorldEditException {
|
||||
|
||||
BaseBlock secondary = we.getBlock(player, args.getString(0));
|
||||
BaseBlock primary = we.getBlock(player, args.getString(1));
|
||||
session.setTool(player.getItemInHand(), new LongRangeBuildTool(primary, secondary));
|
||||
player.print("Long-range building tool bound to " + ItemType.toHeldName(player.getItemInHand()) + ".");
|
||||
player.print("Left-click set to " + ItemType.toName(secondary.getType()) + "; right-click set to "
|
||||
+ ItemType.toName(primary.getType()) + ".");
|
||||
}
|
||||
}
|
||||
|
@ -167,11 +167,7 @@ public class BrushTool implements TraceTool {
|
||||
public boolean actPrimary(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session) {
|
||||
WorldVector target = null;
|
||||
if (this.range > -1) {
|
||||
target = player.getBlockTrace(getRange(), true);
|
||||
} else {
|
||||
target = player.getBlockTrace(MAX_RANGE);
|
||||
}
|
||||
target = player.getBlockTrace(getRange(), true);
|
||||
|
||||
if (target == null) {
|
||||
player.printError("No block in sight!");
|
||||
|
97
src/main/java/com/sk89q/worldedit/tools/LongRangeBuildTool.java
Normale Datei
97
src/main/java/com/sk89q/worldedit/tools/LongRangeBuildTool.java
Normale Datei
@ -0,0 +1,97 @@
|
||||
// $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/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.tools;
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
|
||||
/**
|
||||
* A tool that can place (or remove) blocks at a distance.
|
||||
*
|
||||
* @author wizjany
|
||||
*/
|
||||
public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTool {
|
||||
|
||||
BaseBlock primary;
|
||||
BaseBlock secondary;
|
||||
|
||||
public LongRangeBuildTool(BaseBlock primary, BaseBlock secondary) {
|
||||
super("worldedit.tool.lrbuild");
|
||||
this.primary = primary;
|
||||
this.secondary = secondary;
|
||||
}
|
||||
|
||||
public boolean canUse(LocalPlayer player) {
|
||||
return player.hasPermission("worldedit.tool.lrbuild");
|
||||
}
|
||||
|
||||
public boolean actSecondary(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session) {
|
||||
|
||||
WorldVectorFace pos = getTargetFace(player);
|
||||
if (pos == null) return false;
|
||||
EditSession eS = session.createEditSession(player);
|
||||
try {
|
||||
if (secondary.getType() == BlockID.AIR) {
|
||||
eS.setBlock(pos, secondary);
|
||||
} else {
|
||||
eS.setBlock(pos.getFaceVector(), secondary);
|
||||
}
|
||||
return true;
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
// one block? eat it
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean actPrimary(ServerInterface server, LocalConfiguration config,
|
||||
LocalPlayer player, LocalSession session) {
|
||||
|
||||
WorldVectorFace pos = getTargetFace(player);
|
||||
if (pos == null) return false;
|
||||
EditSession eS = session.createEditSession(player);
|
||||
try {
|
||||
if (primary.getType() == BlockID.AIR) {
|
||||
eS.setBlock(pos, primary);
|
||||
} else {
|
||||
eS.setBlock(pos.getFaceVector(), primary);
|
||||
}
|
||||
return true;
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
// one block? eat it
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public WorldVectorFace getTargetFace(LocalPlayer player) {
|
||||
WorldVectorFace target = null;
|
||||
target = player.getBlockTraceFace(getRange(), true);
|
||||
|
||||
if (target == null) {
|
||||
player.printError("No block in sight!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
}
|
@ -27,6 +27,8 @@ import com.sk89q.worldedit.BlockWorldVector;
|
||||
import com.sk89q.worldedit.LocalPlayer;
|
||||
import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldVectorFace;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
|
||||
/**
|
||||
@ -110,7 +112,7 @@ public class TargetBlock {
|
||||
boolean searchForLastBlock = true;
|
||||
BlockWorldVector lastBlock = null;
|
||||
while (getNextBlock() != null) {
|
||||
if (world.getBlockType(getCurrentBlock()) == 0) {
|
||||
if (world.getBlockType(getCurrentBlock()) == BlockID.AIR) {
|
||||
if(searchForLastBlock) {
|
||||
lastBlock = getCurrentBlock();
|
||||
if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= 127) {
|
||||
@ -196,4 +198,14 @@ public class TargetBlock {
|
||||
public BlockWorldVector getPreviousBlock() {
|
||||
return new BlockWorldVector(world, prevPos);
|
||||
}
|
||||
|
||||
public WorldVectorFace getAnyTargetBlockFace() {
|
||||
getAnyTargetBlock();
|
||||
return WorldVectorFace.getWorldVectorFace(world, getCurrentBlock(), getPreviousBlock());
|
||||
}
|
||||
|
||||
public WorldVectorFace getTargetBlockFace() {
|
||||
getAnyTargetBlock();
|
||||
return WorldVectorFace.getWorldVectorFace(world, getCurrentBlock(), getPreviousBlock());
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren