From ec7af70da4335137e485f9b4f06a65ae1e1c12de Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 22 Aug 2021 14:48:46 -0400 Subject: [PATCH] npc indicators: allow plugins to specify highlight styles After changing the slayer plugin to use npc indicators for the outline style, some users request being able to set the color of slayer highlights to be unique in order to identify marked npcs such as superiors while slaying. This readds the previous target color config and adds new highlight style options to the slayer plugin. --- .../plugins/npchighlight/HighlightedNpc.java | 45 +++++++++++++ .../npchighlight/NpcIndicatorsPlugin.java | 64 +++++++++++++------ .../npchighlight/NpcIndicatorsService.java | 6 +- .../npchighlight/NpcMinimapOverlay.java | 11 ++-- .../plugins/npchighlight/NpcSceneOverlay.java | 21 +++--- .../client/plugins/slayer/SlayerConfig.java | 46 +++++++++++-- .../client/plugins/slayer/SlayerPlugin.java | 23 ++++++- 7 files changed, 173 insertions(+), 43 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/HighlightedNpc.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/HighlightedNpc.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/HighlightedNpc.java new file mode 100644 index 0000000000..8622b1091f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/HighlightedNpc.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.npchighlight; + +import java.awt.Color; +import lombok.Builder; +import lombok.Value; +import net.runelite.api.NPC; + +@Value +@Builder +public class HighlightedNpc +{ + NPC npc; + Color highlightColor; + Color fillColor; + boolean hull; + boolean tile; + boolean swTile; + boolean outline; + boolean name; + boolean nameOnMinimap; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index 7ebe470d97..02e4926088 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -39,7 +39,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Predicate; +import java.util.function.Function; import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; @@ -116,7 +116,7 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService * NPCs to highlight */ @Getter(AccessLevel.PACKAGE) - private final Set highlightedNpcs = new HashSet<>(); + private final Map highlightedNpcs = new HashMap<>(); /** * Dead NPCs that should be displayed with a respawn indicator if the config is on. @@ -175,7 +175,7 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService */ private boolean skipNextSpawnCheck = false; - private final List> higlightPredicates = new ArrayList<>(); + private final List> higlightPredicates = new ArrayList<>(); @Provides NpcIndicatorsConfig provideConfig(ConfigManager configManager) @@ -265,7 +265,7 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService color = config.deadNpcMenuColor(); } - if (color == null && highlightedNpcs.contains(npc) && config.highlightMenuNames() && (!npc.isDead() || !config.ignoreDeadNpcs())) + if (color == null && highlightedNpcs.containsKey(npc) && config.highlightMenuNames() && (!npc.isDead() || !config.ignoreDeadNpcs())) { color = config.highlightColor(); } @@ -365,7 +365,7 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService memorizeNpc(npc); npcTags.add(id); } - highlightedNpcs.add(npc); + highlightedNpcs.put(npc, highlightedNpc(npc)); } } else @@ -391,14 +391,14 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService if (npcTags.contains(npc.getIndex())) { memorizeNpc(npc); - highlightedNpcs.add(npc); + highlightedNpcs.put(npc, highlightedNpc(npc)); spawnedNpcsThisTick.add(npc); return; } if (highlightMatchesNPCName(npcName)) { - highlightedNpcs.add(npc); + highlightedNpcs.put(npc, highlightedNpc(npc)); if (!client.isInInstancedRegion()) { memorizeNpc(npc); @@ -407,11 +407,12 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService return; } - for (Predicate predicate : higlightPredicates) + for (Function predicate : higlightPredicates) { - if (predicate.test(npc)) + HighlightedNpc highlightedNpc = predicate.apply(npc); + if (highlightedNpc != null) { - highlightedNpcs.add(npc); + highlightedNpcs.put(npc, highlightedNpc); if (!client.isInInstancedRegion()) { memorizeNpc(npc); @@ -452,7 +453,18 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService if (npcTags.contains(npc.getIndex()) || highlightMatchesNPCName(npcName)) { - highlightedNpcs.add(npc); + highlightedNpcs.put(npc, highlightedNpc(npc)); + return; + } + + for (Function predicate : higlightPredicates) + { + HighlightedNpc highlightedNpc = predicate.apply(npc); + if (highlightedNpc != null) + { + highlightedNpcs.put(npc, highlightedNpc); + return; + } } } @@ -586,7 +598,7 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService if (npcTags.contains(npc.getIndex())) { - highlightedNpcs.add(npc); + highlightedNpcs.put(npc, highlightedNpc(npc)); continue; } @@ -596,19 +608,20 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService { memorizeNpc(npc); } - highlightedNpcs.add(npc); + highlightedNpcs.put(npc, highlightedNpc(npc)); continue; } - for (Predicate predicate : higlightPredicates) + for (Function predicate : higlightPredicates) { - if (predicate.test(npc)) + HighlightedNpc highlightedNpc = predicate.apply(npc); + if (highlightedNpc != null) { if (!client.isInInstancedRegion()) { memorizeNpc(npc); } - highlightedNpcs.add(npc); + highlightedNpcs.put(npc, highlightedNpc); continue outer; } } @@ -721,14 +734,29 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService teleportGraphicsObjectSpawnedThisTick.clear(); } + private HighlightedNpc highlightedNpc(NPC npc) + { + return HighlightedNpc.builder() + .npc(npc) + .highlightColor(config.highlightColor()) + .fillColor(config.fillColor()) + .hull(config.highlightHull()) + .tile(config.highlightTile()) + .swTile(config.highlightSouthWestTile()) + .outline(config.highlightOutline()) + .name(config.drawNames()) + .nameOnMinimap(config.drawMinimapNames()) + .build(); + } + @Override - public void registerHighlighter(Predicate p) + public void registerHighlighter(Function p) { higlightPredicates.add(p); } @Override - public void unregisterHighlighter(Predicate p) + public void unregisterHighlighter(Function p) { higlightPredicates.remove(p); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsService.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsService.java index 43a3b91694..440f33fd65 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsService.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsService.java @@ -24,12 +24,12 @@ */ package net.runelite.client.plugins.npchighlight; -import java.util.function.Predicate; +import java.util.function.Function; import net.runelite.api.NPC; public interface NpcIndicatorsService { - void registerHighlighter(Predicate p); - void unregisterHighlighter(Predicate p); + void registerHighlighter(Function p); + void unregisterHighlighter(Function p); void rebuild(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java index 52a17975a7..b8905f93ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java @@ -55,16 +55,18 @@ public class NpcMinimapOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - for (NPC npc : plugin.getHighlightedNpcs()) + for (HighlightedNpc highlightedNpc : plugin.getHighlightedNpcs().values()) { - renderNpcOverlay(graphics, npc, Text.removeTags(npc.getName()), config.highlightColor()); + renderNpcOverlay(graphics, highlightedNpc); } return null; } - private void renderNpcOverlay(Graphics2D graphics, NPC actor, String name, Color color) + private void renderNpcOverlay(Graphics2D graphics, HighlightedNpc highlightedNpc) { + NPC actor = highlightedNpc.getNpc(); + String name = Text.removeTags(actor.getName()); NPCComposition npcComposition = actor.getTransformedComposition(); if (npcComposition == null || !npcComposition.isInteractible() || (actor.isDead() && config.ignoreDeadNpcs())) @@ -75,9 +77,10 @@ public class NpcMinimapOverlay extends Overlay Point minimapLocation = actor.getMinimapLocation(); if (minimapLocation != null) { + Color color = highlightedNpc.getHighlightColor(); OverlayUtil.renderMinimapLocation(graphics, minimapLocation, color.darker()); - if (config.drawMinimapNames()) + if (highlightedNpc.isNameOnMinimap()) { OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java index 8c2b2b3b06..84e428918c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java @@ -89,9 +89,9 @@ public class NpcSceneOverlay extends Overlay plugin.getDeadNpcsToDisplay().forEach((id, npc) -> renderNpcRespawn(npc, graphics)); } - for (NPC npc : plugin.getHighlightedNpcs()) + for (HighlightedNpc highlightedNpc : plugin.getHighlightedNpcs().values()) { - renderNpcOverlay(graphics, npc); + renderNpcOverlay(graphics, highlightedNpc); } return null; @@ -141,8 +141,9 @@ public class NpcSceneOverlay extends Overlay } } - private void renderNpcOverlay(Graphics2D graphics, NPC actor) + private void renderNpcOverlay(Graphics2D graphics, HighlightedNpc highlightedNpc) { + NPC actor = highlightedNpc.getNpc(); NPCComposition npcComposition = actor.getTransformedComposition(); if (npcComposition == null || !npcComposition.isInteractible() || (actor.isDead() && config.ignoreDeadNpcs())) @@ -150,16 +151,16 @@ public class NpcSceneOverlay extends Overlay return; } - final Color borderColor = config.highlightColor(); - final Color fillColor = config.fillColor(); + final Color borderColor = highlightedNpc.getHighlightColor(); + final Color fillColor = highlightedNpc.getFillColor(); - if (config.highlightHull()) + if (highlightedNpc.isHull()) { Shape objectClickbox = actor.getConvexHull(); renderPoly(graphics, borderColor, fillColor, objectClickbox); } - if (config.highlightTile()) + if (highlightedNpc.isTile()) { int size = npcComposition.getSize(); LocalPoint lp = actor.getLocalLocation(); @@ -168,7 +169,7 @@ public class NpcSceneOverlay extends Overlay renderPoly(graphics, borderColor, fillColor, tilePoly); } - if (config.highlightSouthWestTile()) + if (highlightedNpc.isSwTile()) { int size = npcComposition.getSize(); LocalPoint lp = actor.getLocalLocation(); @@ -181,12 +182,12 @@ public class NpcSceneOverlay extends Overlay renderPoly(graphics, borderColor, fillColor, southWestTilePoly); } - if (config.highlightOutline()) + if (highlightedNpc.isOutline()) { modelOutlineRenderer.drawOutline(actor, (int)config.borderWidth(), borderColor, config.outlineFeather()); } - if (config.drawNames() && actor.getName() != null) + if (highlightedNpc.isName() && actor.getName() != null) { String npcName = Text.removeTags(actor.getName()); Point textLocation = actor.getCanvasTextLocation(graphics, npcName, actor.getLogicalHeight() + 40); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerConfig.java index 258ea51b17..55952cb6d2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerConfig.java @@ -25,6 +25,8 @@ */ package net.runelite.client.plugins.slayer; +import java.awt.Color; +import net.runelite.client.config.Alpha; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -90,17 +92,51 @@ public interface SlayerConfig extends Config @ConfigItem( position = 5, - keyName = "highlightTargets", - name = "Highlight Targets", - description = "Highlight monsters you can kill for your current slayer assignment" + keyName = "highlightHull", + name = "Highlight hull", + description = "Configures whether the NPC hull should be highlighted" ) - default boolean highlightTargets() + default boolean highlightHull() + { + return false; + } + + @ConfigItem( + position = 6, + keyName = "highlightTile", + name = "Highlight tile", + description = "Configures whether the NPC tile should be highlighted" + ) + default boolean highlightTile() { return false; } @ConfigItem( position = 7, + keyName = "highlightOutline", + name = "Highlight outline", + description = "Configures whether or not the NPC outline should be highlighted" + ) + default boolean highlightOutline() + { + return false; + } + + @Alpha + @ConfigItem( + position = 8, + keyName = "targetColor", + name = "Target color", + description = "Color of the highlighted targets" + ) + default Color getTargetColor() + { + return Color.RED; + } + + @ConfigItem( + position = 9, keyName = "weaknessPrompt", name = "Show Monster Weakness", description = "Show an overlay on a monster when it is weak enough to finish off (Only Lizards, Gargoyles & Rockslugs)" @@ -111,7 +147,7 @@ public interface SlayerConfig extends Config } @ConfigItem( - position = 8, + position = 10, keyName = "taskCommand", name = "Task Command", description = "Configures whether the slayer task command is enabled
!task" 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 729debeb25..6983270fa1 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 @@ -39,7 +39,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ScheduledExecutorService; -import java.util.function.Predicate; +import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; @@ -86,6 +86,7 @@ import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.npchighlight.HighlightedNpc; import net.runelite.client.plugins.npchighlight.NpcIndicatorsPlugin; import net.runelite.client.plugins.npchighlight.NpcIndicatorsService; import net.runelite.client.ui.overlay.OverlayManager; @@ -210,7 +211,23 @@ public class SlayerPlugin extends Plugin private boolean loginFlag; private final List targetNames = new ArrayList<>(); - public final Predicate isTarget = (n) -> config.highlightTargets() && targets.contains(n); + public final Function isTarget = (n) -> + { + if ((config.highlightHull() || config.highlightTile() || config.highlightOutline()) && targets.contains(n)) + { + Color color = config.getTargetColor(); + return HighlightedNpc.builder() + .npc(n) + .highlightColor(color) + .fillColor(ColorUtil.colorWithAlpha(color, color.getAlpha() / 12)) + .hull(config.highlightHull()) + .tile(config.highlightTile()) + .outline(config.highlightOutline()) + .build(); + + } + return null; + }; @Override protected void startUp() throws Exception @@ -603,7 +620,7 @@ public class SlayerPlugin extends Plugin } else { - npcIndicatorsService.rebuild(); + clientThread.invoke(npcIndicatorsService::rebuild); } }