mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-23 17:57:38 +00:00
Added a tool that allows a player to place and remove blocks at a distance.
This commit is contained in:
parent
1a6bc6f42c
commit
67a7969cd1
@ -320,6 +320,10 @@ public abstract class LocalPlayer {
|
|||||||
return (useLastBlock ? tb.getAnyTargetBlock() : tb.getTargetBlock());
|
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.
|
* Get the point of the block being looked at. May return null.
|
||||||
*
|
*
|
||||||
|
68
src/main/java/com/sk89q/worldedit/VectorFace.java
Normal file
68
src/main/java/com/sk89q/worldedit/VectorFace.java
Normal file
@ -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
Normal file
148
src/main/java/com/sk89q/worldedit/WorldVectorFace.java
Normal file
@ -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());
|
session.setTool(player.getItemInHand(), new DistanceWand());
|
||||||
player.print("Far wand tool bound to " + ItemType.toHeldName(player.getItemInHand()) + ".");
|
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,
|
public boolean actPrimary(ServerInterface server, LocalConfiguration config,
|
||||||
LocalPlayer player, LocalSession session) {
|
LocalPlayer player, LocalSession session) {
|
||||||
WorldVector target = null;
|
WorldVector target = null;
|
||||||
if (this.range > -1) {
|
|
||||||
target = player.getBlockTrace(getRange(), true);
|
target = player.getBlockTrace(getRange(), true);
|
||||||
} else {
|
|
||||||
target = player.getBlockTrace(MAX_RANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
player.printError("No block in sight!");
|
player.printError("No block in sight!");
|
||||||
|
@ -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.LocalPlayer;
|
||||||
import com.sk89q.worldedit.LocalWorld;
|
import com.sk89q.worldedit.LocalWorld;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldVectorFace;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockID;
|
||||||
import com.sk89q.worldedit.blocks.BlockType;
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,7 +112,7 @@ public class TargetBlock {
|
|||||||
boolean searchForLastBlock = true;
|
boolean searchForLastBlock = true;
|
||||||
BlockWorldVector lastBlock = null;
|
BlockWorldVector lastBlock = null;
|
||||||
while (getNextBlock() != null) {
|
while (getNextBlock() != null) {
|
||||||
if (world.getBlockType(getCurrentBlock()) == 0) {
|
if (world.getBlockType(getCurrentBlock()) == BlockID.AIR) {
|
||||||
if(searchForLastBlock) {
|
if(searchForLastBlock) {
|
||||||
lastBlock = getCurrentBlock();
|
lastBlock = getCurrentBlock();
|
||||||
if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= 127) {
|
if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= 127) {
|
||||||
@ -196,4 +198,14 @@ public class TargetBlock {
|
|||||||
public BlockWorldVector getPreviousBlock() {
|
public BlockWorldVector getPreviousBlock() {
|
||||||
return new BlockWorldVector(world, prevPos);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user