From 902d2f952b69c1f9da74404886dbfc823c43bd9b Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Thu, 30 May 2019 18:03:03 +0100 Subject: [PATCH 01/30] agility: Fix highlighting of Al Kharid zip line --- .../java/net/runelite/client/plugins/agility/Obstacles.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java index 19f4dc565e..929a4fd759 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java @@ -46,7 +46,7 @@ class Obstacles // Draynor ROUGH_WALL, TIGHTROPE, TIGHTROPE_11406, NARROW_WALL, WALL_11630, GAP_11631, CRATE_11632, STILE_7527, // Al-Kharid - ROUGH_WALL_11633, TIGHTROPE_14398, CABLE, ZIP_LINE, TROPICAL_TREE_14404, ROOF_TOP_BEAMS, + ROUGH_WALL_11633, TIGHTROPE_14398, CABLE, ZIP_LINE_14403, TROPICAL_TREE_14404, ROOF_TOP_BEAMS, TIGHTROPE_14409, GAP_14399, // Pyramid STAIRS_10857, LOW_WALL_10865, LEDGE_10860, PLANK_10868, GAP_10882, LEDGE_10886, STAIRS_10857, GAP_10884, From 52ce25e7807ddcc757149d1da21d3373bd511bf9 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 30 May 2019 19:28:07 -0400 Subject: [PATCH 02/30] Revert "cooking plugin: fix wine fermentation timer to begin at appropriate time" This reverts commit acaef50b91ff709af39f2b94dccc59e4683c6f1f. --- .../client/plugins/cooking/CookingPlugin.java | 41 ++++++------------- .../plugins/cooking/CookingPluginTest.java | 30 +++++++++++--- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java index a08497663d..93ee8e6412 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java @@ -31,11 +31,7 @@ import java.time.Instant; import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; -import static net.runelite.api.AnimationID.COOKING_WINE; import net.runelite.api.ChatMessageType; -import net.runelite.api.Client; -import net.runelite.api.Player; -import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; import net.runelite.client.config.ConfigManager; @@ -54,8 +50,7 @@ import net.runelite.client.ui.overlay.OverlayManager; @PluginDependency(XpTrackerPlugin.class) public class CookingPlugin extends Plugin { - @Inject - private Client client; + private static final String WINE_MESSAGE = "You squeeze the grapes into the jug"; @Inject private CookingConfig config; @@ -129,27 +124,6 @@ public class CookingPlugin extends Plugin } } - @Subscribe - public void onAnimationChanged(AnimationChanged animationChanged) - { - Player localPlayer = client.getLocalPlayer(); - - if (localPlayer != animationChanged.getActor()) - { - return; - } - - if (localPlayer.getAnimation() == COOKING_WINE && config.fermentTimer()) - { - if (fermentTimerSession == null) - { - fermentTimerSession = new FermentTimerSession(); - } - - fermentTimerSession.updateLastWineMakingAction(); - } - } - @Subscribe public void onChatMessage(ChatMessage event) { @@ -160,11 +134,22 @@ public class CookingPlugin extends Plugin final String message = event.getMessage(); + if (message.startsWith(WINE_MESSAGE) && config.fermentTimer()) + { + if (fermentTimerSession == null) + { + fermentTimerSession = new FermentTimerSession(); + } + + fermentTimerSession.updateLastWineMakingAction(); + } + if (message.startsWith("You successfully cook") || message.startsWith("You successfully bake") || message.startsWith("You manage to cook") || message.startsWith("You roast a") - || message.startsWith("You cook")) + || message.startsWith("You cook") + || message.startsWith(WINE_MESSAGE)) { if (cookingSession == null) { diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java index d23fd934c0..067c02943c 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java @@ -29,11 +29,12 @@ 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.events.ChatMessage; import net.runelite.client.ui.overlay.OverlayManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; @@ -51,16 +52,13 @@ public class CookingPluginTest "You cook the karambwan. It looks delicious.", "You roast a lobster.", "You cook a bass.", + "You squeeze the grapes into the jug. The wine begins to ferment.", "You successfully bake a tasty garden pie." }; @Inject CookingPlugin cookingPlugin; - @Mock - @Bind - Client client; - @Mock @Bind CookingConfig config; @@ -96,4 +94,26 @@ public class CookingPluginTest assertNotNull(cookingSession); assertEquals(COOKING_MESSAGES.length, cookingSession.getCookAmount()); } + + @Test + public void testFermentTimerOnChatMessage() + { + when(config.fermentTimer()).thenReturn(true); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", COOKING_MESSAGES[6], "", 0); + cookingPlugin.onChatMessage(chatMessage); + FermentTimerSession fermentTimerSession = cookingPlugin.getFermentTimerSession(); + + assertNotNull(fermentTimerSession); + } + + @Test + public void testFermentTimerOnChatMessage_pluginDisabled() + { + when(config.fermentTimer()).thenReturn(false); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", COOKING_MESSAGES[6], "", 0); + cookingPlugin.onChatMessage(chatMessage); + FermentTimerSession fermentTimerSession = cookingPlugin.getFermentTimerSession(); + + assertNull(fermentTimerSession); + } } \ No newline at end of file From cbfcba325d4dd6c59b6b150074a2ead82b766132 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 30 May 2019 19:28:23 -0400 Subject: [PATCH 03/30] Revert "cooking plugin: add wine ferment timer" This reverts commit e6113dc82af8d8697546e1a51ee19d23636f9f19. --- .../client/plugins/cooking/CookingConfig.java | 11 -- .../client/plugins/cooking/CookingPlugin.java | 47 ++------ .../plugins/cooking/FermentTimerOverlay.java | 101 ------------------ .../plugins/cooking/FermentTimerSession.java | 40 ------- .../plugins/cooking/CookingPluginTest.java | 31 +----- 5 files changed, 7 insertions(+), 223 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimerOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimerSession.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingConfig.java index 1a1db71368..f8ec60a607 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingConfig.java @@ -42,15 +42,4 @@ public interface CookingConfig extends Config { return 5; } - - @ConfigItem( - position = 2, - keyName = "fermentTimer", - name = "Show wine fermenting timer", - description = "Conifgures if the timer before wines are fermented is shown." - ) - default boolean fermentTimer() - { - return true; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java index 93ee8e6412..bbcb8ddf02 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java @@ -50,26 +50,18 @@ import net.runelite.client.ui.overlay.OverlayManager; @PluginDependency(XpTrackerPlugin.class) public class CookingPlugin extends Plugin { - private static final String WINE_MESSAGE = "You squeeze the grapes into the jug"; - @Inject private CookingConfig config; @Inject private CookingOverlay cookingOverlay; - @Inject - private FermentTimerOverlay fermentTimerOverlay; - @Inject private OverlayManager overlayManager; @Getter(AccessLevel.PACKAGE) private CookingSession cookingSession; - @Getter(AccessLevel.PACKAGE) - private FermentTimerSession fermentTimerSession; - @Provides CookingConfig getConfig(ConfigManager configManager) { @@ -80,47 +72,30 @@ public class CookingPlugin extends Plugin protected void startUp() throws Exception { cookingSession = null; - fermentTimerSession = null; overlayManager.add(cookingOverlay); - overlayManager.add(fermentTimerOverlay); } @Override protected void shutDown() throws Exception { - overlayManager.remove(fermentTimerOverlay); overlayManager.remove(cookingOverlay); - fermentTimerSession = null; cookingSession = null; } @Subscribe public void onGameTick(GameTick gameTick) { - if (config.statTimeout() == 0) + if (cookingSession == null || config.statTimeout() == 0) { return; } - if (cookingSession != null) - { - Duration statTimeout = Duration.ofMinutes(config.statTimeout()); - Duration sinceCut = Duration.between(cookingSession.getLastCookingAction(), Instant.now()); + Duration statTimeout = Duration.ofMinutes(config.statTimeout()); + Duration sinceCut = Duration.between(cookingSession.getLastCookingAction(), Instant.now()); - if (sinceCut.compareTo(statTimeout) >= 0) - { - cookingSession = null; - } - } - if (fermentTimerSession != null) + if (sinceCut.compareTo(statTimeout) >= 0) { - Duration statTimeout = Duration.ofMinutes(config.statTimeout()); - Duration sinceCut = Duration.between(fermentTimerSession.getLastWineMakingAction(), Instant.now()); - - if (sinceCut.compareTo(statTimeout) >= 0) - { - fermentTimerSession = null; - } + cookingSession = null; } } @@ -134,22 +109,12 @@ public class CookingPlugin extends Plugin final String message = event.getMessage(); - if (message.startsWith(WINE_MESSAGE) && config.fermentTimer()) - { - if (fermentTimerSession == null) - { - fermentTimerSession = new FermentTimerSession(); - } - - fermentTimerSession.updateLastWineMakingAction(); - } - if (message.startsWith("You successfully cook") || message.startsWith("You successfully bake") || message.startsWith("You manage to cook") || message.startsWith("You roast a") || message.startsWith("You cook") - || message.startsWith(WINE_MESSAGE)) + || message.startsWith("You squeeze the grapes into the jug")) { if (cookingSession == null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimerOverlay.java deleted file mode 100644 index 3ec1783bb0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimerOverlay.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2019, Lucas C - * 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.cooking; - -import com.google.inject.Inject; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.time.Duration; -import java.time.Instant; -import lombok.extern.slf4j.Slf4j; -import static net.runelite.api.AnimationID.COOKING_WINE; -import net.runelite.api.Client; -import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; -import net.runelite.client.ui.overlay.Overlay; -import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; -import net.runelite.client.ui.overlay.OverlayMenuEntry; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.LineComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; -import net.runelite.client.ui.overlay.components.TitleComponent; - -@Slf4j -class FermentTimerOverlay extends Overlay -{ - private static final int INITIAL_TIME = 12; - - private final Client client; - private final CookingPlugin plugin; - private final PanelComponent panelComponent = new PanelComponent(); - - @Inject - private FermentTimerOverlay(final Client client, final CookingPlugin plugin) - { - super(plugin); - setPosition(OverlayPosition.TOP_LEFT); - this.client = client; - this.plugin = plugin; - getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Fermenting Timer overlay")); - } - - @Override - public Dimension render(Graphics2D graphics) - { - FermentTimerSession session = plugin.getFermentTimerSession(); - if (session == null) - { - return null; - } - - panelComponent.getChildren().clear(); - - if (isMakingWine() || Duration.between(session.getLastWineMakingAction(), Instant.now()).getSeconds() < INITIAL_TIME) - { - panelComponent.getChildren().add(TitleComponent.builder() - .text("Making Wine") - .color(Color.GREEN) - .build()); - panelComponent.getChildren().add(LineComponent.builder() - .left("Ferments in: ") - .right(String.valueOf(INITIAL_TIME - Duration.between(session.getLastWineMakingAction(), Instant.now()).getSeconds())) - .build()); - } - else - { - panelComponent.getChildren().add(TitleComponent.builder() - .text("Wine Fermented") - .color(Color.ORANGE) - .build()); - } - - return panelComponent.render(graphics); - } - - private boolean isMakingWine() - { - return (client.getLocalPlayer().getAnimation() == COOKING_WINE); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimerSession.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimerSession.java deleted file mode 100644 index 1e6520d091..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimerSession.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2019, Lucas C - * 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.cooking; - -import java.time.Instant; -import lombok.AccessLevel; -import lombok.Getter; - -class FermentTimerSession -{ - @Getter(AccessLevel.PACKAGE) - private Instant lastWineMakingAction; - - void updateLastWineMakingAction() - { - this.lastWineMakingAction = Instant.now(); - } -} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java index 067c02943c..ae6418ee05 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java @@ -33,9 +33,6 @@ import net.runelite.api.events.ChatMessage; import net.runelite.client.ui.overlay.OverlayManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.when; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -67,10 +64,6 @@ public class CookingPluginTest @Bind CookingOverlay cookingOverlay; - @Mock - @Bind - FermentTimerOverlay fermentTimerOverlay; - @Mock @Bind OverlayManager overlayManager; @@ -90,30 +83,8 @@ public class CookingPluginTest cookingPlugin.onChatMessage(chatMessage); } - CookingSession cookingSession = cookingPlugin.getCookingSession(); + CookingSession cookingSession = cookingPlugin.getSession(); assertNotNull(cookingSession); assertEquals(COOKING_MESSAGES.length, cookingSession.getCookAmount()); } - - @Test - public void testFermentTimerOnChatMessage() - { - when(config.fermentTimer()).thenReturn(true); - ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", COOKING_MESSAGES[6], "", 0); - cookingPlugin.onChatMessage(chatMessage); - FermentTimerSession fermentTimerSession = cookingPlugin.getFermentTimerSession(); - - assertNotNull(fermentTimerSession); - } - - @Test - public void testFermentTimerOnChatMessage_pluginDisabled() - { - when(config.fermentTimer()).thenReturn(false); - ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", COOKING_MESSAGES[6], "", 0); - cookingPlugin.onChatMessage(chatMessage); - FermentTimerSession fermentTimerSession = cookingPlugin.getFermentTimerSession(); - - assertNull(fermentTimerSession); - } } \ No newline at end of file From 79e67a34bc10954ee70d8171065dbb6ed49408e9 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 30 May 2019 20:00:08 -0400 Subject: [PATCH 04/30] Revert "cooking plugin: rename session to cooking session" This reverts commit e40b1a7b10e0378e948f56deec43b2fbce9ba04f. --- .../plugins/cooking/CookingOverlay.java | 4 +-- .../client/plugins/cooking/CookingPlugin.java | 34 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingOverlay.java index a5af5309d9..7e25f3ad31 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingOverlay.java @@ -29,8 +29,8 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.text.DecimalFormat; -import java.time.Duration; import java.time.Instant; +import java.time.Duration; import javax.inject.Inject; import static net.runelite.api.AnimationID.COOKING_FIRE; import static net.runelite.api.AnimationID.COOKING_RANGE; @@ -72,7 +72,7 @@ class CookingOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - CookingSession session = plugin.getCookingSession(); + CookingSession session = plugin.getSession(); if (session == null) { return null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java index bbcb8ddf02..7766438a73 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java @@ -54,13 +54,13 @@ public class CookingPlugin extends Plugin private CookingConfig config; @Inject - private CookingOverlay cookingOverlay; + private CookingOverlay overlay; @Inject private OverlayManager overlayManager; @Getter(AccessLevel.PACKAGE) - private CookingSession cookingSession; + private CookingSession session; @Provides CookingConfig getConfig(ConfigManager configManager) @@ -71,31 +71,31 @@ public class CookingPlugin extends Plugin @Override protected void startUp() throws Exception { - cookingSession = null; - overlayManager.add(cookingOverlay); + session = null; + overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { - overlayManager.remove(cookingOverlay); - cookingSession = null; + overlayManager.remove(overlay); + session = null; } @Subscribe public void onGameTick(GameTick gameTick) { - if (cookingSession == null || config.statTimeout() == 0) + if (session == null || config.statTimeout() == 0) { return; } Duration statTimeout = Duration.ofMinutes(config.statTimeout()); - Duration sinceCut = Duration.between(cookingSession.getLastCookingAction(), Instant.now()); + Duration sinceCut = Duration.between(session.getLastCookingAction(), Instant.now()); if (sinceCut.compareTo(statTimeout) >= 0) { - cookingSession = null; + session = null; } } @@ -116,24 +116,24 @@ public class CookingPlugin extends Plugin || message.startsWith("You cook") || message.startsWith("You squeeze the grapes into the jug")) { - if (cookingSession == null) + if (session == null) { - cookingSession = new CookingSession(); + session = new CookingSession(); } - cookingSession.updateLastCookingAction(); - cookingSession.increaseCookAmount(); + session.updateLastCookingAction(); + session.increaseCookAmount(); } else if (message.startsWith("You accidentally burn")) { - if (cookingSession == null) + if (session == null) { - cookingSession = new CookingSession(); + session = new CookingSession(); } - cookingSession.updateLastCookingAction(); - cookingSession.increaseBurnAmount(); + session.updateLastCookingAction(); + session.increaseBurnAmount(); } } } From 59c1139b5110aa16ad747fa4f98b5438ba1c2f5b Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 30 May 2019 19:59:12 -0400 Subject: [PATCH 05/30] cooking plugin: add wine ferment timer --- .../main/java/net/runelite/api/GraphicID.java | 1 + .../client/plugins/cooking/CookingConfig.java | 11 +++ .../client/plugins/cooking/CookingPlugin.java | 51 ++++++++++++- .../client/plugins/cooking/FermentTimer.java | 76 +++++++++++++++++++ .../plugins/cooking/CookingPluginTest.java | 39 +++++++++- 5 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimer.java diff --git a/runelite-api/src/main/java/net/runelite/api/GraphicID.java b/runelite-api/src/main/java/net/runelite/api/GraphicID.java index b1d2c3d00f..34a7b2d667 100644 --- a/runelite-api/src/main/java/net/runelite/api/GraphicID.java +++ b/runelite-api/src/main/java/net/runelite/api/GraphicID.java @@ -26,6 +26,7 @@ package net.runelite.api; public class GraphicID { + public static final int WINE_MAKE = 47; public static final int SPLASH = 85; public static final int TELEPORT = 111; public static final int GREY_BUBBLE_TELEPORT = 86; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingConfig.java index f8ec60a607..2a12ac1ede 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingConfig.java @@ -42,4 +42,15 @@ public interface CookingConfig extends Config { return 5; } + + @ConfigItem( + position = 2, + keyName = "fermentTimer", + name = "Show wine ferment timer", + description = "Configures if the timer before wines are fermented is shown" + ) + default boolean fermentTimer() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java index 7766438a73..f48897c94d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java @@ -28,19 +28,27 @@ package net.runelite.client.plugins.cooking; import com.google.inject.Provides; import java.time.Duration; import java.time.Instant; +import java.util.Optional; import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.GraphicID; +import net.runelite.api.ItemID; +import net.runelite.api.Player; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; +import net.runelite.api.events.GraphicChanged; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.xptracker.XpTrackerPlugin; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; @PluginDescriptor( name = "Cooking", @@ -50,6 +58,9 @@ import net.runelite.client.ui.overlay.OverlayManager; @PluginDependency(XpTrackerPlugin.class) public class CookingPlugin extends Plugin { + @Inject + private Client client; + @Inject private CookingConfig config; @@ -59,6 +70,12 @@ public class CookingPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private InfoBoxManager infoBoxManager; + + @Inject + private ItemManager itemManager; + @Getter(AccessLevel.PACKAGE) private CookingSession session; @@ -78,6 +95,7 @@ public class CookingPlugin extends Plugin @Override protected void shutDown() throws Exception { + infoBoxManager.removeIf(FermentTimer.class::isInstance); overlayManager.remove(overlay); session = null; } @@ -99,6 +117,36 @@ public class CookingPlugin extends Plugin } } + @Subscribe + public void onGraphicChanged(GraphicChanged graphicChanged) + { + Player player = client.getLocalPlayer(); + + if (graphicChanged.getActor() != player) + { + return; + } + + if (player.getGraphic() == GraphicID.WINE_MAKE && config.fermentTimer()) + { + Optional fermentTimerOpt = infoBoxManager.getInfoBoxes().stream() + .filter(FermentTimer.class::isInstance) + .map(FermentTimer.class::cast) + .findAny(); + + if (fermentTimerOpt.isPresent()) + { + FermentTimer fermentTimer = fermentTimerOpt.get(); + fermentTimer.reset(); + } + else + { + FermentTimer fermentTimer = new FermentTimer(itemManager.getImage(ItemID.JUG_OF_WINE), this); + infoBoxManager.addInfoBox(fermentTimer); + } + } + } + @Subscribe public void onChatMessage(ChatMessage event) { @@ -113,8 +161,7 @@ public class CookingPlugin extends Plugin || message.startsWith("You successfully bake") || message.startsWith("You manage to cook") || message.startsWith("You roast a") - || message.startsWith("You cook") - || message.startsWith("You squeeze the grapes into the jug")) + || message.startsWith("You cook")) { if (session == null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimer.java new file mode 100644 index 0000000000..5312414ad1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimer.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.cooking; + +import java.awt.Color; +import java.awt.Image; +import java.time.Duration; +import java.time.Instant; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.ui.overlay.infobox.InfoBox; + +final class FermentTimer extends InfoBox +{ + private static final Duration FERMENT_TIME = Duration.ofMillis(13_800); + + private Instant fermentTime; + + FermentTimer(Image image, Plugin plugin) + { + super(image, plugin); + reset(); + } + + @Override + public String getText() + { + int seconds = timeUntilFerment(); + return Integer.toString(seconds); + } + + @Override + public Color getTextColor() + { + int seconds = timeUntilFerment(); + return seconds <= 3 ? Color.RED : Color.WHITE; + } + + @Override + public boolean cull() + { + int seconds = timeUntilFerment(); + return seconds <= 0; + } + + void reset() + { + fermentTime = Instant.now().plus(FERMENT_TIME); + } + + private int timeUntilFerment() + { + return (int) Duration.between(Instant.now(), fermentTime).getSeconds(); + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java index ae6418ee05..1384eb908c 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java @@ -29,14 +29,24 @@ 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.GraphicID; +import net.runelite.api.Player; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GraphicChanged; +import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import static org.mockito.Matchers.any; import org.mockito.Mock; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) @@ -49,13 +59,24 @@ public class CookingPluginTest "You cook the karambwan. It looks delicious.", "You roast a lobster.", "You cook a bass.", - "You squeeze the grapes into the jug. The wine begins to ferment.", "You successfully bake a tasty garden pie." }; @Inject CookingPlugin cookingPlugin; + @Mock + @Bind + Client client; + + @Mock + @Bind + InfoBoxManager infoBoxManager; + + @Mock + @Bind + ItemManager itemManager; + @Mock @Bind CookingConfig config; @@ -87,4 +108,20 @@ public class CookingPluginTest assertNotNull(cookingSession); assertEquals(COOKING_MESSAGES.length, cookingSession.getCookAmount()); } + + @Test + public void testOnGraphicChanged() + { + Player player = mock(Player.class); + when(player.getGraphic()).thenReturn(GraphicID.WINE_MAKE); + + when(config.fermentTimer()).thenReturn(true); + when(client.getLocalPlayer()).thenReturn(player); + + GraphicChanged graphicChanged = new GraphicChanged(); + graphicChanged.setActor(player); + cookingPlugin.onGraphicChanged(graphicChanged); + + verify(infoBoxManager).addInfoBox(any(FermentTimer.class)); + } } \ No newline at end of file From 4b42c0ca85c00760b32c5d5ea959c4e184279c43 Mon Sep 17 00:00:00 2001 From: xDemoN Date: Fri, 31 May 2019 11:21:38 -0400 Subject: [PATCH 06/30] Fix numulite buy limit in GE plugin (#8962) --- .../net/runelite/client/plugins/grandexchange/ge_limits.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/ge_limits.json b/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/ge_limits.json index 94bcc83a44..37072ae9b1 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/ge_limits.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/ge_limits.json @@ -3314,7 +3314,7 @@ "21521": 250, "21543": 13000, "21545": 13000, - "21555": 18000, + "21555": 30000, "21622": 13000, "21634": 8, "21637": 5, From 417e48fc7e99bbadf33ab3e6276afbd13e6c43b9 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 31 May 2019 14:57:19 -0400 Subject: [PATCH 07/30] mixins: fix game object events to not fire for actors, projectiles, and graphic objects The client adds and removes these temporary objects each frame, and was firing multiple despawn events each frame. --- .../java/net/runelite/mixins/RSTileMixin.java | 93 ++++++++++++------- 1 file changed, 60 insertions(+), 33 deletions(-) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java index b186ff454a..093fa17d88 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java @@ -26,12 +26,10 @@ package net.runelite.mixins; import java.util.ArrayList; import java.util.List; -import net.runelite.api.Actor; import net.runelite.api.CollisionData; import net.runelite.api.CollisionDataFlag; import net.runelite.api.Constants; import net.runelite.api.DecorativeObject; -import net.runelite.api.GameObject; import net.runelite.api.GroundObject; import net.runelite.api.Item; import net.runelite.api.ItemLayer; @@ -59,13 +57,18 @@ import net.runelite.api.mixins.FieldHook; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Shadow; +import net.runelite.rs.api.RSActor; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSDeque; import net.runelite.rs.api.RSGameObject; +import net.runelite.rs.api.RSGraphicsObject; import net.runelite.rs.api.RSItem; import net.runelite.rs.api.RSItemLayer; import net.runelite.rs.api.RSNode; +import net.runelite.rs.api.RSProjectile; +import net.runelite.rs.api.RSRenderable; import net.runelite.rs.api.RSTile; +import org.slf4j.Logger; @Mixin(RSTile.class) public abstract class RSTileMixin implements RSTile @@ -73,9 +76,6 @@ public abstract class RSTileMixin implements RSTile @Shadow("clientInstance") private static RSClient client; - @Inject - private static GameObject lastGameObject; - @Inject private static RSDeque[][][] lastGroundItems = new RSDeque[Constants.MAX_Z][Constants.SCENE_SIZE][Constants.SCENE_SIZE]; @@ -89,7 +89,7 @@ public abstract class RSTileMixin implements RSTile private GroundObject previousGroundObject; @Inject - private GameObject[] previousGameObjects; + private RSGameObject[] previousGameObjects; @Inject @Override @@ -222,55 +222,82 @@ public abstract class RSTileMixin implements RSTile if (previousGameObjects == null) { - previousGameObjects = new GameObject[5]; + previousGameObjects = new RSGameObject[5]; } // Previous game object - GameObject previous = previousGameObjects[idx]; + RSGameObject previous = previousGameObjects[idx]; // GameObject that was changed. RSGameObject current = (RSGameObject) getGameObjects()[idx]; - // Last game object - GameObject last = lastGameObject; - - // Update last game object - lastGameObject = current; - // Update previous object to current previousGameObjects[idx] = current; // Duplicate event, return - if (current != null && current.equals(last)) + if (current == previous) { return; } - // Characters seem to generate a constant stream of new GameObjects - if (current == null || !(current.getRenderable() instanceof Actor)) + // actors, projectiles, and graphics objects are added and removed from the scene each frame as GameObjects, + // so ignore them. + boolean currentInvalid = false, prevInvalid = false; + if (current != null) { - if (current == null && previous != null) + RSRenderable renderable = current.getRenderable(); + currentInvalid = renderable instanceof RSActor || renderable instanceof RSProjectile || renderable instanceof RSGraphicsObject; + } + + if (previous != null) + { + RSRenderable renderable = previous.getRenderable(); + prevInvalid = renderable instanceof RSActor || renderable instanceof RSProjectile || renderable instanceof RSGraphicsObject; + } + + Logger logger = client.getLogger(); + if (current == null) + { + if (prevInvalid) { - GameObjectDespawned gameObjectDespawned = new GameObjectDespawned(); - gameObjectDespawned.setTile(this); - gameObjectDespawned.setGameObject(previous); - client.getCallbacks().post(gameObjectDespawned); + return; } - else if (current != null && previous == null) + + logger.trace("Game object despawn: {}", previous.getId()); + + GameObjectDespawned gameObjectDespawned = new GameObjectDespawned(); + gameObjectDespawned.setTile(this); + gameObjectDespawned.setGameObject(previous); + client.getCallbacks().post(gameObjectDespawned); + } + else if (previous == null) + { + if (currentInvalid) { - GameObjectSpawned gameObjectSpawned = new GameObjectSpawned(); - gameObjectSpawned.setTile(this); - gameObjectSpawned.setGameObject(current); - client.getCallbacks().post(gameObjectSpawned); + return; } - else if (current != null && previous != null) + + logger.trace("Game object spawn: {}", current.getId()); + + GameObjectSpawned gameObjectSpawned = new GameObjectSpawned(); + gameObjectSpawned.setTile(this); + gameObjectSpawned.setGameObject(current); + client.getCallbacks().post(gameObjectSpawned); + } + else + { + if (currentInvalid && prevInvalid) { - GameObjectChanged gameObjectsChanged = new GameObjectChanged(); - gameObjectsChanged.setTile(this); - gameObjectsChanged.setPrevious(previous); - gameObjectsChanged.setGameObject(current); - client.getCallbacks().post(gameObjectsChanged); + return; } + + logger.trace("Game object change: {} -> {}", previous.getId(), current.getId()); + + GameObjectChanged gameObjectsChanged = new GameObjectChanged(); + gameObjectsChanged.setTile(this); + gameObjectsChanged.setPrevious(previous); + gameObjectsChanged.setGameObject(current); + client.getCallbacks().post(gameObjectsChanged); } } From aeaa2850ee129187f3f2d0767bc241fdd81c69c4 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 31 May 2019 18:02:52 -0400 Subject: [PATCH 08/30] client: add mining plugin Shows progress indicators for respawn times on all rocks that can be mined. Co-authored-by: Barragek0 --- .../client/plugins/mining/MiningOverlay.java | 96 ++++++++++ .../client/plugins/mining/MiningPlugin.java | 168 ++++++++++++++++++ .../runelite/client/plugins/mining/Rock.java | 129 ++++++++++++++ .../client/plugins/mining/RockRespawn.java | 40 +++++ 4 files changed, 433 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/RockRespawn.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java new file mode 100644 index 0000000000..72ada8814e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.mining; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.time.Instant; +import java.util.Iterator; +import java.util.List; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +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.components.ProgressPieComponent; + +class MiningOverlay extends Overlay +{ + private final Client client; + private final MiningPlugin plugin; + + @Inject + private MiningOverlay(Client client, MiningPlugin plugin) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + this.plugin = plugin; + this.client = client; + } + + @Override + public Dimension render(Graphics2D graphics) + { + List respawns = plugin.getRespawns(); + if (respawns.isEmpty()) + { + return null; + } + + Instant now = Instant.now(); + for (Iterator it = respawns.iterator(); it.hasNext();) + { + RockRespawn rockRespawn = it.next(); + float percent = (now.toEpochMilli() - rockRespawn.getStartTime().toEpochMilli()) / (float) rockRespawn.getRespawnTime(); + WorldPoint worldPoint = rockRespawn.getWorldPoint(); + LocalPoint loc = LocalPoint.fromWorld(client, worldPoint); + if (loc == null || percent > 1.0f) + { + it.remove(); + continue; + } + + Point point = Perspective.localToCanvas(client, loc, client.getPlane()); + if (point == null) + { + it.remove(); + continue; + } + + ProgressPieComponent ppc = new ProgressPieComponent(); + ppc.setBorderColor(Color.ORANGE); + ppc.setFill(Color.YELLOW); + ppc.setPosition(point); + ppc.setProgress(percent); + ppc.render(graphics); + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java new file mode 100644 index 0000000000..7d2a60fb57 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.mining; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameObject; +import net.runelite.api.GameState; +import static net.runelite.api.ObjectID.DEPLETED_VEIN_26665; +import static net.runelite.api.ObjectID.DEPLETED_VEIN_26666; +import static net.runelite.api.ObjectID.DEPLETED_VEIN_26667; +import static net.runelite.api.ObjectID.DEPLETED_VEIN_26668; +import static net.runelite.api.ObjectID.EMPTY_WALL; +import net.runelite.api.WallObject; +import net.runelite.api.events.GameObjectDespawned; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.WallObjectSpawned; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +@Slf4j +@PluginDescriptor( + name = "Mining", + description = "Show ore respawn timers", + tags = {"overlay", "skilling", "timers"}, + enabledByDefault = false +) +public class MiningPlugin extends Plugin +{ + private static final int ROCK_DISTANCE = 14; + private static final int MINING_GUILD_REGION = 12183; + + @Inject + private Client client; + + @Inject + private OverlayManager overlayManager; + + @Inject + private MiningOverlay overlay; + + @Getter(AccessLevel.PACKAGE) + private final List respawns = new ArrayList<>(); + private boolean recentlyLoggedIn; + + @Override + protected void startUp() + { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + respawns.clear(); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + switch (event.getGameState()) + { + case LOADING: + case HOPPING: + respawns.clear(); + break; + case LOGGED_IN: + // After login rocks that are depleted will be changed, + // so wait for the next game tick before watching for + // rocks to deplete + recentlyLoggedIn = true; + break; + } + } + + @Subscribe + public void onGameTick(GameTick gameTick) + { + recentlyLoggedIn = false; + } + + @Subscribe + public void onGameObjectDespawned(GameObjectDespawned event) + { + if (client.getGameState() != GameState.LOGGED_IN || recentlyLoggedIn) + { + return; + } + + final GameObject object = event.getGameObject(); + + Rock rock = Rock.getRock(object.getId()); + if (rock != null) + { + RockRespawn rockRespawn = new RockRespawn(rock, object.getWorldLocation(), Instant.now(), (int) rock.getRespawnTime(inMiningGuild()).toMillis()); + respawns.add(rockRespawn); + } + } + + @Subscribe + public void onWallObjectSpawned(WallObjectSpawned event) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + final WallObject object = event.getWallObject(); + + switch (object.getId()) + { + case EMPTY_WALL: + { + Rock rock = Rock.AMETHYST; + RockRespawn rockRespawn = new RockRespawn(rock, object.getWorldLocation(), Instant.now(), (int) rock.getRespawnTime(inMiningGuild()).toMillis()); + respawns.add(rockRespawn); + break; + } + case DEPLETED_VEIN_26665: // Depleted motherlode vein + case DEPLETED_VEIN_26666: // Depleted motherlode vein + case DEPLETED_VEIN_26667: // Depleted motherlode vein + case DEPLETED_VEIN_26668: // Depleted motherlode vein + { + Rock rock = Rock.ORE_VEIN; + RockRespawn rockRespawn = new RockRespawn(rock, object.getWorldLocation(), Instant.now(), (int) rock.getRespawnTime(inMiningGuild()).toMillis()); + respawns.add(rockRespawn); + break; + } + } + } + + private boolean inMiningGuild() + { + return client.getLocalPlayer().getWorldLocation().getRegionID() == MINING_GUILD_REGION; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java new file mode 100644 index 0000000000..ce0d78308e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.mining; + +import com.google.common.collect.ImmutableMap; +import java.time.Duration; +import java.util.Map; +import static net.runelite.api.ObjectID.ROCKS_11161; +import static net.runelite.api.ObjectID.ROCKS_11360; +import static net.runelite.api.ObjectID.ROCKS_11361; +import static net.runelite.api.ObjectID.ROCKS_11364; +import static net.runelite.api.ObjectID.ROCKS_11365; +import static net.runelite.api.ObjectID.ROCKS_11366; +import static net.runelite.api.ObjectID.ROCKS_11367; +import static net.runelite.api.ObjectID.ROCKS_11369; +import static net.runelite.api.ObjectID.ROCKS_11370; +import static net.runelite.api.ObjectID.ROCKS_11371; +import static net.runelite.api.ObjectID.ROCKS_11372; +import static net.runelite.api.ObjectID.ROCKS_11373; +import static net.runelite.api.ObjectID.ROCKS_11374; +import static net.runelite.api.ObjectID.ROCKS_11375; +import static net.runelite.api.ObjectID.ROCKS_11376; +import static net.runelite.api.ObjectID.ROCKS_11377; + +enum Rock +{ + TIN(Duration.ofMillis(2300), ROCKS_11360, ROCKS_11361), + COPPER(Duration.ofMillis(2200), ROCKS_11161), + IRON(Duration.ofMillis(5300), ROCKS_11364, ROCKS_11365) + { + @Override + Duration getRespawnTime(boolean inMiningGuild) + { + return inMiningGuild ? Duration.ofMillis(2200) : super.respawnTime; + } + }, + COAL(Duration.ofSeconds(40), ROCKS_11366, ROCKS_11367) + { + @Override + Duration getRespawnTime(boolean inMiningGuild) + { + return inMiningGuild ? Duration.ofMillis(14_500) : super.respawnTime; + } + }, + SILVER(Duration.ofMinutes(1), ROCKS_11369), + GOLD(Duration.ofMinutes(1), ROCKS_11370, ROCKS_11371), + MITHRIL(Duration.ofMinutes(2), ROCKS_11372, ROCKS_11373) + { + @Override + Duration getRespawnTime(boolean inMiningGuild) + { + return inMiningGuild ? Duration.ofMinutes(1) : super.respawnTime; + } + }, + ADAMANTITE(Duration.ofMinutes(4), ROCKS_11374, ROCKS_11375) + { + @Override + Duration getRespawnTime(boolean inMiningGuild) + { + return inMiningGuild ? Duration.ofMinutes(2) : super.respawnTime; + } + }, + RUNITE(Duration.ofMinutes(12), ROCKS_11376, ROCKS_11377) + { + @Override + Duration getRespawnTime(boolean inMiningGuild) + { + return inMiningGuild ? Duration.ofMinutes(6) : super.respawnTime; + } + }, + ORE_VEIN(Duration.ofSeconds(108)), + AMETHYST(Duration.ofSeconds(75)); + + private static final Map ROCKS; + + static + { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (Rock rock : values()) + { + for (int id : rock.ids) + { + builder.put(id, rock); + } + } + ROCKS = builder.build(); + } + + private final Duration respawnTime; + private final int[] ids; + + Rock(Duration respawnTime, int... ids) + { + this.respawnTime = respawnTime; + this.ids = ids; + } + + Duration getRespawnTime(boolean inMiningGuild) + { + return respawnTime; + } + + static Rock getRock(int id) + { + return ROCKS.get(id); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/RockRespawn.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/RockRespawn.java new file mode 100644 index 0000000000..733bae4bca --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/RockRespawn.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.mining; + +import java.time.Instant; +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.runelite.api.coords.WorldPoint; + +@AllArgsConstructor +@Getter +class RockRespawn +{ + private final Rock rock; + private final WorldPoint worldPoint; + private final Instant startTime; + private final int respawnTime; +} From 82711a6d3551f4ad516137ec4699964389ab6c09 Mon Sep 17 00:00:00 2001 From: xDemoN Date: Sat, 1 Jun 2019 05:07:58 -0400 Subject: [PATCH 09/30] Cluescrolls: Swap STASH Units for Exam Centre Emote Clues (#8963) --- .../runelite/client/plugins/cluescrolls/clues/EmoteClue.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java index d4fd2ce0ee..9723e3e58b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java @@ -97,7 +97,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu new EmoteClue("Cheer in the Ogre Pen in the Training Camp. Show you are angry before you talk to me. Equip a green dragonhide body and chaps and a steel square shield.", OGRE_CAGE_IN_KING_LATHAS_TRAINING_CAMP, new WorldPoint(2527, 3375, 0), CHEER, ANGRY, item(GREEN_DHIDE_BODY), item(GREEN_DHIDE_CHAPS), item(STEEL_SQ_SHIELD)), new EmoteClue("Cheer in the Entrana church. Beware of double agents! Equip a full set of black dragonhide armour.", ENTRANA_CHAPEL, new WorldPoint(2852, 3349, 0), CHEER, item(BLACK_DHIDE_VAMB), item(BLACK_DHIDE_CHAPS), item(BLACK_DHIDE_BODY)), new EmoteClue("Cheer for the monks at Port Sarim. Equip a coif, steel plateskirt and a sapphire necklace.", NEAR_THE_ENTRANA_FERRY_IN_PORT_SARIM, new WorldPoint(3047, 3237, 0), CHEER, item(COIF), item(STEEL_PLATESKIRT), item(SAPPHIRE_NECKLACE)), - new EmoteClue("Clap in the main exam room in the Exam Centre. Equip a white apron, green gnome boots and leather gloves.", INSIDE_THE_DIGSITE_EXAM_CENTRE, new WorldPoint(3361, 3339, 0), CLAP, item(WHITE_APRON), item(GREEN_BOOTS), item(LEATHER_GLOVES)), + new EmoteClue("Clap in the main exam room in the Exam Centre. Equip a white apron, green gnome boots and leather gloves.", OUTSIDE_THE_DIGSITE_EXAM_CENTRE, new WorldPoint(3361, 3339, 0), CLAP, item(WHITE_APRON), item(GREEN_BOOTS), item(LEATHER_GLOVES)), new EmoteClue("Clap on the causeway to the Wizards' Tower. Equip an iron medium helmet, emerald ring and a white apron.", ON_THE_BRIDGE_TO_THE_MISTHALIN_WIZARDS_TOWER, new WorldPoint(3113, 3196, 0), CLAP, item(IRON_MED_HELM), item(EMERALD_RING), item(WHITE_APRON)), new EmoteClue("Clap on the top level of the mill, north of East Ardougne. Equip a blue gnome robe top, HAM robe bottom and an unenchanted tiara.", UPSTAIRS_IN_THE_ARDOUGNE_WINDMILL, new WorldPoint(2635, 3385, 3), CLAP, item(BLUE_ROBE_TOP), item(HAM_ROBE), item(TIARA)), new EmoteClue("Clap in Seers court house. Spin before you talk to me. Equip an adamant halberd, blue mystic robe bottom and a diamond ring.", OUTSIDE_THE_SEERS_VILLAGE_COURTHOUSE, new WorldPoint(2735, 3469, 0), CLAP, SPIN, item(ADAMANT_HALBERD), item(MYSTIC_ROBE_BOTTOM), item(DIAMOND_RING)), @@ -118,7 +118,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu new EmoteClue("Dance at the entrance to the Grand Exchange. Equip a pink skirt, pink robe top and a body tiara.", SOUTH_OF_THE_GRAND_EXCHANGE, new WorldPoint(3165, 3467, 0), DANCE, item(PINK_SKIRT), item(PINK_ROBE_TOP), item(BODY_TIARA)), new EmoteClue("Goblin Salute in the Goblin Village. Beware of double agents! Equip a bandos godsword, a bandos cloak and a bandos platebody.", OUTSIDE_MUDKNUCKLES_HUT, new WorldPoint(2956, 3505, 0), GOBLIN_SALUTE, item(BANDOS_PLATEBODY), item(BANDOS_CLOAK), item(BANDOS_GODSWORD)), new EmoteClue("Headbang in the mine north of Al Kharid. Equip a desert shirt, leather gloves and leather boots.", AL_KHARID_SCORPION_MINE, new WorldPoint(3299, 3289, 0), HEADBANG, item(DESERT_SHIRT), item(LEATHER_GLOVES), item(LEATHER_BOOTS)), - new EmoteClue("Headbang at the exam center. Beware of double agents! Equip a mystic fire staff, a diamond bracelet and rune boots.", OUTSIDE_THE_DIGSITE_EXAM_CENTRE, new WorldPoint(3362, 3340, 0), HEADBANG, item(MYSTIC_FIRE_STAFF), item(DIAMOND_BRACELET), item(RUNE_BOOTS)), + new EmoteClue("Headbang at the exam center. Beware of double agents! Equip a mystic fire staff, a diamond bracelet and rune boots.", INSIDE_THE_DIGSITE_EXAM_CENTRE, new WorldPoint(3362, 3340, 0), HEADBANG, item(MYSTIC_FIRE_STAFF), item(DIAMOND_BRACELET), item(RUNE_BOOTS)), new EmoteClue("Headbang at the top of Slayer Tower. Equip a seercull, a combat bracelet and helm of Neitiznot.", OUTSIDE_THE_SLAYER_TOWER_GARGOYLE_ROOM, new WorldPoint(3421, 3537, 2), HEADBANG, item(SEERCULL), range("Combat bracelet", COMBAT_BRACELET4, COMBAT_BRACELET), item(HELM_OF_NEITIZNOT)), new EmoteClue("Dance a jig by the entrance to the Fishing Guild. Equip an emerald ring, a sapphire amulet, and a bronze chain body.", OUTSIDE_THE_FISHING_GUILD, new WorldPoint(2610, 3391, 0), JIG, item(EMERALD_RING), item(SAPPHIRE_AMULET), item(BRONZE_CHAINBODY)), new EmoteClue("Dance a jig under Shantay's Awning. Bow before you talk to me. Equip a pointed blue snail helmet, an air staff and a bronze square shield.", SHANTAY_PASS, new WorldPoint(3304, 3124, 0), JIG, BOW, any("Bruise blue snelm (pointed)", item(BRUISE_BLUE_SNELM_3343)), item(STAFF_OF_AIR), item(BRONZE_SQ_SHIELD)), From 531546e3a0e12c32031ac8cb5c5768838ae445e6 Mon Sep 17 00:00:00 2001 From: William Collishaw Date: Sat, 1 Jun 2019 13:19:15 -0600 Subject: [PATCH 10/30] Remove redundant subString endindex .length() calls --- .../src/main/java/net/runelite/cache/fs/flat/FlatStorage.java | 4 ++-- .../java/net/runelite/client/plugins/runepouch/Runes.java | 2 +- .../client/ui/overlay/components/TooltipComponent.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java b/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java index fdcdadeb75..8c5d7e77a7 100644 --- a/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java +++ b/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java @@ -116,7 +116,7 @@ public class FlatStorage implements Storage { int lidx = line.indexOf('='); String key = line.substring(0, lidx); - String value = line.substring(lidx + 1, line.length()); + String value = line.substring(lidx + 1); if ("file".equals(key)) { @@ -128,7 +128,7 @@ public class FlatStorage implements Storage int vidx = value.indexOf('='); FileData fd = new FileData(); fd.setId(Integer.parseInt(value.substring(0, vidx))); - fd.setNameHash(Integer.parseInt(value.substring(vidx + 1, value.length()))); + fd.setNameHash(Integer.parseInt(value.substring(vidx + 1))); fileData.add(fd); continue; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/Runes.java b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/Runes.java index b5aebe9bf6..3031aa7b97 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/Runes.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/Runes.java @@ -111,7 +111,7 @@ public enum Runes public String getName() { String name = this.name(); - name = name.substring(0, 1) + name.substring(1, name.length()).toLowerCase(); + name = name.substring(0, 1) + name.substring(1).toLowerCase(); return name; } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java index c7c5381b86..4d606b40ca 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java @@ -154,7 +154,7 @@ public class TooltipComponent implements RenderableEntity // Draw trailing text (after last tag) final TextComponent textComponent = new TextComponent(); textComponent.setColor(nextColor); - textComponent.setText(line.substring(begin, line.length())); + textComponent.setText(line.substring(begin)); textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent)); textComponent.render(graphics); } @@ -194,7 +194,7 @@ public class TooltipComponent implements RenderableEntity } // Include trailing text (after last tag) - textWidth += metrics.stringWidth(line.substring(begin, line.length())); + textWidth += metrics.stringWidth(line.substring(begin)); return textWidth; } From f1c8f380d925062062bbbfbdd5ccc1eb43c233f8 Mon Sep 17 00:00:00 2001 From: William Collishaw Date: Sat, 1 Jun 2019 13:46:56 -0600 Subject: [PATCH 11/30] Replace redundant StringBuilder append String.subString with append CharSequence --- .../src/main/java/net/runelite/cache/updater/CacheUploader.java | 2 +- .../main/java/net/runelite/http/service/cache/CacheService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/CacheUploader.java b/cache-updater/src/main/java/net/runelite/cache/updater/CacheUploader.java index baad6971e0..ed685a9034 100644 --- a/cache-updater/src/main/java/net/runelite/cache/updater/CacheUploader.java +++ b/cache-updater/src/main/java/net/runelite/cache/updater/CacheUploader.java @@ -69,7 +69,7 @@ public class CacheUploader implements Runnable archive.setHash(hash); String path = new StringBuilder() - .append(hashStr.substring(0, 2)) + .append(hashStr, 0, 2) .append('/') .append(hashStr.substring(2)) .toString(); diff --git a/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java b/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java index e0fca4ac21..c0b767a68c 100644 --- a/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java +++ b/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java @@ -104,7 +104,7 @@ public class CacheService { String hashStr = BaseEncoding.base16().encode(archiveEntry.getHash()); String path = new StringBuilder() - .append(hashStr.substring(0, 2)) + .append(hashStr, 0, 2) .append('/') .append(hashStr.substring(2)) .toString(); From 35625f4bba3e63628cc794181339b67bb25d4c27 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jun 2019 19:28:54 -0400 Subject: [PATCH 12/30] ba: update to no longer use icons to determine role The recent game update removed icons. Instead use the interface to determine the player's role. Co-authored-by: jacoblairm --- .../BarbarianAssaultPlugin.java | 91 +++++++++---------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java index ba2069498b..4904233aa0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java @@ -31,13 +31,8 @@ import java.awt.Image; import javax.inject.Inject; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; -import net.runelite.api.EquipmentInventorySlot; -import net.runelite.api.InventoryID; -import net.runelite.api.Item; -import net.runelite.api.ItemID; import net.runelite.api.Varbits; import net.runelite.api.events.ChatMessage; -import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; @@ -115,13 +110,38 @@ public class BarbarianAssaultPlugin extends Plugin @Subscribe public void onWidgetLoaded(WidgetLoaded event) { - if (event.getGroupId() == WidgetID.BA_REWARD_GROUP_ID) + switch (event.getGroupId()) { - Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT); - - if (config.waveTimes() && rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null) + case WidgetID.BA_REWARD_GROUP_ID: { - announceTime("Game finished, duration: ", gameTime.getTime(false)); + Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT); + + if (config.waveTimes() && rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null) + { + announceTime("Game finished, duration: ", gameTime.getTime(false)); + } + + break; + } + case WidgetID.BA_ATTACKER_GROUP_ID: + { + setOverlayRound(Role.ATTACKER); + break; + } + case WidgetID.BA_DEFENDER_GROUP_ID: + { + setOverlayRound(Role.DEFENDER); + break; + } + case WidgetID.BA_HEALER_GROUP_ID: + { + setOverlayRound(Role.HEALER); + break; + } + case WidgetID.BA_COLLECTOR_GROUP_ID: + { + setOverlayRound(Role.COLLECTOR); + break; } } } @@ -146,44 +166,6 @@ public class BarbarianAssaultPlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(final ItemContainerChanged event) - { - if (event.getItemContainer() != client.getItemContainer(InventoryID.EQUIPMENT)) - { - return; - } - - if (overlay.getCurrentRound() != null) - { - return; - } - - final Item[] items = event.getItemContainer().getItems(); - - // Check that the local player is wearing enough items to be wearing a cape. - if (items == null || items.length <= EquipmentInventorySlot.CAPE.getSlotIdx()) - { - return; - } - - switch (items[EquipmentInventorySlot.CAPE.getSlotIdx()].getId()) - { - case ItemID.ATTACKER_ICON: - overlay.setCurrentRound(new Round(Role.ATTACKER)); - break; - case ItemID.COLLECTOR_ICON: - overlay.setCurrentRound(new Round(Role.COLLECTOR)); - break; - case ItemID.DEFENDER_ICON: - overlay.setCurrentRound(new Round(Role.DEFENDER)); - break; - case ItemID.HEALER_ICON: - overlay.setCurrentRound(new Round(Role.HEALER)); - break; - } - } - @Subscribe public void onVarbitChanged(VarbitChanged event) { @@ -205,6 +187,19 @@ public class BarbarianAssaultPlugin extends Plugin inGameBit = inGame; } + private void setOverlayRound(Role role) + { + // Prevent changing roles when a role is already set, as widgets can be + // loaded multiple times in game from eg. opening and closing the horn + // of glory. + if (overlay.getCurrentRound() != null) + { + return; + } + + overlay.setCurrentRound(new Round(role)); + } + private void announceTime(String preText, String time) { final String chatMessage = new ChatMessageBuilder() From 527c7d517260dd741bbb8f068b55a521a48e06ca Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jun 2019 19:29:08 -0400 Subject: [PATCH 13/30] ba: fix wave timer announce from exiting a tutorial Co-authored-by: jacoblairm --- .../plugins/barbarianassault/BarbarianAssaultPlugin.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java index 4904233aa0..10334b7d42 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java @@ -177,7 +177,10 @@ public class BarbarianAssaultPlugin extends Plugin { overlay.setCurrentRound(null); - if (config.waveTimes() && gameTime != null) + // Use an instance check to determine if this is exiting a game or a tutorial + // After exiting tutorials there is a small delay before changing IN_GAME_BA back to + // 0 whereas when in a real wave it changes while still in the instance. + if (config.waveTimes() && gameTime != null && client.isInInstancedRegion()) { announceTime("Wave " + currentWave + " duration: ", gameTime.getTime(true)); } From a4bfef647e4726e245771c59989c608418844df8 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jun 2019 19:28:08 -0400 Subject: [PATCH 14/30] ba: null game time after the game has been finished --- .../client/plugins/barbarianassault/BarbarianAssaultPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java index 10334b7d42..448efc3d15 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java @@ -119,6 +119,7 @@ public class BarbarianAssaultPlugin extends Plugin if (config.waveTimes() && rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null) { announceTime("Game finished, duration: ", gameTime.getTime(false)); + gameTime = null; } break; From c020717346f32ffa1695ad7aa412f32b6b01606f Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jun 2019 19:59:38 -0400 Subject: [PATCH 15/30] music plugin: delete all child widgets before adding buttons --- .../net/runelite/client/plugins/musiclist/MusicListPlugin.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musiclist/MusicListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/musiclist/MusicListPlugin.java index 61a40bd10e..737bddbcc1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/musiclist/MusicListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/musiclist/MusicListPlugin.java @@ -123,6 +123,8 @@ public class MusicListPlugin extends Plugin return; } + header.deleteAllChildren(); + //Creation of the search and toggle status buttons musicSearchButton = header.createChild(-1, WidgetType.GRAPHIC); musicSearchButton.setSpriteId(SpriteID.GE_SEARCH); From 4e357e121b2315704a8ab2f724f303c2226159d4 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jun 2019 20:00:03 -0400 Subject: [PATCH 16/30] quest plugin: delete all child widgets before adding buttons --- .../net/runelite/client/plugins/questlist/QuestListPlugin.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/questlist/QuestListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/questlist/QuestListPlugin.java index 0a18b8d2c9..62583460bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/questlist/QuestListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/questlist/QuestListPlugin.java @@ -134,6 +134,8 @@ public class QuestListPlugin extends Plugin Widget header = client.getWidget(WidgetInfo.QUESTLIST_BOX); if (header != null) { + header.deleteAllChildren(); + questSearchButton = header.createChild(-1, WidgetType.GRAPHIC); questSearchButton.setSpriteId(SpriteID.GE_SEARCH); questSearchButton.setOriginalWidth(18); From 706fdf5844d5a6b67c0a43c000cc16b689732479 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Sun, 2 Jun 2019 03:05:14 +0200 Subject: [PATCH 17/30] Expose loginIndex and otp fields from runescape client Signed-off-by: Tomas Slusny --- .../src/main/java/net/runelite/api/Client.java | 14 ++++++++++++++ .../main/java/net/runelite/rs/api/RSClient.java | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 213bda81cd..fc1e564c0a 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -151,6 +151,13 @@ public interface Client extends GameEngine */ void setPassword(String password); + /** + * Sets the 6 digit pin used for authenticator on login screen. + * + * @param otp one time password + */ + void setOtp(String otp); + /** * Gets currently selected login field. 0 is username, and 1 is password. * @@ -158,6 +165,13 @@ public interface Client extends GameEngine */ int getCurrentLoginField(); + /** + * Gets index of current login state. 2 is username/password form, 4 is authenticator form + * + * @return current login state index + */ + int getLoginIndex(); + /** * Gets the account type of the logged in player. * diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 838a7ea344..6381dd3f99 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -248,10 +248,18 @@ public interface RSClient extends RSGameEngine, Client @Override void setPassword(String password); + @Import("otp") + @Override + void setOtp(String otp); + @Import("currentLoginField") @Override int getCurrentLoginField(); + @Import("loginIndex") + @Override + int getLoginIndex(); + @Import("playerOptions") @Override String[] getPlayerOptions(); From e48a7e4a540daf8ef49e7c17b4f705434116ba8b Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Sun, 2 Jun 2019 03:07:32 +0200 Subject: [PATCH 18/30] Add LOGIN_SCREEN_AUTHENTICATOR game state Signed-off-by: Tomas Slusny --- runelite-api/src/main/java/net/runelite/api/GameState.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/GameState.java b/runelite-api/src/main/java/net/runelite/api/GameState.java index 0751fe0e71..5f9083f9ca 100644 --- a/runelite-api/src/main/java/net/runelite/api/GameState.java +++ b/runelite-api/src/main/java/net/runelite/api/GameState.java @@ -41,6 +41,10 @@ public enum GameState * The client is at the login screen. */ LOGIN_SCREEN(10), + /** + * The client is at the login screen entering authenticator code. + */ + LOGIN_SCREEN_AUTHENTICATOR(11), /** * There is a player logging in. */ From b3e02ac9b7677388a4c9127d7286ab8dd58605f2 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Sun, 2 Jun 2019 03:05:39 +0200 Subject: [PATCH 19/30] Add support for pasting authenticator code on login screen Signed-off-by: Tomas Slusny --- .../loginscreen/LoginScreenPlugin.java | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java index 4da52e1492..bda2e5cdf2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java @@ -54,6 +54,7 @@ public class LoginScreenPlugin extends Plugin implements KeyListener { private static final int MAX_USERNAME_LENGTH = 254; private static final int MAX_PASSWORD_LENGTH = 20; + private static final int MAX_PIN_LENGTH = 6; @Inject private Client client; @@ -163,7 +164,9 @@ public class LoginScreenPlugin extends Plugin implements KeyListener @Override public void keyPressed(KeyEvent e) { - if (!config.pasteEnabled() || client.getGameState() != GameState.LOGIN_SCREEN) + if (!config.pasteEnabled() || ( + client.getGameState() != GameState.LOGIN_SCREEN && + client.getGameState() != GameState.LOGIN_SCREEN_AUTHENTICATOR)) { return; } @@ -182,16 +185,27 @@ public class LoginScreenPlugin extends Plugin implements KeyListener .toString() .trim(); - // 0 is username, 1 is password - if (client.getCurrentLoginField() == 0) + switch (client.getLoginIndex()) { - // Truncate data to maximum username length if necessary - client.setUsername(data.substring(0, Math.min(data.length(), MAX_USERNAME_LENGTH))); - } - else - { - // Truncate data to maximum password length if necessary - client.setPassword(data.substring(0, Math.min(data.length(), MAX_PASSWORD_LENGTH))); + // Username/password form + case 2: + if (client.getCurrentLoginField() == 0) + { + // Truncate data to maximum username length if necessary + client.setUsername(data.substring(0, Math.min(data.length(), MAX_USERNAME_LENGTH))); + } + else + { + // Truncate data to maximum password length if necessary + client.setPassword(data.substring(0, Math.min(data.length(), MAX_PASSWORD_LENGTH))); + } + + break; + // Authenticator form + case 4: + // Truncate data to maximum OTP code length if necessary + client.setOtp(data.substring(0, Math.min(data.length(), MAX_PIN_LENGTH))); + break; } } catch (UnsupportedFlavorException | IOException ex) From 907dc37d404a5d9b5798db516565dc12982b9537 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jun 2019 21:49:29 -0400 Subject: [PATCH 20/30] wasd plugin: rename to keyremapping plugin Co-authored-by: Robert Alexander --- .../KeyRemappingConfig.java} | 14 +++++++------- .../KeyRemappingListener.java} | 8 ++++---- .../KeyRemappingPlugin.java} | 14 +++++++------- 3 files changed, 18 insertions(+), 18 deletions(-) rename runelite-client/src/main/java/net/runelite/client/plugins/{wasdcamera/WASDCameraConfig.java => keyremapping/KeyRemappingConfig.java} (90%) rename runelite-client/src/main/java/net/runelite/client/plugins/{wasdcamera/WASDCameraListener.java => keyremapping/KeyRemappingListener.java} (95%) rename runelite-client/src/main/java/net/runelite/client/plugins/{wasdcamera/WASDCameraPlugin.java => keyremapping/KeyRemappingPlugin.java} (94%) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java similarity index 90% rename from runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraConfig.java rename to runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java index e84b31a17d..558b416db5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java @@ -22,7 +22,7 @@ * (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.wasdcamera; +package net.runelite.client.plugins.keyremapping; import java.awt.event.KeyEvent; import net.runelite.client.config.Config; @@ -30,13 +30,13 @@ import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ModifierlessKeybind; -@ConfigGroup("wasdcamera") -public interface WASDCameraConfig extends Config +@ConfigGroup("keyremapping") +public interface KeyRemappingConfig extends Config { @ConfigItem( position = 1, keyName = "up", - name = "Up key", + name = "Camera Up key", description = "The key which will replace up." ) default ModifierlessKeybind up() @@ -47,7 +47,7 @@ public interface WASDCameraConfig extends Config @ConfigItem( position = 2, keyName = "down", - name = "Down key", + name = "Camera Down key", description = "The key which will replace down." ) default ModifierlessKeybind down() @@ -58,7 +58,7 @@ public interface WASDCameraConfig extends Config @ConfigItem( position = 3, keyName = "left", - name = "Left key", + name = "Camera Left key", description = "The key which will replace left." ) default ModifierlessKeybind left() @@ -69,7 +69,7 @@ public interface WASDCameraConfig extends Config @ConfigItem( position = 4, keyName = "right", - name = "Right key", + name = "Camera Right key", description = "The key which will replace right." ) default ModifierlessKeybind right() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java similarity index 95% rename from runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java rename to runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java index c8fa6e5119..34ebf26154 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java @@ -23,7 +23,7 @@ * (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.wasdcamera; +package net.runelite.client.plugins.keyremapping; import com.google.common.base.Strings; import java.awt.event.KeyEvent; @@ -37,13 +37,13 @@ import net.runelite.client.callback.ClientThread; import net.runelite.client.input.KeyListener; import net.runelite.client.input.MouseAdapter; -class WASDCameraListener extends MouseAdapter implements KeyListener +class KeyRemappingListener extends MouseAdapter implements KeyListener { @Inject - private WASDCameraPlugin plugin; + private KeyRemappingPlugin plugin; @Inject - private WASDCameraConfig config; + private KeyRemappingConfig config; @Inject private Client client; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java similarity index 94% rename from runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraPlugin.java rename to runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java index f975021369..41974f8006 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java @@ -23,7 +23,7 @@ * (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.wasdcamera; +package net.runelite.client.plugins.keyremapping; import com.google.inject.Provides; import java.awt.Color; @@ -50,12 +50,12 @@ import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil; @PluginDescriptor( - name = "WASD Camera", + name = "Key Remapping", description = "Allows use of WASD keys for camera movement with 'Press Enter to Chat'", - tags = {"enter", "chat"}, + tags = {"enter", "chat", "wasd", "camera"}, enabledByDefault = false ) -public class WASDCameraPlugin extends Plugin +public class KeyRemappingPlugin extends Plugin { private static final String PRESS_ENTER_TO_CHAT = "Press Enter to Chat..."; private static final String SCRIPT_EVENT_SET_CHATBOX_INPUT = "setChatboxInput"; @@ -71,7 +71,7 @@ public class WASDCameraPlugin extends Plugin private KeyManager keyManager; @Inject - private WASDCameraListener inputListener; + private KeyRemappingListener inputListener; @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) @@ -107,9 +107,9 @@ public class WASDCameraPlugin extends Plugin } @Provides - WASDCameraConfig getConfig(ConfigManager configManager) + KeyRemappingConfig getConfig(ConfigManager configManager) { - return configManager.getConfig(WASDCameraConfig.class); + return configManager.getConfig(KeyRemappingConfig.class); } boolean chatboxFocused() From 8e2fe91ec853a6bfece63416304ef61e083b24f0 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jun 2019 21:49:47 -0400 Subject: [PATCH 21/30] keyremapping plugin: add F-key remapping Co-authored-by: Robert Alexander --- .../keyremapping/KeyRemappingConfig.java | 28 ++- .../keyremapping/KeyRemappingListener.java | 224 ++++++++++++++---- .../keyremapping/KeyRemappingPlugin.java | 2 +- 3 files changed, 206 insertions(+), 48 deletions(-) mode change 100644 => 100755 runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java old mode 100644 new mode 100755 index 558b416db5..4774bc67e7 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingConfig.java @@ -35,6 +35,17 @@ public interface KeyRemappingConfig extends Config { @ConfigItem( position = 1, + keyName = "cameraRemap", + name = "Remap Camera", + description = "Configures whether the camera movement uses remapped keys" + ) + default boolean cameraRemap() + { + return true; + } + + @ConfigItem( + position = 2, keyName = "up", name = "Camera Up key", description = "The key which will replace up." @@ -45,7 +56,7 @@ public interface KeyRemappingConfig extends Config } @ConfigItem( - position = 2, + position = 3, keyName = "down", name = "Camera Down key", description = "The key which will replace down." @@ -56,7 +67,7 @@ public interface KeyRemappingConfig extends Config } @ConfigItem( - position = 3, + position = 4, keyName = "left", name = "Camera Left key", description = "The key which will replace left." @@ -67,7 +78,7 @@ public interface KeyRemappingConfig extends Config } @ConfigItem( - position = 4, + position = 5, keyName = "right", name = "Camera Right key", description = "The key which will replace right." @@ -76,4 +87,15 @@ public interface KeyRemappingConfig extends Config { return new ModifierlessKeybind(KeyEvent.VK_D, 0); } + + @ConfigItem( + position = 6, + keyName = "fkeyRemap", + name = "Remap F Keys", + description = "Configures whether F-Keys are Remapped to 1 (F1) through 0 (F10), '-' (F11), and '=' (F12)" + ) + default boolean fkeyRemap() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java index 34ebf26154..4c538e2cde 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java @@ -34,11 +34,26 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.VarClientStr; import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.Keybind; +import net.runelite.client.config.ModifierlessKeybind; import net.runelite.client.input.KeyListener; import net.runelite.client.input.MouseAdapter; class KeyRemappingListener extends MouseAdapter implements KeyListener { + private static final Keybind ONE = new ModifierlessKeybind(KeyEvent.VK_1, 0); + private static final Keybind TWO = new ModifierlessKeybind(KeyEvent.VK_2, 0); + private static final Keybind THREE = new ModifierlessKeybind(KeyEvent.VK_3, 0); + private static final Keybind FOUR = new ModifierlessKeybind(KeyEvent.VK_4, 0); + private static final Keybind FIVE = new ModifierlessKeybind(KeyEvent.VK_5, 0); + private static final Keybind SIX = new ModifierlessKeybind(KeyEvent.VK_6, 0); + private static final Keybind SEVEN = new ModifierlessKeybind(KeyEvent.VK_7, 0); + private static final Keybind EIGHT = new ModifierlessKeybind(KeyEvent.VK_8, 0); + private static final Keybind NINE = new ModifierlessKeybind(KeyEvent.VK_9, 0); + private static final Keybind ZERO = new ModifierlessKeybind(KeyEvent.VK_0, 0); + private static final Keybind MINUS = new ModifierlessKeybind(KeyEvent.VK_MINUS, 0); + private static final Keybind EQUALS = new ModifierlessKeybind(KeyEvent.VK_EQUALS, 0); + @Inject private KeyRemappingPlugin plugin; @@ -68,42 +83,108 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener if (!plugin.isTyping()) { - if (config.up().matches(e)) + if (config.cameraRemap()) { - modified.put(e.getKeyCode(), KeyEvent.VK_UP); - e.setKeyCode(KeyEvent.VK_UP); - } - else if (config.down().matches(e)) - { - modified.put(e.getKeyCode(), KeyEvent.VK_DOWN); - e.setKeyCode(KeyEvent.VK_DOWN); - } - else if (config.left().matches(e)) - { - modified.put(e.getKeyCode(), KeyEvent.VK_LEFT); - e.setKeyCode(KeyEvent.VK_LEFT); - } - else if (config.right().matches(e)) - { - modified.put(e.getKeyCode(), KeyEvent.VK_RIGHT); - e.setKeyCode(KeyEvent.VK_RIGHT); - } - else - { - switch (e.getKeyCode()) + if (config.up().matches(e)) { - case KeyEvent.VK_ENTER: - case KeyEvent.VK_SLASH: - case KeyEvent.VK_COLON: - // refocus chatbox - plugin.setTyping(true); - clientThread.invoke(() -> - { - plugin.unlockChat(); - }); - break; + modified.put(e.getKeyCode(), KeyEvent.VK_UP); + e.setKeyCode(KeyEvent.VK_UP); + } + else if (config.down().matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_DOWN); + e.setKeyCode(KeyEvent.VK_DOWN); + } + else if (config.left().matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_LEFT); + e.setKeyCode(KeyEvent.VK_LEFT); + } + else if (config.right().matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_RIGHT); + e.setKeyCode(KeyEvent.VK_RIGHT); } } + + if (config.fkeyRemap()) + { + if (ONE.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F1); + e.setKeyCode(KeyEvent.VK_F1); + } + else if (TWO.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F2); + e.setKeyCode(KeyEvent.VK_F2); + } + else if (THREE.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F3); + e.setKeyCode(KeyEvent.VK_F3); + } + else if (FOUR.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F4); + e.setKeyCode(KeyEvent.VK_F4); + } + else if (FIVE.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F5); + e.setKeyCode(KeyEvent.VK_F5); + } + else if (SIX.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F6); + e.setKeyCode(KeyEvent.VK_F6); + } + else if (SEVEN.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F7); + e.setKeyCode(KeyEvent.VK_F7); + } + else if (EIGHT.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F8); + e.setKeyCode(KeyEvent.VK_F8); + } + else if (NINE.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F9); + e.setKeyCode(KeyEvent.VK_F9); + } + else if (ZERO.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F10); + e.setKeyCode(KeyEvent.VK_F10); + } + else if (MINUS.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F11); + e.setKeyCode(KeyEvent.VK_F11); + } + else if (EQUALS.matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F12); + e.setKeyCode(KeyEvent.VK_F12); + } + } + + switch (e.getKeyCode()) + { + case KeyEvent.VK_ENTER: + case KeyEvent.VK_SLASH: + case KeyEvent.VK_COLON: + // refocus chatbox + plugin.setTyping(true); + clientThread.invoke(() -> + { + plugin.unlockChat(); + }); + break; + } + } else { @@ -146,21 +227,76 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener { modified.remove(e.getKeyCode()); - if (config.up().matches(e)) + if (config.cameraRemap()) { - e.setKeyCode(KeyEvent.VK_UP); + if (config.up().matches(e)) + { + e.setKeyCode(KeyEvent.VK_UP); + } + else if (config.down().matches(e)) + { + e.setKeyCode(KeyEvent.VK_DOWN); + } + else if (config.left().matches(e)) + { + e.setKeyCode(KeyEvent.VK_LEFT); + } + else if (config.right().matches(e)) + { + e.setKeyCode(KeyEvent.VK_RIGHT); + } } - else if (config.down().matches(e)) + + if (config.fkeyRemap()) { - e.setKeyCode(KeyEvent.VK_DOWN); - } - else if (config.left().matches(e)) - { - e.setKeyCode(KeyEvent.VK_LEFT); - } - else if (config.right().matches(e)) - { - e.setKeyCode(KeyEvent.VK_RIGHT); + if (ONE.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F1); + } + else if (TWO.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F2); + } + else if (THREE.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F3); + } + else if (FOUR.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F4); + } + else if (FIVE.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F5); + } + else if (SIX.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F6); + } + else if (SEVEN.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F7); + } + else if (EIGHT.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F8); + } + else if (NINE.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F9); + } + else if (ZERO.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F10); + } + else if (MINUS.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F11); + } + else if (EQUALS.matches(e)) + { + e.setKeyCode(KeyEvent.VK_F12); + } } } else diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java index 41974f8006..eb9e7ebc1a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java @@ -51,7 +51,7 @@ import net.runelite.client.util.ColorUtil; @PluginDescriptor( name = "Key Remapping", - description = "Allows use of WASD keys for camera movement with 'Press Enter to Chat'", + description = "Allows use of WASD keys for camera movement with 'Press Enter to Chat', and remapping number keys to F-keys", tags = {"enter", "chat", "wasd", "camera"}, enabledByDefault = false ) From f57abb7a7c09ec5504a8aa6a262c1045d52e3e2f Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jun 2019 21:44:33 -0400 Subject: [PATCH 22/30] keyremapping: fix keys getting stuck from map loading If a key is depressed when loading, the key press was not getting remapped, causing the camera to continiously spin. Change to only ignore key presses on the login screen. --- .../client/plugins/keyremapping/KeyRemappingListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java index 4c538e2cde..4545c78902 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java @@ -76,7 +76,7 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener @Override public void keyPressed(KeyEvent e) { - if (client.getGameState() != GameState.LOGGED_IN || !plugin.chatboxFocused()) + if (client.getGameState() == GameState.LOGIN_SCREEN || !plugin.chatboxFocused()) { return; } @@ -218,7 +218,7 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener @Override public void keyReleased(KeyEvent e) { - if (client.getGameState() != GameState.LOGGED_IN) + if (client.getGameState() == GameState.LOGIN_SCREEN) { return; } From f69c32f0465adb337664e3cfd08294ca04f1a777 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 1 Jun 2019 21:57:52 -0400 Subject: [PATCH 23/30] keyremappinig: replace some lambdas with method references --- .../plugins/keyremapping/KeyRemappingListener.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java index 4545c78902..89c88345fa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingListener.java @@ -178,10 +178,7 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener case KeyEvent.VK_COLON: // refocus chatbox plugin.setTyping(true); - clientThread.invoke(() -> - { - plugin.unlockChat(); - }); + clientThread.invoke(plugin::unlockChat); break; } @@ -192,10 +189,7 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener { case KeyEvent.VK_ENTER: plugin.setTyping(false); - clientThread.invoke(() -> - { - plugin.lockChat(); - }); + clientThread.invoke(plugin::lockChat); break; case KeyEvent.VK_ESCAPE: plugin.setTyping(false); @@ -209,7 +203,7 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener if (Strings.isNullOrEmpty(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT))) { plugin.setTyping(false); - clientThread.invoke(() -> plugin.lockChat()); + clientThread.invoke(plugin::lockChat); } } } From f3e910984e3465bcef323a6e43de74fa2610c1a5 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 2 Jun 2019 17:14:09 -0400 Subject: [PATCH 24/30] achievement diary: fix legends guild jewllery task The wording of the task changes depending on whether it is complete or not. So, add both variations. Closes #8986 --- .../achievementdiary/diaries/ArdougneDiaryRequirement.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java index 85adb4db7b..fbb7bbfa78 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java @@ -79,6 +79,10 @@ public class ArdougneDiaryRequirement extends GenericDiaryRequirement new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true)); // HARD + // When the task is completed "the Totem" changes to "Totem" - so we add + // both variations. + add("Recharge some Jewellery at the Totem in the Legends Guild.", + new QuestRequirement(Quest.LEGENDS_QUEST)); add("Recharge some Jewellery at Totem in the Legends Guild.", new QuestRequirement(Quest.LEGENDS_QUEST)); add("Enter the Magic Guild.", From 373fba0b5a1b3f09c598c10f6dc351384fe252ca Mon Sep 17 00:00:00 2001 From: Ron Young Date: Thu, 23 May 2019 11:34:00 -0500 Subject: [PATCH 25/30] mixins: correct widget item bounds location for if1 --- .../src/main/java/net/runelite/mixins/RSWidgetMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java index 1b4bda7fc6..3b8ab87c99 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java @@ -299,7 +299,7 @@ public abstract class RSWidgetMixin implements RSWidget int itemX = widgetCanvasLocation.getX() + ((ITEM_SLOT_SIZE + xPitch) * col); int itemY = widgetCanvasLocation.getY() + ((ITEM_SLOT_SIZE + yPitch) * row); - Rectangle bounds = new Rectangle(itemX - 1, itemY - 1, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE); + Rectangle bounds = new Rectangle(itemX, itemY, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE); return new WidgetItem(itemId - 1, itemQuantity, index, bounds, this); } From 4aea1dbc4999675f8c0feb9e81ee05a345381800 Mon Sep 17 00:00:00 2001 From: Ron Young Date: Thu, 23 May 2019 11:38:45 -0500 Subject: [PATCH 26/30] client: readjust widget item overlay positions for modified widget item bounds --- .../plugins/inventorytags/InventoryTagsOverlay.java | 2 +- .../client/plugins/itemcharges/ItemChargeOverlay.java | 2 +- .../itemidentification/ItemIdentificationOverlay.java | 2 +- .../client/plugins/runepouch/RunepouchOverlay.java | 10 +++++----- .../runelite/client/plugins/slayer/SlayerOverlay.java | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java index 14fe723a71..de7d786eb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java @@ -58,7 +58,7 @@ public class InventoryTagsOverlay extends WidgetItemOverlay { Rectangle bounds = itemWidget.getCanvasBounds(); final BufferedImage outline = itemManager.getItemOutline(itemId, itemWidget.getQuantity(), color); - graphics.drawImage(outline, (int) bounds.getX() + 1, (int) bounds.getY() + 1, null); + graphics.drawImage(outline, (int) bounds.getX(), (int) bounds.getY(), null); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java index 2c8220e1a6..fba313e25d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java @@ -119,7 +119,7 @@ class ItemChargeOverlay extends WidgetItemOverlay final Rectangle bounds = itemWidget.getCanvasBounds(); final TextComponent textComponent = new TextComponent(); - textComponent.setPosition(new Point(bounds.x, bounds.y + 16)); + textComponent.setPosition(new Point(bounds.x - 1, bounds.y + 15)); textComponent.setText(charges < 0 ? "?" : String.valueOf(charges)); textComponent.setColor(itemChargePlugin.getColor(charges)); textComponent.render(graphics); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java index badd46bdd3..ee3dc7deb3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java @@ -87,7 +87,7 @@ class ItemIdentificationOverlay extends WidgetItemOverlay private void renderText(Graphics2D graphics, Rectangle bounds, ItemIdentification iden) { final TextComponent textComponent = new TextComponent(); - textComponent.setPosition(new Point(bounds.x, bounds.y + bounds.height)); + textComponent.setPosition(new Point(bounds.x - 1, bounds.y + bounds.height - 1)); textComponent.setColor(config.textColor()); switch (config.identificationType()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java index a7e2fd86d7..91b4e9c6fa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java @@ -118,13 +118,13 @@ public class RunepouchOverlay extends WidgetItemOverlay } graphics.setColor(Color.black); - graphics.drawString("" + formatNumber(amount), location.getX() + (config.showIcons() ? 13 : 6), - location.getY() + 14 + (graphics.getFontMetrics().getHeight() - 1) * i); - - graphics.setColor(config.fontColor()); graphics.drawString("" + formatNumber(amount), location.getX() + (config.showIcons() ? 12 : 5), location.getY() + 13 + (graphics.getFontMetrics().getHeight() - 1) * i); + graphics.setColor(config.fontColor()); + graphics.drawString("" + formatNumber(amount), location.getX() + (config.showIcons() ? 11 : 4), + location.getY() + 12 + (graphics.getFontMetrics().getHeight() - 1) * i); + if (!config.showIcons()) { continue; @@ -134,7 +134,7 @@ public class RunepouchOverlay extends WidgetItemOverlay if (image != null) { OverlayUtil.renderImageLocation(graphics, - new Point(location.getX(), location.getY() + graphics.getFontMetrics().getHeight() * i), + new Point(location.getX() - 1, location.getY() + graphics.getFontMetrics().getHeight() * i - 1), image); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java index 97a191d608..09da9f7ac4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java @@ -132,7 +132,7 @@ class SlayerOverlay extends WidgetItemOverlay } // Draw the counter in the bottom left for equipment, and top left for jewelry - textComponent.setPosition(new Point(bounds.x, bounds.y + (SLAYER_JEWELRY.contains(itemId) + textComponent.setPosition(new Point(bounds.x - 1, bounds.y - 1 + (SLAYER_JEWELRY.contains(itemId) ? bounds.height : graphics.getFontMetrics().getHeight()))); textComponent.render(graphics); From a96260056cacc7060371f4b617dcd1881557528c Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Sun, 2 Jun 2019 18:59:28 -0700 Subject: [PATCH 27/30] HotColdLocation: Replace nbsp with normal spaces The nbsp characters in this file seemed to be placed randomly, and not for the intended purpose of preserving spaces across line breaks. --- .../clues/hotcold/HotColdLocation.java | 204 +++++++++--------- 1 file changed, 102 insertions(+), 102 deletions(-) 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 cd700835a0..45fe44a15f 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 @@ -51,127 +51,127 @@ 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."), - ASGARNIA_JATIX(new WorldPoint(2914, 3429, 0), ASGARNIA, "East of Jatix's Herblore Shop in Taverley."), - ASGARNIA_BARB(new WorldPoint(3036, 3439, 0), ASGARNIA, "West of Barbarian Village."), - ASGARNIA_MIAZRQA(new WorldPoint(2973, 3489, 0), ASGARNIA, "North of Miazrqa's tower, outside Goblin Village."), - ASGARNIA_COW(new WorldPoint(3033, 3308, 0), ASGARNIA, "In the cow pen north of Sarah's Farming Shop."), - ASGARNIA_PARTY_ROOM(new WorldPoint(3026, 3363, 0), ASGARNIA, "Outside the Falador Party Room."), - ASGARNIA_CRAFT_GUILD(new WorldPoint(2917, 3295, 0), ASGARNIA, "Outside the Crafting Guild cow pen."), - ASGARNIA_RIMMINGTON(new WorldPoint(2978, 3241, 0), ASGARNIA, "In the centre of the Rimmington mine."), + ASGARNIA_WARRIORS(new WorldPoint(2860, 3562, 0), ASGARNIA, "North of the Warriors' Guild in Burthorpe."), + ASGARNIA_JATIX(new WorldPoint(2914, 3429, 0), ASGARNIA, "East of Jatix's Herblore Shop in Taverley."), + ASGARNIA_BARB(new WorldPoint(3036, 3439, 0), ASGARNIA, "West of Barbarian Village."), + ASGARNIA_MIAZRQA(new WorldPoint(2973, 3489, 0), ASGARNIA, "North of Miazrqa's tower, outside Goblin Village."), + ASGARNIA_COW(new WorldPoint(3033, 3308, 0), ASGARNIA, "In the cow pen north of Sarah's Farming Shop."), + ASGARNIA_PARTY_ROOM(new WorldPoint(3026, 3363, 0), ASGARNIA, "Outside the Falador Party Room."), + ASGARNIA_CRAFT_GUILD(new WorldPoint(2917, 3295, 0), ASGARNIA, "Outside the Crafting Guild cow pen."), + ASGARNIA_RIMMINGTON(new WorldPoint(2978, 3241, 0), ASGARNIA, "In the centre of the Rimmington mine."), ASGARNIA_MUDSKIPPER(new WorldPoint(2984, 3109, 0), ASGARNIA, "Mudskipper Point, on the starfish in the south-west corner."), - ASGARNIA_TROLL(new WorldPoint(2910, 3616, 0), ASGARNIA, "The Troll arena, where the player fights Dad during the Troll Stronghold quest. Bring climbing boots if travelling from Burthorpe."), - DESERT_GENIE(new WorldPoint(3364, 2910, 0), DESERT, "West of Nardah genie cave."), - DESERT_ALKHARID_MINE(new WorldPoint(3282, 3270, 0), DESERT, "West of Al Kharid mine."), - DESERT_MENAPHOS_GATE(new WorldPoint(3224, 2816, 0), DESERT, "North of Menaphos gate."), + ASGARNIA_TROLL(new WorldPoint(2910, 3616, 0), ASGARNIA, "The Troll arena, where the player fights Dad during the Troll Stronghold quest. Bring climbing boots if travelling from Burthorpe."), + DESERT_GENIE(new WorldPoint(3364, 2910, 0), DESERT, "West of Nardah genie cave."), + DESERT_ALKHARID_MINE(new WorldPoint(3282, 3270, 0), DESERT, "West of Al Kharid mine."), + DESERT_MENAPHOS_GATE(new WorldPoint(3224, 2816, 0), DESERT, "North of Menaphos gate."), DESERT_BEDABIN_CAMP(new WorldPoint(3164, 3050, 0), DESERT, "Bedabin Camp, dig around the north tent."), - DESERT_UZER(new WorldPoint(3431, 3106, 0), DESERT, "West of Uzer."), - DESERT_POLLNIVNEACH(new WorldPoint(3287, 2975, 0), DESERT, "West of Pollnivneach."), - DESERT_MTA(new WorldPoint(3350, 3293, 0), DESERT, "Next to Mage Training Arena."), - DESERT_SHANTY(new WorldPoint(3294, 3106, 0), DESERT, "South-west of Shantay Pass."), - FELDIP_HILLS_JIGGIG(new WorldPoint(2413, 3055, 0), FELDIP_HILLS, "West of Jiggig, east of the fairy ring bkp."), - FELDIP_HILLS_SW(new WorldPoint(2582, 2895, 0), FELDIP_HILLS, "West of the southeasternmost lake in Feldip Hills."), - FELDIP_HILLS_GNOME_GLITER(new WorldPoint(2553, 2972, 0), FELDIP_HILLS, "East of the gnome glider (Lemantolly Undri)."), - FELDIP_HILLS_RANTZ(new WorldPoint(2611, 2946, 0), FELDIP_HILLS, "South of Rantz, six steps west of the empty glass bottles."), - FELDIP_HILLS_SOUTH(new WorldPoint(2487, 3005, 0), FELDIP_HILLS, "South of Jiggig."), - FELDIP_HILLS_RED_CHIN(new WorldPoint(2532, 2900, 0), FELDIP_HILLS, "Outside the red chinchompa hunting ground entrance, south of the Hunting expert's hut."), - FELDIP_HILLS_SE(new WorldPoint(2567, 2916, 0), FELDIP_HILLS, "South-east of the ∩-shaped lake, near the icon."), - FELDIP_HILLS_CW_BALLOON(new WorldPoint(2452, 3108, 0), FELDIP_HILLS, "Directly west of the Castle Wars balloon."), - FREMENNIK_PROVINCE_MTN_CAMP(new WorldPoint(2804, 3672, 0), FREMENNIK_PROVINCE, "At the Mountain Camp."), - FREMENNIK_PROVINCE_RELLEKKA_HUNTER(new WorldPoint(2724, 3783, 0), FREMENNIK_PROVINCE, "At the Rellekka Hunter area, near the icon."), - FREMENNIK_PROVINCE_KELGADRIM_ENTRANCE(new WorldPoint(2715, 3689, 0), FREMENNIK_PROVINCE, "West of the Keldagrim entrance mine."), - FREMENNIK_PROVINCE_SW(new WorldPoint(2605, 3648, 0), FREMENNIK_PROVINCE, "Outside the fence in the south-western corner of Rellekka."), - FREMENNIK_PROVINCE_LIGHTHOUSE(new WorldPoint(2589, 3598, 0), FREMENNIK_PROVINCE, "South-east of the Lighthouse."), - FREMENNIK_PROVINCE_ETCETERIA_CASTLE(new WorldPoint(2614, 3867, 0), FREMENNIK_PROVINCE, "Inside Etceteria's castle, in the southern staircase."), - FREMENNIK_PROVINCE_MISC_COURTYARD(new WorldPoint(2529, 3867, 0), FREMENNIK_PROVINCE, "Outside Miscellania's courtyard."), + DESERT_UZER(new WorldPoint(3431, 3106, 0), DESERT, "West of Uzer."), + DESERT_POLLNIVNEACH(new WorldPoint(3287, 2975, 0), DESERT, "West of Pollnivneach."), + DESERT_MTA(new WorldPoint(3350, 3293, 0), DESERT, "Next to Mage Training Arena."), + DESERT_SHANTY(new WorldPoint(3294, 3106, 0), DESERT, "South-west of Shantay Pass."), + FELDIP_HILLS_JIGGIG(new WorldPoint(2413, 3055, 0), FELDIP_HILLS, "West of Jiggig, east of the fairy ring bkp."), + FELDIP_HILLS_SW(new WorldPoint(2582, 2895, 0), FELDIP_HILLS, "West of the southeasternmost lake in Feldip Hills."), + FELDIP_HILLS_GNOME_GLITER(new WorldPoint(2553, 2972, 0), FELDIP_HILLS, "East of the gnome glider (Lemantolly Undri)."), + FELDIP_HILLS_RANTZ(new WorldPoint(2611, 2946, 0), FELDIP_HILLS, "South of Rantz, six steps west of the empty glass bottles."), + FELDIP_HILLS_SOUTH(new WorldPoint(2487, 3005, 0), FELDIP_HILLS, "South of Jiggig."), + FELDIP_HILLS_RED_CHIN(new WorldPoint(2532, 2900, 0), FELDIP_HILLS, "Outside the red chinchompa hunting ground entrance, south of the Hunting expert's hut."), + FELDIP_HILLS_SE(new WorldPoint(2567, 2916, 0), FELDIP_HILLS, "South-east of the ∩-shaped lake, near the icon."), + FELDIP_HILLS_CW_BALLOON(new WorldPoint(2452, 3108, 0), FELDIP_HILLS, "Directly west of the Castle Wars balloon."), + FREMENNIK_PROVINCE_MTN_CAMP(new WorldPoint(2804, 3672, 0), FREMENNIK_PROVINCE, "At the Mountain Camp."), + FREMENNIK_PROVINCE_RELLEKKA_HUNTER(new WorldPoint(2724, 3783, 0), FREMENNIK_PROVINCE, "At the Rellekka Hunter area, near the icon."), + FREMENNIK_PROVINCE_KELGADRIM_ENTRANCE(new WorldPoint(2715, 3689, 0), FREMENNIK_PROVINCE, "West of the Keldagrim entrance mine."), + FREMENNIK_PROVINCE_SW(new WorldPoint(2605, 3648, 0), FREMENNIK_PROVINCE, "Outside the fence in the south-western corner of Rellekka."), + FREMENNIK_PROVINCE_LIGHTHOUSE(new WorldPoint(2589, 3598, 0), FREMENNIK_PROVINCE, "South-east of the Lighthouse."), + FREMENNIK_PROVINCE_ETCETERIA_CASTLE(new WorldPoint(2614, 3867, 0), FREMENNIK_PROVINCE, "Inside Etceteria's castle, in the southern staircase."), + FREMENNIK_PROVINCE_MISC_COURTYARD(new WorldPoint(2529, 3867, 0), FREMENNIK_PROVINCE, "Outside Miscellania's courtyard."), FREMENNIK_PROVINCE_FREMMY_ISLES_MINE(new WorldPoint(2378, 3849, 0), FREMENNIK_PROVINCE, "Central Fremennik Isles mine."), FREMENNIK_PROVINCE_WEST_ISLES_MINE(new WorldPoint(2313, 3854, 0), FREMENNIK_PROVINCE, "West Fremennik Isles mine."), - FREMENNIK_PROVINCE_WEST_JATIZSO_ENTRANCE(new WorldPoint(2391, 3813, 0), FREMENNIK_PROVINCE, "West of the Jatizso mine entrance."), + FREMENNIK_PROVINCE_WEST_JATIZSO_ENTRANCE(new WorldPoint(2391, 3813, 0), FREMENNIK_PROVINCE, "West of the Jatizso mine entrance."), FREMENNIK_PROVINCE_PIRATES_COVE(new WorldPoint(2210, 3814, 0), FREMENNIK_PROVINCE, "Pirates' Cove"), FREMENNIK_PROVINCE_ASTRAL_ALTER(new WorldPoint(2147, 3862, 0), FREMENNIK_PROVINCE, "Astral altar"), FREMENNIK_PROVINCE_LUNAR_VILLAGE(new WorldPoint(2087, 3915, 0), FREMENNIK_PROVINCE, "Lunar Isle, inside the village."), FREMENNIK_PROVINCE_LUNAR_NORTH(new WorldPoint(2106, 3949, 0), FREMENNIK_PROVINCE, "Lunar Isle, north of the village."), - KANDARIN_SINCLAR_MANSION(new WorldPoint(2726, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut."), + KANDARIN_SINCLAR_MANSION(new WorldPoint(2726, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut."), KANDARIN_CATHERBY(new WorldPoint(2774, 3433, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation."), KANDARIN_GRAND_TREE(new WorldPoint(2444, 3503, 0), KANDARIN, "Grand Tree, just east of the terrorchick gnome enclosure."), - KANDARIN_SEERS(new WorldPoint(2735, 3486, 0), KANDARIN, "Between the Seers' Village bank and Camelot."), + KANDARIN_SEERS(new WorldPoint(2735, 3486, 0), KANDARIN, "Between the Seers' Village bank and Camelot."), KANDARIN_MCGRUBORS_WOOD(new WorldPoint(2653, 3485, 0), KANDARIN, "McGrubor's Wood"), - KANDARIN_FISHING_BUILD(new WorldPoint(2586, 3372, 0), KANDARIN, "South of Fishing Guild"), - KANDARIN_WITCHHAVEN(new WorldPoint(2708, 3304, 0), KANDARIN, "Outside Witchaven, west of Jeb, Holgart, and Caroline."), - KANDARIN_NECRO_TOWER(new WorldPoint(2669, 3242, 0), KANDARIN, "Ground floor inside the Necromancer Tower. Easily accessed by using fairy ring code djp."), - KANDARIN_FIGHT_ARENA(new WorldPoint(2587, 3134, 0), KANDARIN, "South of the Fight Arena, north-west of the Nightmare Zone."), - KANDARIN_TREE_GNOME_VILLAGE(new WorldPoint(2526, 3160, 0), KANDARIN, "Tree Gnome Village, near the general store icon."), + KANDARIN_FISHING_BUILD(new WorldPoint(2586, 3372, 0), KANDARIN, "South of Fishing Guild"), + KANDARIN_WITCHHAVEN(new WorldPoint(2708, 3304, 0), KANDARIN, "Outside Witchaven, west of Jeb, Holgart, and Caroline."), + KANDARIN_NECRO_TOWER(new WorldPoint(2669, 3242, 0), KANDARIN, "Ground floor inside the Necromancer Tower. Easily accessed by using fairy ring code djp."), + KANDARIN_FIGHT_ARENA(new WorldPoint(2587, 3134, 0), KANDARIN, "South of the Fight Arena, north-west of the Nightmare Zone."), + KANDARIN_TREE_GNOME_VILLAGE(new WorldPoint(2526, 3160, 0), KANDARIN, "Tree Gnome Village, near the general store icon."), KANDARIN_GRAVE_OF_SCORPIUS(new WorldPoint(2464, 3228, 0), KANDARIN, "Grave of Scorpius"), - KANDARIN_KHAZARD_BATTLEFIELD(new WorldPoint(2518, 3249, 0), KANDARIN, "Khazard Battlefield, in the small ruins south of tracker gnome 2."), + KANDARIN_KHAZARD_BATTLEFIELD(new WorldPoint(2518, 3249, 0), KANDARIN, "Khazard Battlefield, in the small ruins south of tracker gnome 2."), KANDARIN_WEST_ARDY(new WorldPoint(2533, 3320, 0), KANDARIN, "West Ardougne, near the staircase outside the Civic Office."), - KANDARIN_SW_TREE_GNOME_STRONGHOLD(new WorldPoint(2411, 3431, 0), KANDARIN, "South-west Tree Gnome Stronghold"), - KANDARIN_OUTPOST(new WorldPoint(2458, 3364, 0), KANDARIN, "South of the Tree Gnome Stronghold, north-east of the Outpost."), - KANDARIN_BAXTORIAN_FALLS(new WorldPoint(2534, 3479, 0), KANDARIN, "South-east of Almera's house on Baxtorian Falls."), - KANDARIN_BA_AGILITY_COURSE(new WorldPoint(2536, 3546, 0), KANDARIN, "Inside the Barbarian Agility Course. Completion of Alfred Grimhand's Barcrawl is required."), + KANDARIN_SW_TREE_GNOME_STRONGHOLD(new WorldPoint(2411, 3431, 0), KANDARIN, "South-west Tree Gnome Stronghold"), + KANDARIN_OUTPOST(new WorldPoint(2458, 3364, 0), KANDARIN, "South of the Tree Gnome Stronghold, north-east of the Outpost."), + KANDARIN_BAXTORIAN_FALLS(new WorldPoint(2534, 3479, 0), KANDARIN, "South-east of Almera's house on Baxtorian Falls."), + KANDARIN_BA_AGILITY_COURSE(new WorldPoint(2536, 3546, 0), KANDARIN, "Inside the Barbarian Agility Course. Completion of Alfred Grimhand's Barcrawl is required."), KARAMJA_MUSA_POINT(new WorldPoint(2914, 3168, 0), KARAMJA, "Musa Point, banana plantation."), - KARAMJA_BRIMHAVEN_FRUIT_TREE(new WorldPoint(2783, 3214, 0), KARAMJA, "Brimhaven, east of the fruit tree patch."), - KARAMJA_WEST_BRIMHAVEN(new WorldPoint(2721, 3169, 0), KARAMJA, "West of Brimhaven."), - KARAMJA_GLIDER(new WorldPoint(2966, 2975, 0), KARAMJA, "West of the gnome glider."), - KARAMJA_KHARAZI_NE(new WorldPoint(2908, 2922, 0), KARAMJA, "North-eastern part of Kharazi Jungle."), - KARAMJA_KHARAZI_SW(new WorldPoint(2783, 2898, 0), KARAMJA, "South-western part of Kharazi Jungle."), - KARAMJA_CRASH_ISLAND(new WorldPoint(2910, 2737, 0), KARAMJA, "Northern part of Crash Island."), - MISTHALIN_VARROCK_STONE_CIRCLE(new WorldPoint(3225, 3355, 0), MISTHALIN, "South of the stone circle near Varrock's entrance."), - MISTHALIN_LUMBRIDGE(new WorldPoint(3238, 3169, 0), MISTHALIN, "Just north-west of the Lumbridge Fishing tutor."), - MISTHALIN_LUMBRIDGE_2(new WorldPoint(3170, 3278, 0), MISTHALIN, "North of the pond between Lumbridge and Draynor Village."), - MISTHALIN_GERTUDES(new WorldPoint(3158, 3421, 0), MISTHALIN, "North-east of Gertrude's house west of Varrock."), - MISTHALIN_DRAYNOR_BANK(new WorldPoint(3096, 3235, 0), MISTHALIN, "South of Draynor Village bank."), - MISTHALIN_LUMBER_YARD(new WorldPoint(3303, 3483, 0), MISTHALIN, "South of Lumber Yard, east of Assistant Serf."), - MORYTANIA_BURGH_DE_ROTT(new WorldPoint(3545, 3253, 0), MORYTANIA, "In the north-east area of Burgh de Rott, by the reverse-L-shaped ruins."), - MORYTANIA_PORT_PHASMATYS(new WorldPoint(3613, 3485, 0), MORYTANIA, "West of Port Phasmatys, south-east of fairy ring."), - MORYTANIA_HOLLOWS(new WorldPoint(3500, 3423, 0), MORYTANIA, "Inside The Hollows, south of the bridge which was repaired in a quest."), - MORYTANIA_SWAMP(new WorldPoint(3422, 3374, 0), MORYTANIA, "Inside the Mort Myre Swamp, north-west of the Nature Grotto."), - MORYTANIA_HAUNTED_MINE(new WorldPoint(3441, 3259, 0), MORYTANIA, "At Haunted Mine quest start."), - MORYTANIA_MAUSOLEUM(new WorldPoint(3499, 3539, 0), MORYTANIA, "South of the Mausoleum."), - MORYTANIA_MOS_LES_HARMLESS(new WorldPoint(3744, 3041, 0), MORYTANIA, "Northern area of Mos Le'Harmless, between the lakes."), - MORYTANIA_MOS_LES_HARMLESS_BAR(new WorldPoint(3670, 2974, 0), MORYTANIA, "Near Mos Le'Harmless southern bar."), - MORYTANIA_DRAGONTOOTH_NORTH(new WorldPoint(3813, 3567, 0), MORYTANIA, "Northern part of Dragontooth Island."), - MORYTANIA_DRAGONTOOTH_SOUTH(new WorldPoint(3803, 3532, 0), MORYTANIA, "Southern part of Dragontooth Island."), - WESTERN_PROVINCE_EAGLES_PEAK(new WorldPoint(2297, 3530, 0), WESTERN_PROVINCE, "North-west of Eagles' Peak."), + KARAMJA_BRIMHAVEN_FRUIT_TREE(new WorldPoint(2783, 3214, 0), KARAMJA, "Brimhaven, east of the fruit tree patch."), + KARAMJA_WEST_BRIMHAVEN(new WorldPoint(2721, 3169, 0), KARAMJA, "West of Brimhaven."), + KARAMJA_GLIDER(new WorldPoint(2966, 2975, 0), KARAMJA, "West of the gnome glider."), + KARAMJA_KHARAZI_NE(new WorldPoint(2908, 2922, 0), KARAMJA, "North-eastern part of Kharazi Jungle."), + KARAMJA_KHARAZI_SW(new WorldPoint(2783, 2898, 0), KARAMJA, "South-western part of Kharazi Jungle."), + KARAMJA_CRASH_ISLAND(new WorldPoint(2910, 2737, 0), KARAMJA, "Northern part of Crash Island."), + MISTHALIN_VARROCK_STONE_CIRCLE(new WorldPoint(3225, 3355, 0), MISTHALIN, "South of the stone circle near Varrock's entrance."), + MISTHALIN_LUMBRIDGE(new WorldPoint(3238, 3169, 0), MISTHALIN, "Just north-west of the Lumbridge Fishing tutor."), + MISTHALIN_LUMBRIDGE_2(new WorldPoint(3170, 3278, 0), MISTHALIN, "North of the pond between Lumbridge and Draynor Village."), + MISTHALIN_GERTUDES(new WorldPoint(3158, 3421, 0), MISTHALIN, "North-east of Gertrude's house west of Varrock."), + MISTHALIN_DRAYNOR_BANK(new WorldPoint(3096, 3235, 0), MISTHALIN, "South of Draynor Village bank."), + MISTHALIN_LUMBER_YARD(new WorldPoint(3303, 3483, 0), MISTHALIN, "South of Lumber Yard, east of Assistant Serf."), + MORYTANIA_BURGH_DE_ROTT(new WorldPoint(3545, 3253, 0), MORYTANIA, "In the north-east area of Burgh de Rott, by the reverse-L-shaped ruins."), + MORYTANIA_PORT_PHASMATYS(new WorldPoint(3613, 3485, 0), MORYTANIA, "West of Port Phasmatys, south-east of fairy ring."), + MORYTANIA_HOLLOWS(new WorldPoint(3500, 3423, 0), MORYTANIA, "Inside The Hollows, south of the bridge which was repaired in a quest."), + MORYTANIA_SWAMP(new WorldPoint(3422, 3374, 0), MORYTANIA, "Inside the Mort Myre Swamp, north-west of the Nature Grotto."), + MORYTANIA_HAUNTED_MINE(new WorldPoint(3441, 3259, 0), MORYTANIA, "At Haunted Mine quest start."), + MORYTANIA_MAUSOLEUM(new WorldPoint(3499, 3539, 0), MORYTANIA, "South of the Mausoleum."), + MORYTANIA_MOS_LES_HARMLESS(new WorldPoint(3744, 3041, 0), MORYTANIA, "Northern area of Mos Le'Harmless, between the lakes."), + MORYTANIA_MOS_LES_HARMLESS_BAR(new WorldPoint(3670, 2974, 0), MORYTANIA, "Near Mos Le'Harmless southern bar."), + MORYTANIA_DRAGONTOOTH_NORTH(new WorldPoint(3813, 3567, 0), MORYTANIA, "Northern part of Dragontooth Island."), + MORYTANIA_DRAGONTOOTH_SOUTH(new WorldPoint(3803, 3532, 0), MORYTANIA, "Southern part of Dragontooth Island."), + WESTERN_PROVINCE_EAGLES_PEAK(new WorldPoint(2297, 3530, 0), WESTERN_PROVINCE, "North-west of Eagles' Peak."), WESTERN_PROVINCE_PISCATORIS(new WorldPoint(2337, 3689, 0), WESTERN_PROVINCE, "Piscatoris Fishing Colony"), - WESTERN_PROVINCE_PISCATORIS_HUNTER_AREA(new WorldPoint(2361, 3566, 0), WESTERN_PROVINCE, "Eastern part of Piscatoris Hunter area, south-west of the Falconry."), - WESTERN_PROVINCE_ARANDAR(new WorldPoint(2366, 3318, 0), WESTERN_PROVINCE, "South-west of the crystal gate to Arandar."), - WESTERN_PROVINCE_ELF_CAMP_EAST(new WorldPoint(2270, 3244, 0), WESTERN_PROVINCE, "East of Elf Camp."), - WESTERN_PROVINCE_ELF_CAMP_NW(new WorldPoint(2174, 3280, 0), WESTERN_PROVINCE, "North-west of Elf Camp."), - WESTERN_PROVINCE_LLETYA(new WorldPoint(2335, 3166, 0), WESTERN_PROVINCE, "In Lletya."), - WESTERN_PROVINCE_TYRAS(new WorldPoint(2204, 3157, 0), WESTERN_PROVINCE, "Near Tyras Camp."), - WESTERN_PROVINCE_ZULANDRA(new WorldPoint(2196, 3057, 0), WESTERN_PROVINCE, "The northern house at Zul-Andra."), - WILDERNESS_5(new WorldPoint(3169, 3558, 0), WILDERNESS, "North of the Grand Exchange, level 5 Wilderness."), - WILDERNESS_12(new WorldPoint(3038, 3612, 0), WILDERNESS, "South-east of the Dark Warriors' Fortress, level 12 Wilderness."), - WILDERNESS_20(new WorldPoint(3225, 3676, 0), WILDERNESS, "East of the Corporeal Beast's lair, level 20 Wilderness."), + WESTERN_PROVINCE_PISCATORIS_HUNTER_AREA(new WorldPoint(2361, 3566, 0), WESTERN_PROVINCE, "Eastern part of Piscatoris Hunter area, south-west of the Falconry."), + WESTERN_PROVINCE_ARANDAR(new WorldPoint(2366, 3318, 0), WESTERN_PROVINCE, "South-west of the crystal gate to Arandar."), + WESTERN_PROVINCE_ELF_CAMP_EAST(new WorldPoint(2270, 3244, 0), WESTERN_PROVINCE, "East of Elf Camp."), + WESTERN_PROVINCE_ELF_CAMP_NW(new WorldPoint(2174, 3280, 0), WESTERN_PROVINCE, "North-west of Elf Camp."), + WESTERN_PROVINCE_LLETYA(new WorldPoint(2335, 3166, 0), WESTERN_PROVINCE, "In Lletya."), + WESTERN_PROVINCE_TYRAS(new WorldPoint(2204, 3157, 0), WESTERN_PROVINCE, "Near Tyras Camp."), + WESTERN_PROVINCE_ZULANDRA(new WorldPoint(2196, 3057, 0), WESTERN_PROVINCE, "The northern house at Zul-Andra."), + WILDERNESS_5(new WorldPoint(3169, 3558, 0), WILDERNESS, "North of the Grand Exchange, level 5 Wilderness."), + WILDERNESS_12(new WorldPoint(3038, 3612, 0), WILDERNESS, "South-east of the Dark Warriors' Fortress, level 12 Wilderness."), + WILDERNESS_20(new WorldPoint(3225, 3676, 0), WILDERNESS, "East of the Corporeal Beast's lair, level 20 Wilderness."), WILDERNESS_27(new WorldPoint(3174, 3735, 0), WILDERNESS, "Inside the Ruins north of the Graveyard of Shadows, level 27 Wilderness."), - WILDERNESS_28(new WorldPoint(3374, 3734, 0), WILDERNESS, "East of Venenatis' nest, level 28 Wilderness."), + WILDERNESS_28(new WorldPoint(3374, 3734, 0), WILDERNESS, "East of Venenatis' nest, level 28 Wilderness."), WILDERNESS_32(new WorldPoint(3311, 3773, 0), WILDERNESS, "North of Venenatis' nest, level 32 Wilderness."), - WILDERNESS_35(new WorldPoint(3153, 3795, 0), WILDERNESS, "East of the Wilderness canoe exit, level 35 Wilderness."), - WILDERNESS_37(new WorldPoint(2975, 3811, 0), WILDERNESS, "South-east of the Chaos Temple, level 37 Wilderness."), - WILDERNESS_38(new WorldPoint(3294, 3817, 0), WILDERNESS, "South of Callisto, level 38 Wilderness."), - WILDERNESS_49(new WorldPoint(3140, 3910, 0), WILDERNESS, "South-west of the Deserted Keep, level 49 Wilderness."), - WILDERNESS_54(new WorldPoint(2983, 3946, 0), WILDERNESS, "West of the Wilderness Agility Course, level 54 Wilderness."), - ZEAH_BLASTMINE_BANK(new WorldPoint(1507, 3856, 0), ZEAH, "Next to the bank in the Lovakengj blast mine."), - ZEAH_BLASTMINE_NORTH(new WorldPoint(1490, 3883, 0), ZEAH, "Northern part of the Lovakengj blast mine."), - ZEAH_LOVAKITE_FURNACE(new WorldPoint(1505, 3814, 0), ZEAH, "Next to the lovakite furnace in Lovakengj."), - ZEAH_LOVAKENGJ_MINE(new WorldPoint(1477, 3779, 0), ZEAH, "Next to mithril rock in the Lovakengj mine."), - ZEAH_SULPHR_MINE(new WorldPoint(1428, 3866, 0), ZEAH, "Western entrance in the Lovakengj sulphur mine."), + WILDERNESS_35(new WorldPoint(3153, 3795, 0), WILDERNESS, "East of the Wilderness canoe exit, level 35 Wilderness."), + WILDERNESS_37(new WorldPoint(2975, 3811, 0), WILDERNESS, "South-east of the Chaos Temple, level 37 Wilderness."), + WILDERNESS_38(new WorldPoint(3294, 3817, 0), WILDERNESS, "South of Callisto, level 38 Wilderness."), + WILDERNESS_49(new WorldPoint(3140, 3910, 0), WILDERNESS, "South-west of the Deserted Keep, level 49 Wilderness."), + WILDERNESS_54(new WorldPoint(2983, 3946, 0), WILDERNESS, "West of the Wilderness Agility Course, level 54 Wilderness."), + ZEAH_BLASTMINE_BANK(new WorldPoint(1507, 3856, 0), ZEAH, "Next to the bank in the Lovakengj blast mine."), + ZEAH_BLASTMINE_NORTH(new WorldPoint(1490, 3883, 0), ZEAH, "Northern part of the Lovakengj blast mine."), + ZEAH_LOVAKITE_FURNACE(new WorldPoint(1505, 3814, 0), ZEAH, "Next to the lovakite furnace in Lovakengj."), + ZEAH_LOVAKENGJ_MINE(new WorldPoint(1477, 3779, 0), ZEAH, "Next to mithril rock in the Lovakengj mine."), + ZEAH_SULPHR_MINE(new WorldPoint(1428, 3866, 0), ZEAH, "Western entrance in the Lovakengj sulphur mine."), ZEAH_SHAYZIEN_BANK(new WorldPoint(1517, 3603, 0), ZEAH, "South-east of the bank in Shayzien."), - ZEAH_OVERPASS(new WorldPoint(1467, 3714, 0), ZEAH, "Overpass between Lovakengj and Shayzien."), - ZEAH_LIZARDMAN(new WorldPoint(1493, 3694, 0), ZEAH, "Within Lizardman Canyon, east of the ladder. Requires 5% favour with Shayzien."), - ZEAH_COMBAT_RING(new WorldPoint(1557, 3580, 0), ZEAH, "Shayzien, south-east of the Combat Ring."), - ZEAH_SHAYZIEN_BANK_2(new WorldPoint(1494, 3622, 0), ZEAH, "North-west of the bank in Shayzien."), - ZEAH_LIBRARY(new WorldPoint(1601, 3842, 0), ZEAH, "North-west of the Arceuus Library."), - ZEAH_HOUSECHURCH(new WorldPoint(1682, 3792, 0), ZEAH, "By the entrance to the Arceuus church."), - ZEAH_DARK_ALTAR(new WorldPoint(1699, 3879, 0), ZEAH, "West of the Dark Altar."), + ZEAH_OVERPASS(new WorldPoint(1467, 3714, 0), ZEAH, "Overpass between Lovakengj and Shayzien."), + ZEAH_LIZARDMAN(new WorldPoint(1493, 3694, 0), ZEAH, "Within Lizardman Canyon, east of the ladder. Requires 5% favour with Shayzien."), + ZEAH_COMBAT_RING(new WorldPoint(1557, 3580, 0), ZEAH, "Shayzien, south-east of the Combat Ring."), + ZEAH_SHAYZIEN_BANK_2(new WorldPoint(1494, 3622, 0), ZEAH, "North-west of the bank in Shayzien."), + ZEAH_LIBRARY(new WorldPoint(1601, 3842, 0), ZEAH, "North-west of the Arceuus Library."), + ZEAH_HOUSECHURCH(new WorldPoint(1682, 3792, 0), ZEAH, "By the entrance to the Arceuus church."), + ZEAH_DARK_ALTAR(new WorldPoint(1699, 3879, 0), ZEAH, "West of the Dark Altar."), ZEAH_ARCEUUS_HOUSE(new WorldPoint(1708, 3701, 0), ZEAH, "By the southern entrance to Arceuus."), - ZEAH_ESSENCE_MINE(new WorldPoint(1762, 3852, 0), ZEAH, "By the Arceuus essence mine."), - ZEAH_ESSENCE_MINE_NE(new WorldPoint(1772, 3866, 0), ZEAH, "North-east of the Arceuus essence mine."), - ZEAH_PISCARILUS_MINE(new WorldPoint(1768, 3705, 0), ZEAH, "South of the Piscarilius mine."), - ZEAH_GOLDEN_FIELD_TAVERN(new WorldPoint(1718, 3647, 0), ZEAH, "South of The Golden Field tavern in the northern area of Hosidius."), - ZEAH_MESS_HALL(new WorldPoint(1658, 3621, 0), ZEAH, "East of the Mess hall."), - ZEAH_WATSONS_HOUSE(new WorldPoint(1653, 3573, 0), ZEAH, "East of Watson's house."), - ZEAH_VANNAHS_FARM_STORE(new WorldPoint(1806, 3521, 0), ZEAH, "North of Vannah's Farm Store, between the chicken coop and willow trees."), + ZEAH_ESSENCE_MINE(new WorldPoint(1762, 3852, 0), ZEAH, "By the Arceuus essence mine."), + ZEAH_ESSENCE_MINE_NE(new WorldPoint(1772, 3866, 0), ZEAH, "North-east of the Arceuus essence mine."), + ZEAH_PISCARILUS_MINE(new WorldPoint(1768, 3705, 0), ZEAH, "South of the Piscarilius mine."), + ZEAH_GOLDEN_FIELD_TAVERN(new WorldPoint(1718, 3647, 0), ZEAH, "South of The Golden Field tavern in the northern area of Hosidius."), + ZEAH_MESS_HALL(new WorldPoint(1658, 3621, 0), ZEAH, "East of the Mess hall."), + ZEAH_WATSONS_HOUSE(new WorldPoint(1653, 3573, 0), ZEAH, "East of Watson's house."), + ZEAH_VANNAHS_FARM_STORE(new WorldPoint(1806, 3521, 0), ZEAH, "North of Vannah's Farm Store, between the chicken coop and willow trees."), ZEAH_FARMING_GUILD_W(new WorldPoint(1209, 3737, 0), ZEAH, "West of the Farming Guild."), ZEAH_DAIRY_COW(new WorldPoint(1320, 3718, 0), ZEAH, "North-east of the Kebos Lowlands, east of the dairy cow."), ZEAH_CRIMSON_SWIFTS(new WorldPoint(1186, 3583, 0), ZEAH, "South-west of the Kebos Swamp, below the crimson swifts."); From 57f60a36e40ed1e901b85250930476c38d93ef2d Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 2 Jun 2019 20:02:11 -0400 Subject: [PATCH 28/30] api: modify Widget.getWidgetItem to return widget items when no item exists This allows plugins to get the canvas bounds of where items would be if they existed. Update existing usages to account for the new behavior. --- .../client/plugins/devtools/DevToolsOverlay.java | 1 + .../client/plugins/examine/ExaminePlugin.java | 2 +- .../java/net/runelite/mixins/RSWidgetMixin.java | 13 ++++++++----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java index fd96de011c..fbc132b90f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java @@ -457,6 +457,7 @@ class DevToolsOverlay extends Overlay WidgetItem widgetItem = widget.getWidgetItem(itemIndex); if (widgetItem == null + || widgetItem.getId() < 0 || widgetItem.getId() == ITEM_EMPTY || widgetItem.getId() == ITEM_FILLED) { 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 1f78bddb9f..888a25c08e 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 @@ -120,7 +120,7 @@ public class ExaminePlugin extends Plugin int widgetChild = TO_CHILD(widgetId); Widget widget = client.getWidget(widgetGroup, widgetChild); WidgetItem widgetItem = widget.getWidgetItem(event.getActionParam()); - quantity = widgetItem != null ? widgetItem.getQuantity() : 1; + quantity = widgetItem != null && widgetItem.getId() >= 0 ? widgetItem.getQuantity() : 1; break; } case EXAMINE_ITEM_BANK_EQ: diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java index 3b8ab87c99..60ec7821cb 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java @@ -258,6 +258,11 @@ public abstract class RSWidgetMixin implements RSWidget for (int i = 0; i < itemIds.length; ++i) { + if (itemIds[i] <= 0) + { + continue; + } + WidgetItem item = getWidgetItem(i); if (item != null) @@ -287,17 +292,15 @@ public abstract class RSWidgetMixin implements RSWidget int itemId = itemIds[index]; int itemQuantity = itemQuantities[index]; - Point widgetCanvasLocation = getCanvasLocation(); - - if (itemId <= 0 || itemQuantity <= 0 || columns <= 0) + if (columns <= 0) { return null; } int row = index / columns; int col = index % columns; - int itemX = widgetCanvasLocation.getX() + ((ITEM_SLOT_SIZE + xPitch) * col); - int itemY = widgetCanvasLocation.getY() + ((ITEM_SLOT_SIZE + yPitch) * row); + int itemX = rl$x + ((ITEM_SLOT_SIZE + xPitch) * col); + int itemY = rl$y + ((ITEM_SLOT_SIZE + yPitch) * row); Rectangle bounds = new Rectangle(itemX, itemY, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE); return new WidgetItem(itemId - 1, itemQuantity, index, bounds, this); From 16bd84db3cce773fe054227afad99d5f49c25c60 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 2 Jun 2019 20:02:32 -0400 Subject: [PATCH 29/30] client: add inventory grid plugin Co-authored-by: Jeremy Plsek --- .../main/java/net/runelite/api/Client.java | 13 ++ .../inventorygrid/InventoryGridConfig.java | 63 ++++++++++ .../inventorygrid/InventoryGridOverlay.java | 114 ++++++++++++++++++ .../inventorygrid/InventoryGridPlugin.java | 66 ++++++++++ .../java/net/runelite/rs/api/RSClient.java | 8 ++ 5 files changed, 264 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridPlugin.java diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index fc1e564c0a..f8a4f1f429 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1605,6 +1605,19 @@ public interface Client extends GameEngine void checkClickbox(Model model, int orientation, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y, int z, long hash); + /** + * Get the if1 widget whose item is being dragged + * + * @return + */ + Widget getIf1DraggedWidget(); + + /** + * Get the item index of the item being dragged on an if1 widget + * @return + */ + int getIf1DraggedItemIndex(); + /** * Sets if a widget is in target mode */ 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 new file mode 100644 index 0000000000..eda6b7cbb8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018, Jeremy Plsek + * 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.inventorygrid; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("inventorygrid") +public interface InventoryGridConfig extends Config +{ + @ConfigItem( + keyName = "showItem", + name = "Show item", + description = "Show a preview of the item in the new slot" + ) + default boolean showItem() + { + return true; + } + + @ConfigItem( + keyName = "showGrid", + name = "Show grid", + description = "Show a grid on the inventory while dragging" + ) + default boolean showGrid() + { + return true; + } + + @ConfigItem( + keyName = "showHighlight", + name = "Highlight background", + description = "Show a green background highlight on the new slot" + ) + default boolean showHighlight() + { + return true; + } +} 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 new file mode 100644 index 0000000000..60db349831 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2018, Jeremy Plsek + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.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; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import net.runelite.api.Client; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetItem; +import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; + +class InventoryGridOverlay extends Overlay +{ + private static final int INVENTORY_SIZE = 28; + + 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; + + @Inject + private InventoryGridOverlay(InventoryGridConfig config, Client client, ItemManager itemManager) + { + this.itemManager = itemManager; + this.client = client; + this.config = config; + + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_WIDGETS); + } + + @Override + public Dimension render(Graphics2D graphics) + { + final Widget if1DraggingWidget = client.getIf1DraggedWidget(); + final Widget inventoryWidget = client.getWidget(WidgetInfo.INVENTORY); + + if (if1DraggingWidget == null || if1DraggingWidget != inventoryWidget) + { + return null; + } + + final net.runelite.api.Point mouse = client.getMouseCanvasPosition(); + final Point mousePoint = new Point(mouse.getX(), mouse.getY()); + + for (int i = 0; i < INVENTORY_SIZE; ++i) + { + WidgetItem widgetItem = inventoryWidget.getWidgetItem(i); + + final Rectangle bounds = widgetItem.getCanvasBounds(); + boolean inBounds = bounds.contains(mousePoint); + + if (config.showItem() && inBounds) + { + final WidgetItem draggedItem = inventoryWidget.getWidgetItem(client.getIf1DraggedItemIndex()); + final BufferedImage draggedItemImage = itemManager.getImage(draggedItem.getId()); + final int x = (int) bounds.getX(); + final int y = (int) bounds.getY(); + + graphics.setComposite(AlphaComposite.SrcOver.derive(0.3f)); + graphics.drawImage(draggedItemImage, x, y, null); + graphics.setComposite(AlphaComposite.SrcOver); + } + + if (config.showHighlight() && inBounds) + { + graphics.setColor(HIGHLIGHT); + graphics.fill(bounds); + } + else if (config.showGrid()) + { + graphics.setColor(GRID); + graphics.fill(bounds); + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridPlugin.java new file mode 100644 index 0000000000..dc6b0ae372 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridPlugin.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018, Jeremy Plsek + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.inventorygrid; + +import com.google.inject.Inject; +import com.google.inject.Provides; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "Inventory Grid", + description = "Shows a grid over the inventory and a preview of where items will be dragged", + tags = {"items", "overlay"}, + enabledByDefault = false +) +public class InventoryGridPlugin extends Plugin +{ + @Inject + private InventoryGridOverlay overlay; + + @Inject + private OverlayManager overlayManager; + + @Override + public void startUp() + { + overlayManager.add(overlay); + } + + @Override + public void shutDown() + { + overlayManager.remove(overlay); + } + + @Provides + InventoryGridConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(InventoryGridConfig.class); + } +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 6381dd3f99..66df34bc97 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -932,6 +932,14 @@ public interface RSClient extends RSGameEngine, Client @Import("endY") int getEndY(); + @Import("if1DraggedWidget") + @Override + RSWidget getIf1DraggedWidget(); + + @Import("if1DraggedItemIndex") + @Override + int getIf1DraggedItemIndex(); + @Import("spellSelected") @Override void setSpellSelected(boolean selected); From 8806bba2743602425e826a0c2188e8a0530205cf Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 4 Jun 2019 08:52:05 -0400 Subject: [PATCH 30/30] inventory grid: add delay before activating overlay --- runelite-api/src/main/java/net/runelite/api/Client.java | 7 +++++++ .../client/plugins/inventorygrid/InventoryGridOverlay.java | 4 +++- .../src/main/java/net/runelite/rs/api/RSClient.java | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index f8a4f1f429..cfc24df818 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1360,6 +1360,13 @@ public interface Client extends GameEngine */ boolean isInInstancedRegion(); + /** + * Get the number of client ticks an item has been pressed + * + * @return the number of client ticks an item has been pressed + */ + int getItemPressedDuration(); + /** * Sets whether the client is hiding entities. *

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 60db349831..f628f007c6 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 @@ -45,6 +45,7 @@ import net.runelite.client.ui.overlay.OverlayPosition; class InventoryGridOverlay extends Overlay { private static final int INVENTORY_SIZE = 28; + private static final int DRAG_DELAY = 5; private static final Color HIGHLIGHT = new Color(0, 255, 0, 45); private static final Color GRID = new Color(255, 255, 255, 45); @@ -70,7 +71,8 @@ class InventoryGridOverlay extends Overlay final Widget if1DraggingWidget = client.getIf1DraggedWidget(); final Widget inventoryWidget = client.getWidget(WidgetInfo.INVENTORY); - if (if1DraggingWidget == null || if1DraggingWidget != inventoryWidget) + if (if1DraggingWidget == null || if1DraggingWidget != inventoryWidget + || client.getItemPressedDuration() < DRAG_DELAY) { return null; } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 66df34bc97..96b3333df4 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -777,6 +777,7 @@ public interface RSClient extends RSGameEngine, Client boolean isInInstancedRegion(); @Import("itemPressedDuration") + @Override int getItemPressedDuration(); @Import("itemPressedDuration")