Merge pull request #607 from runelite-extended/newupdates
Updated Motherload Mine
This commit is contained in:
@@ -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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -91,6 +91,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;
|
||||
|
||||
@@ -99,17 +99,6 @@ import static net.runelite.api.AnimationID.MINING_DRAGON_PICKAXE_ORN;
|
||||
import static net.runelite.api.AnimationID.MINING_INFERNAL_PICKAXE;
|
||||
import static net.runelite.api.AnimationID.MINING_IRON_PICKAXE;
|
||||
import static net.runelite.api.AnimationID.MINING_MITHRIL_PICKAXE;
|
||||
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 static net.runelite.api.AnimationID.MINING_RUNE_PICKAXE;
|
||||
import static net.runelite.api.AnimationID.MINING_STEEL_PICKAXE;
|
||||
import static net.runelite.api.AnimationID.PISCARILIUS_CRANE_REPAIR;
|
||||
@@ -295,19 +284,7 @@ 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 */
|
||||
/* Herblore */
|
||||
case HERBLORE_PESTLE_AND_MORTAR:
|
||||
case HERBLORE_POTIONMAKING:
|
||||
case HERBLORE_MAKE_TAR:
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.time.Instant;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
@@ -43,6 +45,13 @@ import net.runelite.client.ui.overlay.components.ProgressPieComponent;
|
||||
|
||||
class MiningOverlay extends Overlay
|
||||
{
|
||||
// Range of Motherlode vein respawn time not 100% confirmed but based on observation
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private static final int ORE_VEIN_MAX_RESPAWN_TIME = 123;
|
||||
private static final int ORE_VEIN_MIN_RESPAWN_TIME = 90;
|
||||
private static final float ORE_VEIN_RANDOM_PERCENT_THRESHOLD = (float) ORE_VEIN_MIN_RESPAWN_TIME / ORE_VEIN_MAX_RESPAWN_TIME;
|
||||
private static final Color DARK_GREEN = new Color(0, 100, 0);
|
||||
|
||||
private final Client client;
|
||||
private final MiningPlugin plugin;
|
||||
|
||||
@@ -67,6 +76,8 @@ class MiningOverlay extends Overlay
|
||||
Instant now = Instant.now();
|
||||
for (Iterator<RockRespawn> it = respawns.iterator(); it.hasNext();)
|
||||
{
|
||||
Color pieFillColor = Color.YELLOW;
|
||||
Color pieBorderColor = Color.ORANGE;
|
||||
RockRespawn rockRespawn = it.next();
|
||||
float percent = (now.toEpochMilli() - rockRespawn.getStartTime().toEpochMilli()) / (float) rockRespawn.getRespawnTime();
|
||||
WorldPoint worldPoint = rockRespawn.getWorldPoint();
|
||||
@@ -84,9 +95,16 @@ class MiningOverlay extends Overlay
|
||||
continue;
|
||||
}
|
||||
|
||||
// Recolour pie on motherlode veins during the portion of the timer where they may respawn
|
||||
if (rockRespawn.getRock() == Rock.ORE_VEIN && percent > ORE_VEIN_RANDOM_PERCENT_THRESHOLD)
|
||||
{
|
||||
pieFillColor = Color.GREEN;
|
||||
pieBorderColor = DARK_GREEN;
|
||||
}
|
||||
|
||||
ProgressPieComponent ppc = new ProgressPieComponent();
|
||||
ppc.setBorderColor(Color.ORANGE);
|
||||
ppc.setFill(Color.YELLOW);
|
||||
ppc.setBorderColor(pieBorderColor);
|
||||
ppc.setFill(pieFillColor);
|
||||
ppc.setPosition(point);
|
||||
ppc.setProgress(percent);
|
||||
ppc.render(graphics);
|
||||
|
||||
@@ -39,7 +39,12 @@ 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 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;
|
||||
import static net.runelite.api.ObjectID.ORE_VEIN_26664;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
@@ -158,6 +163,15 @@ public class MiningPlugin extends Plugin
|
||||
respawns.add(rockRespawn);
|
||||
break;
|
||||
}
|
||||
case ORE_VEIN_26661: // Motherlode vein
|
||||
case ORE_VEIN_26662: // Motherlode vein
|
||||
case ORE_VEIN_26663: // Motherlode vein
|
||||
case ORE_VEIN_26664: // Motherlode vein
|
||||
{
|
||||
final WorldPoint point = object.getWorldLocation();
|
||||
respawns.removeIf(rockRespawn -> rockRespawn.getWorldPoint().equals(point));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ enum Rock
|
||||
return inMiningGuild ? Duration.ofMinutes(6) : super.respawnTime;
|
||||
}
|
||||
},
|
||||
ORE_VEIN(Duration.ofSeconds(108), 150),
|
||||
ORE_VEIN(Duration.ofSeconds(MiningOverlay.getORE_VEIN_MAX_RESPAWN_TIME()), 150),
|
||||
AMETHYST(Duration.ofSeconds(75), 120);
|
||||
|
||||
private static final Map<Integer, Rock> ROCKS;
|
||||
|
||||
@@ -121,4 +121,25 @@ 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;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showTargetVein",
|
||||
name = "Show vein currently being mined",
|
||||
description = "Highlights the vein currently being mined"
|
||||
)
|
||||
default boolean showTargetVein()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -43,13 +40,6 @@ import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
|
||||
class MotherlodeOverlay extends Overlay
|
||||
{
|
||||
private static final Set<Integer> 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;
|
||||
@@ -94,7 +84,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")
|
||||
|
||||
@@ -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,21 +73,29 @@ 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.Notifier;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
@@ -88,6 +114,7 @@ public class MotherlodePlugin extends Plugin
|
||||
{
|
||||
private static final Set<Integer> MOTHERLODE_MAP_REGIONS = ImmutableSet.of(14679, 14680, 14681, 14935, 14936, 14937, 15191, 15192, 15193);
|
||||
private static final Set<Integer> MINE_SPOTS = ImmutableSet.of(ORE_VEIN_26661, ORE_VEIN_26662, ORE_VEIN_26663, ORE_VEIN_26664);
|
||||
private static final Set<Integer> DEPLETED_SPOTS = ImmutableSet.of(DEPLETED_VEIN_26665, DEPLETED_VEIN_26666, DEPLETED_VEIN_26667, DEPLETED_VEIN_26668);
|
||||
private static final Set<Integer> 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<Integer> ROCK_OBSTACLES = ImmutableSet.of(ROCKFALL, ROCKFALL_26680);
|
||||
@@ -99,6 +126,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;
|
||||
|
||||
@@ -126,6 +157,9 @@ public class MotherlodePlugin extends Plugin
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean inMlm;
|
||||
|
||||
@@ -146,6 +180,14 @@ public class MotherlodePlugin extends Plugin
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Set<GameObject> rocks = new HashSet<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean isMining;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private WorldPoint targetVeinLocation = null;
|
||||
private boolean playerHasReachedTargetVein;
|
||||
private int lastAnimation = AnimationID.IDLE;
|
||||
private Instant lastAnimating;
|
||||
|
||||
@Provides
|
||||
MotherlodeConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -278,6 +320,161 @@ 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();
|
||||
sendIdleNotification();
|
||||
}
|
||||
}
|
||||
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();
|
||||
sendIdleNotification();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetIdleChecks()
|
||||
{
|
||||
isMining = false;
|
||||
lastAnimation = IDLE;
|
||||
lastAnimating = null;
|
||||
playerHasReachedTargetVein = false;
|
||||
targetVeinLocation = null;
|
||||
}
|
||||
|
||||
private void sendIdleNotification()
|
||||
{
|
||||
if (!config.notifyOnIdle())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
notifier.notify(client.getLocalPlayer().getName() + " has stopped mining!");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWallObjectSpawned(WallObjectSpawned event)
|
||||
{
|
||||
@@ -287,10 +484,17 @@ 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();
|
||||
sendIdleNotification();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,17 +129,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)
|
||||
|
||||
@@ -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<Color> 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.
|
||||
*
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user