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] 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