From de6df44f4881cb0e76df9e0afc079c12f5ad326a Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Mon, 24 May 2021 10:19:22 +0100 Subject: [PATCH 01/30] clues: count bird glove as being correct for the weapon requirement --- .../client/plugins/cluescrolls/clues/SkillChallengeClue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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)), From 6d17a4b8a124ac0f8323fb381fb5f80a521bd7f1 Mon Sep 17 00:00:00 2001 From: Cyborger1 <45152844+Cyborger1@users.noreply.github.com> Date: Thu, 10 Jun 2021 11:16:05 -0400 Subject: [PATCH 02/30] ItemIdentification: Add Ghorrock tablet --- .../client/plugins/itemidentification/ItemIdentification.java | 1 + 1 file changed, 1 insertion(+) 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), From 798ed5e027154844c903e9696aaff6936c5b3d1e Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 10 Jun 2021 16:10:41 -0400 Subject: [PATCH 03/30] chat commands: update tob duration pattern --- .../chatcommands/ChatCommandsPlugin.java | 4 +-- .../chatcommands/ChatCommandsPluginTest.java | 29 +++++-------------- 2 files changed, 10 insertions(+), 23 deletions(-) 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/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java index 5fa71d9b86..e7106953e2 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 From 3bbecdb061a053c58e4bbaeb41e5d7bd7405526b Mon Sep 17 00:00:00 2001 From: Cyborger1 <45152844+Cyborger1@users.noreply.github.com> Date: Thu, 10 Jun 2021 13:31:50 -0400 Subject: [PATCH 04/30] ChatHistory: Fix "Copy to Clipboard" after clan update --- .../client/plugins/chathistory/ChatHistoryPlugin.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 From 21a14e1d2360fc5253a5d628a4ab23d12de48c09 Mon Sep 17 00:00:00 2001 From: Jeremy Plsek Date: Tue, 4 Jun 2019 13:49:28 +0200 Subject: [PATCH 05/30] inventory grid: add color config --- .../inventorygrid/InventoryGridConfig.java | 38 +++++++++++++++++-- .../inventorygrid/InventoryGridOverlay.java | 8 +--- 2 files changed, 36 insertions(+), 10 deletions(-) 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); } } From f62a7c280a349f1555bd2deb4bc4a1f81f128f3c Mon Sep 17 00:00:00 2001 From: FlashBasedGod Date: Sun, 18 Apr 2021 18:19:45 -0230 Subject: [PATCH 06/30] ground items: Add Tempoross instance to normal despawn timers --- .../client/plugins/grounditems/GroundItemsOverlay.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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); From 851d8a8de7aa92dd9268db6b5333873f47c392be Mon Sep 17 00:00:00 2001 From: LlemonDuck Date: Wed, 2 Jun 2021 12:53:08 -0400 Subject: [PATCH 07/30] camera: prevent pitch increment with "preserve pitch" enabled When clicking the compass, the vanilla camera will jitter randomly within 5 values. With "compassLookPreservePitch" enabled, spam clicking the compass would cause your camera pitch to rise repeatedly by that random jitter. This places the camera pitch restore callback after the random jitter, to eliminate that discrepancy. --- runelite-client/src/main/scripts/ToplevelCompassOp.rs2asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From 074f1e0841bfa7ed4aa86c137c4da5d14ccd4dcc Mon Sep 17 00:00:00 2001 From: Max Weber Date: Fri, 11 Jun 2021 03:18:35 -0600 Subject: [PATCH 08/30] client: correctly use Runnables::doNothing passing it as a method reference complete defeats the point of the method as it desugars to: option("foo", () -> { Runnable unused = Runnables.doNothing(); }); --- .../runelite/client/plugins/banktags/tabs/TabInterface.java | 2 +- .../client/plugins/chatchannel/ChatChannelPlugin.java | 2 +- .../plugins/groundmarkers/GroundMarkerSharingManager.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) 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/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(); } From d4078a95553bee262f0d5ca032cea49dfca5ca3e Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 11 Jun 2021 12:47:39 -0400 Subject: [PATCH 09/30] ground markers: add configurable border width --- .../client/plugins/config/ConfigPanel.java | 14 ++++++++++++++ .../plugins/groundmarkers/GroundMarkerConfig.java | 12 +++++++++++- .../plugins/groundmarkers/GroundMarkerOverlay.java | 14 +++++++++++--- .../runelite/client/ui/overlay/OverlayUtil.java | 11 ++++++----- 4 files changed, 42 insertions(+), 9 deletions(-) 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 b72286e3b1..f451debee8 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 @@ -375,6 +375,20 @@ class ConfigPanel extends PluginPanel item.add(spinner, BorderLayout.EAST); } + 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/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/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); From 53e257ce17b48d3e940b1e4ab8aa3b7745f1625d Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 11 Jun 2021 15:16:29 -0400 Subject: [PATCH 10/30] api: add widget line height accessors --- .../main/java/net/runelite/api/widgets/Widget.java | 14 ++++++++++++++ .../plugins/devtools/WidgetInfoTableModel.java | 1 + 2 files changed, 15 insertions(+) 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 1c1f02193a..bb4418804b 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 @@ -845,6 +845,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/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)); From 6467d0d4b7896237cc69efaa039f026f327943da Mon Sep 17 00:00:00 2001 From: tanlines Date: Sat, 12 Jun 2021 10:32:26 +1000 Subject: [PATCH 11/30] itemstats: Fix stamina restore with Ring of Endurance (#13692) --- .../plugins/itemstats/ItemStatChanges.java | 3 +- .../itemstats/potions/StaminaPotion.java | 58 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 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/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..5d20aa8f7e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/StaminaPotion.java @@ -0,0 +1,58 @@ +/* + * 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. + */ +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; + } +} From 5b55afd2cef4a50d410938e687e5858c25821357 Mon Sep 17 00:00:00 2001 From: Cyborger1 <45152844+Cyborger1@users.noreply.github.com> Date: Fri, 11 Jun 2021 23:39:11 -0400 Subject: [PATCH 12/30] hiscore: add lookup clan member (#13706) --- .../net/runelite/client/plugins/hiscore/HiscorePlugin.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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())) { From c60d714832cafc4c2a5ee1395cba5fe03978f5b0 Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Sun, 6 Jun 2021 15:54:01 -0700 Subject: [PATCH 13/30] HotColdLocation: Add clue type field --- .../clues/hotcold/HotColdLocation.java | 293 +++++++++--------- .../clues/hotcold/HotColdLocationTest.java | 36 +++ 2 files changed, 189 insertions(+), 140 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocationTest.java 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/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocationTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocationTest.java new file mode 100644 index 0000000000..70820f0c41 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocationTest.java @@ -0,0 +1,36 @@ +/* + * 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. + */ +package net.runelite.client.plugins.cluescrolls.clues.hotcold; + +import org.junit.Test; + +public class HotColdLocationTest +{ + @Test + public void test() + { + HotColdLocation.values(); // test clinit + } +} \ No newline at end of file From 4fdd6b799f88a5372c2686be54cf56abaca693d6 Mon Sep 17 00:00:00 2001 From: Broooklyn <54762282+Broooklyn@users.noreply.github.com> Date: Mon, 1 Mar 2021 13:16:23 -0500 Subject: [PATCH 14/30] poh: Add icons for objects changed with Goblin Decorations --- .../java/net/runelite/client/plugins/poh/PohIcons.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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, From 7610649ac051770f625a0c81cdad52fbc88a4c65 Mon Sep 17 00:00:00 2001 From: Broooklyn <54762282+Broooklyn@users.noreply.github.com> Date: Wed, 3 Mar 2021 13:35:02 -0500 Subject: [PATCH 15/30] worldmap: Add TzHaar-Ket-Rak's Challenges minigame location --- .../net/runelite/client/plugins/worldmap/MinigameLocation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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; From afb5f782308d14b2a1634ecde4bfc584ca8ae207 Mon Sep 17 00:00:00 2001 From: Cyborger1 <45152844+Cyborger1@users.noreply.github.com> Date: Sat, 12 Jun 2021 14:43:25 -0400 Subject: [PATCH 16/30] clues: Update description for coordinate south-west of Ferox --- .../client/plugins/cluescrolls/clues/CoordinateClue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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)) From 141d4eac0de122b8ffc434e0644a03fe4821d4dc Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 12 Jun 2021 15:02:00 -0400 Subject: [PATCH 17/30] menu swapper: add achievement diary items with non-standard teleport options Co-authored-by: GG46KG --- .../MenuEntrySwapperConfig.java | 84 +++++++++++++++++++ .../MenuEntrySwapperPlugin.java | 16 ++++ 2 files changed, 100 insertions(+) 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 e9ed2db3fb..07eef368c3 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 11a73a776b..df8b0b3014 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 @@ -68,6 +68,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; @@ -354,6 +358,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); From 86a79a1509ccb4adc5abbf2c5fac641c4f515da6 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 13 Jun 2021 13:43:53 -0400 Subject: [PATCH 18/30] Remove examine api The non-items examine info has been broken for years, and the wiki already has item examines anyway, so we can use those in the future if we need them. --- .../http/api/examine/ExamineClient.java | 94 ------------------ .../service/examine/ExamineController.java | 96 ------------------- .../http/service/examine/ExamineEntry.java | 86 ----------------- .../http/service/examine/ExamineService.java | 94 ------------------ .../http/service/examine/ExamineType.java | 32 ------- .../client/plugins/examine/ExaminePlugin.java | 73 +------------- .../plugins/examine/ExaminePluginTest.java | 50 ---------- 7 files changed, 1 insertion(+), 524 deletions(-) delete mode 100644 http-api/src/main/java/net/runelite/http/api/examine/ExamineClient.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/examine/ExamineController.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/examine/ExamineEntry.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/examine/ExamineService.java delete mode 100644 http-service/src/main/java/net/runelite/http/service/examine/ExamineType.java 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/http-service/src/main/java/net/runelite/http/service/examine/ExamineController.java b/http-service/src/main/java/net/runelite/http/service/examine/ExamineController.java deleted file mode 100644 index b7e079497f..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/examine/ExamineController.java +++ /dev/null @@ -1,96 +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.service.examine; - -import static net.runelite.http.service.examine.ExamineType.ITEM; -import static net.runelite.http.service.examine.ExamineType.NPC; -import static net.runelite.http.service.examine.ExamineType.OBJECT; -import net.runelite.http.service.item.ItemEntry; -import net.runelite.http.service.item.ItemService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import static org.springframework.web.bind.annotation.RequestMethod.POST; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/examine") -public class ExamineController -{ - private final ExamineService examineService; - private final ItemService itemService; - - @Autowired - public ExamineController(ExamineService examineService, ItemService itemService) - { - this.examineService = examineService; - this.itemService = itemService; - } - - @GetMapping("/npc/{id}") - public String getNpc(@PathVariable int id) - { - return examineService.get(NPC, id); - } - - @GetMapping("/object/{id}") - public String getObject(@PathVariable int id) - { - return examineService.get(OBJECT, id); - } - - @GetMapping("/item/{id}") - public String getItem(@PathVariable int id) - { - // Tradeable item examine info is available from the Jagex item API - ItemEntry item = itemService.getItem(id); - if (item != null) - { - return item.getDescription(); - } - - return examineService.get(ITEM, id); - } - - @RequestMapping(path = "/npc/{id}", method = POST) - public void submitNpc(@PathVariable int id, @RequestBody String examine) - { - examineService.insert(NPC, id, examine); - } - - @RequestMapping(path = "/object/{id}", method = POST) - public void submitObject(@PathVariable int id, @RequestBody String examine) - { - examineService.insert(OBJECT, id, examine); - } - - @RequestMapping(path = "/item/{id}", method = POST) - public void submitItem(@PathVariable int id, @RequestBody String examine) - { - examineService.insert(ITEM, id, examine); - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/examine/ExamineEntry.java b/http-service/src/main/java/net/runelite/http/service/examine/ExamineEntry.java deleted file mode 100644 index 5222ef3059..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/examine/ExamineEntry.java +++ /dev/null @@ -1,86 +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.service.examine; - -import java.time.Instant; - -public class ExamineEntry -{ - private ExamineType type; - private int id; - private Instant time; - private int count; - private String text; - - public ExamineType getType() - { - return type; - } - - public void setType(ExamineType type) - { - this.type = type; - } - - public int getId() - { - return id; - } - - public void setId(int id) - { - this.id = id; - } - - public Instant getTime() - { - return time; - } - - public void setTime(Instant time) - { - this.time = time; - } - - public int getCount() - { - return count; - } - - public void setCount(int count) - { - this.count = count; - } - - public String getText() - { - return text; - } - - public void setText(String text) - { - this.text = text; - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/examine/ExamineService.java b/http-service/src/main/java/net/runelite/http/service/examine/ExamineService.java deleted file mode 100644 index c7fa265eea..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/examine/ExamineService.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.http.service.examine; - -import java.sql.Timestamp; -import java.time.Instant; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Service; -import org.sql2o.Connection; -import org.sql2o.Sql2o; - -@Service -public class ExamineService -{ - private static final String CREATE_EXAMINE = "CREATE TABLE IF NOT EXISTS `examine` (\n" - + " `type` enum('OBJECT','NPC','ITEM') NOT NULL,\n" - + " `id` int(11) NOT NULL,\n" - + " `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n" - + " `count` int(11) NOT NULL,\n" - + " `text` tinytext NOT NULL,\n" - + " UNIQUE KEY `type` (`type`,`id`,`text`(64))\n" - + ") ENGINE=InnoDB"; - - private final Sql2o sql2o; - - @Autowired - public ExamineService(@Qualifier("Runelite SQL2O") Sql2o sql2o) - { - this.sql2o = sql2o; - - try (Connection con = sql2o.open()) - { - con.createQuery(CREATE_EXAMINE) - .executeUpdate(); - } - } - - public String get(ExamineType type, int id) - { - try (Connection con = sql2o.open()) - { - ExamineEntry entry = con.createQuery("select text from examine where type = :type and id = :id " - + "order by count desc limit 1") - .addParameter("type", type.toString()) - .addParameter("id", id) - .executeAndFetchFirst(ExamineEntry.class); - - if (entry != null) - { - return entry.getText(); - } - } - - return null; - } - - public void insert(ExamineType type, int id, String examine) - { - try (Connection con = sql2o.open()) - { - con.createQuery("insert into examine (type, id, time, count, text) values " - + "(:type, :id, :time, :count, :text) on duplicate key update count = count + 1") - .addParameter("type", type.toString()) - .addParameter("id", id) - .addParameter("time", Timestamp.from(Instant.now())) - .addParameter("count", 1) - .addParameter("text", examine) - .executeUpdate(); - } - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/examine/ExamineType.java b/http-service/src/main/java/net/runelite/http/service/examine/ExamineType.java deleted file mode 100644 index 86826c0325..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/examine/ExamineType.java +++ /dev/null @@ -1,32 +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.service.examine; - -public enum ExamineType -{ - OBJECT, - NPC, - ITEM; -} 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/test/java/net/runelite/client/plugins/examine/ExaminePluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/examine/ExaminePluginTest.java index e13f926f8b..31589046e0 100644 --- 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 @@ -28,28 +28,19 @@ 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.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.ItemComposition; import net.runelite.api.ItemID; -import net.runelite.api.MenuAction; -import net.runelite.api.events.ChatMessage; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.widgets.Widget; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.game.ItemManager; -import net.runelite.http.api.examine.ExamineClient; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; import org.mockito.Mock; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -60,10 +51,6 @@ public class ExaminePluginTest @Inject ExaminePlugin examinePlugin; - @Mock - @Bind - ExamineClient examineClient; - @Mock @Bind Client client; @@ -82,43 +69,6 @@ public class ExaminePluginTest Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); } - @Test - public void testItem() - { - when(client.getWidget(anyInt(), anyInt())).thenReturn(mock(Widget.class)); - when(itemManager.getItemComposition(anyInt())).thenReturn(mock(ItemComposition.class)); - - MenuOptionClicked menuOptionClicked = new MenuOptionClicked(); - menuOptionClicked.setMenuOption("Examine"); - menuOptionClicked.setMenuAction(MenuAction.EXAMINE_ITEM); - menuOptionClicked.setId(ItemID.ABYSSAL_WHIP); - examinePlugin.onMenuOptionClicked(menuOptionClicked); - - ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.ITEM_EXAMINE, "", "A weapon from the abyss.", "", 0); - examinePlugin.onChatMessage(chatMessage); - - // This passes due to not mocking the ItemComposition for the whip - verify(examineClient).submitItem(anyInt(), anyString()); - } - - @Test - public void testLargeStacks() - { - when(client.getWidget(anyInt(), anyInt())).thenReturn(mock(Widget.class)); - when(itemManager.getItemComposition(anyInt())).thenReturn(mock(ItemComposition.class)); - - MenuOptionClicked menuOptionClicked = new MenuOptionClicked(); - menuOptionClicked.setMenuOption("Examine"); - menuOptionClicked.setMenuAction(MenuAction.EXAMINE_ITEM); - menuOptionClicked.setId(ItemID.ABYSSAL_WHIP); - examinePlugin.onMenuOptionClicked(menuOptionClicked); - - ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.ITEM_EXAMINE, "", "100000 x Abyssal whip", "", 0); - examinePlugin.onChatMessage(chatMessage); - - verify(examineClient, never()).submitItem(anyInt(), anyString()); - } - @Test public void testGetItemPrice() { From 5db59f083ef1e3999ca547d52eeaaf90166b1cdd Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 13 Jun 2021 17:23:13 -0400 Subject: [PATCH 19/30] screenshot plugin: consolidate kill count fields --- .../plugins/screenshot/ScreenshotPlugin.java | 82 ++++++++----------- .../screenshot/ScreenshotPluginTest.java | 6 +- 2 files changed, 39 insertions(+), 49 deletions(-) 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..6fe20b9c33 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 @@ -122,13 +122,16 @@ public class ScreenshotPlugin extends Plugin private String clueType; private Integer clueNumber; - private Integer barrowsNumber; + enum KillType + { + BARROWS, + COX, + COX_CM, + TOB + } - private Integer chambersOfXericNumber; - - private Integer chambersOfXericChallengeNumber; - - private Integer theatreOfBloodNumber; + private KillType killType; + private Integer killCountNumber; private boolean shouldTakeScreenshot; @@ -346,7 +349,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 +360,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,7 +371,8 @@ 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; } } @@ -376,7 +382,8 @@ public class ScreenshotPlugin extends Plugin Matcher m = NUMBER_PATTERN.matcher(Text.removeTags(chatMessage)); if (m.find()) { - theatreOfBloodNumber = Integer.valueOf(m.group()); + killType = KillType.TOB; + killCountNumber = Integer.valueOf(m.group()); return; } } @@ -515,47 +522,48 @@ public class ScreenshotPlugin extends Plugin } case CHAMBERS_OF_XERIC_REWARD_GROUP_ID: { - if (chambersOfXericNumber != null) + if (killType == KillType.COX) { - fileName = "Chambers of Xeric(" + chambersOfXericNumber + ")"; + fileName = "Chambers of Xeric(" + killCountNumber + ")"; screenshotSubDir = "Boss Kills"; - chambersOfXericNumber = null; + killType = null; + killCountNumber = 0; break; } - else if (chambersOfXericChallengeNumber != null) + else if (killType == KillType.COX_CM) { - fileName = "Chambers of Xeric Challenge Mode(" + chambersOfXericChallengeNumber + ")"; + fileName = "Chambers of Xeric Challenge Mode(" + killCountNumber + ")"; screenshotSubDir = "Boss Kills"; - chambersOfXericChallengeNumber = null; + killType = null; + killCountNumber = 0; break; } - else - { - return; - } + return; } case THEATRE_OF_BLOOD_REWARD_GROUP_ID: { - if (theatreOfBloodNumber == null) + if (killType != KillType.TOB) { return; } - fileName = "Theatre of Blood(" + theatreOfBloodNumber + ")"; + fileName = "Theatre of Blood(" + killCountNumber + ")"; screenshotSubDir = "Boss Kills"; - theatreOfBloodNumber = null; + killType = null; + killCountNumber = 0; break; } case BARROWS_REWARD_GROUP_ID: { - if (barrowsNumber == null) + if (killType != KillType.BARROWS) { return; } - fileName = "Barrows(" + barrowsNumber + ")"; + fileName = "Barrows(" + killCountNumber + ")"; screenshotSubDir = "Boss Kills"; - barrowsNumber = null; + killType = null; + killCountNumber = 0; break; } case LEVEL_UP_GROUP_ID: @@ -769,26 +777,8 @@ public class ScreenshotPlugin extends Plugin } @VisibleForTesting - int getBarrowsNumber() + int getKillCountNumber() { - return barrowsNumber; - } - - @VisibleForTesting - int getChambersOfXericNumber() - { - return chambersOfXericNumber; - } - - @VisibleForTesting - int getChambersOfXericChallengeNumber() - { - return chambersOfXericChallengeNumber; - } - - @VisibleForTesting - int gettheatreOfBloodNumber() - { - return theatreOfBloodNumber; + return killCountNumber; } } 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..06885f4854 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 @@ -143,7 +143,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,7 +152,7 @@ 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 @@ -161,7 +161,7 @@ public class ScreenshotPluginTest 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()); } @Test From 79b18d43aa8503e8b3cd6da2074773d049d3a685 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 13 Jun 2021 17:30:48 -0400 Subject: [PATCH 20/30] screenshot plugin: make subdir strings constants --- .../plugins/screenshot/ScreenshotPlugin.java | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) 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 6fe20b9c33..6b67de55a2 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,6 +118,18 @@ 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; @@ -286,11 +298,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); } } } @@ -303,7 +315,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); } } @@ -395,14 +407,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()) @@ -413,7 +425,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); } } @@ -423,7 +435,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); } } @@ -437,7 +449,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); } } } @@ -449,7 +461,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); } } @@ -461,7 +473,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); } } @@ -469,7 +481,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); } } @@ -517,7 +529,7 @@ 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: @@ -525,7 +537,7 @@ public class ScreenshotPlugin extends Plugin if (killType == KillType.COX) { fileName = "Chambers of Xeric(" + killCountNumber + ")"; - screenshotSubDir = "Boss Kills"; + screenshotSubDir = SD_BOSS_KILLS; killType = null; killCountNumber = 0; break; @@ -533,7 +545,7 @@ public class ScreenshotPlugin extends Plugin else if (killType == KillType.COX_CM) { fileName = "Chambers of Xeric Challenge Mode(" + killCountNumber + ")"; - screenshotSubDir = "Boss Kills"; + screenshotSubDir = SD_BOSS_KILLS; killType = null; killCountNumber = 0; break; @@ -548,7 +560,7 @@ public class ScreenshotPlugin extends Plugin } fileName = "Theatre of Blood(" + killCountNumber + ")"; - screenshotSubDir = "Boss Kills"; + screenshotSubDir = SD_BOSS_KILLS; killType = null; killCountNumber = 0; break; @@ -561,7 +573,7 @@ public class ScreenshotPlugin extends Plugin } fileName = "Barrows(" + killCountNumber + ")"; - screenshotSubDir = "Boss Kills"; + screenshotSubDir = SD_BOSS_KILLS; killType = null; killCountNumber = 0; break; @@ -582,7 +594,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; From 35ddeebf04ae84ca10078d1fcb52bba1654637a5 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 13 Jun 2021 18:02:10 -0400 Subject: [PATCH 21/30] screenshot plugin: add tob story and hard mode screenshots --- .../plugins/screenshot/ScreenshotPlugin.java | 16 +++++-- .../screenshot/ScreenshotPluginTest.java | 48 +++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) 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 6b67de55a2..93635e3ec5 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 @@ -139,7 +139,9 @@ public class ScreenshotPlugin extends Plugin BARROWS, COX, COX_CM, - TOB + TOB, + TOB_SM, + TOB_HM } private KillType killType; @@ -389,12 +391,12 @@ public class ScreenshotPlugin extends Plugin } } - 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()) { - killType = KillType.TOB; + killType = chatMessage.contains("Hard Mode") ? KillType.TOB_HM : (chatMessage.contains("Story Mode") ? KillType.TOB_SM : KillType.TOB); killCountNumber = Integer.valueOf(m.group()); return; } @@ -554,7 +556,7 @@ public class ScreenshotPlugin extends Plugin } case THEATRE_OF_BLOOD_REWARD_GROUP_ID: { - if (killType != KillType.TOB) + if (killType != KillType.TOB && killType != KillType.TOB_SM && killType != KillType.TOB_HM) { return; } @@ -788,6 +790,12 @@ public class ScreenshotPlugin extends Plugin return clueType; } + @VisibleForTesting + KillType getKillType() + { + return killType; + } + @VisibleForTesting int getKillCountNumber() { 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 06885f4854..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"; @@ -158,10 +161,55 @@ public class ScreenshotPluginTest @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.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 From 0580e32cc657b2d7771906b80995a5f2dfdd932b Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 13 Jun 2021 18:32:20 -0400 Subject: [PATCH 22/30] screenshot plugin: name tob hm/sm files differently --- .../plugins/screenshot/ScreenshotPlugin.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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 93635e3ec5..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 @@ -561,7 +561,21 @@ public class ScreenshotPlugin extends Plugin return; } - fileName = "Theatre of Blood(" + killCountNumber + ")"; + 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; From 159c239908e844d9e22d2a32b67d450b6da5d0b2 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 13 Jun 2021 17:03:55 -0400 Subject: [PATCH 23/30] xp drops: add option to override standard client xp drop colors Co-authored-by: Zeusay --- .../plugins/experiencedrop/XpDropConfig.java | 17 ++++++++++++----- .../plugins/experiencedrop/XpDropPlugin.java | 18 ++++++++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) 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) From 60b5759fb094312057ab4c62000f107f84536b11 Mon Sep 17 00:00:00 2001 From: Steven Brice Date: Mon, 14 Jun 2021 14:48:18 -0700 Subject: [PATCH 24/30] loot tracker: add Wintertodt supply crate --- .../client/plugins/loottracker/LootTrackerPlugin.java | 9 +++++++++ 1 file changed, 9 insertions(+) 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); From 9d1859234df87515de7c2c8402f8f868574d1308 Mon Sep 17 00:00:00 2001 From: emiljensen2 <55587410+emiljensen2@users.noreply.github.com> Date: Mon, 14 Jun 2021 23:50:05 +0200 Subject: [PATCH 25/30] ItemMapping: add new tob kits Add holy/sanguine scythe, sang, and rapier varients including charged/uncharged versions. --- .../src/main/java/net/runelite/client/game/ItemMapping.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 29f34ea8a9..81f7059bf8 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( From 7522d8f80548589b3d2391e16899e3154406807d Mon Sep 17 00:00:00 2001 From: Bird-Hands Date: Mon, 14 Jun 2021 22:35:01 -0700 Subject: [PATCH 26/30] npc indicators: add configurable border width --- .../npchighlight/NpcIndicatorsConfig.java | 21 ++++++++++++++----- .../plugins/npchighlight/NpcSceneOverlay.java | 5 +++-- 2 files changed, 19 insertions(+), 7 deletions(-) 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); } } From fecd65e7e5b2cfddcff71c2a2a74fa5db7cc00cb Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Mon, 14 Jun 2021 22:42:57 -0700 Subject: [PATCH 27/30] object indicators: add configurable border width --- .../objectindicators/ObjectIndicatorsConfig.java | 10 ++++++++++ .../objectindicators/ObjectIndicatorsOverlay.java | 7 +++++-- 2 files changed, 15 insertions(+), 2 deletions(-) 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); } } From 23412fb2450a954c22b03ba2201019a0e8ab864e Mon Sep 17 00:00:00 2001 From: danshea00 <51503005+danshea00@users.noreply.github.com> Date: Tue, 15 Jun 2021 16:20:13 +1000 Subject: [PATCH 28/30] screenshot: Use separate directory for tournament/beta worlds (#13631) --- .../src/main/java/net/runelite/client/util/ImageCapture.java | 4 ++++ 1 file changed, 4 insertions(+) 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)) { From 7ba679339d90a7437fe7be2344097df311ec1afe Mon Sep 17 00:00:00 2001 From: LlemonDuck Date: Wed, 26 May 2021 19:41:40 -0400 Subject: [PATCH 29/30] Reset spec counter when leaving instanced fights When leaving Vorkath or Alchemical Hydra fights, the spec counter does not reset, despite the boss resetting their stats. This could cause the spec counter to add the player's next trip spec to that, giving an inaccurate total spec count. This clears that counter when leaving the vork + hydra region instances. --- .../specialcounter/SpecialCounterPlugin.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) 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) From 23ce90275fec6404e9095a7cfd1b5db588be5a7e Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 15 Jun 2021 18:58:57 -0400 Subject: [PATCH 30/30] loot tracker: add reset warning to event reset option --- .../plugins/loottracker/LootTrackerPanel.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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()) {