From 198176aa6281e182b1f2b0f069039ae5b4ca3d75 Mon Sep 17 00:00:00 2001
From: Twiglet1022 <29353990+Twiglet1022@users.noreply.github.com>
Date: Fri, 23 Nov 2018 02:21:30 +0000
Subject: [PATCH 1/6] world point: add `distanceToHypotenuse` method for
precise diagonals
---
.../net/runelite/api/coords/WorldPoint.java | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java
index bbacd1914a..c71e323a57 100644
--- a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java
+++ b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java
@@ -305,6 +305,40 @@ public class WorldPoint
return Math.max(Math.abs(getX() - other.getX()), Math.abs(getY() - other.getY()));
}
+ /**
+ * Gets the straight-line distance between this point and another.
+ *
+ * If the other point is not on the same plane, this method will return
+ * {@link Float#MAX_VALUE}. If ignoring the plane is wanted, use the
+ * {@link #distanceTo2DHypotenuse(WorldPoint)} method.
+ *
+ * @param other other point
+ * @return the straight-line distance
+ */
+ public float distanceToHypotenuse(WorldPoint other)
+ {
+ if (other.plane != plane)
+ {
+ return Float.MAX_VALUE;
+ }
+
+ return distanceTo2DHypotenuse(other);
+ }
+
+ /**
+ * Find the straight-line distance from this point to another point.
+ *
+ * This method disregards the plane value of the two tiles and returns
+ * the simple distance between the X-Z coordinate pairs.
+ *
+ * @param other other point
+ * @return the straight-line distance
+ */
+ public float distanceTo2DHypotenuse(WorldPoint other)
+ {
+ return (float) Math.hypot(getX() - other.getX(), getY() - other.getY());
+ }
+
/**
* Converts the passed scene coordinates to a world space
*/
From dae5217d44da59a22a7119e0c7bf18d006ce0975 Mon Sep 17 00:00:00 2001
From: Twiglet1022 <29353990+Twiglet1022@users.noreply.github.com>
Date: Fri, 23 Nov 2018 02:22:10 +0000
Subject: [PATCH 2/6] widget IDs: add widget ID for full inventory at MLM
---
.../src/main/java/net/runelite/api/widgets/WidgetID.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java
index 0c1c2697a8..25815193f8 100644
--- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java
+++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java
@@ -88,6 +88,7 @@ public class WidgetID
public static final int BARROWS_REWARD_GROUP_ID = 155;
public static final int RAIDS_GROUP_ID = 513;
public static final int MOTHERLODE_MINE_GROUP_ID = 382;
+ public static final int MOTHERLODE_MINE_FULL_INVENTORY_GROUP_ID = 229;
public static final int EXPERIENCE_DROP_GROUP_ID = 122;
public static final int PUZZLE_BOX_GROUP_ID = 306;
public static final int LIGHT_BOX_GROUP_ID = 322;
From 3b0f1d2a63510db456a01c1100052398aa72dc2b Mon Sep 17 00:00:00 2001
From: Twiglet1022 <29353990+Twiglet1022@users.noreply.github.com>
Date: Sat, 8 Jun 2019 23:35:31 +0100
Subject: [PATCH 3/6] mlm plugin: improve mining status detection
---
.../plugins/motherlode/MotherlodeOverlay.java | 12 +-
.../plugins/motherlode/MotherlodePlugin.java | 188 +++++++++++++++++-
2 files changed, 188 insertions(+), 12 deletions(-)
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeOverlay.java
index 8a2ad81cdf..53355bde58 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeOverlay.java
@@ -24,15 +24,12 @@
*/
package net.runelite.client.plugins.motherlode;
-import com.google.common.collect.ImmutableSet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.time.Duration;
import java.time.Instant;
-import java.util.Set;
import javax.inject.Inject;
-import static net.runelite.api.AnimationID.*;
import net.runelite.api.Client;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
@@ -42,13 +39,6 @@ import net.runelite.client.ui.overlay.components.TitleComponent;
class MotherlodeOverlay extends Overlay
{
- private static final Set MINING_ANIMATION_IDS = ImmutableSet.of(
- MINING_MOTHERLODE_BRONZE, MINING_MOTHERLODE_IRON, MINING_MOTHERLODE_STEEL,
- MINING_MOTHERLODE_BLACK, MINING_MOTHERLODE_MITHRIL, MINING_MOTHERLODE_ADAMANT,
- MINING_MOTHERLODE_RUNE, MINING_MOTHERLODE_DRAGON, MINING_MOTHERLODE_DRAGON_ORN,
- MINING_MOTHERLODE_INFERNAL
- );
-
private final Client client;
private final MotherlodePlugin plugin;
private final MotherlodeSession motherlodeSession;
@@ -93,7 +83,7 @@ class MotherlodeOverlay extends Overlay
if (config.showMiningState())
{
- if (MINING_ANIMATION_IDS.contains(client.getLocalPlayer().getAnimation()))
+ if (plugin.isMining())
{
panelComponent.getChildren().add(TitleComponent.builder()
.text("Mining")
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
index 82bea5175b..b910a55ae3 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
@@ -40,6 +40,19 @@ import java.util.Set;
import javax.inject.Inject;
import lombok.AccessLevel;
import lombok.Getter;
+import net.runelite.api.AnimationID;
+import static net.runelite.api.AnimationID.IDLE;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_3A;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_ADAMANT;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_BLACK;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_BRONZE;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_DRAGON;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_DRAGON_ORN;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_INFERNAL;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_IRON;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_MITHRIL;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_RUNE;
+import static net.runelite.api.AnimationID.MINING_MOTHERLODE_STEEL;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameObject;
@@ -48,6 +61,11 @@ import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
import net.runelite.api.ItemID;
+import net.runelite.api.MenuAction;
+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.ORE_VEIN_26661;
import static net.runelite.api.ObjectID.ORE_VEIN_26662;
import static net.runelite.api.ObjectID.ORE_VEIN_26663;
@@ -55,20 +73,27 @@ import static net.runelite.api.ObjectID.ORE_VEIN_26664;
import static net.runelite.api.ObjectID.ROCKFALL;
import static net.runelite.api.ObjectID.ROCKFALL_26680;
import net.runelite.api.Perspective;
+import net.runelite.api.Player;
import net.runelite.api.Varbits;
import net.runelite.api.WallObject;
import net.runelite.api.coords.LocalPoint;
+import net.runelite.api.coords.WorldPoint;
+import net.runelite.api.events.AnimationChanged;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameObjectChanged;
import net.runelite.api.events.GameObjectDespawned;
import net.runelite.api.events.GameObjectSpawned;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.ItemContainerChanged;
+import net.runelite.api.events.GameTick;
+import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.VarbitChanged;
import net.runelite.api.events.WallObjectChanged;
import net.runelite.api.events.WallObjectDespawned;
import net.runelite.api.events.WallObjectSpawned;
+import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
+import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
@@ -88,6 +113,7 @@ public class MotherlodePlugin extends Plugin
{
private static final Set MOTHERLODE_MAP_REGIONS = ImmutableSet.of(14679, 14680, 14681, 14935, 14936, 14937, 15191, 15192, 15193);
private static final Set MINE_SPOTS = ImmutableSet.of(ORE_VEIN_26661, ORE_VEIN_26662, ORE_VEIN_26663, ORE_VEIN_26664);
+ private static final Set DEPLETED_SPOTS = ImmutableSet.of(DEPLETED_VEIN_26665, DEPLETED_VEIN_26666, DEPLETED_VEIN_26667, DEPLETED_VEIN_26668);
private static final Set MLM_ORE_TYPES = ImmutableSet.of(ItemID.RUNITE_ORE, ItemID.ADAMANTITE_ORE,
ItemID.MITHRIL_ORE, ItemID.GOLD_ORE, ItemID.COAL, ItemID.GOLDEN_NUGGET);
private static final Set ROCK_OBSTACLES = ImmutableSet.of(ROCKFALL, ROCKFALL_26680);
@@ -99,6 +125,10 @@ public class MotherlodePlugin extends Plugin
private static final int UPPER_FLOOR_HEIGHT = -500;
+ // The motherlode mining animation has gaps in it during which the animation switches to IDLE
+ // so a minimum threshold is required before the idle animation will be registered as not mining
+ private static final Duration ANIMATION_IDLE_DELAY = Duration.ofMillis(1800);
+
@Inject
private OverlayManager overlayManager;
@@ -146,6 +176,13 @@ public class MotherlodePlugin extends Plugin
@Getter(AccessLevel.PACKAGE)
private final Set rocks = new HashSet<>();
+ @Getter(AccessLevel.PACKAGE)
+ private boolean isMining;
+ private WorldPoint targetVeinLocation = null;
+ private boolean playerHasReachedTargetVein;
+ private int lastAnimation = AnimationID.IDLE;
+ private Instant lastAnimating;
+
@Provides
MotherlodeConfig getConfig(ConfigManager configManager)
{
@@ -277,6 +314,149 @@ public class MotherlodePlugin extends Plugin
}
}
+ @Subscribe
+ public void onMenuOptionClicked(MenuOptionClicked menu)
+ {
+ if (!inMlm)
+ {
+ return;
+ }
+
+ if (MINE_SPOTS.contains(menu.getId()) && menu.getMenuAction() == MenuAction.GAME_OBJECT_FIRST_OPTION)
+ {
+ resetIdleChecks();
+ int veinX = menu.getActionParam();
+ int veinY = menu.getWidgetId();
+ targetVeinLocation = WorldPoint.fromScene(client, veinX, veinY, client.getPlane());
+ }
+ }
+
+ @Subscribe
+ public void onGameTick(GameTick event)
+ {
+ if (!inMlm)
+ {
+ return;
+ }
+
+ checkDistanceToTargetVein();
+ checkAnimationIdle();
+ }
+
+ private void checkDistanceToTargetVein()
+ {
+ if (targetVeinLocation == null)
+ {
+ return;
+ }
+
+ float distanceFromTargetVein = client.getLocalPlayer().getWorldLocation().distanceToHypotenuse(targetVeinLocation);
+ // Player must reach the target vein first before we begin checking for the player moving away from it
+ if (!playerHasReachedTargetVein && distanceFromTargetVein == 1)
+ {
+ isMining = true;
+ playerHasReachedTargetVein = true;
+ }
+ else if (playerHasReachedTargetVein && distanceFromTargetVein > 1)
+ {
+ isMining = false;
+ resetIdleChecks();
+ }
+ }
+
+ @Subscribe
+ public void onAnimationChanged (AnimationChanged event)
+ {
+ if (!inMlm)
+ {
+ return;
+ }
+
+ Player localPlayer = client.getLocalPlayer();
+ if (localPlayer != event.getActor())
+ {
+ return;
+ }
+
+ int animation = localPlayer.getAnimation();
+
+ switch (animation)
+ {
+ case MINING_MOTHERLODE_BRONZE:
+ case MINING_MOTHERLODE_IRON:
+ case MINING_MOTHERLODE_STEEL:
+ case MINING_MOTHERLODE_BLACK:
+ case MINING_MOTHERLODE_MITHRIL:
+ case MINING_MOTHERLODE_ADAMANT:
+ case MINING_MOTHERLODE_RUNE:
+ case MINING_MOTHERLODE_DRAGON:
+ case MINING_MOTHERLODE_DRAGON_ORN:
+ case MINING_MOTHERLODE_INFERNAL:
+ case MINING_MOTHERLODE_3A:
+ lastAnimation = animation;
+ lastAnimating = Instant.now();
+ break;
+ case IDLE:
+ lastAnimating = Instant.now();
+ break;
+ default:
+ // On unknown animation simply assume the animation is invalid
+ lastAnimation = IDLE;
+ lastAnimating = null;
+ }
+ }
+
+ private void checkAnimationIdle()
+ {
+ if (lastAnimation == IDLE)
+ {
+ return;
+ }
+
+ final int animation = client.getLocalPlayer().getAnimation();
+
+ if (animation == IDLE)
+ {
+ if (lastAnimating != null && Instant.now().compareTo(lastAnimating.plus(ANIMATION_IDLE_DELAY)) >= 0)
+ {
+ lastAnimation = IDLE;
+ lastAnimating = null;
+ isMining = false;
+ resetIdleChecks();
+ }
+ }
+ else
+ {
+ lastAnimating = Instant.now();
+ }
+ }
+
+ @Subscribe
+ public void onWidgetLoaded(WidgetLoaded event)
+ {
+ if (!inMlm || targetVeinLocation == null)
+ {
+ return;
+ }
+
+ int widgetID = event.getGroupId();
+
+ if (widgetID == WidgetID.MOTHERLODE_MINE_FULL_INVENTORY_GROUP_ID || widgetID == WidgetID.LEVEL_UP_GROUP_ID)
+ {
+ isMining = false;
+ resetIdleChecks();
+ }
+ }
+
+ private void resetIdleChecks()
+ {
+ isMining = false;
+ lastAnimation = IDLE;
+ lastAnimating = null;
+ playerHasReachedTargetVein = false;
+ targetVeinLocation = null;
+ }
+
@Subscribe
public void onWallObjectSpawned(WallObjectSpawned event)
{
@@ -286,10 +466,16 @@ public class MotherlodePlugin extends Plugin
}
WallObject wallObject = event.getWallObject();
- if (MINE_SPOTS.contains(wallObject.getId()))
+ int wallObjectId = wallObject.getId();
+ if (MINE_SPOTS.contains(wallObjectId))
{
veins.add(wallObject);
}
+ else if (DEPLETED_SPOTS.contains(wallObjectId) && wallObject.getWorldLocation().equals(targetVeinLocation))
+ {
+ isMining = false;
+ resetIdleChecks();
+ }
}
@Subscribe
From 72a7e05eac175dab437fff9f18b5575b0214232c Mon Sep 17 00:00:00 2001
From: Twiglet1022 <29353990+Twiglet1022@users.noreply.github.com>
Date: Sat, 8 Jun 2019 23:48:47 +0100
Subject: [PATCH 4/6] mlm plugin: move idle notification from idle notifier to
mlm plugin
---
.../idlenotifier/IdleNotifierPlugin.java | 12 ------------
.../plugins/motherlode/MotherlodeConfig.java | 10 ++++++++++
.../plugins/motherlode/MotherlodePlugin.java | 17 +++++++++++++++++
.../motherlode/MotherlodePluginTest.java | 15 +++++++++++++++
4 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
index bb7dee8b47..01d4770120 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
@@ -188,18 +188,6 @@ public class IdleNotifierPlugin extends Plugin
case MINING_3A_PICKAXE:
case DENSE_ESSENCE_CHIPPING:
case DENSE_ESSENCE_CHISELING:
- /* Mining(Motherlode) */
- case MINING_MOTHERLODE_BRONZE:
- case MINING_MOTHERLODE_IRON:
- case MINING_MOTHERLODE_STEEL:
- case MINING_MOTHERLODE_BLACK:
- case MINING_MOTHERLODE_MITHRIL:
- case MINING_MOTHERLODE_ADAMANT:
- case MINING_MOTHERLODE_RUNE:
- case MINING_MOTHERLODE_DRAGON:
- case MINING_MOTHERLODE_DRAGON_ORN:
- case MINING_MOTHERLODE_INFERNAL:
- case MINING_MOTHERLODE_3A:
/* Herblore */
case HERBLORE_PESTLE_AND_MORTAR:
case HERBLORE_POTIONMAKING:
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeConfig.java
index 10d41810e4..9581f7b12d 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeConfig.java
@@ -121,4 +121,14 @@ public interface MotherlodeConfig extends Config
{
return true;
}
+
+ @ConfigItem(
+ keyName = "notifyOnIdle",
+ name = "Idle notification",
+ description = "Sends a notification when the player stops mining"
+ )
+ default boolean notifyOnIdle()
+ {
+ return false;
+ }
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
index b910a55ae3..5016b54de7 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
@@ -95,6 +95,7 @@ import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
+import net.runelite.client.Notifier;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
@@ -156,6 +157,9 @@ public class MotherlodePlugin extends Plugin
@Inject
private ClientThread clientThread;
+ @Inject
+ private Notifier notifier;
+
@Getter(AccessLevel.PACKAGE)
private boolean inMlm;
@@ -423,6 +427,7 @@ public class MotherlodePlugin extends Plugin
lastAnimating = null;
isMining = false;
resetIdleChecks();
+ sendIdleNotification();
}
}
else
@@ -445,6 +450,7 @@ public class MotherlodePlugin extends Plugin
{
isMining = false;
resetIdleChecks();
+ sendIdleNotification();
}
}
@@ -457,6 +463,16 @@ public class MotherlodePlugin extends Plugin
targetVeinLocation = null;
}
+ private void sendIdleNotification()
+ {
+ if (!config.notifyOnIdle())
+ {
+ return;
+ }
+
+ notifier.notify(client.getLocalPlayer().getName() + " has stopped mining!");
+ }
+
@Subscribe
public void onWallObjectSpawned(WallObjectSpawned event)
{
@@ -475,6 +491,7 @@ public class MotherlodePlugin extends Plugin
{
isMining = false;
resetIdleChecks();
+ sendIdleNotification();
}
}
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/motherlode/MotherlodePluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/motherlode/MotherlodePluginTest.java
index 9ceaf15247..7f4c3bcbb0 100644
--- a/runelite-client/src/test/java/net/runelite/client/plugins/motherlode/MotherlodePluginTest.java
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/motherlode/MotherlodePluginTest.java
@@ -39,6 +39,9 @@ import net.runelite.api.Varbits;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.VarbitChanged;
+import net.runelite.client.Notifier;
+import net.runelite.client.config.ChatColorConfig;
+import net.runelite.client.config.RuneLiteConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -87,6 +90,18 @@ public class MotherlodePluginTest
@Bind
private ScheduledExecutorService scheduledExecutorService;
+ @Mock
+ @Bind
+ private ChatColorConfig chatColorConfig;
+
+ @Mock
+ @Bind
+ private RuneLiteConfig runeliteConfig;
+
+ @Mock
+ @Bind
+ private Notifier notifier;
+
@Before
public void before()
{
From 0de7cbca4ce14580d3d5975e23b37aaea6728684 Mon Sep 17 00:00:00 2001
From: Twiglet1022 <29353990+Twiglet1022@users.noreply.github.com>
Date: Sun, 9 Jun 2019 00:17:50 +0100
Subject: [PATCH 5/6] image util: add conditional `recolorImage` method
---
.../net/runelite/client/util/ImageUtil.java | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java
index d7f579b722..912489eddd 100644
--- a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java
+++ b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java
@@ -405,6 +405,36 @@ public class ImageUtil
return filledImage;
}
+ /**
+ * Recolors pixels of the given image with the given color based on a given recolor condition
+ * predicate.
+ *
+ * @param image The image which should have its non-transparent pixels recolored.
+ * @param color The color with which to recolor pixels.
+ * @param recolorCondition The condition on which to recolor pixels with the given color.
+ * @return The given image with all pixels fulfilling the recolor condition predicate
+ * set to the given color.
+ */
+ public static BufferedImage recolorImage(final BufferedImage image, final Color color, final Predicate recolorCondition)
+ {
+ final BufferedImage recoloredImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
+ for (int x = 0; x < recoloredImage.getWidth(); x++)
+ {
+ for (int y = 0; y < recoloredImage.getHeight(); y++)
+ {
+ final Color pixelColor = new Color(image.getRGB(x, y), true);
+ if (!recolorCondition.test(pixelColor))
+ {
+ recoloredImage.setRGB(x, y, image.getRGB(x, y));
+ continue;
+ }
+
+ recoloredImage.setRGB(x, y, color.getRGB());
+ }
+ }
+ return recoloredImage;
+ }
+
/**
* Performs a rescale operation on the image's color components.
*
From f765bff6f9bb096dc0f3e5fb37ee07a326ca35d6 Mon Sep 17 00:00:00 2001
From: Twiglet1022 <29353990+Twiglet1022@users.noreply.github.com>
Date: Sun, 9 Jun 2019 00:19:49 +0100
Subject: [PATCH 6/6] mlm plugin: add option to recolor the icon on the vein
being mined
---
.../plugins/motherlode/MotherlodeConfig.java | 11 ++++++++
.../plugins/motherlode/MotherlodePlugin.java | 1 +
.../motherlode/MotherlodeRocksOverlay.java | 27 +++++++++++++++----
3 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeConfig.java
index 9581f7b12d..bc4f4269ec 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeConfig.java
@@ -131,4 +131,15 @@ public interface MotherlodeConfig extends Config
{
return false;
}
+
+ @ConfigItem(
+ keyName = "showTargetVein",
+ name = "Show vein currently being mined",
+ description = "Highlights the vein currently being mined"
+ )
+ default boolean showTargetVein()
+ {
+ return false;
+ }
+
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
index 5016b54de7..298f9433d4 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java
@@ -182,6 +182,7 @@ public class MotherlodePlugin extends Plugin
@Getter(AccessLevel.PACKAGE)
private boolean isMining;
+ @Getter(AccessLevel.PACKAGE)
private WorldPoint targetVeinLocation = null;
private boolean playerHasReachedTargetVein;
private int lastAnimation = AnimationID.IDLE;
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeRocksOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeRocksOverlay.java
index 28b131aa06..88f27eb3d6 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeRocksOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodeRocksOverlay.java
@@ -40,11 +40,13 @@ import net.runelite.api.Point;
import net.runelite.api.Skill;
import net.runelite.api.WallObject;
import net.runelite.api.coords.LocalPoint;
+import net.runelite.api.coords.WorldPoint;
import net.runelite.client.game.SkillIconManager;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
+import net.runelite.client.util.ImageUtil;
class MotherlodeRocksOverlay extends Overlay
{
@@ -55,6 +57,9 @@ class MotherlodeRocksOverlay extends Overlay
private final MotherlodeConfig config;
private final BufferedImage miningIcon;
+ private final BufferedImage targetMiningIcon;
+ private static final Color miningIconOldColor = new Color(117, 123, 124);
+ private static final Color miningIconNewColor = new Color(0, 150, 0);
@Inject
MotherlodeRocksOverlay(Client client, MotherlodePlugin plugin, MotherlodeConfig config, SkillIconManager iconManager)
@@ -66,6 +71,7 @@ class MotherlodeRocksOverlay extends Overlay
this.config = config;
miningIcon = iconManager.getSkillImage(Skill.MINING);
+ targetMiningIcon = ImageUtil.recolorImage(miningIcon, miningIconNewColor, Color -> Color.getRGB() == miningIconOldColor.getRGB());
}
@Override
@@ -86,7 +92,6 @@ class MotherlodeRocksOverlay extends Overlay
private void renderTiles(Graphics2D graphics, Player local)
{
LocalPoint localLocation = local.getLocalLocation();
-
if (config.showVeins())
{
for (WallObject vein : plugin.getVeins())
@@ -97,7 +102,16 @@ class MotherlodeRocksOverlay extends Overlay
// Only draw veins on the same level
if (plugin.isUpstairs(localLocation) == plugin.isUpstairs(vein.getLocalLocation()))
{
- renderVein(graphics, vein);
+ if (WorldPoint.fromLocal(client, location).equals(plugin.getTargetVeinLocation())
+ && plugin.isMining()
+ && config.showTargetVein())
+ {
+ renderVein(graphics, vein, true);
+ }
+ else
+ {
+ renderVein(graphics, vein, false);
+ }
}
}
}
@@ -114,17 +128,20 @@ class MotherlodeRocksOverlay extends Overlay
}
}
}
-
}
- private void renderVein(Graphics2D graphics, WallObject vein)
+ private void renderVein(Graphics2D graphics, WallObject vein, Boolean shouldRecolor)
{
Point canvasLoc = Perspective.getCanvasImageLocation(client, vein.getLocalLocation(), miningIcon, 150);
- if (canvasLoc != null)
+ if (canvasLoc != null && !shouldRecolor)
{
graphics.drawImage(miningIcon, canvasLoc.getX(), canvasLoc.getY(), null);
}
+ else if (canvasLoc != null)
+ {
+ graphics.drawImage(targetMiningIcon, canvasLoc.getX(), canvasLoc.getY(), null);
+ }
}
private void renderRock(Graphics2D graphics, GameObject rock)