From 3bffdebd9210fa8a84f1f849d3b471aedfef1b65 Mon Sep 17 00:00:00 2001 From: Pablo Herrera Date: Sun, 12 May 2024 17:09:09 +0200 Subject: [PATCH] Improve world border logic (#1314) 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 c145165b22..62fb0f28df 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 @@ -443,4 +443,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 988b892cc2..01fda85384 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 @@ -307,4 +307,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 056878f4fc..69d98fe9a1 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 @@ -210,4 +210,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 c7199ae81d..5fc822bd7f 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 @@ -972,6 +972,11 @@ public double getTPS() { return 20.0; } + @Override + public int getMaxWorldSize(World world) { + return ((CraftWorld) world).getHandle().getWorldBorder().l(); + } + enum TeamPacketFields { a, b,