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 b535ec643a..6c7b95ebd9 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 @@ -203,7 +203,7 @@ public class SlayerPlugin extends Plugin private int cachedXp = -1; private Instant infoTimer; private boolean loginFlag; - private final List targetNames = new ArrayList<>(); + private final List targetNames = new ArrayList<>(); public final Function isTarget = (n) -> { @@ -664,7 +664,8 @@ public class SlayerPlugin extends Plugin SlayerUnlock.GROTESQUE_GUARDIAN_DOUBLE_COUNT.isEnabled(client); } - private boolean isTarget(NPC npc) + @VisibleForTesting + boolean isTarget(NPC npc) { if (targetNames.isEmpty()) { @@ -681,16 +682,15 @@ public class SlayerPlugin extends Plugin .replace('\u00A0', ' ') .toLowerCase(); - for (String target : targetNames) + for (Pattern target : targetNames) { - if (name.contains(target)) - { - if (ArrayUtils.contains(composition.getActions(), "Attack") + final Matcher targetMatcher = target.matcher(name); + if (targetMatcher.find() + && (ArrayUtils.contains(composition.getActions(), "Attack") // Pick action is for zygomite-fungi - || ArrayUtils.contains(composition.getActions(), "Pick")) - { - return true; - } + || ArrayUtils.contains(composition.getActions(), "Pick"))) + { + return true; } } return false; @@ -703,13 +703,18 @@ public class SlayerPlugin extends Plugin if (task != null) { Arrays.stream(task.getTargetNames()) - .map(String::toLowerCase) + .map(SlayerPlugin::targetNamePattern) .forEach(targetNames::add); - targetNames.add(taskName.toLowerCase().replaceAll("s$", "")); + targetNames.add(targetNamePattern(taskName.replaceAll("s$", ""))); } } + private static Pattern targetNamePattern(final String targetName) + { + return Pattern.compile("(?:\\s|^)" + targetName + "(?:\\s|$)", Pattern.CASE_INSENSITIVE); + } + private void rebuildTargetList() { targets.clear(); @@ -723,7 +728,8 @@ public class SlayerPlugin extends Plugin } } - private void setTask(String name, int amt, int initAmt) + @VisibleForTesting + void setTask(String name, int amt, int initAmt) { setTask(name, amt, initAmt, null); } 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 3fc570c233..6ce2d86783 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 @@ -60,6 +60,8 @@ import net.runelite.client.game.npcoverlay.NpcOverlayService; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -926,4 +928,30 @@ public class SlayerPluginTest assertEquals("Suqahs", slayerPlugin.getTaskName()); assertEquals(229, slayerPlugin.getAmount()); // 2 kills } + + @Test + public void npcMatching() + { + assertTrue(matches("Abyssal demon", Task.ABYSSAL_DEMONS)); + assertTrue(matches("Baby blue dragon", Task.BLUE_DRAGONS)); + assertTrue(matches("Duck", Task.BIRDS)); + assertTrue(matches("Donny the Lad", Task.BANDITS)); + + assertFalse(matches("Rat", Task.PIRATES)); + assertFalse(matches("Wolf", Task.WEREWOLVES)); + assertFalse(matches("Scorpia's offspring", Task.SCORPIA)); + assertFalse(matches("Jonny the beard", Task.BEARS)); + } + + private boolean matches(final String npcName, final Task task) + { + final NPC npc = mock(NPC.class); + final NPCComposition comp = mock(NPCComposition.class); + when(npc.getTransformedComposition()).thenReturn(comp); + when(comp.getName()).thenReturn(npcName); + when(comp.getActions()).thenReturn(new String[] { "Attack" }); + + slayerPlugin.setTask(task.getName(), 0, 0); + return slayerPlugin.isTarget(npc); + } }