diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java new file mode 100644 index 0000000000..1352b351bb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + +package net.runelite.client.plugins.friendtagging; + +import com.google.common.base.Strings; +import com.google.common.collect.ObjectArrays; + +import java.awt.*; +import java.awt.datatransfer.StringSelection; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import javax.inject.Inject; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; +import net.runelite.api.events.*; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.chatbox.ChatboxPanelManager; +import net.runelite.client.game.chatbox.ChatboxTextInput; +import net.runelite.client.menus.MenuManager; +import net.runelite.client.menus.WidgetMenuOption; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.util.Text; +import org.apache.commons.lang3.ArrayUtils; + +@Slf4j +@PluginDescriptor( + name = "Friend Tagging", + description = "Tag people on your friends list.", + tags = {"PVP", "friend", "finder", "pk", "pklite"}, + type = PluginType.UTILITY +) +public class FriendTaggingPlugin extends Plugin +{ + public static ConcurrentHashMap taggedFriends = new ConcurrentHashMap<>(); + + private static final String CONFIG_GROUP = "friendtagging"; + private static final int CHARACTER_LIMIT = 30; + private static final String KEY_PREFIX = "tag_"; + private static final String ADD_TAG = "Add Tag"; + private static final String DELETE_TAG = "Delete Tag"; + private WidgetMenuOption friendsTabMenuOption = new WidgetMenuOption("Copy to", "clipboard", + WidgetInfo.FIXED_VIEWPORT_FRIENDS_TAB); + private WidgetMenuOption ignoreTabMenuOption = new WidgetMenuOption("Copy to", "clipboard", + WidgetInfo.FIXED_VIEWPORT_IGNORES_TAB); + private WidgetMenuOption friendTabResizableOption = new WidgetMenuOption("Copy to", "clipboard", + WidgetInfo.FIXED_VIEWPORT_FRIENDS_TAB); + private WidgetMenuOption ignoreTabResizableOption = new WidgetMenuOption("Copy to", "clipboard", + WidgetInfo.FIXED_VIEWPORT_IGNORES_TAB); + + @Inject + private Client client; + + @Inject + private ConfigManager configManager; + + @Inject + private MenuManager menuManager; + + @Inject + private ChatboxPanelManager chatboxPanelManager; + + @Override + protected void startUp() throws Exception + { + menuManager.addManagedCustomMenu(friendsTabMenuOption); + menuManager.addManagedCustomMenu(ignoreTabMenuOption); + menuManager.addManagedCustomMenu(friendTabResizableOption); + menuManager.addManagedCustomMenu(ignoreTabResizableOption); + loadFriendTags(); + } + + @Override + protected void shutDown() throws Exception + { + menuManager.removeManagedCustomMenu(friendsTabMenuOption); + menuManager.removeManagedCustomMenu(ignoreTabMenuOption); + menuManager.removeManagedCustomMenu(friendTabResizableOption); + menuManager.removeManagedCustomMenu(ignoreTabResizableOption); + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); + + if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) + { + // Friends have color tags + String friendName = Text.removeTags(event.getTarget()); + + // Build "Add Note" or "Edit Note" menu entry + final MenuEntry entry = new MenuEntry(); + entry.setOption(friendName == null || getTag(friendName) == null ? ADD_TAG : DELETE_TAG); + entry.setType(MenuAction.RUNELITE.getId()); + entry.setTarget(event.getTarget()); //Preserve color codes here + entry.setParam0(event.getActionParam0()); + entry.setParam1(event.getActionParam1()); + + // Add menu entry + final MenuEntry[] menuEntries = ObjectArrays.concat(client.getMenuEntries(), entry); + client.setMenuEntries(menuEntries); + } + } + + @Subscribe + public void onRemovedFriend(RemovedFriend event) + { + final String displayName = event.getName().trim().toLowerCase(); + deleteTag(displayName); + } + + @Subscribe + public void onNameableNameChanged(NameableNameChanged event) + { + final Nameable nameable = event.getNameable(); + + if (nameable instanceof Friend) + { + // Migrate a friend's note to their new display name + final Friend friend = (Friend) nameable; + if (friend.getName() != null && friend.getPrevName() != null) + { + migrateFriendTag(friend.getName(), friend.getPrevName()); + } + } + } + + @Subscribe + public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + { + if (event.getWidget().getId() == WidgetInfo.FIXED_VIEWPORT_FRIENDS_TAB.getId() && + Text.standardize(event.getMenuTarget()).equals(Text.standardize("clipboard"))) + { + friendIgnoreToClipboard(); + } + } + + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked event) + { + if (WidgetInfo.TO_GROUP(event.getWidgetId()) == WidgetInfo.FRIENDS_LIST.getGroupId()) + { + if (Strings.isNullOrEmpty(event.getMenuTarget())) + { + return; + } + + final String sanitizedTarget = Text.removeTags(event.getMenuTarget()); + + if (event.getMenuOption().equals(ADD_TAG)) + { + event.consume(); + final ChatboxTextInput build = chatboxPanelManager.openTextInput("Enter the tag").value("") + .onDone((content) -> + { + if (content == null) + { + return; + } + content = Text.removeTags(content).trim(); + setTag(sanitizedTarget, content); + }).build(); + } + if (event.getMenuOption().equals(DELETE_TAG)) + { + event.consume(); + client.getLogger().info(sanitizedTarget); + taggedFriends.forEach((k, v) -> client.getLogger().info(k + ": ", v)); + deleteTag(sanitizedTarget); + } + } + + } + + /** + * Gets a tag from the currently loaded tags + * + * @param name the username of the player + * @return the text of the tag + */ + @NonNull + private String getTag(String name) + { + name = name.trim().toLowerCase(); + String keyName = KEY_PREFIX + name; + return taggedFriends.get(keyName); + } + + /** + * Sets a tag for a friend + * + * @param name the username of the player to tag + * @param tag the text of the tag + */ + private void setTag(String name, String tag) + { + client.getLogger().info("SETTING " + name + ": " + tag); + name = name.trim().toLowerCase(); + String keyName = KEY_PREFIX + name; + if (tag.length() <= CHARACTER_LIMIT) + { + taggedFriends.put(keyName, tag); + configManager.setConfiguration(CONFIG_GROUP, keyName, tag); + } + } + + /** + * Deletes a friends tag + * + * @param name the username of the friend to delete the tag for + */ + private void deleteTag(String name) + { + name = name.trim().toLowerCase(); + String keyName = KEY_PREFIX + name; + configManager.unsetConfiguration(CONFIG_GROUP, keyName); + taggedFriends.remove(keyName); + } + + /** + * Loads all of the friend tags for use with player indicators + */ + private void loadFriendTags() + { + String prefix = CONFIG_GROUP + "." + KEY_PREFIX; + for (String key : configManager.getConfigurationKeys(prefix)) + { + key = key.replace(CONFIG_GROUP + ".", ""); + String result = configManager.getConfiguration(CONFIG_GROUP, key); + if (Objects.nonNull(result) && !result.equals("")) + { + taggedFriends.put(key, configManager.getConfiguration(CONFIG_GROUP, key)); + } + } + } + + /** + * Migrate a friend note to a new display name, and remove the previous one. + * If current name already has a note, or previous name had none, do nothing. + */ + private void migrateFriendTag(String currentDisplayName, String prevDisplayName) + { + final String currentTag = getTag(currentDisplayName); + if (currentTag == null) + { + final String prevTag = getTag(prevDisplayName); + if (prevTag != null) + { + setTag(prevDisplayName, ""); + setTag(currentDisplayName, prevTag); + } + } + } + + /** + * This method combines the list of usernames on local players friend/ignore list into a comma delimited string + * and then copies it to the clipboard. + */ + private void friendIgnoreToClipboard() + { + StringBuilder friendsList = new StringBuilder(); + Friend[] friends = client.getFriends(); + Ignore[] ignores = client.getIgnores(); + String[] friendsIgnores = ArrayUtils.addAll(Arrays.stream(friends).map(Friend::getName).toArray(String[]::new), + Arrays.stream(ignores).map(Ignore::getName).toArray(String[]::new)); + HashSet names = new HashSet<>(Arrays.asList(friendsIgnores)); + names.forEach(n -> friendsList.append(n.toLowerCase()).append(",")); + StringSelection namesSelection = new StringSelection(friendsList.toString()); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(namesSelection, namesSelection); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/locationchatter/LocationChatterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/locationchatter/LocationChatterConfig.java deleted file mode 100644 index 33bbf214ff..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/locationchatter/LocationChatterConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2018, https://runelitepl.us - * 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.locationchatter; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; -import net.runelite.client.config.Keybind; - -@ConfigGroup("locationchatter") -public interface LocationChatterConfig extends Config -{ - @ConfigItem(keyName = "keybind", name = "Send to CC", description = "Configure button to send current location to CC") - default Keybind keybind() - { - return Keybind.NOT_SET; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/locationchatter/LocationChatterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/locationchatter/LocationChatterPlugin.java deleted file mode 100644 index b15bc20df1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/locationchatter/LocationChatterPlugin.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2018, https://runelitepl.us - * 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.locationchatter; - -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.ScriptID; -import net.runelite.api.VarClientStr; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.VarClientStrChanged; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.callback.ClientThread; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.input.KeyManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.PluginManager; -import net.runelite.client.plugins.PluginType; -import net.runelite.client.plugins.wildernesslocations.WildernessLocationsPlugin; -import net.runelite.client.util.HotkeyListener; - -import javax.inject.Inject; - -@Slf4j -@PluginDescriptor( - name = "Location Chatter", - tags = {"location", "exilent", "pklite", "spammer"}, - type = PluginType.PVP - ) -public class LocationChatterPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private ClientThread clientThread; - - @Inject - LocationChatterConfig config; - - @Inject - private KeyManager keyManager; - - @Inject - private PluginManager pluginManager; - - private WildernessLocationsPlugin wildyLocsPlugin; - - private String oldChat = ""; - private int currentCooldown = 0; - private final int COOLDOWN_TICKS = 30; - - private final HotkeyListener hotkeyListener = new HotkeyListener(() -> config.keybind()) - { - @Override - public void hotkeyPressed() - { - sendLocToCC(); - } - }; - - @Override - public void startUp() - { - for (Plugin pl : pluginManager.getPlugins()) - { - if (pl instanceof WildernessLocationsPlugin) - { - wildyLocsPlugin = (WildernessLocationsPlugin) pl; - } - } - keyManager.registerKeyListener(hotkeyListener); - } - - @Override - public void shutDown() - { - keyManager.unregisterKeyListener(hotkeyListener); - } - - @Provides - LocationChatterConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(LocationChatterConfig.class); - } - - @Subscribe - public void onGameTick(GameTick tickEvent) - { - if (currentCooldown != 0) - { - currentCooldown--; - } - } - - @Subscribe - public void onVarClientStrChanged(VarClientStrChanged varClient) - { - String newChat = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); - if (varClient.getIndex() == VarClientStr.CHATBOX_TYPED_TEXT.getIndex() && !newChat.equals(oldChat)) - { - oldChat = newChat; - } - } - - private boolean inClanChat() - { - return client.getWidget(WidgetInfo.CLAN_CHAT_TITLE) != null; - } - - private void sendMessage(String text) - { - int mode = 0; - if (inClanChat() && text.startsWith("/")) - { - mode = 2; - } - int finalMode = mode; - Runnable r = () -> - { - String cached = oldChat; - client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, text); - client.runScript(ScriptID.CHATBOX_INPUT, finalMode, text); - oldChat = cached; - client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, oldChat); - }; - clientThread.invoke(r); - } - - private void sendLocToCC() - { - if (currentCooldown != 0) - { - return; - } - - String location = wildyLocsPlugin.getLocationString(); - if (location.equals("")) - { - return; - } - sendMessage("/World: " + client.getWorld() + " Location: " + location); - currentCooldown = COOLDOWN_TICKS; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/FriendMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/FriendMinimapOverlay.java deleted file mode 100644 index 6786d24ba6..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/FriendMinimapOverlay.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2018, Seth - * 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.playerindicators; - -import net.runelite.api.Player; -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; - -import javax.inject.Inject; -import java.awt.*; - -public class FriendMinimapOverlay extends Overlay -{ - private final PlayerIndicatorsConfig config; - private final PlayerIndicatorsService playerIndicatorsService; - - @Inject - private FriendMinimapOverlay(PlayerIndicatorsConfig config, PlayerIndicatorsService playerIndicatorsService) - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_WIDGETS); - this.config = config; - this.playerIndicatorsService = playerIndicatorsService; - } - - @Override - public Dimension render(Graphics2D graphics) - { - playerIndicatorsService.forEachPlayer((player, color) -> renderPlayerMinimapOverlay(graphics, player, color)); - return null; - } - - private void renderPlayerMinimapOverlay(Graphics2D graphics, Player actor, Color color) { - Point minimapLocation = actor.getMinimapLocation(); - if (!config.highlightFriends() || minimapLocation == null || color == null || actor.isClanMember()) - return; - OverlayUtil.renderMinimapLocation(graphics, minimapLocation, color); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsConfig.java index 7d7245222e..969103036b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsConfig.java @@ -25,9 +25,12 @@ package net.runelite.client.plugins.playerindicators; import java.awt.Color; + +import net.runelite.api.ClanMemberRank; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.Range; @ConfigGroup("playerindicators") public interface PlayerIndicatorsConfig extends Config @@ -137,48 +140,13 @@ public interface PlayerIndicatorsConfig extends Config name = "Non-clan member color", description = "Color of non-clan member names" ) - default Color getNonClanMemberColor() { return Color.RED; } - - @ConfigItem( - position = 10, - keyName = "drawAttackerNames", - name = "Highlight attacker players", - description = "Configures whether or not attacker players should be highlighted" - ) - default boolean highlightAttackerPlayers() + default Color getNonClanMemberColor() { - return false; + return Color.RED; } @ConfigItem( - position = 11, - keyName = "attackerColor", - name = "Attacker player color", - description = "Color of attacking player names" - ) - default Color getAttackerPlayerColor() { return new Color(241, 0, 108); } - - @ConfigItem( - position = 12, - keyName = "drawAttackableNames", - name = "Highlight attackable players", - description = "Configures whether or not attackable players should be highlighted" - ) - default boolean highlightAttackablePlayers() - { - return false; - } - - @ConfigItem( - position = 13, - keyName = "attackableColor", - name = "Attackable player color", - description = "Color of attackable player names" - ) - default Color getAttackablePlayerColor() { return new Color(231, 122,- 0); } - - @ConfigItem( - position = 14, + position = 10, keyName = "drawPlayerTiles", name = "Draw tiles under players", description = "Configures whether or not tiles under highlighted players should be drawn" @@ -189,29 +157,18 @@ public interface PlayerIndicatorsConfig extends Config } @ConfigItem( - position = 15, - keyName = "drawOverheadPlayerNames", - name = "Draw names above players", - description = "Configures whether or not player names should be drawn above players" + position = 11, + keyName = "playerNamePosition", + name = "Name position", + description = "Configures the position of drawn player names, or if they should be disabled" ) - default boolean drawOverheadPlayerNames() + default PlayerNameLocation playerNamePosition() { - return true; + return PlayerNameLocation.ABOVE_HEAD; } @ConfigItem( - position = 16, - keyName = "drawOverheadLevels", - name = "Draw combat levels above players", - description = "Configures whether or not combat levels should be drawn above players" - ) - default boolean drawOverheadLevels() - { - return false; - } - - @ConfigItem( - position = 17, + position = 12, keyName = "drawMinimapNames", name = "Draw names on minimap", description = "Configures whether or not minimap names for players with rendered names should be drawn" @@ -222,7 +179,7 @@ public interface PlayerIndicatorsConfig extends Config } @ConfigItem( - position = 18, + position = 13, keyName = "colorPlayerMenu", name = "Colorize player menu", description = "Color right click menu for players" @@ -233,7 +190,7 @@ public interface PlayerIndicatorsConfig extends Config } @ConfigItem( - position = 19, + position = 14, keyName = "clanMenuIcons", name = "Show clan ranks", description = "Add clan rank to right click menu and next to player names" @@ -243,108 +200,216 @@ public interface PlayerIndicatorsConfig extends Config return true; } - @ConfigItem( - position = 20, - keyName = "showOfflineFriends", - name = "Show offline friends", - description = "Draw friends names even if they're offline" - ) - default boolean showOfflineFriends() - { - return true; - } - @ConfigItem( - position = 21, - keyName = "drawHighlightedNames", - name = "Draw highlighted player names", - description = "Configures whether or not highlighted player names should be drawn" + position = 15, + keyName = "highlightTargets", + name = "Highlight attackable players in wilderness on the minimap", + description = "Highlights players on the minimap that the current player can attack based on combat/wilderness levels", + group = "Target Indicator" ) - default boolean drawHighlightedNames() + default boolean highlightTargets() { return false; } @ConfigItem( - keyName = "highlightedNames", - name = "Highlighted names", - description = "Clan caller names separated by a comma" + position = 16, + keyName = "highlightOverheadTargets", + name = "Highlights attackable players over their head", + description = "Highlights players over their head that the current player can attack based on combat/wilderness levels", + group = "Target Indicator" ) - default String getHighlightedNames() - { - return ""; - } - - @ConfigItem( - keyName = "highlightedNamesColor", - name = "Highlighted names color", - description = "Color of highlighted names" - ) - default Color getHighlightedNamesColor() - { - return Color.ORANGE; - } - - @ConfigItem( - position = 22, - keyName = "drawHighlightedTargetNames", - name = "Draw highlighted target names", - description = "Configures whether or not highlighted target names should be drawn" - ) - default boolean drawHighlightedTargetNames() + default boolean highlightOverheadTargets() { return false; } + @ConfigItem( + position = 17, + keyName = "targetColor", + name = "Target color", + description = "Color of attackable targets", + group = "Target Indicator" + ) + default Color getTargetColor() + { + return Color.RED; + } + + @ConfigItem( + position = 18, + keyName = "showCombat", + name = "Show Combat Levels", + description = "Show the combat level of attackable players next to their name.", + group = "Target Indicator" + ) + default boolean showCombatLevel() + { + return false; + } + + @ConfigItem( + position = 19, + keyName = "playerSkull", + name = "Show Skull Information", + description = "Indicate of the player is skulled.", + group = "Target Indicator" + ) + default boolean playerSkull() + { + return false; + } + + @ConfigItem( + position = 19, + keyName = "minimapSkullLocation", + name = "Skull Icon Location", + description = "The location of the skull icon for skulled players", + group = "Target Indicator" + ) + default PlayerIndicatorsPlugin.minimapSkullLocations skullLocation() + { + return PlayerIndicatorsPlugin.minimapSkullLocations.AFTER_NAME; + } + + @ConfigItem( + position = 19, + keyName = "skulledTargetsOnly", + name = "Tag Skulls Only", + description = "Only indicate skulled targets (which are also attackable)", + group = "Target Indicator" + ) + default boolean skulledTargetsOnly() + { + return false; + } + + @ConfigItem( + position = 19, + keyName = "targetRisk", + name = "Indicate Target Risk", + description = "Indicates the risk (in K GP) of the target", + group = "Target Indicator" + ) + default boolean targetRisk() + { + return false; + } + @ConfigItem( position = 23, - keyName = "highlightedTargetColor", - name = "Highlighted target color", - description = "Color of highlighted target names" + keyName = "rightClickOverhead", + name = "Add Overheads to Right Click Menu", + description = "Feature shows a player's overhead prayer in the right click menu. Useful for DDs, or extremely crowded areas." ) - default Color getHighlightedTargetColor() - { - return new Color(255, 100, 183); - } - - @ConfigItem( - position = 24, - keyName = "limitLevel", - name = "Limit Level", - description = "Limit the players to show +-x your level. Useful for BH" - ) - default boolean limitLevel() + default boolean rightClickOverhead() { return false; } @ConfigItem( - position = 25, - keyName = "level", - name = "Level", - description = "The level to limit players shown +-x" + keyName = "useClanchatRanks", + name = "Use Ranks as Callers", + description = "Uses clanchat ranks as the list of callers", + group = "Callers", + position = 24 ) - default int intLevel() + default boolean useClanchatRanks() { - return 5; + return false; } - @ConfigItem( - position = 26, - keyName = "wildernessOnly", - name = "Show only in wilderness", - description = "Toggle whether or not to only show player indicators in the wilderness" - ) - default boolean showInWildernessOnly() - { - return false; - } + @ConfigItem( + keyName = "callerRank", + name = "Minimum rank for Clan Caller", + description = "Chooses the minimum rank to use as clanchat callers.", + group = "Callers", + position = 25 + ) + default ClanMemberRank callerRank() + { + return ClanMemberRank.CAPTAIN; + } -/* @ConfigItem( + @ConfigItem( + keyName = "callers", + name = "List of callers to highlight", + description = "Highlights callers, only highlights one at a time. Separate each entry with a comma and enter" + + " in the order you want them highlighted.", + group = "Callers" + ) + default String callers() + { + return " "; + } + @ConfigItem( + keyName = "highlightCallers", + name = "Highlight Callers", + description = "Highlights Callers Onscreen", + group = "Callers" + ) + default boolean highlightCallers() + { + return true; + } + @ConfigItem( + position = 26, + keyName = "callerColor", + name = "Caller Color", + description = "Color of Indicated Callers", + group = "Callers" + ) + default Color callerColor() + { + return Color.WHITE; + } + @ConfigItem( position = 27, - keyName="rightClickOverhead", - name="Add Overheads to Right Click Menu", - description="Feature shows a player's overhead prayer in the right click menu. Useful for DDs, or extremely crowded areas.") + keyName = "highlightPile", + name = "Highlight Pile", + description = "Highlights Pile Onscreen", + group = "Callers" + ) + default boolean highlightPile() + { + return false; + } + @ConfigItem( + position = 29, + keyName = "drawPileHull", + name = "Draws the hull of the pile.", + description = "Draws the hull of the pile for best visibility.", + group = "Callers" + ) + default boolean drawPileHull() + { + return false; + } - default boolean rightClickOverhead() { return false; }*/ + @Range( + min = 1, + max = 10 + ) + @ConfigItem( + position = 30, + keyName = "pileColor", + name = "Pile Color", + description = "Color of Indicated Pile", + group = "Callers" + ) + default Color pileColor() + { + return Color.WHITE; + } + @ConfigItem( + position = 27, + keyName = "unchargedGlory", + name = "Uncharged Glory Indication", + description = "Indicates if players have an uncharged glory" + ) + default boolean unchargedGlory() + { + return false; + } + } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsMinimapOverlay.java index 266def094c..10e722ea01 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsMinimapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsMinimapOverlay.java @@ -27,20 +27,32 @@ package net.runelite.client.plugins.playerindicators; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; +import java.awt.image.BufferedImage; import javax.inject.Inject; import javax.inject.Singleton; +import net.runelite.api.Client; import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.friendtagging.FriendTaggingPlugin; 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.OverlayPriority; import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.util.ImageUtil; @Singleton public class PlayerIndicatorsMinimapOverlay extends Overlay { private final PlayerIndicatorsService playerIndicatorsService; private final PlayerIndicatorsConfig config; + private final BufferedImage skullIcon = ImageUtil.getResourceStreamFromClass(PlayerIndicatorsPlugin.class, + "skull.png"); + @Inject + private ItemManager itemManager; + @Inject + private Client client; @Inject private PlayerIndicatorsMinimapOverlay(PlayerIndicatorsConfig config, PlayerIndicatorsService playerIndicatorsService) @@ -61,15 +73,60 @@ public class PlayerIndicatorsMinimapOverlay extends Overlay private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) { - final String name = actor.getName().replace('\u00A0', ' '); - if (config.drawMinimapNames()) { - final net.runelite.api.Point minimapLocation = actor.getMinimapLocation(); + String name = actor.getName().replace('\u00A0', ' '); + String tag = ""; + String prefix = "tag_"; + if (FriendTaggingPlugin.taggedFriends.containsKey(prefix + name.trim().toLowerCase())) + { + tag = " [" + FriendTaggingPlugin.taggedFriends.get(prefix + name.trim().toLowerCase()) + "] "; + } + + name += tag; + + net.runelite.api.Point minimapLocation = actor.getMinimapLocation(); if (minimapLocation != null) { - OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); + if (config.showCombatLevel()) + { + if (config.showCombatLevel()) + { + name += "-(" + actor.getCombatLevel() + ")"; + } + } + if (config.drawMinimapNames()) + { + if (actor.getSkullIcon() != null && config.playerSkull()) + { + switch (actor.getSkullIcon()) + { + case SKULL: + + int width = graphics.getFontMetrics().stringWidth(name); + int height = graphics.getFontMetrics().getHeight(); + if (config.skullLocation().equals(PlayerIndicatorsPlugin.minimapSkullLocations.AFTER_NAME)) + { + OverlayUtil.renderImageLocation(graphics, new Point(minimapLocation.getX() + + width, minimapLocation.getY() - height), + ImageUtil.resizeImage(skullIcon, height, height)); + } + else + { + OverlayUtil.renderImageLocation(graphics, new Point(minimapLocation.getX(), + minimapLocation.getY() - height), + ImageUtil.resizeImage(skullIcon, height, height)); + minimapLocation = new Point(minimapLocation.getX() + skullIcon.getWidth(), + minimapLocation.getY()); + } + break; + default: + break; + } + } + OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); + } } } } 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 2c1b3c4cbb..d475f0ea42 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Tomas Slusny + * Copyright (c) 2019, Jordan Atwood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,23 +33,44 @@ import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.ClanMemberRank; import net.runelite.api.Client; +import net.runelite.api.ItemComposition; import net.runelite.api.Player; import net.runelite.api.Point; +import net.runelite.api.kit.KitType; import net.runelite.client.game.ClanManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.friendtagging.FriendTaggingPlugin; +import net.runelite.client.plugins.pvptools.PvpToolsPlugin; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.util.ImageUtil; +import net.runelite.client.util.PvPUtil; +import static net.runelite.client.util.StackFormatter.formatNumber; +import net.runelite.client.util.Text; @Singleton public class PlayerIndicatorsOverlay extends Overlay { + private static final int ACTOR_OVERHEAD_TEXT_MARGIN = 40; + private static final int ACTOR_HORIZONTAL_TEXT_MARGIN = 10; + private final PlayerIndicatorsService playerIndicatorsService; private final PlayerIndicatorsConfig config; private final ClanManager clanManager; - + private final BufferedImage skullIcon = ImageUtil.getResourceStreamFromClass(PlayerIndicatorsPlugin.class, + "skull.png"); + PvpToolsPlugin pvpToolsPlugin; @Inject private Client client; + @Inject + private SpriteManager spriteManager; + @Inject + private PlayerIndicatorsPlugin playerIndicatorsPlugin; + @Inject + private ItemManager itemManager; @Inject private PlayerIndicatorsOverlay(PlayerIndicatorsConfig config, PlayerIndicatorsService playerIndicatorsService, @@ -70,74 +92,156 @@ public class PlayerIndicatorsOverlay extends Overlay private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) { - if (!config.drawOverheadPlayerNames() && !config.drawOverheadLevels()) + final PlayerNameLocation drawPlayerNamesConfig = config.playerNamePosition(); + if (drawPlayerNamesConfig == PlayerNameLocation.DISABLED) { return; } - String namee = actor.getName().replace('\u00A0', ' '); - String combatLevel = Integer.toString(actor.getCombatLevel()); - String playerInfo = ""; - Point minimapLocation = actor.getMinimapLocation(); - - if (minimapLocation != null) + final int zOffset; + switch (drawPlayerNamesConfig) { - graphics.fillOval(minimapLocation.getX() - 1, minimapLocation.getY() - 1, 2, 2); + case MODEL_CENTER: + case MODEL_RIGHT: + zOffset = actor.getLogicalHeight() / 2; + break; + default: + zOffset = actor.getLogicalHeight() + ACTOR_OVERHEAD_TEXT_MARGIN; } - if (config.drawOverheadPlayerNames()) - { - playerInfo = namee; - } + String name = Text.sanitize(actor.getName()); + Point textLocation = actor.getCanvasTextLocation(graphics, name, zOffset); - if (config.drawOverheadLevels()) + if (drawPlayerNamesConfig == PlayerNameLocation.MODEL_RIGHT) { - if (!playerInfo.isEmpty()) - { - playerInfo = playerInfo.concat("(" + combatLevel + ")"); - } - else - { - playerInfo = combatLevel; - } - } + textLocation = actor.getCanvasTextLocation(graphics, "", zOffset); - if (config.limitLevel()) - { - if (!(client.getLocalPlayer().getCombatLevel() >= actor.getCombatLevel() - config.intLevel() && client.getLocalPlayer().getCombatLevel() <= actor.getCombatLevel() + config.intLevel())) + if (textLocation == null) { return; } + + textLocation = new Point(textLocation.getX() + ACTOR_HORIZONTAL_TEXT_MARGIN, textLocation.getY()); } - String name = actor.getName().replace('\u00A0', ' ') + (config.limitLevel() ? " Lvl: " + actor.getCombatLevel() : ""); - int offset = actor.getLogicalHeight() + 40; - Point textLocation = actor.getCanvasTextLocation(graphics, playerInfo, offset); - - if (textLocation != null) + if (textLocation == null) { - if (config.showClanRanks() && actor.isClanMember()) + return; + } + + if (config.showClanRanks() && actor.isClanMember()) + { + final ClanMemberRank rank = clanManager.getRank(name); + + if (rank != ClanMemberRank.UNRANKED) { - ClanMemberRank rank = clanManager.getRank(name); + final BufferedImage clanchatImage = clanManager.getClanImage(rank); - if (rank != ClanMemberRank.UNRANKED) + if (clanchatImage != null) { - BufferedImage clanchatImage = clanManager.getClanImage(rank); + final int clanImageWidth = clanchatImage.getWidth(); + final int clanImageTextMargin; + final int clanImageNegativeMargin; - if (clanchatImage != null) + if (drawPlayerNamesConfig == PlayerNameLocation.MODEL_RIGHT) { - int width = clanchatImage.getWidth(); - int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent(); - Point imageLocation = new Point(textLocation.getX() - width / 2 - 1, textLocation.getY() - textHeight / 2 - clanchatImage.getHeight() / 2); - OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); - - // move text - textLocation = new Point(textLocation.getX() + width / 2, textLocation.getY()); + clanImageTextMargin = clanImageWidth; + clanImageNegativeMargin = 0; } + else + { + clanImageTextMargin = clanImageWidth / 2; + clanImageNegativeMargin = clanImageWidth / 2; + } + + final int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent(); + final Point imageLocation = new Point(textLocation.getX() - clanImageNegativeMargin - 1, textLocation.getY() - textHeight / 2 - clanchatImage.getHeight() / 2); + OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); + + // move text + textLocation = new Point(textLocation.getX() + clanImageTextMargin, textLocation.getY()); } } - - OverlayUtil.renderTextLocation(graphics, textLocation, playerInfo, color); } + + String tag = ""; + String prefix = "tag_"; + if (FriendTaggingPlugin.taggedFriends.containsKey(prefix + name.trim().toLowerCase())) + { + tag = " [" + FriendTaggingPlugin.taggedFriends.get(prefix + name.trim().toLowerCase()) + "] "; + name += tag; + } + + if (config.highlightCallers() && playerIndicatorsPlugin.isCaller(actor)) + { + name = "[C] " + name; + } + if (config.highlightPile() && playerIndicatorsPlugin.isPile(actor)) + { + name = "[P] " + name; + } + if (config.showCombatLevel()) + { + + OverlayUtil.renderTextLocation(graphics, textLocation, name + " (" + actor.getCombatLevel() + ")", + color); + + } + if (config.targetRisk() && PvPUtil.isAttackable(client, actor) && actor.getPlayerComposition() != null) + { + long totalValue = 0; + int newValue = 0; + StringBuilder stringBuilder = new StringBuilder(" "); + for (KitType kitType : KitType.values()) + { + ItemComposition itemComposition = + itemManager.getItemComposition(actor.getPlayerComposition().getEquipmentId(kitType)); + if (itemComposition != null || itemComposition.getName() != null) + { + totalValue = totalValue + itemComposition.getPrice(); + } + } + newValue = (int) (totalValue / 1000); + if (newValue != 0) + { + stringBuilder.append("(" + formatNumber(newValue) + "K)"); + name = name + stringBuilder; + } + } + if (config.unchargedGlory() && actor.getPlayerComposition() != null) + { + ItemComposition itemComposition = itemManager.getItemComposition(actor.getPlayerComposition().getEquipmentId(KitType.AMULET)); + if (itemComposition != null && itemComposition.getId() == 1704) //1704 is uncharged glory, to be certain + { + name = name + " cGLORY"; + } + } + if (actor.getSkullIcon() != null && config.playerSkull()) + { + switch (actor.getSkullIcon()) + { + case SKULL: + int width = graphics.getFontMetrics().stringWidth(name); + int height = graphics.getFontMetrics().getHeight(); + if (config.skullLocation().equals(PlayerIndicatorsPlugin.minimapSkullLocations.AFTER_NAME)) + { + OverlayUtil.renderImageLocation(graphics, new Point(textLocation.getX() + + width, textLocation.getY() - height), + ImageUtil.resizeImage(skullIcon, height, height)); + } + else + { + OverlayUtil.renderImageLocation(graphics, new Point(textLocation.getX(), + textLocation.getY() - height), + ImageUtil.resizeImage(skullIcon, height, height)); + textLocation = new Point(textLocation.getX() + skullIcon.getWidth(), + textLocation.getY()); + } + break; + default: + break; + } + } + OverlayUtil.renderTextLocation(graphics, textLocation, name, color); } } 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 24e32c34e6..cbac52ca72 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,245 +26,313 @@ package net.runelite.client.plugins.playerindicators; import com.google.inject.Provides; import java.awt.Color; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; import javax.inject.Inject; -import net.runelite.api.*; - +import net.runelite.api.Actor; +import net.runelite.api.ClanMember; +import net.runelite.api.ClanMemberRank; import static net.runelite.api.ClanMemberRank.UNRANKED; +import net.runelite.api.Client; import static net.runelite.api.MenuAction.*; -import net.runelite.api.coords.WorldPoint; +import net.runelite.api.HeadIcon; +import net.runelite.api.MenuEntry; +import net.runelite.api.Player; +import net.runelite.api.events.ClanMemberJoined; +import net.runelite.api.events.ClanMemberLeft; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ClanManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ColorUtil; -import com.google.common.base.Splitter; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Pattern; - -import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.InteractChanged; -import net.runelite.client.util.WildcardMatcher; - +import net.runelite.client.util.PvPUtil; @PluginDescriptor( - name = "Player Indicators", - description = "Highlight players on-screen and/or on the minimap", - tags = {"highlight", "minimap", "overlay", "players"}, - type = PluginType.PVP + name = "Player Indicators", + description = "Highlight players on-screen and/or on the minimap", + tags = {"highlight", "minimap", "overlay", "players", "pklite"} ) public class PlayerIndicatorsPlugin extends Plugin { - private static final Splitter COMMA_SPLITTER = Splitter.on(Pattern.compile("\\s*,\\s*")); @Inject private OverlayManager overlayManager; - + @Inject private PlayerIndicatorsConfig config; - + @Inject private PlayerIndicatorsOverlay playerIndicatorsOverlay; - + @Inject private PlayerIndicatorsTileOverlay playerIndicatorsTileOverlay; - - @Inject - private FriendMinimapOverlay friendMinimapOverlay; - + @Inject private PlayerIndicatorsMinimapOverlay playerIndicatorsMinimapOverlay; - + @Inject private Client client; - + @Inject private ClanManager clanManager; - - private Map highlightedPlayers = new HashMap<>(); - + @Provides PlayerIndicatorsConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(PlayerIndicatorsConfig.class); } - + @Override protected void startUp() throws Exception { overlayManager.add(playerIndicatorsOverlay); overlayManager.add(playerIndicatorsTileOverlay); overlayManager.add(playerIndicatorsMinimapOverlay); - overlayManager.add(friendMinimapOverlay); - updateHighlightList(); + getCallerList(); } - + @Override protected void shutDown() throws Exception { overlayManager.remove(playerIndicatorsOverlay); overlayManager.remove(playerIndicatorsTileOverlay); overlayManager.remove(playerIndicatorsMinimapOverlay); - overlayManager.remove(friendMinimapOverlay); } - + + private ArrayList callers = new ArrayList<>(); + private List pileList; + @Subscribe - public void onInteractChanged(InteractChanged event) + public void onConfigChanged(ConfigChanged e) { - Actor actor = event.getActor(); - if (actor != null - && actor.getName() != null - && isHighlighted(actor)) + if (config.callers() != null && !config.callers().trim().equals("")) { - highlightedPlayers.put(actor.getName().toLowerCase(), actor.getInteracting()); + getCallerList(); } } - + @Subscribe - public void onConfigChanged(ConfigChanged event) + public void onGameTick(GameTick gameTick) { - if (event.getGroup().equals("playerindicators") && event.getKey().equals("highlightedNames")) + if (config.highlightPile() && callers != null) { - updateHighlightList(); + for (Player p : client.getPlayers()) + { + for (String name:callers) + { + Actor pile = null; + String finalName = name.toLowerCase().replace("_", " "); + if (p.getName().toLowerCase().replace("_", " ").equals(finalName)) + { + pile = p.getInteracting(); + if (pile != null) + { + pileList.set(callers.indexOf(name), pile.getName()); + //pileList.add(pile.getName()); + } + else + { + pileList.set(callers.indexOf(name), ""); + } + } + } + } } } - - private void updateHighlightList() + + @Subscribe + public void onClanMemberJoined(ClanMemberJoined event) { - highlightedPlayers.clear(); - for (String player : COMMA_SPLITTER.splitToList(config.getHighlightedNames().toLowerCase().trim())) - { - highlightedPlayers.put(player, null); - } + getCallerList(); } - - boolean isHighlighted(Actor player) + + @Subscribe + public void onClanMemberLeft(ClanMemberLeft event) { - for (Map.Entry map : highlightedPlayers.entrySet()) + getCallerList(); + } + + public void getCallerList() + { + callers.clear(); + if (config.useClanchatRanks() && client.getClanMembers() != null) { - if (WildcardMatcher.matches(map.getKey(), player.getName())) + for (ClanMember clanMember : client.getClanMembers()) + { + if (clanMember.getRank().getValue() > config.callerRank().getValue()) + { + callers.add(clanMember.getUsername()); + } + } + } + if (config.callers().contains(",")) + { + callers.addAll(Arrays.asList(config.callers().split(","))); + } + else + { + if (!config.callers().equals("") || config.callers().length() > 1) + { + callers.add(config.callers()); + } + } + pileList = Arrays.asList(new String[callers.size()]); + } + + public boolean isCaller(Player player) + { + if (callers != null) + { + for (String name:callers) + { + String finalName = name.toLowerCase().replace("_", " "); + if (player.getName().toLowerCase().replace("_", " ").equals(finalName)) + { + return true; + } + } + } + else {return false;} + return false; + } + + public boolean isPile(Player player) + { + if (Objects.nonNull(pileList) && pileList.size() > 0) + { + if (pileList.contains(player.getName())) { return true; } } return false; } - - boolean isHighlightedTarget(Player player) - { - return highlightedPlayers.containsValue(player); - } - + @Subscribe public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) { - if (config.showInWildernessOnly() && client.getVar(Varbits.IN_THE_WILDERNESS) != 1) - { - return; - } int type = menuEntryAdded.getType(); - + if (type >= 2000) { type -= 2000; } - + int identifier = menuEntryAdded.getIdentifier(); if (type == FOLLOW.getId() || type == TRADE.getId() - || type == SPELL_CAST_ON_PLAYER.getId() || type == ITEM_USE_ON_PLAYER.getId() - || type == PLAYER_FIRST_OPTION.getId() - || type == PLAYER_SECOND_OPTION.getId() - || type == PLAYER_THIRD_OPTION.getId() - || type == PLAYER_FOURTH_OPTION.getId() - || type == PLAYER_FIFTH_OPTION.getId() - || type == PLAYER_SIXTH_OPTION.getId() - || type == PLAYER_SEVENTH_OPTION.getId() - || type == PLAYER_EIGTH_OPTION.getId() - || type == RUNELITE.getId()) + || type == SPELL_CAST_ON_PLAYER.getId() || type == ITEM_USE_ON_PLAYER.getId() + || type == PLAYER_FIRST_OPTION.getId() + || type == PLAYER_SECOND_OPTION.getId() + || type == PLAYER_THIRD_OPTION.getId() + || type == PLAYER_FOURTH_OPTION.getId() + || type == PLAYER_FIFTH_OPTION.getId() + || type == PLAYER_SIXTH_OPTION.getId() + || type == PLAYER_SEVENTH_OPTION.getId() + || type == PLAYER_EIGTH_OPTION.getId() + || type == RUNELITE.getId()) { final Player localPlayer = client.getLocalPlayer(); Player[] players = client.getCachedPlayers(); Player player = null; - + if (identifier >= 0 && identifier < players.length) { player = players[identifier]; } - + if (player == null) { return; } - + int image = -1; + int image2 = -1; Color color = null; - - if (config.highlightFriends() && player.isFriend()) + + if (config.colorPlayerMenu() && client.isFriended(player.getName(), false)) { color = config.getFriendColor(); } - else if (config.drawClanMemberNames() && player.isClanMember()) + else if (config.colorPlayerMenu() && player.isClanMember()) { color = config.getClanMemberColor(); - + ClanMemberRank rank = clanManager.getRank(player.getName()); if (rank != UNRANKED) { image = clanManager.getIconNumber(rank); } } - else if (config.highlightTeamMembers() && player.getTeam() > 0 && localPlayer.getTeam() == player.getTeam()) + else if (config.colorPlayerMenu() && player.getTeam() > 0 && localPlayer.getTeam() == player.getTeam()) + { + color = config.getTeamMemberColor(); + } + else if (!player.isClanMember() && !player.isFriend() && !PvPUtil.isAttackable(client, player)) + { + color = config.getNonClanMemberColor(); + } + else if (config.colorPlayerMenu() && !player.isClanMember() && client.isFriended(player.getName(), false) && PvPUtil.isAttackable(client, player)) + { + color = config.getTargetColor(); + } + else if (config.colorPlayerMenu() && PvPUtil.isAttackable(client, player) && !player.isClanMember() && !player.isFriend()) + { + color = config.getTargetColor(); + } + if (config.rightClickOverhead() && !player.isClanMember() && player.getOverheadIcon() != null) { - color = config.getTeamMemberColor(); - } - else if (config.highlightNonClanMembers() && !player.isClanMember()) - { - color = config.getNonClanMemberColor(); - } - else if (config.drawHighlightedNames() && isHighlighted(player)) - { - color = config.getHighlightedNamesColor(); - } - else if (config.drawHighlightedTargetNames() && isHighlightedTarget(player)) - { - color = config.getHighlightedTargetColor(); - } - else if (config.highlightAttackerPlayers() && player.getInteracting() == localPlayer) - { - color = config.getAttackerPlayerColor(); - } - else if (config.highlightAttackablePlayers() && isWithinLevelRange(player.getCombatLevel())) - { - color = config.getAttackablePlayerColor(); - } -/* if (this.config.rightClickOverhead() && !player.isClanMember() && player.getOverheadIcon() != null) { // NEEDS TESTING - if (player.getOverheadIcon().equals((Object)HeadIcon.MAGIC)) { + if (player.getOverheadIcon().equals(HeadIcon.MAGIC)) + { image = 29; - } else if (player.getOverheadIcon().equals((Object)HeadIcon.RANGED)) { + } + else if (player.getOverheadIcon().equals(HeadIcon.RANGED)) + { image = 30; - } else if (player.getOverheadIcon().equals((Object)HeadIcon.MELEE)) { + } + else if (player.getOverheadIcon().equals(HeadIcon.MELEE)) + { image = 31; - } else if (player.getOverheadIcon().equals((Object)HeadIcon.REDEMPTION)) { + } + else if (player.getOverheadIcon().equals(HeadIcon.REDEMPTION)) + { image = 32; - } else if (player.getOverheadIcon().equals((Object)HeadIcon.RETRIBUTION)) { + } + else if (player.getOverheadIcon().equals(HeadIcon.RETRIBUTION)) + { image = 33; - } else if (player.getOverheadIcon().equals((Object)HeadIcon.SMITE)) { + } + else if (player.getOverheadIcon().equals(HeadIcon.SMITE)) + { image = 34; } - }*/ - + + } + if (config.playerSkull() && !player.isClanMember() && player.getSkullIcon() != null) + { + image2 = 35; + } + if (config.colorPlayerMenu() && config.highlightCallers() && this.isCaller(player)) + { + color = config.callerColor(); + } + if (config.colorPlayerMenu() && config.highlightPile() && this.isPile(player)) + { + color = config.pileColor(); + } if (image != -1 || color != null) { MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; - + + if (color != null && config.colorPlayerMenu()) { // strip out existing " + lastEntry.getTarget()); + lastEntry.setTarget(lastEntry.getTarget() + ""); } - + if (image2 != -1 && config.playerSkull()) + { + lastEntry.setTarget("" + lastEntry.getTarget()); + } + client.setMenuEntries(menuEntries); } } } - - public boolean isWithinLevelRange(int playerCombatLevel) - { - Widget levelRangeWidget = client.getWidget(WidgetInfo.PVP_ATTACK_RANGE); - Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL); - - int localPlayerLevel = client.getLocalPlayer().getCombatLevel(); - int lowerLevelBound = localPlayerLevel - 15; - int upperLevelBound = localPlayerLevel + 15; - - if (levelRangeWidget == null && wildernessLevelWidget == null) - { - return false; - } - - if (!levelRangeWidget.isHidden() && !wildernessLevelWidget.isHidden()) - { - int wildernessLevel = calculateWildernessLevel(client.getLocalPlayer().getWorldLocation()); - lowerLevelBound = localPlayerLevel - wildernessLevel - 15; - upperLevelBound = localPlayerLevel + wildernessLevel + 15; - return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound); - } - else if (levelRangeWidget.isHidden() && !wildernessLevelWidget.isHidden()) - { - int wildernessLevel = calculateWildernessLevel(client.getLocalPlayer().getWorldLocation()); - lowerLevelBound = localPlayerLevel - wildernessLevel; - upperLevelBound = localPlayerLevel + wildernessLevel; - return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound); - } - else - { - return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound); - } - } - - public static int calculateWildernessLevel(WorldPoint userLocation) - { - int wildernessLevel = 0; - if (WorldPoint.isInZone(new WorldPoint(2944, 3520, 0), new WorldPoint(3391, 4351, 3), userLocation)) - { - wildernessLevel = ((userLocation.getY() - (55 * 64)) / 8) + 1; - } - else if (WorldPoint.isInZone(new WorldPoint(3008, 10112, 0), new WorldPoint(3071, 10175, 3), userLocation)) - { - wildernessLevel = ((userLocation.getY() - (155 * 64)) / 8) - 1; - } - else if (WorldPoint.isInZone(new WorldPoint(2944, 9920, 0), new WorldPoint(3391, 10879, 3), userLocation)) - { - wildernessLevel = ((userLocation.getY() - (155 * 64)) / 8) + 1; - } - return wildernessLevel; - } - + + public static enum minimapSkullLocations + { + BEFORE_NAME, + AFTER_NAME + } } 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 e8aff835bd..bb09a31a15 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 @@ -30,96 +30,88 @@ import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.Player; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.Varbits; - - -import static net.runelite.client.plugins.playerindicators.PlayerIndicatorsPlugin.calculateWildernessLevel; +import net.runelite.client.util.PvPUtil; @Singleton -public class PlayerIndicatorsService { +public class PlayerIndicatorsService +{ private final Client client; private final PlayerIndicatorsConfig config; + private final PlayerIndicatorsPlugin playerIndicatorsPlugin; @Inject - private PlayerIndicatorsService(Client client, PlayerIndicatorsConfig config) { + private PlayerIndicatorsService(Client client, PlayerIndicatorsConfig config, PlayerIndicatorsPlugin plugin) + { this.config = config; this.client = client; + this.playerIndicatorsPlugin = plugin; } - public void forEachPlayer(final BiConsumer consumer) { - - if (config.showInWildernessOnly() && client.getVar(Varbits.IN_THE_WILDERNESS) != 1) - { - return; - } - + public void forEachPlayer(final BiConsumer consumer) + { if (!config.highlightOwnPlayer() && !config.drawClanMemberNames() - && !config.highlightFriends() && !config.highlightNonClanMembers() - && !config.highlightAttackablePlayers() && !config.highlightAttackerPlayers()) { + && !config.highlightFriends() && !config.highlightNonClanMembers() && !config.highlightTargets() + && !config.highlightPile() && !config.highlightCallers() && !config.highlightTeamMembers()) + { return; } final Player localPlayer = client.getLocalPlayer(); - for (Player player : client.getPlayers()) { - if (player == null || player.getName() == null) { + for (Player player : client.getPlayers()) + { + if (player == null || player.getName() == null) + { continue; } boolean isClanMember = player.isClanMember(); - if (player == localPlayer) { - if (config.highlightOwnPlayer()) { + if (player == localPlayer) + { + if (config.highlightOwnPlayer()) + { consumer.accept(player, config.getOwnPlayerColor()); } - } else if (config.highlightFriends() && (player.isFriend() || client.isFriended(player.getName(), false))) { + } + else if (config.highlightFriends() && client.isFriended(player.getName(), false)) + { consumer.accept(player, config.getFriendColor()); - } else if (config.drawClanMemberNames() && isClanMember) { + } + else if (config.drawClanMemberNames() && isClanMember) + { consumer.accept(player, config.getClanMemberColor()); - } else if (config.highlightTeamMembers() && localPlayer.getTeam() > 0 && localPlayer.getTeam() == player.getTeam()) { + } + else if (config.highlightTeamMembers() && localPlayer.getTeam() > 0 && + localPlayer.getTeam() == player.getTeam()) + { consumer.accept(player, config.getTeamMemberColor()); - } else if (config.highlightNonClanMembers() && !isClanMember) { + } + else if (config.highlightNonClanMembers() && !isClanMember) + { consumer.accept(player, config.getNonClanMemberColor()); - } else if (config.highlightAttackerPlayers() && player.getInteracting() == localPlayer) { - consumer.accept(player, config.getAttackerPlayerColor()); - } else if (config.highlightAttackablePlayers() && isWithinLevelRange(player.getCombatLevel())) { - consumer.accept(player, config.getAttackablePlayerColor()); - } - } - } - - public boolean isWithinLevelRange(int playerCombatLevel) - { - Widget levelRangeWidget = client.getWidget(WidgetInfo.PVP_ATTACK_RANGE); - Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL); - - int localPlayerLevel = client.getLocalPlayer().getCombatLevel(); - int lowerLevelBound = localPlayerLevel - 15; - int upperLevelBound = localPlayerLevel + 15; - - if (levelRangeWidget == null && wildernessLevelWidget == null) - { - return false; - } - - if (!levelRangeWidget.isHidden() && !wildernessLevelWidget.isHidden()) - { - lowerLevelBound = Integer.parseInt(levelRangeWidget.getText().split("-")[0]); - upperLevelBound = Integer.parseInt(levelRangeWidget.getText().split("-")[1]); - return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound); - } - else if (levelRangeWidget.isHidden() && !wildernessLevelWidget.isHidden()) - { - int wildernessLevel = calculateWildernessLevel(client.getLocalPlayer().getWorldLocation()); - lowerLevelBound = localPlayerLevel - wildernessLevel; - upperLevelBound = localPlayerLevel + wildernessLevel; - return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound); - } - else - { - return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound); + } + else if (config.highlightTargets() && PvPUtil.isAttackable(client, player) && + !client.isFriended(player.getName(), false) && !player.isClanMember()) + { + if (config.skulledTargetsOnly() && player.getSkullIcon() != null) + { + consumer.accept(player, config.getTargetColor()); + } + else if (!config.skulledTargetsOnly()) + { + consumer.accept(player, config.getTargetColor()); + } + } + if (config.highlightCallers() && config.callers() != null && playerIndicatorsPlugin.isCaller(player)) + { + consumer.accept(player, config.callerColor()); + } + if (config.highlightPile() && PvPUtil.isAttackable(client, player) && playerIndicatorsPlugin.isPile(player) + && !player.isClanMember()) + { + consumer.accept(player, config.pileColor()); + } } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsTileOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsTileOverlay.java index 0e7c2e31fc..bc5a49fbc1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsTileOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsTileOverlay.java @@ -25,9 +25,7 @@ package net.runelite.client.plugins.playerindicators; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; +import java.awt.*; import javax.inject.Inject; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; @@ -39,12 +37,15 @@ public class PlayerIndicatorsTileOverlay extends Overlay { private final PlayerIndicatorsService playerIndicatorsService; private final PlayerIndicatorsConfig config; + private final PlayerIndicatorsPlugin playerIndicatorsPlugin; @Inject - private PlayerIndicatorsTileOverlay(PlayerIndicatorsConfig config, PlayerIndicatorsService playerIndicatorsService) + private PlayerIndicatorsTileOverlay(PlayerIndicatorsConfig config, + PlayerIndicatorsService playerIndicatorsService, PlayerIndicatorsPlugin plugin) { this.config = config; this.playerIndicatorsService = playerIndicatorsService; + this.playerIndicatorsPlugin = plugin; setLayer(OverlayLayer.ABOVE_SCENE); setPosition(OverlayPosition.DYNAMIC); setPriority(OverlayPriority.MED); @@ -53,21 +54,51 @@ public class PlayerIndicatorsTileOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - if (!config.drawTiles()) + if (config.drawPileHull()) + { + playerIndicatorsService.forEachPlayer((player, color) -> + { + if (playerIndicatorsPlugin.isPile(player)) + { + Polygon objectClickbox = player.getConvexHull(); + + renderPoly(graphics, config.pileColor(), objectClickbox); + + if (objectClickbox != null) + { + + } + } + }); + } + if (!config.drawTiles() /*&& !config.drawPlayerHull()*/) { return null; } - - playerIndicatorsService.forEachPlayer((player, color) -> + else if (config.drawTiles()) { - final Polygon poly = player.getCanvasTilePoly(); - - if (poly != null) + playerIndicatorsService.forEachPlayer((player, color) -> { - OverlayUtil.renderPolygon(graphics, poly, color); - } - }); + final Polygon poly = player.getCanvasTilePoly(); + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, color); + } + }); + } return null; } + + private void renderPoly(Graphics2D graphics, Color color, Polygon polygon) + { + if (polygon != null) + { + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2)); + graphics.draw(polygon); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 20)); + graphics.fill(polygon); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsConfig.java new file mode 100644 index 0000000000..91545b3074 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsConfig.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + +package net.runelite.client.plugins.wildernesslocations; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.Keybind; + +@ConfigGroup("wildernesslocations") +public interface WildernessLocationsConfig extends Config +{ + + @ConfigItem( + keyName = "drawOverlay", + name = "Draw Overlay", + description = "Configure drawing wilderness locations overlay", + position = 1 + ) + default boolean drawOverlay() + { + return true; + } + + @ConfigItem( + keyName = "keybind", + name = "Send to CC", + description = "Configure button to send current location to CC", + position = 2 + ) + default Keybind keybind() + { + return Keybind.NOT_SET; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java index 8ab198dc28..d8148ab8bf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.wildernesslocations; import java.awt.Dimension; @@ -14,6 +23,9 @@ public class WildernessLocationsOverlay extends Overlay { private final WildernessLocationsPlugin plugin; private TextComponent textComponent; + + @Inject + private WildernessLocationsConfig wildyConfig; @Inject public WildernessLocationsOverlay(Client client, WildernessLocationsPlugin plugin) @@ -29,7 +41,7 @@ public class WildernessLocationsOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - if (plugin.isRenderLocation()) + if (plugin.isRenderLocation() && wildyConfig.drawOverlay()) { textComponent.setText(plugin.getLocationString()); return textComponent.render(graphics); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java index b1036cde55..31f8ef045b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.wildernesslocations; @@ -7,25 +16,36 @@ import java.util.Map; import java.util.Objects; import javax.inject.Inject; +import com.google.inject.Provides; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import net.runelite.api.ScriptID; +import net.runelite.api.VarClientStr; import net.runelite.api.Varbits; import net.runelite.api.coords.WorldArea; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameTick; +import net.runelite.api.events.VarClientStrChanged; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.PluginManager; +import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.WildernessLocation; +@Slf4j @PluginDescriptor( - name = "Wild Locations", - description = "Indicates the players current location in the wild", - tags = {"Wildy", "Wilderness Location", "location", "loc", "pvp", "pklite"}, - type = PluginType.PVP + name = "Wild Locations", + description = "Indicates the players current location in the wild", + tags = {"Wildy", "Wilderness Location", "location", "loc", "pvp", "pklite"}, + type = PluginType.PVP ) public class WildernessLocationsPlugin extends Plugin { @@ -39,29 +59,63 @@ public class WildernessLocationsPlugin extends Plugin @Inject private WildernessLocationsOverlay overlay = new WildernessLocationsOverlay(this.client, this); - private final HashMap wildLocs = getLocationMap(); @Getter private boolean renderLocation; + @Getter private String locationString = ""; - private WorldPoint worldPoint = null; + @Inject + private ClientThread clientThread; + + @Inject + private WildernessLocationsConfig wildyConfig; + + @Inject + private KeyManager keyManager; + + private String oldChat = ""; + private int currentCooldown = 0; + private final int COOLDOWN_TICKS = 30; + private WorldPoint worldPoint = null; + private final HashMap wildLocs = getLocationMap(); + + private final HotkeyListener hotkeyListener = new HotkeyListener(() -> wildyConfig.keybind()) + { + @Override + public void hotkeyPressed() + { + sendLocToCC(); + } + }; + + @Provides + WildernessLocationsConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(WildernessLocationsConfig.class); + } @Override protected void startUp() throws Exception { overlayManager.add(overlay); + keyManager.registerKeyListener(hotkeyListener); } @Override protected void shutDown() throws Exception { overlayManager.remove(overlay); + keyManager.unregisterKeyListener(hotkeyListener); } @Subscribe public void onGameTick(GameTick event) { + if (currentCooldown != 0) + { + currentCooldown--; + } renderLocation = client.getVar(Varbits.IN_WILDERNESS) == 1; if (renderLocation) { @@ -78,7 +132,6 @@ public class WildernessLocationsPlugin extends Plugin } } - private String location() { int dist = 10000; @@ -134,4 +187,53 @@ public class WildernessLocationsPlugin extends Plugin hashMap.put(wildernessLocation.getWorldArea(), wildernessLocation.getName())); return hashMap; } + + @Subscribe + public void onVarClientStrChanged(VarClientStrChanged varClient) + { + String newChat = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); + if (varClient.getIndex() == VarClientStr.CHATBOX_TYPED_TEXT.getIndex() && !newChat.equals(oldChat)) + { + oldChat = newChat; + } + } + + private boolean inClanChat() + { + return client.getWidget(WidgetInfo.CLAN_CHAT_TITLE) != null; + } + + private void sendMessage(String text) + { + int mode = 0; + if (inClanChat() && text.startsWith("/")) + { + mode = 2; + } + int finalMode = mode; + Runnable r = () -> + { + String cached = oldChat; + client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, text); + client.runScript(ScriptID.CHATBOX_INPUT, finalMode, text); + oldChat = cached; + client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, oldChat); + }; + clientThread.invoke(r); + } + + private void sendLocToCC() + { + if (currentCooldown != 0) + { + return; + } + String location = getLocationString(); + if (location.equals("")) + { + return; + } + sendMessage("/World: " + client.getWorld() + " Location: " + location); + currentCooldown = COOLDOWN_TICKS; + } } diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/playerindicators/skull.png b/runelite-client/src/main/resources/net/runelite/client/plugins/playerindicators/skull.png new file mode 100644 index 0000000000..09869ea0e1 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/playerindicators/skull.png differ