diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerConfig.java index 11a66081ec..30b3b68532 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerConfig.java @@ -175,4 +175,40 @@ public interface SlayerConfig extends Config description = "" ) void points(int points); + + @ConfigItem( + keyName = "expeditious", + name = "", + description = "", + hidden = true + ) + default int expeditious() + { + return -1; + } + + @ConfigItem( + keyName = "expeditious", + name = "", + description = "" + ) + void expeditious(int expeditious); + + @ConfigItem( + keyName = "slaughter", + name = "", + description = "", + hidden = true + ) + default int slaughter() + { + return -1; + } + + @ConfigItem( + keyName = "slaughter", + name = "", + description = "" + ) + void slaughter(int slaughter); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java index 7238c6595d..d502615186 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java @@ -24,9 +24,7 @@ */ package net.runelite.client.plugins.slayer; -import static com.google.common.collect.ObjectArrays.concat; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Sets; +import com.google.common.collect.ImmutableSet; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; @@ -35,25 +33,19 @@ import java.util.Collection; import java.util.Set; import javax.inject.Inject; import net.runelite.api.ItemID; -import net.runelite.api.Query; -import net.runelite.api.queries.EquipmentItemQuery; -import net.runelite.api.queries.InventoryWidgetItemQuery; -import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.ui.FontManager; 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.components.TextComponent; -import net.runelite.client.util.QueryRunner; class SlayerOverlay extends Overlay { - private final QueryRunner queryRunner; private final SlayerConfig config; private final SlayerPlugin plugin; - private final Set slayerJewelry = Sets.newHashSet( + private final Set slayerJewelry = ImmutableSet.of( ItemID.SLAYER_RING_1, ItemID.SLAYER_RING_2, ItemID.SLAYER_RING_3, @@ -64,7 +56,7 @@ class SlayerOverlay extends Overlay ItemID.SLAYER_RING_8 ); - private final Set slayerEquipment = Sets.newHashSet( + private final Set slayerEquipment = ImmutableSet.of( ItemID.SLAYER_HELMET, ItemID.SLAYER_HELMET_I, ItemID.BLACK_SLAYER_HELMET, @@ -79,15 +71,16 @@ class SlayerOverlay extends Overlay ItemID.TURQUOISE_SLAYER_HELMET_I, ItemID.SLAYER_RING_ETERNAL, ItemID.ENCHANTED_GEM, - ItemID.ETERNAL_GEM + ItemID.ETERNAL_GEM, + ItemID.BRACELET_OF_SLAUGHTER, + ItemID.EXPEDITIOUS_BRACELET ); @Inject - SlayerOverlay(QueryRunner queryRunner, SlayerPlugin plugin, SlayerConfig config) + private SlayerOverlay(SlayerPlugin plugin, SlayerConfig config) { setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_WIDGETS); - this.queryRunner = queryRunner; this.plugin = plugin; this.config = config; } @@ -106,9 +99,13 @@ class SlayerOverlay extends Overlay return null; } + int slaughterCount = plugin.getSlaughterChargeCount(); + int expeditiousCount = plugin.getExpeditiousChargeCount(); + graphics.setFont(FontManager.getRunescapeSmallFont()); - for (WidgetItem item : getSlayerWidgetItems()) + Collection items = plugin.getSlayerItems(); + for (WidgetItem item : items) { int itemId = item.getId(); @@ -119,7 +116,20 @@ class SlayerOverlay extends Overlay final Rectangle bounds = item.getCanvasBounds(); final TextComponent textComponent = new TextComponent(); - textComponent.setText(String.valueOf(amount)); + + switch (item.getId()) + { + case ItemID.EXPEDITIOUS_BRACELET: + textComponent.setText(String.valueOf(expeditiousCount)); + break; + case ItemID.BRACELET_OF_SLAUGHTER: + textComponent.setText(String.valueOf(slaughterCount)); + break; + default: + textComponent.setText(String.valueOf(amount)); + break; + } + // Draw the counter in the bottom left for equipment, and top left for jewelry textComponent.setPosition(new Point(bounds.x, bounds.y + (slayerJewelry.contains(itemId) ? bounds.height @@ -129,16 +139,4 @@ class SlayerOverlay extends Overlay return null; } - - private Collection getSlayerWidgetItems() - { - Query inventoryQuery = new InventoryWidgetItemQuery(); - WidgetItem[] inventoryWidgetItems = queryRunner.runQuery(inventoryQuery); - - Query equipmentQuery = new EquipmentItemQuery().slotEquals(WidgetInfo.EQUIPMENT_HELMET, WidgetInfo.EQUIPMENT_RING); - WidgetItem[] equipmentWidgetItems = queryRunner.runQuery(equipmentQuery); - - WidgetItem[] items = concat(inventoryWidgetItems, equipmentWidgetItems, WidgetItem.class); - return ImmutableList.copyOf(items); - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java index 1e0f88d00d..2a2465de3b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java @@ -25,6 +25,8 @@ */ package net.runelite.client.plugins.slayer; +import com.google.common.collect.ImmutableList; +import static com.google.common.collect.ObjectArrays.concat; import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import java.awt.image.BufferedImage; @@ -41,6 +43,7 @@ import javax.inject.Inject; import joptsimple.internal.Strings; import lombok.AccessLevel; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; @@ -48,14 +51,18 @@ import net.runelite.api.GameState; import net.runelite.api.ItemID; import net.runelite.api.NPC; import net.runelite.api.NPCComposition; +import net.runelite.api.Query; import static net.runelite.api.Skill.SLAYER; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ExperienceChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; +import net.runelite.api.queries.EquipmentItemQuery; +import net.runelite.api.queries.InventoryWidgetItemQuery; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetItem; import net.runelite.client.Notifier; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; @@ -64,6 +71,7 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.util.QueryRunner; import net.runelite.client.util.Text; @PluginDescriptor( @@ -80,6 +88,8 @@ public class SlayerPlugin extends Plugin private static final String CHAT_SUPERIOR_MESSAGE = "A superior foe has appeared..."; private static final String CHAT_BRACELET_SLAUGHTER = "Your bracelet of slaughter prevents your slayer count decreasing."; private static final String CHAT_BRACELET_EXPEDITIOUS = "Your expeditious bracelet helps you progress your slayer task faster."; + private static final String CHAT_BRACELET_SLAUGHTER_CHARGE = "Your bracelet of slaughter has "; + private static final String CHAT_BRACELET_EXPEDITIOUS_CHARGE = "Your expeditious bracelet has "; //NPC messages private static final Pattern NPC_ASSIGN_MESSAGE = Pattern.compile(".*Your new task is to kill (\\d*) (.*)\\."); @@ -88,6 +98,9 @@ public class SlayerPlugin extends Plugin //Reward UI private static final Pattern REWARD_POINTS = Pattern.compile("Reward points: (\\d*)"); + private static final int EXPEDITIOUS_CHARGE = 30; + private static final int SLAUGHTER_CHARGE = 30; + @Inject private Client client; @@ -109,6 +122,9 @@ public class SlayerPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private QueryRunner queryRunner; + @Inject private TargetClickboxOverlay targetClickboxOverlay; @@ -118,6 +134,9 @@ public class SlayerPlugin extends Plugin @Getter(AccessLevel.PACKAGE) private List highlightedTargets = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) + private Collection slayerItems = Collections.emptyList(); + private String taskName; private int amount; private TaskCounter counter; @@ -126,6 +145,12 @@ public class SlayerPlugin extends Plugin private int cachedXp; private Instant infoTimer; private boolean loginFlag; + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private int expeditiousChargeCount; + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private int slaughterChargeCount; @Override protected void startUp() throws Exception @@ -136,6 +161,8 @@ public class SlayerPlugin extends Plugin { setPoints(config.points()); setStreak(config.streak()); + setExpeditiousChargeCount(config.expeditious()); + setSlaughterChargeCount(config.slaughter()); clientThread.invokeLater(() -> setTask(config.taskName(), config.amount())); } } @@ -171,6 +198,8 @@ public class SlayerPlugin extends Plugin { setPoints(config.points()); setStreak(config.streak()); + setExpeditiousChargeCount(config.expeditious()); + setSlaughterChargeCount(config.slaughter()); setTask(config.taskName(), config.amount()); loginFlag = false; } @@ -184,11 +213,15 @@ public class SlayerPlugin extends Plugin config.taskName(taskName); config.points(points); config.streak(streak); + config.expeditious(expeditiousChargeCount); + config.slaughter(slaughterChargeCount); } @Subscribe public void onGameTick(GameTick tick) { + checkInventories(); + Widget NPCDialog = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT); if (NPCDialog != null) { @@ -201,12 +234,29 @@ public class SlayerPlugin extends Plugin { return; } + String taskName = found1 ? mAssign.group(2) : mCurrent.group(1); int amount = Integer.parseInt(found1 ? mAssign.group(1) : mCurrent.group(2)); setTask(taskName, amount); } + Widget braceletBreakWidget = client.getWidget(WidgetInfo.DIALOG_SPRITE_TEXT); + if (braceletBreakWidget != null) + { + String braceletText = Text.removeTags(braceletBreakWidget.getText()); //remove color and linebreaks + if (braceletText.contains("bracelet of slaughter")) + { + slaughterChargeCount = SLAUGHTER_CHARGE; + config.slaughter(slaughterChargeCount); + } + else if (braceletText.contains("expeditious bracelet")) + { + expeditiousChargeCount = EXPEDITIOUS_CHARGE; + config.expeditious(expeditiousChargeCount); + } + } + Widget rewardsBarWidget = client.getWidget(WidgetInfo.SLAYER_REWARDS_TOPBAR); if (rewardsBarWidget != null) { @@ -242,6 +292,18 @@ public class SlayerPlugin extends Plugin } } + private void checkInventories() + { + Query inventoryQuery = new InventoryWidgetItemQuery(); + WidgetItem[] inventoryWidgetItems = queryRunner.runQuery(inventoryQuery); + + Query equipmentQuery = new EquipmentItemQuery().slotEquals(WidgetInfo.EQUIPMENT_HELMET, WidgetInfo.EQUIPMENT_RING, WidgetInfo.EQUIPMENT_GLOVES); + WidgetItem[] equipmentWidgetItems = queryRunner.runQuery(equipmentQuery); + + WidgetItem[] items = concat(inventoryWidgetItems, equipmentWidgetItems, WidgetItem.class); + slayerItems = ImmutableList.copyOf(items); + } + @Subscribe public void onChatMessage(ChatMessage event) { @@ -255,11 +317,30 @@ public class SlayerPlugin extends Plugin if (chatMsg.startsWith(CHAT_BRACELET_SLAUGHTER)) { amount++; + slaughterChargeCount = --slaughterChargeCount <= 0 ? SLAUGHTER_CHARGE : slaughterChargeCount; + config.slaughter(slaughterChargeCount); } if (chatMsg.startsWith(CHAT_BRACELET_EXPEDITIOUS)) { amount--; + expeditiousChargeCount = --expeditiousChargeCount <= 0 ? EXPEDITIOUS_CHARGE : expeditiousChargeCount; + config.expeditious(expeditiousChargeCount); + } + + if (chatMsg.startsWith(CHAT_BRACELET_EXPEDITIOUS_CHARGE)) + { + expeditiousChargeCount = Integer.parseInt(chatMsg + .replace(CHAT_BRACELET_EXPEDITIOUS_CHARGE, "") + .replace(" charges left.", "")); + config.expeditious(expeditiousChargeCount); + } + if (chatMsg.startsWith(CHAT_BRACELET_SLAUGHTER_CHARGE)) + { + slaughterChargeCount = Integer.parseInt(chatMsg + .replace(CHAT_BRACELET_SLAUGHTER_CHARGE, "") + .replace(" charges left.", "")); + config.slaughter(slaughterChargeCount); } if (chatMsg.endsWith("; return to a Slayer master.")) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java index c5d9820dea..18aa07f78d 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java @@ -31,6 +31,9 @@ import javax.inject.Inject; import static net.runelite.api.ChatMessageType.SERVER; import net.runelite.api.Client; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameTick; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; @@ -39,6 +42,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -60,6 +64,12 @@ public class SlayerPluginTest private static final String BRACLET_SLAUGHTER = "Your bracelet of slaughter prevents your slayer count decreasing."; private static final String BRACLET_EXPEDITIOUS = "Your expeditious bracelet helps you progress your slayer task faster."; + private static final String CHAT_BRACELET_SLAUGHTER_CHARGE = "Your bracelet of slaughter has 12 charges left."; + private static final String CHAT_BRACELET_EXPEDITIOUS_CHARGE = "Your expeditious bracelet has 12 charges left."; + + private static final String BREAK_SLAUGHTER = "The bracelet shatters. Your next bracelet of slaughter
will start afresh from 30 charges."; + private static final String BREAK_EXPEDITIOUS = "The bracelet shatters. Your next expeditious bracelet
will start afresh from 30 charges."; + @Mock @Bind Client client; @@ -173,10 +183,31 @@ public class SlayerPluginTest ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_SLAUGHTER, null); slayerPlugin.setAmount(42); + slayerPlugin.setSlaughterChargeCount(10); slayerPlugin.onChatMessage(chatMessageEvent); + assertEquals(9, slayerPlugin.getSlaughterChargeCount()); assertEquals(43, slayerPlugin.getAmount()); + + chatMessageEvent = new ChatMessage(SERVER, "", CHAT_BRACELET_SLAUGHTER_CHARGE, null); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(12, slayerPlugin.getSlaughterChargeCount()); + + slayerPlugin.setSlaughterChargeCount(1); + chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_SLAUGHTER, null); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(30, slayerPlugin.getSlaughterChargeCount()); + + Widget braceletBreakWidget = mock(Widget.class); + when(braceletBreakWidget.getText()).thenReturn(BREAK_SLAUGHTER); + when(client.getWidget(WidgetInfo.DIALOG_SPRITE_TEXT)).thenReturn(braceletBreakWidget); + + slayerPlugin.setSlaughterChargeCount(-1); + slayerPlugin.onGameTick(new GameTick()); + assertEquals(30, slayerPlugin.getSlaughterChargeCount()); } @Test @@ -185,9 +216,30 @@ public class SlayerPluginTest ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_EXPEDITIOUS, null); slayerPlugin.setAmount(42); + slayerPlugin.setExpeditiousChargeCount(10); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(41, slayerPlugin.getAmount()); + assertEquals(9, slayerPlugin.getExpeditiousChargeCount()); + + chatMessageEvent = new ChatMessage(SERVER, "", CHAT_BRACELET_EXPEDITIOUS_CHARGE, null); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(12, slayerPlugin.getExpeditiousChargeCount()); + + slayerPlugin.setExpeditiousChargeCount(1); + chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_EXPEDITIOUS, null); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(30, slayerPlugin.getExpeditiousChargeCount()); + + Widget braceletBreakWidget = mock(Widget.class); + when(braceletBreakWidget.getText()).thenReturn(BREAK_EXPEDITIOUS); + when(client.getWidget(WidgetInfo.DIALOG_SPRITE_TEXT)).thenReturn(braceletBreakWidget); + + slayerPlugin.setExpeditiousChargeCount(-1); + slayerPlugin.onGameTick(new GameTick()); + assertEquals(30, slayerPlugin.getExpeditiousChargeCount()); } }