diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java index 173a2b5aae..cd3dbed6c6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java @@ -114,6 +114,13 @@ public class ClueScrollPlugin extends Plugin private static final Color HIGHLIGHT_BORDER_COLOR = Color.ORANGE; private static final Color HIGHLIGHT_HOVER_BORDER_COLOR = HIGHLIGHT_BORDER_COLOR.darker(); private static final Color HIGHLIGHT_FILL_COLOR = new Color(0, 255, 0, 20); + private static final int[] REGION_MIRRORS = { + // Prifddinas + 12894, 8755, + 12895, 8756, + 13150, 9011, + 13151, 9012 + }; @Getter private ClueScroll clue; @@ -374,12 +381,13 @@ public class ClueScrollPlugin extends Plugin if (clue instanceof LocationClueScroll) { - final WorldPoint location = ((LocationClueScroll) clue).getLocation(); + final WorldPoint[] locations = ((LocationClueScroll) clue).getLocations(); - if (location != null) + for (WorldPoint location : locations) { // Only set the location hint arrow if we do not already have more accurate location - if (config.displayHintArrows() + if (location.isInScene(client) + && config.displayHintArrows() && (client.getHintArrowNpc() == null || !npcsToMark.contains(client.getHintArrowNpc()))) { @@ -610,7 +618,11 @@ public class ClueScrollPlugin extends Plugin minX *= -1; } - return new CoordinateClue(text, coordinatesToWorldPoint(degX, minX, degY, minY)); + WorldPoint coordinate = coordinatesToWorldPoint(degX, minX, degY, minY); + // Convert from overworld to real + WorldPoint mirrorPoint = getMirrorPoint(coordinate, false); + // Use mirror point as mirrorLocation if there is one + return new CoordinateClue(text, coordinate, coordinate == mirrorPoint ? null : mirrorPoint); } /** @@ -812,4 +824,29 @@ public class ClueScrollPlugin extends Plugin newScroll ); } + + /** + * Translate a coordinate either between overworld and real, or real and overworld + * + * @param worldPoint + * @param toOverworld whether to convert to overworld coordinates, or to real coordinates + * @return + */ + public static WorldPoint getMirrorPoint(WorldPoint worldPoint, boolean toOverworld) + { + int region = worldPoint.getRegionID(); + for (int i = 0; i < REGION_MIRRORS.length; i += 2) + { + int real = REGION_MIRRORS[i]; + int overworld = REGION_MIRRORS[i + 1]; + + // Test against what we are converting from + if (region == (toOverworld ? real : overworld)) + { + return WorldPoint.fromRegion(toOverworld ? overworld : real, + worldPoint.getRegionX(), worldPoint.getRegionY(), worldPoint.getPlane()); + } + } + return worldPoint; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java index 2fb7891866..268e03f5a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.cluescrolls.clues; import com.google.common.collect.ImmutableMap; import java.awt.Color; import java.awt.Graphics2D; +import javax.annotation.Nullable; import lombok.Getter; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; @@ -198,14 +199,33 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati private final String text; private final WorldPoint location; + /** + * For regions which are mirrored, the location of the the clue in the mirrored region. + */ + @Nullable + private final WorldPoint mirrorLocation; - public CoordinateClue(String text, WorldPoint location) + public CoordinateClue(String text, WorldPoint location, WorldPoint mirrorLocation) { this.text = text; this.location = location; + this.mirrorLocation = mirrorLocation; setRequiresSpade(true); } + @Override + public WorldPoint[] getLocations() + { + if (mirrorLocation != null) + { + return new WorldPoint[]{location, mirrorLocation}; + } + else + { + return new WorldPoint[]{location}; + } + } + @Override public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) { @@ -229,13 +249,14 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati @Override public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) { - LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation()); - - if (localLocation == null) + for (WorldPoint worldPoint : getLocations()) { - return; - } + LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), worldPoint); - OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, plugin.getSpadeImage(), Color.ORANGE); + if (localLocation != null) + { + OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, plugin.getSpadeImage(), Color.ORANGE); + } + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java index a4f4126656..2499379be4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java @@ -292,7 +292,8 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat return false; } - final WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); + // Convert from real to overworld + final WorldPoint localWorld = ClueScrollPlugin.getMirrorPoint(plugin.getClient().getLocalPlayer().getWorldLocation(), true); if (localWorld == null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/LocationClueScroll.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/LocationClueScroll.java index 323e0a498e..194aefcb5a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/LocationClueScroll.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/LocationClueScroll.java @@ -29,4 +29,10 @@ import net.runelite.api.coords.WorldPoint; public interface LocationClueScroll { WorldPoint getLocation(); + + default WorldPoint[] getLocations() + { + WorldPoint location = getLocation(); + return location == null ? new WorldPoint[0] : new WorldPoint[]{location}; + } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/ClueScrollPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/ClueScrollPluginTest.java new file mode 100644 index 0000000000..d1585382d4 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/ClueScrollPluginTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019 Hydrox6 + * Copyright (c) 2019 Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.cluescrolls; + +import net.runelite.api.coords.WorldPoint; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import org.junit.Test; + +public class ClueScrollPluginTest +{ + @Test + public void getGetMirrorPoint() + { + WorldPoint point, converted; + + // Zalcano's entrance portal + point = new WorldPoint(3282, 6058, 0); + converted = ClueScrollPlugin.getMirrorPoint(point, true); + assertNotEquals(point, converted); + + // Elven Crystal Chest, which is upstairs + point = new WorldPoint(3273, 6082, 2); + converted = ClueScrollPlugin.getMirrorPoint(point, true); + assertNotEquals(point, converted); + + // Around the area of the Elite coordinate clue + point = new WorldPoint(2185, 3280, 0); + // To overworld + converted = ClueScrollPlugin.getMirrorPoint(point, true); + assertEquals(point, converted); + // To real + converted = ClueScrollPlugin.getMirrorPoint(point, false); + assertNotEquals(point, converted); + + // Brugsen Bursen, Grand Exchange + point = new WorldPoint(3165, 3477, 0); + converted = ClueScrollPlugin.getMirrorPoint(point, false); + assertEquals(point, converted); + } +} \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClueTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClueTest.java index 6896928b29..d3854d843f 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClueTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClueTest.java @@ -33,6 +33,6 @@ public class CoordinateClueTest public void testDuplicateCoordinates() { // If this doesn't throw then the clues map doesn't have duplicate keys - new CoordinateClue("test", new WorldPoint(0, 0, 0)); + new CoordinateClue("test", new WorldPoint(0, 0, 0), null); } } \ No newline at end of file