Move npc highlight overlay to core
This allows the other plugins which depend on the npc overaly to work when npc highlight plugin is off, while still letting them use the consistent highlight style of the central overlay.
This commit is contained in:
@@ -22,10 +22,12 @@
|
||||
* (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;
|
||||
package net.runelite.client.game.npcoverlay;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.function.Predicate;
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
import net.runelite.api.NPC;
|
||||
|
||||
@@ -33,13 +35,20 @@ import net.runelite.api.NPC;
|
||||
@Builder
|
||||
public class HighlightedNpc
|
||||
{
|
||||
@NonNull
|
||||
NPC npc;
|
||||
@NonNull
|
||||
Color highlightColor;
|
||||
Color fillColor;
|
||||
@Builder.Default
|
||||
Color fillColor = new Color(0, 0, 0, 50);
|
||||
boolean hull;
|
||||
boolean tile;
|
||||
boolean swTile;
|
||||
boolean outline;
|
||||
boolean name;
|
||||
boolean nameOnMinimap;
|
||||
@Builder.Default
|
||||
float borderWidth = 2.0f;
|
||||
int outlineFeather;
|
||||
Predicate<NPC> render;
|
||||
}
|
||||
@@ -23,12 +23,13 @@
|
||||
* (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;
|
||||
package net.runelite.client.game.npcoverlay;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import net.runelite.api.Point;
|
||||
@@ -38,16 +39,13 @@ import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
public class NpcMinimapOverlay extends Overlay
|
||||
class NpcMinimapOverlay extends Overlay
|
||||
{
|
||||
private final NpcIndicatorsConfig config;
|
||||
private final NpcIndicatorsPlugin plugin;
|
||||
private final Map<NPC, HighlightedNpc> highlightedNpcs;
|
||||
|
||||
@Inject
|
||||
NpcMinimapOverlay(NpcIndicatorsConfig config, NpcIndicatorsPlugin plugin)
|
||||
NpcMinimapOverlay(Map<NPC, HighlightedNpc> highlightedNpcs)
|
||||
{
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
this.highlightedNpcs = highlightedNpcs;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
}
|
||||
@@ -55,7 +53,7 @@ public class NpcMinimapOverlay extends Overlay
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
for (HighlightedNpc highlightedNpc : plugin.getHighlightedNpcs().values())
|
||||
for (HighlightedNpc highlightedNpc : highlightedNpcs.values())
|
||||
{
|
||||
renderNpcOverlay(graphics, highlightedNpc);
|
||||
}
|
||||
@@ -67,8 +65,13 @@ public class NpcMinimapOverlay extends Overlay
|
||||
{
|
||||
NPC actor = highlightedNpc.getNpc();
|
||||
NPCComposition npcComposition = actor.getTransformedComposition();
|
||||
if (npcComposition == null || !npcComposition.isInteractible()
|
||||
|| (actor.isDead() && config.ignoreDeadNpcs()))
|
||||
if (npcComposition == null || !npcComposition.isInteractible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Predicate<NPC> render = highlightedNpc.getRender();
|
||||
if (render != null && !render.test(actor))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2018, James Swindle <wilingua@gmail.com>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.game.npcoverlay;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.outline.ModelOutlineRenderer;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
class NpcOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final ModelOutlineRenderer modelOutlineRenderer;
|
||||
private final Map<NPC, HighlightedNpc> highlightedNpcs;
|
||||
|
||||
NpcOverlay(Client client, ModelOutlineRenderer modelOutlineRenderer, Map<NPC, HighlightedNpc> highlightedNpcs)
|
||||
{
|
||||
this.client = client;
|
||||
this.modelOutlineRenderer = modelOutlineRenderer;
|
||||
this.highlightedNpcs = highlightedNpcs;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
for (HighlightedNpc highlightedNpc : highlightedNpcs.values())
|
||||
{
|
||||
renderNpcOverlay(graphics, highlightedNpc);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderNpcOverlay(Graphics2D graphics, HighlightedNpc highlightedNpc)
|
||||
{
|
||||
NPC actor = highlightedNpc.getNpc();
|
||||
NPCComposition npcComposition = actor.getTransformedComposition();
|
||||
if (npcComposition == null || !npcComposition.isInteractible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Predicate<NPC> render = highlightedNpc.getRender();
|
||||
if (render != null && !render.test(actor))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Color borderColor = highlightedNpc.getHighlightColor();
|
||||
float borderWidth = highlightedNpc.getBorderWidth();
|
||||
final Color fillColor = highlightedNpc.getFillColor();
|
||||
|
||||
if (highlightedNpc.isHull())
|
||||
{
|
||||
Shape objectClickbox = actor.getConvexHull();
|
||||
renderPoly(graphics, borderColor, borderWidth, fillColor, objectClickbox);
|
||||
}
|
||||
|
||||
if (highlightedNpc.isTile())
|
||||
{
|
||||
Polygon tilePoly = actor.getCanvasTilePoly();
|
||||
renderPoly(graphics, borderColor, borderWidth, fillColor, tilePoly);
|
||||
}
|
||||
|
||||
if (highlightedNpc.isSwTile())
|
||||
{
|
||||
int size = npcComposition.getSize();
|
||||
LocalPoint lp = actor.getLocalLocation();
|
||||
|
||||
int x = lp.getX() - ((size - 1) * Perspective.LOCAL_TILE_SIZE / 2);
|
||||
int y = lp.getY() - ((size - 1) * Perspective.LOCAL_TILE_SIZE / 2);
|
||||
|
||||
Polygon southWestTilePoly = Perspective.getCanvasTilePoly(client, new LocalPoint(x, y));
|
||||
|
||||
renderPoly(graphics, borderColor, borderWidth, fillColor, southWestTilePoly);
|
||||
}
|
||||
|
||||
if (highlightedNpc.isOutline())
|
||||
{
|
||||
modelOutlineRenderer.drawOutline(actor, (int) highlightedNpc.getBorderWidth(), borderColor, highlightedNpc.getOutlineFeather());
|
||||
}
|
||||
|
||||
if (highlightedNpc.isName() && actor.getName() != null)
|
||||
{
|
||||
String npcName = Text.removeTags(actor.getName());
|
||||
Point textLocation = actor.getCanvasTextLocation(graphics, npcName, actor.getLogicalHeight() + 40);
|
||||
|
||||
if (textLocation != null)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, npcName, borderColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderPoly(Graphics2D graphics, Color borderColor, float borderWidth, Color fillColor, Shape polygon)
|
||||
{
|
||||
if (polygon != null)
|
||||
{
|
||||
graphics.setColor(borderColor);
|
||||
graphics.setStroke(new BasicStroke(borderWidth));
|
||||
graphics.draw(polygon);
|
||||
graphics.setColor(fillColor);
|
||||
graphics.fill(polygon);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2018, James Swindle <wilingua@gmail.com>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.game.npcoverlay;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.events.NpcChanged;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.outline.ModelOutlineRenderer;
|
||||
|
||||
@Singleton
|
||||
public class NpcOverlayService
|
||||
{
|
||||
private final Client client;
|
||||
private final ClientThread clientThread;
|
||||
private final List<Function<NPC, HighlightedNpc>> highlightFunctions = new ArrayList<>();
|
||||
private final Map<NPC, HighlightedNpc> highlightedNpcs = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
private NpcOverlayService(Client client, ClientThread clientThread,
|
||||
OverlayManager overlayManager, ModelOutlineRenderer modelOutlineRenderer, EventBus eventBus)
|
||||
{
|
||||
this.client = client;
|
||||
this.clientThread = clientThread;
|
||||
overlayManager.add(new NpcOverlay(client, modelOutlineRenderer, highlightedNpcs));
|
||||
overlayManager.add(new NpcMinimapOverlay(highlightedNpcs));
|
||||
eventBus.register(this);
|
||||
}
|
||||
|
||||
@Subscribe(
|
||||
// Run after plugins, which typically capture NPCs on spawn and reference them in the highlight functions
|
||||
priority = -1
|
||||
)
|
||||
private void onNpcSpawned(NpcSpawned npcSpawned)
|
||||
{
|
||||
final NPC npc = npcSpawned.getNpc();
|
||||
|
||||
for (Function<NPC, HighlightedNpc> f : highlightFunctions)
|
||||
{
|
||||
HighlightedNpc highlightedNpc = f.apply(npc);
|
||||
if (highlightedNpc != null)
|
||||
{
|
||||
highlightedNpcs.put(npc, highlightedNpc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onNpcDespawned(NpcDespawned npcDespawned)
|
||||
{
|
||||
final NPC npc = npcDespawned.getNpc();
|
||||
highlightedNpcs.remove(npc);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onNpcChanged(NpcChanged event)
|
||||
{
|
||||
final NPC npc = event.getNpc();
|
||||
|
||||
highlightedNpcs.remove(npc);
|
||||
|
||||
for (Function<NPC, HighlightedNpc> f : highlightFunctions)
|
||||
{
|
||||
HighlightedNpc highlightedNpc = f.apply(npc);
|
||||
if (highlightedNpc != null)
|
||||
{
|
||||
highlightedNpcs.put(npc, highlightedNpc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void rebuild()
|
||||
{
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
highlightedNpcs.clear();
|
||||
|
||||
outer:
|
||||
for (NPC npc : client.getNpcs())
|
||||
{
|
||||
for (Function<NPC, HighlightedNpc> f : highlightFunctions)
|
||||
{
|
||||
HighlightedNpc highlightedNpc = f.apply(npc);
|
||||
if (highlightedNpc != null)
|
||||
{
|
||||
highlightedNpcs.put(npc, highlightedNpc);
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void registerHighlighter(Function<NPC, HighlightedNpc> p)
|
||||
{
|
||||
highlightFunctions.add(p);
|
||||
rebuild();
|
||||
}
|
||||
|
||||
public void unregisterHighlighter(Function<NPC, HighlightedNpc> p)
|
||||
{
|
||||
highlightFunctions.remove(p);
|
||||
rebuild();
|
||||
}
|
||||
}
|
||||
@@ -32,16 +32,13 @@ import net.runelite.api.NPC;
|
||||
import net.runelite.api.events.NpcChanged;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.game.npcoverlay.HighlightedNpc;
|
||||
import net.runelite.client.game.npcoverlay.NpcOverlayService;
|
||||
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;
|
||||
|
||||
@PluginDescriptor(
|
||||
@@ -49,7 +46,6 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
||||
description = "Highlight nearby implings on the minimap and on-screen",
|
||||
tags = {"hunter", "minimap", "overlay", "imp"}
|
||||
)
|
||||
@PluginDependency(NpcIndicatorsPlugin.class)
|
||||
public class ImplingsPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
@@ -65,10 +61,7 @@ public class ImplingsPlugin extends Plugin
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private NpcIndicatorsService npcIndicatorsService;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
private NpcOverlayService npcOverlayService;
|
||||
|
||||
public final Function<NPC, HighlightedNpc> isTarget = (npc) ->
|
||||
{
|
||||
@@ -79,7 +72,6 @@ public class ImplingsPlugin extends Plugin
|
||||
return HighlightedNpc.builder()
|
||||
.npc(npc)
|
||||
.highlightColor(color)
|
||||
.fillColor(new Color(0, 0, 0, 50))
|
||||
.tile(true)
|
||||
.name(true)
|
||||
.nameOnMinimap(config.showName())
|
||||
@@ -98,13 +90,13 @@ public class ImplingsPlugin extends Plugin
|
||||
protected void startUp()
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
npcIndicatorsService.registerHighlighter(isTarget);
|
||||
npcOverlayService.registerHighlighter(isTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
npcIndicatorsService.unregisterHighlighter(isTarget);
|
||||
npcOverlayService.unregisterHighlighter(isTarget);
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
|
||||
@@ -116,7 +108,7 @@ public class ImplingsPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
clientThread.invoke(npcIndicatorsService::rebuild);
|
||||
npcOverlayService.rebuild();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
||||
@@ -27,7 +27,6 @@ package net.runelite.client.plugins.npchighlight;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.time.Instant;
|
||||
@@ -66,6 +65,8 @@ import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.game.npcoverlay.HighlightedNpc;
|
||||
import net.runelite.client.game.npcoverlay.NpcOverlayService;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
@@ -79,7 +80,7 @@ import net.runelite.client.util.WildcardMatcher;
|
||||
tags = {"highlight", "minimap", "npcs", "overlay", "respawn", "tags"}
|
||||
)
|
||||
@Slf4j
|
||||
public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
public class NpcIndicatorsPlugin extends Plugin
|
||||
{
|
||||
private static final int MAX_ACTOR_VIEW_RANGE = 15;
|
||||
|
||||
@@ -104,14 +105,14 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private NpcSceneOverlay npcSceneOverlay;
|
||||
|
||||
@Inject
|
||||
private NpcMinimapOverlay npcMinimapOverlay;
|
||||
private NpcRespawnOverlay npcRespawnOverlay;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private NpcOverlayService npcOverlayService;
|
||||
|
||||
/**
|
||||
* NPCs to highlight
|
||||
*/
|
||||
@@ -175,7 +176,7 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
*/
|
||||
private boolean skipNextSpawnCheck = false;
|
||||
|
||||
private final List<Function<NPC, HighlightedNpc>> higlightPredicates = new ArrayList<>();
|
||||
private final Function<NPC, HighlightedNpc> isHighlighted = highlightedNpcs::get;
|
||||
|
||||
@Provides
|
||||
NpcIndicatorsConfig provideConfig(ConfigManager configManager)
|
||||
@@ -183,17 +184,11 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
return configManager.getConfig(NpcIndicatorsConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
{
|
||||
binder.bind(NpcIndicatorsService.class).toInstance(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(npcSceneOverlay);
|
||||
overlayManager.add(npcMinimapOverlay);
|
||||
npcOverlayService.registerHighlighter(isHighlighted);
|
||||
overlayManager.add(npcRespawnOverlay);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
skipNextSpawnCheck = true;
|
||||
@@ -204,8 +199,8 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(npcSceneOverlay);
|
||||
overlayManager.remove(npcMinimapOverlay);
|
||||
npcOverlayService.unregisterHighlighter(isHighlighted);
|
||||
overlayManager.remove(npcRespawnOverlay);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
deadNpcsToDisplay.clear();
|
||||
@@ -367,10 +362,13 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
}
|
||||
highlightedNpcs.put(npc, highlightedNpc(npc));
|
||||
}
|
||||
|
||||
npcOverlayService.rebuild();
|
||||
}
|
||||
else
|
||||
{
|
||||
final String name = npc.getName();
|
||||
// this trips a config change which triggers the overlay rebuild
|
||||
updateNpcsToHighlight(name);
|
||||
}
|
||||
|
||||
@@ -404,24 +402,7 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
memorizeNpc(npc);
|
||||
spawnedNpcsThisTick.add(npc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (Function<NPC, HighlightedNpc> predicate : higlightPredicates)
|
||||
{
|
||||
HighlightedNpc highlightedNpc = predicate.apply(npc);
|
||||
if (highlightedNpc != null)
|
||||
{
|
||||
highlightedNpcs.put(npc, highlightedNpc);
|
||||
if (!client.isInInstancedRegion())
|
||||
{
|
||||
memorizeNpc(npc);
|
||||
spawnedNpcsThisTick.add(npc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -454,17 +435,6 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
|| highlightMatchesNPCName(npcName))
|
||||
{
|
||||
highlightedNpcs.put(npc, highlightedNpc(npc));
|
||||
return;
|
||||
}
|
||||
|
||||
for (Function<NPC, HighlightedNpc> predicate : higlightPredicates)
|
||||
{
|
||||
HighlightedNpc highlightedNpc = predicate.apply(npc);
|
||||
if (highlightedNpc != null)
|
||||
{
|
||||
highlightedNpcs.put(npc, highlightedNpc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,8 +542,7 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
return Text.fromCSV(configNpcs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rebuild()
|
||||
void rebuild()
|
||||
{
|
||||
highlights = getHighlights();
|
||||
highlightedNpcs.clear();
|
||||
@@ -586,7 +555,6 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
return;
|
||||
}
|
||||
|
||||
outer:
|
||||
for (NPC npc : client.getNpcs())
|
||||
{
|
||||
final String npcName = npc.getName();
|
||||
@@ -612,23 +580,11 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Function<NPC, HighlightedNpc> predicate : higlightPredicates)
|
||||
{
|
||||
HighlightedNpc highlightedNpc = predicate.apply(npc);
|
||||
if (highlightedNpc != null)
|
||||
{
|
||||
if (!client.isInInstancedRegion())
|
||||
{
|
||||
memorizeNpc(npc);
|
||||
}
|
||||
highlightedNpcs.put(npc, highlightedNpc);
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
// NPC is not highlighted
|
||||
memorizedNpcs.remove(npc.getIndex());
|
||||
}
|
||||
|
||||
npcOverlayService.rebuild();
|
||||
}
|
||||
|
||||
private boolean highlightMatchesNPCName(String npcName)
|
||||
@@ -746,18 +702,9 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||
.outline(config.highlightOutline())
|
||||
.name(config.drawNames())
|
||||
.nameOnMinimap(config.drawMinimapNames())
|
||||
.borderWidth((float) config.borderWidth())
|
||||
.outlineFeather(config.outlineFeather())
|
||||
.render(n -> !n.isDead() || !config.ignoreDeadNpcs())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerHighlighter(Function<NPC, HighlightedNpc> p)
|
||||
{
|
||||
higlightPredicates.add(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterHighlighter(Function<NPC, HighlightedNpc> p)
|
||||
{
|
||||
higlightPredicates.remove(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Adam <Adam@sigterm.info>
|
||||
* 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.util.function.Function;
|
||||
import net.runelite.api.NPC;
|
||||
|
||||
public interface NpcIndicatorsService
|
||||
{
|
||||
void registerHighlighter(Function<NPC, HighlightedNpc> p);
|
||||
void unregisterHighlighter(Function<NPC, HighlightedNpc> p);
|
||||
void rebuild();
|
||||
}
|
||||
@@ -38,8 +38,6 @@ import java.util.Locale;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
@@ -48,10 +46,8 @@ import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.outline.ModelOutlineRenderer;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
public class NpcSceneOverlay extends Overlay
|
||||
class NpcRespawnOverlay extends Overlay
|
||||
{
|
||||
// Anything but white text is quite hard to see since it is drawn on
|
||||
// a dark background
|
||||
@@ -67,16 +63,13 @@ public class NpcSceneOverlay extends Overlay
|
||||
private final Client client;
|
||||
private final NpcIndicatorsConfig config;
|
||||
private final NpcIndicatorsPlugin plugin;
|
||||
private final ModelOutlineRenderer modelOutlineRenderer;
|
||||
|
||||
@Inject
|
||||
NpcSceneOverlay(Client client, NpcIndicatorsConfig config, NpcIndicatorsPlugin plugin,
|
||||
ModelOutlineRenderer modelOutlineRenderer)
|
||||
NpcRespawnOverlay(Client client, NpcIndicatorsConfig config, NpcIndicatorsPlugin plugin)
|
||||
{
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
this.modelOutlineRenderer = modelOutlineRenderer;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
}
|
||||
@@ -89,11 +82,6 @@ public class NpcSceneOverlay extends Overlay
|
||||
plugin.getDeadNpcsToDisplay().forEach((id, npc) -> renderNpcRespawn(npc, graphics));
|
||||
}
|
||||
|
||||
for (HighlightedNpc highlightedNpc : plugin.getHighlightedNpcs().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, highlightedNpc);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -141,61 +129,6 @@ public class NpcSceneOverlay extends Overlay
|
||||
}
|
||||
}
|
||||
|
||||
private void renderNpcOverlay(Graphics2D graphics, HighlightedNpc highlightedNpc)
|
||||
{
|
||||
NPC actor = highlightedNpc.getNpc();
|
||||
NPCComposition npcComposition = actor.getTransformedComposition();
|
||||
if (npcComposition == null || !npcComposition.isInteractible()
|
||||
|| (actor.isDead() && config.ignoreDeadNpcs()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Color borderColor = highlightedNpc.getHighlightColor();
|
||||
final Color fillColor = highlightedNpc.getFillColor();
|
||||
|
||||
if (highlightedNpc.isHull())
|
||||
{
|
||||
Shape objectClickbox = actor.getConvexHull();
|
||||
renderPoly(graphics, borderColor, fillColor, objectClickbox);
|
||||
}
|
||||
|
||||
if (highlightedNpc.isTile())
|
||||
{
|
||||
Polygon tilePoly = actor.getCanvasTilePoly();
|
||||
renderPoly(graphics, borderColor, fillColor, tilePoly);
|
||||
}
|
||||
|
||||
if (highlightedNpc.isSwTile())
|
||||
{
|
||||
int size = npcComposition.getSize();
|
||||
LocalPoint lp = actor.getLocalLocation();
|
||||
|
||||
int x = lp.getX() - ((size - 1) * Perspective.LOCAL_TILE_SIZE / 2);
|
||||
int y = lp.getY() - ((size - 1) * Perspective.LOCAL_TILE_SIZE / 2);
|
||||
|
||||
Polygon southWestTilePoly = Perspective.getCanvasTilePoly(client, new LocalPoint(x, y));
|
||||
|
||||
renderPoly(graphics, borderColor, fillColor, southWestTilePoly);
|
||||
}
|
||||
|
||||
if (highlightedNpc.isOutline())
|
||||
{
|
||||
modelOutlineRenderer.drawOutline(actor, (int)config.borderWidth(), borderColor, config.outlineFeather());
|
||||
}
|
||||
|
||||
if (highlightedNpc.isName() && actor.getName() != null)
|
||||
{
|
||||
String npcName = Text.removeTags(actor.getName());
|
||||
Point textLocation = actor.getCanvasTextLocation(graphics, npcName, actor.getLogicalHeight() + 40);
|
||||
|
||||
if (textLocation != null)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, npcName, borderColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderPoly(Graphics2D graphics, Color borderColor, Color fillColor, Shape polygon)
|
||||
{
|
||||
if (polygon != null)
|
||||
@@ -83,12 +83,10 @@ import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ChatInput;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.npcoverlay.HighlightedNpc;
|
||||
import net.runelite.client.game.npcoverlay.NpcOverlayService;
|
||||
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;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
@@ -101,7 +99,6 @@ import org.apache.commons.lang3.ArrayUtils;
|
||||
description = "Show additional slayer task related information",
|
||||
tags = {"combat", "notifications", "overlay", "tasks"}
|
||||
)
|
||||
@PluginDependency(NpcIndicatorsPlugin.class)
|
||||
@Slf4j
|
||||
public class SlayerPlugin extends Plugin
|
||||
{
|
||||
@@ -176,7 +173,7 @@ public class SlayerPlugin extends Plugin
|
||||
private ChatClient chatClient;
|
||||
|
||||
@Inject
|
||||
private NpcIndicatorsService npcIndicatorsService;
|
||||
private NpcOverlayService npcOverlayService;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final List<NPC> targets = new ArrayList<>();
|
||||
@@ -233,7 +230,7 @@ public class SlayerPlugin extends Plugin
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
chatCommandManager.registerCommandAsync(TASK_COMMAND_STRING, this::taskLookup, this::taskSubmit);
|
||||
npcIndicatorsService.registerHighlighter(isTarget);
|
||||
npcOverlayService.registerHighlighter(isTarget);
|
||||
|
||||
overlayManager.add(overlay);
|
||||
overlayManager.add(targetWeaknessOverlay);
|
||||
@@ -259,8 +256,7 @@ public class SlayerPlugin extends Plugin
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
chatCommandManager.unregisterCommand(TASK_COMMAND_STRING);
|
||||
npcIndicatorsService.unregisterHighlighter(isTarget);
|
||||
npcIndicatorsService.rebuild();
|
||||
npcOverlayService.unregisterHighlighter(isTarget);
|
||||
|
||||
overlayManager.remove(overlay);
|
||||
overlayManager.remove(targetWeaknessOverlay);
|
||||
@@ -350,10 +346,7 @@ public class SlayerPlugin extends Plugin
|
||||
setProfileConfig(SlayerConfig.TASK_LOC_KEY, taskLocation);
|
||||
}
|
||||
|
||||
@Subscribe(
|
||||
// Run prior to npc indicators plugin so targets is populated before the isTarget predicate is checked
|
||||
priority = 1
|
||||
)
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned npcSpawned)
|
||||
{
|
||||
NPC npc = npcSpawned.getNpc();
|
||||
@@ -620,7 +613,7 @@ public class SlayerPlugin extends Plugin
|
||||
}
|
||||
else
|
||||
{
|
||||
clientThread.invoke(npcIndicatorsService::rebuild);
|
||||
npcOverlayService.rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,7 +739,7 @@ public class SlayerPlugin extends Plugin
|
||||
Task task = Task.getTask(name);
|
||||
rebuildTargetNames(task);
|
||||
rebuildTargetList();
|
||||
npcIndicatorsService.rebuild();
|
||||
npcOverlayService.rebuild();
|
||||
}
|
||||
|
||||
private void addCounter()
|
||||
|
||||
@@ -78,6 +78,7 @@ public class NpcIndicatorsPluginTest
|
||||
public void setUp()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
when(npcIndicatorsConfig.highlightColor()).thenReturn(Color.RED);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -56,7 +56,7 @@ import net.runelite.client.chat.ChatCommandManager;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.npchighlight.NpcIndicatorsService;
|
||||
import net.runelite.client.game.npcoverlay.NpcOverlayService;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.http.api.chat.ChatClient;
|
||||
@@ -176,7 +176,7 @@ public class SlayerPluginTest
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
NpcIndicatorsService npcIndicatorsService;
|
||||
NpcOverlayService npcOverlayService;
|
||||
|
||||
@Inject
|
||||
SlayerPlugin slayerPlugin;
|
||||
|
||||
Reference in New Issue
Block a user