New "setcorners" command to set border based on corner coordinates: /wb [world] setcorners <x1> <z1> <x2> <z2>

This is useful now that border shapes can be rectangular/elliptical with different X and Z radius values.

Also various cleanup of new rectangular/elliptical support. Commands can now accept a single radius value (as it used to) or separate X and Z. Radius is displayed as single number if X and Z are equal. "shape" and "wshape" commands accept round|square as before for backwards compatibility and simplicity, alongside the new elliptical|rectangular (which work the same). Updated config loader to support loading older configs with single radius value specified. Added various other methods for backwards compatibility.
This commit is contained in:
Brettflan 2013-03-29 17:32:21 -05:00
parent 103d9941be
commit d2f0f407c2
5 changed files with 203 additions and 101 deletions

View File

@ -30,13 +30,21 @@ public class BorderData
public BorderData(double x, double z, int radiusX, int radiusZ) public BorderData(double x, double z, int radiusX, int radiusZ)
{ {
setData(x, z, radiusX, radiusZ , null); setData(x, z, radiusX, radiusZ, null);
} }
public BorderData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound) public BorderData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound)
{ {
setData(x, z, radiusX, radiusZ, shapeRound); setData(x, z, radiusX, radiusZ, shapeRound);
} }
public BorderData(double x, double z, int radius)
{
setData(x, z, radius, null);
}
public BorderData(double x, double z, int radius, Boolean shapeRound)
{
setData(x, z, radius, shapeRound);
}
public final void setData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound) public final void setData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound)
{ {
this.x = x; this.x = x;
@ -45,6 +53,10 @@ public class BorderData
this.setRadiusX(radiusX); this.setRadiusX(radiusX);
this.setRadiusZ(radiusZ); this.setRadiusZ(radiusZ);
} }
public final void setData(double x, double z, int radius, Boolean shapeRound)
{
setData(x, z, radius, radius, shapeRound);
}
public BorderData copy() public BorderData copy()
{ {
@ -98,6 +110,23 @@ public class BorderData
this.DefiniteRectangleZ = Math.sqrt(.5 * this.radiusZSquared); this.DefiniteRectangleZ = Math.sqrt(.5 * this.radiusZSquared);
} }
// backwards-compatible methods from before elliptical/rectangular shapes were supported
/**
* @deprecated Replaced by {@link #getRadiusX()} and {@link #getRadiusZ()};
* this method now returns an average of those two values and is thus imprecise
*/
public int getRadius()
{
return (radiusX + radiusZ) / 2; // average radius; not great, but probably best for backwards compatibility
}
public void setRadius(int radius)
{
setRadiusX(radius);
setRadiusZ(radius);
}
public Boolean getShape() public Boolean getShape()
{ {
return shapeRound; return shapeRound;
@ -110,7 +139,7 @@ public class BorderData
@Override @Override
public String toString() public String toString()
{ {
return "radius " + radiusX + "-" + radiusZ + " at X: " + Config.coord.format(x) + " Z: " + Config.coord.format(z) + (shapeRound != null ? (" (shape override: " + (shapeRound.booleanValue() ? "round" : "square") + ")") : ""); return "radius " + ((radiusX == radiusZ) ? radiusX : radiusX + "x" + radiusZ) + " at X: " + Config.coord.format(x) + " Z: " + Config.coord.format(z) + (shapeRound != null ? (" (shape override: " + Config.ShapeName(shapeRound.booleanValue()) + ")") : "");
} }
// This algorithm of course needs to be fast, since it will be run very frequently // This algorithm of course needs to be fast, since it will be run very frequently
@ -133,7 +162,7 @@ public class BorderData
if (X < DefiniteRectangleX && Z < DefiniteRectangleZ) if (X < DefiniteRectangleX && Z < DefiniteRectangleZ)
return true; // Definitely inside return true; // Definitely inside
else if (X >= radiusX || Z >= radiusZ) //I'm not sure about this one...the chance that a player is totally outside the rectangle around the ellipse is only given if he teleports, and that shouldn't be that frequently else if (X >= radiusX || Z >= radiusZ)
return false; // Definitely outside return false; // Definitely outside
else if (X * X + Z * Z * radiusSquaredQuotient < radiusXSquared) else if (X * X + Z * Z * radiusSquaredQuotient < radiusXSquared)
return true; // After further calculation, inside return true; // After further calculation, inside
@ -176,14 +205,9 @@ public class BorderData
// round border // round border
else else
{ {
// algorithm from: http://stackoverflow.com/questions/300871/best-way-to-find-a-point-on-a-circle-closest-to-a-given-point // algorithm originally from: http://stackoverflow.com/questions/300871/best-way-to-find-a-point-on-a-circle-closest-to-a-given-point
//double vX = xLoc - x; // modified by Lang Lukas to support elliptical border shape
//double vZ = zLoc - z;
//double magV = Math.sqrt(vX*vX / radiusXSquared + vZ*vZ / radiusZSquared);
//xLoc = x + vX / (radiusX * magV) * (radiusX - Config.KnockBack());
//zLoc = z + vZ / (radiusZ * magV) * (radiusZ - Config.KnockBack());
//Transform the ellipse to a circle with radius 1 (we need to transform the point the same way) //Transform the ellipse to a circle with radius 1 (we need to transform the point the same way)
double dX = xLoc - x; double dX = xLoc - x;
double dZ = zLoc - z; double dZ = zLoc - z;
@ -192,7 +216,6 @@ public class BorderData
double f = (1 / dT - Config.KnockBack() / dU); //"correction" factor for the distances double f = (1 / dT - Config.KnockBack() / dU); //"correction" factor for the distances
xLoc = x + dX * f; xLoc = x + dX * f;
zLoc = z + dZ * f; zLoc = z + dZ * f;
} }
int ixLoc = Location.locToBlock(xLoc); int ixLoc = Location.locToBlock(xLoc);
@ -279,6 +302,6 @@ public class BorderData
@Override @Override
public int hashCode() public int hashCode()
{ {
return (((int)(this.x * 10) << 4) + (int)this.z + (this.radiusX << 2)); return (((int)(this.x * 10) << 4) + (int)this.z + (this.radiusX << 2) + (this.radiusZ << 3));
} }
} }

View File

@ -49,6 +49,7 @@ public class Config
return System.currentTimeMillis(); return System.currentTimeMillis();
} }
public static void setBorder(String world, BorderData border) public static void setBorder(String world, BorderData border)
{ {
borders.put(world, border); borders.put(world, border);
@ -56,7 +57,7 @@ public class Config
save(true); save(true);
DynMapFeatures.showBorder(world, border); DynMapFeatures.showBorder(world, border);
} }
public static void setBorder(String world, int radiusX, int radiusZ, double x, double z, Boolean shapeRound) public static void setBorder(String world, int radiusX, int radiusZ, double x, double z, Boolean shapeRound)
{ {
setBorder(world, new BorderData(x, z, radiusX, radiusZ, shapeRound)); setBorder(world, new BorderData(x, z, radiusX, radiusZ, shapeRound));
@ -68,6 +69,35 @@ public class Config
setBorder(world, new BorderData(x, z, radiusX, radiusZ, oldShape)); setBorder(world, new BorderData(x, z, radiusX, radiusZ, oldShape));
} }
// backwards-compatible methods from before elliptical/rectangular shapes were supported
public static void setBorder(String world, int radius, double x, double z, Boolean shapeRound)
{
setBorder(world, new BorderData(x, z, radius, radius, shapeRound));
}
public static void setBorder(String world, int radius, double x, double z)
{
setBorder(world, radius, radius, x, z);
}
// set border based on corner coordinates
public static void setBorderCorners(String world, double x1, double z1, double x2, double z2, Boolean shapeRound)
{
double radiusX = Math.abs(x1 - x2) / 2;
double radiusZ = Math.abs(z1 - z2) / 2;
double x = ((x1 < x2) ? x1 : x2) + radiusX;
double z = ((z1 < z2) ? z1 : z2) + radiusZ;
setBorder(world, new BorderData(x, z, (int)Math.round(radiusX), (int)Math.round(radiusZ), shapeRound));
}
public static void setBorderCorners(String world, double x1, double z1, double x2, double z2)
{
BorderData old = Border(world);
Boolean oldShape = (old == null) ? null : old.getShape();
setBorderCorners(world, x1, z1, x2, z2, oldShape);
}
public static void removeBorder(String world) public static void removeBorder(String world)
{ {
borders.remove(world); borders.remove(world);
@ -131,7 +161,7 @@ public class Config
public static void setShape(boolean round) public static void setShape(boolean round)
{ {
shapeRound = round; shapeRound = round;
Log("Set default border shape to " + (round ? "elliptic" : "rectangular") + "."); Log("Set default border shape to " + (ShapeName()) + ".");
save(true); save(true);
DynMapFeatures.showAllBorders(); DynMapFeatures.showAllBorders();
} }
@ -141,6 +171,15 @@ public class Config
return shapeRound; return shapeRound;
} }
public static String ShapeName()
{
return ShapeName(shapeRound);
}
public static String ShapeName(boolean round)
{
return round ? "elliptic/round" : "rectangular/square";
}
public static void setDebug(boolean debugMode) public static void setDebug(boolean debugMode)
{ {
DEBUG = debugMode; DEBUG = debugMode;
@ -343,7 +382,7 @@ public class Config
} }
private static final int currentCfgVersion = 5; private static final int currentCfgVersion = 6;
public static void load(WorldBorder master, boolean logIt) public static void load(WorldBorder master, boolean logIt)
{ // load config from file { // load config from file
@ -362,7 +401,7 @@ public class Config
timerTicks = cfg.getInt("timer-delay-ticks", 5); timerTicks = cfg.getInt("timer-delay-ticks", 5);
dynmapEnable = cfg.getBoolean("dynmap-border-enabled", true); dynmapEnable = cfg.getBoolean("dynmap-border-enabled", true);
dynmapMessage = cfg.getString("dynmap-border-message", "The border of the world."); dynmapMessage = cfg.getString("dynmap-border-message", "The border of the world.");
LogConfig("Using " + (shapeRound ? "elliptic" : "rectangular") + " border, knockback of " + knockBack + " blocks, and timer delay of " + timerTicks + "."); LogConfig("Using " + (ShapeName()) + " border, knockback of " + knockBack + " blocks, and timer delay of " + timerTicks + ".");
StartBorderTimer(); StartBorderTimer();
@ -389,6 +428,14 @@ public class Config
if (cfgVersion > 3) if (cfgVersion > 3)
worldName = worldName.replace("<", "."); worldName = worldName.replace("<", ".");
// backwards compatibility for config from before elliptical/rectangular borders were supported
if (bord.isSet("radius") && !bord.isSet("radiusX"))
{
int radius = bord.getInt("radius");
bord.set("radiusX", radius);
bord.set("radiusZ", radius);
}
Boolean overrideShape = (Boolean) bord.get("shape-round"); Boolean overrideShape = (Boolean) bord.get("shape-round");
BorderData border = new BorderData(bord.getDouble("x", 0), bord.getDouble("z", 0), bord.getInt("radiusX", 0), bord.getInt("radiusZ", 0), overrideShape); BorderData border = new BorderData(bord.getDouble("x", 0), bord.getDouble("z", 0), bord.getInt("radiusX", 0), bord.getInt("radiusZ", 0), overrideShape);
borders.put(worldName, border); borders.put(worldName, border);

View File

@ -71,7 +71,7 @@ public class WBCommand implements CommandExecutor
} }
// "set" command from player or console, world specified // "set" command from player or console, world specified
if (split.length == 6 && split[1].equalsIgnoreCase("set")) if ((split.length == 5 || split.length == 6) && split[1].equalsIgnoreCase("set"))
{ {
if (!Config.HasPermission(player, "set")) return true; if (!Config.HasPermission(player, "set")) return true;
@ -79,23 +79,23 @@ public class WBCommand implements CommandExecutor
if (world == null) if (world == null)
sender.sendMessage("The world you specified (\"" + split[0] + "\") could not be found on the server, but data for it will be stored anyway."); sender.sendMessage("The world you specified (\"" + split[0] + "\") could not be found on the server, but data for it will be stored anyway.");
if(cmdSet(sender, split[0], split, 2) && player != null) if(cmdSet(sender, split[0], split, 2, (split.length == 5)) && player != null)
sender.sendMessage("Border has been set. " + Config.BorderDescription(split[0])); sender.sendMessage("Border has been set. " + Config.BorderDescription(split[0]));
} }
// "set" command from player, using current world, X and Z specified // "set" command from player, using current world, X and Z specified
else if (split.length == 5 && split[0].equalsIgnoreCase("set") && player != null) else if ((split.length == 4 || split.length == 5) && split[0].equalsIgnoreCase("set") && player != null)
{ {
if (!Config.HasPermission(player, "set")) return true; if (!Config.HasPermission(player, "set")) return true;
String world = player.getWorld().getName(); String world = player.getWorld().getName();
if (cmdSet(sender, world, split, 1)) if (cmdSet(sender, world, split, 1, (split.length == 4)))
sender.sendMessage("Border has been set. " + Config.BorderDescription(world)); sender.sendMessage("Border has been set. " + Config.BorderDescription(world));
} }
// "set" command from player, using current world, X and Z NOT specified // "set" command from player, using current world, X and Z NOT specified
else if (split.length == 3 && split[0].equalsIgnoreCase("set") && player != null) else if ((split.length == 2 || split.length == 3) && split[0].equalsIgnoreCase("set") && player != null)
{ {
if (!Config.HasPermission(player, "set")) return true; if (!Config.HasPermission(player, "set")) return true;
@ -108,11 +108,14 @@ public class WBCommand implements CommandExecutor
try try
{ {
radiusX = Integer.parseInt(split[1]); radiusX = Integer.parseInt(split[1]);
radiusZ = Integer.parseInt(split[2]); if (split.length == 3)
radiusZ = Integer.parseInt(split[2]);
else
radiusZ = radiusX;
} }
catch(NumberFormatException ex) catch(NumberFormatException ex)
{ {
sender.sendMessage(clrErr + "The radius values must be integers."); sender.sendMessage(clrErr + "The radius value(s) must be integers.");
return true; return true;
} }
@ -120,8 +123,60 @@ public class WBCommand implements CommandExecutor
sender.sendMessage("Border has been set. " + Config.BorderDescription(world)); sender.sendMessage("Border has been set. " + Config.BorderDescription(world));
} }
// "setcorners" command from player or console, world specified
else if (split.length == 6 && split[1].equalsIgnoreCase("setcorners"))
{
if (!Config.HasPermission(player, "set")) return true;
String world = split[0];
World worldTest = sender.getServer().getWorld(world);
if (worldTest == null)
sender.sendMessage("The world you specified (\"" + world + "\") could not be found on the server, but data for it will be stored anyway.");
try
{
double x1 = Double.parseDouble(split[2]);
double z1 = Double.parseDouble(split[3]);
double x2 = Double.parseDouble(split[4]);
double z2 = Double.parseDouble(split[5]);
Config.setBorderCorners(world, x1, z1, x2, z2);
}
catch(NumberFormatException ex)
{
sender.sendMessage(clrErr + "The x1, z1, x2, and z2 values must be numerical.");
return true;
}
if(player != null)
sender.sendMessage("Border has been set. " + Config.BorderDescription(world));
}
// "setcorners" command from player, using current world
else if (split.length == 5 && split[0].equalsIgnoreCase("setcorners") && player != null)
{
if (!Config.HasPermission(player, "set")) return true;
String world = player.getWorld().getName();
try
{
double x1 = Double.parseDouble(split[1]);
double z1 = Double.parseDouble(split[2]);
double x2 = Double.parseDouble(split[3]);
double z2 = Double.parseDouble(split[4]);
Config.setBorderCorners(world, x1, z1, x2, z2);
}
catch(NumberFormatException ex)
{
sender.sendMessage(clrErr + "The x1, z1, x2, and z2 values must be numerical.");
return true;
}
sender.sendMessage("Border has been set. " + Config.BorderDescription(world));
}
// "radius" command from player or console, world specified // "radius" command from player or console, world specified
else if (split.length == 4 && split[1].equalsIgnoreCase("radius")) else if ((split.length == 3 || split.length == 4) && split[1].equalsIgnoreCase("radius"))
{ {
if (!Config.HasPermission(player, "radius")) return true; if (!Config.HasPermission(player, "radius")) return true;
@ -141,11 +196,14 @@ public class WBCommand implements CommandExecutor
try try
{ {
radiusX = Integer.parseInt(split[2]); radiusX = Integer.parseInt(split[2]);
radiusZ = Integer.parseInt(split[3]); if (split.length == 4)
radiusZ = Integer.parseInt(split[3]);
else
radiusZ = radiusX;
} }
catch(NumberFormatException ex) catch(NumberFormatException ex)
{ {
sender.sendMessage(clrErr + "The radius values must be integers."); sender.sendMessage(clrErr + "The radius value(s) must be integers.");
return true; return true;
} }
@ -156,7 +214,7 @@ public class WBCommand implements CommandExecutor
} }
// "radius" command from player, using current world // "radius" command from player, using current world
else if (split.length == 3 && split[0].equalsIgnoreCase("radius") && player != null) else if ((split.length == 2 || split.length == 3) && split[0].equalsIgnoreCase("radius") && player != null)
{ {
if (!Config.HasPermission(player, "radius")) return true; if (!Config.HasPermission(player, "radius")) return true;
@ -175,12 +233,15 @@ public class WBCommand implements CommandExecutor
int radiusZ; int radiusZ;
try try
{ {
radiusX = Integer.parseInt(split[2]); radiusX = Integer.parseInt(split[1]);
radiusZ = Integer.parseInt(split[3]); if (split.length == 3)
radiusZ = Integer.parseInt(split[2]);
else
radiusZ = radiusX;
} }
catch(NumberFormatException ex) catch(NumberFormatException ex)
{ {
sender.sendMessage(clrErr + "The radius values must be integers."); sender.sendMessage(clrErr + "The radius value(s) must be integers.");
return true; return true;
} }
@ -240,7 +301,7 @@ public class WBCommand implements CommandExecutor
{ {
if (!Config.HasPermission(player, "list")) return true; if (!Config.HasPermission(player, "list")) return true;
sender.sendMessage("Default border shape for all worlds is \"" + (Config.ShapeRound() ? "elliptic" : "rectangular") + "\"."); sender.sendMessage("Default border shape for all worlds is \"" + Config.ShapeName() + "\".");
Set<String> list = Config.BorderDescriptions(); Set<String> list = Config.BorderDescriptions();
@ -262,18 +323,18 @@ public class WBCommand implements CommandExecutor
{ {
if (!Config.HasPermission(player, "shape")) return true; if (!Config.HasPermission(player, "shape")) return true;
if (split[1].equalsIgnoreCase("rectangular")) if (split[1].equalsIgnoreCase("rectangular") || split[1].equalsIgnoreCase("square"))
Config.setShape(false); Config.setShape(false);
else if (split[1].equalsIgnoreCase("elliptic")) else if (split[1].equalsIgnoreCase("elliptic") || split[1].equalsIgnoreCase("round"))
Config.setShape(true); Config.setShape(true);
else else
{ {
sender.sendMessage("You must specify a shape of \"elliptic\" or \"rectangular\"."); sender.sendMessage("You must specify a shape of \"elliptic\"/\"round\" or \"rectangular\"/\"square\".");
return true; return true;
} }
if (player != null) if (player != null)
sender.sendMessage("Default border shape for all worlds is now set to \"" + (Config.ShapeRound() ? "elliptic" : "rectangular") + "\"."); sender.sendMessage("Default border shape for all worlds is now set to \"" + Config.ShapeName() + "\".");
} }
// "getmsg" command from player or console // "getmsg" command from player or console
@ -418,16 +479,16 @@ public class WBCommand implements CommandExecutor
} }
Boolean shape = null; Boolean shape = null;
if (split[2].equalsIgnoreCase("rectangular")) if (split[2].equalsIgnoreCase("rectangular") || split[2].equalsIgnoreCase("square"))
shape = false; shape = false;
else if (split[2].equalsIgnoreCase("elliptic")) else if (split[2].equalsIgnoreCase("elliptic") || split[2].equalsIgnoreCase("round"))
shape = true; shape = true;
border.setShape(shape); border.setShape(shape);
Config.setBorder(world, border); Config.setBorder(world, border);
if (player != null) if (player != null)
sender.sendMessage("Border shape for world \"" + world + "\" is now set to \"" + (shape == null ? "default" : (shape.booleanValue() ? "elliptic" : "rectangular")) + "\"."); sender.sendMessage("Border shape for world \"" + world + "\" is now set to \"" + (shape == null ? "default" : Config.ShapeName(shape.booleanValue())) + "\".");
} }
// "wshape" command from player, using current world // "wshape" command from player, using current world
@ -444,15 +505,15 @@ public class WBCommand implements CommandExecutor
} }
Boolean shape = null; Boolean shape = null;
if (split[1].equalsIgnoreCase("rectangular")) if (split[1].equalsIgnoreCase("rectangular") || split[1].equalsIgnoreCase("square"))
shape = false; shape = false;
else if (split[1].equalsIgnoreCase("elliptic")) else if (split[1].equalsIgnoreCase("elliptic") || split[1].equalsIgnoreCase("round"))
shape = true; shape = true;
border.setShape(shape); border.setShape(shape);
Config.setBorder(world, border); Config.setBorder(world, border);
sender.sendMessage("Border shape for world \"" + world + "\" is now set to \"" + (shape == null ? "default" : (shape.booleanValue() ? "elliptic" : "rectangular")) + "\"."); sender.sendMessage("Border shape for world \"" + world + "\" is now set to \"" + (shape == null ? "default" : Config.ShapeName(shape.booleanValue())) + "\".");
} }
// "fill" command from player or console, world specified // "fill" command from player or console, world specified
@ -658,32 +719,35 @@ public class WBCommand implements CommandExecutor
if (page == 0 || page == 1) if (page == 0 || page == 1)
{ {
if (player != null) if (player != null)
sender.sendMessage(cmd+" set " + clrReq + "<radiusX> <radiusZ>" + clrDesc + " - set world border, centered on you."); sender.sendMessage(cmd+" set " + clrReq + "<radiusX> " + clrOpt + "[radiusZ]" + clrDesc + " - set border, centered on you.");
sender.sendMessage(cmdW+" set " + clrReq + "<radiusX> <radiusZ> <x> <z>" + clrDesc + " - set world border."); sender.sendMessage(cmdW+" set " + clrReq + "<radiusX> " + clrOpt + "[radiusZ] <x> <z>" + clrDesc + " - set border.");
sender.sendMessage(cmdW+" radius " + clrReq + "<radiusX> <radiusZ>" + clrDesc + " - change a border radius."); sender.sendMessage(cmdW+" setcorners " + clrReq + "<x1> <z1> <x2> <z2>" + clrDesc + " - set by corners.");
sender.sendMessage(cmdW+" radius " + clrReq + "<radiusX> " + clrOpt + "[radiusZ]" + clrDesc + " - change radius.");
sender.sendMessage(cmdW+" clear" + clrDesc + " - remove border for this world."); sender.sendMessage(cmdW+" clear" + clrDesc + " - remove border for this world.");
sender.sendMessage(cmd+" clear all" + clrDesc + " - remove border for all worlds."); sender.sendMessage(cmd+" clear all" + clrDesc + " - remove border for all worlds.");
sender.sendMessage(cmd+" list" + clrDesc + " - show border information for all worlds."); sender.sendMessage(cmd+" shape " + clrReq + "<elliptic|rectangular>" + clrDesc + " - set the default shape.");
sender.sendMessage(cmd+" shape " + clrReq + "<elliptic|rectangular>" + clrDesc + " - set the default border shape."); sender.sendMessage(cmd+" shape " + clrReq + "<round|square>" + clrDesc + " - same as above.");
sender.sendMessage(cmd+" knockback " + clrReq + "<distance>" + clrDesc + " - how far to move the player back.");
if (page == 1) if (page == 1)
sender.sendMessage(cmd+" 2" + clrDesc + " - view second page of commands."); sender.sendMessage(cmd+" 2" + clrDesc + " - view second page of commands.");
} }
if (page == 0 || page == 2) if (page == 0 || page == 2)
{ {
sender.sendMessage(cmd+" list" + clrDesc + " - show border information for all worlds.");
sender.sendMessage(cmdW+" fill " + clrOpt + "[freq] [pad]" + clrDesc + " - generate world out to border."); sender.sendMessage(cmdW+" fill " + clrOpt + "[freq] [pad]" + clrDesc + " - generate world out to border.");
sender.sendMessage(cmdW+" trim " + clrOpt + "[freq] [pad]" + clrDesc + " - trim world outside of border."); sender.sendMessage(cmdW+" trim " + clrOpt + "[freq] [pad]" + clrDesc + " - trim world outside of border.");
sender.sendMessage(cmd+" bypass " + ((player == null) ? clrReq + "<player>" : clrOpt + "[player]") + clrOpt + " [on/off]" + clrDesc + " - let player go beyond border."); sender.sendMessage(cmd+" bypass " + ((player == null) ? clrReq + "<player>" : clrOpt + "[player]") + clrOpt + " [on/off]" + clrDesc + " - let player go beyond border.");
sender.sendMessage(cmd+" wshape " + ((player == null) ? clrReq + "<world>" : clrOpt + "[world]") + clrReq + " <elliptic|rectangular|default>" + clrDesc + " - shape override."); sender.sendMessage(cmd+" wshape " + ((player == null) ? clrReq + "<world>" : clrOpt + "[world]") + clrReq + " <elliptic|rectangular|default>" + clrDesc + " - shape override for this world.");
sender.sendMessage(cmd+" getmsg" + clrDesc + " - display border message."); sender.sendMessage(cmd+" wshape " + ((player == null) ? clrReq + "<world>" : clrOpt + "[world]") + clrReq + " <round|square|default>" + clrDesc + " - same as above.");
sender.sendMessage(cmd+" setmsg " + clrReq + "<text>" + clrDesc + " - set border message.");
sender.sendMessage(cmd+" whoosh " + clrReq + "<on|off>" + clrDesc + " - turn knockback effect on or off."); sender.sendMessage(cmd+" whoosh " + clrReq + "<on|off>" + clrDesc + " - turn knockback effect on or off.");
sender.sendMessage(cmd+" delay " + clrReq + "<amount>" + clrDesc + " - time between border checks.");
if (page == 2) if (page == 2)
sender.sendMessage(cmd+" 3" + clrDesc + " - view third page of commands."); sender.sendMessage(cmd+" 3" + clrDesc + " - view third page of commands.");
} }
if (page == 0 || page == 3) if (page == 0 || page == 3)
{ {
sender.sendMessage(cmd+" getmsg" + clrDesc + " - display border message.");
sender.sendMessage(cmd+" setmsg " + clrReq + "<text>" + clrDesc + " - set border message.");
sender.sendMessage(cmd+" knockback " + clrReq + "<distance>" + clrDesc + " - how far to move the player back.");
sender.sendMessage(cmd+" delay " + clrReq + "<amount>" + clrDesc + " - time between border checks.");
sender.sendMessage(cmd+" reload" + clrDesc + " - re-load data from config.yml."); sender.sendMessage(cmd+" reload" + clrDesc + " - re-load data from config.yml.");
sender.sendMessage(cmd+" dynmap " + clrReq + "<on|off>" + clrDesc + " - turn DynMap border display on or off."); sender.sendMessage(cmd+" dynmap " + clrReq + "<on|off>" + clrDesc + " - turn DynMap border display on or off.");
sender.sendMessage(cmd+" dynmapmsg " + clrReq + "<text>" + clrDesc + " - DynMap border labels will show this."); sender.sendMessage(cmd+" dynmapmsg " + clrReq + "<text>" + clrDesc + " - DynMap border labels will show this.");
@ -712,20 +776,27 @@ public class WBCommand implements CommandExecutor
return enabled ? clrReq+"enabled" : clrErr+"disabled"; return enabled ? clrReq+"enabled" : clrErr+"disabled";
} }
private boolean cmdSet(CommandSender sender, String world, String[] data, int offset) private boolean cmdSet(CommandSender sender, String world, String[] data, int offset, boolean oneRadius)
{ {
int radiusX, radiusZ; int radiusX, radiusZ;
double x, z; double x, z;
try try
{ {
radiusX = Integer.parseInt(data[offset]); radiusX = Integer.parseInt(data[offset]);
radiusZ = Integer.parseInt(data[offset+1]); if (oneRadius)
{
radiusZ = radiusX;
offset -= 1;
}
else
radiusZ = Integer.parseInt(data[offset+1]);
x = Double.parseDouble(data[offset+2]); x = Double.parseDouble(data[offset+2]);
z = Double.parseDouble(data[offset+3]); z = Double.parseDouble(data[offset+3]);
} }
catch(NumberFormatException ex) catch(NumberFormatException ex)
{ {
sender.sendMessage(clrErr + "The radius values must be integers and the x and z values must be numerical."); sender.sendMessage(clrErr + "The radius value(s) must be integers and the x and z values must be numerical.");
return false; return false;
} }

View File

@ -11,19 +11,22 @@ commands:
aliases: [worldborder, wb] aliases: [worldborder, wb]
usage: | usage: |
/<command> - list available commands (show help). /<command> - list available commands (show help).
/<command> set <radiusX> <radiusY> - set world border, centered on you. /<command> set <radiusX> [radiusZ] - set world border, centered on you.
/<command> [world] set <radiusX> <radiusZ> <x> <z> - set world border. /<command> [world] set <radiusX> [radiusZ] <x> <z> - set world border.
/<command> [world] radius <radiusX> <radiusZ> - change world's border radius. /<command> [world] setcorners <x1> <z1> <x2> <z2> - set border from corners.
/<command> [world] radius <radiusX> [radiusZ] - change border's radius.
/<command> [world] clear - remove border for this world. /<command> [world] clear - remove border for this world.
/<command> clear all - remove border for all worlds. /<command> clear all - remove border for all worlds.
/<command> list - show border information for all worlds. /<command> list - show border information for all worlds.
/<command> shape <elliptic|rectangular> - set the default border shape. /<command> shape <elliptic|rectangular> - set the default border shape.
/<command> shape <round|square> - same as above, backwards compatible.
/<command> getmsg - display border message. /<command> getmsg - display border message.
/<command> setmsg <text> - set border message. /<command> setmsg <text> - set border message.
/<command> knockback <distance> - how far to move the player back. /<command> knockback <distance> - how far to move the player back.
/<command> whoosh <on/off> - turn knockback effect on or off. /<command> whoosh <on/off> - turn knockback effect on or off.
/<command> delay <amount> - time between border checks. /<command> delay <amount> - time between border checks.
/<command> wshape [world] <elliptic|rectangular|default> - override shape. /<command> wshape [world] <elliptic|rectangular|default> - override shape.
/<command> wshape [world] <round|square|default> - same as above values.
/<command> [world] fill [freq] [pad] - generate world out to border. /<command> [world] fill [freq] [pad] - generate world out to border.
/<command> [world] trim [freq] [pad] - trim world outside of border. /<command> [world] trim [freq] [pad] - trim world outside of border.
/<command> bypass [player] [on/off] - let player go beyond border. /<command> bypass [player] [on/off] - let player go beyond border.

View File

@ -1,42 +0,0 @@
The things I changed (I hope I didn't forget anything)
plugin.yml:
changed the help (<radius> --> <radiusX> <radiusZ>)
BorderCheckTask.java:
nothing
BorderData.java:
added variable radiusZ and renamed radius to radiusX
changed the "handy data for borderChecks"
adapted constructors to accept to radius-values
added set-/getRadiusZ
adapted toString function (it outputs "radiusX-radiusZ", I'm sure there a clearer way)
changed the inside-border-check procedure for the ellipse (I added a comment, explaining why I think you could remove one check)
changed the procedure that calculates the point inside the border the player need to be teleported to
adapted the equals function
adapted the hashCode function (not sure about this one, maybe you could improve it)
Config.java
adapted the setBorder function to accept both radius-values
adapted config-messages (round --> elliptic...)
adapted the config-file-to-border function
adapted the save procedure
CoordXZ.java:
nothing
DynMapFeatures.java:
adapted the showSquareBorder/showRoundBorder
WBCommand.java:
changed all the commands to accept one parameter more (you always have to enter two values)
changed the names of the shapes to rectangular and elliptic
adapted the help (<radius> --> <radiusX> <radiusZ>)
adapted the error messages to speak of two radius-values
WBListener.java:
nothing
WorldBorder.java:
nothing
WorldFileData.java:
nothing
WorldFillTask.java:
adapted calculation of the toFillBorder
changed calculation of reportTarget
added proposal for different method to calculate reportTarget
WorldTrimTask.java:
adapted calculation of the toTrimBorder