diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNet.java b/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNet.java index 8a5dfdfeeb..99dd0356e1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNet.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNet.java @@ -25,10 +25,13 @@ */ package net.runelite.client.plugins.driftnet; +import java.util.Set; import lombok.Data; import lombok.RequiredArgsConstructor; +import lombok.Setter; import net.runelite.api.GameObject; import net.runelite.api.Varbits; +import net.runelite.api.coords.WorldPoint; @Data @RequiredArgsConstructor @@ -37,10 +40,23 @@ class DriftNet private final int objectId; private final Varbits statusVarbit; private final Varbits countVarbit; + private final Set adjacentTiles; private GameObject net; private DriftNetStatus status; private int count; + @Setter + private DriftNetStatus prevTickStatus; + + // Nets that are not accepting fish are those currently not accepting, or those which were not + // accepting in the previous tick. (When a fish shoal is 2 tiles adjacent to a drift net and is + // moving to a net that is just being setup it will be denied even though the net is currently + // in the CATCHING status) + boolean isNotAcceptingFish() + { + return (status != DriftNetStatus.CATCH && status != DriftNetStatus.SET) || + (prevTickStatus != DriftNetStatus.CATCH && prevTickStatus != DriftNetStatus.SET); + } String getFormattedCountText() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetConfig.java index e5f9756de8..5ca1f29194 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetConfig.java @@ -76,12 +76,12 @@ public interface DriftNetConfig extends Config ) @Range( min = 1, - max = 60 + max = 100 ) @Units(Units.TICKS) default int timeoutDelay() { - return 10; + return 60; } @ConfigItem( @@ -94,4 +94,26 @@ public interface DriftNetConfig extends Config { return Color.CYAN; } + + @ConfigItem( + keyName = "tagAnnette", + name = "Tag Annette when no nets in inventory", + description = "Tag Annette when no nets in inventory", + position = 6 + ) + default boolean tagAnnetteWhenNoNets() + { + return true; + } + + @ConfigItem( + keyName = "annetteTagColor", + name = "Annette tag color", + description = "Color of Annette tag", + position = 7 + ) + default Color annetteTagColor() + { + return Color.RED; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetOverlay.java index d01c88344c..1ff9e117f8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetOverlay.java @@ -28,6 +28,7 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Shape; import javax.inject.Inject; +import net.runelite.api.GameObject; import net.runelite.api.NPC; import net.runelite.api.Point; import net.runelite.client.ui.overlay.Overlay; @@ -67,6 +68,10 @@ class DriftNetOverlay extends Overlay { renderNets(graphics); } + if (config.tagAnnetteWhenNoNets()) + { + renderAnnette(graphics); + } return null; } @@ -101,4 +106,13 @@ class DriftNetOverlay extends Overlay } } } + + private void renderAnnette(Graphics2D graphics) + { + GameObject annette = plugin.getAnnette(); + if (annette != null && !plugin.isDriftNetsInInventory()) + { + OverlayUtil.renderPolygon(graphics, annette.getConvexHull(), config.annetteTagColor()); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetPlugin.java index 8dd6ff16b9..b7eecf2545 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/driftnet/DriftNetPlugin.java @@ -26,12 +26,15 @@ package net.runelite.client.plugins.driftnet; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import javax.inject.Inject; import lombok.Getter; import net.runelite.api.Actor; @@ -39,9 +42,13 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameObject; import net.runelite.api.GameState; +import net.runelite.api.InventoryID; +import net.runelite.api.ItemContainer; +import net.runelite.api.ItemID; import net.runelite.api.NPC; import net.runelite.api.NpcID; import net.runelite.api.NullObjectID; +import net.runelite.api.ObjectID; import net.runelite.api.Player; import net.runelite.api.Varbits; import net.runelite.api.coords.WorldPoint; @@ -51,6 +58,7 @@ import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.InteractingChanged; +import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.VarbitChanged; @@ -94,13 +102,30 @@ public class DriftNetPlugin extends Plugin private Map taggedFish = new HashMap<>(); @Getter private final List NETS = ImmutableList.of( - new DriftNet(NullObjectID.NULL_31433, Varbits.NORTH_NET_STATUS, Varbits.NORTH_NET_CATCH_COUNT), - new DriftNet(NullObjectID.NULL_31434, Varbits.SOUTH_NET_STATUS, Varbits.SOUTH_NET_CATCH_COUNT)); + new DriftNet(NullObjectID.NULL_31433, Varbits.NORTH_NET_STATUS, Varbits.NORTH_NET_CATCH_COUNT, ImmutableSet.of( + new WorldPoint(3746, 10297, 1), + new WorldPoint(3747, 10297, 1), + new WorldPoint(3748, 10297, 1), + new WorldPoint(3749, 10297, 1) + )), + new DriftNet(NullObjectID.NULL_31434, Varbits.SOUTH_NET_STATUS, Varbits.SOUTH_NET_CATCH_COUNT, ImmutableSet.of( + new WorldPoint(3742, 10288, 1), + new WorldPoint(3742, 10289, 1), + new WorldPoint(3742, 10290, 1), + new WorldPoint(3742, 10291, 1), + new WorldPoint(3742, 10292, 1) + ))); @Getter private boolean inDriftNetArea; private boolean armInteraction; + @Getter + private boolean driftNetsInInventory; + + @Getter + private GameObject annette; + @Provides DriftNetConfig provideConfig(ConfigManager configManager) { @@ -132,6 +157,10 @@ public class DriftNetPlugin extends Plugin @Subscribe public void onGameStateChanged(GameStateChanged event) { + if (event.getGameState() != GameState.LOGGED_IN) + { + annette = null; + } switch (event.getGameState()) { case LOGIN_SCREEN: @@ -175,12 +204,6 @@ public class DriftNetPlugin extends Plugin net.setStatus(status); net.setCount(count); } - - // When you collect any loot, all tags become invalidated - if (client.getVar(Varbits.DRIFT_NET_COLLECT) != 0) - { - taggedFish.clear(); - } } @Subscribe @@ -196,6 +219,17 @@ public class DriftNetPlugin extends Plugin } } + private boolean isFishNextToNet(NPC fish, Collection nets) + { + final WorldPoint fishTile = WorldPoint.fromLocalInstance(client, fish.getLocalLocation()); + return nets.stream().anyMatch(net -> net.getAdjacentTiles().contains(fishTile)); + } + + private boolean isTagExpired(Integer tick) + { + return tick + config.timeoutDelay() < client.getTickCount(); + } + @Subscribe public void onGameTick(GameTick tick) { @@ -204,8 +238,16 @@ public class DriftNetPlugin extends Plugin return; } - final int currentTickCount = client.getTickCount(); - taggedFish.entrySet().removeIf(entry -> entry.getValue() + config.timeoutDelay() < currentTickCount); + List closedNets = NETS.stream() + .filter(DriftNet::isNotAcceptingFish) + .collect(Collectors.toList()); + + taggedFish.entrySet().removeIf(entry -> + isTagExpired(entry.getValue()) || + isFishNextToNet(entry.getKey(), closedNets) + ); + + NETS.forEach(net -> net.setPrevTickStatus(net.getStatus())); armInteraction = false; } @@ -256,12 +298,18 @@ public class DriftNetPlugin extends Plugin { final NPC npc = event.getNpc(); fish.remove(npc); + taggedFish.remove(npc); } @Subscribe public void onGameObjectSpawned(GameObjectSpawned event) { GameObject object = event.getGameObject(); + if (object.getId() == ObjectID.ANNETTE) + { + annette = object; + } + for (DriftNet net : NETS) { if (net.getObjectId() == object.getId()) @@ -275,6 +323,11 @@ public class DriftNetPlugin extends Plugin public void onGameObjectDespawned(GameObjectDespawned event) { GameObject object = event.getGameObject(); + if (object == annette) + { + annette = null; + } + for (DriftNet net : NETS) { if (net.getObjectId() == object.getId()) @@ -284,6 +337,18 @@ public class DriftNetPlugin extends Plugin } } + @Subscribe + public void onItemContainerChanged(final ItemContainerChanged event) + { + final ItemContainer itemContainer = event.getItemContainer(); + if (itemContainer != client.getItemContainer(InventoryID.INVENTORY)) + { + return; + } + + driftNetsInInventory = itemContainer.contains(ItemID.DRIFT_NET); + } + private boolean checkArea() { final Player localPlayer = client.getLocalPlayer();