Repository: runelite/runelite
Pull request #18181 (2024-08-21 05:18:17)

tithe farm: remove unused config
The pie timer on fully grown plants was removed in #17931 so this config option doesn't do anything anymore.


Patch:
diff --git a/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java b/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java
index 97511a09b..6ed585fcd 100644
--- a/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java
+++ b/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java
@@ -25,8 +25,10 @@
 package net.runelite.api.coords;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.List;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
 import lombok.Getter;
 import net.runelite.api.CollisionData;
 import net.runelite.api.CollisionDataFlag;
@@ -250,8 +252,8 @@ public class WorldArea
 	 * with some actors. However, using the {@code extraCondition} param
 	 * it is possible to implement this check manually.
 	 *
-	 * @param dx the x-axis direction to travel (-1, 0, or 1)
-	 * @param dy the y-axis direction to travel (-1, 0, or 1)
+	 * @param dx             the x-axis direction to travel (-1, 0, or 1)
+	 * @param dy             the y-axis direction to travel (-1, 0, or 1)
 	 * @param extraCondition an additional condition to perform when checking valid tiles,
 	 *                       such as performing a check for un-passable actors
 	 * @return true if the area can travel in the specified direction
@@ -488,80 +490,34 @@ public class WorldArea
 			return false;
 		}
 
-		LocalPoint sourceLp = LocalPoint.fromWorld(wv, x, y);
-		LocalPoint targetLp = LocalPoint.fromWorld(wv, other.getX(), other.getY());
-		if (sourceLp == null || targetLp == null)
-		{
-			return false;
-		}
-
-		int thisX = sourceLp.getSceneX();
-		int thisY = sourceLp.getSceneY();
-		int otherX = targetLp.getSceneX();
-		int otherY = targetLp.getSceneY();
-
-		int cmpThisX, cmpThisY, cmpOtherX, cmpOtherY;
-
-		// Determine which position to compare with for this NPC
-		if (otherX <= thisX)
-		{
-			cmpThisX = thisX;
-		}
-		else if (otherX >= thisX + width - 1)
-		{
-			cmpThisX = thisX + width - 1;
-		}
-		else
-		{
-			cmpThisX = otherX;
-		}
-		if (otherY <= thisY)
-		{
-			cmpThisY = thisY;
-		}
-		else if (otherY >= thisY + height - 1)
-		{
-			cmpThisY = thisY + height - 1;
-		}
-		else
+		List<WorldPoint> fromEdges = other.getVisibleCandidates(this);
+		List<WorldPoint> toEdges = this.getVisibleCandidates(other);
+		Tile[][][] tiles = wv.getScene().getTiles();
+		for (WorldPoint fromPoint : fromEdges)
 		{
-			cmpThisY = otherY;
-		}
+			for (WorldPoint toPoint : toEdges)
+			{
+				LocalPoint fromLp = LocalPoint.fromWorld(wv, fromPoint);
+				LocalPoint toLp = LocalPoint.fromWorld(wv, toPoint);
 
-		// Determine which position to compare for the other actor
-		if (thisX <= otherX)
-		{
-			cmpOtherX = otherX;
-		}
-		else if (thisX >= otherX + other.getWidth() - 1)
-		{
-			cmpOtherX = otherX + other.getWidth() - 1;
-		}
-		else
-		{
-			cmpOtherX = thisX;
-		}
-		if (thisY <= otherY)
-		{
-			cmpOtherY = otherY;
-		}
-		else if (thisY >= otherY + other.getHeight() - 1)
-		{
-			cmpOtherY = otherY + other.getHeight() - 1;
-		}
-		else
-		{
-			cmpOtherY = thisY;
-		}
+				if (fromLp == null || toLp == null)
+				{
+					continue;
+				}
 
-		Tile[][][] tiles = wv.getScene().getTiles();
-		Tile sourceTile = tiles[plane][cmpThisX][cmpThisY];
-		Tile targetTile = tiles[other.getPlane()][cmpOtherX][cmpOtherY];
-		if (sourceTile == null || targetTile == null)
-		{
-			return false;
+				Tile sourceTile = tiles[plane][fromLp.getSceneX()][fromLp.getSceneY()];
+				Tile targetTile = tiles[other.getPlane()][toLp.getSceneX()][toLp.getSceneY()];
+				if (sourceTile == null || targetTile == null)
+				{
+					continue;
+				}
+				if (hasLineOfSightTo(wv, sourceTile, targetTile))
+				{
+					return true;
+				}
+			}
 		}
-		return hasLineOfSightTo(wv, sourceTile, targetTile);
+		return false;
 	}
 
 	private static boolean hasLineOfSightTo(WorldView wv, Tile from, Tile to)
@@ -692,6 +648,99 @@ public class WorldArea
 		return hasLineOfSightTo(wv, other.toWorldArea());
 	}
 
+	/**
+	 * Gets the points of another worldArea that may be viewable by this WorldArea
+	 * The points are sorted by their distance to the closest point in this WorldArea
+	 *
+	 * @param other the other WorldArea
+	 * @return the list of potentially visible points
+	 */
+	private List<WorldPoint> getVisibleCandidates(WorldArea other)
+	{
+		Point compPoint = this.getComparisonPoint(other);
+		Comparator<WorldPoint> byDistance = Comparator.comparingInt((p) -> p.distanceTo(
+			new WorldPoint(compPoint.getX(), compPoint.getY(), this.getPlane())));
+
+		return other.toWorldPointList()
+			.stream()
+			.filter(p -> isEdgePoint(other, p))
+			.filter(p -> isVisibleCandidate(other, p))
+			.sorted(byDistance)
+			.collect(Collectors.toList());
+	}
+
+	/**
+	 * Checks if the given point is on the edge of the provided WorldArea
+	 *
+	 * @param p Point to test
+	 * @return true if on the edge, false otherwise
+	 */
+	private static boolean isEdgePoint(WorldArea wa, WorldPoint p)
+	{
+		return p.getX() == wa.getX()
+			|| p.getX() == wa.getX() + wa.getWidth() - 1
+			|| p.getY() == wa.getY()
+			|| p.getY() == wa.getY() + wa.getHeight() - 1;
+	}
+
+	/**
+	 * Prunes potentially visible WorldArea points in the other WorldArea by checking
+	 * if the given point is on a visible edge.
+	 *
+	 * @param other The other WorldArea
+	 * @param p     Test point in other WorldArea
+	 * @return true if the point is on a potentially visible edge, false otherwise
+	 */
+	private boolean isVisibleCandidate(WorldArea other, WorldPoint p)
+	{
+		if (this.intersectsWith(other))
+		{
+			return false;
+		}
+		// This WorldArea is east of other
+		if (this.getX() + this.getWidth() - 1 > other.getX() + other.getWidth() - 1)
+		{
+			// Southeast
+			if (this.getY() < other.getY())
+			{
+				return p.getX() == other.getX() + other.getWidth() - 1 || p.getY() == other.getY();
+			}
+			// Northeast
+			if (this.getY() + this.getHeight() - 1 > other.getY() + other.getHeight() - 1)
+			{
+				return p.getX() == other.getX() + other.getWidth() - 1 || p.getY() == other.getY() + other.getHeight() - 1;
+			}
+			return p.getX() == other.getX() + other.getWidth() - 1;
+		}
+		// This WorldArea is west of other
+		else if (this.getX() < other.getX())
+		{
+			// Southwest
+			if (this.getY() < other.getY())
+			{
+				return p.getX() == other.getX() || p.getY() == other.getY();
+			}
+			// Northwest
+			if (this.getY() + this.getHeight() - 1 > other.getY() + other.getHeight() - 1)
+			{
+				return p.getX() == other.getX() || p.getY() == other.getY() + other.getHeight() - 1;
+			}
+			// Straight west
+			return p.getX() == other.getX();
+		}
+		// This WorldArea is north
+		else if (this.getY() > other.getY() + other.getHeight() - 1)
+		{
+			return p.getY() == other.getY() + other.getHeight() - 1;
+		}
+		// This WorldArea is south
+		else if (this.getY() < other.getY())
+		{
+			return p.getY() == other.getY();
+		}
+		return false;
+	}
+
 	/**
 	 * Retrieves the southwestern most point of this WorldArea.
 	 *
diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java
index c534c8994..f31a1d59d 100644
--- a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java
+++ b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java
@@ -126,7 +126,7 @@ public enum ItemMapping
 	ITEM_RUNE_CROSSBOW(RUNE_CROSSBOW, RUNE_CROSSBOW_OR),
 
 	// Godsword ornament kits
-	ITEM_ARMADYL_GODSWORD(ARMADYL_GODSWORD, ARMADYL_GODSWORD_OR),
+	ITEM_ARMADYL_GODSWORD(ARMADYL_GODSWORD, ARMADYL_GODSWORD_OR, ARMADYL_GODSWORD_DEADMAN),
 	ITEM_ARMADYL_GODSWORD_ORNAMENT_KIT(ARMADYL_GODSWORD_ORNAMENT_KIT, ARMADYL_GODSWORD_OR),
 	ITEM_BANDOS_GODSWORD(BANDOS_GODSWORD, BANDOS_GODSWORD_OR),
 	ITEM_BANDOS_GODSWORD_ORNAMENT_KIT(BANDOS_GODSWORD_ORNAMENT_KIT, BANDOS_GODSWORD_OR),
@@ -286,7 +286,7 @@ public enum ItemMapping
 	ITEM_INFINITY_HAT_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_HAT),
 
 	// Miscellaneous ornament kits
-	ITEM_DARK_BOW(DARK_BOW, DARK_BOW_12765, DARK_BOW_12766, DARK_BOW_12767, DARK_BOW_12768, DARK_BOW_20408, DARK_BOW_BH),
+	ITEM_DARK_BOW(DARK_BOW, DARK_BOW_12765, DARK_BOW_12766, DARK_BOW_12767, DARK_BOW_12768, DARK_BOW_20408, DARK_BOW_BH, DARK_BOW_DEADMAN),
 	ITEM_ODIUM_WARD(ODIUM_WARD, ODIUM_WARD_12807),
 	ITEM_MALEDICTION_WARD(MALEDICTION_WARD, MALEDICTION_WARD_12806),
 	ITEM_STEAM_BATTLESTAFF(STEAM_BATTLESTAFF, STEAM_BATTLESTAFF_12795),
@@ -294,6 +294,7 @@ public enum ItemMapping
 	ITEM_TZHAARKETOM(TZHAARKETOM, TZHAARKETOM_T),
 	ITEM_TZHAARKETOM_ORNAMENT_KIT(TZHAARKETOM_ORNAMENT_KIT, TZHAARKETOM_T),
 	ITEM_DRAGON_HUNTER_CROSSBOW(DRAGON_HUNTER_CROSSBOW, DRAGON_HUNTER_CROSSBOW_B, DRAGON_HUNTER_CROSSBOW_T),
+	ITEM_VOIDWAKER(VOIDWAKER, VOIDWAKER_DEADMAN),
 
 	// Slayer helm/black mask
 	ITEM_BLACK_MASK(BLACK_MASK, true, 1L, BLACK_MASK, SLAYER_HELMET),
@@ -308,8 +309,8 @@ public enum ItemMapping
 	ITEM_TWISTED_HORNS(TWISTED_HORNS, TWISTED_SLAYER_HELMET, TWISTED_SLAYER_HELMET_I, TWISTED_SLAYER_HELMET_I_25191, TWISTED_SLAYER_HELMET_I_26681),
 	ITEM_ELDRITCH_ORB(ELDRITCH_ORB, ELDRITCH_NIGHTMARE_STAFF),
 	ITEM_HARMONISED_ORB(HARMONISED_ORB, HARMONISED_NIGHTMARE_STAFF),
-	ITEM_VOLATILE_ORB(VOLATILE_ORB, VOLATILE_NIGHTMARE_STAFF),
-	ITEM_NIGHTMARE_STAFF(NIGHTMARE_STAFF, ELDRITCH_NIGHTMARE_STAFF, HARMONISED_NIGHTMARE_STAFF, VOLATILE_NIGHTMARE_STAFF),
+	ITEM_VOLATILE_ORB(VOLATILE_ORB, VOLATILE_NIGHTMARE_STAFF, VOLATILE_NIGHTMARE_STAFF_DEADMAN),
+	ITEM_NIGHTMARE_STAFF(NIGHTMARE_STAFF, ELDRITCH_NIGHTMARE_STAFF, HARMONISED_NIGHTMARE_STAFF, VOLATILE_NIGHTMARE_STAFF, VOLATILE_NIGHTMARE_STAFF_DEADMAN),
 	ITEM_GHARZI_RAPIER(GHRAZI_RAPIER, HOLY_GHRAZI_RAPIER),
 	ITEM_MASTER_SCROLL_BOOK(MASTER_SCROLL_BOOK_EMPTY, MASTER_SCROLL_BOOK),
 	ITEM_ARCANE_SIGIL(ARCANE_SIGIL, ELIDINIS_WARD_F, ELIDINIS_WARD_OR),
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java
index d06e5cdb6..e169b09a2 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java
@@ -162,7 +162,8 @@ public class MenuEntrySwapperPlugin extends Plugin
 	private NpcUtil npcUtil;
 
 	private final Multimap<String, Swap> swaps = LinkedHashMultimap.create();
-	private final ArrayListMultimap<String, Integer> optionIndexes = ArrayListMultimap.create();
+	private final ArrayListMultimap<String, Integer> cacheOptionIndexes = ArrayListMultimap.create();
+	private Menu cacheOptionMenu;
 	private final Multimap<Integer, TeleportSwap> teleportSwaps = HashMultimap.create();
 	private boolean lastShift, curShift;
 
@@ -1337,7 +1338,7 @@ public class MenuEntrySwapperPlugin extends Plugin
 		};
 	}
 
-	private boolean swapBank(MenuEntry menuEntry, MenuAction type)
+	private boolean swapBank(Menu menu, MenuEntry menuEntry, MenuAction type)
 	{
 		if (type != MenuAction.CC_OP && type != MenuAction.CC_OP_LOW_PRIORITY)
 		{
@@ -1362,7 +1363,7 @@ public class MenuEntrySwapperPlugin extends Plugin
 				: isGroupStoragePlayerInventory ? shiftDepositMode.getIdentifierGroupStorage()
 				: shiftDepositMode.getIdentifier();
 			final MenuAction action = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY : MenuAction.CC_OP;
-			bankModeSwap(action, opId);
+			bankModeSwap(menu, action, opId);
 			return true;
 		}
 
@@ -1385,16 +1386,16 @@ public class MenuEntrySwapperPlugin extends Plugin
 				action = shiftWithdrawMode.getMenuAction();
 				opId = shiftWithdrawMode.getIdentifier();
 			}
-			bankModeSwap(action, opId);
+			bankModeSwap(menu, action, opId);
 			return true;
 		}
 
 		return false;
 	}
 
-	private void bankModeSwap(MenuAction entryType, int entryIdentifier)
+	private void bankModeSwap(Menu menu, MenuAction entryType, int entryIdentifier)
 	{
-		MenuEntry[] menuEntries = client.getMenuEntries();
+		MenuEntry[] menuEntries = menu.getMenuEntries();
 
 		for (int i = menuEntries.length - 1; i >= 0; --i)
 		{
@@ -1408,13 +1409,13 @@ public class MenuEntrySwapperPlugin extends Plugin
 				menuEntries[i] = menuEntries[menuEntries.length - 1];
 				menuEntries[menuEntries.length - 1] = entry;
 
-				client.setMenuEntries(menuEntries);
+				menu.setMenuEntries(menuEntries);
 				break;
 			}
 		}
 	}
 
-	private void swapMenuEntry(MenuEntry parent, MenuEntry[] menuEntries, int index, MenuEntry menuEntry)
+	private void swapMenuEntry(MenuEntry parent, Menu menu, MenuEntry[] menuEntries, int index, MenuEntry menuEntry)
 	{
 		Menu sub = menuEntry.getSubMenu();
 		if (sub != null)
@@ -1423,7 +1424,7 @@ public class MenuEntrySwapperPlugin extends Plugin
 			MenuEntry[] subEntries = sub.getMenuEntries();
 			for (MenuEntry subEntry : subEntries)
 			{
-				swapMenuEntry(menuEntry, subEntries, subidx++, subEntry);
+				swapMenuEntry(menuEntry, sub, subEntries, subidx++, subEntry);
 			}
 		}
 
@@ -1442,11 +1443,11 @@ public class MenuEntrySwapperPlugin extends Plugin
 			{
 				if (swapIndex == -1)
 				{
-					swap(menuEntries, "use", target, index, true);
+					swap(menu, menuEntries, "use", target, index, true);
 				}
 				else if (swapIndex + 1 == menuEntry.getItemOp())
 				{
-					swap(optionIndexes, menuEntries, index, menuEntries.length - 1);
+					swap(menu, menuEntries, index, menuEntries.length - 1);
 				}
 				// Submenu swap. The swapIndex is actually the option hashCode.
 				else if (parent != null && menuEntry.getOption().hashCode() == swapIndex)
@@ -1472,7 +1473,7 @@ public class MenuEntrySwapperPlugin extends Plugin
 				{
 					if (wornItemSwapConfig == menuEntry.getIdentifier())
 					{
-						swap(optionIndexes, menuEntries, index, menuEntries.length - 1);
+						swap(menu, menuEntries, index, menuEntries.length - 1);
 					}
 					// Submenu swap.
 					else if (parent != null && menuEntry.getOption().hashCode() == wornItemSwapConfig)
@@ -1505,7 +1506,7 @@ public class MenuEntrySwapperPlugin extends Plugin
 				MenuAction swapAction = OBJECT_MENU_TYPES.get(customOption);
 				if (swapAction == menuAction)
 				{
-					swap(optionIndexes, menuEntries, index, menuEntries.length - 1);
+					swap(menu, menuEntries, index, menuEntries.length - 1);
 					return;
 				}
 			}
@@ -1531,7 +1532,7 @@ public class MenuEntrySwapperPlugin extends Plugin
 						++i;
 					}
 
-					swap(optionIndexes, menuEntries, index, i);
+					swap(menu, menuEntries, index, i);
 					return;
 				}
 			}
@@ -1553,13 +1554,13 @@ public class MenuEntrySwapperPlugin extends Plugin
 				final Integer op = getUiSwapConfig(shiftModifier(), componentId, itemId);
 				if (op != null && op == menuEntry.getIdentifier())
 				{
-					swap(optionIndexes, menuEntries, index, menuEntries.length - 1);
+					swap(menu, menuEntries, index, menuEntries.length - 1);
 					return;
 				}
 			}
 		}
 
-		if (swapBank(menuEntry, menuAction))
+		if (swapBank(menu, menuEntry, menuAction))
 		{
 			return;
 		}
@@ -1580,7 +1581,7 @@ public class MenuEntrySwapperPlugin extends Plugin
 		{
 			if (swap.getTargetPredicate().test(target) && swap.getEnabled().get())
 			{
-				if (swap(menuEntries, swap.getSwappedOption(), target, index, swap.isStrict()))
+				if (swap(menu, menuEntries, swap.getSwappedOption(), target, index, swap.isStrict()))
 				{
 					break;
 				}
@@ -1669,28 +1670,24 @@ public class MenuEntrySwapperPlugin extends Plugin
 			return;
 		}
 
-		MenuEntry[] menuEntries = client.getMenuEntries();
-
-		// Build option map for quick lookup in findIndex
-		int idx = 0;
-		optionIndexes.clear();
-		for (MenuEntry entry : menuEntries)
-		{
-			String option = Text.removeTags(entry.getOption()).toLowerCase();
-			optionIndexes.put(option, idx++);
-		}
+		Menu root = client.getMenu();
+		MenuEntry[] menuEntries = root.getMenuEntries();
 
 		// Perform swaps
-		idx = 0;
+		int idx = 0;
 		for (MenuEntry entry : menuEntries)
 		{
-			swapMenuEntry(null, menuEntries, idx++, entry);
+			swapMenuEntry(null, root, menuEntries, idx++, entry);
 		}
 
 		if (config.removeDeadNpcMenus())
 		{
 			removeDeadNpcs();
 		}
+
+		// invalidate option index cache
+		cacheOptionIndexes.clear();
+		cacheOptionMenu = null;
 	}
 
 	private void removeDeadNpcs()
@@ -1709,25 +1706,25 @@ public class MenuEntrySwapperPlugin extends Plugin
 		}
 	}
 
-	private boolean swap(MenuEntry[] menuEntries, String option, String target, int index, boolean strict)
+	private boolean swap(Menu menu, MenuEntry[] menuEntries, String option, String target, int index, boolean strict)
 	{
 		// find option to swap with
-		int optionIdx = findIndex(menuEntries, index, option, target, strict);
+		int optionIdx = findIndex(menu, menuEntries, index, option, target, strict);
 
 		if (optionIdx >= 0)
 		{
-			swap(optionIndexes, menuEntries, optionIdx, index);
+			swap(menu, menuEntries, optionIdx, index);
 			return true;
 		}
 
 		return false;
 	}
 
-	private int findIndex(MenuEntry[] entries, int limit, String option, String target, boolean strict)
+	private int findIndex(Menu menu, MenuEntry[] entries, int limit, String option, String target, boolean strict)
 	{
 		if (strict)
 		{
-			List<Integer> indexes = optionIndexes.get(option);
+			List<Integer> indexes = findOptionIndex(menu, option);
 
 			// We want the last index which matches the target, as that is what is top-most
 			// on the menu
@@ -1764,7 +1761,24 @@ public class MenuEntrySwapperPlugin extends Plugin
 		return -1;
 	}
 
-	private void swap(ArrayListMultimap<String, Integer> optionIndexes, MenuEntry[] entries, int index1, int index2)
+	private List<Integer> findOptionIndex(Menu menu, String option)
+	{
+		if (cacheOptionMenu == null || cacheOptionIndexes.isEmpty())
+		{
+			int idx = 0;
+			cacheOptionMenu = menu;
+			cacheOptionIndexes.clear();
+			for (MenuEntry entry : menu.getMenuEntries())
+			{
+				String opt = Text.removeTags(entry.getOption()).toLowerCase();
+				cacheOptionIndexes.put(opt, idx++);
+			}
+			log.trace("[{}] Rebuilt option index cache with {} entries", client.getGameCycle(), idx);
+		}
+		return cacheOptionIndexes.get(option);
+	}
+
+	private void swap(Menu menu, MenuEntry[] entries, int index1, int index2)
 	{
 		if (index1 == index2)
 		{
@@ -1788,21 +1802,26 @@ public class MenuEntrySwapperPlugin extends Plugin
 			entry2.setType(MenuAction.CC_OP);
 		}
 
-		client.setMenuEntries(entries);
+		menu.setMenuEntries(entries);
 
 		// Update optionIndexes
-		String option1 = Text.removeTags(entry1.getOption()).toLowerCase(),
-			option2 = Text.removeTags(entry2.getOption()).toLowerCase();
+		if (cacheOptionMenu == menu)
+		{
+			String option1 = Text.removeTags(entry1.getOption()).toLowerCase(),
+				option2 = Text.removeTags(entry2.getOption()).toLowerCase();
 
-		List<Integer> list1 = optionIndexes.get(option1),
-			list2 = optionIndexes.get(option2);
+			List<Integer> list1 = cacheOptionIndexes.get(option1),
+				list2 = cacheOptionIndexes.get(option2);
 
-		// call remove(Object) instead of remove(int)
-		list1.remove((Integer) index1);
-		list2.remove((Integer) index2);
+			// call remove(Object) instead of remove(int)
+			list1.remove((Integer) index1);
+			list2.remove((Integer) index2);
 
-		sortedInsert(list1, index2);
-		sortedInsert(list2, index1);
+			sortedInsert(list1, index2);
+			sortedInsert(list2, index1);
+
+			log.trace("Swapped option index {} <-> {}", index1, index2);
+		}
 	}
 
 	private static <T extends Comparable<? super T>> void sortedInsert(List<T> list, T value)
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 3cf59bdc1..8cb8c8cf3 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
@@ -493,7 +493,8 @@ public class SlayerPlugin extends Plugin
 	@Subscribe
 	public void onMenuOptionClicked(MenuOptionClicked menuOptionClicked)
 	{
-		if (menuOptionClicked.getMenuAction() == MenuAction.CC_OP && menuOptionClicked.getMenuOption().equals("Check"))
+		if ((menuOptionClicked.getMenuAction() == MenuAction.CC_OP || menuOptionClicked.getMenuAction() == MenuAction.CC_OP_LOW_PRIORITY)
+			&& menuOptionClicked.getMenuOption().equals("Check"))
 		{
 			Widget w = client.getWidget(menuOptionClicked.getParam1());
 			if (w == null)
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java
index 2193e1e7b..bdba82747 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java
@@ -38,24 +38,24 @@ enum Task
 {
 	//<editor-fold desc="Enums">
 	ABERRANT_SPECTRES("Aberrant spectres", ItemID.ABERRANT_SPECTRE, "Spectre"),
-	ABYSSAL_DEMONS("Abyssal demons", ItemID.ABYSSAL_DEMON),
+	ABYSSAL_DEMONS("Abyssal demons", ItemID.ABYSSAL_DEMON, "Abyssal Sire"),
 	ABYSSAL_SIRE("The Abyssal Sire", ItemID.ABYSSAL_ORPHAN),
 	ADAMANT_DRAGONS("Adamant dragons", ItemID.ADAMANT_DRAGON_MASK),
 	ALCHEMICAL_HYDRA("The Alchemical Hydra", ItemID.IKKLE_HYDRA),
 	ANKOU("Ankou", ItemID.ANKOU_MASK),
-	AVIANSIES("Aviansies", ItemID.ENSOULED_AVIANSIE_HEAD),
+	AVIANSIES("Aviansies", ItemID.ENSOULED_AVIANSIE_HEAD, "Kree'arra", "Flight Kilisa", "Flockleader Geerin", "Wingman Skree"),
 	BANDITS("Bandits", ItemID.BANDIT, "Bandit", "Black Heather", "Donny the Lad", "Speedy Keith"),
 	BANSHEES("Banshees", ItemID.BANSHEE),
 	BARROWS_BROTHERS("Barrows Brothers", ItemID.KARILS_COIF),
 	BASILISKS("Basilisks", ItemID.BASILISK),
 	BATS("Bats", ItemID.GIRAL_BAT_2, "Death wing"),
-	BEARS("Bears", ItemID.ENSOULED_BEAR_HEAD),
-	BIRDS("Birds", ItemID.FEATHER, "Chicken", "Rooster", "Terrorbird", "Seagull", "Vulture", "Duck", "Penguin"),
-	BLACK_DEMONS("Black demons", ItemID.BLACK_DEMON_MASK),
-	BLACK_DRAGONS("Black dragons", ItemID.BLACK_DRAGON_MASK, "Baby black dragon"),
+	BEARS("Bears", ItemID.ENSOULED_BEAR_HEAD, "Callisto", "Artio"),
+	BIRDS("Birds", ItemID.FEATHER, "Chicken", "Rooster", "Terrorbird", "Seagull", "Vulture", "Duck", "Penguin", "Baby Roc"),
+	BLACK_DEMONS("Black demons", ItemID.BLACK_DEMON_MASK, "Demonic gorilla", "Balfrug Kreeyath", "Skotizo", "Porazdir"),
+	BLACK_DRAGONS("Black dragons", ItemID.BLACK_DRAGON_MASK),
 	BLACK_KNIGHTS("Black Knights", ItemID.BLACK_FULL_HELM, "Black Knight"),
 	BLOODVELD("Bloodveld", ItemID.BLOODVELD),
-	BLUE_DRAGONS("Blue dragons", ItemID.BLUE_DRAGON_MASK, "Baby blue dragon"),
+	BLUE_DRAGONS("Blue dragons", ItemID.BLUE_DRAGON_MASK, "Vorkath"),
 	BRINE_RATS("Brine rats", ItemID.BRINE_RAT),
 	BRONZE_DRAGONS("Bronze dragons", ItemID.BRONZE_DRAGON_MASK),
 	CALLISTO("Callisto", ItemID.CALLISTO_CUB),
@@ -63,46 +63,46 @@ enum Task
 	CAVE_BUGS("Cave bugs", ItemID.SWAMP_CAVE_BUG),
 	CAVE_CRAWLERS("Cave crawlers", ItemID.CAVE_CRAWLER, "Chasm crawler"),
 	CAVE_HORRORS("Cave horrors", ItemID.CAVE_HORROR, "Cave abomination"),
-	CAVE_KRAKEN("Cave kraken", ItemID.CAVE_KRAKEN),
+	CAVE_KRAKEN("Cave kraken", ItemID.CAVE_KRAKEN, "Kraken"),
 	CAVE_SLIMES("Cave slimes", ItemID.SWAMP_CAVE_SLIME),
 	CERBERUS("Cerberus", ItemID.HELLPUPPY),
-	CHAOS_DRUIDS("Chaos druids", ItemID.ELDER_CHAOS_HOOD, "Elder Chaos druid", "Chaos druid"),
+	CHAOS_DRUIDS("Chaos druids", ItemID.ELDER_CHAOS_HOOD),
 	CHAOS_ELEMENTAL("The Chaos Elemental", ItemID.PET_CHAOS_ELEMENTAL),
 	CHAOS_FANATIC("The Chaos Fanatic", ItemID.ANCIENT_STAFF),
 	COCKATRICE("Cockatrice", ItemID.COCKATRICE, "Cockathrice"),
 	COWS("Cows", ItemID.COW_MASK),
 	CRAWLING_HANDS("Crawling hands", ItemID.CRAWLING_HAND, "Crushing hand"),
-	CRAZY_ARCHAEOLOGIST("Crazy Archaeologists", ItemID.FEDORA, "Crazy Archaeologist"),
+	CRAZY_ARCHAEOLOGIST("Crazy Archaeologists", ItemID.FEDORA),
 	CROCODILES("Crocodiles", ItemID.SWAMP_LIZARD),
 	DAGANNOTH("Dagannoth", ItemID.DAGANNOTH),
 	DAGANNOTH_KINGS("Dagannoth Kings", ItemID.PET_DAGANNOTH_PRIME),
 	DARK_BEASTS("Dark beasts", ItemID.DARK_BEAST, "Night beast"),
 	DARK_WARRIORS("Dark warriors", ItemID.BLACK_MED_HELM, "Dark warrior"),
 	DERANGED_ARCHAEOLOGIST("Deranged Archaeologist", ItemID.ARCHAEOLOGISTS_DIARY),
-	DOGS("Dogs", ItemID.GUARD_DOG, "Jackal"),
+	DOGS("Dogs", ItemID.GUARD_DOG, "Jackal", "Temple Guardian"),
 	DRAKES("Drakes", ItemID.DRAKE),
 	DUKE_SUCELLUS("Duke Sucellus", ItemID.BARON),
 	DUST_DEVILS("Dust devils", ItemID.DUST_DEVIL, "Choke devil"),
 	DWARVES("Dwarves", ItemID.DWARVEN_HELMET, "Dwarf", "Black Guard"),
 	EARTH_WARRIORS("Earth warriors", ItemID.BRONZE_FULL_HELM_T),
 	ELVES("Elves", ItemID.ELF, "Elf", "Iorwerth Warrior", "Iorwerth Archer"),
-	ENTS("Ents", ItemID.NICE_TREE, "Ent"),
+	ENTS("Ents", ItemID.NICE_TREE),
 	FEVER_SPIDERS("Fever spiders", ItemID.FEVER_SPIDER),
 	FIRE_GIANTS("Fire giants", ItemID.FIRE_BATTLESTAFF),
 	FLESH_CRAWLERS("Fleshcrawlers", ItemID.ENSOULED_SCORPION_HEAD, "Flesh crawler"),
 	FOSSIL_ISLAND_WYVERNS("Fossil island wyverns", ItemID.FOSSIL_ISLAND_WYVERN, "Ancient wyvern", "Long-tailed wyvern", "Spitting wyvern", "Taloned wyvern"),
-	GARGOYLES("Gargoyles", ItemID.GARGOYLE, 9, ItemID.ROCK_HAMMER),
+	GARGOYLES("Gargoyles", ItemID.GARGOYLE, 9, ItemID.ROCK_HAMMER, "Dusk", "Dawn"),
 	GENERAL_GRAARDOR("General Graardor", ItemID.PET_GENERAL_GRAARDOR),
 	GHOSTS("Ghosts", ItemID.GHOSTSPEAK_AMULET, "Death wing", "Tortured soul", "Forgotten Soul", "Revenant"),
 	GHOULS("Ghouls", ItemID.ZOMBIE_HEAD),
 	GIANT_MOLE("The Giant Mole", ItemID.BABY_MOLE),
-	GOBLINS("Goblins", ItemID.ENSOULED_GOBLIN_HEAD),
-	GREATER_DEMONS("Greater demons", ItemID.GREATER_DEMON_MASK),
-	GREEN_DRAGONS("Green dragons", ItemID.GREEN_DRAGON_MASK, "Baby green dragon", "Elvarg"),
+	GOBLINS("Goblins", ItemID.ENSOULED_GOBLIN_HEAD, "Sergeant Strongstack", "Sergeant Grimspike", "Sergeant Steelwill"),
+	GREATER_DEMONS("Greater demons", ItemID.GREATER_DEMON_MASK, "K'ril Tsutsaroth", "Tstanon Karlak", "Skotizo", "Tormented Demon"),
+	GREEN_DRAGONS("Green dragons", ItemID.GREEN_DRAGON_MASK, "Elvarg"),
 	GROTESQUE_GUARDIANS("The Grotesque Guardians", ItemID.MIDNIGHT, 0, ItemID.ROCK_HAMMER, "Dusk", "Dawn"),
 	HARPIE_BUG_SWARMS("Harpie bug swarms", ItemID.SWARM),
-	HELLHOUNDS("Hellhounds", ItemID.HELLHOUND),
-	HILL_GIANTS("Hill giants", ItemID.ENSOULED_GIANT_HEAD, "Cyclops"),
+	HELLHOUNDS("Hellhounds", ItemID.HELLHOUND, "Cerberus"),
+	HILL_GIANTS("Hill giants", ItemID.ENSOULED_GIANT_HEAD, "Cyclops", "Reanimated giant", "Obor"),
 	HOBGOBLINS("Hobgoblins", ItemID.HOBGOBLIN_GUARD),
 	HYDRAS("Hydras", ItemID.HYDRA),
 	ICEFIENDS("Icefiends", ItemID.ICE_DIAMOND),
@@ -122,43 +122,43 @@ enum Task
 	KRIL_TSUTSAROTH("K'ril Tsutsaroth", ItemID.PET_KRIL_TSUTSAROTH),
 	KURASK("Kurask", ItemID.KURASK),
 	LAVA_DRAGONS("Lava Dragons", ItemID.LAVA_SCALE, "Lava dragon"),
-	LESSER_DEMONS("Lesser demons", ItemID.LESSER_DEMON_MASK),
+	LESSER_DEMONS("Lesser demons", ItemID.LESSER_DEMON_MASK, "Zakl'n Gritch"),
 	LESSER_NAGUA("Lesser Nagua", ItemID.LESSER_NAGUA, "Sulphur Nagua"),
 	LIZARDMEN("Lizardmen", ItemID.LIZARDMAN_FANG, "Lizardman"),
-	LIZARDS("Lizards", ItemID.DESERT_LIZARD, "Desert lizard", "Sulphur lizard", "Small lizard", "Lizard"),
-	MAGIC_AXES("Magic axes", ItemID.IRON_BATTLEAXE, "Magic axe"),
-	MAMMOTHS("Mammoths", ItemID.ATTACKER_HORN, "Mammoth"),
+	LIZARDS("Lizards", ItemID.DESERT_LIZARD),
+	MAGIC_AXES("Magic axes", ItemID.IRON_BATTLEAXE),
+	MAMMOTHS("Mammoths", ItemID.ATTACKER_HORN),
 	MINIONS_OF_SCABARAS("Minions of scabaras", ItemID.GOLDEN_SCARAB, "Scarab swarm", "Locust rider", "Scarab mage"),
 	MINOTAURS("Minotaurs", ItemID.ENSOULED_MINOTAUR_HEAD),
 	MITHRIL_DRAGONS("Mithril dragons", ItemID.MITHRIL_DRAGON_MASK),
 	MOGRES("Mogres", ItemID.MOGRE),
 	MOLANISKS("Molanisks", ItemID.MOLANISK),
-	MONKEYS("Monkeys", ItemID.ENSOULED_MONKEY_HEAD, "Tortured gorilla"),
-	MOSS_GIANTS("Moss giants", ItemID.MOSSY_KEY),
+	MONKEYS("Monkeys", ItemID.ENSOULED_MONKEY_HEAD, "Tortured gorilla", "Demonic gorilla", "Padulah"),
+	MOSS_GIANTS("Moss giants", ItemID.MOSSY_KEY, "Bryophyta"),
 	MUTATED_ZYGOMITES("Mutated zygomites", ItemID.MUTATED_ZYGOMITE, 7, ItemID.FUNGICIDE_SPRAY_0, "Zygomite", "Fungi"),
 	NECHRYAEL("Nechryael", ItemID.NECHRYAEL, "Nechryarch"),
-	OGRES("Ogres", ItemID.ENSOULED_OGRE_HEAD, "Mogre", "Ogress", "Skogre", "Zogre"),
+	OGRES("Ogres", ItemID.ENSOULED_OGRE_HEAD, "Enclave guard", "Mogre", "Ogress", "Skogre", "Zogre"),
 	OTHERWORLDLY_BEING("Otherworldly beings", ItemID.GHOSTLY_HOOD),
 	PHANTOM_MUSPAH("The Phantom Muspah", ItemID.MUPHIN),
 	PIRATES("Pirates", ItemID.PIRATE_HAT, "Pirate"),
 	PYREFIENDS("Pyrefiends", ItemID.PYREFIEND, "Flaming pyrelord"),
 	RATS("Rats", ItemID.RATS_TAIL),
-	RED_DRAGONS("Red dragons", ItemID.BABY_RED_DRAGON, "Baby red dragon"),
-	REVENANTS("Revenants", ItemID.BRACELET_OF_ETHEREUM, "Revenant imp", "Revenant goblin", "Revenant pyrefiend", "Revenant hobgoblin", "Revenant cyclops", "Revenant hellhound", "Revenant demon", "Revenant ork", "Revenant dark beast", "Revenant knight", "Revenant dragon"),
+	RED_DRAGONS("Red dragons", ItemID.BABY_RED_DRAGON),
+	REVENANTS("Revenants", ItemID.BRACELET_OF_ETHEREUM),
 	ROCKSLUGS("Rockslugs", ItemID.ROCKSLUG, 4, ItemID.BAG_OF_SALT),
-	ROGUES("Rogues", ItemID.ROGUE_MASK, "Rogue"),
+	ROGUES("Rogues", ItemID.ROGUE_MASK),
 	RUNE_DRAGONS("Rune dragons", ItemID.RUNE_DRAGON_MASK),
 	SARACHNIS("Sarachnis", ItemID.SRARACHA),
 	SCORPIA("Scorpia", ItemID.SCORPIAS_OFFSPRING),
-	SCORPIONS("Scorpions", ItemID.ENSOULED_SCORPION_HEAD),
+	SCORPIONS("Scorpions", ItemID.ENSOULED_SCORPION_HEAD, "Scorpia", "Lobstrosity"),
 	SEA_SNAKES("Sea snakes", ItemID.SNAKE_CORPSE),
-	SHADES("Shades", ItemID.SHADE_ROBE_TOP, "Loar Shadow", "Loar Shade", "Phrin Shadow", "Phrin Shade", "Riyl Shadow", "Riyl Shade", "Asyn Shadow", "Asyn Shade", "Fiyr Shadow", "Fiyr Shade"),
+	SHADES("Shades", ItemID.SHADE_ROBE_TOP, "Loar", "Phrin", "Riyl", "Asyn", "Fiyr", "Urium"),
 	SHADOW_WARRIORS("Shadow warriors", ItemID.BLACK_FULL_HELM),
 	SKELETAL_WYVERNS("Skeletal wyverns", ItemID.SKELETAL_WYVERN),
-	SKELETONS("Skeletons", ItemID.SKELETON_GUARD),
+	SKELETONS("Skeletons", ItemID.SKELETON_GUARD, "Vet'ion", "Calvar'ion"),
 	SMOKE_DEVILS("Smoke devils", ItemID.SMOKE_DEVIL),
 	SOURHOGS("Sourhogs", ItemID.SOURHOG_FOOT),
-	SPIDERS("Spiders", ItemID.HUGE_SPIDER),
+	SPIDERS("Spiders", ItemID.HUGE_SPIDER, "Kalrag", "Sarachnis", "Venenatis", "Spindel"),
 	SPIRITUAL_CREATURES("Spiritual creatures", ItemID.DRAGON_BOOTS, "Spiritual ranger", "Spiritual mage", "Spiritual warrior"),
 	STEEL_DRAGONS("Steel dragons", ItemID.STEEL_DRAGON),
 	SUQAHS("Suqahs", ItemID.SUQAH_TOOTH),
@@ -166,10 +166,10 @@ enum Task
 	THE_LEVIATHAN("The Leviathan", ItemID.LILVIATHAN),
 	THE_WHISPERER("The Whisperer", ItemID.WISP),
 	THERMONUCLEAR_SMOKE_DEVIL("The Thermonuclear Smoke Devil", ItemID.PET_SMOKE_DEVIL),
-	TROLLS("Trolls", ItemID.TROLL_GUARD, "Dad", "Arrg"),
+	TROLLS("Trolls", ItemID.TROLL_GUARD, "Dad", "Arrg", "Stick", "Kraka", "Pee Hat", "Rock", "Twig", "Berry"),
 	TUROTH("Turoth", ItemID.TUROTH),
-	TZHAAR("Tzhaar", ItemID.ENSOULED_TZHAAR_HEAD),
-	VAMPYRES("Vampyres", ItemID.STAKE, "Vyrewatch", "Vampire"),
+	TZHAAR("Tzhaar", ItemID.ENSOULED_TZHAAR_HEAD, "TzTok-Jad", "TzKal-Zuk"),
+	VAMPYRES("Vampyres", ItemID.STAKE, "Vyrewatch"),
 	VARDORVIS("Vardorvis", ItemID.BUTCH),
 	VENENATIS("Venenatis", ItemID.VENENATIS_SPIDERLING),
 	VETION("Vet'ion", ItemID.VETION_JR),
@@ -181,7 +181,7 @@ enum Task
 	WOLVES("Wolves", ItemID.GREY_WOLF_FUR, "Wolf"),
 	WYRMS("Wyrms", ItemID.WYRM),
 	ZILYANA("Commander Zilyana", ItemID.PET_ZILYANA),
-	ZOMBIES("Zombies", ItemID.ZOMBIE_HEAD, "Undead"),
+	ZOMBIES("Zombies", ItemID.ZOMBIE_HEAD, "Undead", "Vorkath", "Zogre"),
 	ZUK("TzKal-Zuk", ItemID.TZREKZUK),
 	ZULRAH("Zulrah", ItemID.PET_SNAKELING);
 	//</editor-fold>
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantOverlay.java
index 7394fed37..91a0143ad 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantOverlay.java
@@ -75,11 +75,6 @@ public class TitheFarmPlantOverlay extends Overlay
 		final Color colorWatered = ColorUtil.colorWithAlpha(colorWateredBorder, (int) (colorWateredBorder.getAlpha() / 2.5));
 		borders.put(TitheFarmPlantState.WATERED, colorWateredBorder);
 		fills.put(TitheFarmPlantState.WATERED, colorWatered);
-
-		final Color colorGrownBorder = config.getColorGrown();
-		final Color colorGrown = ColorUtil.colorWithAlpha(colorGrownBorder, (int) (colorGrownBorder.getAlpha() / 2.5));
-		borders.put(TitheFarmPlantState.GROWN, colorGrownBorder);
-		fills.put(TitheFarmPlantState.GROWN, colorGrown);
 	}
 
 	@Override
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPluginConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPluginConfig.java
index f9ee9a26d..bbf591461 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPluginConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPluginConfig.java
@@ -56,16 +56,4 @@ public interface TitheFarmPluginConfig extends Config
 	{
 		return new Color(0, 153, 255);
 	}
-
-	@Alpha
-	@ConfigItem(
-		position = 3,
-		keyName = "hexColorGrown",
-		name = "Grown plant",
-		description = "Color of grown plant timer"
-	)
-	default Color getColorGrown()
-	{
-		return new Color(0, 217, 0);
-	}
 }


Test patch:
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java
index 6d2cc692c..13e440a3b 100644
--- a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java
@@ -31,6 +31,7 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule;
 import java.util.Arrays;
 import net.runelite.api.Client;
 import net.runelite.api.KeyCode;
+import net.runelite.api.Menu;
 import net.runelite.api.MenuAction;
 import net.runelite.api.MenuEntry;
 import net.runelite.api.NPC;
@@ -85,6 +86,7 @@ public class MenuEntrySwapperPluginTest
 	@Inject
 	MenuEntrySwapperPlugin menuEntrySwapperPlugin;
 
+	private Menu menu;
 	private NPC npc;
 	private MenuEntry[] entries;
 
@@ -99,7 +101,10 @@ public class MenuEntrySwapperPluginTest
 		NPCComposition composition = mock(NPCComposition.class);
 		when(npc.getTransformedComposition()).thenReturn(composition);
 
-		when(client.getMenuEntries()).thenAnswer((Answer<MenuEntry[]>) invocationOnMock ->
+		menu = mock(Menu.class);
+		when(client.getMenu()).thenReturn(menu);
+
+		when(menu.getMenuEntries()).thenAnswer((Answer<MenuEntry[]>) invocationOnMock ->
 		{
 			// The menu implementation returns a copy of the array, which causes swap() to not
 			// modify the same array being iterated in onClientTick
@@ -110,7 +115,7 @@ public class MenuEntrySwapperPluginTest
 			Object argument = invocationOnMock.getArguments()[0];
 			entries = (MenuEntry[]) argument;
 			return null;
-		}).when(client).setMenuEntries(any(MenuEntry[].class));
+		}).when(menu).setMenuEntries(any(MenuEntry[].class));
 
 		menuEntrySwapperPlugin.startUp();
 	}
@@ -153,7 +158,7 @@ public class MenuEntrySwapperPluginTest
 		menuEntrySwapperPlugin.onPostMenuSort(new PostMenuSort());
 
 		ArgumentCaptor<MenuEntry[]> argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class);
-		verify(client).setMenuEntries(argumentCaptor.capture());
+		verify(menu).setMenuEntries(argumentCaptor.capture());
 
 		// check the assignment swap is hit first instead of trade
 		assertArrayEquals(new MenuEntry[]{
@@ -190,7 +195,7 @@ public class MenuEntrySwapperPluginTest
 		menuEntrySwapperPlugin.onPostMenuSort(new PostMenuSort());
 
 		ArgumentCaptor<MenuEntry[]> argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class);
-		verify(client, times(2)).setMenuEntries(argumentCaptor.capture());
+		verify(menu, times(2)).setMenuEntries(argumentCaptor.capture());
 
 		assertArrayEquals(new MenuEntry[]{
 			menu("Cancel", "", MenuAction.CANCEL),
@@ -228,7 +233,7 @@ public class MenuEntrySwapperPluginTest
 		menuEntrySwapperPlugin.onPostMenuSort(new PostMenuSort());
 
 		ArgumentCaptor<MenuEntry[]> argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class);
-		verify(client).setMenuEntries(argumentCaptor.capture());
+		verify(menu).setMenuEntries(argumentCaptor.capture());
 
 		assertArrayEquals(new MenuEntry[]{
 			menu("Cancel", "", MenuAction.CANCEL),
@@ -259,7 +264,7 @@ public class MenuEntrySwapperPluginTest
 		menuEntrySwapperPlugin.onPostMenuSort(new PostMenuSort());
 
 		ArgumentCaptor<MenuEntry[]> argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class);
-		verify(client).setMenuEntries(argumentCaptor.capture());
+		verify(menu).setMenuEntries(argumentCaptor.capture());
 
 		assertArrayEquals(new MenuEntry[]{
 			menu("Cancel", "", MenuAction.CANCEL),
@@ -286,7 +291,7 @@ public class MenuEntrySwapperPluginTest
 		menuEntrySwapperPlugin.onPostMenuSort(new PostMenuSort());
 
 		ArgumentCaptor<MenuEntry[]> argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class);
-		verify(client).setMenuEntries(argumentCaptor.capture());
+		verify(menu).setMenuEntries(argumentCaptor.capture());
 
 		assertArrayEquals(new MenuEntry[]{
 			menu("Cancel", "", MenuAction.CANCEL),
@@ -311,7 +316,7 @@ public class MenuEntrySwapperPluginTest
 		menuEntrySwapperPlugin.onPostMenuSort(new PostMenuSort());
 
 		ArgumentCaptor<MenuEntry[]> argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class);
-		verify(client).setMenuEntries(argumentCaptor.capture());
+		verify(menu).setMenuEntries(argumentCaptor.capture());
 
 		assertArrayEquals(new MenuEntry[]{
 			menu("Cancel", "", MenuAction.CANCEL),
@@ -339,7 +344,7 @@ public class MenuEntrySwapperPluginTest
 		menuEntrySwapperPlugin.onPostMenuSort(new PostMenuSort());
 
 		ArgumentCaptor<MenuEntry[]> argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class);
-		verify(client).setMenuEntries(argumentCaptor.capture());
+		verify(menu).setMenuEntries(argumentCaptor.capture());
 
 		assertArrayEquals(new MenuEntry[]{
 			menu("Cancel", "", MenuAction.CANCEL),
@@ -369,7 +374,7 @@ public class MenuEntrySwapperPluginTest
 		menuEntrySwapperPlugin.onPostMenuSort(new PostMenuSort());
 
 		ArgumentCaptor<MenuEntry[]> argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class);
-		verify(client).setMenuEntries(argumentCaptor.capture());
+		verify(menu).setMenuEntries(argumentCaptor.capture());
 
 		assertArrayEquals(new MenuEntry[]{
 			menu("Cancel", "", MenuAction.CANCEL),
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 7f36e52e4..90c8f5ee8 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
@@ -272,11 +272,19 @@ public class SlayerPluginTest
 	@Test
 	public void npcMatching()
 	{
+		assertTrue(matches("Abyssal Sire", Task.ABYSSAL_DEMONS));
 		assertTrue(matches("Abyssal demon", Task.ABYSSAL_DEMONS));
 		assertTrue(matches("Baby blue dragon", Task.BLUE_DRAGONS));
+		assertTrue(matches("Vorkath", Task.BLUE_DRAGONS));
+		assertTrue(matches("Brutal red dragon", Task.RED_DRAGONS));
 		assertTrue(matches("Duck", Task.BIRDS));
 		assertTrue(matches("Donny the Lad", Task.BANDITS));
 		assertTrue(matches("Revenant Imp", Task.GHOSTS));
+		assertTrue(matches("Sulphur lizard", Task.LIZARDS));
+		assertTrue(matches("Spiked Turoth", Task.TUROTH));
+		assertTrue(matches("Loar shade", Task.SHADES));
+		assertTrue(matches("Loar shadow", Task.SHADES));
+		assertTrue(matches("Urium shadow", Task.SHADES));
 
 		assertFalse(matches("Rat", Task.PIRATES));
 		assertFalse(matches("Wolf", Task.WEREWOLVES));