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 97a191d608..88d195131b 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 @@ -104,7 +104,7 @@ class SlayerOverlay extends WidgetItemOverlay return; } - int amount = plugin.getAmount(); + int amount = plugin.getCurrentTask().getAmount(); if (amount <= 0) { return; 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 b789162bd8..65494c5c78 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 @@ -32,6 +32,7 @@ import java.awt.image.BufferedImage; import java.io.IOException; import java.time.Duration; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -46,12 +47,12 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; -import net.runelite.api.GameState; import net.runelite.api.ItemID; import net.runelite.api.MessageNode; import net.runelite.api.NPC; import net.runelite.api.NPCComposition; import static net.runelite.api.Skill.SLAYER; +import net.runelite.api.SpriteID; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; @@ -70,14 +71,21 @@ import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ChatInput; +import net.runelite.client.game.AsyncBufferedImage; import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.task.Schedule; +import net.runelite.client.ui.ClientToolbar; +import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; import net.runelite.http.api.chat.ChatClient; @@ -125,6 +133,12 @@ public class SlayerPlugin extends Plugin private static final Pattern TASK_STRING_VALIDATION = Pattern.compile("[^a-zA-Z0-9' -]"); private static final int TASK_STRING_MAX_LENGTH = 50; + @Inject + private ClientToolbar clientToolbar; + + @Inject + private SpriteManager spriteManager; + @Inject private Client client; @@ -170,20 +184,15 @@ public class SlayerPlugin extends Plugin @Inject private ChatClient chatClient; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private List highlightedTargets = new ArrayList<>(); @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) - private int amount; - - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private int initialAmount; - - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private String taskLocation; + private TaskData currentTask = new TaskData(0, 0, 0, 0, 0, null, null, true); @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) @@ -193,10 +202,6 @@ public class SlayerPlugin extends Plugin @Setter(AccessLevel.PACKAGE) private int slaughterChargeCount; - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private String taskName; - @Getter(AccessLevel.PACKAGE) private int streak; @@ -209,6 +214,10 @@ public class SlayerPlugin extends Plugin private boolean loginFlag; private List targetNames = new ArrayList<>(); + private SlayerTaskPanel panel = new SlayerTaskPanel(this); + private NavigationButton navButton; + private long lastTickMillis = 0; + @Override protected void startUp() throws Exception { @@ -217,15 +226,27 @@ public class SlayerPlugin extends Plugin overlayManager.add(targetWeaknessOverlay); overlayManager.add(targetMinimapOverlay); - if (client.getGameState() == GameState.LOGGED_IN - && config.amount() != -1 + spriteManager.getSpriteAsync(SpriteID.SKILL_SLAYER, 0, panel::loadHeaderIcon); + + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); + + navButton = NavigationButton.builder() + .tooltip("Slayer Tracker") + .icon(icon) + .priority(6) + .panel(panel) + .build(); + + clientToolbar.addNavigation(navButton); + + if (config.amount() != -1 && !config.taskName().isEmpty()) { points = config.points(); streak = config.streak(); setExpeditiousChargeCount(config.expeditious()); setSlaughterChargeCount(config.slaughter()); - clientThread.invoke(() -> setTask(config.taskName(), config.amount(), config.initialAmount(), config.taskLocation())); + clientThread.invoke(() -> setTask(config.taskName(), config.amount(), config.initialAmount(), true, config.taskLocation())); } chatCommandManager.registerCommandAsync(TASK_COMMAND_STRING, this::taskLookup, this::taskSubmit); @@ -242,6 +263,7 @@ public class SlayerPlugin extends Plugin highlightedTargets.clear(); chatCommandManager.unregisterCommand(TASK_COMMAND_STRING); + clientToolbar.removeNavigation(navButton); } @Provides @@ -257,34 +279,17 @@ public class SlayerPlugin extends Plugin { case HOPPING: case LOGGING_IN: - cachedXp = 0; - taskName = ""; - amount = 0; - loginFlag = true; highlightedTargets.clear(); break; - case LOGGED_IN: - if (config.amount() != -1 - && !config.taskName().isEmpty() - && loginFlag) - { - points = config.points(); - streak = config.streak(); - setExpeditiousChargeCount(config.expeditious()); - setSlaughterChargeCount(config.slaughter()); - setTask(config.taskName(), config.amount(), config.initialAmount(), config.taskLocation()); - loginFlag = false; - } - break; } } private void save() { - config.amount(amount); - config.initialAmount(initialAmount); - config.taskName(taskName); - config.taskLocation(taskLocation); + config.amount(currentTask.getAmount()); + config.initialAmount(currentTask.getInitialAmount()); + config.taskName(currentTask.getTaskName()); + config.taskLocation(currentTask.getTaskLocation()); config.points(points); config.streak(streak); config.expeditious(expeditiousChargeCount); @@ -308,11 +313,24 @@ public class SlayerPlugin extends Plugin highlightedTargets.remove(npc); } + // b/c dialog can stay up on screen for multiple ticks in a row we want to make sure we only set a task once + // for the dialog that appears so we need to basically do a rising edge detection that only allows for a dialog + // check to be performed if in the previous ticks there was a period of no dialog + // i.e. once a dialog has been matched dialog cannot be matched again until npc dialog goes away for a tick + // this will work because in order for a new slayer task to happen the player either has to go complete the assignment + // (and close npc dialog) or go into the rewards screen which also closes npc dialog + private boolean canMatchDialog = true; + + // rising edge detection isn't enough for some reason (don't know why) so in addition to a rising edge rather than + // instantly allowing for another assignment we'll do a 2 tick refractory period + private static final int FORCED_WAIT = 2; + private int forcedWait = -1; + @Subscribe public void onGameTick(GameTick tick) { Widget npcDialog = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT); - if (npcDialog != null) + if (npcDialog != null && canMatchDialog) { String npcText = Text.sanitizeMultilineText(npcDialog.getText()); //remove color and linebreaks final Matcher mAssign = NPC_ASSIGN_MESSAGE.matcher(npcText); // amount, name, (location) @@ -325,27 +343,43 @@ public class SlayerPlugin extends Plugin String name = mAssign.group("name"); int amount = Integer.parseInt(mAssign.group("amount")); String location = mAssign.group("location"); - setTask(name, amount, amount, location); + setTask(name, amount, amount, true, location); + canMatchDialog = false; + forcedWait = FORCED_WAIT; } else if (mAssignFirst.find()) { int amount = Integer.parseInt(mAssignFirst.group(2)); - setTask(mAssignFirst.group(1), amount, amount); + setTask(mAssignFirst.group(1), amount, amount, true); + canMatchDialog = false; + forcedWait = FORCED_WAIT; } else if (mAssignBoss.find()) { int amount = Integer.parseInt(mAssignBoss.group(2)); - setTask(mAssignBoss.group(1), amount, amount); + setTask(mAssignBoss.group(1), amount, amount, true); points = Integer.parseInt(mAssignBoss.group(3).replaceAll(",", "")); + canMatchDialog = false; + forcedWait = FORCED_WAIT; } else if (mCurrent.find()) { String name = mCurrent.group("name"); int amount = Integer.parseInt(mCurrent.group("amount")); String location = mCurrent.group("location"); - setTask(name, amount, initialAmount, location); + setTask(name, amount, currentTask.getInitialAmount(), false, location); + canMatchDialog = false; + forcedWait = FORCED_WAIT; } } + else if (npcDialog == null) + { + if (forcedWait <= 0) + { + canMatchDialog = true; + } + forcedWait--; + } Widget braceletBreakWidget = client.getWidget(WidgetInfo.DIALOG_SPRITE_TEXT); if (braceletBreakWidget != null) @@ -411,7 +445,7 @@ public class SlayerPlugin extends Plugin { Matcher mSlaughter = CHAT_BRACELET_SLAUGHTER_REGEX.matcher(chatMsg); - amount++; + currentTask.setAmount(currentTask.getAmount() + 1); slaughterChargeCount = mSlaughter.find() ? Integer.parseInt(mSlaughter.group(1)) : SLAUGHTER_CHARGE; config.slaughter(slaughterChargeCount); } @@ -420,7 +454,7 @@ public class SlayerPlugin extends Plugin { Matcher mExpeditious = CHAT_BRACELET_EXPEDITIOUS_REGEX.matcher(chatMsg); - amount--; + currentTask.setAmount(currentTask.getAmount() - 1); expeditiousChargeCount = mExpeditious.find() ? Integer.parseInt(mExpeditious.group(1)) : EXPEDITIOUS_CHARGE; config.expeditious(expeditiousChargeCount); } @@ -474,13 +508,13 @@ public class SlayerPlugin extends Plugin default: log.warn("Unreachable default case for message ending in '; return to Slayer master'"); } - setTask("", 0, 0); + setTask("", 0, 0, true); return; } if (chatMsg.equals(CHAT_GEM_COMPLETE_MESSAGE) || chatMsg.equals(CHAT_CANCEL_MESSAGE) || chatMsg.equals(CHAT_CANCEL_MESSAGE_JAD)) { - setTask("", 0, 0); + setTask("", 0, 0, true); return; } @@ -497,7 +531,7 @@ public class SlayerPlugin extends Plugin String name = mProgress.group("name"); int gemAmount = Integer.parseInt(mProgress.group("amount")); String location = mProgress.group("location"); - setTask(name, gemAmount, initialAmount, location); + setTask(name, gemAmount, currentTask.getInitialAmount(), false, location); return; } @@ -506,10 +540,10 @@ public class SlayerPlugin extends Plugin if (bracerProgress.find()) { final int taskAmount = Integer.parseInt(bracerProgress.group(1)); - setTask(taskName, taskAmount, initialAmount); + setTask(currentTask.getTaskName(), taskAmount, currentTask.getInitialAmount(), false); // Avoid race condition (combat brace message goes through first before XP drop) - amount++; + currentTask.setAmount(currentTask.getAmount() + 1); } } @@ -535,6 +569,8 @@ public class SlayerPlugin extends Plugin return; } + int delta = slayerExp - cachedXp; + currentTask.setElapsedXp(currentTask.getElapsedXp() + delta); killedOne(); cachedXp = slayerExp; } @@ -560,18 +596,22 @@ public class SlayerPlugin extends Plugin @VisibleForTesting void killedOne() { - if (amount == 0) + if (currentTask.getAmount() == 0) { return; } - amount--; + currentTask.setAmount(currentTask.getAmount() - 1); + currentTask.setElapsedKills(currentTask.getElapsedKills() + 1); if (doubleTroubleExtraKill()) { - amount--; + currentTask.setAmount(currentTask.getAmount() - 1); + currentTask.setElapsedKills(currentTask.getElapsedKills() + 1); } - config.amount(amount); // save changed value + config.amount(currentTask.getAmount()); // save changed value + currentTask.setPaused(false); // no longer paused since xp is gained + panel.updateCurrentTask(true, currentTask.isPaused(), currentTask, false); if (!config.showInfobox()) { @@ -580,7 +620,7 @@ public class SlayerPlugin extends Plugin // add and update counter, set timer addCounter(); - counter.setCount(amount); + counter.setCount(currentTask.getAmount()); infoTimer = Instant.now(); } @@ -634,7 +674,7 @@ public class SlayerPlugin extends Plugin .map(String::toLowerCase) .forEach(targetNames::add); - targetNames.add(taskName.toLowerCase().replaceAll("s$", "")); + targetNames.add(currentTask.getTaskName().toLowerCase().replaceAll("s$", "")); } } @@ -651,17 +691,19 @@ public class SlayerPlugin extends Plugin } } - private void setTask(String name, int amt, int initAmt) + private void setTask(String name, int amt, int initAmt, boolean isNewAssignment) { - setTask(name, amt, initAmt, null); + setTask(name, amt, initAmt, isNewAssignment, null); } - private void setTask(String name, int amt, int initAmt, String location) + private void setTask(String name, int amt, int initAmt, boolean isNewAssignment, String location) { - taskName = name; - amount = amt; - initialAmount = initAmt; - taskLocation = location; + currentTask = new TaskData(isNewAssignment ? 0 : currentTask.getElapsedTime(), + isNewAssignment ? 0 : currentTask.getElapsedKills(), + isNewAssignment ? 0 : currentTask.getElapsedXp(), + amt, initAmt, location, name, + isNewAssignment ? true : currentTask.isPaused()); + panel.updateCurrentTask(true, currentTask.isPaused(), currentTask, isNewAssignment); save(); removeCounter(); addCounter(); @@ -672,26 +714,30 @@ public class SlayerPlugin extends Plugin rebuildTargetList(); } - private void addCounter() + public AsyncBufferedImage getImageForTask(Task task) { - if (!config.showInfobox() || counter != null || Strings.isNullOrEmpty(taskName)) - { - return; - } - - Task task = Task.getTask(taskName); int itemSpriteId = ItemID.ENCHANTED_GEM; if (task != null) { itemSpriteId = task.getItemSpriteId(); } + return itemManager.getImage(itemSpriteId); + } - BufferedImage taskImg = itemManager.getImage(itemSpriteId); + private void addCounter() + { + if (!config.showInfobox() || counter != null || Strings.isNullOrEmpty(currentTask.getTaskName())) + { + return; + } + + Task task = Task.getTask(currentTask.getTaskName()); + AsyncBufferedImage taskImg = getImageForTask(task); String taskTooltip = ColorUtil.wrapWithColorTag("%s", new Color(255, 119, 0)) + "
"; - if (taskLocation != null && !taskLocation.isEmpty()) + if (currentTask.getTaskLocation() != null && !currentTask.getTaskLocation().isEmpty()) { - taskTooltip += taskLocation + "
"; + taskTooltip += currentTask.getTaskLocation() + "
"; } taskTooltip += ColorUtil.wrapWithColorTag("Pts:", Color.YELLOW) @@ -699,15 +745,15 @@ public class SlayerPlugin extends Plugin + ColorUtil.wrapWithColorTag("Streak:", Color.YELLOW) + " %s"; - if (initialAmount > 0) + if (currentTask.getInitialAmount() > 0) { taskTooltip += "
" + ColorUtil.wrapWithColorTag("Start:", Color.YELLOW) - + " " + initialAmount; + + " " + currentTask.getInitialAmount(); } - counter = new TaskCounter(taskImg, this, amount); - counter.setTooltip(String.format(taskTooltip, capsString(taskName), points, streak)); + counter = new TaskCounter(taskImg, this, currentTask.getAmount()); + counter.setTooltip(String.format(taskTooltip, capsString(currentTask.getTaskName()), points, streak)); infoBoxManager.addInfoBox(counter); } @@ -794,7 +840,7 @@ public class SlayerPlugin extends Plugin private boolean taskSubmit(ChatInput chatInput, String value) { - if (Strings.isNullOrEmpty(taskName)) + if (Strings.isNullOrEmpty(currentTask.getTaskName())) { return false; } @@ -805,7 +851,8 @@ public class SlayerPlugin extends Plugin { try { - chatClient.submitTask(playerName, capsString(taskName), amount, initialAmount, taskLocation); + chatClient.submitTask(playerName, capsString(currentTask.getTaskName()), currentTask.getAmount(), + currentTask.getInitialAmount(), currentTask.getTaskLocation()); } catch (Exception ex) { @@ -820,6 +867,39 @@ public class SlayerPlugin extends Plugin return true; } + /* package access method for changing the pause state of the time tracker for the current task */ + void setPaused(boolean paused) + { + currentTask.setPaused(paused); + panel.updateCurrentTask(false, currentTask.isPaused(), currentTask, false); + } + + @Schedule( + period = 1, + unit = ChronoUnit.SECONDS + ) + public void tickTaskTimes() + { + if (lastTickMillis == 0) + { + lastTickMillis = System.currentTimeMillis(); + return; + } + + final long nowMillis = System.currentTimeMillis(); + final long tickDelta = nowMillis - lastTickMillis; + lastTickMillis = nowMillis; + + + if (currentTask == null) + { + return; + } + currentTask.tick(tickDelta); + + panel.updateCurrentTask(false, currentTask.isPaused(), currentTask, false); + } + //Utils private String capsString(String str) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerTaskPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerTaskPanel.java new file mode 100644 index 0000000000..1c3de05230 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerTaskPanel.java @@ -0,0 +1,372 @@ +package net.runelite.client.plugins.slayer; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.border.EmptyBorder; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.PluginPanel; +import net.runelite.client.ui.components.PluginErrorPanel; +import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.ImageUtil; +import net.runelite.client.util.StackFormatter; + +public class SlayerTaskPanel extends PluginPanel +{ + private static final long MILLIS_PER_SECOND = 1000; + private static final long SECONDS_PER_MINUTE = 60; + private static final long MINUTES_PER_HOUR = 60; + + // Templates + private static final String HTML_LABEL_TEMPLATE = + "%s%s"; + private static final String HTML_TIME_LABEL_TEMPLATE = + "%s%02d:%02d:%02d"; + + + private static final ImageIcon PAUSE, PAUSE_FADED, PAUSE_HOVER; + private static final ImageIcon PLAY, PLAY_FADED, PLAY_HOVER; + + // TODO: set some kind of maximum for the amount of tasks to be tracked in a session + private static final int MAX_TASK_BOXES = 50; + + // When there are no tasks, display this + private final PluginErrorPanel errorPanel = new PluginErrorPanel(); + + // Handle task boxes + private final JPanel tasksContainer = new JPanel(); + + // Handle overall slayer session data + private final JPanel overallPanel = new JPanel(); + private final JLabel overallKillsLabel = new JLabel(); + private final JLabel overallTimeLabel = new JLabel(); + private final JLabel overallIcon = new JLabel(); + + // Actions + private final JPanel actionsContainer = new JPanel(); + private final JLabel playBtn = new JLabel(); + private final JLabel pauseBtn = new JLabel(); + + // Log tasks + private final List tasks = new ArrayList<>(); + + private SlayerPlugin slayerPlugin; + + static + { + final BufferedImage pauseImg = ImageUtil.getResourceStreamFromClass(SlayerPlugin.class, "pause_icon.png"); + final BufferedImage playImg = ImageUtil.getResourceStreamFromClass(SlayerPlugin.class, "play_icon.png"); + + PAUSE = new ImageIcon(pauseImg); + PAUSE_FADED = new ImageIcon(ImageUtil.alphaOffset(pauseImg, -180)); + PAUSE_HOVER = new ImageIcon(ImageUtil.alphaOffset(pauseImg, -220)); + + PLAY = new ImageIcon(playImg); + PLAY_FADED = new ImageIcon(ImageUtil.alphaOffset(playImg, -180)); + PLAY_HOVER = new ImageIcon(ImageUtil.alphaOffset(playImg, -220)); + } + + public SlayerTaskPanel(SlayerPlugin slayerPlugin) + { + this.slayerPlugin = slayerPlugin; + + setBorder(new EmptyBorder(6, 6, 6, 6)); + setBackground(ColorScheme.DARK_GRAY_COLOR); + setLayout(new BorderLayout()); + + // Create layout panel for wrapping + final JPanel layoutPanel = new JPanel(); + layoutPanel.setLayout(new BoxLayout(layoutPanel, BoxLayout.Y_AXIS)); + add(layoutPanel, BorderLayout.NORTH); + + actionsContainer.setLayout(new BorderLayout()); + actionsContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR); + actionsContainer.setPreferredSize(new Dimension(0, 30)); + actionsContainer.setBorder(new EmptyBorder(5, 5, 5, 10)); + actionsContainer.setVisible(false); + + final JPanel controlsPanel = new JPanel(new GridLayout(1, 2, 10, 0)); + controlsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + + playBtn.setIcon(PLAY); + playBtn.setToolTipText("Resume the current slayer task"); + playBtn.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + slayerPlugin.setPaused(false); + changePauseState(false); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + boolean paused = true; + TaskData currentTask = slayerPlugin.getCurrentTask(); + if (currentTask != null) + { + paused = currentTask.isPaused(); + } + playBtn.setIcon(paused ? PLAY_FADED : PLAY); + } + + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + boolean paused = true; + TaskData currentTask = slayerPlugin.getCurrentTask(); + if (currentTask != null) + { + paused = currentTask.isPaused(); + } + playBtn.setIcon(paused ? PLAY_HOVER : PLAY); + } + }); + + pauseBtn.setIcon(PAUSE); + pauseBtn.setToolTipText("Pause the current slayer task"); + pauseBtn.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + slayerPlugin.setPaused(true); + changePauseState(true); + } + @Override + public void mouseExited(MouseEvent mouseEvent) + { + boolean paused = true; + TaskData currentTask = slayerPlugin.getCurrentTask(); + if (currentTask != null) + { + paused = currentTask.isPaused(); + } + pauseBtn.setIcon(paused ? PAUSE : PAUSE_FADED); + } + + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + boolean paused = true; + TaskData currentTask = slayerPlugin.getCurrentTask(); + if (currentTask != null) + { + paused = currentTask.isPaused(); + } + pauseBtn.setIcon(paused ? PAUSE : PAUSE_HOVER); + } + }); + + controlsPanel.add(playBtn); + controlsPanel.add(pauseBtn); + + actionsContainer.add(controlsPanel, BorderLayout.EAST); + changePauseState(true); + if (slayerPlugin.getCurrentTask() != null) + { + changePauseState(slayerPlugin.getCurrentTask().isPaused()); + } + + // Create panel that will contain overall data + overallPanel.setBorder(new EmptyBorder(8, 10, 8, 10)); + overallPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + overallPanel.setLayout(new BorderLayout()); + overallPanel.setVisible(false); + + // Add contents + final JPanel overallInfo = new JPanel(); + overallInfo.setBackground(ColorScheme.DARKER_GRAY_COLOR); + overallInfo.setLayout(new GridLayout(2, 1)); + overallInfo.setBorder(new EmptyBorder(2, 10, 2, 0)); + overallKillsLabel.setFont(FontManager.getRunescapeSmallFont()); + overallTimeLabel.setFont(FontManager.getRunescapeSmallFont()); + overallInfo.add(overallKillsLabel); + overallInfo.add(overallTimeLabel); + overallPanel.add(overallIcon, BorderLayout.WEST); + overallPanel.add(overallInfo, BorderLayout.CENTER); + + tasksContainer.setLayout(new BoxLayout(tasksContainer, BoxLayout.Y_AXIS)); + layoutPanel.add(actionsContainer); + layoutPanel.add(Box.createRigidArea(new Dimension(0, 5))); + layoutPanel.add(overallPanel); + layoutPanel.add(tasksContainer); + + // Add error pane + errorPanel.setContent("Task trackers", "You have not received any slayer tasks yet."); + add(errorPanel); + } + + void loadHeaderIcon(BufferedImage img) + { + overallIcon.setIcon(new ImageIcon(img)); + } + + private void changePauseState(boolean paused) + { + playBtn.setIcon(paused ? PLAY_FADED : PLAY); + pauseBtn.setIcon(paused ? PAUSE : PAUSE_FADED); + } + + private void updateOverall() + { + int overallKills = 0; + long overallTime = 0; + for (TaskBox box : tasks) + { + overallKills += box.getTaskData().getElapsedKills(); + overallTime += box.getTaskData().getElapsedTime(); + } + + overallKillsLabel.setText(htmlLabel("Total kills: ", overallKills)); + overallTimeLabel.setText(htmlLabel("Total time: ", overallTime)); + } + + private static boolean isEmptyTask(TaskData taskData) + { + return (taskData.getTaskName() == null || taskData.getTaskName().equals("")) && taskData.getAmount() == 0 && taskData.getInitialAmount() == 0; + } + + private void showMainView() + { + remove(errorPanel); + actionsContainer.setVisible(true); + overallPanel.setVisible(true); + } + + private TaskBox buildBox(SlayerPlugin plugin, JPanel container, TaskData data) + { + TaskBox newBox = new TaskBox(plugin, container, data.toBuilder().build()); + tasks.add(0, newBox); + showMainView(); + return newBox; + } + + private boolean stringsEqualIncludeNull(String str0, String str1) + { + if (str0 == null && str1 == null) + { + return true; // both are null + } + else if (str0 == null || str1 == null) + { + return false; // only 1 is null + } + else + { + // none are null so equals check is safe + return str0.equals(str1); + } + } + + void updateCurrentTask(boolean updated, boolean paused, TaskData newData, boolean isNewAssignment) + { + // important case for if the current task is completed so the update will show the empty task + if (isEmptyTask(newData)) + { + if (tasks.isEmpty()) // if there is no current task an empty task doesn't do anything + { + return; + } + TaskBox current = tasks.get(0); + // current task has ended even though it should still have 1 amount remaining b/c the ending chat message + // pops before the slayer xp drop so we need to force the remaining kc to zero and add the last kc to + // the elapsed kc + if (current.getTaskData().getAmount() != 0) // must check not equal zero b/c otherwise this would constantly tick + { + int amountDelta = current.getTaskData().getAmount(); + current.getTaskData().setAmount(0); + current.getTaskData().setElapsedKills(current.getTaskData().getElapsedKills() + amountDelta); + // current task has ended so it should be paused + current.update(true, true, current.getTaskData()); + updateOverall(); + } + return; + } + + if (tasks.isEmpty() || isNewAssignment) + { + // new task so append it to the front of the list + SwingUtilities.invokeLater(() -> + { + TaskBox newBox = buildBox(slayerPlugin, tasksContainer, newData); + newBox.update(true, newData.isPaused(), newData); + }); + return; + } + else + { + // if here there is a current task so check if the current task matches + // the update being sent + TaskBox current = tasks.get(0); + if (!stringsEqualIncludeNull(current.getTaskData().getTaskName(), newData.getTaskName()) || + !stringsEqualIncludeNull(current.getTaskData().getTaskLocation(), newData.getTaskLocation()) || + current.getTaskData().getInitialAmount() != newData.getInitialAmount()) + { + // current task does not match the update being sent so the current task + // must have been outdated - this is necessarily true because if a true + // new task was sent it would have set the isNewAssignment flag + + // so this previous task is invalid so delete it then add in the new actually + // correct task + SwingUtilities.invokeLater(() -> + { + tasksContainer.remove(tasks.get(0)); + tasks.remove(0); + TaskBox newBox = buildBox(slayerPlugin, tasksContainer, newData); + newBox.update(true, newData.isPaused(), newData); + }); + return; + } + } + + // not an empty assignment or a new assignment so just update the current assignment + TaskBox current = tasks.get(0); + current.update(updated, paused, newData); + + // update the overall stats once this task stats are updated + updateOverall(); + changePauseState(paused); + } + + static String htmlLabel(String key, long timeMillis) + { + if (timeMillis == Long.MAX_VALUE) + { + String valueStr = "N/A"; + return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), + key, valueStr); + } + else + { + long seconds = timeMillis / MILLIS_PER_SECOND; + long minutes = seconds / SECONDS_PER_MINUTE; + seconds %= 60; + long hours = minutes / MINUTES_PER_HOUR; + minutes %= 60; + return String.format(HTML_TIME_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), + key, (int) hours, (int) minutes, (int) seconds); + } + } + + static String htmlLabel(String key, int value) + { + String valueStr = StackFormatter.quantityToRSDecimalStack(value); + return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), + key, valueStr); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetWeaknessOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetWeaknessOverlay.java index ada3f3a727..4f60949a89 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetWeaknessOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetWeaknessOverlay.java @@ -72,7 +72,7 @@ class TargetWeaknessOverlay extends Overlay return null; } - final Task curTask = Task.getTask(plugin.getTaskName()); + final Task curTask = Task.getTask(plugin.getCurrentTask().getTaskName()); if (curTask == null || curTask.getWeaknessThreshold() < 0 || curTask.getWeaknessItem() < 0) { return null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskBox.java new file mode 100644 index 0000000000..443dccb453 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskBox.java @@ -0,0 +1,291 @@ +package net.runelite.client.plugins.slayer; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.image.BufferedImage; +import java.text.DecimalFormat; +import java.util.Collections; +import javax.swing.JLabel; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.border.EmptyBorder; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.DynamicGridLayout; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.components.ProgressBar; +import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.StackFormatter; + +public class TaskBox extends JPanel +{ + private static final long MILLIS_PER_SECOND = 1000; + private static final long SECONDS_PER_MINUTE = 60; + private static final long MINUTES_PER_HOUR = 60; + private static final long MILLIS_PER_HOUR = MILLIS_PER_SECOND * SECONDS_PER_MINUTE * MINUTES_PER_HOUR; + + private static final DecimalFormat TWO_DECIMAL_FORMAT = new DecimalFormat("0.00"); + + + // Templates + private static final String HTML_TOOL_TIP_TEMPLATE = + "%.1f Kills/hr
" + + "%02d:%02d:%02d per kill"; + private static final String HTML_LABEL_TEMPLATE = + "%s%s"; + private static final String HTML_TIME_LABEL_TEMPLATE = + "%s%02d:%02d:%02d"; + + // Instance members + private final JPanel panel; + + @Getter(AccessLevel.PACKAGE) + private final TaskData taskData; + + /* This task's wrapping container */ + private final JPanel container = new JPanel(); + + /* Contains the task icon and the stats panel */ + private final JPanel headerPanel = new JPanel(); + + /* Contains the overall stats of the slayer task */ + private final JPanel statsPanel = new JPanel(); + + private final ProgressBar progressBar = new ProgressBar(); + + private final JLabel currentDuration = new JLabel(); + private final JLabel remainingDuration = new JLabel(); + private final JLabel currentKills = new JLabel(); + private final JLabel remainingKills = new JLabel(); + private final JLabel currentXp = new JLabel(); + private final JLabel remainingXp = new JLabel(); + + private boolean paused = false; + + public TaskBox(SlayerPlugin slayerPlugin, JPanel panel, TaskData taskData) + { + this.panel = panel; + this.taskData = taskData; + + setLayout(new BorderLayout()); + setBorder(new EmptyBorder(5, 0, 0, 0)); + + container.setLayout(new BorderLayout()); + container.setBackground(ColorScheme.DARKER_GRAY_COLOR); + + SwingUtilities.invokeLater(() -> + { + BufferedImage taskImg = slayerPlugin.getImageForTask(Task.getTask(taskData.getTaskName())); + JLabel taskIcon = new JLabel(new ImageIcon(taskImg)); + taskIcon.setHorizontalAlignment(SwingConstants.CENTER); + taskIcon.setVerticalAlignment(SwingConstants.CENTER); + taskIcon.setPreferredSize(new Dimension(35, 35)); + + statsPanel.setLayout(new DynamicGridLayout(3, 2)); + statsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + statsPanel.setBorder(new EmptyBorder(9, 2, 9, 2)); + + currentDuration.setFont(FontManager.getRunescapeSmallFont()); + remainingDuration.setFont(FontManager.getRunescapeSmallFont()); + currentKills.setFont(FontManager.getRunescapeSmallFont()); + remainingKills.setFont(FontManager.getRunescapeSmallFont()); + currentXp.setFont(FontManager.getRunescapeSmallFont()); + remainingXp.setFont(FontManager.getRunescapeSmallFont()); + + statsPanel.add(currentDuration); + statsPanel.add(remainingDuration); + statsPanel.add(currentKills); + statsPanel.add(remainingKills); + statsPanel.add(currentXp); + statsPanel.add(remainingXp); + + headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + headerPanel.setLayout(new BorderLayout()); + + headerPanel.add(statsPanel, BorderLayout.CENTER); + headerPanel.add(taskIcon, BorderLayout.WEST); + }); + + + + + JPanel progressWrapper = new JPanel(); + progressWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR); + progressWrapper.setLayout(new BorderLayout()); + progressWrapper.setBorder(new EmptyBorder(0, 7, 7, 7)); + + + progressBar.setMaximumValue(100); + progressBar.setBackground(new Color(61, 56, 49)); + progressBar.setForeground(new Color(98, 70, 70)); + progressBar.setDimmedText("Paused"); + + progressWrapper.add(progressBar, BorderLayout.NORTH); + + final JPanel logTitle = new JPanel(new BorderLayout(5, 0)); + logTitle.setBorder(new EmptyBorder(7, 7, 7, 7)); + logTitle.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); + + String taskName = taskData.getTaskName(); + taskName = taskName.substring(0, 1).toUpperCase() + taskName.substring(1); + final JLabel titleLabel = new JLabel(taskName); + titleLabel.setFont(FontManager.getRunescapeSmallFont()); + titleLabel.setForeground(Color.WHITE); + + logTitle.add(titleLabel, BorderLayout.WEST); + + final JLabel subTitleLabel = new JLabel("x " + taskData.getInitialAmount()); + subTitleLabel.setFont(FontManager.getRunescapeSmallFont()); + subTitleLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + + logTitle.add(subTitleLabel, BorderLayout.CENTER); + + if (taskData.getTaskLocation() != null && !taskData.getTaskLocation().equals("")) + { + final JLabel locationLabel = new JLabel(taskData.getTaskLocation()); + locationLabel.setFont(FontManager.getRunescapeSmallFont()); + locationLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + + logTitle.add(locationLabel, BorderLayout.EAST); + } + + container.add(logTitle, BorderLayout.NORTH); + container.add(headerPanel, BorderLayout.CENTER); + container.add(progressWrapper, BorderLayout.SOUTH); + + add(container, BorderLayout.NORTH); + } + + void update(boolean updated, boolean paused, TaskData newData) + { + SwingUtilities.invokeLater(() -> rebuildAsync(updated, paused, newData)); + } + + private void rebuildAsync(boolean updated, boolean taskPaused, TaskData newData) + { + if (updated) + { + if (getParent() != panel) + { + panel.add(this, 0); + panel.revalidate(); + } + + // Update data + taskData.setElapsedKills(newData.getElapsedKills()); + taskData.setAmount(newData.getAmount()); + taskData.setElapsedXp(newData.getElapsedXp()); + + // Update information labels + int kills = taskData.getInitialAmount() - taskData.getAmount(); + currentKills.setText(htmlLabel("Elapsed Kills: ", taskData.getElapsedKills())); + remainingKills.setText(htmlLabel("Remaining Kills: ", taskData.getAmount())); + + currentXp.setText(htmlLabel("Elapsed Xp: ", taskData.getElapsedXp())); + double xpPerKill = ((double) taskData.getElapsedXp()) / ((double) taskData.getElapsedKills()); + double xpLeft = xpPerKill * taskData.getAmount(); + remainingXp.setText(htmlLabel("Remaining Xp: ", (int) xpLeft)); + + // Update progress bar + double percentComplete = ((double) kills) / ((double) taskData.getInitialAmount()); + progressBar.setValue((int) (percentComplete * 100)); + progressBar.setCenterLabel(TWO_DECIMAL_FORMAT.format(percentComplete * 100) + "%"); + progressBar.setLeftLabel("0 Kc"); + progressBar.setRightLabel(taskData.getInitialAmount() + " Kc"); + progressBar.setPositions(Collections.emptyList()); + + double killsPerMillis = ((double) taskData.getElapsedKills() - 1) / ((double) taskData.getElapsedTime()); + if (killsPerMillis <= 0) + { + progressBar.setToolTipText(String.format( + HTML_TOOL_TIP_TEMPLATE, + 0, + 99, + 99, + 99 + )); + } + double killsPerHour = killsPerMillis * MILLIS_PER_HOUR; + double millisPerKill = 1.0 / killsPerMillis; + long seconds = ((long) millisPerKill) / MILLIS_PER_SECOND; + long minutes = seconds / SECONDS_PER_MINUTE; + seconds %= 60; + long hours = minutes / MINUTES_PER_HOUR; + minutes %= 60; + progressBar.setToolTipText(String.format( + HTML_TOOL_TIP_TEMPLATE, + killsPerHour, + hours, + minutes, + seconds + )); + + progressBar.setDimmed(taskPaused); + + progressBar.repaint(); + } + else if (!paused && taskPaused) + { + progressBar.setDimmed(true); + progressBar.repaint(); + paused = true; + } + else if (paused && !taskPaused) + { + progressBar.setDimmed(false); + progressBar.repaint(); + paused = false; + } + + // Update duration separately, every time (not only when there's an update) + taskData.setElapsedTime(newData.getElapsedTime()); + currentDuration.setText(htmlLabel("Elapsed Time:
", taskData.getElapsedTime())); + remainingDuration.setText(htmlLabel("Remaining Time:
", estimateRemainingTime(taskData))); + + repaint(); + } + + static long estimateRemainingTime(TaskData taskData) + { + int kills = taskData.getElapsedKills(); + int killsInElapsedTime = kills - 1; // b/c time only elapses after 1st slayer drop + if (killsInElapsedTime < 1) + { + return Long.MAX_VALUE; + } + double timePerKill = ((double) taskData.getElapsedTime()) / ((double) killsInElapsedTime); + double remainingTime = timePerKill * taskData.getAmount(); + return (long) remainingTime; + } + + static String htmlLabel(String key, long timeMillis) + { + if (timeMillis == Long.MAX_VALUE) + { + String valueStr = "N/A"; + return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), + key, valueStr); + } + else + { + long seconds = timeMillis / MILLIS_PER_SECOND; + long minutes = seconds / SECONDS_PER_MINUTE; + seconds %= 60; + long hours = minutes / MINUTES_PER_HOUR; + minutes %= 60; + return String.format(HTML_TIME_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), + key, (int) hours, (int) minutes, (int) seconds); + } + } + + static String htmlLabel(String key, int value) + { + String valueStr = StackFormatter.quantityToRSDecimalStack(value); + return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), + key, valueStr); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskData.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskData.java new file mode 100644 index 0000000000..0e3784e687 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskData.java @@ -0,0 +1,27 @@ +package net.runelite.client.plugins.slayer; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@AllArgsConstructor +@Builder(toBuilder = true) +public class TaskData +{ + private long elapsedTime; + private int elapsedKills; + private int elapsedXp; + private int amount, initialAmount; + private String taskLocation; + private String taskName; + private boolean paused; + + public void tick(long delta) + { + if (!paused) + { + elapsedTime += delta; + } + } +} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/slayer/panel_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/slayer/panel_icon.png new file mode 100644 index 0000000000..cd454c3956 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/slayer/panel_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/slayer/pause_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/slayer/pause_icon.png new file mode 100644 index 0000000000..57baef8bd3 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/slayer/pause_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/slayer/play_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/slayer/play_icon.png new file mode 100644 index 0000000000..1a5b02e867 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/slayer/play_icon.png differ 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 06291d7fce..ec4cdbd84b 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 @@ -171,8 +171,8 @@ public class SlayerPluginTest when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); slayerPlugin.onGameTick(new GameTick()); - assertEquals("Suqahs", slayerPlugin.getTaskName()); - assertEquals(231, slayerPlugin.getAmount()); + assertEquals("Suqahs", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(231, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -183,9 +183,9 @@ public class SlayerPluginTest when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); slayerPlugin.onGameTick(new GameTick()); - assertEquals("Wyrms", slayerPlugin.getTaskName()); - assertEquals(147, slayerPlugin.getAmount()); - assertEquals("Karuulm Slayer Dungeon", slayerPlugin.getTaskLocation()); + assertEquals("Wyrms", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(147, slayerPlugin.getCurrentTask().getAmount()); + assertEquals("Karuulm Slayer Dungeon", slayerPlugin.getCurrentTask().getTaskLocation()); } @Test @@ -196,9 +196,9 @@ public class SlayerPluginTest when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); slayerPlugin.onGameTick(new GameTick()); - assertEquals("Hellhounds", slayerPlugin.getTaskName()); - assertEquals(142, slayerPlugin.getAmount()); - assertEquals("Witchhaven Dungeon", slayerPlugin.getTaskLocation()); + assertEquals("Hellhounds", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(142, slayerPlugin.getCurrentTask().getAmount()); + assertEquals("Witchhaven Dungeon", slayerPlugin.getCurrentTask().getTaskLocation()); } @Test @@ -209,8 +209,8 @@ public class SlayerPluginTest when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); slayerPlugin.onGameTick(new GameTick()); - assertEquals("goblins", slayerPlugin.getTaskName()); - assertEquals(17, slayerPlugin.getAmount()); + assertEquals("goblins", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(17, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -221,8 +221,8 @@ public class SlayerPluginTest when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); slayerPlugin.onGameTick(new GameTick()); - assertEquals("Suqahs", slayerPlugin.getTaskName()); - assertEquals(211, slayerPlugin.getAmount()); + assertEquals("Suqahs", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(211, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -233,8 +233,8 @@ public class SlayerPluginTest when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); slayerPlugin.onGameTick(new GameTick()); - assertEquals("Vet'ion", slayerPlugin.getTaskName()); - assertEquals(3, slayerPlugin.getAmount()); + assertEquals("Vet'ion", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(3, slayerPlugin.getCurrentTask().getAmount()); assertEquals(914, slayerPlugin.getPoints()); } @@ -246,8 +246,8 @@ public class SlayerPluginTest when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); slayerPlugin.onGameTick(new GameTick()); - assertEquals("Chaos Elemental", slayerPlugin.getTaskName()); - assertEquals(3, slayerPlugin.getAmount()); + assertEquals("Chaos Elemental", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(3, slayerPlugin.getCurrentTask().getAmount()); assertEquals(914, slayerPlugin.getPoints()); } @@ -257,8 +257,8 @@ public class SlayerPluginTest ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_NEW_FROM_PARTNER, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); - assertEquals("Dust Devils", slayerPlugin.getTaskName()); - assertEquals(377, slayerPlugin.getAmount()); + assertEquals("Dust Devils", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(377, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -266,8 +266,8 @@ public class SlayerPluginTest { ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_CHECKSLAYERGEM, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); - assertEquals("Suqahs", slayerPlugin.getTaskName()); - assertEquals(211, slayerPlugin.getAmount()); + assertEquals("Suqahs", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(211, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -275,9 +275,9 @@ public class SlayerPluginTest { ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_CHECKSLAYERGEM_WILDERNESS, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); - assertEquals("Suqahs", slayerPlugin.getTaskName()); - assertEquals(211, slayerPlugin.getAmount()); - assertEquals("Wilderness", slayerPlugin.getTaskLocation()); + assertEquals("Suqahs", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(211, slayerPlugin.getCurrentTask().getAmount()); + assertEquals("Wilderness", slayerPlugin.getCurrentTask().getTaskLocation()); } @Test @@ -286,9 +286,9 @@ public class SlayerPluginTest ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_CHECKSLAYERGEM_KONAR, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); - assertEquals("Blue dragons", slayerPlugin.getTaskName()); - assertEquals(122, slayerPlugin.getAmount()); - assertEquals("Ogre Enclave", slayerPlugin.getTaskLocation()); + assertEquals("Blue dragons", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(122, slayerPlugin.getCurrentTask().getAmount()); + assertEquals("Ogre Enclave", slayerPlugin.getCurrentTask().getTaskLocation()); } @Test @@ -299,8 +299,8 @@ public class SlayerPluginTest when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); slayerPlugin.onGameTick(new GameTick()); - assertEquals("suqahs", slayerPlugin.getTaskName()); - assertEquals(222, slayerPlugin.getAmount()); + assertEquals("suqahs", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(222, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -325,8 +325,8 @@ public class SlayerPluginTest slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(1, slayerPlugin.getStreak()); - assertEquals("", slayerPlugin.getTaskName()); - assertEquals(0, slayerPlugin.getAmount()); + assertEquals("", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(0, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -336,8 +336,8 @@ public class SlayerPluginTest slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(3, slayerPlugin.getStreak()); - assertEquals("", slayerPlugin.getTaskName()); - assertEquals(0, slayerPlugin.getAmount()); + assertEquals("", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(0, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -347,8 +347,8 @@ public class SlayerPluginTest slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(9, slayerPlugin.getStreak()); - assertEquals("", slayerPlugin.getTaskName()); - assertEquals(0, slayerPlugin.getAmount()); + assertEquals("", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(0, slayerPlugin.getCurrentTask().getAmount()); assertEquals(18_000, slayerPlugin.getPoints()); } @@ -359,35 +359,35 @@ public class SlayerPluginTest slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(2465, slayerPlugin.getStreak()); - assertEquals("", slayerPlugin.getTaskName()); - assertEquals(0, slayerPlugin.getAmount()); + assertEquals("", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(0, slayerPlugin.getCurrentTask().getAmount()); assertEquals(17_566_000, slayerPlugin.getPoints()); } @Test public void testComplete() { - slayerPlugin.setTaskName("cows"); - slayerPlugin.setAmount(42); + slayerPlugin.getCurrentTask().setTaskName("cows"); + slayerPlugin.getCurrentTask().setAmount(42); ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_COMPLETE, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); - assertEquals("", slayerPlugin.getTaskName()); - assertEquals(0, slayerPlugin.getAmount()); + assertEquals("", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(0, slayerPlugin.getCurrentTask().getAmount()); } @Test public void testCancelled() { - slayerPlugin.setTaskName("cows"); - slayerPlugin.setAmount(42); + slayerPlugin.getCurrentTask().setTaskName("cows"); + slayerPlugin.getCurrentTask().setAmount(42); ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_CANCELED, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); - assertEquals("", slayerPlugin.getTaskName()); - assertEquals(0, slayerPlugin.getAmount()); + assertEquals("", slayerPlugin.getCurrentTask().getTaskName()); + assertEquals(0, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -409,13 +409,13 @@ public class SlayerPluginTest { ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_SLAUGHTER, null, 0); - slayerPlugin.setAmount(42); + slayerPlugin.getCurrentTask().setAmount(42); slayerPlugin.setSlaughterChargeCount(10); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(9, slayerPlugin.getSlaughterChargeCount()); - assertEquals(43, slayerPlugin.getAmount()); + assertEquals(43, slayerPlugin.getCurrentTask().getAmount()); chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", CHAT_BRACELET_SLAUGHTER_CHARGE, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); @@ -443,13 +443,13 @@ public class SlayerPluginTest chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_SLAUGHTER_V2, null, 0); - slayerPlugin.setAmount(42); + slayerPlugin.getCurrentTask().setAmount(42); slayerPlugin.setSlaughterChargeCount(2); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(1, slayerPlugin.getSlaughterChargeCount()); - assertEquals(43, slayerPlugin.getAmount()); + assertEquals(43, slayerPlugin.getCurrentTask().getAmount()); } @Test @@ -457,12 +457,12 @@ public class SlayerPluginTest { ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_EXPEDITIOUS, null, 0); - slayerPlugin.setAmount(42); + slayerPlugin.getCurrentTask().setAmount(42); slayerPlugin.setExpeditiousChargeCount(10); slayerPlugin.onChatMessage(chatMessageEvent); - assertEquals(41, slayerPlugin.getAmount()); + assertEquals(41, slayerPlugin.getCurrentTask().getAmount()); assertEquals(9, slayerPlugin.getExpeditiousChargeCount()); chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", CHAT_BRACELET_EXPEDITIOUS_CHARGE, null, 0); @@ -491,12 +491,12 @@ public class SlayerPluginTest chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_EXPEDITIOUS_V2, null, 0); - slayerPlugin.setAmount(42); + slayerPlugin.getCurrentTask().setAmount(42); slayerPlugin.setExpeditiousChargeCount(2); slayerPlugin.onChatMessage(chatMessageEvent); - assertEquals(41, slayerPlugin.getAmount()); + assertEquals(41, slayerPlugin.getCurrentTask().getAmount()); assertEquals(1, slayerPlugin.getExpeditiousChargeCount()); } @@ -507,15 +507,15 @@ public class SlayerPluginTest when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0)); when(client.getLocalPlayer()).thenReturn(player); - slayerPlugin.setTaskName("Suqahs"); - slayerPlugin.setAmount(231); + slayerPlugin.getCurrentTask().setTaskName("Suqahs"); + slayerPlugin.getCurrentTask().setAmount(231); ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", TASK_UPDATE_COMBAT_BRACELET, null, 0); slayerPlugin.onChatMessage(chatMessage); - assertEquals("Suqahs", slayerPlugin.getTaskName()); + assertEquals("Suqahs", slayerPlugin.getCurrentTask().getTaskName()); slayerPlugin.killedOne(); - assertEquals(30, slayerPlugin.getAmount()); + assertEquals(30, slayerPlugin.getCurrentTask().getAmount()); } @Test