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)
{
setData(x, z, radiusX, radiusZ , null);
setData(x, z, radiusX, radiusZ, null);
}
public BorderData(double x, double z, int radiusX, int radiusZ, Boolean 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)
{
this.x = x;
@ -45,6 +53,10 @@ public class BorderData
this.setRadiusX(radiusX);
this.setRadiusZ(radiusZ);
}
public final void setData(double x, double z, int radius, Boolean shapeRound)
{
setData(x, z, radius, radius, shapeRound);
}
public BorderData copy()
{
@ -98,6 +110,23 @@ public class BorderData
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()
{
return shapeRound;
@ -110,7 +139,7 @@ public class BorderData
@Override
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
@ -133,7 +162,7 @@ public class BorderData
if (X < DefiniteRectangleX && Z < DefiniteRectangleZ)
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
else if (X * X + Z * Z * radiusSquaredQuotient < radiusXSquared)
return true; // After further calculation, inside
@ -176,14 +205,9 @@ public class BorderData
// round border
else
{
// algorithm from: http://stackoverflow.com/questions/300871/best-way-to-find-a-point-on-a-circle-closest-to-a-given-point
//double vX = xLoc - x;
//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());
// algorithm originally from: http://stackoverflow.com/questions/300871/best-way-to-find-a-point-on-a-circle-closest-to-a-given-point
// modified by Lang Lukas to support elliptical border shape
//Transform the ellipse to a circle with radius 1 (we need to transform the point the same way)
double dX = xLoc - x;
double dZ = zLoc - z;
@ -192,7 +216,6 @@ public class BorderData
double f = (1 / dT - Config.KnockBack() / dU); //"correction" factor for the distances
xLoc = x + dX * f;
zLoc = z + dZ * f;
}
int ixLoc = Location.locToBlock(xLoc);
@ -279,6 +302,6 @@ public class BorderData
@Override
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();
}
public static void setBorder(String world, BorderData border)
{
borders.put(world, border);
@ -56,7 +57,7 @@ public class Config
save(true);
DynMapFeatures.showBorder(world, border);
}
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));
@ -68,6 +69,35 @@ public class Config
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)
{
borders.remove(world);
@ -131,7 +161,7 @@ public class Config
public static void setShape(boolean round)
{
shapeRound = round;
Log("Set default border shape to " + (round ? "elliptic" : "rectangular") + ".");
Log("Set default border shape to " + (ShapeName()) + ".");
save(true);
DynMapFeatures.showAllBorders();
}
@ -141,6 +171,15 @@ public class Config
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)
{
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)
{ // load config from file
@ -362,7 +401,7 @@ public class Config
timerTicks = cfg.getInt("timer-delay-ticks", 5);
dynmapEnable = cfg.getBoolean("dynmap-border-enabled", true);
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();
@ -389,6 +428,14 @@ public class Config
if (cfgVersion > 3)
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");
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);

View File

@ -71,7 +71,7 @@ public class WBCommand implements CommandExecutor
}
// "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;
@ -79,23 +79,23 @@ public class WBCommand implements CommandExecutor
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.");
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]));
}
// "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;
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));
}
// "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;
@ -108,11 +108,14 @@ public class WBCommand implements CommandExecutor
try
{
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)
{
sender.sendMessage(clrErr + "The radius values must be integers.");
sender.sendMessage(clrErr + "The radius value(s) must be integers.");
return true;
}
@ -120,8 +123,60 @@ public class WBCommand implements CommandExecutor
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
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;
@ -141,11 +196,14 @@ public class WBCommand implements CommandExecutor
try
{
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)
{
sender.sendMessage(clrErr + "The radius values must be integers.");
sender.sendMessage(clrErr + "The radius value(s) must be integers.");
return true;
}
@ -156,7 +214,7 @@ public class WBCommand implements CommandExecutor
}
// "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;
@ -175,12 +233,15 @@ public class WBCommand implements CommandExecutor
int radiusZ;
try
{
radiusX = Integer.parseInt(split[2]);
radiusZ = Integer.parseInt(split[3]);
radiusX = Integer.parseInt(split[1]);
if (split.length == 3)
radiusZ = Integer.parseInt(split[2]);
else
radiusZ = radiusX;
}
catch(NumberFormatException ex)
{
sender.sendMessage(clrErr + "The radius values must be integers.");
sender.sendMessage(clrErr + "The radius value(s) must be integers.");
return true;
}
@ -240,7 +301,7 @@ public class WBCommand implements CommandExecutor
{
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();
@ -262,18 +323,18 @@ public class WBCommand implements CommandExecutor
{
if (!Config.HasPermission(player, "shape")) return true;
if (split[1].equalsIgnoreCase("rectangular"))
if (split[1].equalsIgnoreCase("rectangular") || split[1].equalsIgnoreCase("square"))
Config.setShape(false);
else if (split[1].equalsIgnoreCase("elliptic"))
else if (split[1].equalsIgnoreCase("elliptic") || split[1].equalsIgnoreCase("round"))
Config.setShape(true);
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;
}
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
@ -418,16 +479,16 @@ public class WBCommand implements CommandExecutor
}
Boolean shape = null;
if (split[2].equalsIgnoreCase("rectangular"))
if (split[2].equalsIgnoreCase("rectangular") || split[2].equalsIgnoreCase("square"))
shape = false;
else if (split[2].equalsIgnoreCase("elliptic"))
else if (split[2].equalsIgnoreCase("elliptic") || split[2].equalsIgnoreCase("round"))
shape = true;
border.setShape(shape);
Config.setBorder(world, border);
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
@ -444,15 +505,15 @@ public class WBCommand implements CommandExecutor
}
Boolean shape = null;
if (split[1].equalsIgnoreCase("rectangular"))
if (split[1].equalsIgnoreCase("rectangular") || split[1].equalsIgnoreCase("square"))
shape = false;
else if (split[1].equalsIgnoreCase("elliptic"))
else if (split[1].equalsIgnoreCase("elliptic") || split[1].equalsIgnoreCase("round"))
shape = true;
border.setShape(shape);
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
@ -658,32 +719,35 @@ public class WBCommand implements CommandExecutor
if (page == 0 || page == 1)
{
if (player != null)
sender.sendMessage(cmd+" set " + clrReq + "<radiusX> <radiusZ>" + clrDesc + " - set world border, centered on you.");
sender.sendMessage(cmdW+" set " + clrReq + "<radiusX> <radiusZ> <x> <z>" + clrDesc + " - set world border.");
sender.sendMessage(cmdW+" radius " + clrReq + "<radiusX> <radiusZ>" + clrDesc + " - change a border radius.");
sender.sendMessage(cmd+" set " + clrReq + "<radiusX> " + clrOpt + "[radiusZ]" + clrDesc + " - set border, centered on you.");
sender.sendMessage(cmdW+" set " + clrReq + "<radiusX> " + clrOpt + "[radiusZ] <x> <z>" + clrDesc + " - set border.");
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(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 border shape.");
sender.sendMessage(cmd+" knockback " + clrReq + "<distance>" + clrDesc + " - how far to move the player back.");
sender.sendMessage(cmd+" shape " + clrReq + "<elliptic|rectangular>" + clrDesc + " - set the default shape.");
sender.sendMessage(cmd+" shape " + clrReq + "<round|square>" + clrDesc + " - same as above.");
if (page == 1)
sender.sendMessage(cmd+" 2" + clrDesc + " - view second page of commands.");
}
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+" 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+" wshape " + ((player == null) ? clrReq + "<world>" : clrOpt + "[world]") + clrReq + " <elliptic|rectangular|default>" + clrDesc + " - shape override.");
sender.sendMessage(cmd+" getmsg" + clrDesc + " - display border message.");
sender.sendMessage(cmd+" setmsg " + clrReq + "<text>" + clrDesc + " - set border message.");
sender.sendMessage(cmd+" wshape " + ((player == null) ? clrReq + "<world>" : clrOpt + "[world]") + clrReq + " <elliptic|rectangular|default>" + clrDesc + " - shape override for this world.");
sender.sendMessage(cmd+" wshape " + ((player == null) ? clrReq + "<world>" : clrOpt + "[world]") + clrReq + " <round|square|default>" + clrDesc + " - same as above.");
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)
sender.sendMessage(cmd+" 3" + clrDesc + " - view third page of commands.");
}
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+" 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.");
@ -712,20 +776,27 @@ public class WBCommand implements CommandExecutor
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;
double x, z;
try
{
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]);
z = Double.parseDouble(data[offset+3]);
}
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;
}

View File

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