diff --git a/http-api/src/main/java/net/runelite/http/api/examine/ExamineClient.java b/http-api/src/main/java/net/runelite/http/api/examine/ExamineClient.java deleted file mode 100644 index 3271f9994e..0000000000 --- a/http-api/src/main/java/net/runelite/http/api/examine/ExamineClient.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.http.api.examine; - -import java.io.IOException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import net.runelite.http.api.RuneLiteAPI; -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; - -@Slf4j -@RequiredArgsConstructor -public class ExamineClient -{ - private static final MediaType TEXT = MediaType.parse("text"); - - private final OkHttpClient client; - - public void submitObject(int id, String text) - { - submit("object", id, text); - } - - public void submitNpc(int id, String text) - { - submit("npc", id, text); - } - - public void submitItem(int id, String text) - { - submit("item", id, text); - } - - private void submit(String type, int id, String text) - { - HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() - .addPathSegment("examine") - .addPathSegment(type) - .addPathSegment(Integer.toString(id)) - .build(); - - log.debug("Built URI: {}", url); - - Request request = new Request.Builder() - .url(url) - .post(RequestBody.create(TEXT, text)) - .build(); - - client.newCall(request).enqueue(new Callback() - { - @Override - public void onFailure(Call call, IOException e) - { - log.warn("Error submitting examine", e); - } - - @Override - public void onResponse(Call call, Response response) - { - response.close(); - log.debug("Submitted examine info for {} {}: {}", type, id, text); - } - }); - } -} diff --git a/runelite-api/src/main/java/net/runelite/api/queries/HotColdLocationTest.java b/runelite-api/src/main/java/net/runelite/api/queries/HotColdLocationTest.java new file mode 100644 index 0000000000..01636a6754 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/queries/HotColdLocationTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +<<<<<<< HEAD:deobfuscator/src/test/java/net/runelite/deob/deobfuscators/unusedclass/EmptyInterface.java +package net.runelite.deob.deobfuscators.unusedclass; + +public interface EmptyInterface {} +======= +package net.runelite.client.plugins.cluescrolls.clues.hotcold; + +import org.junit.Test; + +public class HotColdLocationTest +{ + @Test + public void test() + { + HotColdLocation.values(); // test clinit + } +} +>>>>>>> upstream/master:runelite-api/src/main/java/net/runelite/api/queries/HotColdLocationTest.java diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java b/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java index f01e7b6bb3..19bb851535 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java @@ -846,6 +846,20 @@ public interface Widget */ void setYPositionMode(int ypm); + /** + * Get the line height for this widget. + * + * @return + */ + int getLineHeight(); + + /** + * Set the line height for this widget. If set to 0, the line height is taken from the font instead. + * + * @param lineHeight + */ + void setLineHeight(int lineHeight); + /** * Gets the X axis text position mode * diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java index db600bc120..fad7b9246e 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java @@ -193,8 +193,8 @@ public enum ItemMapping ITEM_DRAGONFIRE_SHIELD(DRAGONFIRE_SHIELD_11284, DRAGONFIRE_SHIELD), ITEM_DRAGONFIRE_WARD(DRAGONFIRE_WARD_22003, DRAGONFIRE_WARD), ITEM_ANCIENT_WYVERN_SHIELD(ANCIENT_WYVERN_SHIELD_21634, ANCIENT_WYVERN_SHIELD), - ITEM_SANGUINESTI_STAFF(SANGUINESTI_STAFF_UNCHARGED, SANGUINESTI_STAFF), - ITEM_SCYTHE_OF_VITUR(SCYTHE_OF_VITUR_UNCHARGED, SCYTHE_OF_VITUR), + ITEM_SANGUINESTI_STAFF(SANGUINESTI_STAFF_UNCHARGED, SANGUINESTI_STAFF, HOLY_SANGUINESTI_STAFF_UNCHARGED, HOLY_SANGUINESTI_STAFF), + ITEM_SCYTHE_OF_VITUR(SCYTHE_OF_VITUR_UNCHARGED, SCYTHE_OF_VITUR, HOLY_SCYTHE_OF_VITUR_UNCHARGED, HOLY_SCYTHE_OF_VITUR, SANGUINE_SCYTHE_OF_VITUR_UNCHARGED, SANGUINE_SCYTHE_OF_VITUR), ITEM_TOME_OF_FIRE(TOME_OF_FIRE_EMPTY, TOME_OF_FIRE), ITEM_CRAWS_BOW(CRAWS_BOW_U, CRAWS_BOW), ITEM_VIGGORAS_CHAINMACE(VIGGORAS_CHAINMACE_U, VIGGORAS_CHAINMACE), @@ -252,6 +252,7 @@ public enum ItemMapping ITEM_HARMONISED_ORB(HARMONISED_ORB, HARMONISED_NIGHTMARE_STAFF), ITEM_VOLATILE_ORB(VOLATILE_ORB, VOLATILE_NIGHTMARE_STAFF), ITEM_NIGHTMARE_STAFF(NIGHTMARE_STAFF, ELDRITCH_NIGHTMARE_STAFF, HARMONISED_NIGHTMARE_STAFF, VOLATILE_NIGHTMARE_STAFF), + ITEM_GHARZI_RAPIER(GHRAZI_RAPIER, HOLY_GHRAZI_RAPIER), // Trouver Parchment ITEM_TROUVER_PARCHMENT( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java index 0564d7b38b..0846efdf43 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java @@ -447,7 +447,7 @@ public class TabInterface }) ) .option("2. Only tab", () -> clientThread.invoke(() -> deleteTab(target))) - .option("3. Cancel", Runnables::doNothing) + .option("3. Cancel", Runnables.doNothing()) .build(); break; case Tab.EXPORT_TAB: diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java index 308af21d5b..d58fa8ad27 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java @@ -809,7 +809,7 @@ public class ChatChannelPlugin extends Plugin kickConfirmed = false; }) ) - .option("2. Cancel", Runnables::doNothing) + .option("2. Cancel", Runnables.doNothing()) .build(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 6a2cfc1323..5e5f95d903 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -98,8 +98,8 @@ public class ChatCommandsPlugin extends Plugin private static final String COX_TEAM_SIZES = "(?:\\d+(?:\\+|-\\d+)? players|Solo)"; private static final Pattern RAIDS_PB_PATTERN = Pattern.compile("Congratulations - your raid is complete!
Team size: " + COX_TEAM_SIZES + " Duration: (?[0-9:]+(?:\\.[0-9]+)?) \\(new personal best\\)"); private static final Pattern RAIDS_DURATION_PATTERN = Pattern.compile("Congratulations - your raid is complete!
Team size: " + COX_TEAM_SIZES + " Duration: [0-9:.]+ Personal best: (?[0-9:]+(?:\\.[0-9]+)?)"); - private static final Pattern TOB_WAVE_PB_PATTERN = Pattern.compile("^.*Theatre of Blood wave completion time: (?[0-9:]+(?:\\.[0-9]+)?) \\(new personal best\\)"); - private static final Pattern TOB_WAVE_DURATION_PATTERN = Pattern.compile("^.*Theatre of Blood wave completion time: [0-9:.]+
Personal best: (?[0-9:]+(?:\\.[0-9]+)?)"); + private static final Pattern TOB_WAVE_PB_PATTERN = Pattern.compile("Theatre of Blood wave completion time: (?[0-9:]+(?:\\.[0-9]+)?) \\(new personal best\\)"); + private static final Pattern TOB_WAVE_DURATION_PATTERN = Pattern.compile("Theatre of Blood wave completion time: [0-9:.]+\\. Personal best: (?[0-9:]+(?:\\.[0-9]+)?)"); private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?i)^(?:(?:Fight |Lap |Challenge |Corrupted challenge )?duration:|Subdued in) [0-9:.]+\\. Personal best: (?:)?(?[0-9:]+(?:\\.[0-9]+)?)"); private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?i)^(?:(?:Fight |Lap |Challenge |Corrupted challenge )?duration:|Subdued in) (?[0-9:]+(?:\\.[0-9]+)?) \\(new personal best\\)"); private static final Pattern DUEL_ARENA_WINS_PATTERN = Pattern.compile("You (were defeated|won)! You have(?: now)? won (\\d+) duels?"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java index 30b0b740cd..8464d973e0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java @@ -221,8 +221,10 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener // Convert current message static widget id to dynamic widget id of message node with message contents // When message is right clicked, we are actually right clicking static widget that contains only sender. // The actual message contents are stored in dynamic widgets that follow same order as static widgets. - // Every first dynamic widget is message sender and every second one is message contents. - final int dynamicChildId = (childId - first) * 2 + 1; + // Every first dynamic widget is message sender, every second one is message contents, + // every third one is clan name and every fourth one is clan rank icon. + // The last two are hidden when the message is not from a clan chat or guest clan chat. + final int dynamicChildId = (childId - first) * 4 + 1; // Extract and store message contents when menu is opened because dynamic children can change while right click // menu is open and dynamicChildId will be outdated diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java index ff2b5bb432..09d1026e29 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java @@ -140,7 +140,7 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati .put(new WorldPoint(3441, 3419, 0), new CoordinateClueInfo("Mort Myre Swamp (BKR).", SARADOMIN_WIZARD)) .put(new WorldPoint(2950, 2902, 0), new CoordinateClueInfo("South-east of Kharazi Jungle.", SARADOMIN_WIZARD)) .put(new WorldPoint(2775, 2891, 0), new CoordinateClueInfo("South-west of Kharazi Jungle.", SARADOMIN_WIZARD)) - .put(new WorldPoint(3113, 3602, 0), new CoordinateClueInfo("Wilderness. North of Edgeville (level 11).", ZAMORAK_WIZARD)) + .put(new WorldPoint(3113, 3602, 0), new CoordinateClueInfo("Wilderness. South-west of Ferox Enclave (level 11).", ZAMORAK_WIZARD)) .put(new WorldPoint(2892, 3675, 0), new CoordinateClueInfo("On the summit of Trollheim.", SARADOMIN_WIZARD)) .put(new WorldPoint(3168, 3677, 0), new CoordinateClueInfo("Wilderness. Graveyard of Shadows.", ZAMORAK_WIZARD)) .put(new WorldPoint(2853, 3690, 0), new CoordinateClueInfo("Entrance to the troll Stronghold.", SARADOMIN_WIZARD)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java index a9152aa70a..e33b4be5f4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java @@ -147,7 +147,7 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam any("Earth Rune x15", xOfItem(ItemID.EARTH_RUNE, 15), xOfItem(ItemID.DUST_RUNE, 15), xOfItem(ItemID.MUD_RUNE, 15), xOfItem(ItemID.LAVA_RUNE, 15), item(ItemID.STAFF_OF_EARTH), item(ItemID.EARTH_BATTLESTAFF), item(ItemID.MYSTIC_EARTH_STAFF), item(ItemID.MUD_BATTLESTAFF), item(ItemID.MYSTIC_MUD_STAFF), item(ItemID.DUST_BATTLESTAFF), item(ItemID.MYSTIC_DUST_STAFF), item(ItemID.LAVA_BATTLESTAFF), item(ItemID.MYSTIC_LAVA_STAFF), item(ItemID.LAVA_BATTLESTAFF_21198), item(ItemID.MYSTIC_LAVA_STAFF_21200)), any("Unenchanted Dragonstone Jewellery", item(ItemID.DRAGONSTONE_RING), item(ItemID.DRAGON_NECKLACE), item(ItemID.DRAGONSTONE_BRACELET), item(ItemID.DRAGONSTONE_AMULET))), new SkillChallengeClue("Craft a nature rune.", item(ItemID.PURE_ESSENCE)), - new SkillChallengeClue("Catch a mottled eel with aerial fishing in Lake Molch.", any("Fish chunks or King worms", item(ItemID.FISH_CHUNKS), item(ItemID.KING_WORM)), emptySlot("No Gloves", EquipmentInventorySlot.GLOVES), emptySlot("No Weapon", EquipmentInventorySlot.WEAPON), emptySlot("No Shield", EquipmentInventorySlot.SHIELD)), + new SkillChallengeClue("Catch a mottled eel with aerial fishing in Lake Molch.", any("Fish chunks or King worms", item(ItemID.FISH_CHUNKS), item(ItemID.KING_WORM)), emptySlot("No Gloves", EquipmentInventorySlot.GLOVES), any("No Weapon", emptySlot("", EquipmentInventorySlot.WEAPON), item(ItemID.CORMORANTS_GLOVE), item(ItemID.CORMORANTS_GLOVE_22817)), emptySlot("No Shield", EquipmentInventorySlot.SHIELD)), new SkillChallengeClue("Score a goal in skullball.", true, any("Ring of Charos", item(ItemID.RING_OF_CHAROS), item(ItemID.RING_OF_CHAROSA))), new SkillChallengeClue("Complete a lap of Ape atoll agility course.", true, any("Ninja Monkey Greegree", item(ItemID.NINJA_MONKEY_GREEGREE), item(ItemID.NINJA_MONKEY_GREEGREE_4025), item(ItemID.KRUK_MONKEY_GREEGREE))), new SkillChallengeClue("Create a super defence potion.", item(ItemID.CADANTINE_POTION_UNF), item(ItemID.WHITE_BERRIES)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java index ab01f4b3e3..415c06112b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java @@ -26,12 +26,15 @@ */ package net.runelite.client.plugins.cluescrolls.clues.hotcold; +import com.google.common.base.Preconditions; import java.awt.Rectangle; import lombok.AllArgsConstructor; import lombok.Getter; import net.runelite.api.coords.WorldPoint; import net.runelite.client.plugins.cluescrolls.clues.Enemy; -import static net.runelite.client.plugins.cluescrolls.clues.Enemy.*; +import static net.runelite.client.plugins.cluescrolls.clues.Enemy.ANCIENT_WIZARDS; +import static net.runelite.client.plugins.cluescrolls.clues.Enemy.BRASSICAN_MAGE; +import static net.runelite.client.plugins.cluescrolls.clues.Enemy.BRASSICAN_OR_WIZARDS; import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea.ASGARNIA; import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea.DESERT; import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea.FELDIP_HILLS; @@ -43,6 +46,8 @@ import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea. import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea.WESTERN_PROVINCE; import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea.WILDERNESS; import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea.ZEAH; +import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation.HotColdType.BEGINNER; +import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation.HotColdType.MASTER; // The locations contains all hot/cold points and their descriptions according to the wiki // these central points were obtained by checking wiki location pictures against a coordinate map @@ -53,160 +58,168 @@ import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea. @Getter public enum HotColdLocation { - ASGARNIA_WARRIORS(new WorldPoint(2860, 3562, 0), ASGARNIA, "North of the Warriors' Guild in Burthorpe.", BRASSICAN_MAGE), - ASGARNIA_JATIX(new WorldPoint(2915, 3425, 0), ASGARNIA, "East of Jatix's Herblore Shop in Taverley.", BRASSICAN_MAGE), - ASGARNIA_BARB(new WorldPoint(3033, 3438, 0), ASGARNIA, "West of Barbarian Village.", BRASSICAN_MAGE), - ASGARNIA_MIAZRQA(new WorldPoint(2972, 3486, 0), ASGARNIA, "North of Miazrqa's tower, outside Goblin Village.", BRASSICAN_MAGE), - ASGARNIA_COW(new WorldPoint(3031, 3304, 0), ASGARNIA, "In the cow pen north of Sarah's Farming Shop.", ANCIENT_WIZARDS), - ASGARNIA_PARTY_ROOM(new WorldPoint(3030, 3364, 0), ASGARNIA, "Outside the Falador Party Room.", BRASSICAN_MAGE), - ASGARNIA_CRAFT_GUILD(new WorldPoint(2917, 3295, 0), ASGARNIA, "Outside the Crafting Guild cow pen.", BRASSICAN_MAGE), - ASGARNIA_RIMMINGTON(new WorldPoint(2976, 3239, 0), ASGARNIA, "In the centre of the Rimmington mine.", BRASSICAN_MAGE), - ASGARNIA_MUDSKIPPER(new WorldPoint(2987, 3110, 0), ASGARNIA, "Mudskipper Point, near the starfish in the south-west corner.", BRASSICAN_MAGE), - ASGARNIA_TROLL(new WorldPoint(2910, 3615, 0), ASGARNIA, "The Troll arena, where the player fights Dad during the Troll Stronghold quest. Bring climbing boots if travelling from Burthorpe.", BRASSICAN_MAGE), - DESERT_GENIE(new WorldPoint(3359, 2912, 0), DESERT, "West of Nardah genie cave.", BRASSICAN_MAGE), - DESERT_ALKHARID_MINE(new WorldPoint(3279, 3263, 0), DESERT, "West of Al Kharid mine.", BRASSICAN_MAGE), - DESERT_MENAPHOS_GATE(new WorldPoint(3223, 2820, 0), DESERT, "North of Menaphos gate.", BRASSICAN_MAGE), - DESERT_BEDABIN_CAMP(new WorldPoint(3161, 3047, 0), DESERT, "Bedabin Camp, near the north tent.", BRASSICAN_MAGE), - DESERT_UZER(new WorldPoint(3432, 3105, 0), DESERT, "West of Uzer.", BRASSICAN_MAGE), - DESERT_POLLNIVNEACH(new WorldPoint(3288, 2976, 0), DESERT, "West of Pollnivneach.", BRASSICAN_MAGE), - DESERT_MTA(new WorldPoint(3347, 3295, 0), DESERT, "Next to Mage Training Arena.", BRASSICAN_MAGE), - DESERT_SHANTY(new WorldPoint(3292, 3107, 0), DESERT, "South-west of Shantay Pass.", BRASSICAN_MAGE), - DRAYNOR_MANOR_MUSHROOMS(new WorldPoint(3096, 3379, 0), MISTHALIN, "Patch of mushrooms just northwest of Draynor Manor"), - DRAYNOR_WHEAT_FIELD(new WorldPoint(3120, 3282, 0), MISTHALIN, "Inside the wheat field next to Draynor Village"), - FELDIP_HILLS_JIGGIG(new WorldPoint(2409, 3053, 0), FELDIP_HILLS, "West of Jiggig, east of the fairy ring bkp.", BRASSICAN_MAGE), - FELDIP_HILLS_SW(new WorldPoint(2586, 2897, 0), FELDIP_HILLS, "West of the southeasternmost lake in Feldip Hills.", BRASSICAN_MAGE), - FELDIP_HILLS_GNOME_GLITER(new WorldPoint(2555, 2972, 0), FELDIP_HILLS, "East of the gnome glider (Lemantolly Undri).", BRASSICAN_MAGE), - FELDIP_HILLS_RANTZ(new WorldPoint(2611, 2950, 0), FELDIP_HILLS, "South of Rantz, west of the empty glass bottles.", BRASSICAN_MAGE), - FELDIP_HILLS_SOUTH(new WorldPoint(2486, 3007, 0), FELDIP_HILLS, "South of Jiggig.", BRASSICAN_MAGE), - FELDIP_HILLS_RED_CHIN(new WorldPoint(2530, 2901, 0), FELDIP_HILLS, "Outside the red chinchompa hunting ground entrance, south of the Hunting expert's hut.", BRASSICAN_MAGE), - FELDIP_HILLS_SE(new WorldPoint(2569, 2918, 0), FELDIP_HILLS, "South-east of the ∩-shaped lake, near the Hunter icon.", BRASSICAN_MAGE), - FELDIP_HILLS_CW_BALLOON(new WorldPoint(2451, 3112, 0), FELDIP_HILLS, "Directly west of the Castle Wars balloon.", BRASSICAN_MAGE), - FREMENNIK_PROVINCE_MTN_CAMP(new WorldPoint(2800, 3669, 0), FREMENNIK_PROVINCE, "At the Mountain Camp.", BRASSICAN_MAGE), - FREMENNIK_PROVINCE_RELLEKKA_HUNTER(new WorldPoint(2720, 3784, 0), FREMENNIK_PROVINCE, "At the Rellekka Hunter area, near the Hunter icon.", BRASSICAN_MAGE), - FREMENNIK_PROVINCE_KELGADRIM_ENTRANCE(new WorldPoint(2711, 3689, 0), FREMENNIK_PROVINCE, "West of the Keldagrim entrance mine.", BRASSICAN_MAGE), - FREMENNIK_PROVINCE_SW(new WorldPoint(2604, 3648, 0), FREMENNIK_PROVINCE, "Outside the fence in the south-western corner of Rellekka.", BRASSICAN_MAGE), - FREMENNIK_PROVINCE_LIGHTHOUSE(new WorldPoint(2585, 3601, 0), FREMENNIK_PROVINCE, "South-east of the Lighthouse.", BRASSICAN_MAGE), - FREMENNIK_PROVINCE_ETCETERIA_CASTLE(new WorldPoint(2617, 3862, 0), FREMENNIK_PROVINCE, "South-east of Etceteria's castle.", BRASSICAN_MAGE), - FREMENNIK_PROVINCE_MISC_COURTYARD(new WorldPoint(2527, 3868, 0), FREMENNIK_PROVINCE, "Outside Miscellania's courtyard.", BRASSICAN_MAGE), - FREMENNIK_PROVINCE_FREMMY_ISLES_MINE(new WorldPoint(2374, 3850, 0), FREMENNIK_PROVINCE, "Central Fremennik Isles mine.", ANCIENT_WIZARDS), - FREMENNIK_PROVINCE_WEST_ISLES_MINE(new WorldPoint(2313, 3850, 0), FREMENNIK_PROVINCE, "West Fremennik Isles mine.", ANCIENT_WIZARDS), - FREMENNIK_PROVINCE_WEST_JATIZSO_ENTRANCE(new WorldPoint(2393, 3812, 0), FREMENNIK_PROVINCE, "West of the Jatizso mine entrance.", BRASSICAN_MAGE), - FREMENNIK_PROVINCE_PIRATES_COVE(new WorldPoint(2211, 3817, 0), FREMENNIK_PROVINCE, "Pirates' Cove", ANCIENT_WIZARDS), - FREMENNIK_PROVINCE_ASTRAL_ALTER(new WorldPoint(2149, 3865, 0), FREMENNIK_PROVINCE, "Astral altar", ANCIENT_WIZARDS), - FREMENNIK_PROVINCE_LUNAR_VILLAGE(new WorldPoint(2084, 3916, 0), FREMENNIK_PROVINCE, "Lunar Isle, inside the village.", ANCIENT_WIZARDS), - FREMENNIK_PROVINCE_LUNAR_NORTH(new WorldPoint(2106, 3949, 0), FREMENNIK_PROVINCE, "Lunar Isle, north of the village.", ANCIENT_WIZARDS), - ICE_MOUNTAIN(new WorldPoint(3007, 3475, 0), MISTHALIN, "Atop Ice Mountain"), - ISLE_OF_SOULS_MINE(new WorldPoint(2189, 2794, 0), KANDARIN, "Isle of Souls Mine, south of the Soul Wars lobby", BRASSICAN_MAGE), - KANDARIN_SINCLAR_MANSION(new WorldPoint(2730, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut.", BRASSICAN_MAGE), - KANDARIN_CATHERBY(new WorldPoint(2774, 3436, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation.", BRASSICAN_MAGE), - KANDARIN_GRAND_TREE(new WorldPoint(2448, 3503, 0), KANDARIN, "Grand Tree, just east of the terrorchick gnome enclosure.", BRASSICAN_MAGE), - KANDARIN_SEERS(new WorldPoint(2732, 3485, 0), KANDARIN, "Outside Seers' Village bank.", BRASSICAN_MAGE), - KANDARIN_MCGRUBORS_WOOD(new WorldPoint(2653, 3485, 0), KANDARIN, "McGrubor's Wood", BRASSICAN_MAGE), - KANDARIN_FISHING_BUILD(new WorldPoint(2590, 3369, 0), KANDARIN, "South of Fishing Guild", BRASSICAN_MAGE), - KANDARIN_WITCHHAVEN(new WorldPoint(2707, 3306, 0), KANDARIN, "Outside Witchaven, west of Jeb, Holgart, and Caroline.", BRASSICAN_MAGE), - KANDARIN_NECRO_TOWER(new WorldPoint(2667, 3241, 0), KANDARIN, "Ground floor inside the Necromancer Tower. Easily accessed by using fairy ring code djp.", ANCIENT_WIZARDS), - KANDARIN_FIGHT_ARENA(new WorldPoint(2587, 3135, 0), KANDARIN, "South of the Fight Arena, north-west of the Nightmare Zone.", BRASSICAN_MAGE), - KANDARIN_TREE_GNOME_VILLAGE(new WorldPoint(2530, 3164, 0), KANDARIN, "Tree Gnome Village, near the general store icon.", BRASSICAN_MAGE), - KANDARIN_GRAVE_OF_SCORPIUS(new WorldPoint(2467, 3227, 0), KANDARIN, "Grave of Scorpius", BRASSICAN_MAGE), - KANDARIN_KHAZARD_BATTLEFIELD(new WorldPoint(2522, 3252, 0), KANDARIN, "Khazard Battlefield, south of Tracker gnome 2.", BRASSICAN_MAGE), - KANDARIN_WEST_ARDY(new WorldPoint(2535, 3322, 0), KANDARIN, "West Ardougne, near the staircase outside the Civic Office.", BRASSICAN_MAGE), - KANDARIN_SW_TREE_GNOME_STRONGHOLD(new WorldPoint(2411, 3429, 0), KANDARIN, "South-west Tree Gnome Stronghold", BRASSICAN_MAGE), - KANDARIN_OUTPOST(new WorldPoint(2457, 3362, 0), KANDARIN, "South of the Tree Gnome Stronghold, north-east of the Outpost.", BRASSICAN_MAGE), - KANDARIN_BAXTORIAN_FALLS(new WorldPoint(2530, 3477, 0), KANDARIN, "South-east of Almera's house on Baxtorian Falls.", BRASSICAN_MAGE), - KANDARIN_BA_AGILITY_COURSE(new WorldPoint(2540, 3548, 0), KANDARIN, "Inside the Barbarian Agility Course. Completion of Alfred Grimhand's Barcrawl is required.", BRASSICAN_MAGE), - KARAMJA_MUSA_POINT(new WorldPoint(2913, 3169, 0), KARAMJA, "Musa Point, banana plantation.", BRASSICAN_MAGE), - KARAMJA_BRIMHAVEN_FRUIT_TREE(new WorldPoint(2782, 3215, 0), KARAMJA, "Brimhaven, east of the fruit tree patch.", BRASSICAN_MAGE), - KARAMJA_WEST_BRIMHAVEN(new WorldPoint(2718, 3167, 0), KARAMJA, "West of Brimhaven.", BRASSICAN_MAGE), - KARAMJA_GLIDER(new WorldPoint(2966, 2976, 0), KARAMJA, "West of the gnome glider.", BRASSICAN_MAGE), - KARAMJA_KHARAZI_NE(new WorldPoint(2904, 2925, 0), KARAMJA, "North-eastern part of Kharazi Jungle.", BRASSICAN_MAGE), - KARAMJA_KHARAZI_SW(new WorldPoint(2786, 2899, 0), KARAMJA, "South-western part of Kharazi Jungle.", BRASSICAN_MAGE), - KARAMJA_CRASH_ISLAND(new WorldPoint(2909, 2737, 0), KARAMJA, "Northern part of Crash Island.", BRASSICAN_MAGE), - LUMBRIDGE_COW_FIELD( new WorldPoint(3174, 3336, 0), MISTHALIN, "Cow field north of Lumbridge"), - MISTHALIN_VARROCK_STONE_CIRCLE(new WorldPoint(3225, 3356, 0), MISTHALIN, "South of the stone circle near Varrock's entrance.", BRASSICAN_MAGE), - MISTHALIN_LUMBRIDGE(new WorldPoint(3234, 3169, 0), MISTHALIN, "Just north-west of the Lumbridge Fishing tutor.", BRASSICAN_MAGE), - MISTHALIN_LUMBRIDGE_2(new WorldPoint(3169, 3279, 0), MISTHALIN, "North of the pond between Lumbridge and Draynor Village.", BRASSICAN_MAGE), - MISTHALIN_GERTUDES(new WorldPoint(3154, 3421, 0), MISTHALIN, "North-east of Gertrude's house west of Varrock.", BRASSICAN_MAGE), - MISTHALIN_DRAYNOR_BANK(new WorldPoint(3098, 3234, 0), MISTHALIN, "South of Draynor Village bank.", BRASSICAN_MAGE), - MISTHALIN_LUMBER_YARD(new WorldPoint(3301, 3484, 0), MISTHALIN, "South of Lumber Yard, east of Assistant Serf.", BRASSICAN_MAGE), - MORYTANIA_BURGH_DE_ROTT(new WorldPoint(3546, 3252, 0), MORYTANIA, "In the north-east area of Burgh de Rott, by the reverse-L-shaped ruins.", BRASSICAN_MAGE), - MORYTANIA_DARKMEYER(new WorldPoint(3604, 3326, 0), MORYTANIA, "Southwestern part of Darkmeyer.", BRASSICAN_MAGE), - MORYTANIA_PORT_PHASMATYS(new WorldPoint(3611, 3485, 0), MORYTANIA, "West of Port Phasmatys, south-east of fairy ring.", BRASSICAN_MAGE), - MORYTANIA_HOLLOWS(new WorldPoint(3499, 3421, 0), MORYTANIA, "Inside The Hollows, south of the bridge which was repaired in a quest.", BRASSICAN_MAGE), - MORYTANIA_SWAMP(new WorldPoint(3418, 3372, 0), MORYTANIA, "Inside the Mort Myre Swamp, north-west of the Nature Grotto.", BRASSICAN_MAGE), - MORYTANIA_HAUNTED_MINE(new WorldPoint(3444, 3255, 0), MORYTANIA, "At Haunted Mine quest start.", BRASSICAN_MAGE), - MORYTANIA_MAUSOLEUM(new WorldPoint(3499, 3539, 0), MORYTANIA, "South of the Mausoleum.", BRASSICAN_MAGE), - MORYTANIA_MOS_LES_HARMLESS(new WorldPoint(3740, 3041, 0), MORYTANIA, "Northern area of Mos Le'Harmless, between the lakes.", BRASSICAN_MAGE), - MORYTANIA_MOS_LES_HARMLESS_BAR(new WorldPoint(3666, 2972, 0), MORYTANIA, "Near Mos Le'Harmless southern bar.", BRASSICAN_MAGE), - MORYTANIA_DRAGONTOOTH_NORTH(new WorldPoint(3811, 3569, 0), MORYTANIA, "Northern part of Dragontooth Island.", BRASSICAN_MAGE), - MORYTANIA_DRAGONTOOTH_SOUTH(new WorldPoint(3803, 3532, 0), MORYTANIA, "Southern part of Dragontooth Island.", BRASSICAN_MAGE), - MORYTANIA_SLEPE_TENTS(new WorldPoint(3769, 3383, 0), MORYTANIA, "North-east of Slepe, near the tents.", BRASSICAN_MAGE), - NORTHEAST_OF_AL_KHARID_MINE(new WorldPoint(3332, 3313, 0), MISTHALIN, "Northeast of Al Kharid Mine"), - WESTERN_PROVINCE_EAGLES_PEAK(new WorldPoint(2297, 3529, 0), WESTERN_PROVINCE, "North-west of Eagles' Peak.", BRASSICAN_MAGE), - WESTERN_PROVINCE_PISCATORIS(new WorldPoint(2334, 3685, 0), WESTERN_PROVINCE, "Piscatoris Fishing Colony", ANCIENT_WIZARDS), - WESTERN_PROVINCE_PISCATORIS_HUNTER_AREA(new WorldPoint(2359, 3564, 0), WESTERN_PROVINCE, "Eastern part of Piscatoris Hunter area, south-west of the Falconry.", BRASSICAN_MAGE), - WESTERN_PROVINCE_ARANDAR(new WorldPoint(2370, 3319, 0), WESTERN_PROVINCE, "South-west of the crystal gate to Arandar.", ANCIENT_WIZARDS), - WESTERN_PROVINCE_ELF_CAMP_EAST(new WorldPoint(2268, 3242, 0), WESTERN_PROVINCE, "East of Iorwerth Camp.", BRASSICAN_MAGE), - WESTERN_PROVINCE_ELF_CAMP_NW(new WorldPoint(2177, 3282, 0), WESTERN_PROVINCE, "North-west of Iorwerth Camp.", BRASSICAN_MAGE), - WESTERN_PROVINCE_LLETYA(new WorldPoint(2337, 3166, 0), WESTERN_PROVINCE, "In Lletya.", BRASSICAN_MAGE), - WESTERN_PROVINCE_TYRAS(new WorldPoint(2206, 3158, 0), WESTERN_PROVINCE, "Near Tyras Camp.", BRASSICAN_MAGE), - WESTERN_PROVINCE_ZULANDRA(new WorldPoint(2196, 3057, 0), WESTERN_PROVINCE, "The northern house at Zul-Andra.", BRASSICAN_MAGE), - WILDERNESS_5(new WorldPoint(3173, 3556, 0), WILDERNESS, "North of the Grand Exchange, level 5 Wilderness.", ANCIENT_WIZARDS), - WILDERNESS_12(new WorldPoint(3036, 3612, 0), WILDERNESS, "South-east of the Dark Warriors' Fortress, level 12 Wilderness.", ANCIENT_WIZARDS), - WILDERNESS_20(new WorldPoint(3222, 3679, 0), WILDERNESS, "East of the Corporeal Beast's lair, level 20 Wilderness.", ANCIENT_WIZARDS), - WILDERNESS_27(new WorldPoint(3174, 3736, 0), WILDERNESS, "Inside the Ruins north of the Graveyard of Shadows, level 27 Wilderness.", BRASSICAN_MAGE), - WILDERNESS_28(new WorldPoint(3377, 3737, 0), WILDERNESS, "East of Venenatis' nest, level 28 Wilderness.", BRASSICAN_MAGE), - WILDERNESS_32(new WorldPoint(3311, 3773, 0), WILDERNESS, "North of Venenatis' nest, level 32 Wilderness.", ANCIENT_WIZARDS), - WILDERNESS_35(new WorldPoint(3152, 3796, 0), WILDERNESS, "East of the Wilderness canoe exit, level 35 Wilderness.", BRASSICAN_OR_WIZARDS), - WILDERNESS_37(new WorldPoint(2974, 3814, 0), WILDERNESS, "South-east of the Chaos Temple, level 37 Wilderness.", BRASSICAN_MAGE), - WILDERNESS_38(new WorldPoint(3293, 3813, 0), WILDERNESS, "South of Callisto, level 38 Wilderness.", ANCIENT_WIZARDS), - WILDERNESS_49(new WorldPoint(3136, 3914, 0), WILDERNESS, "South-west of the Deserted Keep, level 49 Wilderness.", BRASSICAN_MAGE), - WILDERNESS_54(new WorldPoint(2981, 3944, 0), WILDERNESS, "West of the Wilderness Agility Course, level 54 Wilderness.", BRASSICAN_MAGE), - ZEAH_BLASTMINE_BANK(new WorldPoint(1504, 3859, 0), ZEAH, "Next to the bank in the Lovakengj blast mine.", BRASSICAN_MAGE), - ZEAH_BLASTMINE_NORTH(new WorldPoint(1488, 3881, 0), ZEAH, "Northern part of the Lovakengj blast mine.", BRASSICAN_MAGE), - ZEAH_LOVAKITE_FURNACE(new WorldPoint(1507, 3819, 0), ZEAH, "Next to the lovakite furnace in Lovakengj.", ANCIENT_WIZARDS), - ZEAH_LOVAKENGJ_MINE(new WorldPoint(1477, 3778, 0), ZEAH, "Next to mithril rock in the Lovakengj mine.", ANCIENT_WIZARDS), - ZEAH_SULPHR_MINE(new WorldPoint(1428, 3869, 0), ZEAH, "Western entrance in the Lovakengj sulphur mine. Facemask or Slayer Helmet recommended.", BRASSICAN_MAGE), - ZEAH_SHAYZIEN_BANK(new WorldPoint(1517, 3603, 0), ZEAH, "South-east of the bank in Shayzien.", ANCIENT_WIZARDS), - ZEAH_OVERPASS(new WorldPoint(1467, 3714, 0), ZEAH, "Overpass between Lovakengj and Shayzien.", BRASSICAN_MAGE), - ZEAH_LIZARDMAN(new WorldPoint(1490, 3698, 0), ZEAH, "Within Lizardman Canyon, east of the ladder. Requires 5% favour with Shayzien.", ANCIENT_WIZARDS), - ZEAH_COMBAT_RING(new WorldPoint(1559, 3582, 0), ZEAH, "Shayzien, south-east of the Combat Ring.", BRASSICAN_MAGE), - ZEAH_SHAYZIEN_BANK_2(new WorldPoint(1491, 3623, 0), ZEAH, "North-west of the bank in Shayzien.", ANCIENT_WIZARDS), - ZEAH_LIBRARY(new WorldPoint(1603, 3843, 0), ZEAH, "North-west of the Arceuus Library.", BRASSICAN_MAGE), - ZEAH_HOUSECHURCH(new WorldPoint(1682, 3792, 0), ZEAH, "By the entrance to the Arceuus church.", ANCIENT_WIZARDS), - ZEAH_DARK_ALTAR(new WorldPoint(1698, 3881, 0), ZEAH, "West of the Dark Altar.", BRASSICAN_MAGE), - ZEAH_ARCEUUS_HOUSE(new WorldPoint(1710, 3700, 0), ZEAH, "By the southern entrance to Arceuus.", ANCIENT_WIZARDS), - ZEAH_ESSENCE_MINE(new WorldPoint(1762, 3852, 0), ZEAH, "By the Arceuus essence mine.", BRASSICAN_MAGE), - ZEAH_ESSENCE_MINE_NE(new WorldPoint(1773, 3867, 0), ZEAH, "North-east of the Arceuus essence mine.", BRASSICAN_MAGE), - ZEAH_PISCARILUS_MINE(new WorldPoint(1768, 3705, 0), ZEAH, "South of the Piscarilius mine.", ANCIENT_WIZARDS), - ZEAH_GOLDEN_FIELD_TAVERN(new WorldPoint(1718, 3643, 0), ZEAH, "South of the gravestone in Kingstown.", BRASSICAN_MAGE), - ZEAH_MESS_HALL(new WorldPoint(1656, 3621, 0), ZEAH, "East of the Mess hall.", ANCIENT_WIZARDS), - ZEAH_WATSONS_HOUSE(new WorldPoint(1653, 3573, 0), ZEAH, "East of Watson's house.", ANCIENT_WIZARDS), - ZEAH_VANNAHS_FARM_STORE(new WorldPoint(1807, 3523, 0), ZEAH, "North of Tithe Farm, next to the pond.", BRASSICAN_MAGE), - ZEAH_FARMING_GUILD_W(new WorldPoint(1208, 3736, 0), ZEAH, "West of the Farming Guild.", BRASSICAN_MAGE), - ZEAH_DAIRY_COW(new WorldPoint(1324, 3722, 0), ZEAH, "North-east of the Kebos Lowlands, east of the dairy cow.", BRASSICAN_MAGE), - ZEAH_CRIMSON_SWIFTS(new WorldPoint(1187, 3580, 0), ZEAH, "South-west of the Kebos Swamp, below the crimson swifts.", BRASSICAN_MAGE); + ASGARNIA_WARRIORS(MASTER, new WorldPoint(2860, 3562, 0), ASGARNIA, "North of the Warriors' Guild in Burthorpe.", BRASSICAN_MAGE), + ASGARNIA_JATIX(MASTER, new WorldPoint(2915, 3425, 0), ASGARNIA, "East of Jatix's Herblore Shop in Taverley.", BRASSICAN_MAGE), + ASGARNIA_BARB(MASTER, new WorldPoint(3033, 3438, 0), ASGARNIA, "West of Barbarian Village.", BRASSICAN_MAGE), + ASGARNIA_MIAZRQA(MASTER, new WorldPoint(2972, 3486, 0), ASGARNIA, "North of Miazrqa's tower, outside Goblin Village.", BRASSICAN_MAGE), + ASGARNIA_COW(MASTER, new WorldPoint(3031, 3304, 0), ASGARNIA, "In the cow pen north of Sarah's Farming Shop.", ANCIENT_WIZARDS), + ASGARNIA_PARTY_ROOM(MASTER, new WorldPoint(3030, 3364, 0), ASGARNIA, "Outside the Falador Party Room.", BRASSICAN_MAGE), + ASGARNIA_CRAFT_GUILD(MASTER, new WorldPoint(2917, 3295, 0), ASGARNIA, "Outside the Crafting Guild cow pen.", BRASSICAN_MAGE), + ASGARNIA_RIMMINGTON(MASTER, new WorldPoint(2976, 3239, 0), ASGARNIA, "In the centre of the Rimmington mine.", BRASSICAN_MAGE), + ASGARNIA_MUDSKIPPER(MASTER, new WorldPoint(2987, 3110, 0), ASGARNIA, "Mudskipper Point, near the starfish in the south-west corner.", BRASSICAN_MAGE), + ASGARNIA_TROLL(MASTER, new WorldPoint(2910, 3615, 0), ASGARNIA, "The Troll arena, where the player fights Dad during the Troll Stronghold quest. Bring climbing boots if travelling from Burthorpe.", BRASSICAN_MAGE), + DESERT_GENIE(MASTER, new WorldPoint(3359, 2912, 0), DESERT, "West of Nardah genie cave.", BRASSICAN_MAGE), + DESERT_ALKHARID_MINE(MASTER, new WorldPoint(3279, 3263, 0), DESERT, "West of Al Kharid mine.", BRASSICAN_MAGE), + DESERT_MENAPHOS_GATE(MASTER, new WorldPoint(3223, 2820, 0), DESERT, "North of Menaphos gate.", BRASSICAN_MAGE), + DESERT_BEDABIN_CAMP(MASTER, new WorldPoint(3161, 3047, 0), DESERT, "Bedabin Camp, near the north tent.", BRASSICAN_MAGE), + DESERT_UZER(MASTER, new WorldPoint(3432, 3105, 0), DESERT, "West of Uzer.", BRASSICAN_MAGE), + DESERT_POLLNIVNEACH(MASTER, new WorldPoint(3288, 2976, 0), DESERT, "West of Pollnivneach.", BRASSICAN_MAGE), + DESERT_MTA(MASTER, new WorldPoint(3347, 3295, 0), DESERT, "Next to Mage Training Arena.", BRASSICAN_MAGE), + DESERT_SHANTY(MASTER, new WorldPoint(3292, 3107, 0), DESERT, "South-west of Shantay Pass.", BRASSICAN_MAGE), + DRAYNOR_MANOR_MUSHROOMS(BEGINNER, new WorldPoint(3096, 3379, 0), MISTHALIN, "Patch of mushrooms just northwest of Draynor Manor"), + DRAYNOR_WHEAT_FIELD(BEGINNER, new WorldPoint(3120, 3282, 0), MISTHALIN, "Inside the wheat field next to Draynor Village"), + FELDIP_HILLS_JIGGIG(MASTER, new WorldPoint(2409, 3053, 0), FELDIP_HILLS, "West of Jiggig, east of the fairy ring bkp.", BRASSICAN_MAGE), + FELDIP_HILLS_SW(MASTER, new WorldPoint(2586, 2897, 0), FELDIP_HILLS, "West of the southeasternmost lake in Feldip Hills.", BRASSICAN_MAGE), + FELDIP_HILLS_GNOME_GLITER(MASTER, new WorldPoint(2555, 2972, 0), FELDIP_HILLS, "East of the gnome glider (Lemantolly Undri).", BRASSICAN_MAGE), + FELDIP_HILLS_RANTZ(MASTER, new WorldPoint(2611, 2950, 0), FELDIP_HILLS, "South of Rantz, west of the empty glass bottles.", BRASSICAN_MAGE), + FELDIP_HILLS_SOUTH(MASTER, new WorldPoint(2486, 3007, 0), FELDIP_HILLS, "South of Jiggig.", BRASSICAN_MAGE), + FELDIP_HILLS_RED_CHIN(MASTER, new WorldPoint(2530, 2901, 0), FELDIP_HILLS, "Outside the red chinchompa hunting ground entrance, south of the Hunting expert's hut.", BRASSICAN_MAGE), + FELDIP_HILLS_SE(MASTER, new WorldPoint(2569, 2918, 0), FELDIP_HILLS, "South-east of the ∩-shaped lake, near the Hunter icon.", BRASSICAN_MAGE), + FELDIP_HILLS_CW_BALLOON(MASTER, new WorldPoint(2451, 3112, 0), FELDIP_HILLS, "Directly west of the Castle Wars balloon.", BRASSICAN_MAGE), + FREMENNIK_PROVINCE_MTN_CAMP(MASTER, new WorldPoint(2800, 3669, 0), FREMENNIK_PROVINCE, "At the Mountain Camp.", BRASSICAN_MAGE), + FREMENNIK_PROVINCE_RELLEKKA_HUNTER(MASTER, new WorldPoint(2720, 3784, 0), FREMENNIK_PROVINCE, "At the Rellekka Hunter area, near the Hunter icon.", BRASSICAN_MAGE), + FREMENNIK_PROVINCE_KELGADRIM_ENTRANCE(MASTER, new WorldPoint(2711, 3689, 0), FREMENNIK_PROVINCE, "West of the Keldagrim entrance mine.", BRASSICAN_MAGE), + FREMENNIK_PROVINCE_SW(MASTER, new WorldPoint(2604, 3648, 0), FREMENNIK_PROVINCE, "Outside the fence in the south-western corner of Rellekka.", BRASSICAN_MAGE), + FREMENNIK_PROVINCE_LIGHTHOUSE(MASTER, new WorldPoint(2585, 3601, 0), FREMENNIK_PROVINCE, "South-east of the Lighthouse.", BRASSICAN_MAGE), + FREMENNIK_PROVINCE_ETCETERIA_CASTLE(MASTER, new WorldPoint(2617, 3862, 0), FREMENNIK_PROVINCE, "South-east of Etceteria's castle.", BRASSICAN_MAGE), + FREMENNIK_PROVINCE_MISC_COURTYARD(MASTER, new WorldPoint(2527, 3868, 0), FREMENNIK_PROVINCE, "Outside Miscellania's courtyard.", BRASSICAN_MAGE), + FREMENNIK_PROVINCE_FREMMY_ISLES_MINE(MASTER, new WorldPoint(2374, 3850, 0), FREMENNIK_PROVINCE, "Central Fremennik Isles mine.", ANCIENT_WIZARDS), + FREMENNIK_PROVINCE_WEST_ISLES_MINE(MASTER, new WorldPoint(2313, 3850, 0), FREMENNIK_PROVINCE, "West Fremennik Isles mine.", ANCIENT_WIZARDS), + FREMENNIK_PROVINCE_WEST_JATIZSO_ENTRANCE(MASTER, new WorldPoint(2393, 3812, 0), FREMENNIK_PROVINCE, "West of the Jatizso mine entrance.", BRASSICAN_MAGE), + FREMENNIK_PROVINCE_PIRATES_COVE(MASTER, new WorldPoint(2211, 3817, 0), FREMENNIK_PROVINCE, "Pirates' Cove", ANCIENT_WIZARDS), + FREMENNIK_PROVINCE_ASTRAL_ALTER(MASTER, new WorldPoint(2149, 3865, 0), FREMENNIK_PROVINCE, "Astral altar", ANCIENT_WIZARDS), + FREMENNIK_PROVINCE_LUNAR_VILLAGE(MASTER, new WorldPoint(2084, 3916, 0), FREMENNIK_PROVINCE, "Lunar Isle, inside the village.", ANCIENT_WIZARDS), + FREMENNIK_PROVINCE_LUNAR_NORTH(MASTER, new WorldPoint(2106, 3949, 0), FREMENNIK_PROVINCE, "Lunar Isle, north of the village.", ANCIENT_WIZARDS), + ICE_MOUNTAIN(BEGINNER, new WorldPoint(3007, 3475, 0), MISTHALIN, "Atop Ice Mountain"), + ISLE_OF_SOULS_MINE(MASTER, new WorldPoint(2189, 2794, 0), KANDARIN, "Isle of Souls Mine, south of the Soul Wars lobby", BRASSICAN_MAGE), + KANDARIN_SINCLAR_MANSION(MASTER, new WorldPoint(2730, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut.", BRASSICAN_MAGE), + KANDARIN_CATHERBY(MASTER, new WorldPoint(2774, 3436, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation.", BRASSICAN_MAGE), + KANDARIN_GRAND_TREE(MASTER, new WorldPoint(2448, 3503, 0), KANDARIN, "Grand Tree, just east of the terrorchick gnome enclosure.", BRASSICAN_MAGE), + KANDARIN_SEERS(MASTER, new WorldPoint(2732, 3485, 0), KANDARIN, "Outside Seers' Village bank.", BRASSICAN_MAGE), + KANDARIN_MCGRUBORS_WOOD(MASTER, new WorldPoint(2653, 3485, 0), KANDARIN, "McGrubor's Wood", BRASSICAN_MAGE), + KANDARIN_FISHING_BUILD(MASTER, new WorldPoint(2590, 3369, 0), KANDARIN, "South of Fishing Guild", BRASSICAN_MAGE), + KANDARIN_WITCHHAVEN(MASTER, new WorldPoint(2707, 3306, 0), KANDARIN, "Outside Witchaven, west of Jeb, Holgart, and Caroline.", BRASSICAN_MAGE), + KANDARIN_NECRO_TOWER(MASTER, new WorldPoint(2667, 3241, 0), KANDARIN, "Ground floor inside the Necromancer Tower. Easily accessed by using fairy ring code djp.", ANCIENT_WIZARDS), + KANDARIN_FIGHT_ARENA(MASTER, new WorldPoint(2587, 3135, 0), KANDARIN, "South of the Fight Arena, north-west of the Nightmare Zone.", BRASSICAN_MAGE), + KANDARIN_TREE_GNOME_VILLAGE(MASTER, new WorldPoint(2530, 3164, 0), KANDARIN, "Tree Gnome Village, near the general store icon.", BRASSICAN_MAGE), + KANDARIN_GRAVE_OF_SCORPIUS(MASTER, new WorldPoint(2467, 3227, 0), KANDARIN, "Grave of Scorpius", BRASSICAN_MAGE), + KANDARIN_KHAZARD_BATTLEFIELD(MASTER, new WorldPoint(2522, 3252, 0), KANDARIN, "Khazard Battlefield, south of Tracker gnome 2.", BRASSICAN_MAGE), + KANDARIN_WEST_ARDY(MASTER, new WorldPoint(2535, 3322, 0), KANDARIN, "West Ardougne, near the staircase outside the Civic Office.", BRASSICAN_MAGE), + KANDARIN_SW_TREE_GNOME_STRONGHOLD(MASTER, new WorldPoint(2411, 3429, 0), KANDARIN, "South-west Tree Gnome Stronghold", BRASSICAN_MAGE), + KANDARIN_OUTPOST(MASTER, new WorldPoint(2457, 3362, 0), KANDARIN, "South of the Tree Gnome Stronghold, north-east of the Outpost.", BRASSICAN_MAGE), + KANDARIN_BAXTORIAN_FALLS(MASTER, new WorldPoint(2530, 3477, 0), KANDARIN, "South-east of Almera's house on Baxtorian Falls.", BRASSICAN_MAGE), + KANDARIN_BA_AGILITY_COURSE(MASTER, new WorldPoint(2540, 3548, 0), KANDARIN, "Inside the Barbarian Agility Course. Completion of Alfred Grimhand's Barcrawl is required.", BRASSICAN_MAGE), + KARAMJA_MUSA_POINT(MASTER, new WorldPoint(2913, 3169, 0), KARAMJA, "Musa Point, banana plantation.", BRASSICAN_MAGE), + KARAMJA_BRIMHAVEN_FRUIT_TREE(MASTER, new WorldPoint(2782, 3215, 0), KARAMJA, "Brimhaven, east of the fruit tree patch.", BRASSICAN_MAGE), + KARAMJA_WEST_BRIMHAVEN(MASTER, new WorldPoint(2718, 3167, 0), KARAMJA, "West of Brimhaven.", BRASSICAN_MAGE), + KARAMJA_GLIDER(MASTER, new WorldPoint(2966, 2976, 0), KARAMJA, "West of the gnome glider.", BRASSICAN_MAGE), + KARAMJA_KHARAZI_NE(MASTER, new WorldPoint(2904, 2925, 0), KARAMJA, "North-eastern part of Kharazi Jungle.", BRASSICAN_MAGE), + KARAMJA_KHARAZI_SW(MASTER, new WorldPoint(2786, 2899, 0), KARAMJA, "South-western part of Kharazi Jungle.", BRASSICAN_MAGE), + KARAMJA_CRASH_ISLAND(MASTER, new WorldPoint(2909, 2737, 0), KARAMJA, "Northern part of Crash Island.", BRASSICAN_MAGE), + LUMBRIDGE_COW_FIELD(BEGINNER, new WorldPoint(3174, 3336, 0), MISTHALIN, "Cow field north of Lumbridge"), + MISTHALIN_VARROCK_STONE_CIRCLE(MASTER, new WorldPoint(3225, 3356, 0), MISTHALIN, "South of the stone circle near Varrock's entrance.", BRASSICAN_MAGE), + MISTHALIN_LUMBRIDGE(MASTER, new WorldPoint(3234, 3169, 0), MISTHALIN, "Just north-west of the Lumbridge Fishing tutor.", BRASSICAN_MAGE), + MISTHALIN_LUMBRIDGE_2(MASTER, new WorldPoint(3169, 3279, 0), MISTHALIN, "North of the pond between Lumbridge and Draynor Village.", BRASSICAN_MAGE), + MISTHALIN_GERTUDES(MASTER, new WorldPoint(3154, 3421, 0), MISTHALIN, "North-east of Gertrude's house west of Varrock.", BRASSICAN_MAGE), + MISTHALIN_DRAYNOR_BANK(MASTER, new WorldPoint(3098, 3234, 0), MISTHALIN, "South of Draynor Village bank.", BRASSICAN_MAGE), + MISTHALIN_LUMBER_YARD(MASTER, new WorldPoint(3301, 3484, 0), MISTHALIN, "South of Lumber Yard, east of Assistant Serf.", BRASSICAN_MAGE), + MORYTANIA_BURGH_DE_ROTT(MASTER, new WorldPoint(3546, 3252, 0), MORYTANIA, "In the north-east area of Burgh de Rott, by the reverse-L-shaped ruins.", BRASSICAN_MAGE), + MORYTANIA_DARKMEYER(MASTER, new WorldPoint(3604, 3326, 0), MORYTANIA, "Southwestern part of Darkmeyer.", BRASSICAN_MAGE), + MORYTANIA_PORT_PHASMATYS(MASTER, new WorldPoint(3611, 3485, 0), MORYTANIA, "West of Port Phasmatys, south-east of fairy ring.", BRASSICAN_MAGE), + MORYTANIA_HOLLOWS(MASTER, new WorldPoint(3499, 3421, 0), MORYTANIA, "Inside The Hollows, south of the bridge which was repaired in a quest.", BRASSICAN_MAGE), + MORYTANIA_SWAMP(MASTER, new WorldPoint(3418, 3372, 0), MORYTANIA, "Inside the Mort Myre Swamp, north-west of the Nature Grotto.", BRASSICAN_MAGE), + MORYTANIA_HAUNTED_MINE(MASTER, new WorldPoint(3444, 3255, 0), MORYTANIA, "At Haunted Mine quest start.", BRASSICAN_MAGE), + MORYTANIA_MAUSOLEUM(MASTER, new WorldPoint(3499, 3539, 0), MORYTANIA, "South of the Mausoleum.", BRASSICAN_MAGE), + MORYTANIA_MOS_LES_HARMLESS(MASTER, new WorldPoint(3740, 3041, 0), MORYTANIA, "Northern area of Mos Le'Harmless, between the lakes.", BRASSICAN_MAGE), + MORYTANIA_MOS_LES_HARMLESS_BAR(MASTER, new WorldPoint(3666, 2972, 0), MORYTANIA, "Near Mos Le'Harmless southern bar.", BRASSICAN_MAGE), + MORYTANIA_DRAGONTOOTH_NORTH(MASTER, new WorldPoint(3811, 3569, 0), MORYTANIA, "Northern part of Dragontooth Island.", BRASSICAN_MAGE), + MORYTANIA_DRAGONTOOTH_SOUTH(MASTER, new WorldPoint(3803, 3532, 0), MORYTANIA, "Southern part of Dragontooth Island.", BRASSICAN_MAGE), + MORYTANIA_SLEPE_TENTS(MASTER, new WorldPoint(3769, 3383, 0), MORYTANIA, "North-east of Slepe, near the tents.", BRASSICAN_MAGE), + NORTHEAST_OF_AL_KHARID_MINE(BEGINNER, new WorldPoint(3332, 3313, 0), MISTHALIN, "Northeast of Al Kharid Mine"), + WESTERN_PROVINCE_EAGLES_PEAK(MASTER, new WorldPoint(2297, 3529, 0), WESTERN_PROVINCE, "North-west of Eagles' Peak.", BRASSICAN_MAGE), + WESTERN_PROVINCE_PISCATORIS(MASTER, new WorldPoint(2334, 3685, 0), WESTERN_PROVINCE, "Piscatoris Fishing Colony", ANCIENT_WIZARDS), + WESTERN_PROVINCE_PISCATORIS_HUNTER_AREA(MASTER, new WorldPoint(2359, 3564, 0), WESTERN_PROVINCE, "Eastern part of Piscatoris Hunter area, south-west of the Falconry.", BRASSICAN_MAGE), + WESTERN_PROVINCE_ARANDAR(MASTER, new WorldPoint(2370, 3319, 0), WESTERN_PROVINCE, "South-west of the crystal gate to Arandar.", ANCIENT_WIZARDS), + WESTERN_PROVINCE_ELF_CAMP_EAST(MASTER, new WorldPoint(2268, 3242, 0), WESTERN_PROVINCE, "East of Iorwerth Camp.", BRASSICAN_MAGE), + WESTERN_PROVINCE_ELF_CAMP_NW(MASTER, new WorldPoint(2177, 3282, 0), WESTERN_PROVINCE, "North-west of Iorwerth Camp.", BRASSICAN_MAGE), + WESTERN_PROVINCE_LLETYA(MASTER, new WorldPoint(2337, 3166, 0), WESTERN_PROVINCE, "In Lletya.", BRASSICAN_MAGE), + WESTERN_PROVINCE_TYRAS(MASTER, new WorldPoint(2206, 3158, 0), WESTERN_PROVINCE, "Near Tyras Camp.", BRASSICAN_MAGE), + WESTERN_PROVINCE_ZULANDRA(MASTER, new WorldPoint(2196, 3057, 0), WESTERN_PROVINCE, "The northern house at Zul-Andra.", BRASSICAN_MAGE), + WILDERNESS_5(MASTER, new WorldPoint(3173, 3556, 0), WILDERNESS, "North of the Grand Exchange, level 5 Wilderness.", ANCIENT_WIZARDS), + WILDERNESS_12(MASTER, new WorldPoint(3036, 3612, 0), WILDERNESS, "South-east of the Dark Warriors' Fortress, level 12 Wilderness.", ANCIENT_WIZARDS), + WILDERNESS_20(MASTER, new WorldPoint(3222, 3679, 0), WILDERNESS, "East of the Corporeal Beast's lair, level 20 Wilderness.", ANCIENT_WIZARDS), + WILDERNESS_27(MASTER, new WorldPoint(3174, 3736, 0), WILDERNESS, "Inside the Ruins north of the Graveyard of Shadows, level 27 Wilderness.", BRASSICAN_MAGE), + WILDERNESS_28(MASTER, new WorldPoint(3377, 3737, 0), WILDERNESS, "East of Venenatis' nest, level 28 Wilderness.", BRASSICAN_MAGE), + WILDERNESS_32(MASTER, new WorldPoint(3311, 3773, 0), WILDERNESS, "North of Venenatis' nest, level 32 Wilderness.", ANCIENT_WIZARDS), + WILDERNESS_35(MASTER, new WorldPoint(3152, 3796, 0), WILDERNESS, "East of the Wilderness canoe exit, level 35 Wilderness.", BRASSICAN_OR_WIZARDS), + WILDERNESS_37(MASTER, new WorldPoint(2974, 3814, 0), WILDERNESS, "South-east of the Chaos Temple, level 37 Wilderness.", BRASSICAN_MAGE), + WILDERNESS_38(MASTER, new WorldPoint(3293, 3813, 0), WILDERNESS, "South of Callisto, level 38 Wilderness.", ANCIENT_WIZARDS), + WILDERNESS_49(MASTER, new WorldPoint(3136, 3914, 0), WILDERNESS, "South-west of the Deserted Keep, level 49 Wilderness.", BRASSICAN_MAGE), + WILDERNESS_54(MASTER, new WorldPoint(2981, 3944, 0), WILDERNESS, "West of the Wilderness Agility Course, level 54 Wilderness.", BRASSICAN_MAGE), + ZEAH_BLASTMINE_BANK(MASTER, new WorldPoint(1504, 3859, 0), ZEAH, "Next to the bank in the Lovakengj blast mine.", BRASSICAN_MAGE), + ZEAH_BLASTMINE_NORTH(MASTER, new WorldPoint(1488, 3881, 0), ZEAH, "Northern part of the Lovakengj blast mine.", BRASSICAN_MAGE), + ZEAH_LOVAKITE_FURNACE(MASTER, new WorldPoint(1507, 3819, 0), ZEAH, "Next to the lovakite furnace in Lovakengj.", ANCIENT_WIZARDS), + ZEAH_LOVAKENGJ_MINE(MASTER, new WorldPoint(1477, 3778, 0), ZEAH, "Next to mithril rock in the Lovakengj mine.", ANCIENT_WIZARDS), + ZEAH_SULPHR_MINE(MASTER, new WorldPoint(1428, 3869, 0), ZEAH, "Western entrance in the Lovakengj sulphur mine. Facemask or Slayer Helmet recommended.", BRASSICAN_MAGE), + ZEAH_SHAYZIEN_BANK(MASTER, new WorldPoint(1517, 3603, 0), ZEAH, "South-east of the bank in Shayzien.", ANCIENT_WIZARDS), + ZEAH_OVERPASS(MASTER, new WorldPoint(1467, 3714, 0), ZEAH, "Overpass between Lovakengj and Shayzien.", BRASSICAN_MAGE), + ZEAH_LIZARDMAN(MASTER, new WorldPoint(1490, 3698, 0), ZEAH, "Within Lizardman Canyon, east of the ladder. Requires 5% favour with Shayzien.", ANCIENT_WIZARDS), + ZEAH_COMBAT_RING(MASTER, new WorldPoint(1559, 3582, 0), ZEAH, "Shayzien, south-east of the Combat Ring.", BRASSICAN_MAGE), + ZEAH_SHAYZIEN_BANK_2(MASTER, new WorldPoint(1491, 3623, 0), ZEAH, "North-west of the bank in Shayzien.", ANCIENT_WIZARDS), + ZEAH_LIBRARY(MASTER, new WorldPoint(1603, 3843, 0), ZEAH, "North-west of the Arceuus Library.", BRASSICAN_MAGE), + ZEAH_HOUSECHURCH(MASTER, new WorldPoint(1682, 3792, 0), ZEAH, "By the entrance to the Arceuus church.", ANCIENT_WIZARDS), + ZEAH_DARK_ALTAR(MASTER, new WorldPoint(1698, 3881, 0), ZEAH, "West of the Dark Altar.", BRASSICAN_MAGE), + ZEAH_ARCEUUS_HOUSE(MASTER, new WorldPoint(1710, 3700, 0), ZEAH, "By the southern entrance to Arceuus.", ANCIENT_WIZARDS), + ZEAH_ESSENCE_MINE(MASTER, new WorldPoint(1762, 3852, 0), ZEAH, "By the Arceuus essence mine.", BRASSICAN_MAGE), + ZEAH_ESSENCE_MINE_NE(MASTER, new WorldPoint(1773, 3867, 0), ZEAH, "North-east of the Arceuus essence mine.", BRASSICAN_MAGE), + ZEAH_PISCARILUS_MINE(MASTER, new WorldPoint(1768, 3705, 0), ZEAH, "South of the Piscarilius mine.", ANCIENT_WIZARDS), + ZEAH_GOLDEN_FIELD_TAVERN(MASTER, new WorldPoint(1718, 3643, 0), ZEAH, "South of the gravestone in Kingstown.", BRASSICAN_MAGE), + ZEAH_MESS_HALL(MASTER, new WorldPoint(1656, 3621, 0), ZEAH, "East of the Mess hall.", ANCIENT_WIZARDS), + ZEAH_WATSONS_HOUSE(MASTER, new WorldPoint(1653, 3573, 0), ZEAH, "East of Watson's house.", ANCIENT_WIZARDS), + ZEAH_VANNAHS_FARM_STORE(MASTER, new WorldPoint(1807, 3523, 0), ZEAH, "North of Tithe Farm, next to the pond.", BRASSICAN_MAGE), + ZEAH_FARMING_GUILD_W(MASTER, new WorldPoint(1208, 3736, 0), ZEAH, "West of the Farming Guild.", BRASSICAN_MAGE), + ZEAH_DAIRY_COW(MASTER, new WorldPoint(1324, 3722, 0), ZEAH, "North-east of the Kebos Lowlands, east of the dairy cow.", BRASSICAN_MAGE), + ZEAH_CRIMSON_SWIFTS(MASTER, new WorldPoint(1187, 3580, 0), ZEAH, "South-west of the Kebos Swamp, below the crimson swifts.", BRASSICAN_MAGE); - private final boolean beginnerClue; + private final HotColdType type; private final WorldPoint worldPoint; private final HotColdArea hotColdArea; private final String area; private final Enemy enemy; - HotColdLocation(WorldPoint worldPoint, HotColdArea hotColdArea, String areaDescription, Enemy enemy) + public enum HotColdType { - this(false, worldPoint, hotColdArea, areaDescription, enemy); + BEGINNER, + MASTER, + ; } - HotColdLocation(WorldPoint worldPoint, HotColdArea hotColdArea, String areaDescription) + HotColdLocation(HotColdType type, WorldPoint worldPoint, HotColdArea hotColdArea, String areaDescription) { - //only master clues have enemies, so if no enemy it is a beginner clue - this(true, worldPoint, hotColdArea, areaDescription, null); + this(type, worldPoint, hotColdArea, areaDescription, null); + // only master clues have enemies, so if no enemy it must be a beginner clue + Preconditions.checkArgument(type == BEGINNER, "locations without bosses must be beginner"); } public Rectangle getRect() { - final int digRadius = beginnerClue ? HotColdTemperature.BEGINNER_VISIBLY_SHAKING.getMaxDistance() : + final int digRadius = isBeginnerClue() ? HotColdTemperature.BEGINNER_VISIBLY_SHAKING.getMaxDistance() : HotColdTemperature.MASTER_VISIBLY_SHAKING.getMaxDistance(); return new Rectangle(worldPoint.getX() - digRadius, worldPoint.getY() - digRadius, digRadius * 2 + 1, digRadius * 2 + 1); } + + public boolean isBeginnerClue() + { + return type == BEGINNER; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 11a2ce8aa3..b9d17a01f3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -777,6 +777,20 @@ class ConfigPanel extends PluginPanel } } + else if (cid.getType() == double.class) + { + double value = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), double.class); + + SpinnerModel model = new SpinnerNumberModel(value, 0, Double.MAX_VALUE, 0.1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); + + item.add(spinner, BorderLayout.EAST); + } + if (cid.getType() == String.class) { JTextComponent textField; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java index c996287728..5e5e9a6011 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java @@ -181,6 +181,7 @@ public class WidgetInfoTableModel extends AbstractTableModel out.add(new WidgetField<>("YPositionMode", Widget::getYPositionMode, Widget::setYPositionMode, Integer.class)); out.add(new WidgetField<>("WidthMode", Widget::getWidthMode, Widget::setWidthMode, Integer.class)); out.add(new WidgetField<>("HeightMode", Widget::getHeightMode, Widget::setHeightMode, Integer.class)); + out.add(new WidgetField<>("LineHeight", Widget::getLineHeight, Widget::setLineHeight, Integer.class)); out.add(new WidgetField<>("XTextAlignment", Widget::getXTextAlignment, Widget::setXTextAlignment, Integer.class)); out.add(new WidgetField<>("YTextAlignment", Widget::getYTextAlignment, Widget::setYTextAlignment, Integer.class)); out.add(new WidgetField<>("RelativeX", Widget::getRelativeX, Widget::setRelativeX, Integer.class)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java index 5e1914b173..8e57e889c8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java @@ -25,13 +25,9 @@ package net.runelite.client.plugins.examine; import com.google.common.annotations.VisibleForTesting; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.inject.Provides; import java.time.Instant; import java.util.ArrayDeque; import java.util.Deque; -import java.util.regex.Pattern; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; @@ -58,14 +54,7 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.Text; -import net.runelite.http.api.examine.ExamineClient; -import okhttp3.OkHttpClient; -/** - * Submits examine info to the api - * - * @author Adam - */ @PluginDescriptor( name = "Examine", description = "Shows additional examine information (eg. GE Average, HA Value)", @@ -74,15 +63,7 @@ import okhttp3.OkHttpClient; @Slf4j public class ExaminePlugin extends Plugin { - private static final Pattern X_PATTERN = Pattern.compile("^\\d+ x "); - private final Deque pending = new ArrayDeque<>(); - private final Cache cache = CacheBuilder.newBuilder() - .maximumSize(128L) - .build(); - - @Inject - private ExamineClient examineClient; @Inject private Client client; @@ -93,12 +74,6 @@ public class ExaminePlugin extends Plugin @Inject private ChatMessageManager chatMessageManager; - @Provides - ExamineClient provideExamineClient(OkHttpClient okHttpClient) - { - return new ExamineClient(okHttpClient); - } - @Subscribe public void onGameStateChanged(GameStateChanged event) { @@ -222,7 +197,6 @@ public class ExaminePlugin extends Plugin log.debug("Got examine for {} {}: {}", pendingExamine.getType(), pendingExamine.getId(), event.getMessage()); // If it is an item, show the price of it - final ItemComposition itemComposition; if (pendingExamine.getType() == ExamineType.ITEM || pendingExamine.getType() == ExamineType.ITEM_BANK_EQ) { final int itemId = pendingExamine.getId(); @@ -233,35 +207,9 @@ public class ExaminePlugin extends Plugin return; } - itemComposition = itemManager.getItemComposition(itemId); + final ItemComposition itemComposition = itemManager.getItemComposition(itemId); getItemPrice(itemComposition.getId(), itemComposition, itemQuantity); } - else - { - itemComposition = null; - } - - // Don't submit examine info for tradeable items, which we already have from the RS item api - if (itemComposition != null && itemComposition.isTradeable()) - { - return; - } - - // Large quantities of items show eg. 100000 x Coins - if (type == ExamineType.ITEM && X_PATTERN.matcher(event.getMessage()).lookingAt()) - { - return; - } - - CacheKey key = new CacheKey(type, pendingExamine.getId()); - Boolean cached = cache.getIfPresent(key); - if (cached != null) - { - return; - } - - cache.put(key, Boolean.TRUE); - submitExamine(pendingExamine, event.getMessage()); } private int[] findItemFromWidget(int widgetId, int actionParam) @@ -407,23 +355,4 @@ public class ExaminePlugin extends Plugin .build()); } } - - private void submitExamine(PendingExamine examine, String text) - { - int id = examine.getId(); - - switch (examine.getType()) - { - case ITEM: - examineClient.submitItem(id, text); - break; - case OBJECT: - examineClient.submitObject(id, text); - break; - case NPC: - examineClient.submitNpc(id, text); - break; - } - } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java index 568a656ae2..b3aaf7bc44 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java @@ -44,11 +44,19 @@ public interface XpDropConfig extends Config return false; } + @ConfigItem( + keyName = "standardColor", + name = "Standard Color", + description = "XP drop color when no prayer is active", + position = 1 + ) + Color standardColor(); + @ConfigItem( keyName = "meleePrayerColor", name = "Melee Prayer Color", description = "XP drop color when a melee prayer is active", - position = 1 + position = 2 ) default Color getMeleePrayerColor() { @@ -59,7 +67,7 @@ public interface XpDropConfig extends Config keyName = "rangePrayerColor", name = "Range Prayer Color", description = "XP drop color when a range prayer is active", - position = 2 + position = 3 ) default Color getRangePrayerColor() { @@ -70,7 +78,7 @@ public interface XpDropConfig extends Config keyName = "magePrayerColor", name = "Mage Prayer Color", description = "XP drop color when a mage prayer is active", - position = 3 + position = 4 ) default Color getMagePrayerColor() { @@ -81,12 +89,11 @@ public interface XpDropConfig extends Config keyName = "fakeXpDropDelay", name = "Fake Xp Drop delay", description = "Configures how many ticks should pass between fake XP drops, 0 to disable", - position = 4 + position = 5 ) @Units(Units.TICKS) default int fakeXpDropDelay() { return 0; } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java index c3b9523f21..419c90b242 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java @@ -25,6 +25,7 @@ package net.runelite.client.plugins.experiencedrop; import com.google.inject.Provides; +import java.awt.Color; import java.util.Arrays; import java.util.EnumMap; import java.util.Map; @@ -151,10 +152,19 @@ public class XpDropPlugin extends Plugin private void resetTextColor(Widget widget) { - EnumComposition colorEnum = client.getEnum(EnumID.XPDROP_COLORS); - int defaultColorId = client.getVar(Varbits.EXPERIENCE_DROP_COLOR); - int color = colorEnum.getIntValue(defaultColorId); - widget.setTextColor(color); + Color standardColor = config.standardColor(); + if (standardColor != null) + { + int color = standardColor.getRGB(); + widget.setTextColor(color); + } + else + { + EnumComposition colorEnum = client.getEnum(EnumID.XPDROP_COLORS); + int defaultColorId = client.getVar(Varbits.EXPERIENCE_DROP_COLOR); + int color = colorEnum.getIntValue(defaultColorId); + widget.setTextColor(color); + } } private void hideSkillIcons(Widget xpdrop) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index f565652b11..e939470613 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -83,6 +83,7 @@ public class GroundItemsOverlay extends Overlay private static final int KRIL_TSUTSAROTH_REGION = 11603; private static final int KREEARRA_REGION = 11346; private static final int NIGHTMARE_REGION = 15515; + private static final int TEMPOROSS_REGION = 12078; private final Client client; private final GroundItemsPlugin plugin; @@ -452,9 +453,10 @@ public class GroundItemsOverlay extends Overlay } } else if (playerRegionID == ZILYANA_REGION || playerRegionID == GRAARDOR_REGION || - playerRegionID == KRIL_TSUTSAROTH_REGION || playerRegionID == KREEARRA_REGION || playerRegionID == NIGHTMARE_REGION) + playerRegionID == KRIL_TSUTSAROTH_REGION || playerRegionID == KREEARRA_REGION || + playerRegionID == NIGHTMARE_REGION || playerRegionID == TEMPOROSS_REGION) { - // GWD and Nightmare instances use the normal despawn timers + // GWD, Nightmare, and Tempoross instances use the normal despawn timers despawnTime = spawnTime.plus(groundItem.getLootType() == LootType.DROPPED ? DESPAWN_TIME_DROP : DESPAWN_TIME_LOOT); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java index 7a6538e22d..c577f72f35 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java @@ -41,7 +41,7 @@ public interface GroundMarkerConfig extends Config @Alpha @ConfigItem( keyName = "markerColor", - name = "Color of the tile", + name = "Tile color", description = "Configures the color of marked tile" ) default Color markerColor() @@ -88,4 +88,14 @@ public interface GroundMarkerConfig extends Config { return false; } + + @ConfigItem( + keyName = "borderWidth", + name = "Border Width", + description = "Width of the marked tile border" + ) + default double borderWidth() + { + return 2; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java index 31d3e1bf08..266e89c9b5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java @@ -26,10 +26,12 @@ package net.runelite.client.plugins.groundmarkers; import com.google.common.base.Strings; +import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Polygon; +import java.awt.Stroke; import java.util.Collection; import javax.annotation.Nullable; import javax.inject.Inject; @@ -67,6 +69,12 @@ public class GroundMarkerOverlay extends Overlay public Dimension render(Graphics2D graphics) { final Collection points = plugin.getPoints(); + if (points.isEmpty()) + { + return null; + } + + Stroke stroke = new BasicStroke((float) config.borderWidth()); for (final ColorTileMarker point : points) { WorldPoint worldPoint = point.getWorldPoint(); @@ -82,13 +90,13 @@ public class GroundMarkerOverlay extends Overlay tileColor = config.markerColor(); } - drawTile(graphics, worldPoint, tileColor, point.getLabel()); + drawTile(graphics, worldPoint, tileColor, point.getLabel(), stroke); } return null; } - private void drawTile(Graphics2D graphics, WorldPoint point, Color color, @Nullable String label) + private void drawTile(Graphics2D graphics, WorldPoint point, Color color, @Nullable String label, Stroke borderStroke) { WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); @@ -106,7 +114,7 @@ public class GroundMarkerOverlay extends Overlay Polygon poly = Perspective.getCanvasTilePoly(client, lp); if (poly != null) { - OverlayUtil.renderPolygon(graphics, poly, color); + OverlayUtil.renderPolygon(graphics, poly, color, borderStroke); } if (!Strings.isNullOrEmpty(label)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java index 056ed509f2..ff4be28f8a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java @@ -202,7 +202,7 @@ class GroundMarkerSharingManager chatboxPanelManager.openTextMenuInput("Are you sure you want to import " + importPoints.size() + " ground markers?") .option("Yes", () -> importGroundMarkers(importPoints)) - .option("No", Runnables::doNothing) + .option("No", Runnables.doNothing()) .build(); } @@ -275,7 +275,7 @@ class GroundMarkerSharingManager + (numActivePoints == 1 ? " was cleared." : "s were cleared.")); }) - .option("No", Runnables::doNothing) + .option("No", Runnables.doNothing()) .build(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java index a310a15aaf..7f1f65606e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java @@ -158,13 +158,15 @@ public class HiscorePlugin extends Plugin return; } - int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); + final int componentId = event.getActionParam1(); + int groupId = WidgetInfo.TO_GROUP(componentId); String option = event.getOption(); if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() || groupId == WidgetInfo.FRIENDS_CHAT.getGroupId() || groupId == WidgetInfo.CHATBOX.getGroupId() && !KICK_OPTION.equals(option) || //prevent from adding for Kick option (interferes with the raiding party one) groupId == WidgetInfo.RAIDING_PARTY.getGroupId() || groupId == WidgetInfo.PRIVATE_CHAT_MESSAGE.getGroupId() || - groupId == WidgetInfo.IGNORE_LIST.getGroupId()) + groupId == WidgetInfo.IGNORE_LIST.getGroupId() || componentId == WidgetInfo.CLAN_MEMBER_LIST.getId() || + componentId == WidgetInfo.CLAN_GUEST_MEMBER_LIST.getId()) { if (!AFTER_OPTIONS.contains(option) || (option.equals("Delete") && groupId != WidgetInfo.IGNORE_LIST.getGroupId())) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java index 45551025b7..7af1dc77ca 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java @@ -24,6 +24,8 @@ */ package net.runelite.client.plugins.inventorygrid; +import java.awt.Color; +import net.runelite.client.config.Alpha; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -35,7 +37,8 @@ public interface InventoryGridConfig extends Config @ConfigItem( keyName = "showItem", name = "Show item", - description = "Show a preview of the item in the new slot" + description = "Show a preview of the item in the new slot", + position = 6 ) default boolean showItem() { @@ -45,7 +48,8 @@ public interface InventoryGridConfig extends Config @ConfigItem( keyName = "showGrid", name = "Show grid", - description = "Show a grid on the inventory while dragging" + description = "Show a grid on the inventory while dragging", + position = 3 ) default boolean showGrid() { @@ -55,7 +59,8 @@ public interface InventoryGridConfig extends Config @ConfigItem( keyName = "showHighlight", name = "Highlight background", - description = "Show a green background highlight on the new slot" + description = "Show a background highlight on the new slot", + position = 2 ) default boolean showHighlight() { @@ -65,11 +70,36 @@ public interface InventoryGridConfig extends Config @ConfigItem( keyName = "dragDelay", name = "Drag delay", - description = "Time to wait after an item press before the overlay is enabled" + description = "Time to wait after an item press before the overlay is enabled", + position = 1 ) @Units(Units.MILLISECONDS) default int dragDelay() { return 0; } + + @Alpha + @ConfigItem( + keyName = "gridColor", + name = "Grid color", + description = "The color of the grid", + position = 4 + ) + default Color gridColor() + { + return new Color(255, 255, 255, 45); + } + + @Alpha + @ConfigItem( + keyName = "highlightColor", + name = "Highlight color", + description = "The color of the new inventory slot highlight", + position = 5 + ) + default Color highlightColor() + { + return new Color(0, 255, 0, 45); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java index 3d606d8d6a..b54d157898 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.inventorygrid; import com.google.inject.Inject; import java.awt.AlphaComposite; -import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; @@ -48,9 +47,6 @@ class InventoryGridOverlay extends Overlay private static final int INVENTORY_SIZE = 28; private static final int DISTANCE_TO_ACTIVATE_HOVER = 5; - private static final Color HIGHLIGHT = new Color(0, 255, 0, 45); - private static final Color GRID = new Color(255, 255, 255, 45); - private final InventoryGridConfig config; private final Client client; private final ItemManager itemManager; @@ -126,12 +122,12 @@ class InventoryGridOverlay extends Overlay if (config.showHighlight() && inBounds) { - graphics.setColor(HIGHLIGHT); + graphics.setColor(config.highlightColor()); graphics.fill(bounds); } else if (config.showGrid()) { - graphics.setColor(GRID); + graphics.setColor(config.gridColor()); graphics.fill(bounds); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java index 7c96f47246..8901ffaab9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java @@ -335,6 +335,7 @@ enum ItemIdentification ANNAKARL_TELEPORT(Type.TABLET, "Annak", "GDZ", ItemID.ANNAKARL_TELEPORT), CARRALLANGAR_TELEPORT(Type.TABLET, "Carra", "CAR", ItemID.CARRALLANGAR_TELEPORT), DAREEYAK_TELEPORT(Type.TABLET, "Dareey", "DAR", ItemID.DAREEYAK_TELEPORT), + GHORROCK_TELEPORT(Type.TABLET, "Ghorr", "GHRK", ItemID.GHORROCK_TELEPORT), KHARYRLL_TELEPORT(Type.TABLET, "Khary", "KHRL", ItemID.KHARYRLL_TELEPORT), LASSAR_TELEPORT(Type.TABLET, "Lass", "LSR", ItemID.LASSAR_TELEPORT), PADDEWWA_TELEPORT(Type.TABLET, "Paddew", "PDW", ItemID.PADDEWWA_TELEPORT), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java index ac7be8d848..e8aa2b4de9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java @@ -36,6 +36,7 @@ import net.runelite.client.plugins.itemstats.food.Anglerfish; import net.runelite.client.plugins.itemstats.potions.GauntletPotion; import net.runelite.client.plugins.itemstats.potions.PrayerPotion; import net.runelite.client.plugins.itemstats.potions.SaradominBrew; +import net.runelite.client.plugins.itemstats.potions.StaminaPotion; import net.runelite.client.plugins.itemstats.potions.SuperRestore; import net.runelite.client.plugins.itemstats.special.CastleWarsBandage; import net.runelite.client.plugins.itemstats.special.SpicyStew; @@ -160,7 +161,7 @@ public class ItemStatChanges add(new SuperRestore(.25, 8), SUPER_RESTORE1, SUPER_RESTORE2, SUPER_RESTORE3, SUPER_RESTORE4, BLIGHTED_SUPER_RESTORE1, BLIGHTED_SUPER_RESTORE2, BLIGHTED_SUPER_RESTORE3, BLIGHTED_SUPER_RESTORE4); add(new SuperRestore(.30, 4), SANFEW_SERUM1, SANFEW_SERUM2, SANFEW_SERUM3, SANFEW_SERUM4); - add(heal(RUN_ENERGY, 20), STAMINA_POTION1, STAMINA_POTION2, STAMINA_POTION3, STAMINA_POTION4); + add(new StaminaPotion(), STAMINA_POTION1, STAMINA_POTION2, STAMINA_POTION3, STAMINA_POTION4); // Raids potions (+) add(combo(5, boost(ATTACK, perc(.16, 6)), boost(STRENGTH, perc(.16, 6)), boost(DEFENCE, perc(.16, 6)), boost(RANGED, perc(.16, 6)), boost(MAGIC, perc(.16, 6)), heal(HITPOINTS, -50)), OVERLOAD_1_20993, OVERLOAD_2_20994, OVERLOAD_3_20995, OVERLOAD_4_20996); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/StaminaPotion.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/StaminaPotion.java new file mode 100644 index 0000000000..214bb30fcd --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/StaminaPotion.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016-2018, Adam + * Copyright (c) 2021, Tanlines + * 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. + */ +<<<<<<< HEAD:deobfuscator/src/main/java/net/runelite/deob/deobfuscators/lvt/MapKey.java +package net.runelite.deob.deobfuscators.lvt; + +import java.util.Objects; + +public class MapKey +{ + private final int idx; + private final LVTType type; + + public MapKey(int idx, LVTType type) + { + this.idx = idx; + this.type = type; + } + + @Override + public int hashCode() + { + int hash = 7; + hash = 89 * hash + this.idx; + hash = 89 * hash + Objects.hashCode(this.type); + return hash; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final MapKey other = (MapKey) obj; + if (this.idx != other.idx) + { + return false; + } + if (this.type != other.type) + { + return false; + } + return true; +======= +package net.runelite.client.plugins.itemstats.potions; + +import net.runelite.api.Client; +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.api.ItemID; +import net.runelite.client.plugins.itemstats.StatBoost; +import static net.runelite.client.plugins.itemstats.stats.Stats.RUN_ENERGY; + +public class StaminaPotion extends StatBoost +{ + public StaminaPotion() + { + super(RUN_ENERGY, false); + } + + @Override + public int heals(Client client) + { + ItemContainer equipContainer = client.getItemContainer(InventoryID.EQUIPMENT); + if (equipContainer != null) + { + Item ring = equipContainer.getItem(EquipmentInventorySlot.RING.getSlotIdx()); + if (ring != null && ring.getId() == ItemID.RING_OF_ENDURANCE) + { + return 40; + } + } + return 20; +>>>>>>> upstream/master:runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/StaminaPotion.java + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java index cb4802cdaf..a3d500dc49 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java @@ -554,6 +554,18 @@ class LootTrackerPanel extends PluginPanel final JMenuItem reset = new JMenuItem("Reset"); reset.addActionListener(e -> { + final LootTrackerClient client = plugin.getLootTrackerClient(); + final boolean syncLoot = client.getUuid() != null && config.syncPanel(); + final int result = JOptionPane.showOptionDialog(overallPanel, + syncLoot ? SYNC_RESET_ALL_WARNING_TEXT : NO_SYNC_RESET_ALL_WARNING_TEXT, + "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, new String[]{"Yes", "No"}, "No"); + + if (result != JOptionPane.YES_OPTION) + { + return; + } + Predicate match = groupLoot // With grouped loot, remove any record with this title ? r -> r.matches(record.getTitle(), record.getType()) @@ -566,7 +578,6 @@ class LootTrackerPanel extends PluginPanel logsContainer.remove(box); logsContainer.repaint(); - LootTrackerClient client = plugin.getLootTrackerClient(); // Without loot being grouped we have no way to identify single kills to be deleted if (client.getUuid() != null && groupLoot && config.syncPanel()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java index 6ca04ce159..1604c1575e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java @@ -237,6 +237,8 @@ public class LootTrackerPlugin extends Plugin private static final String CASKET_EVENT = "Casket"; + private static final String WINTERTODT_SUPPLY_CRATE_EVENT = "Supply crate (Wintertodt)"; + // Soul Wars private static final String SPOILS_OF_WAR_EVENT = "Spoils of war"; private static final Set SOUL_WARS_REGIONS = ImmutableSet.of(8493, 8749, 9005); @@ -786,6 +788,7 @@ public class LootTrackerPlugin extends Plugin || HALLOWED_SEPULCHRE_COFFIN_EVENT.equals(eventType) || HERBIBOAR_EVENT.equals(eventType) || HESPORI_EVENT.equals(eventType) + || WINTERTODT_SUPPLY_CRATE_EVENT.equals(eventType) || eventType.endsWith("Bird House") || eventType.startsWith("H.A.M. chest") || lootRecordType == LootRecordType.PICKPOCKET) @@ -843,6 +846,12 @@ public class LootTrackerPlugin extends Plugin takeInventorySnapshot(); } + if (event.getMenuOption().equals("Open") && (event.getId() == ItemID.SUPPLY_CRATE || event.getId() == ItemID.EXTRA_SUPPLY_CRATE)) + { + setEvent(LootRecordType.EVENT, WINTERTODT_SUPPLY_CRATE_EVENT); + takeInventorySnapshot(); + } + if (event.getMenuOption().equals("Open") && event.getId() == ItemID.SPOILS_OF_WAR) { setEvent(LootRecordType.EVENT, SPOILS_OF_WAR_EVENT); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index a68231eeb5..ef9936d396 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -66,6 +66,46 @@ public interface MenuEntrySwapperConfig extends Config ) String uiSection = "ui"; + enum ArdougneCloakMode + { + WEAR, + MONASTERY, + FARM, + } + + enum KaramjaGlovesMode + { + WEAR, + GEM_MINE, + DURADEL, + } + + enum MorytaniaLegsMode + { + WEAR, + ECTOFUNTUS, + BURGH_DE_ROTT; + + @Override + public String toString() + { + switch (this) + { + case BURGH_DE_ROTT: + return "Burgh de Rott"; + default: + return name(); + } + } + } + + enum RadasBlessingMode + { + EQUIP, + KOUREND_WOODLAND, + MOUNT_KARUULM, + } + @ConfigItem( position = -2, keyName = "shiftClickCustomization", @@ -430,6 +470,50 @@ public interface MenuEntrySwapperConfig extends Config return false; } + @ConfigItem( + keyName = "swapKaramjaGloves", + name = "Karamja Gloves", + description = "Swap Wear with the Gem Mine or Duradel teleport on the Karamja Gloves 3 and 4", + section = itemSection + ) + default KaramjaGlovesMode swapKaramjaGlovesMode() + { + return KaramjaGlovesMode.WEAR; + } + + @ConfigItem( + keyName = "swapArdougneCloak", + name = "Ardougne Cloak", + description = "Swap Wear with Monastery Teleport or Farm Teleport on the Ardougne cloak.", + section = itemSection + ) + default ArdougneCloakMode swapArdougneCloakMode() + { + return ArdougneCloakMode.WEAR; + } + + @ConfigItem( + keyName = "swapRadasBlessing", + name = "Rada's Blessing", + description = "Swap Equip with the Woodland or Mount Karuulm teleport on Rada's Blessing.", + section = itemSection + ) + default RadasBlessingMode swapRadasBlessingMode() + { + return RadasBlessingMode.EQUIP; + } + + @ConfigItem( + keyName = "swapMorytaniaLegs", + name = "Morytania Legs", + description = "Swap Wear with the Ectofunctus or Burgh de Rott teleport on the Morytania Legs.", + section = itemSection + ) + default MorytaniaLegsMode swapMorytaniaLegsMode() + { + return MorytaniaLegsMode.WEAR; + } + @ConfigItem( keyName = "swapAbyssTeleport", name = "Teleport to Abyss", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index 6345148989..4c02ace6c4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -69,6 +69,10 @@ import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.ArdougneCloakMode; +import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.KaramjaGlovesMode; +import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.MorytaniaLegsMode; +import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.RadasBlessingMode; import net.runelite.client.util.Text; import org.apache.commons.lang3.ArrayUtils; @@ -355,6 +359,18 @@ public class MenuEntrySwapperPlugin extends Plugin swap("wield", "teleport", config::swapTeleportItem); swap("wield", "invoke", config::swapTeleportItem); + swap("wear", "farm teleport", () -> config.swapArdougneCloakMode() == ArdougneCloakMode.FARM); + swap("wear", "monastery teleport", () -> config.swapArdougneCloakMode() == ArdougneCloakMode.MONASTERY); + + swap("wear", "gem mine", () -> config.swapKaramjaGlovesMode() == KaramjaGlovesMode.GEM_MINE); + swap("wear", "duradel", () -> config.swapKaramjaGlovesMode() == KaramjaGlovesMode.DURADEL); + + swap("equip", "kourend woodland", () -> config.swapRadasBlessingMode() == RadasBlessingMode.KOUREND_WOODLAND); + swap("equip", "mount karuulm", () -> config.swapRadasBlessingMode() == RadasBlessingMode.MOUNT_KARUULM); + + swap("wear", "ecto teleport", () -> config.swapMorytaniaLegsMode() == MorytaniaLegsMode.ECTOFUNTUS); + swap("wear", "burgh teleport", () -> config.swapMorytaniaLegsMode() == MorytaniaLegsMode.BURGH_DE_ROTT); + swap("bury", "use", config::swapBones); swap("wield", "battlestaff", "use", config::swapBattlestaves); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsConfig.java index 26e93c6196..6c86a373d0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsConfig.java @@ -109,6 +109,17 @@ public interface NpcIndicatorsConfig extends Config @ConfigItem( position = 5, + keyName = "borderWidth", + name = "Border Width", + description = "Width of the highlighted NPC border" + ) + default double borderWidth() + { + return 2; + } + + @ConfigItem( + position = 6, keyName = "drawNames", name = "Draw names above NPC", description = "Configures whether or not NPC names should be drawn above the NPC" @@ -119,7 +130,7 @@ public interface NpcIndicatorsConfig extends Config } @ConfigItem( - position = 6, + position = 7, keyName = "drawMinimapNames", name = "Draw names on minimap", description = "Configures whether or not NPC names should be drawn on the minimap" @@ -130,7 +141,7 @@ public interface NpcIndicatorsConfig extends Config } @ConfigItem( - position = 7, + position = 8, keyName = "highlightMenuNames", name = "Highlight menu names", description = "Highlight NPC names in right click menu" @@ -141,7 +152,7 @@ public interface NpcIndicatorsConfig extends Config } @ConfigItem( - position = 8, + position = 9, keyName = "ignoreDeadNpcs", name = "Ignore dead NPCs", description = "Prevents highlighting NPCs after they are dead" @@ -152,7 +163,7 @@ public interface NpcIndicatorsConfig extends Config } @ConfigItem( - position = 9, + position = 10, keyName = "deadNpcMenuColor", name = "Dead NPC menu color", description = "Color of the NPC menus for dead NPCs" @@ -160,7 +171,7 @@ public interface NpcIndicatorsConfig extends Config Color deadNpcMenuColor(); @ConfigItem( - position = 10, + position = 11, keyName = "showRespawnTimer", name = "Show respawn timer", description = "Show respawn timer of tagged NPCs") diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java index 441d811a97..d07f53c2bf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java @@ -48,6 +48,7 @@ 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.util.ColorUtil; import net.runelite.client.util.Text; public class NpcSceneOverlay extends Overlay @@ -197,9 +198,9 @@ public class NpcSceneOverlay extends Overlay if (polygon != null) { graphics.setColor(color); - graphics.setStroke(new BasicStroke(2)); + graphics.setStroke(new BasicStroke((float) config.borderWidth())); graphics.draw(polygon); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 20)); + graphics.setColor(ColorUtil.colorWithAlpha(color, 20)); graphics.fill(polygon); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsConfig.java index 049269756b..eacde6f23f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsConfig.java @@ -54,4 +54,14 @@ public interface ObjectIndicatorsConfig extends Config { return false; } + + @ConfigItem( + keyName = "borderWidth", + name = "Border Width", + description = "Width of the marked object border" + ) + default double borderWidth() + { + return 2; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsOverlay.java index 980e9317d9..a174e92335 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsOverlay.java @@ -24,10 +24,12 @@ */ package net.runelite.client.plugins.objectindicators; +import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Shape; +import java.awt.Stroke; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.DecorativeObject; @@ -62,6 +64,7 @@ class ObjectIndicatorsOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { + Stroke stroke = new BasicStroke((float) config.borderWidth()); for (ColorTileObject colorTileObject : plugin.getObjects()) { TileObject object = colorTileObject.getTileObject(); @@ -118,12 +121,12 @@ class ObjectIndicatorsOverlay extends Overlay if (polygon != null) { - OverlayUtil.renderPolygon(graphics, polygon, color); + OverlayUtil.renderPolygon(graphics, polygon, color, stroke); } if (polygon2 != null) { - OverlayUtil.renderPolygon(graphics, polygon2, color); + OverlayUtil.renderPolygon(graphics, polygon2, color, stroke); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohIcons.java b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohIcons.java index bfc5fa2157..de6d2e7862 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohIcons.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohIcons.java @@ -70,12 +70,15 @@ public enum PohIcons ALTAR_13187, ALTAR_13188, ALTAR_13189, ALTAR_13190, ALTAR_13191, ALTAR_13192, ALTAR_13193, ALTAR_13194, ALTAR_13196, ALTAR_13197, ALTAR_13198, ALTAR_13199 ), - POOLS("pool", POOL_OF_RESTORATION, POOL_OF_REVITALISATION, POOL_OF_REJUVENATION, FANCY_POOL_OF_REJUVENATION, ORNATE_POOL_OF_REJUVENATION), + POOLS("pool", + POOL_OF_RESTORATION, POOL_OF_REVITALISATION, POOL_OF_REJUVENATION, FANCY_POOL_OF_REJUVENATION, ORNATE_POOL_OF_REJUVENATION, + FROZEN_POOL_OF_RESTORATION, FROZEN_POOL_OF_REVITALISATION, FROZEN_POOL_OF_REJUVENATION, FROZEN_FANCY_POOL_OF_REJUVENATION, FROZEN_ORNATE_POOL_OF_REJUVENATION + ), GLORY("glory", AMULET_OF_GLORY), REPAIR("repair", ARMOUR_REPAIR_STAND), SPELLBOOKALTAR("spellbook", ANCIENT_ALTAR, LUNAR_ALTAR, DARK_ALTAR, NULL_29150), JEWELLERYBOX("jewellery", NULL_29154, NULL_29155, NULL_29156), - MAGICTRAVEL("transportation", SPIRIT_TREE_29227, NULL_29228, NULL_29229, OBELISK_31554), + MAGICTRAVEL("transportation", SPIRIT_TREE_29227, NULL_29228, NULL_29229, OBELISK_31554, CHRISTMASSPIRIT_TREE, NULL_40779), PORTALNEXUS("portalnexus", PORTAL_NEXUS, PORTAL_NEXUS_33355, PORTAL_NEXUS_33356, PORTAL_NEXUS_33357, PORTAL_NEXUS_33358, PORTAL_NEXUS_33359, PORTAL_NEXUS_33360, PORTAL_NEXUS_33361, PORTAL_NEXUS_33362, PORTAL_NEXUS_33363, PORTAL_NEXUS_33364, PORTAL_NEXUS_33365, PORTAL_NEXUS_33366, PORTAL_NEXUS_33367, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index 28449b69ca..f7c8c9e440 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -118,17 +118,34 @@ public class ScreenshotPlugin extends Plugin WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID); + private static final String SD_KINGDOM_REWARDS = "Kingdom Rewards"; + private static final String SD_BOSS_KILLS = "Boss Kills"; + private static final String SD_CLUE_SCROLL_REWARDS = "Clue Scroll Rewards"; + private static final String SD_FRIENDS_CHAT_KICKS = "Friends Chat Kicks"; + private static final String SD_PETS = "Pets"; + private static final String SD_CHEST_LOOT = "Chest Loot"; + private static final String SD_VALUABLE_DROPS = "Valuable Drops"; + private static final String SD_UNTRADEABLE_DROPS = "Untradeable Drops"; + private static final String SD_DUELS = "Duels"; + private static final String SD_COLLECTION_LOG = "Collection Log"; + private static final String SD_PVP_KILLS = "PvP Kills"; + private static final String SD_DEATHS = "Deaths"; private String clueType; private Integer clueNumber; - private Integer barrowsNumber; + enum KillType + { + BARROWS, + COX, + COX_CM, + TOB, + TOB_SM, + TOB_HM + } - private Integer chambersOfXericNumber; - - private Integer chambersOfXericChallengeNumber; - - private Integer theatreOfBloodNumber; + private KillType killType; + private Integer killCountNumber; private boolean shouldTakeScreenshot; @@ -283,11 +300,11 @@ public class ScreenshotPlugin extends Plugin Player player = (Player) actor; if (player == client.getLocalPlayer() && config.screenshotPlayerDeath()) { - takeScreenshot("Death", "Deaths"); + takeScreenshot("Death", SD_DEATHS); } else if (player != client.getLocalPlayer() && (player.isFriendsChatMember() || player.isFriend()) && config.screenshotFriendDeath() && player.getCanvasTilePoly() != null) { - takeScreenshot("Death " + player.getName(), "Deaths"); + takeScreenshot("Death " + player.getName(), SD_DEATHS); } } } @@ -300,7 +317,7 @@ public class ScreenshotPlugin extends Plugin final Player player = playerLootReceived.getPlayer(); final String name = player.getName(); String fileName = "Kill " + name; - takeScreenshot(fileName, "PvP Kills"); + takeScreenshot(fileName, SD_PVP_KILLS); } } @@ -346,7 +363,8 @@ public class ScreenshotPlugin extends Plugin Matcher m = NUMBER_PATTERN.matcher(Text.removeTags(chatMessage)); if (m.find()) { - barrowsNumber = Integer.valueOf(m.group()); + killType = KillType.BARROWS; + killCountNumber = Integer.valueOf(m.group()); return; } } @@ -356,7 +374,8 @@ public class ScreenshotPlugin extends Plugin Matcher m = NUMBER_PATTERN.matcher(Text.removeTags(chatMessage)); if (m.find()) { - chambersOfXericNumber = Integer.valueOf(m.group()); + killType = KillType.COX; + killCountNumber = Integer.valueOf(m.group()); return; } } @@ -366,17 +385,19 @@ public class ScreenshotPlugin extends Plugin Matcher m = NUMBER_PATTERN.matcher(Text.removeTags(chatMessage)); if (m.find()) { - chambersOfXericChallengeNumber = Integer.valueOf(m.group()); + killType = KillType.COX_CM; + killCountNumber = Integer.valueOf(m.group()); return; } } - if (chatMessage.startsWith("Your completed Theatre of Blood count is:")) + if (chatMessage.startsWith("Your completed Theatre of Blood")) { Matcher m = NUMBER_PATTERN.matcher(Text.removeTags(chatMessage)); if (m.find()) { - theatreOfBloodNumber = Integer.valueOf(m.group()); + killType = chatMessage.contains("Hard Mode") ? KillType.TOB_HM : (chatMessage.contains("Story Mode") ? KillType.TOB_SM : KillType.TOB); + killCountNumber = Integer.valueOf(m.group()); return; } } @@ -388,14 +409,14 @@ public class ScreenshotPlugin extends Plugin return; } - takeScreenshot("Kick " + kickPlayerName, "Friends Chat Kicks"); + takeScreenshot("Kick " + kickPlayerName, SD_FRIENDS_CHAT_KICKS); kickPlayerName = null; } if (config.screenshotPet() && PET_MESSAGES.stream().anyMatch(chatMessage::contains)) { String fileName = "Pet"; - takeScreenshot(fileName, "Pets"); + takeScreenshot(fileName, SD_PETS); } if (config.screenshotBossKills()) @@ -406,7 +427,7 @@ public class ScreenshotPlugin extends Plugin String bossName = m.group(1); String bossKillcount = m.group(2); String fileName = bossName + "(" + bossKillcount + ")"; - takeScreenshot(fileName, "Boss Kills"); + takeScreenshot(fileName, SD_BOSS_KILLS); } } @@ -416,7 +437,7 @@ public class ScreenshotPlugin extends Plugin String eventName = CHEST_LOOT_EVENTS.get(regionID); if (eventName != null) { - takeScreenshot(eventName, "Chest Loot"); + takeScreenshot(eventName, SD_CHEST_LOOT); } } @@ -430,7 +451,7 @@ public class ScreenshotPlugin extends Plugin { String valuableDropName = m.group(1); String fileName = "Valuable drop " + valuableDropName; - takeScreenshot(fileName, "Valuable Drops"); + takeScreenshot(fileName, SD_VALUABLE_DROPS); } } } @@ -442,7 +463,7 @@ public class ScreenshotPlugin extends Plugin { String untradeableDropName = m.group(1); String fileName = "Untradeable drop " + untradeableDropName; - takeScreenshot(fileName, "Untradeable Drops"); + takeScreenshot(fileName, SD_UNTRADEABLE_DROPS); } } @@ -454,7 +475,7 @@ public class ScreenshotPlugin extends Plugin String result = m.group(1); String count = m.group(2); String fileName = "Duel " + result + " (" + count + ")"; - takeScreenshot(fileName, "Duels"); + takeScreenshot(fileName, SD_DUELS); } } @@ -462,7 +483,7 @@ public class ScreenshotPlugin extends Plugin { String entry = Text.removeTags(chatMessage).substring(COLLECTION_LOG_TEXT.length()); String fileName = "Collection log (" + entry + ")"; - takeScreenshot(fileName, "Collection Log"); + takeScreenshot(fileName, SD_COLLECTION_LOG); } } @@ -510,52 +531,67 @@ public class ScreenshotPlugin extends Plugin case KINGDOM_GROUP_ID: { fileName = "Kingdom " + LocalDate.now(); - screenshotSubDir = "Kingdom Rewards"; + screenshotSubDir = SD_KINGDOM_REWARDS; break; } case CHAMBERS_OF_XERIC_REWARD_GROUP_ID: { - if (chambersOfXericNumber != null) + if (killType == KillType.COX) { - fileName = "Chambers of Xeric(" + chambersOfXericNumber + ")"; - screenshotSubDir = "Boss Kills"; - chambersOfXericNumber = null; + fileName = "Chambers of Xeric(" + killCountNumber + ")"; + screenshotSubDir = SD_BOSS_KILLS; + killType = null; + killCountNumber = 0; break; } - else if (chambersOfXericChallengeNumber != null) + else if (killType == KillType.COX_CM) { - fileName = "Chambers of Xeric Challenge Mode(" + chambersOfXericChallengeNumber + ")"; - screenshotSubDir = "Boss Kills"; - chambersOfXericChallengeNumber = null; + fileName = "Chambers of Xeric Challenge Mode(" + killCountNumber + ")"; + screenshotSubDir = SD_BOSS_KILLS; + killType = null; + killCountNumber = 0; break; } - else - { - return; - } + return; } case THEATRE_OF_BLOOD_REWARD_GROUP_ID: { - if (theatreOfBloodNumber == null) + if (killType != KillType.TOB && killType != KillType.TOB_SM && killType != KillType.TOB_HM) { return; } - fileName = "Theatre of Blood(" + theatreOfBloodNumber + ")"; - screenshotSubDir = "Boss Kills"; - theatreOfBloodNumber = null; + switch (killType) + { + case TOB: + fileName = "Theatre of Blood(" + killCountNumber + ")"; + break; + case TOB_SM: + fileName = "Theatre of Blood Story Mode(" + killCountNumber + ")"; + break; + case TOB_HM: + fileName = "Theatre of Blood Hard Mode(" + killCountNumber + ")"; + break; + default: + throw new IllegalStateException(); + } + + screenshotSubDir = SD_BOSS_KILLS; + killType = null; + killCountNumber = 0; break; } case BARROWS_REWARD_GROUP_ID: { - if (barrowsNumber == null) + if (killType != KillType.BARROWS) { return; } - fileName = "Barrows(" + barrowsNumber + ")"; - screenshotSubDir = "Boss Kills"; - barrowsNumber = null; + fileName = "Barrows(" + killCountNumber + ")"; + screenshotSubDir = SD_BOSS_KILLS; + killType = null; + killCountNumber = 0; break; } case LEVEL_UP_GROUP_ID: @@ -574,7 +610,7 @@ public class ScreenshotPlugin extends Plugin } fileName = Character.toUpperCase(clueType.charAt(0)) + clueType.substring(1) + "(" + clueNumber + ")"; - screenshotSubDir = "Clue Scroll Rewards"; + screenshotSubDir = SD_CLUE_SCROLL_REWARDS; clueType = null; clueNumber = null; break; @@ -769,26 +805,14 @@ public class ScreenshotPlugin extends Plugin } @VisibleForTesting - int getBarrowsNumber() + KillType getKillType() { - return barrowsNumber; + return killType; } @VisibleForTesting - int getChambersOfXericNumber() + int getKillCountNumber() { - return chambersOfXericNumber; - } - - @VisibleForTesting - int getChambersOfXericChallengeNumber() - { - return chambersOfXericChallengeNumber; - } - - @VisibleForTesting - int gettheatreOfBloodNumber() - { - return theatreOfBloodNumber; + return killCountNumber; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java index 655c3745ba..6c612efff9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java @@ -43,7 +43,9 @@ import net.runelite.api.ItemContainer; import net.runelite.api.NPC; import net.runelite.api.NpcID; import net.runelite.api.VarPlayer; +import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; import net.runelite.api.events.HitsplatApplied; import net.runelite.api.events.InteractingChanged; import net.runelite.api.events.NpcDespawned; @@ -72,12 +74,20 @@ public class SpecialCounterPlugin extends Plugin NpcID.DARK_ENERGY_CORE, NpcID.ZOMBIFIED_SPAWN, NpcID.ZOMBIFIED_SPAWN_8063, NpcID.COMBAT_DUMMY, NpcID.UNDEAD_COMBAT_DUMMY ); + + private static final Set RESET_ON_LEAVE_INSTANCED_REGIONS = ImmutableSet.of( + 9023, // vorkath + 5536 // hydra + ); private int currentWorld; private int specialPercentage; private Actor lastSpecTarget; private int lastSpecTick; + private int previousRegion; + private boolean wasInInstance; + private SpecialWeapon specialWeapon; private final Set interactedNpcIds = new HashSet<>(); private final SpecialCounter[] specialCounter = new SpecialCounter[SpecialWeapon.values().length]; @@ -129,6 +139,31 @@ public class SpecialCounterPlugin extends Plugin removeCounters(); wsClient.unregisterMessage(SpecialCounterUpdate.class); } + + @Subscribe + public void onGameTick(GameTick event) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + assert client.getLocalPlayer() != null; + int currentRegion = WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()).getRegionID(); + boolean inInstance = client.isInInstancedRegion(); + + // if the player left the region/instance and was fighting boss that resets, reset specs + if (currentRegion != previousRegion || (wasInInstance && !inInstance)) + { + if (RESET_ON_LEAVE_INSTANCED_REGIONS.contains(previousRegion)) + { + removeCounters(); + } + } + + previousRegion = currentRegion; + wasInInstance = inInstance; + } @Subscribe public void onGameStateChanged(GameStateChanged event) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java index cc387c4872..a5b40c185f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java @@ -78,7 +78,8 @@ enum MinigameLocation MAHOGANY_HOMES_HOSIDIUS("Mahogany Homes", new WorldPoint(1780, 3623, 0)), MAHOGANY_HOMES_VARROCK("Mahogany Homes", new WorldPoint(3240, 3471, 0)), SOUL_WARS("Soul Wars", new WorldPoint(2209, 2855, 0)), - SOUL_WARS_EDGEVILLE_PORTAL("Soul Wars", new WorldPoint(3082, 3474, 0)); + SOUL_WARS_EDGEVILLE_PORTAL("Soul Wars", new WorldPoint(3082, 3474, 0)), + TZHAAR_KET_RAKS_CHALLENGES("TzHaar-Ket-Rak's Challenges", new WorldPoint(2544, 5111, 0)); private final String tooltip; private final WorldPoint location; diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java index 7a59965f68..1caa3a7c01 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java @@ -42,20 +42,21 @@ import net.runelite.api.TileObject; import net.runelite.api.coords.LocalPoint; import net.runelite.client.util.ColorUtil; - -/** - * Created by Kyle Fricilone on Jun 09, 2017. - */ public class OverlayUtil { private static final int MINIMAP_DOT_RADIUS = 4; private static final double UNIT = Math.PI / 1024.0d; public static void renderPolygon(Graphics2D graphics, Shape poly, Color color) + { + renderPolygon(graphics, poly, color, new BasicStroke(2)); + } + + public static void renderPolygon(Graphics2D graphics, Shape poly, Color color, Stroke borderStroke) { graphics.setColor(color); final Stroke originalStroke = graphics.getStroke(); - graphics.setStroke(new BasicStroke(2)); + graphics.setStroke(borderStroke); graphics.draw(poly); graphics.setColor(new Color(0, 0, 0, 50)); graphics.fill(poly); diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java index e842005dba..9cfd63174d 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java @@ -127,6 +127,10 @@ public class ImageCapture { playerDir += "-League"; } + else if (worldTypes.contains(WorldType.TOURNAMENT)) + { + playerDir += "-Tournament"; + } if (!Strings.isNullOrEmpty(subDir)) { diff --git a/runelite-client/src/main/scripts/ToplevelCompassOp.rs2asm b/runelite-client/src/main/scripts/ToplevelCompassOp.rs2asm index 630b1bfdbc..fca087a53e 100644 --- a/runelite-client/src/main/scripts/ToplevelCompassOp.rs2asm +++ b/runelite-client/src/main/scripts/ToplevelCompassOp.rs2asm @@ -47,11 +47,11 @@ LOOK: iconst 0 sound_synth iconst 225 - sconst "lookPreservePitch" - runelite_callback iconst 5 randominc add + sconst "lookPreservePitch" + runelite_callback iload 1 ; load target angle cam_forceangle return diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java index 788437d165..6d510e1516 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java @@ -157,56 +157,43 @@ public class ChatCommandsPluginTest @Test public void testTheatreOfBlood() { - ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: 5:04
Theatre of Blood wave completion time: 37:04 (new personal best)", null, 0); + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", + "Wave 'The Final Challenge' (Normal Mode) complete!
Duration: 2:42.0
Theatre of Blood wave completion time: 17:00.20 (new personal best)", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood count is: 73.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); verify(configManager).setRSProfileConfiguration("killcount", "theatre of blood", 73); - verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4.0); - - // Precise times - ChatMessage chatMessagePrecise = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: 5:04
Theatre of Blood wave completion time: 37:04.20 (new personal best)", null, 0); - chatCommandsPlugin.onChatMessage(chatMessagePrecise); - chatCommandsPlugin.onChatMessage(chatMessageEvent); - - verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4.2); + verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 17 * 60 + .2); } @Test public void testTheatreOfBloodNoPb() { - ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: 5:04
Theatre of Blood wave completion time: 38:17
Personal best: 37:04", null, 0); + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", + "Wave 'The Final Challenge' (Normal Mode) complete!
Duration: 2:42
Theatre of Blood wave completion time: 17:00. Personal best: 13:52.80", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood count is: 73.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); verify(configManager).setRSProfileConfiguration("killcount", "theatre of blood", 73); - verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4.0); - - // Precise times - ChatMessage chatMessagePrecise = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: 5:04
Theatre of Blood wave completion time: 38:17.00
Personal best: 37:04.40", null, 0); - chatCommandsPlugin.onChatMessage(chatMessagePrecise); - chatCommandsPlugin.onChatMessage(chatMessageEvent); - - verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4.4); + verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 13 * 60 + 52.8); } @Test public void testTheatreOfBloodStoryMode() { ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", - "Theatre of Blood wave completion time: 5:04 (new personal best)
" + - "Theatre of Blood total completion time: 24:39 (new personal best)", null, 0); + "Wave 'The Final Challenge' (Story Mode) complete!
Duration: 2:42
Theatre of Blood wave completion time: 17:00 (new personal best)", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood: Story Mode count is: 73.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); verify(configManager).setRSProfileConfiguration("killcount", "theatre of blood story mode", 73); - verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood story mode", 5 * 60 + 4.0); + verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood story mode", 17 * 60.); } @Test diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/examine/ExaminePluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/examine/ExaminePluginTest.java new file mode 100644 index 0000000000..31589046e0 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/examine/ExaminePluginTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.examine; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.ItemComposition; +import net.runelite.api.ItemID; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.game.ItemManager; +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ExaminePluginTest +{ + @Inject + ExaminePlugin examinePlugin; + + @Mock + @Bind + Client client; + + @Mock + @Bind + ChatMessageManager chatMessageManager; + + @Mock + @Bind + ItemManager itemManager; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testGetItemPrice() + { + ItemComposition itemComposition = mock(ItemComposition.class); + when(itemComposition.getName()).thenReturn("Abyssal whip"); + when(itemComposition.getHaPrice()).thenReturn(2); + when(itemManager.getItemPrice(ItemID.ABYSSAL_WHIP)).thenReturn(3); + examinePlugin.getItemPrice(ItemID.ABYSSAL_WHIP, itemComposition, 2_000_000_000); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(QueuedMessage.class); + verify(chatMessageManager).queue(argumentCaptor.capture()); + + QueuedMessage queuedMessage = argumentCaptor.getValue(); + assertEquals( + "Price of 2,000,000,000 x Abyssal whip: GE average 6,000,000,000 (3ea) HA value 4,000,000,000 (2ea)", + queuedMessage.getRuneLiteFormattedMessage() + ); + } +} \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java index edd5101817..2664c031e7 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java @@ -36,6 +36,7 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; import static net.runelite.api.widgets.WidgetID.DIALOG_SPRITE_GROUP_ID; import static net.runelite.api.widgets.WidgetID.LEVEL_UP_GROUP_ID; import static net.runelite.api.widgets.WidgetInfo.DIALOG_SPRITE_TEXT; @@ -68,6 +69,8 @@ public class ScreenshotPluginTest private static final String BARROWS_CHEST = "Your Barrows chest count is 310"; private static final String CHAMBERS_OF_XERIC_CHEST = "Your completed Chambers of Xeric count is: 489."; private static final String THEATRE_OF_BLOOD_CHEST = "Your completed Theatre of Blood count is: 73."; + private static final String THREATRE_OF_BLOOD_SM_CHEST = "Your completed Theatre of Blood: Story Mode count is: 73."; + private static final String THREATRE_OF_BLOOD_HM_CHEST = "Your completed Theatre of Blood: Hard Mode count is: 73."; private static final String NOT_SO_VALUABLE_DROP = "Valuable drop: 6 x Bronze arrow (42 coins)"; private static final String VALUABLE_DROP = "Valuable drop: Rune scimitar (25,600 coins)"; private static final String UNTRADEABLE_DROP = "Untradeable drop: Rusty sword"; @@ -143,7 +146,7 @@ public class ScreenshotPluginTest ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Seth", BARROWS_CHEST, null, 0); screenshotPlugin.onChatMessage(chatMessageEvent); - assertEquals(310, screenshotPlugin.getBarrowsNumber()); + assertEquals(310, screenshotPlugin.getKillCountNumber()); } @Test @@ -152,16 +155,61 @@ public class ScreenshotPluginTest ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Seth", CHAMBERS_OF_XERIC_CHEST, null, 0); screenshotPlugin.onChatMessage(chatMessageEvent); - assertEquals(489, screenshotPlugin.getChambersOfXericNumber()); + assertEquals(489, screenshotPlugin.getKillCountNumber()); } @Test public void testTheatreOfBloodChest() { + when(screenshotConfig.screenshotRewards()).thenReturn(true); + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Magic fTail", THEATRE_OF_BLOOD_CHEST, null, 0); screenshotPlugin.onChatMessage(chatMessageEvent); - assertEquals(73, screenshotPlugin.gettheatreOfBloodNumber()); + assertEquals(73, screenshotPlugin.getKillCountNumber()); + assertEquals(ScreenshotPlugin.KillType.TOB, screenshotPlugin.getKillType()); + + WidgetLoaded widgetLoaded = new WidgetLoaded(); + widgetLoaded.setGroupId(WidgetID.THEATRE_OF_BLOOD_REWARD_GROUP_ID); + screenshotPlugin.onWidgetLoaded(widgetLoaded); + + verify(drawManager).requestNextFrameListener(any(Consumer.class)); + } + + @Test + public void testTheatreOfBloodSmChest() + { + when(screenshotConfig.screenshotRewards()).thenReturn(true); + + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Magic fTail", THREATRE_OF_BLOOD_SM_CHEST, null, 0); + screenshotPlugin.onChatMessage(chatMessageEvent); + + assertEquals(73, screenshotPlugin.getKillCountNumber()); + assertEquals(ScreenshotPlugin.KillType.TOB_SM, screenshotPlugin.getKillType()); + + WidgetLoaded widgetLoaded = new WidgetLoaded(); + widgetLoaded.setGroupId(WidgetID.THEATRE_OF_BLOOD_REWARD_GROUP_ID); + screenshotPlugin.onWidgetLoaded(widgetLoaded); + + verify(drawManager).requestNextFrameListener(any(Consumer.class)); + } + + @Test + public void testTheatreOfBloodHmChest() + { + when(screenshotConfig.screenshotRewards()).thenReturn(true); + + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Magic fTail", THREATRE_OF_BLOOD_HM_CHEST, null, 0); + screenshotPlugin.onChatMessage(chatMessageEvent); + + assertEquals(73, screenshotPlugin.getKillCountNumber()); + assertEquals(ScreenshotPlugin.KillType.TOB_HM, screenshotPlugin.getKillType()); + + WidgetLoaded widgetLoaded = new WidgetLoaded(); + widgetLoaded.setGroupId(WidgetID.THEATRE_OF_BLOOD_REWARD_GROUP_ID); + screenshotPlugin.onWidgetLoaded(widgetLoaded); + + verify(drawManager).requestNextFrameListener(any(Consumer.class)); } @Test