From 9313747479f6330566248f2b938ad5ca30159e82 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Thu, 22 Feb 2018 09:38:42 +0100 Subject: [PATCH 1/2] Prevent throwing duplacite events for GameObject Store last gameObject as static variable in tile mixin and in case new event is exactly same as last one in game object spawned, do not proceed. Signed-off-by: Tomas Slusny --- .../java/net/runelite/mixins/RSTileMixin.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 a1a76aff89..9ee17a68ee 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java @@ -58,6 +58,9 @@ public abstract class RSTileMixin implements RSTile @Shadow("clientInstance") private static RSClient client; + @Inject + private static GameObject lastGameObject; + @Inject private WallObject previousWallObject; @@ -208,12 +211,25 @@ public abstract class RSTileMixin implements RSTile // Previous game object GameObject 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)) + { + return; + } + // Characters seem to generate a constant stream of new GameObjects if (current == null || !(current.getRenderable() instanceof Actor)) { From 807a38d7693cb93da61382579f58f48d760bf0bc Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Wed, 21 Feb 2018 23:04:26 +0100 Subject: [PATCH 2/2] Add support for maniacal monkeys to hunter plugin - Add support for maniacal monkey large boulder traps to hunter plugin - Add support for notifications on maniacal monkey catch/escape Signed-off-by: Tomas Slusny --- .../java/net/runelite/api/AnimationID.java | 1 + .../plugins/hunter/CatchrateOverlay.java | 4 +- .../client/plugins/hunter/HunterConfig.java | 11 ++ .../client/plugins/hunter/HunterPlugin.java | 105 ++++++++++++------ .../client/plugins/hunter/HunterTrap.java | 2 +- 5 files changed, 87 insertions(+), 36 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java index b4f64915b7..61bbc7e42c 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -46,6 +46,7 @@ public final class AnimationID public static final int HUNTER_LAY_BOXTRAP_BIRDSNARE = 5208; //same for laying bird snares and box traps public static final int HUNTER_LAY_DEADFALLTRAP = 5212; //setting up deadfall trap public static final int HUNTER_LAY_NETTRAP = 5215; //setting up net trap + public static final int HUNTER_LAY_MANIACAL_MONKEY_BOULDER_TRAP = 7259; // setting up maniacal monkey boulder trap public static final int HUNTER_CHECK_BIRD_SNARE = 5207; public static final int HUNTER_CHECK_BOX_TRAP = 5212; public static final int HERBLORE_MAKE_TAR = 5249; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/CatchrateOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/CatchrateOverlay.java index ab7a5bb944..cdf8469a1a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/CatchrateOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/CatchrateOverlay.java @@ -47,14 +47,12 @@ public class CatchrateOverlay extends Overlay private final PanelComponent catchRatePanel = new PanelComponent(); private final HunterPlugin plugin; - private final HunterConfig config; @Inject - CatchrateOverlay(HunterPlugin plugin, HunterConfig config) + CatchrateOverlay(HunterPlugin plugin) { setPosition(OverlayPosition.BOTTOM_RIGHT); this.plugin = plugin; - this.config = config; } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterConfig.java index d3f376ea6e..91d7f94f8c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterConfig.java @@ -79,4 +79,15 @@ public interface HunterConfig extends Config { return Color.ORANGE; } + + @ConfigItem( + position = 5, + keyName = "maniacalMonkeyNotify", + name = "Maniacal monkey notification", + description = "Send notification when maniacal monkey is caught or you fail to catch." + ) + default boolean maniacalMonkeyNotify() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterPlugin.java index 2c8cf113bb..5849502a75 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterPlugin.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.hunter; import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import java.time.Instant; -import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -40,19 +39,18 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.AnimationID; import net.runelite.api.Client; import net.runelite.api.GameObject; -import net.runelite.api.GameState; import net.runelite.api.ObjectID; import net.runelite.api.Player; import net.runelite.api.Point; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameObjectSpawned; -import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; import net.runelite.api.queries.GameObjectQuery; import net.runelite.api.queries.PlayerQuery; +import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.task.Schedule; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.util.QueryRunner; @@ -74,6 +72,12 @@ public class HunterPlugin extends Plugin @Inject private CatchrateOverlay catchrateOverlay; + @Inject + private Notifier notifier; + + @Inject + private HunterConfig config; + @Getter private final Set traps = new HashSet<>(); @@ -95,6 +99,12 @@ public class HunterPlugin extends Plugin return Arrays.asList(trapOverlay, catchrateOverlay); } + @Override + protected void startUp() + { + trapOverlay.updateConfig(); + } + @Override protected void shutDown() throws Exception { @@ -108,13 +118,16 @@ public class HunterPlugin extends Plugin public void onGameObjectSpawned(GameObjectSpawned event) { GameObject gameObject = event.getGameObject(); - HunterTrap myTrap = getTrapFromCollection(gameObject); - Player localPlayer = client.getLocalPlayer(); switch (gameObject.getId()) { + /* + * ------------------------------------------------------------------------------ + * Placing traps + * ------------------------------------------------------------------------------ + */ case ObjectID.DEADFALL: //Deadfall trap placed if (localPlayer.getWorldLocation().distanceTo(gameObject.getWorldLocation()) <= 2 && localPlayer.getAnimation() == AnimationID.HUNTER_LAY_DEADFALLTRAP) @@ -124,6 +137,15 @@ public class HunterPlugin extends Plugin lastActionTime = Instant.now(); } break; + case ObjectID.MONKEY_TRAP: // Maniacal monkey trap placed + if (localPlayer.getWorldLocation().distanceTo(gameObject.getWorldLocation()) < 2) + { + log.debug("Maniacal monkey trap placed by \"{}\" on {} of {}", localPlayer.getName(), + gameObject.getWorldLocation(), gameObject); + traps.add(new HunterTrap(gameObject)); + lastActionTime = Instant.now(); + } + break; case ObjectID.MAGIC_BOX: // Imp box placed case ObjectID.BOX_TRAP_9380: //Box trap placed case ObjectID.BIRD_SNARE_9345: //Bird snare placed @@ -155,6 +177,11 @@ public class HunterPlugin extends Plugin } break; + /* + * ------------------------------------------------------------------------------ + * Catching stuff + * ------------------------------------------------------------------------------ + */ case ObjectID.MAGIC_BOX_19226: // Imp caught case ObjectID.SHAKING_BOX: //Black chinchompa caught case ObjectID.SHAKING_BOX_9382: // Grey chinchompa caught @@ -172,16 +199,27 @@ public class HunterPlugin extends Plugin case ObjectID.NET_TRAP_8986: //Red sally caught case ObjectID.NET_TRAP_8734: //Orange sally caught case ObjectID.NET_TRAP_8996: //Black sally caught + case ObjectID.LARGE_BOULDER_28830: // Maniacal monkey tail obtained + case ObjectID.LARGE_BOULDER_28831: // Maniacal monkey tail obtained if (myTrap != null) { log.debug("Yay, you caught something"); myTrap.setState(HunterTrap.State.FULL); catchAtempts++; catchSuccess++; - lastActionTime = Instant.now(); + + if (config.maniacalMonkeyNotify() && myTrap.getGameObject().getId() == ObjectID.MONKEY_TRAP) + { + notifier.notify("You've caught part of a monkey's tail."); + } } break; + /* + * ------------------------------------------------------------------------------ + * Failed catch + * ------------------------------------------------------------------------------ + */ case ObjectID.MAGIC_BOX_FAILED: //Empty imp box case ObjectID.BOX_TRAP_9385: //Empty box trap case ObjectID.BIRD_SNARE: //Empty box trap @@ -195,6 +233,11 @@ public class HunterPlugin extends Plugin lastActionTime = Instant.now(); } break; + /* + * ------------------------------------------------------------------------------ + * Transitions + * ------------------------------------------------------------------------------ + */ // Imp entering box case ObjectID.MAGIC_BOX_19225: @@ -241,6 +284,10 @@ public class HunterPlugin extends Plugin case ObjectID.NET_TRAP_8987: case ObjectID.NET_TRAP_8993: case ObjectID.NET_TRAP_8997: + + // Maniacal monkey boulder trap + case ObjectID.MONKEY_TRAP_28828: + case ObjectID.MONKEY_TRAP_28829: if (myTrap != null) { myTrap.setState(HunterTrap.State.TRANSITION); @@ -249,34 +296,13 @@ public class HunterPlugin extends Plugin } } - @Subscribe - public void onGameStateChange(GameStateChanged event) - { - if (event.getGameState().equals(GameState.LOGIN_SCREEN)) - { - trapOverlay.updateConfig(); - } - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (event.getGroup().equals("hunterplugin")) - { - trapOverlay.updateConfig(); - } - } - /** * Iterates over all the traps that were placed by the local player and * checks if the trap is still there. If the trap is gone, it removes * the trap from the local players trap collection. */ - @Schedule( - period = 500, - unit = ChronoUnit.MILLIS - ) - public void updateTraps() + @Subscribe + public void onGameTick(GameTick event) { //Check if all traps are still there, and remove the ones that are not. //TODO: use despawn events @@ -296,18 +322,33 @@ public class HunterPlugin extends Plugin } else //For traps like deadfalls. This is different because when the trap is gone, there is still a GameObject (boulder) { - goQuery = goQuery - .idEquals(ObjectID.BOULDER_19215); //Deadfalls are the only ones (that i can test) that have this behaviour. I think maniacal monkeys have this too. + goQuery = goQuery.idEquals(ObjectID.BOULDER_19215, ObjectID.LARGE_BOULDER); if (queryRunner.runQuery(goQuery).length != 0) { it.remove(); log.debug("Special trap removed from personal trap collection, {} left", traps.size()); + + // Case we have notifications enabled and the action was not manual, throw notification + if (config.maniacalMonkeyNotify() && trap.getGameObject().getId() == ObjectID.MONKEY_TRAP && + !trap.getState().equals(HunterTrap.State.FULL) && !trap.getState().equals(HunterTrap.State.OPEN)) + { + notifier.notify("The monkey escaped."); + } } } } } + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals("hunterplugin")) + { + trapOverlay.updateConfig(); + } + } + /** * Looks for a trap in the local players trap collection, on the same * place as the given GameObject. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterTrap.java b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterTrap.java index e089ed6964..10d9a3ba37 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterTrap.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterTrap.java @@ -134,7 +134,7 @@ class HunterTrap public int hashCode() { int hash = 7; - hash = 97 * hash + Objects.hashCode(this.gameObject); + hash = 97 * hash + Objects.hashCode(this.gameObject.getWorldLocation()); return hash; } }