mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-24 10:17:39 +00:00
Merge branch 'master' of git@github.com:sk89q/worldedit.git
This commit is contained in:
commit
282b3fbd05
120
README.md
120
README.md
@ -16,6 +16,12 @@ simply run:
|
|||||||
Maven will automatically download dependencies for you. Note: For that to work,
|
Maven will automatically download dependencies for you. Note: For that to work,
|
||||||
be sure to add Maven to your "PATH".
|
be sure to add Maven to your "PATH".
|
||||||
|
|
||||||
|
Issue Tracker
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Please submit bug reports and feature requests here:
|
||||||
|
http://redmine.sk89q.com/projects/worldedit/issues
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -25,117 +31,3 @@ look at it, make comments, and merge it into WorldEdit if everything
|
|||||||
works out.
|
works out.
|
||||||
|
|
||||||
Your submissions have to be licensed under the GNU General Public License v3.
|
Your submissions have to be licensed under the GNU General Public License v3.
|
||||||
|
|
||||||
General Concepts
|
|
||||||
----------------
|
|
||||||
|
|
||||||
The entry point for all of WorldEdit is in `com.sk89q.worldedit.WorldEdit`.
|
|
||||||
This is where all the events and chat commands are handled. The commands
|
|
||||||
themselves are found in the `com.sk89q.worldedit.commands` package.
|
|
||||||
|
|
||||||
Each user has a _session_ that stores session-related data, including
|
|
||||||
history and clipboard. The class that handles session data is
|
|
||||||
`com.sk89q.worldedit.LocalSession`. A copy of it is created when needed
|
|
||||||
by the `getSession` method of `WorldEdit` and it's also stored on
|
|
||||||
`WorldEdit` in a hash map. The history is merely a list of
|
|
||||||
`com.sk89q.worldedit.EditSession`s, while the clipboard is a copy of
|
|
||||||
`com.sk89q.worldedit.CuboidClipboard`.
|
|
||||||
|
|
||||||
Now, one of the most important classes in WorldEdit is
|
|
||||||
`com.sk89q.worldedit.EditSession`. Nearly all block sets and gets are routed
|
|
||||||
through it because it automatically records a log of operations (for undo),
|
|
||||||
handles block placement order, and does a lot of magic to make sure things
|
|
||||||
come out the way it is intended. However, to make sure that block placement
|
|
||||||
order is adhered, remember to call `EditSession.enableQueue()` and later
|
|
||||||
`EditSession.flushQueue()`. Also, to actually an edit session in a player's
|
|
||||||
history, it has to be passed to `LocalSession.remember(EditSession)`.
|
|
||||||
|
|
||||||
Blocks in WorldEdit are entirely abstracted. Block types and block data not
|
|
||||||
simply passed around; rather, because blocks can contain a lot more data
|
|
||||||
(such as with signs and such), all blocks are an instance of
|
|
||||||
`com.sk89q.worldedit.blocks.BaseBlock`. For special block types, there's
|
|
||||||
a `SignBlock`, a `ChestBlock`, etc. Blocks are __detached__ from the world,
|
|
||||||
meaning they don't know where they are. You can pass them around freely
|
|
||||||
if you want (this is why syntax like `//set sign:3|Hi|there!` can work).
|
|
||||||
|
|
||||||
If you are making a command, you need to add the new command to `plugin.yml`
|
|
||||||
if you are using Bukkit. However,
|
|
||||||
`com.sk89q.worldedit.dev.DocumentationPrinter` is a program that will
|
|
||||||
generate `plugin.yml` by using Java reflection on the command classes.
|
|
||||||
Commands are given an edit session automatically (with queue
|
|
||||||
enabled) and so there's not much to set up. If you want to add a new class
|
|
||||||
altogether that contains commands, you need to update the constructor of
|
|
||||||
`com.sk89q.worldedit.WorldEdit` load your class.
|
|
||||||
|
|
||||||
### Core Routines ###
|
|
||||||
|
|
||||||
`com.sk89q.worldedit.WorldEdit.getBlock` handles the block syntax
|
|
||||||
(such as `sign:3|Hi|there!`).
|
|
||||||
`com.sk89q.worldedit.WorldEdit.getBlockPattern` handles the pattern
|
|
||||||
syntax (such as `90%rock,10%brick` or `#clipboard`).
|
|
||||||
|
|
||||||
Package Summary
|
|
||||||
---------------
|
|
||||||
|
|
||||||
WorldEdit is well organized and uses abstraction heavily to make adding new
|
|
||||||
things easy. An explanation of WorldEdit's package layout is as follows:
|
|
||||||
|
|
||||||
* `com.sk89q.bukkit.migration` has classes to handle permissions for
|
|
||||||
Bukkit plugins until Bukkit attains built-in permissions support
|
|
||||||
* `com.sk89q.util` has some utility classes
|
|
||||||
* `com.sk89q.util.commands` has some base command handling code
|
|
||||||
(commands in WorldEdit are defined using Java annotations)
|
|
||||||
* `com.sk89q.worldedit` has core WorldEdit classes
|
|
||||||
* `com.sk89q.worldedit.bags` has support for block sources and sinks
|
|
||||||
such as inventory (which allows blocks to be taken from a player's
|
|
||||||
inventory)
|
|
||||||
* `com.sk89q.worldedit.blocks` abstracts blocks from the game
|
|
||||||
(such as chest blocks, etc.) and has support for all block data
|
|
||||||
* `com.sk89q.worldedit.bukkit` contains the implementation of WorldEdit
|
|
||||||
for Bukkit as a plugin
|
|
||||||
* `com.sk89q.worldedit.commands` has all of WorldEdit's chat commands
|
|
||||||
* `com.sk89q.worldedit.data` contains classes to read Minecraft's world
|
|
||||||
files directly from disk
|
|
||||||
* `com.sk89q.worldedit.dev` contains a class to generate documentation
|
|
||||||
and other development-related files
|
|
||||||
* `com.sk89q.worldedit.filters` contains filters used for the smoothing
|
|
||||||
algorithm
|
|
||||||
* `com.sk89q.worldedit.patterns` contains the pattern support
|
|
||||||
(such as for `//set 90%rock,10%air` or `//set #clipboard`)
|
|
||||||
* `com.sk89q.worldedit.regions` contains the selection regions for
|
|
||||||
WorldEdit; there's only one at the moment (a cuboid), but different
|
|
||||||
region shapes can be added easily
|
|
||||||
* `com.sk89q.worldedit.scripting` contains scripting engines
|
|
||||||
* `com.sk89q.worldedit.snapshots` contains snapshot loading code (but
|
|
||||||
actual world file reading code is in `com.sk89q.worldedit.data`)
|
|
||||||
* `com.sk89q.worldedit.superpickaxe` contains the code for the different
|
|
||||||
super pickaxe modes
|
|
||||||
* `com.sk89q.worldedit.superpickaxe.brush` contains the different brush
|
|
||||||
shapes for the brush super pickaxe tools
|
|
||||||
* `com.sk89q.worldedit.util` has some utility classes
|
|
||||||
* `org.jnbt` is the JNBT library to read JNBT formatted files
|
|
||||||
|
|
||||||
Task Tutorials
|
|
||||||
--------------
|
|
||||||
|
|
||||||
### How to Add a Command ###
|
|
||||||
|
|
||||||
1. If you want to add your command to an existing category of commands
|
|
||||||
(check out the classes in `com.sk89q.worldedit.commands`) then you
|
|
||||||
can just re-use one. If you want to create a new class, create a new
|
|
||||||
class (it does not have to inherit or implement anything) and add it
|
|
||||||
to the constructor of `com.sk89q.worldedit.WorldEdit`.
|
|
||||||
2. Add a new method, named anything.
|
|
||||||
3. Add the `@Command` annotation to signify that it is a command. The
|
|
||||||
`aliases` property contains a list of command aliases and the first
|
|
||||||
one in the list is the main alias. `usage` contains parameter usage
|
|
||||||
information. `desc` is a short description. `flags` is an optional
|
|
||||||
string of flags (each flag is only one character long).
|
|
||||||
`min` is the minimum number of arguments. `max` is the maximum number of
|
|
||||||
arguments and it can be -1 to allow an unlimited number.
|
|
||||||
4. Adding `@CommandPermissions` causes permissions to be checked for the
|
|
||||||
command. Only one permission needs to be satisfied in the list.
|
|
||||||
5. Write the command.
|
|
||||||
6. If using Bukkit, update `plugin.yml` or run
|
|
||||||
`com.sk89q.worldedit.dev.DocumentationPrinter` to generate it for you.
|
|
||||||
7. Compile and test!
|
|
||||||
|
@ -294,6 +294,9 @@ commands:
|
|||||||
none:
|
none:
|
||||||
description: Turn off all superpickaxe alternate modes
|
description: Turn off all superpickaxe alternate modes
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
|
farwand:
|
||||||
|
description: Wand tool at a distance
|
||||||
|
usage: /<command>
|
||||||
tree:
|
tree:
|
||||||
description: Tree generator tool
|
description: Tree generator tool
|
||||||
usage: /<command> [type]
|
usage: /<command> [type]
|
||||||
|
@ -25,6 +25,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import org.bukkit.util.config.Configuration;
|
import org.bukkit.util.config.Configuration;
|
||||||
|
import org.bukkit.util.config.ConfigurationNode;
|
||||||
|
|
||||||
public class ConfigurationPermissionsResolver implements PermissionsResolver {
|
public class ConfigurationPermissionsResolver implements PermissionsResolver {
|
||||||
private Configuration config;
|
private Configuration config;
|
||||||
@ -36,6 +37,16 @@ public class ConfigurationPermissionsResolver implements PermissionsResolver {
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void generateDefaultPerms(Configuration config) {
|
||||||
|
config.setProperty("permissions.groups.default.permissions", new String[] {
|
||||||
|
"worldedit.reload",
|
||||||
|
"worldedit.selection.*",
|
||||||
|
"worlds.creative.worldedit.region.*"});
|
||||||
|
config.setProperty("permissions.groups.admins.permissions", new String[]{"*"});
|
||||||
|
config.setProperty("permissions.users.sk89q.permissions", new String[]{"worldedit.*"});
|
||||||
|
config.setProperty("permissions.users.sk89q.groups", new String[]{"admins"});
|
||||||
|
}
|
||||||
|
|
||||||
public void load() {
|
public void load() {
|
||||||
userGroups = new HashMap<String,Set<String>>();
|
userGroups = new HashMap<String,Set<String>>();
|
||||||
userPermissionsCache = new HashMap<String,Set<String>>();
|
userPermissionsCache = new HashMap<String,Set<String>>();
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
package com.sk89q.bukkit.migration;
|
package com.sk89q.bukkit.migration;
|
||||||
|
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
@ -19,34 +19,58 @@
|
|||||||
|
|
||||||
package com.sk89q.bukkit.migration;
|
package com.sk89q.bukkit.migration;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.util.config.Configuration;
|
import org.bukkit.util.config.Configuration;
|
||||||
|
|
||||||
public class PermissionsResolverManager implements PermissionsResolver {
|
public class PermissionsResolverManager implements PermissionsResolver {
|
||||||
private Configuration config;
|
private static final String CONFIG_HEADER = "#\r\n" +
|
||||||
|
"# WEPIF Configuration File\r\n" +
|
||||||
|
"#\r\n" +
|
||||||
|
"# This file handles permissions configuration for every plugin using WEPIF\r\n" +
|
||||||
|
"#\r\n" +
|
||||||
|
"# About editing this file:\r\n" +
|
||||||
|
"# - DO NOT USE TABS. You MUST use spaces or Bukkit will complain. If\r\n" +
|
||||||
|
"# you use an editor like Notepad++ (recommended for Windows users), you\r\n" +
|
||||||
|
"# must configure it to \"replace tabs with spaces.\" In Notepad++, this can\r\n" +
|
||||||
|
"# be changed in Settings > Preferences > Language Menu.\r\n" +
|
||||||
|
"# - Don't get rid of the indents. They are indented so some entries are\r\n" +
|
||||||
|
"# in categories (like \"enforce-single-session\" is in the \"protection\"\r\n" +
|
||||||
|
"# category.\r\n" +
|
||||||
|
"# - If you want to check the format of this file before putting it\r\n" +
|
||||||
|
"# into WEPIF, paste it into http://yaml-online-parser.appspot.com/\r\n" +
|
||||||
|
"# and see if it gives \"ERROR:\".\r\n" +
|
||||||
|
"# - Lines starting with # are comments and so they are ignored.\r\n" +
|
||||||
|
"#\r\n" +
|
||||||
|
"# About Configuration Permissions\r\n" +
|
||||||
|
"# - See http://wiki.sk89q.com/wiki/WorldEdit/Permissions/Bukkit\r\n" +
|
||||||
|
"# - Now with multiworld support (see example)\r\n" +
|
||||||
|
"\r\n";
|
||||||
|
|
||||||
private Server server;
|
private Server server;
|
||||||
private PermissionsResolver perms;
|
private PermissionsResolver perms;
|
||||||
|
private Configuration permsConfig;
|
||||||
private String name;
|
private String name;
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
|
|
||||||
public PermissionsResolverManager(Configuration config, Server server, String name, Logger logger) {
|
public PermissionsResolverManager(Configuration config, Server server, String name, Logger logger) {
|
||||||
this.config = config;
|
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
loadConfig(new File("wepif.yml")); // TODO: config migration, maybe
|
||||||
findResolver();
|
findResolver();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void findResolver() {
|
public void findResolver() {
|
||||||
if (tryDinnerPerms()) return;
|
if (tryDinnerPerms()) return;
|
||||||
if (tryPluginPermissionsResolver()) return;
|
if (tryPluginPermissionsResolver()) return;
|
||||||
if (tryNijiPermissions()) return;
|
if (tryNijiPermissions()) return;
|
||||||
if (tryFlatFilePermissions()) return;
|
if (tryFlatFilePermissions()) return;
|
||||||
|
|
||||||
perms = new ConfigurationPermissionsResolver(config);
|
perms = new ConfigurationPermissionsResolver(permsConfig);
|
||||||
logger.info(name + ": No known permissions plugin detected. Using configuration file for permissions.");
|
logger.info(name + ": No known permissions plugin detected. Using configuration file for permissions.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +109,7 @@ public class PermissionsResolverManager implements PermissionsResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean tryDinnerPerms() {
|
private boolean tryDinnerPerms() {
|
||||||
if (!config.getBoolean("permissions.dinner-perms", true))
|
if (!permsConfig.getBoolean("dinnerperms", true))
|
||||||
return false;
|
return false;
|
||||||
perms = new DinnerPermsResolver(server);
|
perms = new DinnerPermsResolver(server);
|
||||||
logger.info(name + ": Using the Bukkit Permissions API.");
|
logger.info(name + ": Using the Bukkit Permissions API.");
|
||||||
@ -123,4 +147,36 @@ public class PermissionsResolverManager implements PermissionsResolver {
|
|||||||
return perms.getGroups(player);
|
return perms.getGroups(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean loadConfig(File file) {
|
||||||
|
boolean isUpdated = false;
|
||||||
|
if (!file.exists()) {
|
||||||
|
try {
|
||||||
|
file.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
permsConfig = new Configuration(file);
|
||||||
|
permsConfig.load();
|
||||||
|
List<String> keys = permsConfig.getKeys();
|
||||||
|
permsConfig.setHeader(CONFIG_HEADER);
|
||||||
|
if (!keys.contains("dinnerperms")) {
|
||||||
|
permsConfig.setProperty("dinnerperms", permsConfig.getBoolean("dinner-perms", true));
|
||||||
|
isUpdated = true;
|
||||||
|
}
|
||||||
|
if (keys.contains("dinner-perms")) {
|
||||||
|
permsConfig.removeProperty("dinner-perms");
|
||||||
|
isUpdated = true;
|
||||||
|
}
|
||||||
|
if (!keys.contains("permissions")) {
|
||||||
|
ConfigurationPermissionsResolver.generateDefaultPerms(permsConfig);
|
||||||
|
isUpdated = true;
|
||||||
|
}
|
||||||
|
if (isUpdated) {
|
||||||
|
logger.info("WEPIF: Updated config file");
|
||||||
|
permsConfig.save();
|
||||||
|
}
|
||||||
|
return isUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1327,7 +1327,7 @@ public class EditSession {
|
|||||||
|
|
||||||
for (int y = upperY; y >= lowerY; --y) {
|
for (int y = upperY; y >= lowerY; --y) {
|
||||||
Vector pt = new Vector(x, y, z);
|
Vector pt = new Vector(x, y, z);
|
||||||
Vector above = new Vector(x, y + 1, z);
|
//Vector above = new Vector(x, y + 1, z);
|
||||||
int blockType = getBlockType(pt);
|
int blockType = getBlockType(pt);
|
||||||
|
|
||||||
boolean isTransformable =
|
boolean isTransformable =
|
||||||
@ -1687,7 +1687,8 @@ public class EditSession {
|
|||||||
pos = pos.subtract(0, height, 0);
|
pos = pos.subtract(0, height, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos.getBlockY() - height - 1 < 0) {
|
// Only do this check if height is negative --Elizabeth
|
||||||
|
if (height < 0 && pos.getBlockY() - height - 1 < 0) {
|
||||||
height = pos.getBlockY() + 1;
|
height = pos.getBlockY() + 1;
|
||||||
} else if (pos.getBlockY() + height - 1 > 127) {
|
} else if (pos.getBlockY() + height - 1 > 127) {
|
||||||
height = 127 - pos.getBlockY() + 1;
|
height = 127 - pos.getBlockY() + 1;
|
||||||
|
@ -879,19 +879,17 @@ public class WorldEdit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called on left click (not on a block).
|
* Called on arm swing.
|
||||||
*
|
*
|
||||||
* @param player
|
* @param player
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean handleLeftClick(LocalPlayer player) {
|
public boolean handleArmSwing(LocalPlayer player) {
|
||||||
LocalSession session = getSession(player);
|
LocalSession session = getSession(player);
|
||||||
WorldVector pos = player.getSolidBlockTrace(config.navigationWandMaxDistance);
|
if (player.getItemInHand() == config.navigationWand
|
||||||
if (player.getItemInHand() == config.wandItem) {
|
|
||||||
return selectFirstPoint(player, session, pos);
|
|
||||||
} else if (player.getItemInHand() == config.navigationWand
|
|
||||||
&& config.navigationWandMaxDistance > 0
|
&& config.navigationWandMaxDistance > 0
|
||||||
&& player.hasPermission("worldedit.navigation.jumpto")) {
|
&& player.hasPermission("worldedit.navigation.jumpto")) {
|
||||||
|
WorldVector pos = player.getSolidBlockTrace(config.navigationWandMaxDistance);
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
player.findFreePosition(pos);
|
player.findFreePosition(pos);
|
||||||
} else {
|
} else {
|
||||||
@ -899,6 +897,13 @@ public class WorldEdit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tool tool = session.getTool(player.getItemInHand());
|
||||||
|
if (tool != null && tool instanceof DoubleActionTraceTool) {
|
||||||
|
if (tool.canUse(player)) {
|
||||||
|
((DoubleActionTraceTool) tool).actSecondary(server, config, player, session);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -918,16 +923,13 @@ public class WorldEdit {
|
|||||||
if (!player.passThroughForwardWall(40)) {
|
if (!player.passThroughForwardWall(40)) {
|
||||||
player.printError("Nothing to pass through!");
|
player.printError("Nothing to pass through!");
|
||||||
}
|
}
|
||||||
} else if (player.getItemInHand() == config.wandItem) {
|
|
||||||
WorldVector pos = player.getSolidBlockTrace(config.navigationWandMaxDistance);
|
|
||||||
return selectSecondPoint(player, session, pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tool tool = session.getTool(player.getItemInHand());
|
Tool tool = session.getTool(player.getItemInHand());
|
||||||
|
|
||||||
if (tool != null && tool instanceof TraceTool) {
|
if (tool != null && tool instanceof TraceTool) {
|
||||||
if (tool.canUse(player)) {
|
if (tool.canUse(player)) {
|
||||||
((TraceTool)tool).act(server, config, player, session);
|
((TraceTool) tool).actPrimary(server, config, player, session);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -943,10 +945,18 @@ public class WorldEdit {
|
|||||||
* @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, WorldVector clicked) {
|
public boolean handleBlockRightClick(LocalPlayer player, WorldVector clicked) {
|
||||||
|
int itemInHand = player.getItemInHand();
|
||||||
|
|
||||||
LocalSession session = getSession(player);
|
LocalSession session = getSession(player);
|
||||||
|
|
||||||
if (player.getItemInHand() == config.wandItem) {
|
if (itemInHand == config.wandItem && session.isToolControlEnabled()
|
||||||
return selectSecondPoint(player, session, clicked);
|
&& player.hasPermission("worldedit.selection.pos")) {
|
||||||
|
RegionSelector selector = session.getRegionSelector(player.getWorld());
|
||||||
|
if (selector.selectSecondary(clicked)) {
|
||||||
|
selector.explainSecondarySelection(player, session, clicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tool tool = session.getTool(player.getItemInHand());
|
Tool tool = session.getTool(player.getItemInHand());
|
||||||
@ -972,7 +982,21 @@ public class WorldEdit {
|
|||||||
LocalSession session = getSession(player);
|
LocalSession session = getSession(player);
|
||||||
|
|
||||||
if (player.getItemInHand() == config.wandItem) {
|
if (player.getItemInHand() == config.wandItem) {
|
||||||
return selectFirstPoint(player, session, clicked);
|
if (session.isToolControlEnabled()
|
||||||
|
&& player.hasPermission("worldedit.selection.pos")) {
|
||||||
|
// Bug workaround
|
||||||
|
if (clicked.getBlockX() == 0 && clicked.getBlockY() == 0
|
||||||
|
&& clicked.getBlockZ() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionSelector selector = session.getRegionSelector(player.getWorld());
|
||||||
|
if (selector.selectPrimary(clicked)) {
|
||||||
|
selector.explainPrimarySelection(player, session, clicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} else if (player.isHoldingPickAxe() && session.hasSuperPickAxe()) {
|
} else if (player.isHoldingPickAxe() && session.hasSuperPickAxe()) {
|
||||||
if (session.getSuperPickaxe() != null) {
|
if (session.getSuperPickaxe() != null) {
|
||||||
if (session.getSuperPickaxe().canUse(player)) {
|
if (session.getSuperPickaxe().canUse(player)) {
|
||||||
@ -994,40 +1018,6 @@ public class WorldEdit {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean selectFirstPoint(LocalPlayer player, LocalSession session, WorldVector clicked)
|
|
||||||
{
|
|
||||||
if (session.isToolControlEnabled()
|
|
||||||
&& player.hasPermission("worldedit.selection.pos")) {
|
|
||||||
// Bug workaround
|
|
||||||
if (clicked.getBlockX() == 0 && clicked.getBlockY() == 0
|
|
||||||
&& clicked.getBlockZ() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionSelector selector = session.getRegionSelector(player.getWorld());
|
|
||||||
if (selector.selectPrimary(clicked)) {
|
|
||||||
selector.explainPrimarySelection(player, session, clicked);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean selectSecondPoint(LocalPlayer player, LocalSession session, WorldVector clicked)
|
|
||||||
{
|
|
||||||
if (session.isToolControlEnabled()
|
|
||||||
&& player.hasPermission("worldedit.selection.pos")) {
|
|
||||||
RegionSelector selector = session.getRegionSelector(player.getWorld());
|
|
||||||
if (selector.selectSecondary(clicked)) {
|
|
||||||
selector.explainSecondarySelection(player, session, clicked);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param player
|
* @param player
|
||||||
|
@ -21,8 +21,6 @@ package com.sk89q.worldedit.bukkit;
|
|||||||
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.player.PlayerAnimationEvent;
|
|
||||||
import org.bukkit.event.player.PlayerAnimationType;
|
|
||||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.event.player.PlayerListener;
|
import org.bukkit.event.player.PlayerListener;
|
||||||
@ -30,7 +28,6 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
|||||||
import com.sk89q.worldedit.LocalPlayer;
|
import com.sk89q.worldedit.LocalPlayer;
|
||||||
import com.sk89q.worldedit.LocalWorld;
|
import com.sk89q.worldedit.LocalWorld;
|
||||||
import com.sk89q.worldedit.WorldVector;
|
import com.sk89q.worldedit.WorldVector;
|
||||||
import com.sk89q.worldedit.blocks.BlockID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all events thrown in relation to a Player
|
* Handles all events thrown in relation to a Player
|
||||||
@ -95,7 +92,13 @@ public class WorldEditPlayerListener extends PlayerListener {
|
|||||||
|
|
||||||
if (plugin.getWorldEdit().handleBlockLeftClick(player, pos)) {
|
if (plugin.getWorldEdit().handleBlockLeftClick(player, pos)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
} else if (plugin.getWorldEdit().handleLeftClick(wrapPlayer(event.getPlayer()))) {
|
}
|
||||||
|
|
||||||
|
if (plugin.getWorldEdit().handleArmSwing(wrapPlayer(event.getPlayer()))) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
} else if (event.getAction() == Action.LEFT_CLICK_AIR) {
|
||||||
|
if (plugin.getWorldEdit().handleArmSwing(wrapPlayer(event.getPlayer()))) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
} else if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
} else if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||||
@ -106,17 +109,15 @@ public class WorldEditPlayerListener extends PlayerListener {
|
|||||||
|
|
||||||
if (plugin.getWorldEdit().handleBlockRightClick(player, pos)) {
|
if (plugin.getWorldEdit().handleBlockRightClick(player, pos)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
} else if (plugin.getWorldEdit().handleRightClick(wrapPlayer(event.getPlayer()))) {
|
}
|
||||||
|
|
||||||
|
if (plugin.getWorldEdit().handleRightClick(wrapPlayer(event.getPlayer()))) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
} else if (event.getAction() == Action.RIGHT_CLICK_AIR) {
|
} else if (event.getAction() == Action.RIGHT_CLICK_AIR) {
|
||||||
if (plugin.getWorldEdit().handleRightClick(wrapPlayer(event.getPlayer()))) {
|
if (plugin.getWorldEdit().handleRightClick(wrapPlayer(event.getPlayer()))) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
} else if (event.getAction() == Action.LEFT_CLICK_AIR) {
|
|
||||||
if (plugin.getWorldEdit().handleLeftClick(wrapPlayer(event.getPlayer()))) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,4 +176,20 @@ public class ToolCommands {
|
|||||||
player.print("Floating tree remover tool bound to "
|
player.print("Floating tree remover tool bound to "
|
||||||
+ ItemType.toHeldName(player.getItemInHand()) + ".");
|
+ ItemType.toHeldName(player.getItemInHand()) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
aliases = {"farwand"},
|
||||||
|
usage = "",
|
||||||
|
desc = "Wand at a distance tool",
|
||||||
|
min = 0,
|
||||||
|
max = 0
|
||||||
|
)
|
||||||
|
@CommandPermissions({"worldedit.tool.farwand"})
|
||||||
|
public static void farwand(CommandContext args, WorldEdit we,
|
||||||
|
LocalSession session, LocalPlayer player, EditSession editSession)
|
||||||
|
throws WorldEditException {
|
||||||
|
|
||||||
|
session.setTool(player.getItemInHand(), new DistanceWand());
|
||||||
|
player.print("Far wand tool bound to " + ItemType.toHeldName(player.getItemInHand()) + ".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,8 @@ import com.sk89q.worldedit.tools.brushes.SphereBrush;
|
|||||||
* @author sk89q
|
* @author sk89q
|
||||||
*/
|
*/
|
||||||
public class BrushTool implements TraceTool {
|
public class BrushTool implements TraceTool {
|
||||||
private static int MAX_RANGE = 500;
|
protected static int MAX_RANGE = 500;
|
||||||
private int range = -1;
|
protected int range = -1;
|
||||||
private Mask mask = null;
|
private Mask mask = null;
|
||||||
private Brush brush = new SphereBrush();
|
private Brush brush = new SphereBrush();
|
||||||
private Pattern material = new SingleBlockPattern(new BaseBlock(BlockID.COBBLESTONE));
|
private Pattern material = new SingleBlockPattern(new BaseBlock(BlockID.COBBLESTONE));
|
||||||
@ -164,7 +164,7 @@ public class BrushTool implements TraceTool {
|
|||||||
* @param session
|
* @param session
|
||||||
* @return true to deny
|
* @return true to deny
|
||||||
*/
|
*/
|
||||||
public boolean act(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) {
|
if (this.range > -1) {
|
||||||
|
96
src/main/java/com/sk89q/worldedit/tools/DistanceWand.java
Normal file
96
src/main/java/com/sk89q/worldedit/tools/DistanceWand.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// $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.bags.BlockBag;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
|
import com.sk89q.worldedit.regions.RegionSelector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wand that can be used at a distance.
|
||||||
|
*
|
||||||
|
* @author wizjany
|
||||||
|
*/
|
||||||
|
public class DistanceWand extends BrushTool implements DoubleActionTraceTool {
|
||||||
|
|
||||||
|
public DistanceWand() {
|
||||||
|
super("worldedit.wand");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canUse(LocalPlayer player) {
|
||||||
|
return player.hasPermission("worldedit.wand");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean actSecondary(ServerInterface server, LocalConfiguration config,
|
||||||
|
LocalPlayer player, LocalSession session) {
|
||||||
|
if (session.isToolControlEnabled() && player.hasPermission("worldedit.selection.pos")) {
|
||||||
|
WorldVector target = getTarget(player);
|
||||||
|
if (target == null) return true;
|
||||||
|
|
||||||
|
RegionSelector selector = session.getRegionSelector(player.getWorld());
|
||||||
|
if (selector.selectPrimary(target)) {
|
||||||
|
selector.explainPrimarySelection(player, session, target);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean actPrimary(ServerInterface server, LocalConfiguration config,
|
||||||
|
LocalPlayer player, LocalSession session) {
|
||||||
|
if (session.isToolControlEnabled() && player.hasPermission("worldedit.selection.pos")) {
|
||||||
|
WorldVector target = getTarget(player);
|
||||||
|
if (target == null) return true;
|
||||||
|
|
||||||
|
RegionSelector selector = session.getRegionSelector(player.getWorld());
|
||||||
|
if (selector.selectSecondary(target)) {
|
||||||
|
selector.explainSecondarySelection(player, session, target);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WorldVector getTarget(LocalPlayer player) {
|
||||||
|
WorldVector target = null;
|
||||||
|
if (this.range > -1) {
|
||||||
|
target = player.getBlockTrace(getRange(), true);
|
||||||
|
} else {
|
||||||
|
target = player.getBlockTrace(MAX_RANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null) {
|
||||||
|
player.printError("No block in sight!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bug workaround
|
||||||
|
if (target.getBlockX() == 0 && target.getBlockY() == 0 && target.getBlockZ() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 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.LocalConfiguration;
|
||||||
|
import com.sk89q.worldedit.LocalPlayer;
|
||||||
|
import com.sk89q.worldedit.LocalSession;
|
||||||
|
import com.sk89q.worldedit.ServerInterface;
|
||||||
|
import com.sk89q.worldedit.WorldVector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a trace tool that also has a secondary/primary function.
|
||||||
|
*/
|
||||||
|
public interface DoubleActionTraceTool extends TraceTool {
|
||||||
|
/**
|
||||||
|
* Perform the secondary action. Should return true to deny the default
|
||||||
|
* action.
|
||||||
|
*
|
||||||
|
* @param server
|
||||||
|
* @param config
|
||||||
|
* @param player
|
||||||
|
* @param session
|
||||||
|
* @return true to deny
|
||||||
|
*/
|
||||||
|
public boolean actSecondary(ServerInterface server, LocalConfiguration config,
|
||||||
|
LocalPlayer player, LocalSession session);
|
||||||
|
}
|
@ -40,6 +40,6 @@ public interface TraceTool extends Tool {
|
|||||||
* @param session
|
* @param session
|
||||||
* @return true to deny
|
* @return true to deny
|
||||||
*/
|
*/
|
||||||
public boolean act(ServerInterface server, LocalConfiguration config,
|
public boolean actPrimary(ServerInterface server, LocalConfiguration config,
|
||||||
LocalPlayer player, LocalSession session);
|
LocalPlayer player, LocalSession session);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user