From 9f20fec34329b195aa594c776772fe703801b7e6 Mon Sep 17 00:00:00 2001 From: Pablo Herrera Date: Sat, 4 May 2024 18:01:15 +0200 Subject: [PATCH] Improve world border logic Signed-off-by: Pablo Herrera --- .../tc/oc/pgm/util/bukkit/WorldBorders.java | 65 +++++++++++-------- .../java/tc/oc/pgm/util/nms/NMSHacks.java | 4 ++ .../java/tc/oc/pgm/util/nms/NMSHacksNoOp.java | 5 ++ .../tc/oc/pgm/util/nms/NMSHacksPlatform.java | 2 + .../tc/oc/pgm/util/nms/v1_8/NMSHacks1_8.java | 5 ++ 5 files changed, 54 insertions(+), 27 deletions(-) diff --git a/util/src/main/java/tc/oc/pgm/util/bukkit/WorldBorders.java b/util/src/main/java/tc/oc/pgm/util/bukkit/WorldBorders.java index dd79e85ea4..8e680355b9 100644 --- a/util/src/main/java/tc/oc/pgm/util/bukkit/WorldBorders.java +++ b/util/src/main/java/tc/oc/pgm/util/bukkit/WorldBorders.java @@ -1,49 +1,60 @@ package tc.oc.pgm.util.bukkit; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.WorldBorder; +import org.bukkit.util.NumberConversions; +import tc.oc.pgm.util.nms.NMSHacks; -public interface WorldBorders { +public class WorldBorders { - static boolean isInsideBorder(Location location) { - WorldBorder border = location.getWorld().getWorldBorder(); - Location center = border.getCenter(); - double radius = border.getSize() / 2d; - return Math.abs(location.getX() - center.getX()) < radius - && Math.abs(location.getZ() - center.getZ()) < radius; + private WorldBorders() {} + + public static boolean isInsideBorder(Location location) { + BorderRect rect = new BorderRect(location.getWorld()); + return location.getBlockX() >= rect.xMin + && location.getBlockX() <= rect.xMax + && location.getBlockZ() >= rect.zMin + && location.getBlockZ() <= rect.zMax; } - static boolean clampToBorder(Location location) { - WorldBorder border = location.getWorld().getWorldBorder(); - Location center = border.getCenter(); - double radius = border.getSize() / 2d; - double xMin = center.getX() - radius; - double xMax = center.getX() + radius; - double zMin = center.getZ() - radius; - double zMax = center.getZ() + radius; + public static boolean clampToBorder(Location location) { + BorderRect rect = new BorderRect(location.getWorld()); boolean moved = false; - if (location.getX() < xMin) { - location.setX(xMin); + if (location.getX() <= rect.xMin) { + location.setX(rect.xMin + 0.5); moved = true; - } - - if (location.getX() > xMax) { - location.setX(xMax); + } else if (location.getX() >= rect.xMax) { + location.setX(rect.xMax - 0.5); moved = true; } - if (location.getZ() < zMin) { - location.setZ(zMin); + if (location.getZ() <= rect.zMin) { + location.setZ(rect.zMin + 0.5); moved = true; - } - - if (location.getZ() > zMax) { - location.setZ(zMax); + } else if (location.getZ() >= rect.zMax) { + location.setZ(rect.zMax - 0.5); moved = true; } return moved; } + + private static class BorderRect { + public final int xMin, xMax, zMin, zMax; + + public BorderRect(World world) { + WorldBorder border = world.getWorldBorder(); + Location center = border.getCenter(); + double radius = border.getSize() / 2d; + int maxWorldSize = NMSHacks.getMaxWorldSize(world); + + xMin = Math.max(NumberConversions.floor(center.getX() - radius), -maxWorldSize); + xMax = Math.min(NumberConversions.ceil(center.getX() + radius), maxWorldSize); + zMin = Math.max(NumberConversions.floor(center.getZ() - radius), -maxWorldSize); + zMax = Math.min(NumberConversions.ceil(center.getZ() + radius), maxWorldSize); + } + } } diff --git a/util/src/main/java/tc/oc/pgm/util/nms/NMSHacks.java b/util/src/main/java/tc/oc/pgm/util/nms/NMSHacks.java index 2cbe12a538..2b22490420 100644 --- a/util/src/main/java/tc/oc/pgm/util/nms/NMSHacks.java +++ b/util/src/main/java/tc/oc/pgm/util/nms/NMSHacks.java @@ -439,4 +439,8 @@ static AttributeMap buildAttributeMap(Player player) { static void postToMainThread(Plugin plugin, boolean priority, Runnable task) { INSTANCE.postToMainThread(plugin, priority, task); } + + static int getMaxWorldSize(World world) { + return INSTANCE.getMaxWorldSize(world); + } } diff --git a/util/src/main/java/tc/oc/pgm/util/nms/NMSHacksNoOp.java b/util/src/main/java/tc/oc/pgm/util/nms/NMSHacksNoOp.java index d8cf92f7e5..509d8f7d46 100644 --- a/util/src/main/java/tc/oc/pgm/util/nms/NMSHacksNoOp.java +++ b/util/src/main/java/tc/oc/pgm/util/nms/NMSHacksNoOp.java @@ -302,4 +302,9 @@ public void postToMainThread(Plugin plugin, boolean priority, Runnable task) { // runs the task on the next tick, not a perfect replacement plugin.getServer().getScheduler().runTask(plugin, task); } + + @Override + public int getMaxWorldSize(World world) { + return 29999984; // Vanilla's default + } } diff --git a/util/src/main/java/tc/oc/pgm/util/nms/NMSHacksPlatform.java b/util/src/main/java/tc/oc/pgm/util/nms/NMSHacksPlatform.java index 4894d88f30..2752766c6d 100644 --- a/util/src/main/java/tc/oc/pgm/util/nms/NMSHacksPlatform.java +++ b/util/src/main/java/tc/oc/pgm/util/nms/NMSHacksPlatform.java @@ -208,4 +208,6 @@ Object teamPacket( AttributeMap buildAttributeMap(Player player); void postToMainThread(Plugin plugin, boolean priority, Runnable task); + + int getMaxWorldSize(World world); } diff --git a/util/src/main/java/tc/oc/pgm/util/nms/v1_8/NMSHacks1_8.java b/util/src/main/java/tc/oc/pgm/util/nms/v1_8/NMSHacks1_8.java index f5f401b629..4c96ada52d 100644 --- a/util/src/main/java/tc/oc/pgm/util/nms/v1_8/NMSHacks1_8.java +++ b/util/src/main/java/tc/oc/pgm/util/nms/v1_8/NMSHacks1_8.java @@ -966,6 +966,11 @@ public double getTPS() { return 20.0; } + @Override + public int getMaxWorldSize(World world) { + return ((CraftWorld) world).getHandle().getWorldBorder().l(); + } + enum TeamPacketFields { a, b,