diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/FairyRingLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/FairyRingLocation.java new file mode 100644 index 0000000000..664d4db0e9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/FairyRingLocation.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2018, Morgan Lewis + * 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 HOLDER 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.worldmap; + +import java.awt.image.BufferedImage; +import lombok.Getter; +import net.runelite.api.coords.WorldPoint; + +@Getter +enum FairyRingLocation +{ + AIR("AIR", new WorldPoint(2699, 3249, 0)), + AIQ("AIQ", new WorldPoint(2995, 3112, 0)), + AJR("AJR", new WorldPoint(2779, 3615, 0)), + AJS("AJS", new WorldPoint(2499, 3898, 0)), + AKQ("AKQ", new WorldPoint(2318, 3617, 0)), + AKS("AKS", new WorldPoint(2570, 2958, 0)), + ALP("ALP", new WorldPoint(2502, 3638, 0)), + ALQ("ALQ", new WorldPoint(3598, 3496, 0)), + ALS("ALS", new WorldPoint(2643, 3497, 0)), + BIP("BIP", new WorldPoint(3409, 3326, 0)), + BIQ("BIQ", new WorldPoint(3248, 3095, 0)), + BIS("BIS", new WorldPoint(2635, 3268, 0)), + BJQ("BJQ", new WorldPoint(1737, 5342, 0)), + BJS("BJS", new WorldPoint(2147, 3069, 0)), + BKP("BKP", new WorldPoint(2384, 3037, 0)), + BKR("BKR", new WorldPoint(3468, 3433, 0)), + BLP("BLP", new WorldPoint(2432, 5127, 0)), + BLR("BLR", new WorldPoint(2739, 3353, 0)), + CIP("CIP", new WorldPoint(2512, 3886, 0)), + CIQ("CIQ", new WorldPoint(2527, 3129, 0)), + CJR("CJR", new WorldPoint(2704, 3578, 0)), + CKR("CKR", new WorldPoint(2800, 3005, 0)), + CKS("CKS", new WorldPoint(3446, 3472, 0)), + CLP("CLP", new WorldPoint(3081, 3208, 0)), + CLS("CLS", new WorldPoint(2681, 3083, 0)), + DIP("DIP", new WorldPoint(3039, 4757, 0)), + DIS("DIS", new WorldPoint(3109, 3149, 0)), + DJP("DJP", new WorldPoint(2657, 3232, 0)), + DJR("DJR", new WorldPoint(1452, 3659, 0)), + DKP("DKP", new WorldPoint(2899, 3113, 0)), + DKR("DKR", new WorldPoint(3126, 3496, 0)), + DKS("DKS", new WorldPoint(2743, 3721, 0)), + DLQ("DLQ", new WorldPoint(3422, 3018, 0)), + DLR("DLR", new WorldPoint(2212, 3101, 0)), + CIS("CIS", new WorldPoint(1638, 3868, 0)), + CLR("CLR", new WorldPoint(2737, 2739, 0)), + ZANARIS("Zanaris", new WorldPoint(2411, 4436, 0)); + + private final String code; + private final WorldPoint location; + private final FairyRingPoint fairyRingPoint; + + FairyRingLocation(String code, WorldPoint location) + { + this.code = code; + this.location = location; + this.fairyRingPoint = new FairyRingPoint(code, location); + } + + static void setIcon(BufferedImage image) + { + for (FairyRingLocation fairyRingLocation : values()) + { + fairyRingLocation.fairyRingPoint.setImage(image); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/FairyRingPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/FairyRingPoint.java new file mode 100644 index 0000000000..3422d9cf0e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/FairyRingPoint.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, Morgan Lewis + * 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 HOLDER 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.worldmap; + +import net.runelite.api.coords.WorldPoint; +import static net.runelite.client.plugins.worldmap.WorldMapPlugin.BLANK_ICON; +import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; + +class FairyRingPoint extends WorldMapPoint +{ + FairyRingPoint(String tooltip, WorldPoint worldPoint) + { + super(worldPoint, BLANK_ICON); + setTooltip("Fairy Ring - " + tooltip); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapConfig.java new file mode 100644 index 0000000000..7b915b1429 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapConfig.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, Morgan Lewis + * 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 HOLDER 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.worldmap; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup( + keyName = WorldMapPlugin.CONFIG_KEY, + name = "World Map", + description = "Various World Map enhancements" +) +public interface WorldMapConfig extends Config +{ + @ConfigItem( + keyName = WorldMapPlugin.CONFIG_KEY_FAIRY_RING_TOOLTIPS, + name = "Show fairy ring codes in tooltip", + description = "Display the code for fairy rings in the icon tooltip", + position = 1 + ) + default boolean fairyRingTooltips() + { + return true; + } + + @ConfigItem( + keyName = WorldMapPlugin.CONFIG_KEY_FAIRY_RING_ICON, + name = "Show fairy ring travel icon", + description = "Override the travel icon for fairy rings", + position = 2 + ) + default boolean fairyRingIcon() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java new file mode 100644 index 0000000000..f6b9817a6b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2018, Morgan Lewis + * 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 HOLDER 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.worldmap; + +import com.google.common.eventbus.Subscribe; +import com.google.inject.Inject; +import com.google.inject.Provides; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.Arrays; +import javax.imageio.ImageIO; +import net.runelite.api.events.ConfigChanged; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager; + +@PluginDescriptor( + name = "World Map" +) +public class WorldMapPlugin extends Plugin +{ + static final BufferedImage BLANK_ICON; + static final BufferedImage FAIRY_TRAVEL_ICON; + + static final String CONFIG_KEY = "worldmap"; + static final String CONFIG_KEY_FAIRY_RING_TOOLTIPS = "fairyRingTooltips"; + static final String CONFIG_KEY_FAIRY_RING_ICON = "fairyRingIcon"; + + static + { + //A size of 17 gives us a buffer when triggering tooltips + final int iconBufferSize = 17; + + BLANK_ICON = new BufferedImage(iconBufferSize, iconBufferSize, BufferedImage.TYPE_INT_ARGB); + + try + { + synchronized (ImageIO.class) + { + FAIRY_TRAVEL_ICON = new BufferedImage(iconBufferSize, iconBufferSize, BufferedImage.TYPE_INT_ARGB); + final BufferedImage icon = ImageIO.read(WorldMapPlugin.class.getResourceAsStream("fairy_ring_travel.png")); + FAIRY_TRAVEL_ICON.getGraphics().drawImage(icon, 1, 1, null); + } + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + + @Inject + private WorldMapConfig config; + + @Inject + private WorldMapPointManager worldMapPointManager; + + @Provides + WorldMapConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(WorldMapConfig.class); + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals(CONFIG_KEY)) + { + switch (event.getKey()) + { + case CONFIG_KEY_FAIRY_RING_TOOLTIPS: + if (config.fairyRingTooltips()) + { + Arrays.stream(FairyRingLocation.values()) + .map(FairyRingLocation::getFairyRingPoint) + .forEach(worldMapPointManager::add); + } + else + { + worldMapPointManager.removeIf(FairyRingPoint.class::isInstance); + } + break; + case CONFIG_KEY_FAIRY_RING_ICON: + FairyRingLocation.setIcon(config.fairyRingIcon() ? FAIRY_TRAVEL_ICON : BLANK_ICON); + break; + } + } + } + + @Override + protected void startUp() throws Exception + { + FairyRingLocation.setIcon(config.fairyRingIcon() ? FAIRY_TRAVEL_ICON : BLANK_ICON); + + if (config.fairyRingTooltips()) + { + Arrays.stream(FairyRingLocation.values()) + .map(FairyRingLocation::getFairyRingPoint) + .forEach(worldMapPointManager::add); + } + } + + @Override + protected void shutDown() throws Exception + { + worldMapPointManager.removeIf(FairyRingPoint.class::isInstance); + } +} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/fairy_ring_travel.png b/runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/fairy_ring_travel.png new file mode 100644 index 0000000000..2bce38a741 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/fairy_ring_travel.png differ