diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java index 246f848f5c..619bddfe9c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java @@ -54,6 +54,7 @@ public class PlayerIndicatorsOverlay extends Overlay { private static final int ACTOR_OVERHEAD_TEXT_MARGIN = 40; private static final int ACTOR_HORIZONTAL_TEXT_MARGIN = 10; + private static final Object[] NULL_OBJ = new Object[]{null}; private final BufferedImage agilityIcon = ImageUtil.getResourceStreamFromClass(PlayerIndicatorsPlugin.class, "agility.png"); private final BufferedImage noAgilityIcon = ImageUtil.getResourceStreamFromClass(PlayerIndicatorsPlugin.class, @@ -83,47 +84,52 @@ public class PlayerIndicatorsOverlay extends Overlay private void drawSceneOverlays(Graphics2D graphics, Player actor, PlayerRelation relation) { - if (!plugin.getLocationHashMap().containsKey(relation)) + if (actor.getName() == null || !plugin.getLocationHashMap().containsKey(relation)) { return; } + final List indicationLocations = Arrays.asList(plugin.getLocationHashMap().get(relation)); final Color color = plugin.getRelationColorHashMap().get(relation); + final boolean skulls = plugin.isPlayerSkull(); + final String name = actor.getName(); + final int zOffset = actor.getLogicalHeight() + ACTOR_OVERHEAD_TEXT_MARGIN; + final Point textLocation = actor.getCanvasTextLocation(graphics, name, zOffset); if (indicationLocations.contains(PlayerIndicationLocation.ABOVE_HEAD)) { - String name = actor.getName(); - final boolean skulls = plugin.isPlayerSkull(); - final int zOffset = actor.getLogicalHeight() + ACTOR_OVERHEAD_TEXT_MARGIN; - final Point textLocation = actor.getCanvasTextLocation(graphics, name, zOffset); + final StringBuilder nameSb = new StringBuilder(name); if (plugin.isShowCombatLevel()) { - name = name + " (" + actor.getCombatLevel() + ")"; + nameSb.append(" ("); + nameSb.append(actor.getCombatLevel()); + nameSb.append(")"); } - if (plugin.isUnchargedGlory()) + if (plugin.isUnchargedGlory() && + actor.getPlayerAppearance().getEquipmentId(KitType.AMULET) == ItemID.AMULET_OF_GLORY) { - if (actor.getPlayerAppearance().getEquipmentId(KitType.AMULET) == ItemID.AMULET_OF_GLORY) - { - name += " (glory)"; - } + nameSb.append(" (glory)"); } - if (plugin.isPlayerSkull() && actor.getSkullIcon() != null) + final String builtString = nameSb.toString(); + + if (skulls && actor.getSkullIcon() != null) { - int x = graphics.getFontMetrics().stringWidth(name); - int y = graphics.getFontMetrics().getHeight(); - OverlayUtil.renderActorTextAndImage(graphics, actor, name, color, + final int x = graphics.getFontMetrics().stringWidth(builtString); + final int y = graphics.getFontMetrics().getHeight(); + OverlayUtil.renderActorTextAndImage(graphics, actor, builtString, color, ImageUtil.resizeImage(skullIcon, y, y), 0, x); } - else { - OverlayUtil.renderActorTextOverlay(graphics, actor, name, color); + OverlayUtil.renderActorTextOverlay(graphics, actor, builtString, color); } } - if (Arrays.asList(plugin.getLocationHashMap().get(relation)).contains(PlayerIndicationLocation.HULL)) + if (Arrays.asList(plugin.getLocationHashMap() + .getOrDefault(relation, NULL_OBJ)) + .contains(PlayerIndicationLocation.HULL)) { if (actor.getConvexHull() == null) { @@ -132,7 +138,9 @@ public class PlayerIndicatorsOverlay extends Overlay OverlayUtil.renderPolygon(graphics, actor.getConvexHull(), color); } - if (Arrays.asList(plugin.getLocationHashMap().get(relation)).contains(PlayerIndicationLocation.TILE)) + if (Arrays.asList(plugin.getLocationHashMap() + .getOrDefault(relation, NULL_OBJ)) + .contains(PlayerIndicationLocation.TILE)) { final Polygon poly = actor.getCanvasTilePoly(); if (poly != null) @@ -140,6 +148,63 @@ public class PlayerIndicatorsOverlay extends Overlay OverlayUtil.renderPolygon(graphics, poly, color); } } + + if (plugin.isShowAgilityLevel() && checkWildy() && plugin.getResultCache().containsKey(actor.getName())) + { + if (textLocation == null) + { + return; + } + + final int level = plugin.getResultCache().get(actor.getName()).getAgility().getLevel(); + + if (plugin.getAgilityFormat() == PlayerIndicatorsPlugin.AgilityFormats.ICONS) + { + final int width = graphics.getFontMetrics().stringWidth(name); + final int height = graphics.getFontMetrics().getHeight(); + if (level >= plugin.getAgilityFirstThreshold()) + { + OverlayUtil.renderImageLocation(graphics, + new Point(textLocation.getX() + 5 + width, + textLocation.getY() - height), + ImageUtil.resizeImage(agilityIcon, height, height)); + } + if (level >= plugin.getAgilitySecondThreshold()) + { + OverlayUtil.renderImageLocation(graphics, + new Point(textLocation.getX() + agilityIcon.getWidth() + width, + textLocation.getY() - height), + ImageUtil.resizeImage(agilityIcon, height, height)); + } + if (level < plugin.getAgilityFirstThreshold()) + { + OverlayUtil.renderImageLocation(graphics, + new Point(textLocation.getX() + 5 + width, + textLocation.getY() - height), + ImageUtil.resizeImage(noAgilityIcon, height, height)); + } + } + else + { + Color agiColor = Color.WHITE; + + if (level >= plugin.getAgilityFirstThreshold()) + { + agiColor = Color.CYAN; + } + else if (level >= plugin.getAgilitySecondThreshold()) + { + agiColor = Color.GREEN; + } + else if (level < plugin.getAgilityFirstThreshold()) + { + agiColor = Color.RED; + } + + final String n = level + " " + "Agility"; + OverlayUtil.renderActorTextOverlay(graphics, actor, n, agiColor, 60); + } + } } private boolean checkWildy() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java index 66116d8549..c2e38c082b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java @@ -26,12 +26,16 @@ package net.runelite.client.plugins.playerindicators; import com.google.inject.Provides; import java.awt.Color; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; @@ -49,6 +53,7 @@ import net.runelite.api.events.ClanMemberLeft; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.InteractingChanged; import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.PlayerSpawned; import net.runelite.api.util.Text; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; @@ -59,6 +64,8 @@ import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ColorUtil; import net.runelite.client.util.PvPUtil; +import net.runelite.http.api.hiscore.HiscoreClient; +import net.runelite.http.api.hiscore.HiscoreResult; @PluginDescriptor( name = "Player Indicators", @@ -70,6 +77,8 @@ import net.runelite.client.util.PvPUtil; @Getter(AccessLevel.PACKAGE) public class PlayerIndicatorsPlugin extends Plugin { + private static final HiscoreClient HISCORE_CLIENT = new HiscoreClient(); + @Inject @Getter(AccessLevel.NONE) private OverlayManager overlayManager; @@ -98,6 +107,9 @@ public class PlayerIndicatorsPlugin extends Plugin private final Map relationColorHashMap = new ConcurrentHashMap<>(); private final Map locationHashMap = new ConcurrentHashMap<>(); private final Map callerPiles = new ConcurrentHashMap<>(); + @Getter(AccessLevel.PACKAGE) + private final Map resultCache = new HashMap<>(); + private final ExecutorService executorService = Executors.newFixedThreadPool(100); private PlayerIndicatorsPlugin.AgilityFormats agilityFormat; private PlayerIndicatorsPlugin.MinimapSkullLocations skullLocation; private String configCallers; @@ -130,10 +142,9 @@ public class PlayerIndicatorsPlugin extends Plugin { updateConfig(); addSubscriptions(); - + resultCache.clear(); overlayManager.add(playerIndicatorsOverlay); overlayManager.add(playerIndicatorsMinimapOverlay); - getCallerList(); } @@ -141,9 +152,9 @@ public class PlayerIndicatorsPlugin extends Plugin protected void shutDown() throws Exception { eventBus.unregister(this); - overlayManager.remove(playerIndicatorsOverlay); overlayManager.remove(playerIndicatorsMinimapOverlay); + resultCache.clear(); } private void addSubscriptions() @@ -153,6 +164,7 @@ public class PlayerIndicatorsPlugin extends Plugin eventBus.subscribe(ClanMemberLeft.class, this, this::onClanMemberLeft); eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); + eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); } private void onInteractingChanged(InteractingChanged event) @@ -199,6 +211,43 @@ public class PlayerIndicatorsPlugin extends Plugin getCallerList(); } + private void onPlayerSpawned(PlayerSpawned event) + { + final Player player = event.getPlayer(); + + if (!this.showAgilityLevel || resultCache.containsKey(player.getName())) + { + return; + } + + executorService.submit(() -> + { + HiscoreResult result; + do + { + try + { + result = HISCORE_CLIENT.lookup(player.getName()); + } + catch (IOException ex) + { + try + { + Thread.sleep(250); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + return; + } + } + while (result == null); + + resultCache.put(player.getName(), result); + }); + } + private void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) { int type = menuEntryAdded.getType(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsService.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsService.java index aef3fad5fb..6e03514bec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsService.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsService.java @@ -52,7 +52,6 @@ public class PlayerIndicatorsService private final Predicate callerTarget; private final List piles = new ArrayList<>(); - @Inject private PlayerIndicatorsService(final Client client, final PlayerIndicatorsPlugin plugin) { @@ -73,6 +72,7 @@ public class PlayerIndicatorsService || (plugin.isHighlightClan() && player.isClanMember()) || (plugin.isHighlightFriends() && client.isFriended(player.getName(), false)) || (plugin.isHighlightCallers() && plugin.isCaller(player)) + || (plugin.isHighlightCallerTargets() && piles.contains(player)) || (plugin.isHighlightTeam() && Objects.requireNonNull(client.getLocalPlayer()).getTeam() != 0 && client.getLocalPlayer().getTeam() == player.getTeam())) { @@ -82,7 +82,6 @@ public class PlayerIndicatorsService }); } - public void forEachPlayer(final BiConsumer consumer) { if (!highlight()) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java index df910aebcb..e95f9bc45f 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java @@ -141,7 +141,12 @@ public class OverlayUtil public static void renderActorTextOverlay(Graphics2D graphics, Actor actor, String text, Color color) { - Point textLocation = actor.getCanvasTextLocation(graphics, text, actor.getLogicalHeight() + 40); + renderActorTextOverlay(graphics, actor, text, color, 40); + } + + public static void renderActorTextOverlay(Graphics2D graphics, Actor actor, String text, Color color, int offset) + { + Point textLocation = actor.getCanvasTextLocation(graphics, text, actor.getLogicalHeight() + offset); if (textLocation != null) { renderTextLocation(graphics, textLocation, text, color);