From 160ef002e4c1d140af3a0e545dfc90e374d8dfcc Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 20 Feb 2019 21:42:43 -0800 Subject: [PATCH] Fixes island coords that are not on the grid. https://github.com/BentoBoxWorld/BentoBox/issues/549 --- .../bentobox/managers/IslandsManager.java | 23 ++++++ .../bentobox/managers/IslandsManagerTest.java | 75 +++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 17693fb27..8e0b70742 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -713,6 +713,8 @@ public class IslandsManager { // Add to quarantine cache quarantineCache.computeIfAbsent(island.getOwner(), k -> new ArrayList<>()).add(island); } else { + // Fix island center if it is off + fixIslandCenter(island); if (!islandCache.addIsland(island)) { // Quarantine the offending island toQuarantine.add(island); @@ -731,6 +733,27 @@ public class IslandsManager { } } + /** + * Island coordinates should always be a multiple of the island distance x 2. If they are not, this method + * realigns the grid coordinates. + * @param island - island + */ + public void fixIslandCenter(Island island) { + World world = island.getWorld(); + if (world == null || island.getCenter() == null || !plugin.getIWM().inWorld(world)) { + return; + } + int distance = island.getRange() * 2; + long x = island.getCenter().getBlockX() - plugin.getIWM().getIslandXOffset(world); + long z = island.getCenter().getBlockZ() - plugin.getIWM().getIslandZOffset(world); + if (x % distance != 0 || z % distance != 0) { + // Island is off grid + x = Math.round((double) x / distance) * distance + plugin.getIWM().getIslandXOffset(world); + z = Math.round((double) z / distance) * distance + plugin.getIWM().getIslandZOffset(world); + } + island.setCenter(new Location(world, x, island.getCenter().getBlockY(), z)); + } + /** * Checks if a specific location is within the protected range of an island * that the player is a member of (owner or member) diff --git a/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java index 162fcf8e9..31ff1dd7a 100644 --- a/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java @@ -1115,4 +1115,79 @@ public class IslandsManagerTest { im.setIslandCache(islandCache); assertEquals(island, im.getIslandById(uuid).get()); } + + /** + * Test method for {@link IslandsManager#fixIslandCenter(Island)}. + */ + @Test + public void testFixIslandCenter() { + // Setup + when(iwm.inWorld(Mockito.any(World.class))).thenReturn(true); + when(iwm.getIslandXOffset(Mockito.any())).thenReturn(0); + when(iwm.getIslandZOffset(Mockito.any())).thenReturn(0); + Island island = mock(Island.class); + Location center = mock(Location.class); + when(center.getWorld()).thenReturn(world); + when(center.getBlockX()).thenReturn(129); + when(center.getBlockY()).thenReturn(120); + when(center.getBlockZ()).thenReturn(127); + when(island.getCenter()).thenReturn(center); + when(island.getRange()).thenReturn(64); + when(island.getWorld()).thenReturn(world); + // Test + IslandsManager im = new IslandsManager(plugin); + im.fixIslandCenter(island); + Location loc = new Location(world, 128, 120, 128); + Mockito.verify(island).setCenter(Mockito.eq(loc)); + } + + /** + * Test method for {@link IslandsManager#fixIslandCenter(Island)}. + */ + @Test + public void testFixIslandCenterOffsets() { + // Setup + when(iwm.inWorld(Mockito.any(World.class))).thenReturn(true); + when(iwm.getIslandXOffset(Mockito.any())).thenReturn(10); + when(iwm.getIslandZOffset(Mockito.any())).thenReturn(10); + Island island = mock(Island.class); + Location center = mock(Location.class); + when(center.getWorld()).thenReturn(world); + when(center.getBlockX()).thenReturn(1295); + when(center.getBlockY()).thenReturn(120); + when(center.getBlockZ()).thenReturn(1295); + when(island.getCenter()).thenReturn(center); + when(island.getRange()).thenReturn(64); + when(island.getWorld()).thenReturn(world); + // Test + IslandsManager im = new IslandsManager(plugin); + im.fixIslandCenter(island); + Location loc = new Location(world, 1290, 120, 1290); + Mockito.verify(island).setCenter(Mockito.eq(loc)); + } + + /** + * Test method for {@link IslandsManager#fixIslandCenter(Island)}. + */ + @Test + public void testFixIslandCenterOffsetsNegatives() { + // Setup + when(iwm.inWorld(Mockito.any(World.class))).thenReturn(true); + when(iwm.getIslandXOffset(Mockito.any())).thenReturn(0); + when(iwm.getIslandZOffset(Mockito.any())).thenReturn(0); + Island island = mock(Island.class); + Location center = mock(Location.class); + when(center.getWorld()).thenReturn(world); + when(center.getBlockX()).thenReturn(-1295); + when(center.getBlockY()).thenReturn(120); + when(center.getBlockZ()).thenReturn(-1287); + when(island.getCenter()).thenReturn(center); + when(island.getRange()).thenReturn(64); + when(island.getWorld()).thenReturn(world); + // Test + IslandsManager im = new IslandsManager(plugin); + im.fixIslandCenter(island); + Location loc = new Location(world, -1280, 120, -1280); + Mockito.verify(island).setCenter(Mockito.eq(loc)); + } }