Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2021-08-25 06:18:52 +02:00
15 changed files with 1353 additions and 1237 deletions

View File

@@ -69,7 +69,7 @@ import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.vars.AccountType;
import net.runelite.api.widgets.Widget;
import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID;
import static net.runelite.api.widgets.WidgetID.GENERIC_SCROLL_GROUP_ID;
import static net.runelite.api.widgets.WidgetID.DIARY_QUEST_GROUP_ID;
import static net.runelite.api.widgets.WidgetID.KILL_LOGS_GROUP_ID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread;
@@ -109,9 +109,9 @@ import org.apache.commons.text.WordUtils;
public class ChatCommandsPlugin extends Plugin
{
private static final Pattern KILLCOUNT_PATTERN = Pattern.compile("Your (?:completion count for |subdued |completed )?(.+?) (?:(?:kill|harvest|lap|completion) )?(?:count )?is: <col=ff0000>(\\d+)</col>");
private static final String COX_TEAM_SIZES = "(?:\\d+(?:\\+|-\\d+)? players|Solo)";
private static final Pattern RAIDS_PB_PATTERN = Pattern.compile("<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>" + COX_TEAM_SIZES + "</col> Duration:</col> <col=ff0000>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col> \\(new personal best\\)</col>");
private static final Pattern RAIDS_DURATION_PATTERN = Pattern.compile("<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>" + COX_TEAM_SIZES + "</col> Duration:</col> <col=ff0000>[0-9:.]+</col> Personal best: </col><col=ff0000>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col>");
private static final String TEAM_SIZES = "(?:\\d+(?:\\+|-\\d+)? players|Solo)";
private static final Pattern RAIDS_PB_PATTERN = Pattern.compile("<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>" + TEAM_SIZES + "</col> Duration:</col> <col=ff0000>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col> \\(new personal best\\)</col>");
private static final Pattern RAIDS_DURATION_PATTERN = Pattern.compile("<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>" + TEAM_SIZES + "</col> Duration:</col> <col=ff0000>[0-9:.]+</col> Personal best: </col><col=ff0000>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col>");
private static final Pattern TOB_WAVE_PB_PATTERN = Pattern.compile("Theatre of Blood wave completion time: <col=ff0000>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col> \\(new personal best\\)");
private static final Pattern TOB_WAVE_DURATION_PATTERN = Pattern.compile("Theatre of Blood wave completion time: <col=ff0000>[0-9:.]+</col>\\. Personal best: (?<pb>[0-9:]+(?:\\.[0-9]+)?)");
private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?i)(?:(?:Fight |Lap |Challenge |Corrupted challenge )?duration:|Subdued in) <col=[0-9a-f]{6}>[0-9:.]+</col>\\. Personal best: (?:<col=ff0000>)?(?<pb>[0-9:]+(?:\\.[0-9]+)?)");
@@ -119,9 +119,7 @@ public class ChatCommandsPlugin extends Plugin
private static final Pattern DUEL_ARENA_WINS_PATTERN = Pattern.compile("You (were defeated|won)! You have(?: now)? won (\\d+) duels?");
private static final Pattern DUEL_ARENA_LOSSES_PATTERN = Pattern.compile("You have(?: now)? lost (\\d+) duels?");
private static final Pattern ADVENTURE_LOG_TITLE_PATTERN = Pattern.compile("The Exploits of (.+)");
private static final Pattern ADVENTURE_LOG_COX_PB_PATTERN = Pattern.compile("Fastest (?:kill|run)(?: - \\(Team size: " + COX_TEAM_SIZES + "\\))?: ([0-9:]+(?:\\.[0-9]+)?)");
private static final Pattern ADVENTURE_LOG_BOSS_PB_PATTERN = Pattern.compile("[a-zA-Z]+(?: [a-zA-Z]+)*");
private static final Pattern ADVENTURE_LOG_PB_PATTERN = Pattern.compile("(" + ADVENTURE_LOG_BOSS_PB_PATTERN + "(?: - " + ADVENTURE_LOG_BOSS_PB_PATTERN + ")*) (?:" + ADVENTURE_LOG_COX_PB_PATTERN + "( )*)+");
private static final Pattern ADVENTURE_LOG_PB_PATTERN = Pattern.compile("Fastest (?:kill|run)(?: - \\(Team size: " + TEAM_SIZES + "\\))?: ([0-9:]+(?:\\.[0-9]+)?)");
private static final Pattern HS_PB_PATTERN = Pattern.compile("Floor (?<floor>\\d) time: <col=ff0000>(?<floortime>[0-9:]+(?:\\.[0-9]+)?)</col>(?: \\(new personal best\\)|. Personal best: (?<floorpb>[0-9:]+(?:\\.[0-9]+)?))" +
"(?:<br>Overall time: <col=ff0000>(?<otime>[0-9:]+(?:\\.[0-9]+)?)</col>(?: \\(new personal best\\)|. Personal best: (?<opb>[0-9:]+(?:\\.[0-9]+)?)))?");
private static final Pattern HS_KC_FLOOR_PATTERN = Pattern.compile("You have completed Floor (\\d) of the Hallowed Sepulchre! Total completions: <col=ff0000>([0-9,]+)</col>\\.");
@@ -392,6 +390,9 @@ public class ChatCommandsPlugin extends Plugin
unsetPb(boss);
unsetKc(boss.replace(":", "."));
unsetPb(boss.replace(":", "."));
// Unset old story mode
unsetKc("Theatre of Blood Story Mode");
unsetPb("Theatre of Blood Story Mode");
}
setKc(renamedBoss, kc);
@@ -630,37 +631,47 @@ public class ChatCommandsPlugin extends Plugin
}
}
// Adventure log - Counters
if (scrollInterfaceLoaded)
{
scrollInterfaceLoaded = false;
if (client.getLocalPlayer().getName().equals(pohOwner))
{
String counterText = Text.sanitizeMultilineText(client.getWidget(WidgetInfo.GENERIC_SCROLL_TEXT).getText());
Matcher mCounterText = ADVENTURE_LOG_PB_PATTERN.matcher(counterText);
while (mCounterText.find())
Widget parent = client.getWidget(WidgetInfo.DIARY_QUEST_WIDGET_TEXT);
// Each line is a separate static child
Widget[] children = parent.getStaticChildren();
String[] text = Arrays.stream(children)
.map(Widget::getText)
.map(Text::removeTags)
.toArray(String[]::new);
for (int i = 0; i < text.length; ++i)
{
String bossName = longBossName(mCounterText.group(1));
if (bossName.equalsIgnoreCase("chambers of xeric") ||
bossName.equalsIgnoreCase("chambers of xeric challenge mode"))
String boss = longBossName(text[i]);
double pb = Double.MAX_VALUE;
for (i = i + 1; i < text.length; ++i)
{
Matcher mCoxRuns = ADVENTURE_LOG_COX_PB_PATTERN.matcher(mCounterText.group());
double bestPbTime = Double.MAX_VALUE;
while (mCoxRuns.find())
String line = text[i];
if (line.isEmpty())
{
bestPbTime = Math.min(timeStringToSeconds(mCoxRuns.group(1)), bestPbTime);
break;
}
// So we don't reset people's already saved PB's if they had one before the update
double currentPb = getPb(bossName);
if (currentPb == 0 || currentPb > bestPbTime)
// Some bosses have multiple pbs for each team size, just use the lowest
Matcher matcher = ADVENTURE_LOG_PB_PATTERN.matcher(line);
if (matcher.find())
{
setPb(bossName, bestPbTime);
double s = timeStringToSeconds(matcher.group(1));
pb = Math.min(pb, s);
}
}
else
if (pb < Double.MAX_VALUE)
{
String pbTime = mCounterText.group(2);
setPb(bossName, timeStringToSeconds(pbTime));
log.debug("Found adventure log PB for {}: {}", boss, pb);
setPb(boss, pb);
}
}
}
@@ -719,7 +730,7 @@ public class ChatCommandsPlugin extends Plugin
case KILL_LOGS_GROUP_ID:
bossLogLoaded = true;
break;
case GENERIC_SCROLL_GROUP_ID:
case DIARY_QUEST_GROUP_ID:
scrollInterfaceLoaded = true;
break;
}
@@ -1965,13 +1976,17 @@ public class ChatCommandsPlugin extends Plugin
case "raids 2":
return "Theatre of Blood";
case "Theatre of Blood: Story Mode":
case "theatre of blood: story mode":
case "tob sm":
case "tob story mode":
case "tob story":
return "Theatre of Blood Story Mode";
case "Theatre of Blood: Entry Mode":
case "tob em":
case "tob entry mode":
case "tob entry":
return "Theatre of Blood Entry Mode";
case "Theatre of Blood: Hard Mode":
case "theatre of blood: hard mode":
case "tob cm":
case "tob hm":
case "tob hard mode":

View File

@@ -479,14 +479,14 @@ public class GrandExchangePlugin extends Plugin
private WorldType getGeWorldType()
{
EnumSet<net.runelite.api.WorldType> worldTypes = client.getWorldType();
if (worldTypes.contains(net.runelite.api.WorldType.DEADMAN))
{
return WorldType.DEADMAN;
}
else if (worldTypes.contains(net.runelite.api.WorldType.DEADMAN_TOURNAMENT))
if (worldTypes.contains(net.runelite.api.WorldType.DEADMAN_TOURNAMENT))
{
return WorldType.DEADMAN_TOURNAMENT;
}
else if (worldTypes.contains(net.runelite.api.WorldType.DEADMAN))
{
return WorldType.DEADMAN;
}
else
{
return null;

View File

@@ -1,82 +0,0 @@
/*
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
* 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.implings;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.util.List;
import javax.inject.Inject;
import net.runelite.api.NPC;
import net.runelite.api.Point;
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;
public class ImplingMinimapOverlay extends Overlay
{
private final ImplingsPlugin plugin;
private final ImplingsConfig config;
@Inject
private ImplingMinimapOverlay(ImplingsPlugin plugin, ImplingsConfig config)
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_WIDGETS);
this.plugin = plugin;
this.config = config;
}
@Override
public Dimension render(Graphics2D graphics)
{
List<NPC> imps = plugin.getImplings();
if (imps.isEmpty())
{
return null;
}
for (NPC imp : imps)
{
Point impLocation = imp.getMinimapLocation();
Color color = plugin.npcToColor(imp);
if (!plugin.showNpc(imp) || impLocation == null || color == null)
{
continue;
}
OverlayUtil.renderMinimapLocation(graphics, impLocation, color);
if (config.showName())
{
Point textLocation = new Point(impLocation.getX() + 1, impLocation.getY());
OverlayUtil.renderTextLocation(graphics, textLocation, imp.getName(), color);
}
}
return null;
}
}

View File

@@ -31,13 +31,11 @@ import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.ConfigSection;
/**
*
* @author robin
*/
@ConfigGroup("implings")
@ConfigGroup(ImplingsConfig.GROUP)
public interface ImplingsConfig extends Config
{
String GROUP = "implings";
enum ImplingMode
{
NONE,

View File

@@ -28,13 +28,10 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.util.List;
import javax.inject.Inject;
import net.runelite.api.Actor;
import net.runelite.api.Client;
import net.runelite.api.NPC;
import net.runelite.api.Point;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint;
import net.runelite.client.ui.overlay.Overlay;
@@ -42,10 +39,7 @@ import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
/**
* @author robin
*/
public class ImplingsOverlay extends Overlay
class ImplingsOverlay extends Overlay
{
private final Client client;
private final ImplingsConfig config;
@@ -64,25 +58,6 @@ public class ImplingsOverlay extends Overlay
@Override
public Dimension render(Graphics2D graphics)
{
List<NPC> implings = plugin.getImplings();
if (implings.isEmpty())
{
return null;
}
for (NPC imp : implings)
{
Color color = plugin.npcToColor(imp);
if (!plugin.showNpc(imp) || color == null)
{
continue;
}
drawImp(graphics, imp, imp.getName(), color);
}
//Draw static spawns
if (config.showSpawn())
{
for (ImplingSpawn spawn : ImplingSpawn.values())
@@ -126,20 +101,4 @@ public class ImplingsOverlay extends Overlay
OverlayUtil.renderTextLocation(graphics, textPoint, text, color);
}
}
private void drawImp(Graphics2D graphics, Actor actor, String text, Color color)
{
Polygon poly = actor.getCanvasTilePoly();
if (poly != null)
{
OverlayUtil.renderPolygon(graphics, poly, color);
}
Point textLocation = actor.getCanvasTextLocation(graphics, text, actor.getLogicalHeight());
if (textLocation != null)
{
OverlayUtil.renderTextLocation(graphics, textLocation, text, color);
}
}
}

View File

@@ -26,22 +26,22 @@ package net.runelite.client.plugins.implings;
import com.google.inject.Provides;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import javax.inject.Inject;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.api.GameState;
import net.runelite.api.NPC;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.NpcChanged;
import net.runelite.api.events.NpcDespawned;
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.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,26 +49,45 @@ 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
{
@Getter(AccessLevel.PACKAGE)
private final List<NPC> implings = new ArrayList<>();
@Inject
private OverlayManager overlayManager;
@Inject
private ImplingsOverlay overlay;
@Inject
private ImplingMinimapOverlay minimapOverlay;
@Inject
private ImplingsConfig config;
@Inject
private Notifier notifier;
@Inject
private NpcIndicatorsService npcIndicatorsService;
@Inject
private ClientThread clientThread;
public final Function<NPC, HighlightedNpc> isTarget = (npc) ->
{
Impling impling = Impling.findImpling(npc.getId());
if (impling != null && showImpling(impling))
{
Color color = implingColor(impling);
return HighlightedNpc.builder()
.npc(npc)
.highlightColor(color)
.fillColor(new Color(0, 0, 0, 50))
.tile(true)
.name(true)
.nameOnMinimap(config.showName())
.build();
}
return null;
};
@Provides
ImplingsConfig getConfig(ConfigManager configManager)
{
@@ -79,15 +98,25 @@ public class ImplingsPlugin extends Plugin
protected void startUp()
{
overlayManager.add(overlay);
overlayManager.add(minimapOverlay);
npcIndicatorsService.registerHighlighter(isTarget);
}
@Override
protected void shutDown()
{
implings.clear();
npcIndicatorsService.unregisterHighlighter(isTarget);
overlayManager.remove(overlay);
overlayManager.remove(minimapOverlay);
}
@Subscribe
private void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals(ImplingsConfig.GROUP))
{
return;
}
clientThread.invoke(npcIndicatorsService::rebuild);
}
@Subscribe
@@ -102,8 +131,6 @@ public class ImplingsPlugin extends Plugin
{
notifier.notify(impling.getImplingType().getName() + " impling is in the area");
}
implings.add(npc);
}
}
@@ -119,43 +146,11 @@ public class ImplingsPlugin extends Plugin
{
notifier.notify(impling.getImplingType().getName() + " impling is in the area");
}
if (!implings.contains(npc))
{
implings.add(npc);
}
}
}
@Subscribe
public void onGameStateChanged(GameStateChanged event)
private boolean showImpling(Impling impling)
{
if (event.getGameState() == GameState.LOGIN_SCREEN || event.getGameState() == GameState.HOPPING)
{
implings.clear();
}
}
@Subscribe
public void onNpcDespawned(NpcDespawned npcDespawned)
{
if (implings.isEmpty())
{
return;
}
NPC npc = npcDespawned.getNpc();
implings.remove(npc);
}
boolean showNpc(NPC npc)
{
Impling impling = Impling.findImpling(npc.getId());
if (impling == null)
{
return false;
}
ImplingsConfig.ImplingMode impMode = showImplingType(impling.getImplingType());
return impMode == ImplingsConfig.ImplingMode.HIGHLIGHT || impMode == ImplingsConfig.ImplingMode.NOTIFY;
}
@@ -193,17 +188,10 @@ public class ImplingsPlugin extends Plugin
}
}
Color npcToColor(NPC npc)
private Color implingColor(Impling impling)
{
Impling impling = Impling.findImpling(npc.getId());
if (impling == null)
{
return null;
}
switch (impling.getImplingType())
{
case BABY:
return config.getBabyColor();
case YOUNG:
@@ -229,7 +217,7 @@ public class ImplingsPlugin extends Plugin
case LUCKY:
return config.getLuckyColor();
default:
return null;
throw new IllegalArgumentException();
}
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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.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;
}

View File

@@ -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<NPC> highlightedNpcs = new HashSet<>();
private final Map<NPC, HighlightedNpc> 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<Predicate<NPC>> higlightPredicates = new ArrayList<>();
private final List<Function<NPC, HighlightedNpc>> 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<NPC> predicate : higlightPredicates)
for (Function<NPC, HighlightedNpc> 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<NPC, HighlightedNpc> 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<NPC> predicate : higlightPredicates)
for (Function<NPC, HighlightedNpc> 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<NPC> p)
public void registerHighlighter(Function<NPC, HighlightedNpc> p)
{
higlightPredicates.add(p);
}
@Override
public void unregisterHighlighter(Predicate<NPC> p)
public void unregisterHighlighter(Function<NPC, HighlightedNpc> p)
{
higlightPredicates.remove(p);
}

View File

@@ -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<NPC> p);
void unregisterHighlighter(Predicate<NPC> p);
void registerHighlighter(Function<NPC, HighlightedNpc> p);
void unregisterHighlighter(Function<NPC, HighlightedNpc> p);
void rebuild();
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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<br> !task"

View File

@@ -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<String> targetNames = new ArrayList<>();
public final Predicate<NPC> isTarget = (n) -> config.highlightTargets() && targets.contains(n);
public final Function<NPC, HighlightedNpc> 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);
}
}

View File

@@ -155,12 +155,12 @@ public class NpcIndicatorsPluginTest
when(npc.getName()).thenReturn("Joseph");
npcIndicatorsPlugin.onNpcSpawned(new NpcSpawned(npc));
assertTrue(npcIndicatorsPlugin.getHighlightedNpcs().contains(npc));
assertTrue(npcIndicatorsPlugin.getHighlightedNpcs().containsKey(npc));
when(npc.getName()).thenReturn("Werewolf");
npcIndicatorsPlugin.onNpcChanged(new NpcChanged(npc, null));
assertFalse(npcIndicatorsPlugin.getHighlightedNpcs().contains(npc));
assertFalse(npcIndicatorsPlugin.getHighlightedNpcs().containsKey(npc));
}
@Test
@@ -174,11 +174,11 @@ public class NpcIndicatorsPluginTest
when(npc.getName()).thenReturn("Joseph");
npcIndicatorsPlugin.onNpcSpawned(new NpcSpawned(npc));
assertFalse(npcIndicatorsPlugin.getHighlightedNpcs().contains(npc));
assertFalse(npcIndicatorsPlugin.getHighlightedNpcs().containsKey(npc));
when(npc.getName()).thenReturn("Werewolf");
npcIndicatorsPlugin.onNpcChanged(new NpcChanged(npc, null));
assertTrue(npcIndicatorsPlugin.getHighlightedNpcs().contains(npc));
assertTrue(npcIndicatorsPlugin.getHighlightedNpcs().containsKey(npc));
}
}