From 14aa57e126393bdd6a38ce3c7cbe2a15bb9b8f0c Mon Sep 17 00:00:00 2001 From: Lotto Date: Mon, 26 Mar 2018 17:25:58 +0200 Subject: [PATCH] runelite-client: revamp clue scroll plugin --- .../cluescrolls/ClueScrollEmoteOverlay.java | 144 ++++++ .../cluescrolls/ClueScrollOverlay.java | 48 +- .../plugins/cluescrolls/ClueScrollPlugin.java | 279 ++++++++++-- .../cluescrolls/ClueScrollWorldOverlay.java | 88 ++++ .../cluescrolls/clues/AnagramClue.java | 214 +++++++++ .../plugins/cluescrolls/clues/CipherClue.java | 123 +++++ .../plugins/cluescrolls/clues/ClueScroll.java | 36 ++ .../cluescrolls/clues/CoordinateClue.java | 69 +++ .../cluescrolls/clues/CrypticClue.java | 419 ++++++++++++++++++ .../plugins/cluescrolls/clues/Emote.java | 75 ++++ .../plugins/cluescrolls/clues/EmoteClue.java | 241 ++++++++++ .../cluescrolls/clues/FairyRingClue.java | 103 +++++ .../plugins/cluescrolls/clues/MapClue.java | 174 ++++++++ .../cluescrolls/clues/NpcClueScroll.java | 30 ++ .../cluescrolls/clues/ObjectClueScroll.java | 30 ++ .../cluescrolls/clues/TextClueScroll.java | 30 ++ 16 files changed, 2032 insertions(+), 71 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollEmoteOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ClueScroll.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/Emote.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FairyRingClue.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MapClue.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/NpcClueScroll.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ObjectClueScroll.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/TextClueScroll.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollEmoteOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollEmoteOverlay.java new file mode 100644 index 0000000000..b7ffe30fc6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollEmoteOverlay.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2018, Lotto + * 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 java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.geom.Area; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.plugins.cluescrolls.clues.ClueScroll; +import net.runelite.client.plugins.cluescrolls.clues.EmoteClue; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.components.TextComponent; + +public class ClueScrollEmoteOverlay extends Overlay +{ + 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 final ClueScrollPlugin plugin; + private final Client client; + private final TextComponent textComponent = new TextComponent(); + + @Inject + public ClueScrollEmoteOverlay(ClueScrollPlugin plugin, Client client) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_WIDGETS); + this.plugin = plugin; + this.client = client; + } + + @Override + public Dimension render(Graphics2D graphics) + { + ClueScroll clue = plugin.getClue(); + + if (clue == null || !(clue instanceof EmoteClue)) + { + return null; + } + + EmoteClue emoteClue = (EmoteClue) clue; + + if (!emoteClue.getFirstEmote().hasSprite()) + { + return null; + } + + Widget emoteContainer = client.getWidget(WidgetInfo.EMOTE_CONTAINER); + + if (emoteContainer == null || emoteContainer.isHidden()) + { + return null; + } + + Widget emoteWindow = client.getWidget(WidgetInfo.EMOTE_WINDOW); + + if (emoteWindow == null) + { + return null; + } + + for (Widget emoteWidget : emoteContainer.getDynamicChildren()) + { + if (emoteWidget.getSpriteId() == emoteClue.getFirstEmote().getSpriteId()) + { + highlightWidget(graphics, emoteWindow, emoteWidget, + emoteClue.getSecondEmote() != null ? "1st" : ""); + } + else if (emoteClue.getSecondEmote() != null + && emoteWidget.getSpriteId() == emoteClue.getSecondEmote().getSpriteId()) + { + highlightWidget(graphics, emoteWindow, emoteWidget, "2nd"); + } + } + + return null; + } + + private void highlightWidget(Graphics2D graphics, Widget window, Widget widget, String text) + { + net.runelite.api.Point canvasLocation = widget.getCanvasLocation(); + + if (canvasLocation == null) + { + return; + } + + // Don't draw outside the emotes window + net.runelite.api.Point windowLocation = window.getCanvasLocation(); + + if (windowLocation.getY() > canvasLocation.getY() + || windowLocation.getY() + window.getHeight() < canvasLocation.getY() + widget.getHeight()) + { + return; + } + + Area widgetArea = new Area(new Rectangle(canvasLocation.getX(), canvasLocation.getY(), widget.getWidth(), widget.getHeight())); + + OverlayUtil.renderHoverableArea(graphics, widgetArea, client.getMouseCanvasPosition(), + HIGHLIGHT_FILL_COLOR, HIGHLIGHT_BORDER_COLOR, HIGHLIGHT_HOVER_BORDER_COLOR); + + FontMetrics fontMetrics = graphics.getFontMetrics(); + + textComponent.setPosition(new Point( + canvasLocation.getX() + widget.getWidth() / 2 - fontMetrics.stringWidth(text) / 2, + canvasLocation.getY() + fontMetrics.getHeight())); + textComponent.setText(text); + textComponent.render(graphics); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollOverlay.java index 76ff14f312..6b27a90a0c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollOverlay.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2017, Seth + * Copyright (c) 2018, Lotto * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,72 +23,43 @@ * 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 java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; -import java.time.Duration; -import java.time.Instant; import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.ItemComposition; +import net.runelite.client.plugins.cluescrolls.clues.ClueScroll; import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.components.PanelComponent; public class ClueScrollOverlay extends Overlay { - private static final Duration WAIT_DURATION = Duration.ofMinutes(4); + public static final Color TITLED_CONTENT_COLOR = new Color(190, 190, 190); - private final Client client; + private final ClueScrollPlugin plugin; private final PanelComponent panelComponent = new PanelComponent(); - ClueScroll clue; - Instant clueTimeout; - @Inject - public ClueScrollOverlay(Client client) + public ClueScrollOverlay(ClueScrollPlugin plugin) { - setPosition(OverlayPosition.TOP_LEFT); - this.client = client; + this.plugin = plugin; } @Override public Dimension render(Graphics2D graphics) { + ClueScroll clue = plugin.getClue(); + if (clue == null) { return null; } - if (clueTimeout == null || Instant.now().compareTo(clueTimeout.plus(WAIT_DURATION)) >= 0) - { - return null; - } - panelComponent.getLines().clear(); - panelComponent.setTitle("Required items"); - if (clue.getIds().length == 0) - { - panelComponent.getLines().add(new PanelComponent.Line("None", "")); - } - else - { - for (int id : clue.getIds()) - { - ItemComposition clueItem = client.getItemDefinition(id); - - if (clueItem == null) - { - continue; - } - - panelComponent.getLines().add(new PanelComponent.Line(clueItem.getName(), "")); - } - } + clue.makeOverlayHint(panelComponent, plugin); return panelComponent.render(graphics); } 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 5663b232c9..9b3a00e76d 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2017, Seth + * Copyright (c) 2018, Lotto * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,36 +23,111 @@ * 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 com.google.common.eventbus.Subscribe; +import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; import javax.inject.Inject; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.ChatMessageType; import net.runelite.api.Client; +import net.runelite.api.GameObject; import net.runelite.api.GameState; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.NPC; +import net.runelite.api.Query; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.queries.GameObjectQuery; +import net.runelite.api.queries.InventoryItemQuery; +import net.runelite.api.queries.NPCQuery; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.cluescrolls.clues.AnagramClue; +import net.runelite.client.plugins.cluescrolls.clues.CipherClue; +import net.runelite.client.plugins.cluescrolls.clues.ClueScroll; +import net.runelite.client.plugins.cluescrolls.clues.CoordinateClue; +import net.runelite.client.plugins.cluescrolls.clues.CrypticClue; +import net.runelite.client.plugins.cluescrolls.clues.EmoteClue; +import net.runelite.client.plugins.cluescrolls.clues.FairyRingClue; +import net.runelite.client.plugins.cluescrolls.clues.MapClue; +import net.runelite.client.plugins.cluescrolls.clues.NpcClueScroll; +import net.runelite.client.plugins.cluescrolls.clues.ObjectClueScroll; +import net.runelite.client.plugins.cluescrolls.clues.TextClueScroll; import net.runelite.client.task.Schedule; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.util.QueryRunner; @PluginDescriptor( name = "Clue Scroll" ) +@Slf4j public class ClueScrollPlugin extends Plugin { + private static final Duration WAIT_DURATION = Duration.ofMinutes(4); + + @Getter + private ClueScroll clue; + + @Getter + private NPC[] npcsToMark; + + @Getter + private GameObject[] objectsToMark; + + @Getter + private Set equippedItems; + + @Getter + private Instant clueTimeout; + @Inject + @Getter private Client client; + @Inject + private QueryRunner queryRunner; + @Inject private ClueScrollOverlay clueScrollOverlay; + @Inject + private ClueScrollEmoteOverlay clueScrollEmoteOverlay; + + @Inject + private ClueScrollWorldOverlay clueScrollWorldOverlay; + @Override - public ClueScrollOverlay getOverlay() + public Collection getOverlays() { - return clueScrollOverlay; + return Arrays.asList(clueScrollOverlay, clueScrollEmoteOverlay, clueScrollWorldOverlay); + } + + @Subscribe + public void onChatMessage(ChatMessage event) + { + if (event.getType() != ChatMessageType.SERVER) + { + return; + } + + if (!event.getMessage().equals("Well done, you've completed the Treasure Trail!")) + { + return; + } + + clue = null; } @Schedule( @@ -60,64 +136,201 @@ public class ClueScrollPlugin extends Plugin ) public void checkForClues() { - if (client.getGameState() != GameState.LOGGED_IN) + if (client.getGameState() == GameState.LOGIN_SCREEN) { + clue = null; return; } - Widget clueScroll = client.getWidget(WidgetInfo.CLUE_SCROLL_TEXT); + npcsToMark = null; + objectsToMark = null; + equippedItems = null; - if (clueScroll == null) + if (clue instanceof NpcClueScroll) { - return; + String npc = ((NpcClueScroll) clue).getNpc(); + + if (npc != null) + { + Query query = new NPCQuery().nameContains(npc); + npcsToMark = queryRunner.runQuery(query); + } } - //remove line breaks and also the rare occasion where there are double line breaks - ClueScroll clue = ClueScroll.forText(clueScroll.getText().replaceAll("
", " ").replaceAll(" ", " ").toLowerCase()); - - if (clue == null) + if (clue instanceof ObjectClueScroll) { - clueScrollOverlay.clue = null; - return; + int objectId = ((ObjectClueScroll) clue).getObjectId(); + + if (objectId != -1) + { + GameObjectQuery query = new GameObjectQuery().idEquals(); + objectsToMark = queryRunner.runQuery(query); + } } - if (clue.getType() == ClueScrollType.EMOTE) + if (clue instanceof EmoteClue) { - clueScrollOverlay.clue = clue; + equippedItems = new HashSet<>(); - clueScrollOverlay.clueTimeout = Instant.now(); - return; + Item[] result = queryRunner.runQuery(new InventoryItemQuery(InventoryID.EQUIPMENT)); + + if (result != null) + { + for (Item item : result) + { + equippedItems.add(item.getId()); + } + } } - clueScrollOverlay.clue = null; + ClueScroll clue = findClueScroll(); - //check for which tells us if the string has already been built - if (clueScroll.getText().contains("")) + if (clue == null && this.clue != null) { - return; + // If clue window isn't open, and we don't have a map clue in inventory, + // but we have recorded the player having a clue, + // wait for WAIT_DURATION before discarding the knowledge of the player having a clue. + if (Instant.now().compareTo(clueTimeout.plus(WAIT_DURATION)) < 0) + { + return; + } } - //Build widget text - StringBuilder clueText = new StringBuilder(); - - clueText.append(clueScroll.getText()).append("

"); - - if (clue.getNpc() != null) + // If we have a clue, save that knowledge + // so the clue window doesn't have to be open. + if (clue != null) { - clueText.append("Talk to: ").append(clue.getNpc()).append("
"); + this.clue = clue; + this.clueTimeout = Instant.now(); + } + } + + private ClueScroll findClueScroll() + { + Widget clueScrollText = client.getWidget(WidgetInfo.CLUE_SCROLL_TEXT); + + if (clueScrollText != null) + { + // Remove line breaks and also the rare occasion where there are double line breaks + String text = clueScrollText.getText() + .replaceAll("-
", "-") + .replaceAll("
", " ") + .replaceAll("[ ]+", " ") + .toLowerCase(); + + if (clue != null && clue instanceof TextClueScroll) + { + if (((TextClueScroll) clue).getText().equalsIgnoreCase(text)) + { + return clue; + } + } + + if (text.startsWith("this anagram reveals who to speak to next:")) + { + return AnagramClue.forText(text); + } + else if (text.startsWith("the cipher reveals who to speak to next:")) + { + return CipherClue.forText(text); + } + else if (text.contains("degrees") && text.contains("minutes")) + { + return coordinatesToWorldPoint(text); + } + else + { + CrypticClue crypticClue = CrypticClue.forText(text); + + if (crypticClue != null) + { + return crypticClue; + } + + EmoteClue emoteClue = EmoteClue.forText(text); + + if (emoteClue != null) + { + return emoteClue; + } + + return FairyRingClue.forText(text); + } } - if (clue.getLocation() != null) + Item[] result = queryRunner.runQuery(new InventoryItemQuery(InventoryID.INVENTORY)); + + if (result == null) { - clueText.append("Location: ").append(clue.getLocation()).append("
"); + return null; } - if (clue.getAnswer() != null) + for (Item item : result) { - clueText.append("Answer: ").append(clue.getAnswer()); + MapClue clue = MapClue.forItemId(item.getId()); + + if (clue != null) + { + return clue; + } } - clueScroll.setText(clueText.toString()); + return null; + } + /** + * Example input: "00 degrees 00 minutes north 07 degrees 13 minutes west" + */ + private CoordinateClue coordinatesToWorldPoint(String text) + { + String[] splitText = text.split(" "); + + if (splitText.length != 10) + { + log.warn("Splitting \"" + text + "\" did not result in an array of 10 cells"); + return null; + } + + if (!splitText[1].equals("degrees") || !splitText[3].equals("minutes")) + { + log.warn("\"" + text + "\" is not a well formed coordinate string"); + return null; + } + + int degY = Integer.parseInt(splitText[0]); + int minY = Integer.parseInt(splitText[2]); + + if (splitText[4].equals("south")) + { + degY *= -1; + minY *= -1; + } + + int degX = Integer.parseInt(splitText[5]); + int minX = Integer.parseInt(splitText[7]); + + if (splitText[9].equals("west")) + { + degX *= -1; + minX *= -1; + } + + return new CoordinateClue(text, coordinatesToWorldPoint(degX, minX, degY, minY)); + } + + /** + * This conversion is explained on + * http://oldschoolrunescape.wikia.com/wiki/Treasure_Trails/Guide/Coordinates + */ + private WorldPoint coordinatesToWorldPoint(int degX, int minX, int degY, int minY) + { + // Center of the Observatory + int x2 = 2440; + int y2 = 3161; + + x2 += degX * 32 + Math.round(minX / 1.875); + y2 += degY * 32 + Math.round(minY / 1.875); + + return new WorldPoint(x2, y2, 0); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldOverlay.java new file mode 100644 index 0000000000..1fb438963c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldOverlay.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018, Lotto + * 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 java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.inject.Inject; +import net.runelite.client.plugins.cluescrolls.clues.ClueScroll; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; + +public class ClueScrollWorldOverlay extends Overlay +{ + public static final int IMAGE_Z_OFFSET = 30; + + public static final BufferedImage EMOTE_IMAGE; + public static final BufferedImage CLUE_SCROLL_IMAGE; + public static final BufferedImage SPADE_IMAGE; + + public static final Color CLICKBOX_BORDER_COLOR = Color.ORANGE; + public static final Color CLICKBOX_HOVER_BORDER_COLOR = CLICKBOX_BORDER_COLOR.darker(); + public static final Color CLICKBOX_FILL_COLOR = new Color(0, 255, 0, 20); + + private final ClueScrollPlugin plugin; + + static + { + try + { + synchronized (ImageIO.class) + { + EMOTE_IMAGE = ImageIO.read(ClueScrollPlugin.class.getResourceAsStream("emote.png")); + CLUE_SCROLL_IMAGE = ImageIO.read(ClueScrollPlugin.class.getResourceAsStream("clue_scroll.png")); + SPADE_IMAGE = ImageIO.read(ClueScrollPlugin.class.getResourceAsStream("spade.png")); + } + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + + @Inject + public ClueScrollWorldOverlay(ClueScrollPlugin plugin) + { + setPosition(OverlayPosition.DYNAMIC); + this.plugin = plugin; + } + + @Override + public Dimension render(Graphics2D graphics) + { + ClueScroll clue = plugin.getClue(); + + if (clue != null) + { + clue.makeWorldOverlayHint(graphics, plugin); + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java new file mode 100644 index 0000000000..44ccec7114 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.Set; +import lombok.Getter; +import net.runelite.api.NPC; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.components.PanelComponent; +import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLUE_SCROLL_IMAGE; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; + +@Getter +public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueScroll +{ + private static final Set CLUES = ImmutableSet.of( + new AnagramClue("This anagram reveals who to speak to next: A BAKER", "Baraek", new WorldPoint(3217, 3434, 0), "Varrock square", "5"), + new AnagramClue("This anagram reveals who to speak to next: A BASIC ANTI POT", "Captain Tobias", new WorldPoint(3026, 3216, 0), "Port Sarim", "7"), + new AnagramClue("This anagram reveals who to speak to next: A HEART", "Aretha", new WorldPoint(1814, 3851, 0), "Soul altar", "2"), + new AnagramClue("This anagram reveals who to speak to next: A ZEN SHE", "Zenesha", new WorldPoint(2652, 3295, 0), "Platebody Southern Ardougne centre square"), + new AnagramClue("This anagram reveals who to speak to next: ACE MATCH ELM", "Cam The Camel", new WorldPoint(3300, 3231, 0), "North of the glider in Al Kharid"), + new AnagramClue("This anagram reveals who to speak to next: AHA JAR", "Jaraah", new WorldPoint(3359, 3276, 0), "Duel Arena hosptial"), + new AnagramClue("This anagram reveals who to speak to next: AN PAINT TONIC", "Captain Ninto", new WorldPoint(2865, 9877, 0), "Bar under White Wolf Mountain"), + new AnagramClue("This anagram reveals who to speak to next: ARC O LINE", "Caroline", new WorldPoint(2715, 3302, 0), "North Witchaven next to the row boat", "11"), + new AnagramClue("This anagram reveals who to speak to next: ARE COL", "Oracle", new WorldPoint(3013, 3501, 0), "Ice Mountain West of Edgeville", "48"), + new AnagramClue("This anagram reveals who to speak to next: ARMCHAIR THE PELT", "Charlie the Tramp", new WorldPoint(3209, 3392, 0), "South entrance of Varrock", "0"), + new AnagramClue("This anagram reveals who to speak to next: ARR! SO I AM A CRUST, AND?", "Ramara du Croissant", new WorldPoint(2339, 3677, 0), "Piscatoris Fishing Colony"), + new AnagramClue("This anagram reveals who to speak to next: AT HERG", "Regath", new WorldPoint(1719, 3723, 0), "General Store, Arceuus, Zeah", "25"), + new AnagramClue("This anagram reveals who to speak to next: A BAS", "Saba", new WorldPoint(2858, 3577, 0), "Death Plateau"), + new AnagramClue("This anagram reveals who to speak to next: AREA CHEF TREK", "Father Aereck", new WorldPoint(3243, 3208, 0), "Lumbridge Church", "19 or 20"), + new AnagramClue("This anagram reveals who to speak to next: BAIL TRIMS", "Brimstail", new WorldPoint(2402, 3419, 0), "West of Stronghold Slayer Cave"), + new AnagramClue("This anagram reveals who to speak to next: BAKER CLIMB", "Brambickle", new WorldPoint(2783, 3861, 0), "Trollweiss mountain"), + new AnagramClue("This anagram reveals who to speak to next: BY LOOK", "Bolkoy", new WorldPoint(2529, 3162, 0), "Tree Gnome Village general store", "13"), + new AnagramClue("This anagram reveals who to speak to next: MOTHERBOARD", "Lumbridge Guide", new WorldPoint(3232, 3232, 0), "Monastery south of Ardougne", "129"), + new AnagramClue("This anagram reveals who to speak to next: CAR IF ICES", "Sacrifice", new WorldPoint(2209, 3056, 0), "Zul-Andra"), + new AnagramClue("This anagram reveals who to speak to next: CAREER IN MOON", "Oneiromancer", new WorldPoint(2150, 3866, 0), "Astral altar", "25"), + new AnagramClue("This anagram reveals who to speak to next: C ON GAME HOC", "Gnome Coach", new WorldPoint(2395, 3486, 0), "Gnome Ball course", "6"), + new AnagramClue("This anagram reveals who to speak to next: COOL NERD", "Old Crone", new WorldPoint(3462, 3557, 0), "East of the Slayer Tower", "619"), + new AnagramClue("This anagram reveals who to speak to next: COPPER ORE CRYPTS", "Prospector Percy", new WorldPoint(3061, 3377, 0), "Motherlode Mine", "12"), + new AnagramClue("This anagram reveals who to speak to next: DED WAR", "Edward", new WorldPoint(3284, 3943, 0), "Inside Rogue's Castle"), + new AnagramClue("This anagram reveals who to speak to next: DEKAGRAM", "Dark Mage", new WorldPoint(3039, 4835, 0), "Centre of the Abyss", "13"), + new AnagramClue("This anagram reveals who to speak to next: DO SAY MORE", "Doomsayer", new WorldPoint(3230, 3230, 0), "East of Lumbridge Castle", "95"), + new AnagramClue("This anagram reveals who to speak to next: DIM THARN", "Mandrith", new WorldPoint(3182, 3946, 0), "Wilderness Resource Area", "28 or Puzzle box"), + new AnagramClue("This anagram reveals who to speak to next: DR HITMAN", "Mandrith", new WorldPoint(3182, 3946, 0), "Wilderness Resource Area", "28, Light box or Puzzle box"), + new AnagramClue("This anagram reveals who to speak to next: DR WARDEN FUNK", "Drunken Dwarf", new WorldPoint(2913, 10221, 0), "East Side of Keldagrim"), + new AnagramClue("This anagram reveals who to speak to next: DRAGONS LAMENT", "Strange old Man", new WorldPoint(3564, 3288, 0), "Barrows", "40"), + new AnagramClue("This anagram reveals who to speak to next: DT RUN B", "Brundt the Chieftain", new WorldPoint(2658, 3670, 0), "Rellekka, main hall", "4"), + new AnagramClue("This anagram reveals who to speak to next: DUO PLUG", "Dugopul", new WorldPoint(2803, 2744, 0), "Graveyard on Ape Atoll"), + new AnagramClue("This anagram reveals who to speak to next: EEK ZERO OP", "Zookeeper", new WorldPoint(2613, 3269, 0), "Ardougne Zoo", "40"), + new AnagramClue("This anagram reveals who to speak to next: EL OW", "Lowe", new WorldPoint(3233, 3423, 0), "Varrock archery store"), + new AnagramClue("This anagram reveals who to speak to next: ERR CURE IT", "Recruiter", new WorldPoint(2541, 3305, 0), "West Ardougne centre square", "20"), + new AnagramClue("This anagram reveals who to speak to next: FORLUN", "Runolf", new WorldPoint(2512, 10256, 0), "Miscellania & Etceteria Dungeon"), + new AnagramClue("This anagram reveals who to speak to next: GOBLIN KERN", "King Bolren", new WorldPoint(2541, 3170, 0), "Tree Gnome Village"), + new AnagramClue("This anagram reveals who to speak to next: GOT A BOY", "Gabooty", new WorldPoint(2790, 3066, 0), "Centre of Tai Bwo Wannai", "11"), + new AnagramClue("This anagram reveals who to speak to next: GULAG RUN", "Uglug Nar", new WorldPoint(2442, 3051, 0), "West of Jiggig"), + new AnagramClue("This anagram reveals who to speak to next: GOBLETS ODD TOES", "Otto Godblessed", new WorldPoint(2501, 3487, 0), "Otto's Grotto", "2"), + new AnagramClue("This anagram reveals who to speak to next: HALT US", "Luthas", new WorldPoint(2938, 3152, 0), "Banana plantation, Karamja", "33 or 0"), + new AnagramClue("This anagram reveals who to speak to next: HE DO POSE. IT IS CULTRRL, MK?", "Riki the sculptor's model", new WorldPoint(2904, 10206, 0), "East Keldagrim, south of kebab seller."), + new AnagramClue("This anagram reveals who to speak to next: HEORIC", "Eohric", new WorldPoint(2900, 3565, 0), "Burthorpe Castle, top floor", "36"), + new AnagramClue("This anagram reveals who to speak to next: HIS PHOR", "Horphis", new WorldPoint(1639, 3812, 0), "Arceuus Library, Zeah", "1"), + new AnagramClue("This anagram reveals who to speak to next: I AM SIR", "Marisi", new WorldPoint(1813, 3488, 0), "Allotment patch, South coast Zeah", "5"), + new AnagramClue("This anagram reveals who to speak to next: ICY FE", "Fycie", new WorldPoint(2630, 2997, 0), "East Feldip Hills"), + new AnagramClue("This anagram reveals who to speak to next: I DOOM ICON INN", "Dominic Onion", new WorldPoint(2609, 3116, 0), "Nightmare Zone", "9,500"), + new AnagramClue("This anagram reveals who to speak to next: I EAT ITS CHART HINTS DO U", "Shiratti the Custodian", new WorldPoint(3427, 2927, 0), "North of fountain, Nardah"), + new AnagramClue("This anagram reveals who to speak to next: I EVEN", "Nieve", new WorldPoint(2432, 3422, 0), "The slayer master in Gnome Stronghold", "2"), + new AnagramClue("This anagram reveals who to speak to next: I FAFFY RUN", "Fairy Nuff", new WorldPoint(3201, 3169, 0), "North of the bank in Zanaris"), + new AnagramClue("This anagram reveals who to speak to next: IM N ZEZIM", "Immenizz", new WorldPoint(2592, 4324, 0), "The Imp inside Puro-Puro"), + new AnagramClue("This anagram reveals who to speak to next: KAY SIR", "Sir Kay", new WorldPoint(2760, 3496, 0), "The courtyard in Camelot Castle", "6"), + new AnagramClue("This anagram reveals who to speak to next: LEAKEY", "Kaylee", new WorldPoint(2957, 3370, 0), "Rising Sun Inn in Falador", "18"), + new AnagramClue("This anagram reveals who to speak to next: LAND DOOMD", "Odd Old Man", new WorldPoint(3359, 3506, 0), "Limestone mine northeast of Varrock"), + new AnagramClue("This anagram reveals who to speak to next: LARK IN DOG", "King Roald", new WorldPoint(3220, 3476, 0), "Ground floor of Varrock castle", "24"), + new AnagramClue("This anagram reveals who to speak to next: LOW LAG", "Gallow", new WorldPoint(1805, 3566, 0), "Vinery in the Great Kourend", "12"), + new AnagramClue("This anagram reveals who to speak to next: LADDER MEMO GUV", "Guard Vemmeldo", new WorldPoint(2447, 3418, 0), "Gnome Stronghold Bank", "3"), + new AnagramClue("This anagram reveals who to speak to next: I AM SIR", "Ambassador Alvijar", new WorldPoint(2721, 5358, 0), "Allotment patch, South coast Zeah", "5"), + new AnagramClue("This anagram reveals who to speak to next: MAL IN TAU", "Luminata", new WorldPoint(3508, 3237, 0), "Near Burgh de Rott entrance"), + new AnagramClue("This anagram reveals who to speak to next: ME AM THE CALC", "Cam the Camel", new WorldPoint(3300, 3231, 0), "Outside Duel Arena"), + new AnagramClue("This anagram reveals who to speak to next: MACHETE CLAM", "Cam the Camel", new WorldPoint(3300, 3231, 0), "Outside Duel Arena", "6"), + new AnagramClue("This anagram reveals who to speak to next: ME IF", "Femi", new WorldPoint(2461, 3382, 0), "Gates of Tree Gnome Stronghold"), + new AnagramClue("This anagram reveals who to speak to next: MOLD LA RAN", "Old Man Ral", new WorldPoint(3602, 3209, 0), "Meiyerditch"), + new AnagramClue("This anagram reveals who to speak to next: MOTHERBOARD", "Brother Omad", new WorldPoint(2606, 3211, 0), "Monastery south of Ardougne", "129"), + new AnagramClue("This anagram reveals who to speak to next: MUS KIL READER", "Radimus Erkle", new WorldPoint(2726, 3368, 0), "Legends' Guild"), + new AnagramClue("This anagram reveals who to speak to next: MY MANGLE LAL", "Lammy Langle", new WorldPoint(1688, 3540, 0), "Hosidius House spirit tree patch"), + new AnagramClue("This anagram reveals who to speak to next: NO OWNER", "Oronwen", new WorldPoint(1162, 3178, 0), "Lletya Seamstress shop in Lletya", "20"), + new AnagramClue("This anagram reveals who to speak to next: NOD MED", "Edmond", new WorldPoint(2566, 3332, 0), "Behind the most NW house in East Ardougne", "3"), + new AnagramClue("This anagram reveals who to speak to next: O BIRDZ A ZANY EN PC", "Cap'n Izzy no Beard", new WorldPoint(2807, 3191, 0), "Brimhaven Agility Arena", "33"), + new AnagramClue("This anagram reveals who to speak to next: OK CO", "Cook", new WorldPoint(3207, 3214, 0), "Ground floor of Lumbridge Castle", "9"), + new AnagramClue("This anagram reveals who to speak to next: OR ZINC FUMES WARD", "Wizard Frumscone", new WorldPoint(2594, 3086, 0), "Downstairs in the Wizards' Guild"), + new AnagramClue("This anagram reveals who to speak to next: OUR OWN NEEDS", "Nurse Wooned", new WorldPoint(1578, 3533, 0), "Shayzien House Infirmary", "52"), + new AnagramClue("This anagram reveals who to speak to next: PACINNG A TAIE", "Captain Ginea", new WorldPoint(1561, 3602, 0), "Building east of Shayzien combat ring", "113"), + new AnagramClue("This anagram reveals who to speak to next: PEAK REFLEX", "Flax keeper", new WorldPoint(2744, 3444, 0), "Flax field south of Seers Village", "676"), + new AnagramClue("This anagram reveals who to speak to next: PEATY PERT", "Party Pete", new WorldPoint(3047, 3376, 0), "Falador Party Room"), + new AnagramClue("This anagram reveals who to speak to next: PROFS LOSE WRONG PIE", "Professor Onglewip", new WorldPoint(3113, 3162, 0), "Ground floor Wizards Tower"), + new AnagramClue("This anagram reveals who to speak to next: QUIT HORRIBLE TYRANT", "Brother Tranquility", new WorldPoint(3681, 2963, 0), "Mos Le'Harmless or Harmony Island", "7"), + new AnagramClue("This anagram reveals who to speak to next: QUE SIR", "Squire", new WorldPoint(2975, 3343, 0), "Falador Castle Courtyard", "654"), + new AnagramClue("This anagram reveals who to speak to next: R AK MI", "Karim", new WorldPoint(3273, 3181, 0), "Al Kharid Kebab shop", "5"), + new AnagramClue("This anagram reveals who to speak to next: RAT MAT WITHIN", "Martin Thwait", new WorldPoint(2906, 3537, 0), "Rogues' Den", "2"), + new AnagramClue("This anagram reveals who to speak to next: RED ART TANS", "Trader Stan", new WorldPoint(3041, 3193, 0), "Port Sarim Charter ship"), + new AnagramClue("This anagram reveals who to speak to next: RATAI", "Taria", new WorldPoint(2940, 3223, 0), "Rimmington bush patch", "7"), + new AnagramClue("This anagram reveals who to speak to next: R SLICER", "Clerris", new WorldPoint(1761, 3850, 0), "Arceuus mine, Zeah", "738"), + new AnagramClue("This anagram reveals who to speak to next: SAND NUT", "Dunstan", new WorldPoint(2919, 3574, 0), "Anvil in north east Burthorpe", "8"), + new AnagramClue("This anagram reveals who to speak to next: SEQUIN DIRGE", "Queen Sigrid", new WorldPoint(2612, 3867, 0), "Throne room of Etceteria Castle."), + new AnagramClue("This anagram reveals who to speak to next: SLAM DUSTER GRAIL", "Guildmaster Lars", new WorldPoint(1649, 3498, 0), "Woodcutting guild, Zeah"), + new AnagramClue("This anagram reveals who to speak to next: SLIDE WOMAN", "Wise Old Man", new WorldPoint(3088, 3253, 0), "Draynor Village", "28"), + new AnagramClue("This anagram reveals who to speak to next: SNAH", "Hans", new WorldPoint(3218, 3219, 0), "Lumbridge Castle courtyard"), + new AnagramClue("This anagram reveals who to speak to next: SNAKES SO I SAIL", "Lisse Isaakson", new WorldPoint(2351, 3801, 0), "Neitiznot", "2"), + new AnagramClue("This anagram reveals who to speak to next: TAMED ROCKS", "Dockmaster", new WorldPoint(1822, 3739, 0), "Piscarilius House, NE of General store", "5"), + new AnagramClue("This anagram reveals who to speak to next: TEN WIGS ON", "Wingstone", new WorldPoint(3389, 2877, 0), "Between Nardah & Agility Pyramid"), + new AnagramClue("This anagram reveals who to speak to next: THEM CAL CAME", "Cam the Camel", new WorldPoint(3300, 3231, 0), "Just outside of the Duel Arena"), + new AnagramClue("This anagram reveals who to speak to next: THICKNO", "Hickton", new WorldPoint(2822, 3442, 0), "Catherby fletching shop", "2"), + new AnagramClue("This anagram reveals who to speak to next: TWENTY CURE IRON", "New recruit Tony", new WorldPoint(1498, 3544, 0), "Shayzien House's Graveyard"), + new AnagramClue("This anagram reveals who to speak to next: UNLEASH NIGHT MIST", "Sigli the Huntsman", new WorldPoint(2660, 3654, 0), "Rellekka", "302"), + new AnagramClue("This anagram reveals who to speak to next: VESTE", "Steve", new WorldPoint(2432, 3423, 0), "Upstairs Wyvern Area or Stronghold Slayer Cave", "2"), + new AnagramClue("This anagram reveals who to speak to next: VEIL VEDA", "Evil Dave", new WorldPoint(3079, 9892, 0), "Doris' basement, Edgeville", "666"), + new AnagramClue("This anagram reveals who to speak to next: WOO AN EGG KIWI", "Awowogei", new WorldPoint(2802, 2764, 0), "Ape Atoll", "24"), + new AnagramClue("This anagram reveals who to speak to next: YAWNS GY", "Ysgawyn", new WorldPoint(2340, 3167, 0), "Lletya") + ); + + private String text; + private String npc; + private WorldPoint location; + private String area; + private String answer; + + private AnagramClue(String text, String npc, WorldPoint location, String area) + { + this(text, npc, location, area, null); + } + + private AnagramClue(String text, String npc, WorldPoint location, String area, String answer) + { + this.text = text; + this.npc = npc; + this.location = location; + this.area = area; + this.answer = answer; + } + + @Override + public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) + { + panelComponent.setTitle("Anagram Clue"); + panelComponent.setWidth(150); + + panelComponent.getLines().add(new PanelComponent.Line("NPC:")); + panelComponent.getLines().add(new PanelComponent.Line(getNpc(), TITLED_CONTENT_COLOR)); + + panelComponent.getLines().add(new PanelComponent.Line("Area:")); + panelComponent.getLines().add(new PanelComponent.Line(true, getArea(), TITLED_CONTENT_COLOR)); + + if (getAnswer() != null) + { + panelComponent.getLines().add(new PanelComponent.Line("Answer:")); + panelComponent.getLines().add(new PanelComponent.Line(true, getAnswer(), TITLED_CONTENT_COLOR)); + } + } + + @Override + public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) + { + if (!getLocation().isInScene(plugin.getClient())) + { + return; + } + + if (plugin.getNpcsToMark() != null) + { + for (NPC npc : plugin.getNpcsToMark()) + { + OverlayUtil.renderActorOverlayImage(graphics, npc, CLUE_SCROLL_IMAGE, Color.ORANGE, IMAGE_Z_OFFSET); + } + } + } + + public static AnagramClue forText(String text) + { + for (AnagramClue clue : CLUES) + { + if (clue.text.equalsIgnoreCase(text)) + { + return clue; + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java new file mode 100644 index 0000000000..ea5d8ca393 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.Set; +import lombok.Getter; +import net.runelite.api.NPC; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.components.PanelComponent; +import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLUE_SCROLL_IMAGE; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; + +@Getter +public class CipherClue extends ClueScroll implements TextClueScroll, NpcClueScroll +{ + private static final Set CLUES = ImmutableSet.of( + new CipherClue("The cipher reveals who to speak to next: BMJ UIF LFCBC TFMMFS", "Ali the Kebab seller", new WorldPoint(3354, 2974, 0), "Pollnivneach", "399"), + new CipherClue("The cipher reveals who to speak to next: GUHCHO", "Drezel", new WorldPoint(3440, 9895, 0), "Paterdomus", "7"), + new CipherClue("The cipher reveals who to speak to next: ZCZL", "Adam", new WorldPoint(3227, 3227, 0), "Outside Lumbridge castle", "666"), + new CipherClue("The cipher reveals who to speak to next: ZHLUG ROG PDQ", "Weird Old Man", new WorldPoint(3224, 3112, 0), "Kalphite Lair entrance", "150"), + new CipherClue("The cipher reveals who to speak to next: ECRVCKP MJCNGF", "Captain Khaled", new WorldPoint(1845, 3754, 0), "Large eastern building in Piscarilius House", "5"), + new CipherClue("The cipher reveals who to speak to next: OVEXON", "Eluned", new WorldPoint(2289, 3144, 0), "Outside Lletya", "53,000"), + new CipherClue("The cipher reveals who to speak to next: VTYR APCNTGLW", "King Percival", new WorldPoint(2638, 4686, 0), "Fisher Realm", "5"), + new CipherClue("The cipher reveals who to speak to next: UZZU MUJHRKYYKJ", "Otto Godblessed", new WorldPoint(2501, 3487, 0), "Otto's Grotto", "3"), + new CipherClue("The cipher reveals who to speak to next: USBJCPSO", "Traiborn", new WorldPoint(3112, 3162, 0), "Wizard's Tower, 2nd floor", "3150"), + new CipherClue("The cipher reveals who to speak to next: HCKTA IQFHCVJGT", "Fairy Godfather", new WorldPoint(2446, 4428, 0), "Zanaris throne room", "64"), + new CipherClue("The cipher reveals who to speak to next: ZSBKDO ZODO", "Pirate Pete", new WorldPoint(3680, 3537, 0), "Dock northeast of the Ectofunctus", "Puzzle"), + new CipherClue("The cipher reveals who to speak to next: GBJSZ RVFFO", "Fairy Queen", new WorldPoint(2347, 4435, 0), "Fairy Resistance Hideout", "Puzzle"), + new CipherClue("The cipher reveals who to speak to next: QSPGFTTPS HSBDLMFCPOF", "Professor Gracklebone", new WorldPoint(1625, 3802, 0), "Arceuus House Library, ground floor", "9") + ); + + private String text; + private String npc; + private WorldPoint location; + private String area; + private String answer; + + private CipherClue(String text, String npc, WorldPoint location, String area, String answer) + { + this.text = text; + this.npc = npc; + this.location = location; + this.area = area; + this.answer = answer; + } + + @Override + public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) + { + panelComponent.setTitle("Cipher Clue"); + panelComponent.setWidth(150); + + panelComponent.getLines().add(new PanelComponent.Line("NPC:")); + panelComponent.getLines().add(new PanelComponent.Line(getNpc(), TITLED_CONTENT_COLOR)); + + panelComponent.getLines().add(new PanelComponent.Line("Area:")); + panelComponent.getLines().add(new PanelComponent.Line(true, getArea(), TITLED_CONTENT_COLOR)); + + if (getAnswer() != null) + { + panelComponent.getLines().add(new PanelComponent.Line("Answer:")); + panelComponent.getLines().add(new PanelComponent.Line(true, getAnswer(), TITLED_CONTENT_COLOR)); + } + } + + @Override + public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) + { + if (!getLocation().isInScene(plugin.getClient())) + { + return; + } + + if (plugin.getNpcsToMark() != null) + { + for (NPC npc : plugin.getNpcsToMark()) + { + OverlayUtil.renderActorOverlayImage(graphics, npc, CLUE_SCROLL_IMAGE, Color.ORANGE, IMAGE_Z_OFFSET); + } + } + } + + public static CipherClue forText(String text) + { + for (CipherClue clue : CLUES) + { + if (clue.text.equalsIgnoreCase(text)) + { + return clue; + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ClueScroll.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ClueScroll.java new file mode 100644 index 0000000000..95a3ecded8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ClueScroll.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +import java.awt.Graphics2D; +import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import net.runelite.client.ui.overlay.components.PanelComponent; + +public abstract class ClueScroll +{ + public abstract void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin); + + public abstract void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin); +} 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 new file mode 100644 index 0000000000..82d49f2721 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +import java.awt.Color; +import java.awt.Graphics2D; +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.components.PanelComponent; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.SPADE_IMAGE; + +@Getter +@AllArgsConstructor +public class CoordinateClue extends ClueScroll implements TextClueScroll +{ + private String text; + private WorldPoint location; + + @Override + public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) + { + panelComponent.setTitle("Coordinate Clue"); + panelComponent.setWidth(135); + + panelComponent.getLines().add(new PanelComponent.Line("Travel to the marked")); + panelComponent.getLines().add(new PanelComponent.Line("out destination to see")); + panelComponent.getLines().add(new PanelComponent.Line("a marker for where")); + panelComponent.getLines().add(new PanelComponent.Line("you should dig.")); + } + + @Override + public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) + { + LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation()); + + if (localLocation == null) + { + return; + } + + OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, SPADE_IMAGE, Color.ORANGE); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java new file mode 100644 index 0000000000..bd9aebdce7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.Set; +import lombok.Getter; +import net.runelite.api.GameObject; +import net.runelite.api.NPC; +import net.runelite.api.ObjectComposition; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.components.PanelComponent; +import static net.runelite.api.ObjectID.*; +import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_BORDER_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_FILL_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_HOVER_BORDER_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLUE_SCROLL_IMAGE; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.SPADE_IMAGE; + +@Getter +public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueScroll, ObjectClueScroll +{ + private static final Set CLUES = ImmutableSet.of( + new CrypticClue("Show this to Sherlock.", "Sherlock", new WorldPoint(2733, 3415, 0), "Sherlock is located to the east of the Sorcerer's tower in Seers' Village."), + new CrypticClue("Talk to the bartender of the Rusty Anchor in Port Sarim.", "Bartender", new WorldPoint(3045, 3256, 0), "The Rusty Anchor is located in the north of Port Sarim."), + new CrypticClue("The keeper of Melzars... Spare? Skeleton? Anar?", "Oziach", new WorldPoint(3068, 3516, 0), "Speak to Oziach in Edgeville"), + new CrypticClue("Speak to Ulizius.", "Ulizius", new WorldPoint(3444, 3461, 0), "Ulizius is the monk who guards the gate into Mort Myre Swamp."), + new CrypticClue("Search for a crate in a building in Hemenster.", CRATE_356, new WorldPoint(2636, 3454, 0), "House north of the Fishing Contest quest area. West of Grandpa Jack."), + new CrypticClue("A reck you say Let's pray there aren't any ghosts.", "Father Aereck", new WorldPoint(3242, 3207, 0), "Speak to Father Aereck in Lumbridge."), + new CrypticClue("Search the bucket in the Port Sarim jail.", NULL_337, new WorldPoint(3012, 3179, 0), "Talk to Shantay & identify yourself as an outlaw, refuse to pay the 5gp fine twice and you will be sent to the Port Sarim jail."), + new CrypticClue("Search the crates in a bank in Varrock.", NULL_336, new WorldPoint(3187, 9824, 0), "Search in the basement of the West Varrock bank."), + new CrypticClue("Falo the bard wants to see you.", "Falo the Bard", new WorldPoint(2689, 3550, 0), "Speak to Falo the Bard"), + new CrypticClue("Search a bookcase in the Wizards tower.", BOOKCASE_12539, new WorldPoint(3113, 3159, 0), "The bookcase located on the ground floor."), + new CrypticClue("Come have a cip with this great soot covered denizen.", "Miner Magnus", new WorldPoint(2527, 3891, 0), "Talk to Miner Magnus east of the fairy ring CIP. Answer: 8"), + new CrypticClue("Citric cellar.", "Heckel Funch", new WorldPoint(2490, 3488, 0), "Speak to Heckel Funch on the first floor in the Grand Tree."), + new CrypticClue("I burn between heroes and legends.", "Candle maker", new WorldPoint(2799, 3438, 0), "Speak to the Candle maker in Catherby."), + new CrypticClue("Speak to Sarah at Falador farm.", "Sarah", new WorldPoint(3038, 3292, 0), "Talk to Sarah at Falador farm, north of Port Sarim."), + new CrypticClue("Search for a crate on the ground floor of a house in Seers' Village.", NULL_25890, new WorldPoint(2699, 3469, 0), "Search inside Phantuwti Fanstuwi Farsight's house, located south of the pub in Seers' Village."), + new CrypticClue("Snah? I feel all confused, like one of those cakes...", "Hans", new WorldPoint(3211, 3219, 0), "Talk to Hans roaming around Lumbridge Castle."), + new CrypticClue("Speak to Sir Kay in Camelot Castle.", "Sir Kay", new WorldPoint(2759, 3497, 0), "Sir Kay can be found in the courtyard at Camelot castle."), + new CrypticClue("Gold I see, yet gold I require. Give me 875 if death you desire.", "Saniboch", new WorldPoint(2745, 3151, 0), "Speak to Saniboch at the Brimhaven Dungeon entrance."), + new CrypticClue("Find a crate close to the monks that like to paaarty!", CRATE_354, new WorldPoint(2614, 3204, 0), "The crate is in the east side of the Kandarin monastery, near Brother Omad"), + new CrypticClue("Identify the back of this over-acting brother. (He's a long way from home.)", "Hamid", new WorldPoint(3376, 3284, 0), "Talk to Hamid, the monk at the altar in the Duel Arena"), + new CrypticClue("In a town where thieves steal from stalls, search for some drawers in the upstairs of a house near the bank.", new WorldPoint(2611, 3324, 0), "Kill any Guard located around East Ardougne for a medium key. Then search the drawers in the upstairs hallway of Jerico's house, which is the house with pigeon cages located south of the northern East Ardougne bank."), + new CrypticClue("His bark is worse than his bite.", "Barker", new WorldPoint(3499, 3503, 0), "Speak to the Barker at Canifis's Barkers' Haberdashery."), + new CrypticClue("The beasts to my east snap claws and tails, The rest to my west can slide and eat fish. The force to my north will jump and they'll wail, Come dig by my fire and make a wish.", new WorldPoint(2598, 3267, 0), "Dig by the torch in the Ardougne Zoo, between the penguins and the scorpions."), + new CrypticClue("A town with a different sort of night-life is your destination. Search for some crates in one of the houses.", CRATE_24344, new WorldPoint(3499, 3507, 1), "Search the crate inside of the clothes shop in Canifis."), + new CrypticClue("Stop crying! Talk to the head.", "Head mourner", new WorldPoint(2042, 4630, 0), "Talk to the Head mourner in the mourner headquarters in West Ardougne"), + new CrypticClue("Search the crate near a cart in Port Khazard.", CRATE_366, new WorldPoint(2660, 3149, 0), "Search by the southern Khazard General Store in Port Khazard."), + new CrypticClue("Speak to the bartender of the Blue Moon Inn in Varrock.", "Blue Moon Inn", new WorldPoint(3226, 3399, 0), "Talk to the bartender in Blue Moon Inn in Varrock."), + new CrypticClue("This aviator is at the peak of his profession.", "Captain Bleemadge", new WorldPoint(2846, 1749, 0), "Captain Bleemadge, the gnome glider pilot, is found at the top of White Wolf Mountain."), + new CrypticClue("Search the crates in the shed just north of East Ardougne.", NULL_1247, new WorldPoint(2618, 3346, 0), "The crates in the shed north of the northern Ardougne bank."), + new CrypticClue("I wouldn't wear this jean on my legs.", "Father Jean", new WorldPoint(1697, 3574, 0), "Talk to father Jean in the Hosidius church"), + new CrypticClue("Search the crate in the Toad and Chicken pub.", NULL_1827, new WorldPoint(2912, 3536, 0), "The Toad and Chicken pub is located in Burthorpe."), + new CrypticClue("Search chests found in the upstairs of shops in Port Sarim.", BOOKCASE_380, new WorldPoint(3016, 3204, 1), "Search the chest in the upstairs of Wydin's Food Store, on the east wall."), + new CrypticClue("Right on the blessed border, cursed by the evil ones. On the spot inaccessible by both; I will be waiting. The bugs imminent possession holds the answer.", new WorldPoint(3410, 3324, 0), "B I P. Dig right under the fairy ring."), + new CrypticClue("The dead, red dragon watches over this chest. He must really dig the view.", "Barbarian", 375, new WorldPoint(3353, 3332, 0), "Search the chest underneath the Red Dragon's head in the Exam Centre. Kill a MALE Barbarian in Barbarian Village or Barbarian Outpost to receive the key."), + new CrypticClue("My home is grey, and made of stone; A castle with a search for a meal. Hidden in some drawers I am, across from a wooden wheel.", DRAWERS_5618, new WorldPoint(3213, 3216, 1), "Open the drawers inside the room with the spinning wheel on the first floor of Lumbridge Castle."), + new CrypticClue("Come to the evil ledge, Yew know yew want to. Try not to get stung.", new WorldPoint(3089, 3468, 0), "Dig in Edgeville, just east of the Southern Yew tree."), + new CrypticClue("Look in the ground floor crates of houses in Falador.", NULL_5536, new WorldPoint(3027, 3356, 0), "The house east of the east bank."), + new CrypticClue("You were 3 and I was the 6th. Come speak to me.", "Vannaka", new WorldPoint(3146, 9913, 0), "Speak to Vannaka in Edgeville Dungeon."), + new CrypticClue("Search the crates in Draynor Manor.", CRATES_11486, new WorldPoint(3105, 3369, 2), "Top floor of the manor"), + new CrypticClue("Search the crates near a cart in Varrock.", MILL_2571, new WorldPoint(3226, 3452, 0), "South east of Varrock Palace, south of the tree farming patch."), + new CrypticClue("A Guthixian ring lies between two peaks. Search the stones and you'll find what you seek.", STONES_26633, new WorldPoint(2922, 3484, 0), "Search the stones several steps west of the Guthixian stone circle in Taverley"), + new CrypticClue("Search the boxes in the house near the south entrance to Varrock.", TABLE_2496, new WorldPoint(3204, 3384, 0), "The first house on the left when entering the city from the southern entrance."), + new CrypticClue("His head might be hollow, but the crates nearby are filled with surprises.", CRATE_354, new WorldPoint(3478, 3091, 0), "Search the crates near the Clay golem in the ruins of Uzer."), + new CrypticClue("One of the sailors in Port Sarim is your next destination.", "Captain Tobias", new WorldPoint(3026, 3216, 0), "Speak to Captain Tobias on the docks of Port Sarim."), + new CrypticClue("THEY'RE EVERYWHERE!!!! But they were here first. Dig for treasure where the ground is rich with ore.", new WorldPoint(3081, 3421, 0), "Dig at Barbarian Village, next to the Stronghold of Security."), + new CrypticClue("Talk to the mother of a basement dwelling son.", "Doris", new WorldPoint(3079, 3493, 0), "Evil Dave's mother, Doris is located in the house west of Edgeville bank."), + new CrypticClue("Speak to Ned in Draynor Village.", "Ned", new WorldPoint(3098, 3258, 0), "Ned is found north or the Draynor bank."), + new CrypticClue("Speak to Hans to solve the clue.", "Hans", new WorldPoint(3211, 3219, 0), "Hans can be found at Lumbridge Castle."), + new CrypticClue("Search the crates in Canifis.", CRATE_24344, new WorldPoint(3509, 3497, 1), "Search inside the shop, Rufus' Meat Emporium."), + new CrypticClue("Search the crates in the Dwarven mine.", CRATE_356, new WorldPoint(3034, 9849, 0), "Search the east of the Ice Mountain ladder entrance in the Drogo's Mining Emporium."), + new CrypticClue("A crate found in the tower of a church is your next location.", NULL_10627, new WorldPoint(2612, 3304, 1), "Climb the ladder and search the crates on the 1st floor in the Church in Ardougne"), + new CrypticClue("Covered in shadows, the centre of the circle is where you will find the answer.", new WorldPoint(3488, 3289, 0), "Dig in the centre of Mort'ton, where the roads intersect"), + new CrypticClue("I lie lonely and forgotten in mid wilderness, where the dead rise from their beds. Feel free to quarrel and wind me up and dig while you shoot their heads.", new WorldPoint(3174, 3663, 0), "Directly under the crossbow respawn in the Graveyard of Shadows in level 18 Wilderness."), + new CrypticClue("In the city where merchants are said to have lived, talk to a man with a splendid cape, but a hat dropped by goblins.", "Head chef", new WorldPoint(3143, 3445, 0), "Talk to the Head chef in Cooks' Guild west of Varrock."), + new CrypticClue("The mother of the reptilian sacrifice.", "Zul-Cheray", new WorldPoint(2204, 3050, 0), "Talk to Zul-Cheray in a house near the sacrificial boat at Zul-Andra."), + new CrypticClue("I watch the sea. I watch you fish. I watch your tree.", "Ellena", new WorldPoint(2860, 3431, 0), "Speak to Ellena at Catherby fruit tree patch."), + new CrypticClue("Dig between some ominous stones in Falador.", new WorldPoint(3040, 3399, 0), "Three standing stones inside a walled area. East of the northern Falador gate."), + new CrypticClue("Speak to Rusty north of Falador.", "Rusty", new WorldPoint(2979, 3435, 0), "Rusty can be found northeast of Falador on the way to the Mind altar."), + new CrypticClue("Search a wardrobe in Draynor.", NULL_5620, new WorldPoint(3088, 3259, 0), "Go to Aggie's house and search the wardrobe in northern wall."), + new CrypticClue("Show this to Sherlock", "Sherlock", new WorldPoint(2733, 3415, 0), "Sherlock can be found south of Seer's Village."), + new CrypticClue("I have many arms but legs, I have just one, I have little family but my seed, You can grow on, I am not dead, yet I am but a spirit, and my power on your quests, you will earn the right to free it.", NULL_1293, new WorldPoint(2542, 3170, 0), "Spirit Tree in Tree Gnome Village"), + new CrypticClue("I am the one who watches the giants. The giants in turn watch me. I watch with two while they watch with one. Come seek where I may be.", "Kamfreena", new WorldPoint(2845, 3539, 0), "Speak to Kamfreena on the top floor of the Warriors' Guild."), + new CrypticClue("In a town where wizards are known to gather, search upstairs in a large house to the north.", new WorldPoint(2595, 3105, 0), "Search the chest, upstairs, in the house north of Yanille Wizards' Guild. Open the chest to receive the message: The chest is locked! An inscription on the chest reads: Stand by your man. Head downstairs to kill a Man."), + new CrypticClue("Probably filled with wizards socks.", "Wizard", new WorldPoint(3109, 9959, 0), "Search the drawers in the basement of the Wizard's Tower south of Draynor Village. Kill one of the Wizards for the key."), + new CrypticClue("Even the seers say this clue goes right over their heads.", CRATE_26635, new WorldPoint(2707, 3488, 2), "Search the crate on the Seers Agility Course in Seers Village"), + new CrypticClue("Speak to a Wyse man.", "Wyson the gardener", new WorldPoint(3026, 3378, 0), "Talk to Wyson the gardener at Falador Park."), + new CrypticClue("You'll need to look for a town with a central fountain. Look for a locked chest in the town's chapel.", CLOSED_CHEST_5108, new WorldPoint(3256, 3487, 0), "Search the chest by the stairs in the Varrock church. Kill a Monk in Ardougne Monastery to obtain the key."), + new CrypticClue("Talk to Ambassador Spanfipple in the White Knights Castle.", "Ambassador Spanfipple", new WorldPoint(2979, 3340, 0), "Ambassador Spanfipple can be found roaming on the 2nd floor of the White Knights Castle."), + new CrypticClue("Mine was the strangest birth under the sun. I left the crimson sack, yet life had not begun. Entered the world, and yet was seen by none.", new WorldPoint(2832, 9586, 0), "Inside Karamja Volcano, dig directly underneath the Red spiders' eggs respawn."), + new CrypticClue("Search for a crate in Varrock Castle.", CRATE_5110, new WorldPoint(3223, 3492, 0), "Search the crate in the corner of the kitchen in Varrock Castle."), + new CrypticClue("And so on, and so on, and so on. Walking from the land of many unimportant things leads to a choice of paths.", new WorldPoint(2591, 3879, 0), "Dig on Etceteria next to the Evergreen tree in front of the castle walls."), + new CrypticClue("Speak to Donovan, the Family Handyman.", "Donovan the Family Handyman", new WorldPoint(2743, 3578, 0), "Donovan the Family Handyman is found on the 2nd floor of Sinclair Mansion."), + new CrypticClue("Search the crates in the Barbarian Village helmet shop.", NULL_10627, new WorldPoint(3073, 3430, 0), "Peska's Helmet Shop in Barbarian Village."), + new CrypticClue("Search the boxes of Falador's general store.", CRATES_24088, new WorldPoint(2955, 3390, 0), "Falador general store."), + new CrypticClue("In a village made of bamboo, look for some crates under one of the houses.", CRATE_356, new WorldPoint(2799, 3074, 0), "Search the crate by the house at the northern point of the broken jungle fence in Tai Bwo Wannai."), + new CrypticClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", "Jorral", new WorldPoint(2437, 3347, 0), "Speak to Jorral to receive a strange device."), + new CrypticClue("This crate is mine, all mine, even if it is in the middle of the desert.", new WorldPoint(3290, 3022, 0), "Center of desert Mining Camp. Search the crates. Requires the metal key from Tourist Trap to enter."), + new CrypticClue("Dig where 4 siblings and I all live with our evil overlord.", new WorldPoint(3195, 3357, 0), "Dig in the chicken pen inside the Champion's Guild"), + new CrypticClue("In a town where the guards are armed with maces, search the upstairs rooms of the Public House.", "Guard Dog", 348, new WorldPoint(2574, 3326, 1), "Search the drawers in the pub north of Ardougne Castle. Kill a Guard dog at Handelmort Mansion to obtain the key."), + new CrypticClue("Four blades I have, yet draw no blood; Still I turn my prey to powder. If you are brave, come search my roof; It is there my blades are louder.", NULL_1784, new WorldPoint(3167, 3307, 2), "Lumbridge windmill, search the crates on the top floor."), + new CrypticClue("Search through some drawers in the upstairs of a house in Rimmington.", NULL_10627, new WorldPoint(2970, 3214, 1), "On the first floor of the house north of Hetty the Witch's house in Rimmington."), + new CrypticClue("Probably filled with books on magic.", BOOKCASE_380, new WorldPoint(3096, 9572, 0), "Search the bookcase in the basement of Wizard's Tower."), + new CrypticClue("If you look closely enough, it seems that the archers have lost more than their needles.", HAYSTACK, new WorldPoint(2672, 3416, 0), "Search the haystack by the south corner of the Rangers' Guild"), + new CrypticClue("Search the crate in the left-hand tower of Lumbridge Castle.", CRATE_357, new WorldPoint(3228, 3212, 1), "Located on the first floor of the southern tower at the Lumbridge Castle entrance."), + new CrypticClue("'Small shoe.' Often found with rod on mushroom.", "Gnome trainer", new WorldPoint(2476, 3428, 0), "Talk to any Gnome trainer in the agility area of the Tree Gnome Stronghold."), + new CrypticClue("I live in a deserted crack collecting soles.", "Genie", new WorldPoint(3371, 9320, 0), "Enter the crack west of Nardah Rug merchant, and talk to the Genie."), + new CrypticClue("46 is my number. My body is the colour of burnt orange and crawls among those with eight. Three mouths I have, yet I cannot eat. My blinking blue eye hides my grave.", new WorldPoint(3170, 3885, 0), "Sapphire respawn in the Spider's Nest, lvl 46 Wilderness. Dig under the sapphire spawn."), + new CrypticClue("Green is the colour of my death as the winter-guise, I swoop towards the ground.", new WorldPoint(2780, 3783, 0), "Players need to slide down to where Trollweiss grows on Trollweiss Mountain."), + new CrypticClue("Talk to a party-goer in Falador.", "Lucy", new WorldPoint(3046, 3382, 0), "Lucy is the bartender on the 1st2nd floor[U.K. floor] of the party room."), + new CrypticClue("He knows just how easy it is to lose track of time.", "Brother Kojo", new WorldPoint(2570, 3250, 0), "Speak to brother Kojo in the Clock Tower."), + new CrypticClue("A great view - watch the rapidly drying hides get splashed. Check the box you are sitting on.", NULL_1838, new WorldPoint(2523, 3493, 1), "Almera's House north of Baxtorian Falls, search boxes on the 2nd floor."), + new CrypticClue("Search the Coffin in Edgeville.", COFFIN, new WorldPoint(3091, 3477, 0), "Search the coffin located by the Wilderness teleport lever."), + new CrypticClue("When no weapons are at hand, now it is time to reflect, in Saradomin's name! Redemption draws closer...", DRAWERS_350, new WorldPoint(2818, 3351, 0), "On Entrana, search the southern drawer in the house with the cooking range."), + new CrypticClue("Search the crates in a house in Yanille that has a piano.", NULL_17088, new WorldPoint(2598, 3105, 0), "The house is located northwest of the bank."), + new CrypticClue("Speak to the staff of Sinclair mansion.", "Louisa", new WorldPoint(2736, 3578, 0), "Speak to Louisa, on the ground floor, found at the Sinclair Mansion."), + new CrypticClue("I am a token of the greatest love. I have no beginning or end. My eye is red, I can fit like a glove. Go to the place where it's money they lend, And dig by the gate to be my friend.", new WorldPoint(3191, 9825, 0), "Dig by the gate in the basement of the West Varrock bank."), + new CrypticClue("Speak to Kangai Mau.", "Kangai Mau", new WorldPoint(2791, 3183, 0), "Kangai Mau is found in the Shrimp and Parrot in Brimhaven."), + new CrypticClue("Speak to Hajedy.", "Hajedy", new WorldPoint(2779, 3211, 0), "Hajedy is found by the cart, located just south of the Brimhaven docks."), + new CrypticClue("Must be full of railings.", BOXES_6176, new WorldPoint(2576, 3464, 0), "Search the boxes around the hut where the broken Dwarf Cannon is, close to the start of the Dwarf Cannon quest."), + new CrypticClue("I wonder how many bronze swords he has handed out.", "Vannaka", new WorldPoint(3164, 9913, 0), "Talk to Vannaka. He can be found in Edgeville Dungeon."), + new CrypticClue("Read 'How to breed scorpions.' By O.W.Thathurt.", BOOKCASE_380, new WorldPoint(2703, 3409, 1), "Search the northern bookcase on the 1st2nd floor[U.K. floor] of the Sorcerer's Tower."), + new CrypticClue("Search the crates in the Port Sarim Fishing shop.", NULL_918, new WorldPoint(3013, 3222, 0), "Search the crates, by the door, in Gerrant's Fishy Business in Port Sarim."), + new CrypticClue("Speak to the Lady of the Lake.", "Lady of the Lake", new WorldPoint(2924, 3405, 0), "Talk to the Lady of the Lake in Taverley."), + new CrypticClue("Rotting next to a ditch. Dig next to the fish", new WorldPoint(3547, 3183, 0), "Dig next to a fishing spot on the south-east side of Burgh de Rott."), + new CrypticClue("The King's magic won't be wasted by me.", "Guardian Mummy", new WorldPoint(1934, 4427, 0), "Talk to the Guardian mummy inside the Pyramid Plunder minigame in Sophanem"), + new CrypticClue("Dig where the forces of Zamorak and Saradomin collide.", new WorldPoint(3049, 4839, 0), "Dig next to the law rift in the Abyss"), + new CrypticClue("Search the boxes in the goblin house near Lumbridge.", NULL_10627, new WorldPoint(3245, 3245, 0), "Goblin house on the eastern side of the river."), + new CrypticClue("W marks the spot.", new WorldPoint(2867, 3546, 0), "Dig in the middle of the Warriors' Guild entrance hall"), + new CrypticClue("There is no 'worthier' lord.", "Lord Iorwerth", new WorldPoint(2205, 3252, 0), "Speak to Lord Iorwerth in the elven camp near Prifddinas"), + new CrypticClue("Surviving.", "Sir Vyvin", new WorldPoint(2983, 3338, 0), "Talk to Sir Vyvin on the 3rd floor of Falador castle."), + new CrypticClue("My name is like a tree, yet it is spelt with a 'g'. Come see the fur which is right near me.", "Wilough", new WorldPoint(3221, 3435, 0), "Speak to Wilough, next to the Fur Merchant in Varrock Square."), + new CrypticClue("Speak to Jatix in Taverley.", "Jatix", new WorldPoint(2898, 3428, 0), "Jatix is found in the middle of Taverley."), + new CrypticClue("Speak to Gaius in Taverley.", "Gaius", new WorldPoint(2884, 3450, 0), "Gaius is found at the northwest corner in Taverley."), + new CrypticClue("If a man carried my burden, he would break his back. I am not rich, but leave silver in my track. Speak to the keeper of my trail.", "Gerrant", new WorldPoint(3013, 3224, 0), "Speak to Gerrant in the fish shop in Port Sarim."), + new CrypticClue("Search the drawers in Falador's chain mail shop.", DRAWERS, new WorldPoint(2972, 3312, 0), "Wayne's Chains - Chainmail Specialist store at the southern Falador walls."), + new CrypticClue("Talk to the barber in the Falador barber shop.", "Hairdresser", new WorldPoint(2945, 3379, 0), "The Hairdresser can be found in the barber shop, north of the west Falador bank."), + new CrypticClue("Often sought out by scholars of histories past, find me where words of wisdom speak volumes.", "Examiner", new WorldPoint(3362, 3341, 0), "Speak to an examiner at the Exam Centre."), + new CrypticClue("Generally speaking, his nose was very bent.", "General Bentnoze", new WorldPoint(2957, 3511, 0), "Talk to General Bentnoze"), + new CrypticClue("Search the bush at the digsite centre.", BUSH_2357, new WorldPoint(3345, 3378, 0), "The bush is on the east side of the first pathway towards the digsite from the Exam Centre."), + new CrypticClue("Someone watching the fights in the Duel Arena is your next destination.", "Jeed", new WorldPoint(3360, 3242, 0), "Talk to Jeed, found on the upper floors, at the Duel Arena."), + new CrypticClue("It seems to have reached the end of the line, and it's still empty.", NULL_638, new WorldPoint(3041, 9821, 0), "Search the carts in the northern part of the Dwarven Mine."), + new CrypticClue("You'll have to plug your nose if you use this source of herbs.", new WorldPoint(3426, 3550, 1), "Kill an Aberrant spectre and pick up the casket"), + new CrypticClue("When you get tired of fighting, go deep, deep down until you need an antidote.", CRATE_357, new WorldPoint(2576, 9583, 0), "Go to Yanille Agility dungeon and fall into the place with the poison spiders. Search the crate by the stairs leading up."), + new CrypticClue("Search the bookcase in the monastery.", BOOKCASE_380, new WorldPoint(3054, 3484, 0), "Search the southeastern bookcase at Edgeville Monastery."), + new CrypticClue("Surprising? I bet he is...", "Sir Prysin", new WorldPoint(3205, 3474, 0), "Talk to Sir Prysin in Varrock Palace."), + new CrypticClue("Search upstairs in the houses of Seers' Village for some drawers.", NULL_925, new WorldPoint(2714, 3471, 1), "Located in the house with the spinning wheel. South of the Seers' Village bank."), + new CrypticClue("Leader of the Yak City.", "Mawnis Burowgar", new WorldPoint(2336, 3799, 0), "Talk to Mawnis Burowgar in Neitiznot."), + new CrypticClue("Speak to Arhein in Catherby.", "Arhein", new WorldPoint(2803, 3430, 0), "Arhein is just south of the Catherby bank."), + new CrypticClue("Speak to Doric, who lives north of Falador.", "Doric", new WorldPoint(2951, 3451, 0), "Doric is found north of Falador and east of the Taverley gate."), + new CrypticClue("Between where the best are commemorated for a year, and a celebratory cup, not just for beer.", new WorldPoint(3388, 3152, 0), "Dig at the Clan Cup Trophy at Clan Wars."), + new CrypticClue("'See you in your dreams' said the vegetable man.", "Dominic Onion", new WorldPoint(2608, 3116, 0), "Speak to Dominic Onion at the Nightmare Zone teleport spot."), + new CrypticClue("Try not to step on any aquatic nasties while searching this crate.", CRATE_18204, new WorldPoint(2764, 3273, 0), "Search the crate in Bailey's house on the Fishing Platform."), + new CrypticClue("The cheapest water for miles around, but they react badly to religious icons.", CRATE_354, new WorldPoint(3178, 2987, 0), "Search the crates in the General Store tent in the Bandit Camp"), + new CrypticClue("This village has a problem with cartloads of the undead. Try checking the bookcase to find an answer.", BOOKCASE_394, new WorldPoint(2833, 2992, 0), "Search the bookcase by the doorway of the building just south east of the Shilo Village Gem Mine."), + new CrypticClue("Dobson is my last name, and with gardening I seek fame.", "Horacio", new WorldPoint(2635, 3310, 0), "Horacio, located in the garden of the Handelmort Mansion in East Ardougne."), + new CrypticClue("The magic of 4 colours, an early experience you could learn. The large beast caged up top, rages, as his demised kin's loot now returns.", "Wizard Mizgog", new WorldPoint(3103, 3163, 2), "Speak to Wizard Mizgog at the top of the Wizard's Tower south of Draynor."), + new CrypticClue("Aggie I see, Lonely and southern I feel I am neither inside nor outside the house yet no house would be complete without me. Your treasure lies beneath me.", new WorldPoint(3085, 3255, 0), "Dig outside the window of Aggies house in Draynor Village."), + new CrypticClue("Search the chest in Barbarian Village.", null, "The chest located in the house with a spinning wheel."), + new CrypticClue("Search the crates in the outhouse of the long building in Taverley.", null, "Located in the small building attached by a fence to the main building. Climb over the stile."), + new CrypticClue("Talk to Ermin.", null, "Ermin can be found on the 1st floor of the tree house south-east of the Gnome Agility Course."), + new CrypticClue("Ghostly bones.", null, "Kill an Ankou"), + new CrypticClue("Search through chests found in the upstairs of houses in eastern Falador.", null, "The house is located southwest of the Falador Party Room. There are two chests in the room, search the northern chest."), + new CrypticClue("Let's hope you don't meet a watery death when you encounter this fiend.", null, "Kill a waterfiend."), + new CrypticClue("Reflection is the weakness for these eyes of evil.", "Falo the Bard", null, "Kill a basilisk"), + new CrypticClue("Search a bookcase in Lumbridge swamp.", null, "Located in Father Urhney's house."), + new CrypticClue("Surround my bones in fire, ontop the wooden pyre. Finally lay me to rest, before my one last test.", null, "Kill a confused/lost barbarian to receive mangled bones. Construct and burn a pyre ship. Kill the ferocious barbarian spirit that spawns to receive a clue casket."), + new CrypticClue("Fiendish cooks probably won’t dig the dirty dishes.", null, "Dig by the fire in the Rogues' Den."), + new CrypticClue("My life was spared but these voices remain, now guarding these iron gates is my bane.", null, "Speak to the Key Master in Cerberus' Lair."), + new CrypticClue("Search the boxes in one of the tents in Al Kharid.", null, "Search the crates in the tent east of the Silk trader."), + new CrypticClue("One of several rhyming brothers, in business attire with an obsession for paper work.", null, "Speak to Piles in the Resource Area."), + new CrypticClue("Search the drawers on the first floor of a building overlooking Ardougne's Market.", null, "Climb the ladder in the house north of the market."), + new CrypticClue("'A bag belt only?', he asked his balding brothers.", null, "Talk to Abbot Langley in the monastery"), + new CrypticClue("Search the drawers upstairs in Falador's shield shop.", null, "Cassie's Shield Shop at the northern Falador entrance."), + new CrypticClue("Go to this building to be illuminated, and check the drawers while you are there.", "Market Guard", null, "The 2nd of the Lighthouse, Kill a Rellekka marketplace guard to obtain the key."), + new CrypticClue("Dig near some giant mushrooms behind the Grand Tree.", null, "Dig near the red mushrooms northwest of the Grand Tree."), + new CrypticClue("Pentagrams and demons, burnt bones and remains, I wonder what the blood contains.", null, "Dig under the blood rune spawn next the the Demonic Ruins."), + new CrypticClue("Search the drawers above Varrock's shops.", null, "Located upstairs in Thessalia's Fine Clothes shop in Varrock."), + new CrypticClue("Search the drawers in one of Gertrude's bedrooms.", null, "Kanel's bedroom (southeastern room), outside of west Varrock."), + new CrypticClue("Under a giant robotic bird that cannot fly.", null, "Dig next to the terrorbird display in the south exhibit of Varrock Museum's basement."), + new CrypticClue("Great demons, dragons, and spiders protect this blue rock, beneath which, you may find what you seek.", null, "Dig by the runite rock in the Lava Maze Dungeon"), + new CrypticClue("My giant guardians below the market streets would be fans of rock and roll, if only they could grab hold of it. Dig near my green bubbles!", null, "Dig near the cauldron by Moss Giants under Varrock Sewers"), + new CrypticClue("Varrock is where I reside not the land of the dead, but I am so old, I should be there instead. Let's hope your reward is as good as it says, just 1 gold one and you can have it read.", null, "Talk to Gypsy Aris, West of varrock main square."), + new CrypticClue("Speak to a referee.", null, "Talk to a Gnome ball referee found on the Gnome ball field in the Gnome Stronghold."), + new CrypticClue("This crate holds a better reward than a broken arrow.", null, "Inside the Ranging Guild. Search the crate behind the northern most building."), + new CrypticClue("Search the drawers in the house next to the Port Sarim mage shop.", null, "House east of Betty's. Contains a cooking sink."), + new CrypticClue("With a name like that, you'd expect a little more than just a few scimitars.", null, "Speak to Daga on Ape Atoll."), + new CrypticClue("Strength potions with red spiders' eggs? He is quite a herbalist.", null, "Talk to Apothecary in the South-western Varrock. (the) apothecary is just north-west of the Varrock Swordshop."), + new CrypticClue("Robin wishes to see your finest range equipment.", null, "Robin at the inn in Port Phasmatys. Speak to him with +182 in ranged attack bonus."), + new CrypticClue("You will need to under-cook to solve this one.", null, "Search the crate in the Lumbridge basement."), + new CrypticClue("Search through some drawers found in Taverley's houses.", null, "The south-eastern most house, south of Jatix's Herblore Shop."), + new CrypticClue("Anger Abbot Langley.", null, "Speak to Abbot Langley while you have a negative prayer bonus"), + new CrypticClue("Dig where only the skilled, the wealthy, or the brave can choose not to visit again.", null, "Dig at Lumbridge spawn"), + new CrypticClue("Scattered coins and gems fill the floor. The chest you seek is in the north east.", null, "Kill the King Black Dragon for a key (elite), and then open the closed chest in the NE corner of the lair."), + new CrypticClue("A ring of water surrounds 4 powerful rings. Dig by the ladder that is located there.", null, "Dig by the ladder leading to the Dagannoth Kings room in the Waterbirth Island Dungeon."), + new CrypticClue("This place sure is a mess.", null, "Ewesey is located in the Hosidius House mess hall in Great Kourend."), + new CrypticClue("Here, there are tears, but nobody is crying. Speak to the guardian and show off your alignment to balance.", null, "Talk to Juna while wearing three Guthix related items."), + new CrypticClue("You might have to turn over a few stones to progress.", null, "Kill a rock crab and pick up the casket (elite) that it drops."), + new CrypticClue("Dig under Razorlor's toad batta.", null, "Dig on the toad batta spawn in Tarn's Lair."), + new CrypticClue("Talk to Cassie in Falador.", null, "Cassie is found just south-east of the northern Falador gate."), + new CrypticClue("Faint sounds of 'Arr', fire giants found deep, the eastern tip of a lake, are the rewards you could reap.", null, "Dig south of the pillar at the end of the Deep Wilderness Dungeon."), + new CrypticClue("If you're feeling brave, dig beneath the dragon's eye.", null, "Dig below the mossy rock under the Viyeldi caves."), + new CrypticClue("Search the tents in the Imperial Guard camp in Burthorpe for some boxes.", null, "Search in the tents in northwest corner of the camp."), + new CrypticClue("A dwarf, approaching death, but very much in the light.", null, "Thorgel at the entrance to the Death altar"), + new CrypticClue("You must be 100 to play with me.", null, "Speak to the Veteran boat squire at Pest Control"), + new CrypticClue("Three rule below and three sit at top. Come dig at my entrance.", null, "Dig in front of the entrance to the Waterbirth Island Dungeon."), + new CrypticClue("Search the drawers in the ground floor of a shop in Yanille.", null, "Search the drawers in Yanille's hunting shop."), + new CrypticClue("Search the drawers of houses in Burthorpe.", null, "Inside Hild's house in the northeast corner of Burthorpe."), + new CrypticClue("Where safe to speak, the man who offers the pouch of smallest size wishes to see your alignment.", null, "Speak to the Mage of Zamorak south of the Rune Shop in Varrock while wearing three zamorakian items"), + new CrypticClue("Search the crates in the guard house of the northern gate of East Ardougne.", null, "The guard house is northeast of the Handelmort Mansion."), + new CrypticClue("Go to the village being attacked by trolls, search the drawers in one of the houses.", null, "Go to Dunstan's house in the northeast corner of Burthorpe. Kill Penda in the Toad and Chicken to obtain the key."), + new CrypticClue("You'll get licked.", null, "Kill a Bloodveld."), + new CrypticClue("She's small but can build both literally and figuratively, as long as you have their favour", null, "Speak to Lovada south of the Lovakengj House blast mine"), + new CrypticClue("Dig in front of the icy arena where 1 of 4 was fought.", null, "Where you fought Kamil from Desert Treasure."), + new CrypticClue("Speak to Roavar.", null, "Talk to Roavar in the Canifis tavern."), + new CrypticClue("Search the drawers upstairs of houses in the eastern part of Falador.", null, "House is located east of the eastern Falador bank and south of the fountain. The house is indicated by the icon on the minimap."), + new CrypticClue("Search the drawers found upstairs in East Ardougne's houses.", null, "Upstairs of the pub north of the Ardougne Castle."), + new CrypticClue("The far north eastern corner where 1 of 4 was defeated, the shadows still linger.", null, "Dig on the northeastern-most corner of the Shadow Dungeon. Bring a ring of visibility."), + new CrypticClue("Search the drawers in a house in Draynor Village.", null, "The drawer is located in the northernmost house in Draynor Village."), + new CrypticClue("Search the boxes in a shop in Taverley.", null, "The box inside Gaius' Two Handed Shop."), + new CrypticClue("I lie beneath the first descent to the holy encampment.", null, "Dig immediately after climbing down the first set of rocks towards Saradomin's encampment within the God Wars Dungeon."), + new CrypticClue("Search the upstairs drawers of a house in a village where pirates are known to have a good time.", null, "The house in the southeast corner of Brimhaven, northeast of Davon's Amulet Store. Kill any Pirate located around Brimhaven to obtain the key."), + new CrypticClue("Search the chest in the Duke of Lumbridge's bedroom.", null, "The Duke's room is on the 2nd floor in Lumbridge Castle."), + new CrypticClue("Talk to the Doomsayer.", null, "Doomsayer can be found just north of Lumbridge Castle entrance."), + new CrypticClue("Search the chests upstairs in Al Kharid Palace.", null, "The chest is located, in the northeast corner, on the first floor of the Al Kharid Palace"), + new CrypticClue("Search the boxes just outside the Armour shop in East Ardounge.", null, "Outside Zenesha's Plate Mail Body Shop"), + new CrypticClue("Surrounded by white walls and gems.", null, "Talk to Herquin, the gem store owner in Falador."), + new CrypticClue("Monk's residence in the far west. See robe storage device.", null, "Search the drawers upstairs in the chapel found on the southern coast of Great Kourend's Hosidius House. Directly south of the player-owned house portal."), + new CrypticClue("Search the drawers in Catherby's Archery shop.", null, "Hickton's Archery Emporium in Catherby."), + new CrypticClue("The hand ain't listening!", null, "Talk to The Face located by the manhole just north of the Port Sarim fishing shop."), + new CrypticClue("Search the chest in the left-hand tower of Camelot Castle.", null, "Located on the 2nd floor of the western tower of Camelot."), + new CrypticClue("Kill the spiritual, magic and godly whilst representing their own god", null, "Kill a spiritual mage in the God Wars Dungeon"), + new CrypticClue("Anger those who adhere to Saradomin's edicts to prevent travel.", null, "Port Sarim Docks, try to charter a ship to Entrana with armour or weapons equipped."), + new CrypticClue("South of a river in a town surrounded by the undead, what lies beneath the furnace?", null, "Dig in front of the Shilo Village furnace."), + new CrypticClue("Talk to the Squire in the White Knights' castle in Falador.", null, "The squire is located in the courtyard of the White Knights' Castle."), + new CrypticClue("Thanks Grandma!", null, "Tynan can be found in the north-east corner of Piscarilius House in Great Kourend."), + new CrypticClue("In a town where everyone has perfect vision, seek some locked drawers in a house that sits opposite a workshop.", null, "The drawers is in Seers' Village in the house south of the Elemental Workshop entrance. Kill any Chicken to obtain a key."), + new CrypticClue("The treasure is buried in a small building full of bones. Here is a hint: it's not near a graveyard.", null, "In the western building near the Limestone quarry east of Varrock. Dig south of the box of bones in the smaller building."), + new CrypticClue("Search the crates in East Ardougne's general store.", null, "Located south of the Ardounge church."), + new CrypticClue("Come brave adventurer, your sense is on fire. If you talk to me, it's an old god you desire.", null, "Speak to Viggora"), + new CrypticClue("2 musical birds. Dig in front of the spinning light.", null, "Dig in front of the spinning light in Ping and Pong's room inside the Iceberg"), + new CrypticClue("Search the wheelbarrow in Rimmington mine.", null, "The Rimmington mining site is located north of Rimmington."), + new CrypticClue("Belladonna, my dear. If only I had gloves, then I could hold you at last.", null, "Talk to Tool Leprechaun at Draynor Manor"), + new CrypticClue("Impossible to make angry", null, "Speak to Abbot Langley"), + new CrypticClue("Search the crates in Horvik's armoury.", null, "Horvik's in Varrock"), + new CrypticClue("Ghommal wishes to be impressed by how strong your equipment is.", null, "Talk to Ghommal at the Warrior's Guild while wearing sufficiently strong equipment"), + new CrypticClue("Shhhh!", null, "Speak to Logosia in the Arceuus House Library's ground floor."), + new CrypticClue("Salty Peter", null, "Talk to Konoo who is digging saltpeter in the Hosidius district in Zeah."), + new CrypticClue("Talk to Zeke in Al Kharid.", null, "Zeke is the owner of the scimitar shop in Al Kharid."), + new CrypticClue("Guthix left his mark in a fiery lake, dig at the tip of it.", null, "Dig at the tip of the lava lake that is shaped like a Guthixian symbol, west of the Mage Arena."), + new CrypticClue("Search the drawers in the upstairs of a house in Catherby.", null, "Perdu's house in Catherby."), + new CrypticClue("Search a crate in the Haymaker's arms.", null, "Search the crate in the north-east corner of The Haymaker's Arms tavern east of the Woodcutting Guild."), + new CrypticClue("Desert insects is what I see, Taking care of them was my responsibility. Your solution is found by digging near me.", null, "Dig next to the Entomologist, Kalphite area, Stronghold Slayer Cave."), + new CrypticClue("Search the crates in most north-western house in Al Kharid.", null, "Search the crates in the house, marked with a icon, southeast of the gem stall."), + new CrypticClue("You will have to fly high where a sword cannot help you.", null, "Kill an Aviansie."), + new CrypticClue("A massive battle rages beneath so be careful when you dig by the large broken crossbow.", null, "NE of the God Wars Dungeon entrance, climb the rocky handholds & dig by large crossbow."), + new CrypticClue("Mix yellow with blue and add heat, make sure you bring protection.", null, "Kill a green dragon."), + new CrypticClue("Speak to Ellis in Al Kharid.", null, "Ellis is tanner just north of Al Kharid bank."), + new CrypticClue("Search the chests in the Dwarven Mine.", null, "The chest is on the western wall, where Hura's Crossbow Shop is, in the Dwarven Mine."), + new CrypticClue("In a while...", null, "Kill a crocodile."), + new CrypticClue("A chisel and hammer reside in his home, strange for one of magic. Impress him with your magical equipment.", null, "Wizard Cromperty NE, East Ardougne. +100 magic attack bonus needed"), + new CrypticClue("You have all of the elements available to solve this clue. Fortunately you do not have to go as far as to stand in a draft.", null, "Search the crate, west of the Air Elementals, inside the Elemental Workshop."), + new CrypticClue("A demon's best friend holds the next step of this clue.", null, "Kill a hellhound"), + new CrypticClue("Dig in the centre of a great city of 5 districts.", null, "Dig in front of the large statue in the centre of Great Kourend."), + new CrypticClue("Hopefully this set of armor will help you to keep surviving.", null, "Speak to Sir Vyvin while wearing a white full helm, platebody, and platelegs."), + new CrypticClue("North of the best monkey restaurant on Karamja, look for the centre of the triangle of boats and search there", null, "The crate on the dock to the west of the fishing site on the Northern shore of Karamja."), + new CrypticClue("The beasts retreat, for their Queen is gone; the song of this town still plays on. Dig near the birthplace of a blade, be careful not to melt your spade.", null, "Dig in front of the small furnace in the Piscatoris Fishing Colony."), + new CrypticClue("Darkness wanders around me, but fills my mind with knowledge.", null, "Speak to Biblia on the Arceuus House Library's top floor."), + new CrypticClue("I would make a chemistry joke, but I'm afraid I wouldn't get a reaction.", null, "Talk to the Chemist in Rimmington"), + new CrypticClue("Show this to Hazelmere.", null, "Hazelmere is found upstairs on the island located just east of Yanille."), + new CrypticClue("Does one really need a fire to stay warm here?", null, "Dig next to the fire near the Volcanic Mine entrance."), + new CrypticClue("Search the open crate found in a small farmhouse in Hosidius. Cabbages grow outside.", null, "The house is east of the Mess in Great Kourend.") + ); + + private String text; + private String npc; + private int objectId; + private WorldPoint location; + private String solution; + + private CrypticClue(String text, WorldPoint location, String solution) + { + this(text, null, -1, location, solution); + } + + private CrypticClue(String text, int objectId, WorldPoint location, String solution) + { + this(text, null, objectId, location, solution); + } + + private CrypticClue(String text, String npc, WorldPoint location, String solution) + { + this(text, npc, -1, location, solution); + } + + private CrypticClue(String text, String npc, int objectId, WorldPoint location, String solution) + { + this.text = text; + this.npc = npc; + this.objectId = objectId; + this.location = location; + this.solution = solution; + } + + @Override + public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) + { + panelComponent.setTitle("Cryptic Clue"); + panelComponent.setWidth(150); + + panelComponent.getLines().add(new PanelComponent.Line("Clue:")); + panelComponent.getLines().add(new PanelComponent.Line(true, getText(), TITLED_CONTENT_COLOR)); + + if (getNpc() != null) + { + panelComponent.getLines().add(new PanelComponent.Line("NPC:")); + panelComponent.getLines().add(new PanelComponent.Line(getNpc(), TITLED_CONTENT_COLOR)); + } + + if (objectId != -1) + { + ObjectComposition object = plugin.getClient().getObjectDefinition(getObjectId()); + + if (object != null) + { + panelComponent.getLines().add(new PanelComponent.Line("Object:")); + panelComponent.getLines().add(new PanelComponent.Line(object.getName(), TITLED_CONTENT_COLOR)); + } + } + + panelComponent.getLines().add(new PanelComponent.Line("Solution:")); + panelComponent.getLines().add(new PanelComponent.Line(true, getSolution(), TITLED_CONTENT_COLOR)); + } + + @Override + public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) + { + // Mark dig location + if (getLocation() != null && getNpc() == null && objectId == -1) + { + LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation()); + + if (localLocation != null) + { + OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, SPADE_IMAGE, Color.ORANGE); + } + } + + // Mark NPC + if (plugin.getNpcsToMark() != null) + { + for (NPC npc : plugin.getNpcsToMark()) + { + OverlayUtil.renderActorOverlayImage(graphics, npc, CLUE_SCROLL_IMAGE, Color.ORANGE, IMAGE_Z_OFFSET); + } + } + + // Mark game object + if (objectId != -1) + { + net.runelite.api.Point mousePosition = plugin.getClient().getMouseCanvasPosition(); + + if (plugin.getObjectsToMark() != null) + { + for (GameObject gameObject : plugin.getObjectsToMark()) + { + OverlayUtil.renderHoverableArea(graphics, gameObject.getClickbox(), mousePosition, + CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR); + + OverlayUtil.renderImageLocation(plugin.getClient(), graphics, gameObject.getLocalLocation(), CLUE_SCROLL_IMAGE, IMAGE_Z_OFFSET); + } + } + } + } + + public static CrypticClue forText(String text) + { + for (CrypticClue clue : CLUES) + { + if (clue.text.equalsIgnoreCase(text)) + { + return clue; + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/Emote.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/Emote.java new file mode 100644 index 0000000000..d98d60e2d8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/Emote.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +import lombok.Getter; +import static net.runelite.api.SpriteID.*; + +@Getter +public enum Emote +{ + BULL_ROARER("Bull Roarer", -1), + YES("Yes", EMOTE_YES), + NO("No", EMOTE_NO), + THINK("Think", EMOTE_THINK), + BOW("Bow", EMOTE_BOW), + ANGRY("Angry", EMOTE_ANGRY), + CRY("Cry", EMOTE_CRY), + LAUGH("Laugh", EMOTE_LAUGH), + CHEER("Cheer", EMOTE_CHEER), + WAVE("Wave", EMOTE_WAVE), + BECKON("Beckon", EMOTE_BECKON), + DANCE("Dance", EMOTE_DANCE), + CLAP("Clap", EMOTE_CLAP), + PANIC("Panic", EMOTE_PANIC), + JIG("Jig", EMOTE_JIG), + SPIN("Spin", EMOTE_SPIN), + HEADBANG("Headbang", EMOTE_HEADBANG), + JUMP_FOR_JOY("Jump for Joy", EMOTE_JUMP_FOR_JOY), + RASPBERRY("Raspberry", EMOTE_RASPBERRY), + YAWN("Yawn", EMOTE_YAWN), + SALUTE("Salute", EMOTE_SALUTE), + SHRUG("Shrug", EMOTE_SHRUG), + BLOW_KISS("Blow Kiss", EMOTE_BLOW_KISS), + GOBLIN_SALUTE("Goblin Salute", EMOTE_GOBLIN_SALUTE), + SLAP_HEAD("Slap Head", EMOTE_SLAP_HEAD), + STOMP("Stomp", EMOTE_STOMP), + FLAP("Flap", EMOTE_FLAP), + PUSH_UP("Push up", EMOTE_PUSH_UP); + + private String name; + private int spriteId; + + Emote(String name, int spriteId) + { + this.name = name; + this.spriteId = spriteId; + } + + public boolean hasSprite() + { + return spriteId != -1; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java new file mode 100644 index 0000000000..b9d5311395 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.Set; +import lombok.Getter; +import net.runelite.api.ItemComposition; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.components.PanelComponent; +import static net.runelite.api.ItemID.*; +import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.EMOTE_IMAGE; +import static net.runelite.client.plugins.cluescrolls.clues.Emote.*; +import static net.runelite.client.plugins.cluescrolls.clues.Emote.BULL_ROARER; + +@Getter +public class EmoteClue extends ClueScroll implements TextClueScroll +{ + private static final Set CLUES = ImmutableSet.of( + new EmoteClue("Show your anger towards the Statue of Saradomin in Ellamaria's garden. Beware of double agents! Equip a Zamorak godsword.", new WorldPoint(3230, 3478, 0), ANGRY, ZAMORAK_GODSWORD), + new EmoteClue("Show your anger at the Wise old man. Beware of double agents! Equip an abyssal whip, a legend's cape and some spined chaps.", new WorldPoint(3088, 3254, 0), ANGRY, ABYSSAL_WHIP, CAPE_OF_LEGENDS, SPINED_CHAPS), + new EmoteClue("Beckon in the Digsite, near the eastern winch. Bow before you talk to me Equip a green gnome hat, snakeskin boots and an iron pickaxe.", new WorldPoint(2971, 3331, 0), BECKON, BOW, GREEN_HAT, SNAKESKIN_BOOTS, IRON_PICKAXE), + new EmoteClue("Beckon in Tai Bwo Wannai. Clap before you talk to me. Equip green dragonhide chaps, a ring of dueling and a mithril medium helmet.", new WorldPoint(2784, 3065, 0), BECKON, CLAP, GREEN_DHIDE_CHAPS, RING_OF_DUELING8, MITHRIL_MED_HELM), + new EmoteClue("Beckon on the east coast of the Kharazi Jungle. Beware of double agents! Equip any vestment stole and a heraldic rune shield.", new WorldPoint(2954, 2933, 0), BECKON, SARADOMIN_STOLE, RUNE_SHIELD_H1_10667), + new EmoteClue("Beckon in the combat ring of Shayzien. Show your anger before you talk to me. Equip an adamant platebody, adamant full helm and adamant platelegs.", new WorldPoint(1545, 3594, 0), BECKON, ANGRY, ADAMANT_PLATELEGS, ADAMANT_PLATEBODY, ADAMANT_FULL_HELM), + new EmoteClue("Bow near Lord Iorwerth. Beware of double agents! Equip a new imbued crystal bow.", new WorldPoint(2205, 3252, 0), BOW, NEW_CRYSTAL_BOW_I), + new EmoteClue("Bow outside the entrance to the Legends' Guild. Equip iron platelegs, an emerald amulet and an oak longbow.", new WorldPoint(2709, 4113, 0), BOW, IRON_PLATELEGS, OAK_LONGBOW, EMERALD_AMULET), + new EmoteClue("Bow on the ground floor of the Legend's guild. Equip Legend's cape, a dragon battleaxe and an amulet of glory.", new WorldPoint(2728, 3377, 0), BOW, CAPE_OF_LEGENDS, DRAGON_BATTLEAXE, AMULET_OF_GLORY), + new EmoteClue("Bow in the ticket office of the Duel Arena. Equip an iron chain body, leather chaps and coif.", new WorldPoint(3314, 3241, 0), BOW, IRON_CHAINBODY, LEATHER_CHAPS, COIF), + new EmoteClue("Bow at the top of the lighthouse. Beware of double agents! Equip a blue dragonhide body, blue dragonhide vambraces and no jewellery.", new WorldPoint(2511, 3641, 2), BOW, BLUE_DHIDE_BODY, BLUE_DHIDE_VAMB), + new EmoteClue("Bow upstairs in the Monastery. Equip a completed prayer book.", new WorldPoint(3136, 3513, 0), BOW, HOLY_BOOK, UNHOLY_BOOK, BOOK_OF_BALANCE), + new EmoteClue("Blow a kiss between the tables in Shilo Village bank. Beware of double agents! Equip a blue mystic hat, bone spear and rune plate body.", new WorldPoint(2851, 2954, 0), BLOW_KISS, MYSTIC_HAT, BONE_SPEAR, RUNE_PLATEBODY), + new EmoteClue("Blow a kiss in the heart of the lava maze. Equip black dragonhide chaps, a spotted cape and a rolling pin.", new WorldPoint(2417, 4454, 0), BLOW_KISS, BLACK_DHIDE_CHAPS, SPOTTED_CAPE, ROLLING_PIN), + new EmoteClue("Blow a kiss outside K'ril Tsutsaroth's chamber. Beware of double agents! Equip a Zamorak full helm and the shadow sword.", new WorldPoint(2925, 5333, 0), BLOW_KISS, ZAMORAK_FULL_HELM, SHADOW_SWORD), + new EmoteClue("Cheer at the Druids' Circle. Equip a blue wizard hat, a bronze two-handed sword and HAM boots.", new WorldPoint(2925, 3484, 0), CHEER, BLUE_WIZARD_HAT, BRONZE_2H_SWORD, HAM_BOOTS), + new EmoteClue("Cheer at the games room. Have nothing equipped at all when you do.", new WorldPoint(2207, 4952, 0), CHEER), + new EmoteClue("Cheer in the Barbarian Agility Arena. Headbang before you talk to me. Equip a steel platebody, maple shortbow and a Wilderness cape.", new WorldPoint(2552, 3557, 0), CHEER, HEADBANG, STEEL_PLATEBODY, MAPLE_SHORTBOW, TEAM1_CAPE), + new EmoteClue("Cheer in the Edgeville general store. Dance before you talk to me. Equip a brown apron, leather boots and leather gloves.", new WorldPoint(3080, 3509, 0), CHEER, DANCE, BROWN_APRON, LEATHER_BOOTS, LEATHER_GLOVES), + new EmoteClue("Cheer in the Ogre Pen in the Training Camp. Show you are angry before you talk to me. Equip a green dragonhide body and chaps and a steel square shield.", new WorldPoint(2527, 3375, 0), CHEER, ANGRY, GREEN_DHIDE_BODY, GREEN_DHIDE_CHAPS, STEEL_SQ_SHIELD), + new EmoteClue("Cheer in the Shadow dungeon. Equip a rune crossbow, climbing boots and any mitre.", new WorldPoint(2774, 6785, 0), CHEER, RUNE_CROSSBOW, CLIMBING_BOOTS, SARADOMIN_MITRE), + new EmoteClue("Cheer in the Entrana church. Beware of double agents! Equip a set of full black dragonhide armour.", new WorldPoint(2852, 3349, 0), CHEER, BLACK_DHIDE_VAMB, BLACK_DHIDE_CHAPS, BLACK_DHIDE_BODY), + new EmoteClue("Cheer for the monks at Port Sarim. Equip a coif, steel plate skirt and a sapphire necklace.", new WorldPoint(2959, 3362, 0), CHEER, COIF, STEEL_PLATESKIRT, SAPPHIRE_NECKLACE), + new EmoteClue("Cheer at the top of the agility pyramid. Beware of double agents! Equip a blue mystic robe top, and any rune heraldic shield.", new WorldPoint(3043, 4697, 3), CHEER, MYSTIC_ROBE_TOP, RUNE_SHIELD_H1_10667), + new EmoteClue("Clap in the main exam room in the Exam Centre. Equip a white apron, green gnome boots and leather gloves.", new WorldPoint(3361, 3339, 0), CLAP, WHITE_APRON, GREEN_BOOTS, LEATHER_GLOVES), + new EmoteClue("Clap on the causeway to the Wizards' Tower. Equip an iron med helm, emerald ring and a white apron.", new WorldPoint(3098, 3212, 0), CLAP, IRON_MED_HELM, EMERALD_RING, WHITE_APRON), + new EmoteClue("Clap on the top level of the mill, north of East Ardougne. Equip a blue gnome robe top, HAM robe bottom and an unenchanted tiara.", new WorldPoint(2653, 3279, 0), CLAP, BLUE_ROBE_TOP, HAM_ROBE, TIARA), + new EmoteClue("Clap in Seers court house. Spin before you talk to me. Equip an adamant halberd, blue mystic robe bottom and a diamond ring.", new WorldPoint(2735, 3469, 0), CLAP, SPIN, ADAMANT_HALBERD, MYSTIC_ROBE_BOTTOM, DIAMOND_RING), + new EmoteClue("Clap in the magic axe hut. Beware of double agents. Equip only flared trousers.", new WorldPoint(3191, 3960, 0), CLAP, FLARED_TROUSERS), + new EmoteClue("Cry in the Catherby Ranging shop. Bow before you talk to me. Equip blue gnome boots, a hard leather body and an unblessed silver sickle.", new WorldPoint(2823, 3443, 0), CRY, BOW, BLUE_BOOTS, HARDLEATHER_BODY, SILVER_SICKLE), + new EmoteClue("Cry on the shore of Catherby beach. Laugh before you talk to me. Equip an adamant sq shield, a bone dagger and mithril platebody.", new WorldPoint(3079, 6330, 0), CRY, LAUGH, ADAMANT_SQ_SHIELD, BONE_DAGGER, MITHRIL_PLATELEGS), + new EmoteClue("Cry on top of the western tree in the Gnome Agility Arena. Indicate 'no' before you talk to me. Equip a steel kiteshield, ring of forging, and green dragonhide chaps.", new WorldPoint(2473, 3420, 0), CRY, NO, STEEL_KITESHIELD, RING_OF_FORGING, GREEN_DHIDE_CHAPS), + new EmoteClue("Cry in the Tzhaar gem shop. Beware of the double agents! Equip a fire cape and a Toktz-xil-ul.", new WorldPoint(2463, 5149, 0), CRY, FIRE_CAPE, TOKTZXILUL), + new EmoteClue("Cry in the Draynor Village jail. Jump for joy before you talk to me. Equip an adamant sword, a sapphire amulet and an adamant plate skirt.", new WorldPoint(3128, 3245, 0), CRY, JUMP_FOR_JOY, ADAMANT_SWORD, SAPPHIRE_AMULET, ADAMANT_PLATESKIRT), + new EmoteClue("Dance at the crossroads north of Draynor. Equip an iron chain body, a sapphire ring and a longbow.", new WorldPoint(3018, 3357, 0), DANCE, IRON_CHAINBODY, SAPPHIRE_RING, LONGBOW), + new EmoteClue("Dance in the Party Room. Equip a steel full helmet, steel platebody and an iron plate skirt.", new WorldPoint(2863, 3272, 0), DANCE, STEEL_FULL_HELM, STEEL_PLATEBODY, IRON_PLATESKIRT), + new EmoteClue("Dance in the shack in Lumbridge Swamp. Equip a bronze dagger, iron full helmet and a gold ring.", new WorldPoint(3096, 3202, 0), DANCE, BRONZE_DAGGER, IRON_FULL_HELM, GOLD_RING), + new EmoteClue("Dance in the dark caves beneath Lumbridge Swamp. Blow a kiss before you talk to me. Equip an air staff, Bronze full helm and an Amulet of power.", new WorldPoint(3223, 9597, 0), DANCE, BLOW_KISS, STAFF_OF_AIR, BRONZE_FULL_HELM, AMULET_OF_POWER), + new EmoteClue("Dance at the cat-doored pyramid in Sophanem. Beware of double agents! Equip a ring of life, an uncharged amulet of glory and an adamant two-handed sword.", new WorldPoint(3294, 2781, 0), DANCE, RING_OF_LIFE, AMULET_OF_GLORY, ADAMANT_2H_SWORD), + new EmoteClue("Dance in the centre of Canifis. Bow before you talk to me. Equip a green gnome robe top, mithril platelegs and an iron two-handed sword.", new WorldPoint(3492, 3488, 0), DANCE, BOW, ADAMANT_2H_SWORD, MITHRIL_PLATELEGS, IRON_2H_SWORD), + new EmoteClue("Dance in the King Black Dragon's lair. Beware of double agents! Equip a black dragonhide body, black dragonhide vambs and a black dragon mask.", new WorldPoint(2271, 4680, 0), DANCE, BLACK_DHIDE_BODY, BLACK_DHIDE_VAMB, BLACK_DRAGON_MASK), + new EmoteClue("Dance in Iban's temple. Beware of double agents! Equip Iban's staff, a black mystic top, and a black mystic bottom.", new WorldPoint(2011, 4712, 0), DANCE, IBANS_STAFF, MYSTIC_ROBE_TOP_DARK, MYSTIC_ROBE_BOTTOM_DARK), + new EmoteClue("Dance on the Fishing Platform. Equip barrows gloves, an amulet of glory and a dragon med helm.", new WorldPoint(2782, 3273, 0), DANCE, BARROWS_GLOVES, AMULET_OF_GLORY, DRAGON_MED_HELM), + new EmoteClue("Dance at the entrance to the Grand Exchange. Equip a pink skirt, pink robe top and a body tiara.", new WorldPoint(3165, 3467, 0), DANCE, PINK_SKIRT, PINK_ROBE_TOP, BODY_TIARA), + new EmoteClue("Flap at the death altar. Beware of double agents! Equip a death tiara, a legend's cape and any ring of wealth.", new WorldPoint(2205, 4838, 0), FLAP, DEATH_TIARA, CAPE_OF_LEGENDS, RING_OF_WEALTH), + new EmoteClue("Goblin Salute in the Goblin Village. Beware of double agents! Equip a Bandos platebody, Bandos cloak and Bandos godsword.", new WorldPoint(2956, 3505, 0), GOBLIN_SALUTE, BANDOS_PLATEBODY, BANDOS_CLOAK, BANDOS_GODSWORD), + new EmoteClue("Headbang in the mine north of Al Kharid. Equip a desert shirt, leather gloves and leather boots.", new WorldPoint(3124, 3304, 0), HEADBANG, DESERT_SHIRT, LEATHER_GLOVES, LEATHER_BOOTS), + new EmoteClue("Headbang at the exam center. Beware of double agents! Equip a mystic fire staff, a diamond bracelet and rune boots.", new WorldPoint(3362, 3340, 0), HEADBANG, MYSTIC_FIRE_STAFF, DIAMOND_BRACELET, RUNE_BOOTS), + new EmoteClue("Headbang at the top of Slayer Tower. Equip a seercull, a combat bracelet and helm of Neitiznot.", new WorldPoint(3115, 3420, 0), HEADBANG, SEERCULL, COMBAT_BRACELET, HELM_OF_NEITIZNOT), + new EmoteClue("Dance a jig by the entrance to the Fishing Guild. Equip an emerald ring, a sapphire amulet, and a bronze chain body.", new WorldPoint(2610, 3391, 0), DANCE, EMERALD_RING, SAPPHIRE_AMULET, BRONZE_CHAINBODY), + new EmoteClue("Dance a jig under Shantay's Awning. Bow before you talk to me. Equip a pointed blue snail helmet, an air staff and a bronze square shield.", new WorldPoint(2983, 3305, 0), DANCE, BOW, BRUISE_BLUE_SNELM_3343, STAFF_OF_AIR, BRONZE_SQ_SHIELD), + new EmoteClue("Jig at Jiggig. Beware of double agents! Equip a Rune spear, rune platelegs and any rune heraldic helm.", new WorldPoint(2477, 3047, 0), JIG, RUNE_SPEAR, RUNE_PLATELEGS, RUNE_HELM_H1), + new EmoteClue("Do a jig in Varrock's rune store. Equip an air tiara and a staff of water.", new WorldPoint(3253, 3401, 0), JIG, AIR_TIARA, STAFF_OF_WATER), + new EmoteClue("Dance a jig by the Barrows reward chest. Beware of double agents! Equip any set of Barrows equipment.", new WorldPoint(3551, 9694, 0), DANCE), + new EmoteClue("Jump for joy at the beehives. Equip a desert shirt, green gnome robe bottoms and a steel axe.", new WorldPoint(2759, 3445, 0), JUMP_FOR_JOY, DESERT_SHIRT, GREEN_ROBE_BOTTOMS, STEEL_AXE), + new EmoteClue("Jump for joy in Yanille bank. Dance a jig before you talk to me. Equip a brown apron, adamant med helm and snakeskin chaps.", new WorldPoint(2760, 3299, 0), JUMP_FOR_JOY, JIG, BROWN_APRON, ADAMANT_MED_HELM, SNAKESKIN_CHAPS), + new EmoteClue("Jump for joy in the TzHaar sword shop. Shrug before you talk to me. Equip a steel longsword, blue dragonhide body and blue mystic gloves.", new WorldPoint(2477, 5146, 0), JUMP_FOR_JOY, SHRUG, STEEL_LONGSWORD, BLUE_DHIDE_BODY, MYSTIC_GLOVES), + new EmoteClue("Jump for joy in the Ancient Cavern. Equip a granite shield, splitbark body, and any rune heraldic helm.", new WorldPoint(2339, 6787, 0), JUMP_FOR_JOY, GRANITE_SHIELD, SPLITBARK_BODY, RUNE_HELM_H1), + new EmoteClue("Jump for joy at the Neitiznot rune rock. Equip rune boots, a proselyte hauberk and a dragonstone ring.", new WorldPoint(2375, 3850, 0), JUMP_FOR_JOY, RUNE_BOOTS, PROSELYTE_HAUBERK, DRAGONSTONE_RING), + new EmoteClue("Jump for joy in the centre of Zul-Andra. Beware of double agents! Equip a dragon 2h sword, bandos boots and an obsidian cape.", new WorldPoint(2199, 3056, 0), JUMP_FOR_JOY, DRAGON_2H_SWORD, BANDOS_BOOTS, OBSIDIAN_CAPE), + new EmoteClue("Laugh by the fountain of heroes. Equip splitbark legs, dragon boots and a rune longsword.", new WorldPoint(2716, 6584, 0), LAUGH, SPLITBARK_LEGS, DRAGON_BOOTS, RUNE_LONGSWORD), + new EmoteClue("Laugh in Jokul's tent in the Mountain Camp. Beware of double agents! Equip a rune full helmet, blue dragonhide chaps and a fire battlestaff.", new WorldPoint(2812, 3681, 0), LAUGH, RUNE_FULL_HELM, BLUE_DHIDE_CHAPS, FIRE_BATTLESTAFF), + new EmoteClue("Laugh at the crossroads south of the Sinclair Mansion. Equip a cowl, blue wizard robe top and an iron scimitar.", new WorldPoint(2741, 3536, 0), LAUGH, LEATHER_COWL, EARTH_RUNE, IRON_SCIMITAR), + new EmoteClue("Panic in the Limestone Mine. Equip bronze platelegs, a steel pickaxe and a steel medium helmet.", new WorldPoint(3372, 3498, 0), PANIC, BRONZE_PLATELEGS, STEEL_PICKAXE, STEEL_MED_HELM), + new EmoteClue("Panic on the pier where you catch the Fishing trawler. Have nothing equipped at all when you do.", new WorldPoint(2676, 3169, 0), PANIC), + new EmoteClue("Panic by the mausoleum in Morytania. Wave before you speak to me. Equip a mithril plate skirt, a maple longbow and no boots.", new WorldPoint(3438, 3501, 0), PANIC, MITHRIL_PLATESKIRT, MAPLE_LONGBOW), + new EmoteClue("Panic on the Wilderness volcano bridge. Beware of double agents! Equip any headband and crozier.", new WorldPoint(3368, 3935, 0), PANIC, RED_HEADBAND, SARADOMIN_CROZIER), + new EmoteClue("Panic in the heart of the Haunted Woods. Beware of double agents! Have no items equipped when you do.", new WorldPoint(3611, 3492, 0), PANIC), + new EmoteClue("Panic by the pilot on White Wolf Mountain. Beware of double agents! Equip mithril platelegs, a ring of life, and a rune axe.", new WorldPoint(2847, 3499, 0), PANIC, MITHRIL_PLATELEGS, RING_OF_LIFE, RUNE_AXE), + new EmoteClue("Panic by the big egg where no one dare goes and the ground is burnt. Beware of double agents! Equip a dragon med helm, a TokTz-Ket-Xil, a brine sabre, rune platebody and an uncharged amulet of glory.", new WorldPoint(3227, 3831, 0), PANIC, DRAGON_MED_HELM, TOKTZKETXIL, BRINE_SABRE, RUNE_PLATEBODY, AMULET_OF_GLORY), + new EmoteClue("Do a push up at the bank of the Warrior's guild. Beware of double agents! Equip a dragon battleaxe, a dragon defender and a slayer helm of any kind.", new WorldPoint(2843, 3543, 0), PUSH_UP, DRAGON_BATTLEAXE, DRAGON_DEFENDER, SLAYER_HELMET), + new EmoteClue("Blow a raspberry at the monkey cage in Ardougne Zoo. Equip a studded leather body, bronze platelegs and a normal staff with no orb.", new WorldPoint(2853, 3329, 0), RASPBERRY, STUDDED_BODY, BRONZE_PLATELEGS, STAFF), + new EmoteClue("Blow raspberries outside the entrance to Keep Le Faye. Equip a coif, an iron platebody and leather gloves.", new WorldPoint(2705, 4057, 0), RASPBERRY, COIF, IRON_PLATEBODY, LEATHER_GLOVES), + new EmoteClue("Blow a raspberry in the Fishing Guild bank. Beware of double agents! Equip an elemental shield, blue dragonhide chaps and a rune warhammer.", new WorldPoint(2588, 3419, 0), RASPBERRY, ELEMENTAL_SHIELD, BLUE_DHIDE_CHAPS, RUNE_WARHAMMER), + new EmoteClue("Salute in the banana plantation. Beware of double agents! Equip a diamond ring, amulet of power, and nothing on your chest and legs.", new WorldPoint(2918, 3168, 0), SALUTE, DIAMOND_RING, AMULET_OF_POWER), + new EmoteClue("Salute in the warriors' guild bank. Equip only a black salamander.", new WorldPoint(2844, 3542, 0), SALUTE, BLACK_SALAMANDER), + new EmoteClue("Salute in the centre of the mess hall. Beware of double agents! Equip a rune halberd, rune platebody and an amulet of strength.", new WorldPoint(1646, 3632, 0), SALUTE, RUNE_HALBERD, RUNE_PLATEBODY, AMULET_OF_STRENGTH), + new EmoteClue("Shrug in the mine near Rimmington. Equip a gold necklace, a gold ring and a bronze spear.", new WorldPoint(2873, 3337, 0), SHRUG, GOLD_NECKLACE, GOLD_RING, BRONZE_SPEAR), + new EmoteClue("Shrug in Catherby bank. Yawn before you talk to me. Equip a maple longbow, green dragonhide chaps and an iron med helm.", new WorldPoint(2966, 3291, 0), SHRUG, YAWN, MAPLE_LONGBOW, GREEN_DHIDE_CHAPS, IRON_MED_HELM), + new EmoteClue("Shrug in the Zamorak temple found in the Eastern Wilderness. Beware of double agents! Equip rune platelegs, an iron platebody and blue dragonhide vambraces.", new WorldPoint(3239, 3611, 0), SHRUG, RUNE_PLATELEGS, IRON_PLATEBODY, BLUE_DHIDE_VAMB), + new EmoteClue("Slap your head in the centre of the Kourend catacombs. Beware of double agents! Equip the arclight and an amulet of the damned.", new WorldPoint(1666, 10050, 0), SLAP_HEAD, ARCLIGHT, AMULET_OF_THE_DAMNED), + new EmoteClue("Spin at the crossroads north of Rimmington. Equip a green gnome hat, cream gnome top and leather chaps.", new WorldPoint(2981, 3276, 0), SPIN, GREEN_HAT, CREAM_ROBE_TOP, LEATHER_CHAPS), + new EmoteClue("Spin in the Draynor Manor by the fountain. Equip an iron platebody, studded leather chaps and a bronze full helmet.", new WorldPoint(3088, 3336, 0), SPIN, IRON_PLATELEGS, STUDDED_CHAPS, BRONZE_FULL_HELM), + new EmoteClue("Spin in front of the Soul altar. Beware of double agents! Equip a dragon pickaxe, helm of neitiznot and a pair of rune boots.", new WorldPoint(1815, 3856, 0), SPIN, DRAGON_PICKAXE, HELM_OF_NEITIZNOT, RUNE_BOOTS), + new EmoteClue("Spin in the Varrock Castle courtyard. Equip a black axe, a coif and a ruby ring.", new WorldPoint(3023, 3309, 0), SPIN, BLACK_AXE, COIF, RUBY_RING), + new EmoteClue("Spin in West Ardougne Church. Equip a dragon spear and red dragonhide chaps.", new WorldPoint(2404, 4326, 0), SPIN, DRAGON_SPEAR, RED_DHIDE_CHAPS), + new EmoteClue("Spin on the bridge by the Barbarian Village. Salute before you talk to me. Equip purple gloves, a steel kiteshield and a mithril full helmet.", new WorldPoint(3058, 3334, 0), SPIN, SALUTE, PURPLE_GLOVES, STEEL_KITESHIELD, MITHRIL_FULL_HELM), + new EmoteClue("Stomp in the Enchanted valley west of the waterfall. Beware of double agents! Equip a dragon axe.", new WorldPoint(3034, 4518, 0), STOMP, DRAGON_AXE), + new EmoteClue("Think in middle of the wheat field by the lumbridge mill. Equip a blue gnome robetop, a turquoise gnome robe bottom and an oak shortbow.", new WorldPoint(3259, 3332, 0), THINK, BLUE_ROBE_TOP, TURQUOISE_ROBE_BOTTOMS, OAK_SHORTBOW), + new EmoteClue("Think in the centre of the Observatory. Spin before you talk to me. Equip a mithril chain body, green dragonhide chaps and a ruby amulet.", new WorldPoint(2439, 3161, 0), THINK, SPIN, MITHRIL_CHAINBODY, GREEN_DHIDE_CHAPS, RUBY_AMULET), + new EmoteClue("Wave along the south fence of the Lumber Yard. Equip a hard leather body, leather chaps and a bronze axe.", new WorldPoint(2971, 3438, 0), WAVE, HARDLEATHER_BODY, LEATHER_CHAPS, BRONZE_AXE), + new EmoteClue("Wave in the Falador gem store. Equip a Mithril pickaxe, Black platebody and an Iron Kiteshield.", new WorldPoint(2945, 3335, 0), WAVE, MITHRIL_PICKAXE, BLACK_PLATEBODY, IRON_KITESHIELD), + new EmoteClue("Wave on Mudskipper Point. Equip a black cape, leather chaps and a steel mace.", new WorldPoint(2995, 3119, 0), WAVE, BLACK_CAPE, LEATHER_CHAPS, STEEL_MACE), + new EmoteClue("Wave on the the nothern wall of the Castle Drakan. Beware of double agents! Wear a dragon sq shield, splitbark body and any boater.", new WorldPoint(3560, 3385, 0), WAVE, DRAGON_SQ_SHIELD, SPLITBARK_BODY, RED_BOATER), + new EmoteClue("Yawn in the 7th room of Pyramid Plunder. Beware of double agents! Equip a pharoah sceptre and a full set of menaphite robes.", new WorldPoint(1944, 4427, 0), YAWN, PHARAOHS_SCEPTRE_3, MENAPHITE_PURPLE_HAT, MENAPHITE_PURPLE_TOP, MENAPHITE_PURPLE_ROBE), + new EmoteClue("Yawn in the Varrock library. Equip a green gnome robe top, HAM robe bottom and an iron warhammer.", new WorldPoint(3209, 3492, 0), YAWN, GREEN_ROBE_TOP, HAM_ROBE, IRON_WARHAMMER), + new EmoteClue("Yawn in Draynor Marketplace. Equip studded leather chaps, an iron kiteshield and a steel longsword.", new WorldPoint(3076, 3310, 0), YAWN, STUDDED_CHAPS, IRON_KITESHIELD, STEEL_LONGSWORD), + new EmoteClue("Yawn in the Castle Wars lobby. Shrug before you talk to me. Equip a ruby amulet, a mithril scimitar and a Wilderness cape.", new WorldPoint(2772, 3251, 0), YAWN, SHRUG, RUBY_AMULET, MITHRIL_SCIMITAR, TEAM1_CAPE), + new EmoteClue("Yawn in the rogues' general store. Beware of double agents! Equip an adamant square shield, blue dragon vambraces and a rune pickaxe.", new WorldPoint(3026, 3701, 0), YAWN, ADAMANT_SQ_SHIELD, BLUE_DHIDE_VAMB, RUNE_PICKAXE), + new EmoteClue("Yawn at the top of Trollheim. Equip a lava battlestaff, black dragonhide vambraces and a mind shield.", new WorldPoint(2590, 4452, 0), YAWN, LAVA_BATTLESTAFF, BLACK_DHIDE_VAMB, MIND_SHIELD), + new EmoteClue("Yawn in the centre of Arceuus library. Nod your head before you talk to me. Equip blue dragonhide vambraces, adamant boots and an adamant dagger.", new WorldPoint(1632, 3807, 0), YAWN, YES, BLUE_DHIDE_VAMB, ADAMANT_BOOTS, ADAMANT_DAGGER), + new EmoteClue("Swing a bullroarer at the top of the watchtower. Beware of double agents! Equip a dragon plate skirt, climbing boots and a dragon chainbody.", new WorldPoint(2932, 4712, 0), BULL_ROARER, DRAGON_PLATESKIRT, CLIMBING_BOOTS, DRAGON_CHAINBODY_3140) + ); + + private String text; + private WorldPoint location; + private Emote firstEmote; + private Emote secondEmote; + private int[] itemIds; + + private EmoteClue(String text, WorldPoint location, Emote emote, int... itemIds) + { + this(text, location, emote, null, itemIds); + } + + private EmoteClue(String text, WorldPoint location, Emote firstEmote, Emote secondEmote, int... itemIds) + { + this.text = text; + this.location = location; + this.firstEmote = firstEmote; + this.secondEmote = secondEmote; + this.itemIds = itemIds; + } + + @Override + public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) + { + panelComponent.setTitle("Emote Clue"); + + panelComponent.getLines().add(new PanelComponent.Line("Emotes:")); + panelComponent.getLines().add(new PanelComponent.Line(getFirstEmote().getName(), TITLED_CONTENT_COLOR)); + if (getSecondEmote() != null) + { + panelComponent.getLines().add(new PanelComponent.Line(getSecondEmote().getName(), TITLED_CONTENT_COLOR)); + } + + if (getItemIds().length != 0) + { + panelComponent.setWidth(160); + panelComponent.getLines().add(new PanelComponent.Line("Equip:")); + + if (plugin.getEquippedItems() != null) + { + for (int itemId : getItemIds()) + { + ItemComposition itemDefinition = plugin.getClient().getItemDefinition(itemId); + + if (itemDefinition != null) + { + if (plugin.getEquippedItems().contains(itemId)) + { + panelComponent.getLines().add(new PanelComponent.Line(itemDefinition.getName(), TITLED_CONTENT_COLOR, "X", Color.GREEN)); + } + else + { + panelComponent.getLines().add(new PanelComponent.Line(itemDefinition.getName(), TITLED_CONTENT_COLOR, "-", Color.RED)); + } + } + } + } + } + else + { + panelComponent.setWidth(130); + panelComponent.getLines().add(new PanelComponent.Line("Items:", "None")); + } + } + + @Override + public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) + { + LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation()); + + if (localLocation == null) + { + return; + } + + OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, EMOTE_IMAGE, Color.ORANGE); + } + + public static EmoteClue forText(String text) + { + for (EmoteClue clue : CLUES) + { + if (clue.text.equalsIgnoreCase(text)) + { + return clue; + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FairyRingClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FairyRingClue.java new file mode 100644 index 0000000000..32b0531330 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FairyRingClue.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.Set; +import lombok.Getter; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.components.PanelComponent; +import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.SPADE_IMAGE; + +@Getter +public class FairyRingClue extends ClueScroll implements TextClueScroll +{ + private static final Set CLUES = ImmutableSet.of( + new FairyRingClue("A I R 2 3 3 1", new WorldPoint(2702, 3246, 0)), + new FairyRingClue("A I Q 0 4 4 0", new WorldPoint(3000, 3110, 0)), + new FairyRingClue("A L P 1 1 4 0", new WorldPoint(2504, 3633, 0)), + new FairyRingClue("B L P 6 2 0 0", new WorldPoint(2439, 5132, 0)), + new FairyRingClue("B J R 1 1 2 3", new WorldPoint(2648, 4729, 0)), + new FairyRingClue("B I P 7 0 1 3", new WorldPoint(3407, 3330, 0)), + new FairyRingClue("C I S 0 0 0 9", new WorldPoint(1630, 3868, 0)), + new FairyRingClue("C K P 0 2 2 4", new WorldPoint(2073, 4846, 0)), + new FairyRingClue("D I P 8 5 1 1", new WorldPoint(3041, 4770, 0)), + new FairyRingClue("D K S 2 3 1 0", new WorldPoint(2747, 3720, 0)) + ); + + private String text; + private WorldPoint location; + + private FairyRingClue(String text, WorldPoint location) + { + this.text = text; + this.location = location; + } + + @Override + public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) + { + panelComponent.setTitle("Fairy Ring Clue"); + panelComponent.setWidth(140); + + panelComponent.getLines().add(new PanelComponent.Line("Code:")); + panelComponent.getLines().add(new PanelComponent.Line(getText().substring(0, 5), TITLED_CONTENT_COLOR)); + + panelComponent.getLines().add(new PanelComponent.Line("Travel to the fairy ring")); + panelComponent.getLines().add(new PanelComponent.Line("to see where to dig.")); + } + + @Override + public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) + { + LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation()); + + if (localLocation == null) + { + return; + } + + OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, SPADE_IMAGE, Color.ORANGE); + } + + public static FairyRingClue forText(String text) + { + for (FairyRingClue clue : CLUES) + { + if (clue.text.equalsIgnoreCase(text)) + { + return clue; + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MapClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MapClue.java new file mode 100644 index 0000000000..ea02ef9b7f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MapClue.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.Set; +import lombok.Getter; +import net.runelite.api.GameObject; +import net.runelite.api.ObjectComposition; +import net.runelite.api.Region; +import net.runelite.api.Tile; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.components.PanelComponent; +import static net.runelite.api.ItemID.*; +import static net.runelite.api.ObjectID.*; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_BORDER_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_FILL_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_HOVER_BORDER_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLUE_SCROLL_IMAGE; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.SPADE_IMAGE; + +@Getter +public class MapClue extends ClueScroll implements ObjectClueScroll +{ + private static final Set CLUES = ImmutableSet.of( + new MapClue(CLUE_SCROLL_EASY_2713, new WorldPoint(2977, 3341, 0)), + new MapClue(CLUE_SCROLL_EASY_2716, new WorldPoint(3290, 3374, 0)), + new MapClue(CLUE_SCROLL_EASY_2719, new WorldPoint(3043, 3398, 0)), + new MapClue(CLUE_SCROLL_HARD, new WorldPoint(3309, 3502, 0), CRATE_2620), + new MapClue(CLUE_SCROLL_EASY_3516, new WorldPoint(2612, 3482, 0)), + new MapClue(CLUE_SCROLL_EASY_3518, new WorldPoint(3110, 3152, 0)), + new MapClue(CLUE_SCROLL_HARD_3520, new WorldPoint(2616, 3077, 0)), + new MapClue(CLUE_SCROLL_HARD_3522, new WorldPoint(2488, 3308, 0)), + new MapClue(CLUE_SCROLL_HARD_3524, new WorldPoint(3458, 3182, 0), CRATE_18506), + new MapClue(CLUE_SCROLL_HARD_3525, new WorldPoint(3026, 3629, 0), CRATE_354), + new MapClue(CLUE_SCROLL_MEDIUM_3596, new WorldPoint(2907, 3295, 0)), + new MapClue(CLUE_SCROLL_MEDIUM_3598, new WorldPoint(2659, 3488, 0), CRATE_357), + new MapClue(CLUE_SCROLL_MEDIUM_3599, new WorldPoint(2651, 3231, 0)), + new MapClue(CLUE_SCROLL_MEDIUM_3601, new WorldPoint(2564, 3249, 0), CRATE_354), + new MapClue(CLUE_SCROLL_MEDIUM_3602, new WorldPoint(2924, 3210, 0)), + new MapClue(CLUE_SCROLL_EASY_7236, new WorldPoint(2970, 3415, 0)), + new MapClue(CLUE_SCROLL_HARD_7241, new WorldPoint(2722, 3338, 0)), + new MapClue(CLUE_SCROLL_MEDIUM_7286, new WorldPoint(2536, 3865, 0)), + new MapClue(CLUE_SCROLL_MEDIUM_7288, new WorldPoint(3434, 3265, 0)), + new MapClue(CLUE_SCROLL_MEDIUM_7290, new WorldPoint(2454, 3230, 0)), + new MapClue(CLUE_SCROLL_MEDIUM_7292, new WorldPoint(2578, 3597, 0)), + new MapClue(CLUE_SCROLL_MEDIUM_7294, new WorldPoint(2666, 3562, 0)), + new MapClue(CLUE_SCROLL_ELITE_12130, new WorldPoint(2449, 3130, 0)), + new MapClue(CLUE_SCROLL_EASY_12179, new WorldPoint(3300, 3291, 0)) + ); + + private int itemId; + private WorldPoint location; + private int objectId; + + private MapClue(int itemId, WorldPoint location) + { + this(itemId, location, -1); + } + + private MapClue(int itemId, WorldPoint location, int objectId) + { + this.itemId = itemId; + this.location = location; + this.objectId = objectId; + } + + @Override + public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) + { + panelComponent.setTitle("Map Clue"); + + if (objectId != -1) + { + panelComponent.setWidth(150); + + ObjectComposition objectToClick = plugin.getClient().getObjectDefinition(getObjectId()); + + String objectName = "N/A"; + if (objectToClick != null) + { + objectName = objectToClick.getName(); + } + + panelComponent.getLines().add(new PanelComponent.Line("Travel to the destination")); + panelComponent.getLines().add(new PanelComponent.Line("and click the " + objectName + ".")); + } + else + { + panelComponent.setWidth(160); + + panelComponent.getLines().add(new PanelComponent.Line("Travel to the destination")); + panelComponent.getLines().add(new PanelComponent.Line("and dig on the marked tile.")); + } + } + + @Override + public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) + { + LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation()); + + if (localLocation == null) + { + return; + } + + // Mark game object + if (objectId != -1) + { + Region region = plugin.getClient().getRegion(); + Tile[][][] tiles = region.getTiles(); + + Tile tile = tiles[plugin.getClient().getPlane()][localLocation.getRegionX()][localLocation.getRegionY()]; + + net.runelite.api.Point mousePosition = plugin.getClient().getMouseCanvasPosition(); + + for (GameObject gameObject : tile.getGameObjects()) + { + if (gameObject != null) + { + OverlayUtil.renderHoverableArea(graphics, gameObject.getClickbox(), mousePosition, + CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR); + + OverlayUtil.renderImageLocation(plugin.getClient(), graphics, localLocation, CLUE_SCROLL_IMAGE, IMAGE_Z_OFFSET); + } + } + } + else + { + OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, SPADE_IMAGE, Color.ORANGE); + } + } + + public static MapClue forItemId(int itemId) + { + for (MapClue clue : CLUES) + { + if (clue.itemId == itemId) + { + return clue; + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/NpcClueScroll.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/NpcClueScroll.java new file mode 100644 index 0000000000..df8d468817 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/NpcClueScroll.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +public interface NpcClueScroll +{ + String getNpc(); +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ObjectClueScroll.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ObjectClueScroll.java new file mode 100644 index 0000000000..87149e6a67 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ObjectClueScroll.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +public interface ObjectClueScroll +{ + int getObjectId(); +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/TextClueScroll.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/TextClueScroll.java new file mode 100644 index 0000000000..d402606618 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/TextClueScroll.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, Lotto + * 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.clues; + +public interface TextClueScroll +{ + String getText(); +}