5) {
+ Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
+ return;
+ }
+ peer.mousePress(InputEvent.getMaskForButton(buttonID));
+ this.delay(getMinDelay());
+ }
+
+ public synchronized void mousePressAndRelease(int buttonID) {
+ if (buttonID<1 || buttonID >5) {
+ Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
+ return;
+ }
+ peer.mousePress(InputEvent.getMaskForButton(buttonID));
+ this.delay(getMinDelay());
+ peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
+ this.delay(getMinDelay());
+ }
+
+ //TODO: Symbols are nut supported at this time
+ public synchronized void typeMessage(String message) {
+
+ Random r = new Random();
+ char[] charArray = message.toCharArray();
+ for (char c : charArray) {
+ keyPress(KeyEvent.getExtendedKeyCodeForChar(c));
+ this.delay(93+r.nextInt(getMinDelay()));
+ }
+ keyPress(KeyEvent.VK_ENTER);
+ this.delay(93+r.nextInt(getMinDelay()));
+ ClientUI.allowInput = true;
+ }
+
+
+
+ @Override
+ public synchronized void mouseRelease(int buttonID) {
+ if (buttonID<1 || buttonID >5) {
+ Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
+ return;
+ }
+ peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
+ this.delay(getMinDelay());
+ }
+
+ private int getMinDelay() {
+ Random random = new Random();
+ int random1 = random.nextInt(minDelay);
+ if (random1 < minDelay/2)
+ random1 = random.nextInt(minDelay/2) + minDelay/2+random.nextInt(minDelay/2);
+ return random1;
+ }
+
+ private int getWheelDelay() {
+ Random random = new Random();
+ int random1 = random.nextInt(minDelay);
+ if (random1 < minDelay/2)
+ random1 = random.nextInt(minDelay/2) + minDelay/2+random.nextInt(minDelay/2);
+ return random1;
+ }
+
+ /**
+ * Rotates the scroll wheel on wheel-equipped mice.
+ *
+ * @param wheelAmt number of "notches" to move the mouse wheel
+ * Negative values indicate movement up/away from the user,
+ * positive values indicate movement down/towards the user.
+ *
+ * @since 1.4
+ */
+ @Override
+ public synchronized void mouseWheel(int wheelAmt) {
+ for (int i : new int[wheelAmt]) {
+ peer.mouseWheel(wheelAmt);
+ this.delay(getWheelDelay());
+ }
+ }
+
+ /**
+ * Presses a given key. The key should be released using the
+ * keyRelease method.
+ *
+ * Key codes that have more than one physical key associated with them
+ * (e.g. KeyEvent.VK_SHIFT could mean either the
+ * left or right shift key) will map to the left key.
+ *
+ * @param keycode Key to press (e.g. KeyEvent.VK_A)
+ * @throws IllegalArgumentException if keycode is not
+ * a valid key
+ * @see #keyRelease(int)
+ * @see java.awt.event.KeyEvent
+ */
+ @Override
+ public synchronized void keyPress(int keycode) {
+ peer.keyPress(keycode);
+ this.delay(getMinDelay());
+ }
+
+ @Override
+ public synchronized void keyRelease(int keycode) {
+ peer.keyRelease(keycode);
+ this.delay(getMinDelay());
+ }
+
+ public synchronized void holdKey(int keycode, int timeMS) {
+ new Thread(() -> {
+ peer.keyPress(keycode);
+ long startTime = System.currentTimeMillis();
+ while ((startTime + timeMS) > System.currentTimeMillis()) { }
+ peer.keyRelease(keycode);
+ this.delay(getMinDelay());
+ }).start();
+ }
+
+ public synchronized void holdKeyIndefinitely(int keycode) {
+ holdKeyThread = new Thread(() -> {
+ pausedIndefinitely = true;
+ peer.keyPress(keycode);
+ while (pausedIndefinitely) {
+ try {
+ holdKeyThread.sleep(10);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ peer.keyRelease(keycode);
+ this.delay(getMinDelay());
+ });
+ holdKeyThread.start();
+
+ }
+
+ @Override
+ public Color getPixelColor(int x, int y) {
+ Color color = new Color(peer.getRGBPixel(x, y));
+ return color;
+ }
+
+ @Override
+ public void delay(int ms) {
+ pauseMS(ms);
+ }
+
+ public int determineHorizontalOffset() {
+ return clientUI.getCanvasOffset().getX();
+ }
+
+ public int determineVerticalOffset() {
+ return clientUI.getCanvasOffset().getY();
+ }
+
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java
new file mode 100644
index 0000000000..70bbf51ba6
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java
@@ -0,0 +1,190 @@
+
+/*
+ *
+ * Copyright (c) 2019, Zeruth
+ * 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.flexo;
+
+import net.runelite.client.ui.ClientUI;
+
+import java.awt.*;
+import java.util.Random;
+import java.util.logging.Logger;
+
+public class FlexoMouse {
+
+ /*
+ Should pass unstretched coords, handles all conversions here.
+ */
+ public static Point getClickPoint(Rectangle rect)
+ {
+ if (rect!=null) {
+ Random r = new Random();
+ int x = -1;
+ int y = -1;
+ x = rect.x+r.nextInt(rect.width);
+ y = rect.y+r.nextInt(rect.height);
+
+ if (Flexo.isStretched) {
+ double wScale;
+ double hScale;
+
+ if (Flexo.client.isResized()) {
+ wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width);
+ hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height);
+ int newX = (int)(x*wScale);
+ int newY = (int)(y*hScale);
+ if (newX>0 && newX< ClientUI.frame.getWidth()) {
+ if (newY>0 && newY< ClientUI.frame.getHeight()) {
+ return new Point(newX, newY);
+ }
+ }
+ Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
+ return null;
+ } else {
+ if (x>0 && x< ClientUI.frame.getWidth()) {
+ if (y>0 && y< ClientUI.frame.getHeight()) {
+ return new Point(x, y);
+ }
+ }
+ Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
+ return null;
+ }
+
+ } else if (!Flexo.client.isResized()) {
+ int fixedWidth = 765;
+ int widthDif = ClientUI.frame.getWidth();
+
+ if (ClientUI.pluginToolbar.isVisible()) {
+ widthDif -= ClientUI.pluginToolbar.getWidth();
+ }
+ if (ClientUI.pluginPanel!=null)
+ widthDif -= ClientUI.pluginPanel.getWidth();
+
+ widthDif -= fixedWidth;
+ if (x+(widthDif/2)>0 && x+(widthDif/2)< ClientUI.frame.getWidth()) {
+ if (y>0 && y< ClientUI.frame.getHeight()) {
+ return new Point(x, y);
+ }
+ }
+ Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
+ return null;
+ }
+ else {
+ if (x>0 && x< ClientUI.frame.getWidth()) {
+ if (y>0 && y< ClientUI.frame.getHeight()) {
+ return new Point(x, y);
+ }
+ }
+ Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
+ return null;
+ }
+ }
+ return null;
+ }
+
+ public static Rectangle getClickArea(Rectangle rect)
+ {
+ if (Flexo.isStretched)
+ {
+ double wScale;
+ double hScale;
+
+ if (Flexo.client.isResized()) {
+ wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width);
+ hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height);
+ } else {
+ wScale = ((double) Flexo.client.getStretchedDimensions().width) / Flexo.fixedWidth;
+ hScale = ((double) Flexo.client.getStretchedDimensions().height) / Flexo.fixedHeight;
+ }
+
+ int xPadding = (int)rect.getWidth()/5;
+ int yPadding = (int)rect.getHeight()/5;
+ Random r = new Random();
+ Rectangle clickRect = new Rectangle();
+ clickRect.width = rect.width-xPadding*2;
+ clickRect.height = rect.height-yPadding*2;
+ clickRect.x = rect.x+xPadding;
+ clickRect.y = rect.y+yPadding;
+ if (clickRect.width>0&&clickRect.height>0) {
+ int x = clickRect.x+r.nextInt(clickRect.width);
+ int y = clickRect.y+r.nextInt(clickRect.height);
+ double tScale = 1 + (Flexo.scale / 100);
+
+ if (Flexo.client.isResized()) {
+ return new Rectangle((int)(clickRect.x * wScale), (int)(clickRect.y * wScale), (int)(clickRect.width * wScale), (int)(clickRect.getHeight()*hScale));
+ } else {
+ return new Rectangle((int)(clickRect.x), (int)(clickRect.y), (int)(clickRect.width), (int)(clickRect.getHeight()));
+ }
+ }
+
+ }
+ //Fixed, not stretched
+ else if (!Flexo.client.isResized()) {
+ int fixedWidth = 765;
+ int widthDif = ClientUI.frame.getWidth();
+
+ if (ClientUI.pluginToolbar.isVisible()) {
+ widthDif -= ClientUI.pluginToolbar.getWidth();
+ }
+ if (ClientUI.pluginPanel!=null)
+ widthDif -= ClientUI.pluginPanel.getWidth();
+
+ widthDif -= fixedWidth;
+ int xPadding = (int)rect.getWidth()/5;
+ int yPadding = (int)rect.getHeight()/5;
+ Random r = new Random();
+ Rectangle clickRect = new Rectangle();
+ clickRect.width = rect.width-xPadding;
+ clickRect.height = rect.height-yPadding;
+ clickRect.x = rect.x+xPadding;
+ clickRect.y = rect.y+yPadding;
+ if (clickRect.height>0&&clickRect.width>0) {
+ int x = clickRect.x + r.nextInt(clickRect.width);
+ int y = clickRect.y + r.nextInt(clickRect.height);
+ return new Rectangle((int) (clickRect.x), (int) (clickRect.y), (int) (clickRect.width), (int) (clickRect.getHeight()));
+ }
+ }
+ //Resizable, not stretched
+ else {
+ int xPadding = (int)rect.getWidth()/5;
+ int yPadding = (int)rect.getHeight()/5;
+ Random r = new Random();
+ Rectangle clickRect = new Rectangle();
+ clickRect.width = rect.width-xPadding*2;
+ clickRect.height = rect.height-yPadding*2;
+ clickRect.x = rect.x+xPadding;
+ clickRect.y = rect.y+yPadding;
+ if (clickRect.height>0&&clickRect.width>0) {
+ int x = clickRect.x+r.nextInt(clickRect.width);
+ int y = clickRect.y+r.nextInt(clickRect.height);
+ return new Rectangle((int)(clickRect.x), (int)(clickRect.y), (int)(clickRect.width), (int)(clickRect.getHeight()));
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java
index b7111848a2..1fb9a72b29 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java
@@ -107,11 +107,15 @@ public enum AoeProjectileInfo
*/
ADDY_DRAG_POISON(ProjectileID.ADDY_DRAG_POISON, 1),
- /**
- * the Breath of the Drake
- */
-
- DRAKE_BREATH(ProjectileID.DRAKE_BREATH, 1);
+ /**
+ * the Breath of the Drake
+ */
+ DRAKE_BREATH(ProjectileID.DRAKE_BREATH, 1),
+
+ /**
+ * Cerbs fire
+ */
+ CERB_FIRE(ProjectileID.CERB_FIRE, 2);
private static final Map map = new HashMap<>();
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningConfig.java
index 42e7b5efc8..3475d9f7b9 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningConfig.java
@@ -253,14 +253,25 @@ public interface AoeWarningConfig extends Config
return true;
}
- @ConfigItem(
- keyName = "drake",
- name = "Drakes Breath",
- description = "Configures if Drakes Breath tile markers are displayed"
- )
- default boolean isDrakeEnabled() {
- return true;
- }
+ @ConfigItem(
+ keyName = "drake",
+ name = "Drakes Breath",
+ description = "Configures if Drakes Breath tile markers are displayed"
+ )
+ default boolean isDrakeEnabled()
+ {
+ return true;
+ }
+
+ @ConfigItem(
+ keyName = "cerbFire",
+ name = "Cerberus Fire",
+ description = "Configures if Cerberus fire tile markers are displayed"
+ )
+ default boolean isCerbFireEnabled()
+ {
+ return true;
+ }
@ConfigItem(
keyName = "delay",
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java
index feaa5f27f6..9971635bb4 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java
@@ -300,8 +300,10 @@ public class AoeWarningPlugin extends Plugin
return config.isXarpusEnabled();
case ADDY_DRAG_POISON:
return config.addyDrags();
- case DRAKE_BREATH:
- return config.isDrakeEnabled();
+ case DRAKE_BREATH:
+ return config.isDrakeEnabled();
+ case CERB_FIRE:
+ return config.isCerbFireEnabled();
}
return false;
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blackjack/BlackjackPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/blackjack/BlackjackPlugin.java
new file mode 100644
index 0000000000..dd71c6e89b
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/blackjack/BlackjackPlugin.java
@@ -0,0 +1,132 @@
+/*
+ * 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.blackjack;
+
+import com.google.inject.Binder;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import net.runelite.api.*;
+import net.runelite.api.events.ChatMessage;
+import net.runelite.api.events.GameTick;
+import net.runelite.api.events.MenuEntryAdded;
+import net.runelite.client.eventbus.Subscribe;
+import net.runelite.client.plugins.Plugin;
+import net.runelite.client.plugins.PluginDescriptor;
+import net.runelite.client.plugins.PluginType;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Authors gazivodag longstreet
+ */
+@PluginDescriptor(
+ name = "Blackjack",
+ description = "Uses chat messages and tick timers instead of animations to read",
+ tags = {"blackjack", "thieving"},
+ type = PluginType.UTILITY
+)
+@Singleton
+@Slf4j
+public class BlackjackPlugin extends Plugin {
+
+ @Inject
+ Client client;
+
+ private static long timeSinceKnockout;
+ private static long timeSinceAggro;
+
+ @Getter
+ private static long currentGameTick;
+
+ @Override
+ public void configure(Binder binder) {
+ }
+
+ @Override
+ protected void startUp() throws Exception {
+ currentGameTick = 0;
+ }
+
+ @Override
+ protected void shutDown() throws Exception {
+ currentGameTick = 0;
+ }
+
+ @Subscribe
+ public void onGameTick(GameTick gameTick) {
+ currentGameTick++;
+ }
+
+
+ @Subscribe
+ public void onChatMessage(ChatMessage chatMessage) {
+ if (chatMessage.getType() == ChatMessageType.SPAM) {
+ if (chatMessage.getMessage().equals("You smack the bandit over the head and render them unconscious.")) {
+ timeSinceKnockout = getCurrentGameTick();
+ }
+ if (chatMessage.getMessage().equals("Your blow only glances off the bandit's head.")) {
+ timeSinceAggro = getCurrentGameTick();
+ }
+ }
+ }
+
+ @Subscribe
+ public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) {
+ String target = menuEntryAdded.getTarget().toLowerCase();
+ if ((target.contains("bandit") | target.contains("menaphite thug"))) {
+ Quest quest = Quest.THE_FEUD;
+ if (quest.getState(client) == QuestState.FINISHED) {
+ if (currentGameTick < (timeSinceKnockout + 4)) {
+ stripSpecificEntries("pickpocket");
+ }
+ if (currentGameTick < (timeSinceAggro + 4)) {
+ stripSpecificEntries("pickpocket");
+ }
+ stripSpecificEntries("knock-out");
+ }
+ }
+ }
+
+ private void stripSpecificEntries(String exceptFor) {
+ MenuEntry[] currentEntires = client.getMenuEntries();
+ MenuEntry[] newEntries = new MenuEntry[2];
+
+ for (MenuEntry currentEntry : currentEntires) {
+ if (currentEntry.getOption().toLowerCase().equals(exceptFor.toLowerCase())) {
+ newEntries[1] = currentEntry;
+ }
+ if (currentEntry.getOption().toLowerCase().equals("lure")) {
+ newEntries[0] = currentEntry;
+ }
+ }
+
+ if (newEntries[0] != null && newEntries[1] != null) {
+ client.setMenuEntries(newEntries);
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java
index 388ebb300a..44ff821be8 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java
@@ -70,6 +70,8 @@ import net.runelite.http.api.hiscore.HiscoreSkill;
import net.runelite.http.api.hiscore.SingleHiscoreSkillResult;
import net.runelite.http.api.hiscore.Skill;
import net.runelite.http.api.item.ItemPrice;
+import net.runelite.http.api.osbuddy.OSBGrandExchangeClient;
+import net.runelite.http.api.osbuddy.OSBGrandExchangeResult;
import org.apache.commons.text.WordUtils;
@PluginDescriptor(
@@ -98,6 +100,7 @@ public class ChatCommandsPlugin extends Plugin
private final HiscoreClient hiscoreClient = new HiscoreClient();
private final ChatClient chatClient = new ChatClient();
+ private final OSBGrandExchangeClient CLIENT = new OSBGrandExchangeClient();
private boolean logKills;
private HiscoreEndpoint hiscoreEndpoint; // hiscore endpoint for current player
@@ -597,19 +600,31 @@ public class ChatCommandsPlugin extends Plugin
if (!results.isEmpty())
{
ItemPrice item = retrieveFromList(results, search);
+ OSBGrandExchangeResult osbresult = new OSBGrandExchangeResult();
+ try
+ {
+ osbresult = CLIENT.lookupItem(item.getId());
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
int itemId = item.getId();
int itemPrice = item.getPrice();
- final ChatMessageBuilder builder = new ChatMessageBuilder()
- .append(ChatColorType.NORMAL)
- .append("Price of ")
- .append(ChatColorType.HIGHLIGHT)
- .append(item.getName())
- .append(ChatColorType.NORMAL)
- .append(": GE average ")
- .append(ChatColorType.HIGHLIGHT)
- .append(StackFormatter.formatNumber(itemPrice));
+ final ChatMessageBuilder builder = new ChatMessageBuilder();
+ builder.append(ChatColorType.NORMAL);
+ builder.append(ChatColorType.HIGHLIGHT);
+ builder.append(item.getName());
+ builder.append(ChatColorType.NORMAL);
+ builder.append(": GE ");
+ builder.append(ChatColorType.HIGHLIGHT);
+ builder.append(StackFormatter.formatNumber(itemPrice));
+ builder.append(ChatColorType.NORMAL);
+ builder.append(": OSB ");
+ builder.append(ChatColorType.HIGHLIGHT);
+ builder.append(StackFormatter.formatNumber(osbresult.getOverall_average()));
ItemComposition itemComposition = itemManager.getItemComposition(itemId);
if (itemComposition != null)
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java
index 1ec94fad94..8e2f32f2ba 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java
@@ -1,420 +1,633 @@
+/*
+ * Copyright (c) 2017, Devin French
+ * Copyright (c) 2019, Adam
+ * Copyright (c) 2018, trimbe
+ * 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.clanchat;
-import net.runelite.client.plugins.*;
-import net.runelite.client.game.*;
-import net.runelite.client.callback.*;
-
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.inject.Provides;
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.*;
-import net.runelite.client.config.*;
-import com.google.inject.*;
-import net.runelite.client.util.*;
-import net.runelite.client.eventbus.*;
-import com.google.common.base.*;
-import net.runelite.api.widgets.*;
-import net.runelite.client.ui.*;
-import net.runelite.client.chat.*;
-import java.awt.*;
-import net.runelite.api.*;
-import net.runelite.api.events.*;
-import com.google.common.collect.*;
-import java.util.*;
-import java.util.function.*;
-import net.runelite.client.ui.overlay.infobox.*;
-import java.awt.image.*;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import javax.inject.Inject;
+import net.runelite.api.ChatLineBuffer;
+import net.runelite.api.ChatMessageType;
+import net.runelite.api.ClanMember;
+import net.runelite.api.ClanMemberRank;
+import net.runelite.api.Client;
+import net.runelite.api.GameState;
+import net.runelite.api.MessageNode;
+import net.runelite.api.Opcodes;
+import net.runelite.api.Player;
+import net.runelite.api.Script;
+import net.runelite.api.ScriptID;
+import net.runelite.api.SpriteID;
+import net.runelite.api.VarClientStr;
+import net.runelite.api.Varbits;
+import net.runelite.api.events.ChatMessage;
+import net.runelite.api.events.ClanChanged;
+import net.runelite.api.events.ClanMemberJoined;
+import net.runelite.api.events.ClanMemberLeft;
+import net.runelite.api.events.ConfigChanged;
+import net.runelite.api.events.GameStateChanged;
+import net.runelite.api.events.GameTick;
+import net.runelite.api.events.PlayerDespawned;
+import net.runelite.api.events.PlayerSpawned;
+import net.runelite.api.events.ScriptCallbackEvent;
+import net.runelite.api.events.VarClientStrChanged;
+import net.runelite.api.events.WidgetMenuOptionClicked;
+import net.runelite.api.widgets.JavaScriptCallback;
+import net.runelite.api.widgets.Widget;
+import net.runelite.api.widgets.WidgetInfo;
+import net.runelite.api.widgets.WidgetType;
+import net.runelite.client.callback.ClientThread;
+import net.runelite.client.chat.ChatMessageBuilder;
+import net.runelite.client.config.ConfigManager;
+import net.runelite.client.eventbus.Subscribe;
+import net.runelite.client.game.ClanManager;
+import net.runelite.client.game.SpriteManager;
+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 static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND;
+import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND;
+import static net.runelite.client.ui.JagexColors.CHAT_CLAN_TEXT_OPAQUE_BACKGROUND;
+import static net.runelite.client.ui.JagexColors.CHAT_CLAN_TEXT_TRANSPARENT_BACKGROUND;
+import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
+import net.runelite.client.util.Text;
-@PluginDescriptor(name = "Clan Chat", description = "Add rank icons to users talking in clan chat", tags = { "icons", "rank", "recent" })
+@PluginDescriptor(
+ name = "Clan Chat",
+ description = "Add rank icons to users talking in clan chat",
+ tags = {"icons", "rank", "recent"}
+)
public class ClanChatPlugin extends Plugin
{
- private static final int MAX_CHATS = 10;
+ private static final int MAX_CHATS = 20;
private static final String CLAN_CHAT_TITLE = "CC";
private static final String RECENT_TITLE = "Recent CCs";
private static final int JOIN_LEAVE_DURATION = 20;
private static final int MESSAGE_DELAY = 10;
+
@Inject
private Client client;
+
@Inject
private ClanManager clanManager;
+
@Inject
private ClanChatConfig config;
+
@Inject
private InfoBoxManager infoBoxManager;
+
@Inject
private SpriteManager spriteManager;
+
@Inject
private ClientThread clientThread;
- private List chats;
- private static CopyOnWriteArrayList clanMembers;
+
+ @Inject
+ private MenuManager menuManager;
+
+ private List chats = new ArrayList<>();
+
+ public static CopyOnWriteArrayList getClanMembers()
+ {
+ return (CopyOnWriteArrayList) clanMembers.clone();
+ }
+
+ private static CopyOnWriteArrayList clanMembers = new CopyOnWriteArrayList<>();
private ClanChatIndicator clanMemberCounter;
- private final Deque clanJoinMessages;
- private Map activityBuffer;
+ /**
+ * queue of temporary messages added to the client
+ */
+ private final Deque clanJoinMessages = new ArrayDeque<>();
+ private Map activityBuffer = new HashMap<>();
private int clanJoinedTick;
- public ClanChatPlugin() {
- this.chats = new ArrayList();
- this.clanJoinMessages = new ArrayDeque();
- this.activityBuffer = new HashMap();
- }
-
- public static CopyOnWriteArrayList getClanMembers() {
- return (CopyOnWriteArrayList)ClanChatPlugin.clanMembers.clone();
- }
+ private ConcurrentHashMap ccWidgetMap = new ConcurrentHashMap();
@Provides
- ClanChatConfig getConfig(final ConfigManager configManager) {
+ ClanChatConfig getConfig(ConfigManager configManager)
+ {
return configManager.getConfig(ClanChatConfig.class);
}
- public void startUp() {
- this.chats = new ArrayList(Text.fromCSV(this.config.chatsData()));
+ @Override
+ public void startUp()
+ {
+ chats = new ArrayList<>(Text.fromCSV(config.chatsData()));
}
- public void shutDown() {
- ClanChatPlugin.clanMembers.clear();
- this.removeClanCounter();
- this.resetClanChats();
+ @Override
+ public void shutDown()
+ {
+ clanMembers.clear();
+ removeClanCounter();
+ resetClanChats();
}
@Subscribe
- public void onConfigChanged(final ConfigChanged configChanged) {
- if (configChanged.getGroup().equals("clanchat")) {
- if (!this.config.recentChats()) {
- this.resetClanChats();
+ public void onConfigChanged(ConfigChanged configChanged)
+ {
+ if (configChanged.getGroup().equals("clanchat"))
+ {
+ if (!config.recentChats())
+ {
+ resetClanChats();
}
- if (this.config.showClanCounter()) {
- this.clientThread.invoke(this::addClanCounter);
+
+ if (config.showClanCounter())
+ {
+ clientThread.invoke(this::addClanCounter);
}
- else {
- this.removeClanCounter();
+ else
+ {
+ removeClanCounter();
}
}
}
- @Subscribe
- public void onClanMemberJoined(ClanMemberJoined event)
- {
- final ClanMember member = event.getMember();
-
- if (member.getWorld() == client.getWorld())
- {
- final Player local = client.getLocalPlayer();
- final String memberName = Text.toJagexName(member.getUsername());
-
- for (final Player player : client.getPlayers())
- {
- if (player != null && player != local && memberName.equals(Text.toJagexName(player.getName())))
- {
- clanMembers.add(player);
- addClanCounter();
- break;
- }
- }
- }
-
- if (this.clanJoinedTick == this.client.getTickCount()) {
- return;
- }
- if (!this.config.showJoinLeave() || member.getRank().getValue() < this.config.joinLeaveRank().getValue()) {
- return;
- }
- if (!this.activityBuffer.containsKey(member.getUsername())) {
- final ClanMemberActivity joinActivity = new ClanMemberActivity(ClanActivityType.JOINED, member, this.client.getTickCount());
- this.activityBuffer.put(member.getUsername(), joinActivity);
- }
- else {
- this.activityBuffer.remove(member.getUsername());
- }
- }
-
@Subscribe
- public void onClanMemberLeft(final ClanMemberLeft event) {
+ public void onClanMemberJoined(ClanMemberJoined event)
+ {
final ClanMember member = event.getMember();
- if (member.getWorld() == this.client.getWorld()) {
+
+ if (member.getWorld() == client.getWorld())
+ {
+ final Player local = client.getLocalPlayer();
final String memberName = Text.toJagexName(member.getUsername());
- final Iterator each = ClanChatPlugin.clanMembers.iterator();
- while (each.hasNext()) {
- if (memberName.equals(Text.toJagexName(each.next().getName()))) {
- each.remove();
- if (ClanChatPlugin.clanMembers.isEmpty()) {
- this.removeClanCounter();
- break;
- }
+
+ for (final Player player : client.getPlayers())
+ {
+ if (player != null && player != local && memberName.equals(Text.toJagexName(player.getName())))
+ {
+ clanMembers.add(player);
+ addClanCounter();
break;
}
}
}
- if (!this.config.showJoinLeave() || member.getRank().getValue() < this.config.joinLeaveRank().getValue()) {
+
+ // clan members getting initialized isn't relevant
+ if (clanJoinedTick == client.getTickCount())
+ {
return;
}
- if (!this.activityBuffer.containsKey(member.getUsername())) {
- final ClanMemberActivity leaveActivity = new ClanMemberActivity(ClanActivityType.LEFT, member, this.client.getTickCount());
- this.activityBuffer.put(member.getUsername(), leaveActivity);
+
+ if (!config.showJoinLeave() ||
+ member.getRank().getValue() < config.joinLeaveRank().getValue())
+ {
+ return;
}
- else {
- this.activityBuffer.remove(member.getUsername());
+
+ // attempt to filter out world hopping joins
+ if (!activityBuffer.containsKey(member.getUsername()))
+ {
+ ClanMemberActivity joinActivity = new ClanMemberActivity(ClanActivityType.JOINED,
+ member, client.getTickCount());
+ activityBuffer.put(member.getUsername(), joinActivity);
+ }
+ else
+ {
+ activityBuffer.remove(member.getUsername());
}
}
@Subscribe
- public void onGameTick(final GameTick gameTick) {
- if (this.client.getGameState() != GameState.LOGGED_IN) {
- return;
- }
- final Widget clanChatTitleWidget = this.client.getWidget(WidgetInfo.CLAN_CHAT_TITLE);
- if (clanChatTitleWidget != null) {
- final Widget clanChatList = this.client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
- final Widget owner = this.client.getWidget(WidgetInfo.CLAN_CHAT_OWNER);
- if (this.client.getClanChatCount() > 0) {
- clanChatTitleWidget.setText("Clan Chat (" + this.client.getClanChatCount() + "/100)");
- }
- else if (this.config.recentChats() && clanChatList.getChildren() == null && !Strings.isNullOrEmpty(owner.getText())) {
- clanChatTitleWidget.setText("Recent Clan Chats");
- this.loadClanChats();
+ public void onClanMemberLeft(ClanMemberLeft event)
+ {
+ final ClanMember member = event.getMember();
+
+ if (member.getWorld() == client.getWorld())
+ {
+ final String memberName = Text.toJagexName(member.getUsername());
+ final Iterator each = clanMembers.iterator();
+
+ while (each.hasNext())
+ {
+ if (memberName.equals(Text.toJagexName(each.next().getName())))
+ {
+ each.remove();
+
+ if (clanMembers.isEmpty())
+ {
+ removeClanCounter();
+ }
+
+ break;
+ }
}
}
- if (!this.config.showJoinLeave()) {
+
+ if (!config.showJoinLeave() ||
+ member.getRank().getValue() < config.joinLeaveRank().getValue())
+ {
return;
}
- this.timeoutClanMessages();
- this.addClanActivityMessages();
+
+ if (!activityBuffer.containsKey(member.getUsername()))
+ {
+ ClanMemberActivity leaveActivity = new ClanMemberActivity(ClanActivityType.LEFT,
+ member, client.getTickCount());
+ activityBuffer.put(member.getUsername(), leaveActivity);
+ }
+ else
+ {
+ activityBuffer.remove(member.getUsername());
+ }
}
- private void timeoutClanMessages() {
- if (this.clanJoinMessages.isEmpty()) {
+ @Subscribe
+ public void onGameTick(GameTick gameTick)
+ {
+ if (client.getGameState() != GameState.LOGGED_IN)
+ {
return;
}
+
+ Widget clanChatTitleWidget = client.getWidget(WidgetInfo.CLAN_CHAT_TITLE);
+ if (clanChatTitleWidget != null)
+ {
+ Widget clanChatList = client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
+ Widget owner = client.getWidget(WidgetInfo.CLAN_CHAT_OWNER);
+ if (client.getClanChatCount() > 0)
+ {
+ clanChatTitleWidget.setText(CLAN_CHAT_TITLE + " (" + client.getClanChatCount() + "/100)");
+ }
+ else if (config.recentChats() && clanChatList.getChildren() == null && !Strings.isNullOrEmpty(owner.getText()))
+ {
+ clanChatTitleWidget.setText(RECENT_TITLE);
+
+ loadClanChats();
+ }
+ }
+
+ if (!config.showJoinLeave())
+ {
+ return;
+ }
+
+ timeoutClanMessages();
+
+ addClanActivityMessages();
+ }
+
+ private void timeoutClanMessages()
+ {
+ if (clanJoinMessages.isEmpty())
+ {
+ return;
+ }
+
boolean removed = false;
- final Iterator it = this.clanJoinMessages.iterator();
- while (it.hasNext()) {
- final ClanJoinMessage clanJoinMessage = it.next();
- final MessageNode messageNode = clanJoinMessage.getMessageNode();
+
+ for (Iterator it = clanJoinMessages.iterator(); it.hasNext(); )
+ {
+ ClanJoinMessage clanJoinMessage = it.next();
+ MessageNode messageNode = clanJoinMessage.getMessageNode();
final int createdTick = clanJoinMessage.getTick();
- if (this.client.getTickCount() <= createdTick + 20) {
+
+ if (client.getTickCount() > createdTick + JOIN_LEAVE_DURATION)
+ {
+ it.remove();
+
+ // If this message has been reused since, it will get a different id
+ if (clanJoinMessage.getGetMessageId() == messageNode.getId())
+ {
+ ChatLineBuffer ccInfoBuffer = client.getChatLineMap().get(ChatMessageType.FRIENDSCHATNOTIFICATION.getType());
+ if (ccInfoBuffer != null)
+ {
+ ccInfoBuffer.removeMessageNode(messageNode);
+ removed = true;
+ }
+ }
+ }
+ else
+ {
+ // Everything else in the deque is newer
break;
}
- it.remove();
- if (clanJoinMessage.getGetMessageId() != messageNode.getId()) {
- continue;
- }
- final ChatLineBuffer ccInfoBuffer = this.client.getChatLineMap().get(ChatMessageType.FRIENDSCHATNOTIFICATION.getType());
- if (ccInfoBuffer == null) {
- continue;
- }
- ccInfoBuffer.removeMessageNode(messageNode);
- removed = true;
}
- if (removed) {
- this.clientThread.invoke(() -> this.client.runScript(216, new Object[0]));
+
+ if (removed)
+ {
+ clientThread.invoke(() -> client.runScript(ScriptID.BUILD_CHATBOX));
}
}
- private void addClanActivityMessages() {
- final Iterator activityIt = this.activityBuffer.values().iterator();
- while (activityIt.hasNext()) {
- final ClanMemberActivity activity = activityIt.next();
- if (activity.getTick() < this.client.getTickCount() - 10) {
+ private void addClanActivityMessages()
+ {
+ Iterator activityIt = activityBuffer.values().iterator();
+
+ while (activityIt.hasNext())
+ {
+ ClanMemberActivity activity = activityIt.next();
+
+ if (activity.getTick() < client.getTickCount() - MESSAGE_DELAY)
+ {
activityIt.remove();
- this.addActivityMessage(activity.getMember(), activity.getActivityType());
+ addActivityMessage(activity.getMember(), activity.getActivityType());
}
}
}
- private void addActivityMessage(final ClanMember member, final ClanActivityType activityType) {
- final String activityMessage = (activityType == ClanActivityType.JOINED) ? " has joined." : " has left.";
+ private void addActivityMessage(ClanMember member, ClanActivityType activityType)
+ {
+ final String activityMessage = activityType == ClanActivityType.JOINED ? " has joined." : " has left.";
final ClanMemberRank rank = member.getRank();
- Color textColor = JagexColors.CHAT_CLAN_TEXT_OPAQUE_BACKGROUND;
- Color channelColor = JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND;
+ Color textColor = CHAT_CLAN_TEXT_OPAQUE_BACKGROUND;
+ Color channelColor = CHAT_CLAN_NAME_OPAQUE_BACKGROUND;
int rankIcon = -1;
- if (this.client.isResized() && this.client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1) {
- textColor = JagexColors.CHAT_CLAN_TEXT_TRANSPARENT_BACKGROUND;
- channelColor = JagexColors.CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND;
+
+ if (client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1)
+ {
+ textColor = CHAT_CLAN_TEXT_TRANSPARENT_BACKGROUND;
+ channelColor = CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND;
}
- if (this.config.clanChatIcons() && rank != null && rank != ClanMemberRank.UNRANKED) {
- rankIcon = this.clanManager.getIconNumber(rank);
+
+ if (config.clanChatIcons() && rank != null && rank != ClanMemberRank.UNRANKED)
+ {
+ rankIcon = clanManager.getIconNumber(rank);
}
- final ChatMessageBuilder message = new ChatMessageBuilder().append("[").append(channelColor, this.client.getClanChatName());
- if (rankIcon > -1) {
- message.append(" ").img(rankIcon);
+
+ ChatMessageBuilder message = new ChatMessageBuilder()
+ .append("[")
+ .append(channelColor, client.getClanChatName());
+ if (rankIcon > -1)
+ {
+ message
+ .append(" ")
+ .img(rankIcon);
}
- message.append("] ").append(textColor, member.getUsername() + activityMessage);
+ message
+ .append("] ")
+ .append(textColor, member.getUsername() + activityMessage);
+
final String messageString = message.build();
- this.client.addChatMessage(ChatMessageType.FRIENDSCHATNOTIFICATION, "", messageString, "");
- final ChatLineBuffer chatLineBuffer = this.client.getChatLineMap().get(ChatMessageType.FRIENDSCHATNOTIFICATION.getType());
+ client.addChatMessage(ChatMessageType.FRIENDSCHATNOTIFICATION, "", messageString, "");
+
+ final ChatLineBuffer chatLineBuffer = client.getChatLineMap().get(ChatMessageType.FRIENDSCHATNOTIFICATION.getType());
final MessageNode[] lines = chatLineBuffer.getLines();
final MessageNode line = lines[0];
- final ClanJoinMessage clanJoinMessage = new ClanJoinMessage(line, line.getId(), this.client.getTickCount());
- this.clanJoinMessages.addLast(clanJoinMessage);
+
+ ClanJoinMessage clanJoinMessage = new ClanJoinMessage(line, line.getId(), client.getTickCount());
+ clanJoinMessages.addLast(clanJoinMessage);
}
@Subscribe
- public void onVarClientStrChanged(final VarClientStrChanged strChanged) {
- if (strChanged.getIndex() == VarClientStr.RECENT_CLAN_CHAT.getIndex() && this.config.recentChats()) {
- this.updateRecentChat(this.client.getVar(VarClientStr.RECENT_CLAN_CHAT));
+ public void onVarClientStrChanged(VarClientStrChanged strChanged)
+ {
+ if (strChanged.getIndex() == VarClientStr.RECENT_CLAN_CHAT.getIndex() && config.recentChats())
+ {
+ updateRecentChat(client.getVar(VarClientStr.RECENT_CLAN_CHAT));
}
}
@Subscribe
- public void onChatMessage(final ChatMessage chatMessage) {
- if (this.client.getGameState() != GameState.LOADING && this.client.getGameState() != GameState.LOGGED_IN) {
+ public void onChatMessage(ChatMessage chatMessage)
+ {
+ if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN)
+ {
return;
}
- if (this.client.getClanChatCount() <= 0) {
+
+ if (client.getClanChatCount() <= 0)
+ {
return;
}
- switch (chatMessage.getType()) {
+
+ switch (chatMessage.getType())
+ {
case PRIVATECHAT:
- case MODPRIVATECHAT: {
- if (!this.config.privateMessageIcons()) {
+ case MODPRIVATECHAT:
+ if (!config.privateMessageIcons())
+ {
return;
}
break;
- }
case PUBLICCHAT:
- case MODCHAT: {
- if (!this.config.publicChatIcons()) {
+ case MODCHAT:
+ if (!config.publicChatIcons())
+ {
return;
}
break;
- }
- case FRIENDSCHAT: {
- if (!this.config.clanChatIcons()) {
+ case FRIENDSCHAT:
+ if (!config.clanChatIcons())
+ {
return;
}
break;
- }
- default: {
+ default:
return;
- }
}
- this.insertClanRankIcon(chatMessage);
+
+ insertClanRankIcon(chatMessage);
}
@Subscribe
- public void onGameStateChanged(final GameStateChanged state) {
- final GameState gameState = state.getGameState();
- if (gameState == GameState.LOGIN_SCREEN || gameState == GameState.CONNECTION_LOST || gameState == GameState.HOPPING) {
- ClanChatPlugin.clanMembers.clear();
- this.removeClanCounter();
- this.clanJoinMessages.clear();
- }
- }
+ public void onGameStateChanged(GameStateChanged state)
+ {
+ GameState gameState = state.getGameState();
- @Subscribe
- public void onPlayerSpawned(PlayerSpawned event)
- {
- final Player local = client.getLocalPlayer();
- final Player player = event.getPlayer();
+ if (gameState == GameState.LOGIN_SCREEN || gameState == GameState.CONNECTION_LOST || gameState == GameState.HOPPING)
+ {
+ clanMembers.clear();
+ removeClanCounter();
- if (player != local && player.isClanMember())
- {
- clanMembers.add(player);
- addClanCounter();
- }
- }
-
- @Subscribe
- public void onPlayerDespawned(final PlayerDespawned event) {
- if (ClanChatPlugin.clanMembers.remove(event.getPlayer()) && ClanChatPlugin.clanMembers.isEmpty()) {
- this.removeClanCounter();
+ clanJoinMessages.clear();
}
}
@Subscribe
- public void onClanChanged(final ClanChanged event) {
- if (event.isJoined()) {
- this.clanJoinedTick = this.client.getTickCount();
+ public void onPlayerSpawned(PlayerSpawned event)
+ {
+ final Player local = client.getLocalPlayer();
+ final Player player = event.getPlayer();
+
+ if (player != local && player.isClanMember())
+ {
+ clanMembers.add(player);
+ addClanCounter();
}
- else {
- ClanChatPlugin.clanMembers.clear();
- this.removeClanCounter();
- }
- this.activityBuffer.clear();
}
- int getClanAmount() {
- return ClanChatPlugin.clanMembers.size();
+ @Subscribe
+ public void onPlayerDespawned(PlayerDespawned event)
+ {
+ if (clanMembers.remove(event.getPlayer()) && clanMembers.isEmpty())
+ {
+ removeClanCounter();
+ }
}
- private void insertClanRankIcon(final ChatMessage message) {
- final ClanMemberRank rank = this.clanManager.getRank(message.getName());
- if (rank != null && rank != ClanMemberRank.UNRANKED) {
- final int iconNumber = this.clanManager.getIconNumber(rank);
+ @Subscribe
+ public void onClanChanged(ClanChanged event)
+ {
+ if (event.isJoined())
+ {
+ clanJoinedTick = client.getTickCount();
+ }
+ else
+ {
+ clanMembers.clear();
+ removeClanCounter();
+ }
+
+ activityBuffer.clear();
+ }
+
+ int getClanAmount()
+ {
+ return clanMembers.size();
+ }
+
+ private void insertClanRankIcon(final ChatMessage message)
+ {
+ final ClanMemberRank rank = clanManager.getRank(message.getName());
+
+ if (rank != null && rank != ClanMemberRank.UNRANKED)
+ {
+ int iconNumber = clanManager.getIconNumber(rank);
final String img = "
";
- if (message.getType() == ChatMessageType.FRIENDSCHAT) {
- message.getMessageNode().setSender(message.getMessageNode().getSender() + " " + img);
+ if (message.getType() == ChatMessageType.FRIENDSCHAT)
+ {
+ message.getMessageNode()
+ .setSender(message.getMessageNode().getSender() + " " + img);
}
- else {
- message.getMessageNode().setName(img + message.getMessageNode().getName());
+ else
+ {
+ message.getMessageNode()
+ .setName(img + message.getMessageNode().getName());
}
- this.client.refreshChat();
+ client.refreshChat();
}
}
- private void resetClanChats() {
- final Widget clanChatList = this.client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
- final Widget clanChatTitleWidget = this.client.getWidget(WidgetInfo.CLAN_CHAT_TITLE);
- if (clanChatList == null) {
+
+ private void resetClanChats()
+ {
+ Widget clanChatList = client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
+ Widget clanChatTitleWidget = client.getWidget(WidgetInfo.CLAN_CHAT_TITLE);
+
+ if (clanChatList == null)
+ {
return;
}
- if (this.client.getClanChatCount() == 0) {
+
+ if (client.getClanChatCount() == 0)
+ {
clanChatList.setChildren(null);
}
- clanChatTitleWidget.setText("Clan Chat");
+
+ clanChatTitleWidget.setText(CLAN_CHAT_TITLE);
}
- private void loadClanChats() {
- final Widget clanChatList = this.client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
- if (clanChatList == null) {
+ private void loadClanChats()
+ {
+ Widget clanChatList = client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
+ clanChatList.setScrollHeight( 14 * chats.size());
+ clanChatList.revalidateScroll();
+ if (clanChatList == null)
+ {
return;
}
+
int y = 2;
clanChatList.setChildren(null);
- for (final String chat : Lists.reverse(this.chats)) {
- final Widget widget = clanChatList.createChild(-1, 4);
+ for (String chat : Lists.reverse(chats))
+ {
+ Widget widget = clanChatList.createChild(-1, WidgetType.TEXT);
widget.setFontId(494);
- widget.setTextColor(16777215);
+ widget.setHasListener(true);
+
+ widget.setTextColor(0xffffff);
widget.setText(chat);
+ widget.setTextShadowed(true);
+ widget.setBorderType(1);
+ widget.setAction(0, "Join");
+ widget.setOnOpListener(ScriptID.FORCE_JOIN_CC, widget.getText());
widget.setOriginalHeight(14);
widget.setOriginalWidth(142);
widget.setOriginalY(y);
widget.setOriginalX(20);
widget.revalidate();
+
y += 14;
}
+ clanChatList.revalidateScroll();
}
- private void updateRecentChat(String s) {
- if (Strings.isNullOrEmpty(s)) {
+ private void updateRecentChat(String s)
+ {
+ if (Strings.isNullOrEmpty(s))
+ {
return;
}
+
s = Text.toJagexName(s);
- final List chats = this.chats;
- final String s2 = s;
- Objects.requireNonNull(s2);
- chats.removeIf(s2::equalsIgnoreCase);
- this.chats.add(s);
- while (this.chats.size() > 10) {
- this.chats.remove(0);
+
+ chats.removeIf(s::equalsIgnoreCase);
+ chats.add(s);
+
+ while (chats.size() > MAX_CHATS)
+ {
+ chats.remove(0);
}
- this.config.chatsData(Text.toCSV(this.chats));
+
+ config.chatsData(Text.toCSV(chats));
}
- private void removeClanCounter() {
- this.infoBoxManager.removeInfoBox(this.clanMemberCounter);
- this.clanMemberCounter = null;
+ private void removeClanCounter()
+ {
+ infoBoxManager.removeInfoBox(clanMemberCounter);
+ clanMemberCounter = null;
}
- private void addClanCounter() {
- if (!this.config.showClanCounter() || this.clanMemberCounter != null || ClanChatPlugin.clanMembers.isEmpty()) {
+ private void addClanCounter()
+ {
+ if (!config.showClanCounter() || clanMemberCounter != null || clanMembers.isEmpty())
+ {
return;
}
- final BufferedImage image = this.spriteManager.getSprite(904, 0);
- this.clanMemberCounter = new ClanChatIndicator(image, this);
- this.infoBoxManager.addInfoBox(this.clanMemberCounter);
- }
- static {
- ClanChatPlugin.clanMembers = new CopyOnWriteArrayList();
+ final BufferedImage image = spriteManager.getSprite(SpriteID.TAB_CLAN_CHAT, 0);
+ clanMemberCounter = new ClanChatIndicator(image, this);
+ infoBoxManager.addInfoBox(clanMemberCounter);
}
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetField.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetField.java
index a4b21cb94d..ade94fa6f6 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetField.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetField.java
@@ -88,6 +88,7 @@ public class WidgetField
}
else
{
+ setter.accept(widget, (T) value);
log.warn("Type {} is not supported for editing", type);
}
setter.accept(widget, (T) value);
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java
index 1f78bddb9f..936d814725 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java
@@ -26,6 +26,7 @@ package net.runelite.client.plugins.examine;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
+import java.io.IOException;
import java.time.Instant;
import java.util.ArrayDeque;
import java.util.Deque;
@@ -54,6 +55,8 @@ import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.StackFormatter;
import net.runelite.http.api.examine.ExamineClient;
+import net.runelite.http.api.osbuddy.OSBGrandExchangeClient;
+import net.runelite.http.api.osbuddy.OSBGrandExchangeResult;
/**
* Submits examine info to the api
@@ -72,6 +75,7 @@ public class ExaminePlugin extends Plugin
private static final Pattern X_PATTERN = Pattern.compile("^\\d+ x ");
private final Deque pending = new ArrayDeque<>();
+ private final OSBGrandExchangeClient CLIENT = new OSBGrandExchangeClient();
private final Cache cache = CacheBuilder.newBuilder()
.maximumSize(128L)
.build();
@@ -342,11 +346,24 @@ public class ExaminePlugin extends Plugin
if (gePrice > 0)
{
+ OSBGrandExchangeResult osbresult = new OSBGrandExchangeResult();
+ try
+ {
+ osbresult = CLIENT.lookupItem(itemComposition.getId());
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
message
.append(ChatColorType.NORMAL)
- .append(" GE average ")
+ .append(" GE ")
.append(ChatColorType.HIGHLIGHT)
- .append(StackFormatter.formatNumber(gePrice * quantity));
+ .append(StackFormatter.formatNumber(gePrice * quantity))
+ .append(ChatColorType.NORMAL)
+ .append(" OSB ")
+ .append(ChatColorType.HIGHLIGHT)
+ .append(StackFormatter.formatNumber(osbresult.getOverall_average() * quantity));
if (quantity > 1)
{
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java
index 441af6adab..66a9fb0477 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java
@@ -53,6 +53,7 @@ import net.runelite.client.plugins.PluginType;
import net.runelite.client.plugins.grounditems.GroundItem;
import net.runelite.client.plugins.grounditems.GroundItemsPlugin;
import net.runelite.client.plugins.stretchedmode.StretchedModeConfig;
+import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.overlay.OverlayManager;
import javax.inject.Inject;
@@ -80,6 +81,9 @@ public class FlexoPlugin extends Plugin {
@Inject
private Client client;
+
+ @Inject
+ private ClientUI clientUI;
@Inject
private ConfigManager configManager;
@@ -112,6 +116,8 @@ public class FlexoPlugin extends Plugin {
public void onBeforeRender(BeforeRender event) {
if (Flexo.client==null)
Flexo.client = client;
+ if (Flexo.clientUI==null)
+ Flexo.clientUI = clientUI;
overlay.clickAreas = new ArrayList<>();
overlay.clickPoints = new ArrayList<>();
if (getConfig(configManager).getDebugNPCs()) {
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingConfig.java
new file mode 100644
index 0000000000..a178d3ad5b
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingConfig.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2018, Fluffeh
+ * 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.flinching;
+
+import java.awt.Color;
+import net.runelite.client.config.Config;
+import net.runelite.client.config.ConfigGroup;
+import net.runelite.client.config.ConfigItem;
+
+@ConfigGroup("flinching")
+public interface FlinchingConfig extends Config
+{
+ @ConfigItem(
+
+ position = 0,
+ keyName = "hexColorFlinch",
+ name = "Overlay Color",
+ description = "Color of flinching timer overlay"
+ )
+ default Color getFlinchOverlayColor()
+ {
+ return Color.CYAN;
+ }
+
+ @ConfigItem(
+
+ position = 1,
+ keyName = "flinchOverlaySize",
+ name = "Overlay Diameter",
+ description = "Flinch overlay timer diameter"
+ )
+ default int getFlinchOverlaySize()
+ {
+ return 30;
+ }
+
+ @ConfigItem(
+
+ position = 2,
+ keyName = "flinchDelay",
+ name = "Flinch Timer Delay",
+ description = "Shows the appropriate time to attack while flinching milliseconds"
+ )
+ default int getFlinchDelay()
+ {
+ return 5400;
+ }
+
+ @ConfigItem(
+
+ position = 3,
+ keyName = "flinchOnHitReceivedDelay",
+ name = "Flinch Hit Received Delay",
+ description = "Slightly longer delay after being attacked milliseconds"
+ )
+ default int getFlinchAttackedDelay()
+ {
+ return 6600;
+ }
+
+ @ConfigItem(
+
+ position = 4,
+ keyName = "flinchResetOnHit",
+ name = "Reset on Hit",
+ description = "Timer resets after every attack from your character"
+ )
+ default boolean getFlinchResetOnHit()
+ {
+ return true;
+ }
+
+ @ConfigItem(
+
+ position = 5,
+ keyName = "flinchResetOnHitReceived",
+ name = "Reset on Hit Received",
+ description = "Timer resets when your character gets attacked"
+ )
+ default boolean getFlinchResetOnHitReceived()
+ {
+ return true;
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingOverlay.java
new file mode 100644
index 0000000000..2c26db899f
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingOverlay.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018, Fluffeh
+ * 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.flinching;
+
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.util.Map;
+import javax.inject.Inject;
+import net.runelite.api.Client;
+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;
+import net.runelite.client.ui.overlay.OverlayLayer;
+import net.runelite.client.ui.overlay.OverlayPosition;
+import net.runelite.client.ui.overlay.components.ProgressPieComponent;
+
+
+public class FlinchingOverlay extends Overlay
+{
+ private final Client client;
+ private final FlinchingPlugin plugin;
+ private final FlinchingConfig config;
+
+ private Color color;
+ private Color borderColor;
+
+ private int overlaySize = 25;
+
+ @Inject
+ FlinchingOverlay(Client client, FlinchingPlugin plugin, FlinchingConfig config)
+ {
+ setPosition(OverlayPosition.DYNAMIC);
+ setLayer(OverlayLayer.ABOVE_SCENE);
+ this.plugin = plugin;
+ this.config = config;
+ this.client = client;
+
+ overlaySize = this.config.getFlinchOverlaySize();
+ }
+
+ @Override
+ public Dimension render(Graphics2D graphics)
+ {
+ drawOverlays(graphics);
+ return null;
+ }
+
+ public void updateConfig()
+ {
+ borderColor = config.getFlinchOverlayColor();
+ color = new Color(borderColor.getRed(), borderColor.getGreen(), borderColor.getBlue(), 100);
+
+ overlaySize = config.getFlinchOverlaySize();
+ }
+
+ private void drawOverlays(Graphics2D graphics)
+ {
+ for (Map.Entry entry : plugin.GetTargets().entrySet())
+ {
+ FlinchingTarget target = entry.getValue();
+
+ drawFlinchTimer(graphics, target.worldLocation, target.GetRemainingTimePercent());
+ }
+ }
+
+
+ private void drawFlinchTimer(Graphics2D graphics, WorldPoint targetLocation, double fillAmount)
+ {
+ if (targetLocation.getPlane() != client.getPlane())
+ {
+ return;
+ }
+
+ LocalPoint localLoc = LocalPoint.fromWorld(client, targetLocation);
+ if (localLoc == null)
+ {
+ return;
+ }
+
+ Point loc = Perspective.localToCanvas(client, localLoc, client.getPlane());
+
+ ProgressPieComponent pie = new ProgressPieComponent();
+ pie.setDiameter(overlaySize);
+ pie.setFill(color);
+ pie.setBorderColor(borderColor);
+ pie.setPosition(loc);
+ pie.setProgress(fillAmount);
+ pie.render(graphics);
+ }
+}
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingPlugin.java
new file mode 100644
index 0000000000..3780edce2e
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingPlugin.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2018, Fluffeh
+ * 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.flinching;
+
+import net.runelite.client.eventbus.Subscribe;
+import net.runelite.api.Client;
+import net.runelite.api.Player;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import lombok.extern.slf4j.Slf4j;
+import net.runelite.api.events.GameTick;
+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 javax.inject.Inject;
+import net.runelite.api.Actor;
+import net.runelite.api.NPC;
+import net.runelite.api.GameState;
+import net.runelite.api.events.GameStateChanged;
+import net.runelite.api.events.NpcDespawned;
+import net.runelite.client.config.ConfigManager;
+import net.runelite.api.events.ConfigChanged;
+import net.runelite.api.events.HitsplatApplied;
+import com.google.inject.Provides;
+
+
+@Slf4j
+@PluginDescriptor(
+ name = "Flinching Timer",
+ description = "Time your attacks while flinching",
+ tags = {"overlay", "flinching", "timers", "combat"},
+ enabledByDefault = false,
+ type = PluginType.PVM
+)
+public class FlinchingPlugin extends Plugin
+{
+ @Inject
+ private Client client;
+
+ @Inject
+ private OverlayManager overlayManager;
+
+ @Inject
+ private FlinchingConfig config;
+
+ @Inject
+ private FlinchingOverlay overlay;
+
+ private int currentWorld = -1;
+
+ private int currentInteractingId = -1;
+ private final Map flinchingTargets = new HashMap();
+
+ private boolean resetOnHit = true;
+ private boolean resetOnHitReceived = true;
+
+ @Provides
+ FlinchingConfig provideConfig(ConfigManager configManager)
+ {
+ return configManager.getConfig(FlinchingConfig.class);
+ }
+
+ @Override
+ protected void startUp()
+ {
+ overlayManager.add(overlay);
+
+ overlay.updateConfig();
+ resetOnHit = config.getFlinchResetOnHit();
+ resetOnHitReceived = config.getFlinchResetOnHitReceived();
+
+ ClearTargets();
+ }
+
+ @Override
+ protected void shutDown()
+ {
+ ClearTargets();
+ }
+
+ @Subscribe
+ public void onConfigChanged(ConfigChanged event)
+ {
+ if (event.getGroup().equals("flinching"))
+ {
+ overlay.updateConfig();
+ resetOnHit = config.getFlinchResetOnHit();
+ resetOnHitReceived = config.getFlinchResetOnHitReceived();
+
+ Iterator> it = flinchingTargets.entrySet().iterator();
+ while (it.hasNext())
+ {
+ FlinchingTarget target = it.next().getValue();
+ if(target != null)
+ {
+ target.SetDelayTime(config.getFlinchDelay(), config.getFlinchAttackedDelay());
+ }
+ }
+ }
+ }
+
+ @Subscribe
+ public void onGameStateChanged(GameStateChanged event)
+ {
+ if (event.getGameState() == GameState.LOGGED_IN)
+ {
+ if (currentWorld == -1)
+ {
+ currentWorld = client.getWorld();
+ }
+ else if (currentWorld != client.getWorld())
+ {
+ ClearTargets();
+ }
+ }
+ }
+
+ private void ClearTargets()
+ {
+ Iterator> it = flinchingTargets.entrySet().iterator();
+
+ while (it.hasNext())
+ {
+ it.remove();
+ }
+ }
+
+ @Subscribe
+ private void onGameTick(GameTick tick)
+ {
+ if (client.getGameState() != GameState.LOGGED_IN)
+ {
+
+ }
+ else
+ {
+ TickTargets();
+ checkInteracting();
+ }
+ }
+
+ @Subscribe
+ public void onHitsplatApplied(HitsplatApplied hitsplatApplied)
+ {
+ Actor actor = hitsplatApplied.getActor();
+
+ if (actor instanceof NPC)
+ {
+ NPC hitTarget = (NPC) actor;
+
+ int hitId = hitTarget.getId();
+ if(hitId == currentInteractingId)
+ {
+ if (!flinchingTargets.containsKey(hitId))
+ {
+ TargetGained(hitTarget);
+ }
+ else
+ {
+ FlinchingTarget currentTarget = flinchingTargets.get(hitId);
+ if(currentTarget != null)
+ {
+ if(resetOnHit)
+ {
+ currentTarget.TargetHit();
+ }
+ }
+ }
+ }
+ }
+ else if(resetOnHitReceived && actor == client.getLocalPlayer())
+ {
+ PlayerHit();
+ }
+ }
+
+ private void checkInteracting()
+ {
+ Player localPlayer = client.getLocalPlayer();
+ Actor interacting = localPlayer.getInteracting();
+
+ if (interacting instanceof NPC)
+ {
+ NPC newTarget = (NPC) interacting;
+ currentInteractingId = newTarget.getId();
+
+ if(newTarget.getHealth() <= 0 || newTarget.isDead())
+ {
+ if (flinchingTargets.containsKey(currentInteractingId))
+ {
+ flinchingTargets.remove(currentInteractingId);
+ currentInteractingId = -1;
+ }
+ }
+ }
+ }
+
+ private void TickTargets()
+ {
+ Iterator> it = flinchingTargets.entrySet().iterator();
+
+ while (it.hasNext())
+ {
+ FlinchingTarget target = it.next().getValue();
+ if(target != null)
+ {
+ target.Tick();
+ if(target.isActive == false)
+ {
+ it.remove();
+ }
+ }
+ else
+ {
+ it.remove();
+ }
+ }
+ }
+
+ @Subscribe
+ public void onNpcDespawned(NpcDespawned npcDespawned)
+ {
+ NPC actor = npcDespawned.getNpc();
+
+ int actorId = actor.getId();
+ if (actor.isDead() && flinchingTargets.containsKey(actorId))
+ {
+ TargetLost(actorId);
+ }
+ }
+
+ private void TargetLost(int targetId)
+ {
+ flinchingTargets.remove(targetId);
+ }
+
+ private void TargetGained(NPC _newTarget)
+ {
+ FlinchingTarget newTarget = new FlinchingTarget(_newTarget);
+ newTarget.SetDelayTime(config.getFlinchDelay(), config.getFlinchAttackedDelay());
+ flinchingTargets.put(_newTarget.getId(), newTarget);
+ }
+
+ public void PlayerHit()
+ {
+ Iterator> it = flinchingTargets.entrySet().iterator();
+ while (it.hasNext())
+ {
+ FlinchingTarget target = it.next().getValue();
+ if(target != null)
+ {
+ target.PlayerHit();
+ }
+ }
+ }
+
+ public Map GetTargets()
+ {
+ return(flinchingTargets);
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingTarget.java b/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingTarget.java
new file mode 100644
index 0000000000..a654437e3f
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/flinching/FlinchingTarget.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2018, Fluffeh
+ * 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.flinching;
+
+import java.time.Duration;
+import java.time.Instant;
+import lombok.Getter;
+import net.runelite.api.NPC;
+import net.runelite.api.coords.WorldPoint;
+
+public class FlinchingTarget
+{
+ private int currentDisplayLength = 5400;
+
+ private boolean usingHitDelay = false;
+
+ private int displayLength = 5400;
+ private int displayHitReceivedLength = 6600;
+ private Instant lastAttacked;
+
+ public boolean isActive = false;
+
+ @Getter
+ private int objectId;
+ private NPC targetObject;
+
+ @Getter
+ public WorldPoint worldLocation;
+
+ public FlinchingTarget(NPC target)
+ {
+ isActive = true;
+
+ this.targetObject = target;
+ this.lastAttacked = Instant.now();
+ this.objectId = target.getId();
+ this.worldLocation = target.getWorldLocation();
+ }
+
+ public void TargetHit()
+ {
+ boolean shouldHit = true;
+ if(usingHitDelay)
+ {
+ if(GetRemainingTime() > displayLength)
+ {
+ shouldHit = false;
+ }
+ }
+
+ if(shouldHit)
+ {
+ lastAttacked = Instant.now();
+
+ usingHitDelay = false;
+ currentDisplayLength = displayLength;
+ }
+ }
+
+ public double GetRemainingTimePercent()
+ {
+ double remainingTime = GetRemainingTime();
+ double timePercent = remainingTime / currentDisplayLength;
+ if(timePercent < 0)
+ {
+ timePercent = 0;
+ }
+ else if(timePercent > 1)
+ {
+ timePercent = 1;
+ }
+
+ return(timePercent);
+ }
+
+ private double GetRemainingTime()
+ {
+ Duration duration = Duration.between(lastAttacked, Instant.now());
+ return( (currentDisplayLength - ((double)duration.toMillis())));
+ }
+
+ public void Tick()
+ {
+ if(targetObject == null)
+ {
+ isActive = false;
+ }
+ else
+ {
+ worldLocation = targetObject.getWorldLocation();
+
+ double remainingTime = GetRemainingTime();
+ if(remainingTime <= 0)
+ {
+ isActive = false;
+ }
+ }
+ }
+
+ public void SetDelayTime(int delayTime, int delayHitReceivedTime)
+ {
+ displayLength = delayTime;
+ displayHitReceivedLength = delayHitReceivedTime;
+
+ if(usingHitDelay)
+ {
+ currentDisplayLength = displayHitReceivedLength;
+ }
+ else
+ {
+ currentDisplayLength = displayLength;
+ }
+ }
+
+ public void PlayerHit()
+ {
+ usingHitDelay = true;
+ currentDisplayLength = displayHitReceivedLength;
+
+ lastAttacked = Instant.now();
+ }
+}
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java
index 7598d30597..2d5949a838 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java
@@ -7,26 +7,70 @@ import net.runelite.client.config.ConfigItem;
@ConfigGroup("freezetimers")
public interface FreezeTimersConfig extends Config
{
-
+
@ConfigItem(
- keyName = "showOverlay",
- name = "Show Players",
- description = "Configure if the player overlay should be shown",
- position = 1
+ keyName = "showOverlay",
+ name = "Show Players",
+ description = "Configure if the player overlay should be shown",
+ position = 1
)
default boolean showPlayers()
{
return true;
}
-
+
@ConfigItem(
- keyName = "showNpcs",
- name = "Show NPCs",
- description = "Configure if the npc overlay should be shown",
- position = 2
+ keyName = "showNpcs",
+ name = "Show NPCs",
+ description = "Configure if the npc overlay should be shown",
+ position = 2
)
default boolean showNpcs()
{
return false;
}
+
+ @ConfigItem(
+ keyName = "FreezeTimers",
+ name = "Show Freeze Timers",
+ description = "Toggle overlay for Freeze timers",
+ position = 3
+ )
+ default boolean FreezeTimers()
+ {
+ return true;
+ }
+
+ @ConfigItem(
+ keyName = "TB",
+ name = "Show TB Timers",
+ description = "Toggle overlay for TB timers",
+ position = 4
+ )
+ default boolean TB()
+ {
+ return true;
+ }
+
+ @ConfigItem(
+ keyName = "Veng",
+ name = "Show Veng Timers",
+ description = "Toggle overlay for Veng timers",
+ position = 5
+ )
+ default boolean Veng()
+ {
+ return true;
+ }
+
+ @ConfigItem(
+ keyName = "noImage",
+ name = "Text Timers",
+ description = "Remove Images from Timers",
+ position = 6
+ )
+ default boolean noImage()
+ {
+ return false;
+ }
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java
index 04d9e5955a..c0252b19bf 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java
@@ -1,9 +1,18 @@
package net.runelite.client.plugins.freezetimers;
+import java.awt.Color;
+import static java.awt.Color.RED;
+import static java.awt.Color.WHITE;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import javax.inject.Inject;
import net.runelite.api.Actor;
import net.runelite.api.Client;
import net.runelite.api.GraphicID;
-import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.Overlay;
@@ -13,28 +22,21 @@ import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.util.ImageUtil;
-import javax.inject.Inject;
-import java.awt.*;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-
-import static java.awt.Color.RED;
-import static java.awt.Color.WHITE;
-import static java.awt.Color.green;
-
public class FreezeTimersOverlay extends Overlay
{
-
- @Inject
- private Timers timers;
-
+
private final FreezeTimersConfig config;
private final Client client;
private final Font timerFont = FontManager.getRunescapeBoldFont().deriveFont(14.0f);
private final BufferedImage FREEZE_IMAGE = ImageUtil.getResourceStreamFromClass(getClass(), "freeze.png");
private final BufferedImage TB_IMAGE = ImageUtil.getResourceStreamFromClass(getClass(), "teleblock.png");
private final BufferedImage VENG_IMAGE = ImageUtil.getResourceStreamFromClass(getClass(), "veng.png");
-
+ @Inject
+ private Timers timers;
+ private boolean lock;
+ private long finishedAtTest;
+ private Actor player;
+
@Inject
public FreezeTimersOverlay(FreezeTimersConfig config, Client client)
{
@@ -44,7 +46,7 @@ public class FreezeTimersOverlay extends Overlay
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.UNDER_WIDGETS);
}
-
+
@Override
public Dimension render(Graphics2D graphics)
{
@@ -58,30 +60,30 @@ public class FreezeTimersOverlay extends Overlay
}
return null;
}
-
+
private void renderOverlayFor(Graphics2D g, Actor actor)
{
if (timers.areAllTimersZero(actor))
{
return;
}
-
+
int overlaysDrawn = 0;
-
- if (drawFreezeOverlay(g, actor, overlaysDrawn))
+
+ if (drawFreezeOverlay(g, actor, overlaysDrawn) && config.FreezeTimers())
{
overlaysDrawn++;
}
- if (drawTBOverlay(g, actor, overlaysDrawn))
+ if (drawTBOverlay(g, actor, overlaysDrawn) && config.TB())
{
overlaysDrawn++;
}
- if (drawVengOverlay(g, actor, overlaysDrawn))
+ if (drawVengOverlay(g, actor, overlaysDrawn) && config.Veng())
{
overlaysDrawn++;
}
}
-
+
private boolean drawFreezeOverlay(Graphics2D g, Actor actor, int overlaysDrawn)
{
long currentTick = System.currentTimeMillis();
@@ -90,13 +92,24 @@ public class FreezeTimersOverlay extends Overlay
return false;
}
long finishedAt = timers.getTimerEnd(actor, TimerType.FREEZE);
-
+
String text = processTickCounter(finishedAt);
-
- renderActorText(g, actor, text, overlaysDrawn, FREEZE_IMAGE);
+ Point poi = actor.getCanvasTextLocation(g, text, 0);
+ int xpoi = poi.getX();
+ int ypoi = poi.getY();
+ Point FixedPoint = new Point(xpoi, ypoi);
+
+ if (config.noImage())
+ {
+ renderTextLocation(g, text, 11, Font.BOLD, Color.WHITE, FixedPoint);
+ }
+ else
+ {
+ renderActorText(g, actor, text, overlaysDrawn, FREEZE_IMAGE);
+ }
return true;
}
-
+
private boolean drawTBOverlay(Graphics2D g, Actor actor, int overlaysDrawn)
{
long currentTick = System.currentTimeMillis();
@@ -105,13 +118,31 @@ public class FreezeTimersOverlay extends Overlay
return false;
}
long finishedAt = timers.getTimerEnd(actor, TimerType.TELEBLOCK);
-
+
String text = processTickCounter(finishedAt);
-
- renderActorText(g, actor, text, overlaysDrawn, TB_IMAGE);
+ Point poi = actor.getCanvasTextLocation(g, text, 0);
+ int xpoi = poi.getX() + 20;
+ int ypoi = poi.getY();
+ Point FixedPoint = new Point(xpoi, ypoi);
+
+ if (config.noImage())
+ {
+ if (timers.getTimerEnd(actor, TimerType.FREEZE) <= currentTick)
+ {
+ renderTextLocation(g, text, 11, Font.BOLD, Color.CYAN, poi);
+ }
+ if (timers.getTimerEnd(actor, TimerType.FREEZE) >= currentTick)
+ {
+ renderTextLocation(g, " | " + text, 11, Font.BOLD, Color.CYAN, FixedPoint);
+ }
+ }
+ else
+ {
+ renderActorText(g, actor, text, overlaysDrawn, TB_IMAGE);
+ }
return true;
}
-
+
private boolean drawVengOverlay(Graphics2D g, Actor actor, int overlaysDrawn)
{
long currentTick = System.currentTimeMillis();
@@ -120,25 +151,42 @@ public class FreezeTimersOverlay extends Overlay
return false;
}
long finishedAt = timers.getTimerEnd(actor, TimerType.VENG);
-
+
String text = processTickCounter(finishedAt);
-
- renderActorText(g, actor, text, overlaysDrawn, VENG_IMAGE);
+ Point poi = actor.getCanvasTextLocation(g, text, 0);
+ int xpoi = poi.getX() - 20;
+ int ypoi = poi.getY();
+ Point FixedPoint = new Point(xpoi, ypoi);
+ if (config.noImage())
+ {
+ if (timers.getTimerEnd(actor, TimerType.FREEZE) <= currentTick)
+ {
+ renderTextLocation(g, text, 11, Font.BOLD, Color.RED, poi);
+ }
+ if (timers.getTimerEnd(actor, TimerType.FREEZE) >= currentTick)
+ {
+ renderTextLocation(g, text + " | ", 11, Font.BOLD, Color.RED, FixedPoint);
+ }
+ }
+ else
+ {
+ renderActorText(g, actor, text, overlaysDrawn, VENG_IMAGE);
+ }
if (actor.getGraphic() == GraphicID.VENGEANCE || actor.getGraphic() == GraphicID.VENGEANCE_OTHER)
{
-
+
g.setColor(RED);
Polygon poly = actor.getCanvasTilePoly();
if (poly != null)
{
OverlayUtil.renderPolygon(g, poly, RED);
}
- OverlayUtil.renderTextLocation(g, new Point((int)poly.getBounds2D().getCenterX(),
- (int)poly.getBounds2D().getCenterY()), actor.getName(), RED);
+ OverlayUtil.renderTextLocation(g, new Point((int) poly.getBounds2D().getCenterX(),
+ (int) poly.getBounds2D().getCenterY()), actor.getName(), RED);
}
return true;
}
-
+
private void renderActorText(Graphics2D g, Actor actor, String text, int overlaysDrawn, BufferedImage image)
{
int yOffset = (overlaysDrawn * 18);
@@ -147,9 +195,25 @@ public class FreezeTimersOverlay extends Overlay
Rectangle rect = actor.getConvexHull().getBounds();
int xOffset = (int) rect.getWidth();
OverlayUtil.renderActorTextAndImage(g, actor, text, Color.WHITE, image, yOffset,
- xOffset);
+ xOffset);
}
-
+
+ private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint)
+ {
+ graphics.setFont(new Font("Arial", fontStyle, fontSize));
+ if (canvasPoint != null)
+ {
+ final Point canvasCenterPoint = new Point(
+ canvasPoint.getX(),
+ canvasPoint.getY());
+ final Point canvasCenterPoint_shadow = new Point(
+ canvasPoint.getX() + 1,
+ canvasPoint.getY() + 1);
+ OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
+ OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
+ }
+ }
+
private String processTickCounter(long finishedAt)
{
long currentTick = System.currentTimeMillis();
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java
index ce582e790d..d3fd38f653 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java
@@ -1,6 +1,7 @@
package net.runelite.client.plugins.freezetimers;
import com.google.inject.Provides;
+import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.GraphicChanged;
@@ -8,52 +9,49 @@ import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
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.ui.overlay.OverlayManager;
-import javax.inject.Inject;
-
@PluginDescriptor(
- name = "Freeze Timers",
- description = "Shows a freeze timer overlay on players",
- tags = {"freeze", "timers", "barrage", "teleblock", "pklite"},
- type = PluginType.PVP
+ name = "Freeze Timers",
+ description = "Shows a freeze timer overlay on players",
+ tags = {"freeze", "timers", "barrage", "teleblock", "pklite"},
+ type = PluginType.PVP
)
public class FreezeTimersPlugin extends Plugin
{
-
+
@Inject
private Client client;
-
+
@Inject
private OverlayManager overlayManager;
-
+
@Inject
private Timers timers;
-
+
@Inject
private PrayerTracker prayerTracker;
-
+
@Inject
private FreezeTimersOverlay overlay;
-
+
public void startUp()
{
overlayManager.add(overlay);
}
-
+
public void shutDown()
{
overlayManager.remove(overlay);
}
-
+
@Provides
public FreezeTimersConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(FreezeTimersConfig.class);
}
-
+
@Subscribe
public void onGraphicChanged(GraphicChanged graphicChanged)
{
@@ -73,15 +71,19 @@ public class FreezeTimersPlugin extends Plugin
{
length /= 2;
}
+ if (timers.getTimerEnd(graphicChanged.getActor(), effect.getType()) > System.currentTimeMillis())
+ {
+ return;
+ }
timers.setTimerEnd(graphicChanged.getActor(), effect.getType(),
- System.currentTimeMillis() + length);
+ System.currentTimeMillis() + length);
}
-
+
@Subscribe
public void onGameTick(GameTick tickEvent)
{
timers.gameTick();
prayerTracker.gameTick();
}
-
+
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java
index 6e524e9aa0..1d8f22a0e5 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java
@@ -6,7 +6,7 @@ import lombok.Getter;
@AllArgsConstructor
public enum PlayerSpellEffect
{
- BIND("Bind", 181,5000, true, 0, TimerType.FREEZE),
+ BIND("Bind", 181, 5000, true, 0, TimerType.FREEZE),
SNARE("Snare", 180, 10000, true, 1, TimerType.FREEZE),
ENTANGLE("Entangle", 179, 15000, true, 2, TimerType.FREEZE),
RUSH("Ice Rush", 361, 5000, false, 3, TimerType.FREEZE),
@@ -17,7 +17,7 @@ public enum PlayerSpellEffect
VENG("Vengeance", 726, 30000, false, 8, TimerType.VENG),
VENG_OTHER("Vengeance Other", 725, 30000, false, 9, TimerType.VENG),
NONE("Nothing", -69, 420, true, 9999, TimerType.THIS_SHIT_BROKE);
-
+
@Getter
private final String name;
@Getter
@@ -30,7 +30,7 @@ public enum PlayerSpellEffect
private final int spriteIdx;
@Getter
private final TimerType type;
-
+
public static PlayerSpellEffect getFromSpotAnim(int spotAnim)
{
for(PlayerSpellEffect effect : values())
@@ -40,5 +40,5 @@ public enum PlayerSpellEffect
}
return NONE;
}
-
+
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PrayerTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PrayerTracker.java
index a7aa54b710..3cecf8519a 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PrayerTracker.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PrayerTracker.java
@@ -1,26 +1,25 @@
package net.runelite.client.plugins.freezetimers;
+import java.util.HashMap;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Actor;
import net.runelite.api.Client;
import net.runelite.api.NPC;
import net.runelite.api.Player;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import java.util.HashMap;
-
@Slf4j
@Singleton
public class PrayerTracker
{
-
+
@Inject
private Client client;
-
+
private HashMap> lastTick = new HashMap<>();
private HashMap> newTick = new HashMap<>();
-
+
public void gameTick()
{
lastTick.clear();
@@ -35,7 +34,7 @@ public class PrayerTracker
processActor(npc);
}
}
-
+
private void processActor(Actor actor)
{
if (!newTick.containsKey(actor))
@@ -43,20 +42,23 @@ public class PrayerTracker
newTick.put(actor, new HashMap<>());
}
if (actor instanceof Player)
- if(actor instanceof Player) {
+ {
+ if (actor instanceof Player)
+ {
newTick.get(actor).put("PrayerIcon", ((Player) actor).getOverheadIcon() == null ? -1 : ((Player) actor).getOverheadIcon().ordinal());
}
+ }
newTick.get(actor).put("SpotAnim", actor.getGraphic());
}
-
+
public int getPrayerIconLastTick(Actor p)
{
return lastTick.getOrDefault(p, new HashMap<>()).getOrDefault("PrayerIcon", -1337);
}
-
+
public int getSpotanimLastTick(Actor p)
{
return lastTick.getOrDefault(p, new HashMap<>()).getOrDefault("SpotAnim", -1337);
}
-
+
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/TimerType.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/TimerType.java
index 699d9f6403..c9e30c4dc1 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/TimerType.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/TimerType.java
@@ -5,5 +5,5 @@ public enum TimerType
FREEZE,
VENG,
TELEBLOCK,
- THIS_SHIT_BROKE;
+ THIS_SHIT_BROKE
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Timers.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Timers.java
index 09f3694a2d..58345fcc06 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Timers.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Timers.java
@@ -1,29 +1,27 @@
package net.runelite.client.plugins.freezetimers;
+import java.util.HashMap;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Actor;
import net.runelite.api.Client;
-import net.runelite.api.Player;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import java.util.HashMap;
@Slf4j
@Singleton
public class Timers
{
-
+
@Inject
private Client client;
-
+
private HashMap> timerMap = new HashMap<>();
-
+
public void gameTick()
{
-
+
}
-
+
public void setTimerEnd(Actor actor, TimerType type, long n)
{
if (!timerMap.containsKey(actor))
@@ -32,16 +30,16 @@ public class Timers
}
timerMap.get(actor).put(type, n);
}
-
+
public long getTimerEnd(Actor actor, TimerType type)
{
if (!timerMap.containsKey(actor))
{
timerMap.put(actor, new HashMap<>());
}
- return timerMap.get(actor).getOrDefault(type, (long)0);
+ return timerMap.get(actor).getOrDefault(type, (long) 0);
}
-
+
public boolean areAllTimersZero(Actor actor)
{
for (TimerType type : TimerType.values())
@@ -53,5 +51,5 @@ public class Timers
}
return true;
}
-
+
}
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/hideprayers/HidePrayersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java
index 8a92bed779..5ad0060269 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java
@@ -1,35 +1,118 @@
-package net.runelite.client.plugins.hideprayers;
-
-import net.runelite.client.config.Config;
-import net.runelite.client.config.ConfigGroup;
-import net.runelite.client.config.ConfigItem;
-
-@ConfigGroup("hideprayers")
-public interface HidePrayersConfig extends Config
-{
- @ConfigItem(
- position = 0,
- keyName = "pk prayers",
- name = "Hides none pk prayers",
- description = "Hides widget icons."
- )
- default boolean showPrayers() { return false; }
-
- @ConfigItem(
- position = 1,
- keyName = "eagle/mystic",
- name = "Shows eagle and mystic prayers",
- description = "Hides widget icons."
- )
- default boolean showEagleMystic() { return false; }
-
- @ConfigItem(
- position = 1,
- keyName = "ultstr",
- name = "Shows ultimate strength",
- description = "Hides widget icons."
- )
- default boolean showUltStrength() { return false; }
-
-}
-
+/*
+ * 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.hideprayers;
+
+import net.runelite.client.config.Config;
+import net.runelite.client.config.ConfigGroup;
+import net.runelite.client.config.ConfigItem;
+
+@ConfigGroup("hideprayers")
+public interface HidePrayersConfig extends Config
+{
+ @ConfigItem
+ (
+ position = 0,
+ keyName = "pk prayers",
+ name = "Hides none pk prayers",
+ description = "Hides widget icons."
+ )
+ default boolean showPrayers()
+ {
+ return false;
+ }
+
+ @ConfigItem
+ (
+ position = 1,
+ keyName = "eagle/mystic",
+ name = "Shows Eagle and Mystic Prayers",
+ description = "Hides widget icons."
+ )
+ default boolean showEagleMystic()
+ {
+ return false;
+ }
+
+ @ConfigItem
+ (
+ position = 2,
+ keyName = "ultstr",
+ name = "Shows Ultimate Strength/Incredible Reflex/Steel Skin",
+ description = "Hides widget icons."
+ )
+ default boolean showUltStrength()
+ {
+ return false;
+ }
+
+ @ConfigItem
+ (
+ position = 3,
+ keyName = "preserve",
+ name = "Shows Preserve",
+ description = "unides widget icons."
+ )
+ default boolean showPreserve()
+ {
+ return false;
+ }
+
+ @ConfigItem
+ (
+ position = 4,
+ keyName = "redemption",
+ name = "Shows Redemption",
+ description = "unides widget icons."
+ )
+ default boolean showRedemption()
+ {
+ return false;
+ }
+
+ @ConfigItem
+ (
+ position = 5,
+ keyName = "rapidheal",
+ name = "Shows Rapid Heal",
+ description = "unides widget icons."
+ )
+ default boolean showRapidHeal()
+ {
+ return false;
+ }
+
+ @ConfigItem
+ (
+ position = 6,
+ keyName = "rapidRestore",
+ name = "Shows Rapid restore",
+ description = "unides widget icons."
+ )
+ default boolean showRapidRestore()
+ {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java
index fa88699a97..546072b88c 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java
@@ -1,171 +1,297 @@
-package net.runelite.client.plugins.hideprayers;
-
-import com.google.common.collect.ImmutableList;
-import net.runelite.client.eventbus.Subscribe;
-import com.google.inject.Provides;
-import net.runelite.api.*;
-import net.runelite.api.events.ConfigChanged;
-import net.runelite.api.events.GameStateChanged;
-import net.runelite.api.events.WidgetLoaded;
-import net.runelite.api.widgets.Widget;
-import net.runelite.api.widgets.WidgetID;
-import net.runelite.api.widgets.WidgetInfo;
-import net.runelite.client.config.ConfigManager;
-import net.runelite.client.plugins.Plugin;
-import net.runelite.client.plugins.PluginDescriptor;
-import net.runelite.client.plugins.PluginType;
-
-import javax.inject.Inject;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-@PluginDescriptor(
- name = "Hide Prayers",
- description = "Hides specific Prayers in the Prayer tab.",
- type = PluginType.UTILITY
-)
-public class HidePrayersPlugin extends Plugin {
- private static final int PRAYER_COUNT = Prayer.values().length;
-
- private static final List PRAYER_WIDGET_INFO_LIST = ImmutableList.of(WidgetInfo.PRAYER_THICK_SKIN,
- WidgetInfo.PRAYER_BURST_OF_STRENGTH, WidgetInfo.PRAYER_CLARITY_OF_THOUGHT, WidgetInfo.PRAYER_SHARP_EYE,
- WidgetInfo.PRAYER_MYSTIC_WILL, WidgetInfo.PRAYER_ROCK_SKIN, WidgetInfo.PRAYER_SUPERHUMAN_STRENGTH,
- WidgetInfo.PRAYER_IMPROVED_REFLEXES, WidgetInfo.PRAYER_RAPID_RESTORE, WidgetInfo.PRAYER_RAPID_HEAL,
- WidgetInfo.PRAYER_PROTECT_ITEM, WidgetInfo.PRAYER_HAWK_EYE, WidgetInfo.PRAYER_MYSTIC_LORE,
- WidgetInfo.PRAYER_STEEL_SKIN, WidgetInfo.PRAYER_ULTIMATE_STRENGTH, WidgetInfo.PRAYER_INCREDIBLE_REFLEXES,
- WidgetInfo.PRAYER_PROTECT_FROM_MAGIC, WidgetInfo.PRAYER_PROTECT_FROM_MISSILES,
- WidgetInfo.PRAYER_PROTECT_FROM_MELEE, WidgetInfo.PRAYER_EAGLE_EYE, WidgetInfo.PRAYER_MYSTIC_MIGHT,
- WidgetInfo.PRAYER_RETRIBUTION, WidgetInfo.PRAYER_REDEMPTION, WidgetInfo.PRAYER_SMITE,
- WidgetInfo.PRAYER_PRESERVE, WidgetInfo.PRAYER_CHIVALRY, WidgetInfo.PRAYER_PIETY, WidgetInfo.PRAYER_RIGOUR,
- WidgetInfo.PRAYER_AUGURY);
-
- @Inject
- private Client client;
-
- @Inject
- private HidePrayersConfig config;
-
- @Provides
- HidePrayersConfig provideConfig(ConfigManager configManager) {
- return configManager.getConfig(HidePrayersConfig.class);
- }
-
- @Override
- protected void startUp() throws Exception {
- hidePrayers();
- }
-
- @Override
- protected void shutDown() throws Exception {
- restorePrayers();
- }
-
- @Subscribe
- public void onGameStateChanged(GameStateChanged event) {
- if (event.getGameState() == GameState.LOGGED_IN) {
- hidePrayers();
- }
- }
-
- @Subscribe
- public void onConfigChanged(ConfigChanged event) {
- if (event.getGroup().equals("hideprayers")) {
- hidePrayers();
- }
- }
-
- @Subscribe
- public void onWidgetLoaded(WidgetLoaded event) {
- if (event.getGroupId() == WidgetID.PRAYER_GROUP_ID || event.getGroupId() == WidgetID.QUICK_PRAYERS_GROUP_ID) {
- hidePrayers();
- }
- }
-
- private PrayerTabState getPrayerTabState() {
- HashTable componentTable = client.getComponentTable();
- for (WidgetNode widgetNode : componentTable.getNodes()) {
- if (widgetNode.getId() == WidgetID.PRAYER_GROUP_ID) {
- return PrayerTabState.PRAYERS;
- } else if (widgetNode.getId() == WidgetID.QUICK_PRAYERS_GROUP_ID) {
- return PrayerTabState.QUICK_PRAYERS;
- }
- }
- return PrayerTabState.NONE;
- }
-
- private void restorePrayers() {
- if (client.getGameState() != GameState.LOGGED_IN)
- return;
-
- PrayerTabState prayerTabState = getPrayerTabState();
-
- if (prayerTabState == PrayerTabState.PRAYERS) {
- List prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget)
- .filter(Objects::nonNull).collect(Collectors.toList());
-
- if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size())
- return;
-
- for (int index = 0; index < PRAYER_COUNT; index++)
- prayerWidgets.get(Prayer.values()[index].ordinal()).setHidden(false);
- }
- }
-
- private void hidePrayers() {
- if (client.getGameState() != GameState.LOGGED_IN)
- return;
-
- PrayerTabState prayerTabState = getPrayerTabState();
-
- if (prayerTabState == PrayerTabState.PRAYERS) {
- List prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget)
- .filter(Objects::nonNull).collect(Collectors.toList());
-
- if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size())
- return;
-
- for (int index = 0; index < PRAYER_COUNT; index++) {
- Prayer prayer = Prayer.values()[index];
- Widget prayerWidget = prayerWidgets.get(prayer.ordinal());
-
- if (!config.showPrayers() && !config.showEagleMystic())
- prayerWidget.setHidden(false);
-
- if (config.showPrayers()) {
- prayerWidget.setHidden(true);
- prayerWidgets.get(Prayer.values()[10].ordinal()).setHidden(false);// protect item
- prayerWidgets.get(Prayer.values()[16].ordinal()).setHidden(false);// mage
- prayerWidgets.get(Prayer.values()[17].ordinal()).setHidden(false);// range
- prayerWidgets.get(Prayer.values()[18].ordinal()).setHidden(false);// melee
- prayerWidgets.get(Prayer.values()[23].ordinal()).setHidden(false);// smite
- if (config.showEagleMystic()) {
- prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour
- prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury
- } else {
- prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(false);// rigour
- prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(false);// augury
- }
- if (config.showUltStrength()) {
- prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety
- } else {
- prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(false);// piety
- }
- }
- if (config.showEagleMystic()) {
- prayerWidget.setHidden(true);
- prayerWidgets.get(Prayer.values()[19].ordinal()).setHidden(false);// eagle
- prayerWidgets.get(Prayer.values()[20].ordinal()).setHidden(false);// mystic
- prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour
- prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury
- }
- if (config.showUltStrength()) {
- prayerWidget.setHidden(true);
- prayerWidgets.get(Prayer.values()[14].ordinal()).setHidden(false);// Ult Strength
- prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety
- }
-
- }
- }
- }
-}
+/*
+ * 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.hideprayers;
+
+import com.google.common.collect.ImmutableList;
+import net.runelite.client.eventbus.Subscribe;
+import com.google.inject.Provides;
+import net.runelite.api.*;
+import net.runelite.api.events.ConfigChanged;
+import net.runelite.api.events.GameStateChanged;
+import net.runelite.api.events.WidgetLoaded;
+import net.runelite.api.widgets.Widget;
+import net.runelite.api.widgets.WidgetID;
+import net.runelite.api.widgets.WidgetInfo;
+import net.runelite.client.config.ConfigManager;
+import net.runelite.client.plugins.Plugin;
+import net.runelite.client.plugins.PluginDescriptor;
+import net.runelite.client.plugins.PluginType;
+import javax.inject.Inject;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@PluginDescriptor
+(
+ name = "Hide Prayers",
+ description = "Hides specific Prayers in the Prayer tab.",
+ type = PluginType.UTILITY
+)
+public class HidePrayersPlugin extends Plugin
+{
+ private static final int PRAYER_COUNT = Prayer.values().length;
+
+ private static final List PRAYER_WIDGET_INFO_LIST = ImmutableList.of(
+ WidgetInfo.PRAYER_THICK_SKIN, //0
+ WidgetInfo.PRAYER_BURST_OF_STRENGTH, //1
+ WidgetInfo.PRAYER_CLARITY_OF_THOUGHT, //2
+ WidgetInfo.PRAYER_SHARP_EYE, //3
+ WidgetInfo.PRAYER_MYSTIC_WILL, //4
+ WidgetInfo.PRAYER_ROCK_SKIN, //5
+ WidgetInfo.PRAYER_SUPERHUMAN_STRENGTH, //6
+ WidgetInfo.PRAYER_IMPROVED_REFLEXES, //7
+ WidgetInfo.PRAYER_RAPID_RESTORE, //8
+ WidgetInfo.PRAYER_RAPID_HEAL, //9
+ WidgetInfo.PRAYER_PROTECT_ITEM, //10
+ WidgetInfo.PRAYER_HAWK_EYE, //11
+ WidgetInfo.PRAYER_MYSTIC_LORE, //12
+ WidgetInfo.PRAYER_STEEL_SKIN, //13
+ WidgetInfo.PRAYER_ULTIMATE_STRENGTH, //14
+ WidgetInfo.PRAYER_INCREDIBLE_REFLEXES, //15
+ WidgetInfo.PRAYER_PROTECT_FROM_MAGIC, //16
+ WidgetInfo.PRAYER_PROTECT_FROM_MISSILES, //17
+ WidgetInfo.PRAYER_PROTECT_FROM_MELEE, //18
+ WidgetInfo.PRAYER_EAGLE_EYE, //19
+ WidgetInfo.PRAYER_MYSTIC_MIGHT, //20
+ WidgetInfo.PRAYER_RETRIBUTION, //21
+ WidgetInfo.PRAYER_REDEMPTION, //22
+ WidgetInfo.PRAYER_SMITE, //23
+ WidgetInfo.PRAYER_PRESERVE, //24
+ WidgetInfo.PRAYER_CHIVALRY, //25
+ WidgetInfo.PRAYER_PIETY, //26
+ WidgetInfo.PRAYER_RIGOUR, //27
+ WidgetInfo.PRAYER_AUGURY); //28
+
+ @Inject
+ private Client client;
+
+ @Inject
+ private HidePrayersConfig config;
+
+ @Provides
+ HidePrayersConfig provideConfig(ConfigManager configManager)
+ {
+ return configManager.getConfig(HidePrayersConfig.class);
+ }
+
+ @Override
+ protected void startUp() throws Exception
+ {
+ hidePrayers();
+ }
+
+ @Override
+ protected void shutDown() throws Exception
+ {
+ restorePrayers();
+ }
+
+ @Subscribe
+ public void onGameStateChanged(GameStateChanged event)
+ {
+ if (event.getGameState() == GameState.LOGGED_IN)
+ {
+ hidePrayers();
+ }
+ }
+
+ @Subscribe
+ public void onConfigChanged(ConfigChanged event)
+ {
+ if (event.getGroup().equals("hideprayers"))
+ {
+ hidePrayers();
+ }
+ }
+
+ @Subscribe
+ public void onWidgetLoaded(WidgetLoaded event)
+ {
+ if (event.getGroupId() == WidgetID.PRAYER_GROUP_ID || event.getGroupId() == WidgetID.QUICK_PRAYERS_GROUP_ID)
+ {
+ hidePrayers();
+ }
+ }
+
+ private PrayerTabState getPrayerTabState()
+ {
+ HashTable componentTable = client.getComponentTable();
+ for (WidgetNode widgetNode : componentTable.getNodes())
+ {
+ if (widgetNode.getId() == WidgetID.PRAYER_GROUP_ID)
+ {
+ return PrayerTabState.PRAYERS;
+ }
+ else if (widgetNode.getId() == WidgetID.QUICK_PRAYERS_GROUP_ID)
+ {
+ return PrayerTabState.QUICK_PRAYERS;
+ }
+ }
+ return PrayerTabState.NONE;
+ }
+
+ private void restorePrayers()
+ {
+ if (client.getGameState() != GameState.LOGGED_IN)
+ return;
+
+ PrayerTabState prayerTabState = getPrayerTabState();
+
+ if (prayerTabState == PrayerTabState.PRAYERS)
+ {
+ List prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget)
+ .filter(Objects::nonNull).collect(Collectors.toList());
+
+ if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size())
+ return;
+
+ for (int index = 0; index < PRAYER_COUNT; index++)
+ prayerWidgets.get(Prayer.values()[index].ordinal()).setHidden(false);
+ }
+ }
+
+ private void hidePrayers()
+ {
+ if (client.getGameState() != GameState.LOGGED_IN)
+ return;
+
+ PrayerTabState prayerTabState = getPrayerTabState();
+
+ if (prayerTabState == PrayerTabState.PRAYERS)
+ {
+ List prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget)
+ .filter(Objects::nonNull).collect(Collectors.toList());
+
+ if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size())
+ return;
+
+ for (int index = 0; index < PRAYER_COUNT; index++)
+ {
+ Prayer prayer = Prayer.values()[index];
+ Widget prayerWidget = prayerWidgets.get(prayer.ordinal());
+
+ if (!config.showPrayers() && !config.showEagleMystic())
+ prayerWidget.setHidden(false);
+
+ if (config.showPrayers())
+ {
+ prayerWidget.setHidden(true);
+ prayerWidgets.get(Prayer.values()[10].ordinal()).setHidden(false);// protect item
+ prayerWidgets.get(Prayer.values()[16].ordinal()).setHidden(false);// mage
+ prayerWidgets.get(Prayer.values()[17].ordinal()).setHidden(false);// range
+ prayerWidgets.get(Prayer.values()[18].ordinal()).setHidden(false);// melee
+ prayerWidgets.get(Prayer.values()[23].ordinal()).setHidden(false);// smite
+ if (config.showEagleMystic())
+ {
+ prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour
+ prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury
+ }
+ else
+ {
+ prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(false);// rigour
+ prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(false);// augury
+ }
+ if (config.showUltStrength())
+ {
+ prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety
+ }
+ else
+ {
+ prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(false);// piety
+ }
+ if (config.showPreserve())
+ {
+ prayerWidgets.get(Prayer.values()[24].ordinal()).setHidden(true);// Preserve
+ }
+ else
+ {
+ prayerWidgets.get(Prayer.values()[24].ordinal()).setHidden(false);// Preserve
+ }
+ if (config.showRedemption())
+ {
+ prayerWidgets.get(Prayer.values()[22].ordinal()).setHidden(true);// Redemption
+ }
+ else
+ {
+ prayerWidgets.get(Prayer.values()[22].ordinal()).setHidden(false);// Redemption
+ }
+ if (config.showRapidRestore())
+ {
+ prayerWidgets.get(Prayer.values()[8].ordinal()).setHidden(true);// Rapid Restore
+ }
+ else
+ {
+ prayerWidgets.get(Prayer.values()[8].ordinal()).setHidden(false);// Rapid Restore
+ }
+ if (config.showRapidHeal())
+ {
+ prayerWidgets.get(Prayer.values()[9].ordinal()).setHidden(true);// Rapid Heal
+ }
+ else
+ {
+ prayerWidgets.get(Prayer.values()[9].ordinal()).setHidden(false);// Rapid Heal
+ }
+ }
+ if (config.showEagleMystic())
+ {
+ prayerWidget.setHidden(true);
+ prayerWidgets.get(Prayer.values()[19].ordinal()).setHidden(false);// eagle
+ prayerWidgets.get(Prayer.values()[20].ordinal()).setHidden(false);// mystic
+ prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour
+ prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury
+ }
+ if (config.showUltStrength())
+ {
+ prayerWidget.setHidden(true);
+ prayerWidgets.get(Prayer.values()[13].ordinal()).setHidden(false);// Steel Skin
+ prayerWidgets.get(Prayer.values()[14].ordinal()).setHidden(false);// Ult Strength
+ prayerWidgets.get(Prayer.values()[15].ordinal()).setHidden(false);// Incredible Reflexes
+ prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety
+ }
+ if (config.showPreserve())
+ {
+ prayerWidget.setHidden(true);
+ prayerWidgets.get(Prayer.values()[24].ordinal()).setHidden(false);// Preserve
+ }
+ if (config.showRedemption())
+ {
+ prayerWidget.setHidden(true);
+ prayerWidgets.get(Prayer.values()[22].ordinal()).setHidden(false);// Redemption
+ }
+ if (config.showRapidRestore())
+ {
+ prayerWidget.setHidden(true);
+ prayerWidgets.get(Prayer.values()[8].ordinal()).setHidden(false);// Rapid Restore
+ }
+ if (config.showRapidHeal())
+ {
+ prayerWidget.setHidden(true);
+ prayerWidgets.get(Prayer.values()[9].ordinal()).setHidden(false);// Rapid Heal
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java
index 699300f8a9..c0249c3f0e 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java
@@ -1,8 +1,33 @@
-package net.runelite.client.plugins.hideprayers;
-
-public enum PrayerTabState
-{
- NONE,
- PRAYERS,
- QUICK_PRAYERS
-}
+/*
+ * 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.hideprayers;
+
+public enum PrayerTabState
+{
+ NONE,
+ PRAYERS,
+ QUICK_PRAYERS
+}
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/loottracker/LootTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java
index bba5994d89..c2f355d7f9 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java
@@ -59,6 +59,16 @@ public interface LootTrackerConfig extends Config
return true;
}
+ @ConfigItem(
+ keyName = "chestLootChat",
+ name = "Show chest loot value in chat",
+ description = "Show the value of items from CoX/ToB/Barrows chests in chat"
+ )
+ default boolean chestLootChat()
+ {
+ return true;
+ }
+
@ConfigItem(
keyName = "syncPanel",
name = "Synchronize panel contents",
@@ -70,4 +80,4 @@ public interface LootTrackerConfig extends Config
{
return true;
}
-}
\ No newline at end of file
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
index 5429ec5941..f561a87a25 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
@@ -51,6 +51,7 @@ import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
+import net.runelite.api.Item;
import net.runelite.api.InventoryID;
import net.runelite.api.ItemComposition;
import net.runelite.api.ItemContainer;
@@ -66,6 +67,10 @@ import net.runelite.api.widgets.WidgetID;
import net.runelite.client.account.AccountSession;
import net.runelite.client.account.SessionManager;
import net.runelite.client.callback.ClientThread;
+import net.runelite.client.chat.ChatColorType;
+import net.runelite.client.chat.ChatMessageBuilder;
+import net.runelite.client.chat.ChatMessageManager;
+import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.NpcLootReceived;
@@ -80,6 +85,7 @@ import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.util.ImageUtil;
+import net.runelite.client.util.StackFormatter;
import net.runelite.client.util.Text;
import net.runelite.http.api.loottracker.GameItem;
import net.runelite.http.api.loottracker.LootRecord;
@@ -115,6 +121,9 @@ public class LootTrackerPlugin extends Plugin
@Inject
private ItemManager itemManager;
+
+ @Inject
+ private ChatMessageManager chatMessageManager;
@Inject
private SpriteManager spriteManager;
@@ -352,6 +361,29 @@ public class LootTrackerPlugin extends Plugin
return;
}
+ if (!(event.getGroupId() == WidgetID.CLUE_SCROLL_REWARD_GROUP_ID) && config.chestLootChat())
+ {
+ Item[] items = container.getItems();
+ long chestPrice = 0;
+ for (Item item : items)
+ {
+ long itemStack = (long) itemManager.getItemPrice(item.getId()) * (long) item.getQuantity();
+ chestPrice += itemStack;
+ }
+
+ final ChatMessageBuilder message = new ChatMessageBuilder()
+ .append(ChatColorType.HIGHLIGHT)
+ .append("Your loot is worth around ")
+ .append(StackFormatter.formatNumber(chestPrice))
+ .append(" coins.")
+ .append(ChatColorType.NORMAL);
+
+ chatMessageManager.queue(QueuedMessage.builder()
+ .type(ChatMessageType.ITEM_EXAMINE)
+ .runeLiteFormattedMessage(message.build())
+ .build());
+ }
+
// Convert container items to array of ItemStack
final Collection items = Arrays.stream(container.getItems())
.filter(item -> item.getId() > 0)
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java
index 1a7fec63b7..e8f0691f8d 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java
@@ -37,10 +37,10 @@ import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
+import net.runelite.client.plugins.PluginType;
import net.runelite.client.plugins.mining.MiningConfig;
import net.runelite.client.task.Schedule;
import net.runelite.client.ui.overlay.OverlayManager;
-
import javax.inject.Inject;
import java.time.temporal.ChronoUnit;
import java.util.HashSet;
@@ -52,6 +52,7 @@ import static net.runelite.api.ObjectID.*;
name = "Mining",
description = "Show helpful information about Mining",
tags = {"mining", "skilling", "overlay"},
+ type = PluginType.UTILITY,
enabledByDefault = false
)
public class MiningPlugin extends Plugin
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..5dda29c978 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() && 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/locationchatter/LocationChatterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java
similarity index 61%
rename from runelite-client/src/main/java/net/runelite/client/plugins/locationchatter/LocationChatterConfig.java
rename to runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java
index 33bbf214ff..6c1370ef76 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/locationchatter/LocationChatterConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java
@@ -1,40 +1,56 @@
-/*
- * 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;
- }
-}
+/*
+ * Copyright (c) 2019, gazivodag
+ * 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.prayagainstplayer;
+
+import net.runelite.api.Player;
+
+/**
+ * Contains a player object
+ * When they attacked me
+ * And (in milliseconds) when to expire the overlay around them
+ */
+public class PlayerContainer {
+
+ private Player player;
+ private long whenTheyAttackedMe;
+ private int millisToExpireHighlight;
+
+ public PlayerContainer(Player player, long whenTheyAttackedMe, int millisToExpireHighlight) {
+ this.player = player;
+ this.whenTheyAttackedMe = whenTheyAttackedMe;
+ this.millisToExpireHighlight = millisToExpireHighlight;
+ }
+
+
+ //getters
+ public Player getPlayer() {
+ return player;
+ }
+ public long getWhenTheyAttackedMe() {
+ return whenTheyAttackedMe;
+ }
+ public int getMillisToExpireHighlight() { return millisToExpireHighlight; };
+
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java
new file mode 100644
index 0000000000..ce453fd3d9
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2019, gazivodag
+ * 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.prayagainstplayer;
+
+import net.runelite.client.config.Config;
+import net.runelite.client.config.ConfigGroup;
+import net.runelite.client.config.ConfigItem;
+
+import java.awt.*;
+
+@ConfigGroup("prayagainstplayer")
+public interface PrayAgainstPlayerConfig extends Config {
+ @ConfigItem(
+ position = 0,
+ keyName = "attackerPlayerColor",
+ name = "Attacker color",
+ description = "This is the color that will be used to highlight attackers."
+ )
+ default Color attackerPlayerColor() { return new Color(0xFF0006); }
+
+ @ConfigItem(
+ position = 1,
+ keyName = "potentialPlayerColor",
+ name = "Potential Attacker color",
+ description = "This is the color that will be used to highlight potential attackers."
+ )
+ default Color potentialPlayerColor() { return new Color(0xFFFF00); }
+
+ ////
+ @ConfigItem(
+ position = 2,
+ keyName = "attackerTargetTimeout",
+ name = "Attacker Timeout",
+ description = "Seconds until attacker is no longer highlighted."
+ )
+ default int attackerTargetTimeout() { return 10; }
+
+ @ConfigItem(
+ position = 3,
+ keyName = "potentialTargetTimeout",
+ name = "Potential Attacker Timeout",
+ description = "Seconds until potential attacker is no longer highlighted."
+ )
+ default int potentialTargetTimeout() { return 10; }
+
+ @ConfigItem(
+ position = 4,
+ keyName = "newSpawnTimeout",
+ name = "New Player Timeout",
+ description = "Seconds until logged in/spawned player is no longer highlighted."
+ )
+ default int newSpawnTimeout() { return 5; }
+ ////
+
+ ////
+ @ConfigItem(
+ position = 5,
+ keyName = "ignoreFriends",
+ name = "Ignore Friends",
+ description = "This lets you decide whether you want friends to be highlighted by this plugin."
+ )
+ default boolean ignoreFriends() { return true; }
+
+ @ConfigItem(
+ position = 6,
+ keyName = "ignoreClanMates",
+ name = "Ignore Clan Mates",
+ description = "This lets you decide whether you want clan mates to be highlighted by this plugin."
+ )
+ default boolean ignoreClanMates() { return true; }
+ ////
+
+ @ConfigItem(
+ position = 7,
+ keyName = "markNewPlayer",
+ name = "Mark new player as potential attacker",
+ description = "Marks someone that logged in or teleported as a potential attacker for your safety\nDO NOT RUN THIS IN WORLD 1-2 GRAND EXCHANGE!"
+ )
+ default boolean markNewPlayer() { return false; }
+
+ @ConfigItem(
+ position = 8,
+ keyName = "drawTargetPrayAgainst",
+ name = "Draw what to pray on attacker",
+ description = "Tells you what to pray from what weapon the attacker is holding"
+ )
+ default boolean drawTargetPrayAgainst() { return true; }
+
+ @ConfigItem(
+ position = 9,
+ keyName = "drawPotentialTargetPrayAgainst",
+ name = "Draw what to pray on potential attacker",
+ description = "Tells you what to pray from what weapon the potential attacker is holding"
+ )
+ default boolean drawPotentialTargetPrayAgainst() { return true; }
+
+ @ConfigItem(
+ position = 10,
+ keyName = "drawTargetPrayAgainstPrayerTab",
+ name = "Draw what to pray from prayer tab",
+ description = "Tells you what to pray from what weapon the attacker is holding from the prayer tab"
+ )
+ default boolean drawTargetPrayAgainstPrayerTab() { return false; }
+
+ @ConfigItem(
+ position = 11,
+ keyName = "drawTargetsName",
+ name = "Draw name on attacker",
+ description = "Configures whether or not the attacker\'s name should be shown"
+ )
+ default boolean drawTargetsName() { return true; }
+
+ @ConfigItem(
+ position = 12,
+ keyName = "drawPotentialTargetsName",
+ name = "Draw name on potential attacker",
+ description = "Configures whether or not the potential attacker\'s name should be shown"
+ )
+ default boolean drawPotentialTargetsName() { return true; }
+
+ @ConfigItem(
+ position = 13,
+ keyName = "drawTargetHighlight",
+ name = "Draw highlight around attacker",
+ description = "Configures whether or not the attacker should be highlighted"
+ )
+ default boolean drawTargetHighlight() { return true; }
+
+ @ConfigItem(
+ position = 14,
+ keyName = "drawPotentialTargetHighlight",
+ name = "Draw highlight around potential attacker",
+ description = "Configures whether or not the potential attacker should be highlighted"
+ )
+ default boolean drawPotentialTargetHighlight() { return true; }
+
+ @ConfigItem(
+ position = 15,
+ keyName = "drawTargetTile",
+ name = "Draw tile under attacker",
+ description = "Configures whether or not the attacker\'s tile be highlighted"
+ )
+ default boolean drawTargetTile() { return false; }
+
+ @ConfigItem(
+ position = 16,
+ keyName = "drawPotentialTargetTile",
+ name = "Draw tile under potential attacker",
+ description = "Configures whether or not the potential attacker\'s tile be highlighted"
+ )
+ default boolean drawPotentialTargetTile() { return false; }
+
+ @ConfigItem(
+ position = 17,
+ keyName = "drawUnknownWeapons",
+ name = "Draw unknown weapons",
+ description = "Configures whether or not the unknown weapons should be shown when a player equips one"
+ )
+ default boolean drawUnknownWeapons() { return false; }
+
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java
new file mode 100644
index 0000000000..e54efd8127
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2019, gazivodag
+ * 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.prayagainstplayer;
+
+import net.runelite.api.Client;
+import net.runelite.api.ItemComposition;
+import net.runelite.api.Player;
+import net.runelite.api.kit.KitType;
+import net.runelite.client.ui.overlay.*;
+import net.runelite.client.util.Text;
+import net.runelite.api.Point;
+
+import javax.inject.Inject;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.util.ConcurrentModificationException;
+
+class PrayAgainstPlayerOverlay extends Overlay {
+
+ private final PrayAgainstPlayerPlugin plugin;
+ private final PrayAgainstPlayerConfig config;
+ private final Client client;
+
+ @Inject
+ private PrayAgainstPlayerOverlay(PrayAgainstPlayerPlugin plugin, PrayAgainstPlayerConfig config, Client client) {
+ super(plugin);
+ this.plugin = plugin;
+ this.config = config;
+ this.client = client;
+
+ setLayer(OverlayLayer.ABOVE_SCENE);
+ setPosition(OverlayPosition.DYNAMIC);
+ setPriority(OverlayPriority.HIGH);
+ }
+
+
+ @Override
+ public Dimension render(Graphics2D graphics) {
+ renderPotentialPlayers(graphics);
+ renderAttackingPlayers(graphics);
+ return null;
+ }
+
+ private void renderPotentialPlayers(Graphics2D graphics) {
+ if (plugin.getPotentialPlayersAttackingMe() == null || !plugin.getPotentialPlayersAttackingMe().isEmpty()) {
+ try {
+ for (PlayerContainer container : plugin.getPotentialPlayersAttackingMe()) {
+ if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) {
+ plugin.removePlayerFromPotentialContainer(container);
+ }
+ if (config.drawPotentialTargetsName()) renderNameAboveHead(graphics, container.getPlayer(), config.potentialPlayerColor());
+ if (config.drawPotentialTargetHighlight()) renderHighlightedPlayer(graphics, container.getPlayer(), config.potentialPlayerColor());
+ if (config.drawPotentialTargetTile()) renderTileUnderPlayer(graphics, container.getPlayer(), config.potentialPlayerColor());
+ if (config.drawPotentialTargetPrayAgainst()) renderPrayAgainstOnPlayer(graphics, container.getPlayer(), config.potentialPlayerColor());
+ }
+ } catch (ConcurrentModificationException e) {
+ }
+ }
+ }
+
+ private void renderAttackingPlayers(Graphics2D graphics) {
+ if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) {
+ try {
+ for (PlayerContainer container : plugin.getPlayersAttackingMe()) {
+ if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) {
+ plugin.removePlayerFromAttackerContainer(container);
+ }
+
+ if (config.drawTargetsName()) renderNameAboveHead(graphics, container.getPlayer(), config.attackerPlayerColor());
+ if (config.drawTargetHighlight()) renderHighlightedPlayer(graphics, container.getPlayer(), config.attackerPlayerColor());
+ if (config.drawTargetTile()) renderTileUnderPlayer(graphics, container.getPlayer(), config.attackerPlayerColor());
+ if (config.drawTargetPrayAgainst()) renderPrayAgainstOnPlayer(graphics, container.getPlayer(), config.attackerPlayerColor());
+ }
+ } catch (ConcurrentModificationException e) {
+ }
+ }
+ }
+
+ private void renderNameAboveHead(Graphics2D graphics, Player player, Color color) {
+ final String name = Text.sanitize(player.getName());
+ final int offset = player.getLogicalHeight() + 40;
+ Point textLocation = player.getCanvasTextLocation(graphics, name, offset);
+ if (textLocation != null) {
+ OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
+ }
+ }
+
+ private void renderHighlightedPlayer(Graphics2D graphics, Player player, Color color) {
+ try {
+ OverlayUtil.renderPolygon(graphics, player.getConvexHull(), color);
+ } catch (NullPointerException e) {
+ }
+ }
+
+ private void renderTileUnderPlayer(Graphics2D graphics, Player player, Color color) {
+ Polygon poly = player.getCanvasTilePoly();
+ OverlayUtil.renderPolygon(graphics, poly, color);
+ }
+
+ private void renderPrayAgainstOnPlayer(Graphics2D graphics, Player player, Color color) {
+ final int offset = (player.getLogicalHeight() / 2) + 75;
+ BufferedImage icon;
+
+ switch (WeaponType.checkWeaponOnPlayer(client, player)) {
+ case WEAPON_MELEE:
+ icon = plugin.getProtectionIcon(WeaponType.WEAPON_MELEE);
+ break;
+ case WEAPON_MAGIC:
+ icon = plugin.getProtectionIcon(WeaponType.WEAPON_MAGIC);
+ break;
+ case WEAPON_RANGED:
+ icon = plugin.getProtectionIcon(WeaponType.WEAPON_RANGED);
+ break;
+ default:
+ icon = null;
+ break;
+ }
+ try {
+ if (icon != null) {
+ Point point = player.getCanvasImageLocation(icon, offset);
+ OverlayUtil.renderImageLocation(graphics, point, icon);
+ } else {
+ if (config.drawUnknownWeapons()) {
+ int itemId = player.getPlayerComposition().getEquipmentId(KitType.WEAPON);
+ ItemComposition itemComposition = client.getItemDefinition(itemId);
+
+ final String str = itemComposition.getName().toUpperCase();
+ Point point = player.getCanvasTextLocation(graphics, str, offset);
+ OverlayUtil.renderTextLocation(graphics, point, str, color);
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java
new file mode 100644
index 0000000000..4e505675f6
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019, gazivodag
+ * 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.prayagainstplayer;
+
+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.client.ui.overlay.*;
+
+import javax.inject.Inject;
+import java.awt.*;
+import java.util.ConcurrentModificationException;
+
+class PrayAgainstPlayerOverlayPrayerTab extends Overlay {
+
+ private final PrayAgainstPlayerPlugin plugin;
+ private final PrayAgainstPlayerConfig config;
+ private final Client client;
+
+ @Inject
+ private PrayAgainstPlayerOverlayPrayerTab (PrayAgainstPlayerPlugin plugin, PrayAgainstPlayerConfig config, Client client) {
+ super(plugin);
+ this.plugin = plugin;
+ this.config = config;
+ this.client = client;
+
+ setPosition(OverlayPosition.DETACHED);
+ setLayer(OverlayLayer.ALWAYS_ON_TOP);
+ setPriority(OverlayPriority.MED);
+ }
+
+
+ @Override
+ public Dimension render(Graphics2D graphics) {
+ if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) {
+ try {
+ for (PlayerContainer container : plugin.getPlayersAttackingMe()) {
+ if (plugin.getPlayersAttackingMe() != null && plugin.getPlayersAttackingMe().size() > 0) {
+ //no reason to show you what prayers to pray in your prayer tab if multiple people are attacking you
+ if ((plugin.getPlayersAttackingMe().size() == 1) && (config.drawTargetPrayAgainstPrayerTab())) {
+ renderPrayerToClick(graphics, container.getPlayer());
+ }
+ }
+ }
+ } catch (ConcurrentModificationException e) {
+ }
+ }
+ return null;
+ }
+
+ private void renderPrayerToClick(Graphics2D graphics, Player player) {
+ Widget PROTECT_FROM_MAGIC = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MAGIC);
+ Widget PROTECT_FROM_RANGED = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MISSILES);
+ Widget PROTECT_FROM_MELEE = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MELEE);
+ Color color = Color.RED;
+ if (PROTECT_FROM_MELEE.isHidden()) return;
+ switch (WeaponType.checkWeaponOnPlayer(client, player)) {
+ case WEAPON_MAGIC:
+ OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MAGIC.getBounds()), color);
+ break;
+ case WEAPON_MELEE:
+ OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MELEE.getBounds()), color);
+ break;
+ case WEAPON_RANGED:
+ OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_RANGED.getBounds()), color);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private static Polygon rectangleToPolygon(Rectangle rect) {
+ int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x};
+ int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height};
+ return new Polygon(xpoints, ypoints, 4);
+ }
+
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java
new file mode 100644
index 0000000000..0f9d144bcb
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2019, gazivodag
+ * 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.prayagainstplayer;
+
+import com.google.inject.Provides;
+import net.runelite.api.*;
+import net.runelite.api.events.*;
+import net.runelite.client.config.ConfigManager;
+import net.runelite.client.eventbus.Subscribe;
+import net.runelite.client.game.SpriteManager;
+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.ImageUtil;
+
+import javax.inject.Inject;
+import java.awt.*;
+import java.awt.image.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+@PluginDescriptor(
+ name = "Pray Against Player",
+ description = "Use plugin in PvP situations for best results!!",
+ tags = {"highlight", "pvp", "overlay", "players"},
+ type = PluginType.PVP
+)
+
+/**
+ * I am fully aware that there is plenty of overhead and is a MESS!
+ * If you'd like to contribute please do!
+ */
+public class PrayAgainstPlayerPlugin extends Plugin {
+
+ private static final int[] PROTECTION_ICONS = {
+ SpriteID.PRAYER_PROTECT_FROM_MISSILES,
+ SpriteID.PRAYER_PROTECT_FROM_MELEE,
+ SpriteID.PRAYER_PROTECT_FROM_MAGIC
+ };
+ private static final Dimension PROTECTION_ICON_DIMENSION = new Dimension(33, 33);
+ private static final Color PROTECTION_ICON_OUTLINE_COLOR = new Color(33, 33, 33);
+ public final BufferedImage[] ProtectionIcons = new BufferedImage[PROTECTION_ICONS.length];
+
+ private ArrayList potentialPlayersAttackingMe;
+ private ArrayList playersAttackingMe;
+
+ @Inject
+ private Client client;
+
+ @Inject
+ private SpriteManager spriteManager;
+
+ @Inject
+ private OverlayManager overlayManager;
+
+ @Inject
+ private PrayAgainstPlayerOverlay overlay;
+
+ @Inject
+ private PrayAgainstPlayerOverlayPrayerTab overlayPrayerTab;
+
+ @Inject
+ private PrayAgainstPlayerConfig config;
+
+ @Provides
+ PrayAgainstPlayerConfig provideConfig(ConfigManager configManager) {
+ return configManager.getConfig(PrayAgainstPlayerConfig.class);
+ }
+
+ @Subscribe
+ public void onGameStateChanged(GameStateChanged gameStateChanged) {
+ if (gameStateChanged.getGameState() == GameState.LOGGED_IN) {
+ loadProtectionIcons();
+ }
+ }
+
+ @Override
+ protected void startUp() {
+ potentialPlayersAttackingMe = new ArrayList<>();
+ playersAttackingMe = new ArrayList<>();
+ overlayManager.add(overlay);
+ overlayManager.add(overlayPrayerTab);
+ }
+
+ @Override
+ protected void shutDown() throws Exception {
+ overlayManager.remove(overlay);
+ overlayManager.remove(overlayPrayerTab);
+ }
+
+ @Subscribe
+ protected void onAnimationChanged(AnimationChanged animationChanged) {
+ if ((animationChanged.getActor() instanceof Player) && (animationChanged.getActor().getInteracting() instanceof Player) && (animationChanged.getActor().getInteracting() == client.getLocalPlayer())) {
+ Player sourcePlayer = (Player) animationChanged.getActor();
+
+ //is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list
+ if (client.isFriended(sourcePlayer.getName(), true) && config.ignoreFriends()) return;
+ if (client.isClanMember(sourcePlayer.getName()) && config.ignoreClanMates()) return;
+
+ if ((sourcePlayer.getAnimation() != -1) && (!isBlockAnimation(sourcePlayer.getAnimation()))) {
+ //if attacker attacks again, reset his timer so overlay doesn't go away
+ if (findPlayerInAttackerList(sourcePlayer) != null) {
+ resetPlayerFromAttackerContainerTimer(findPlayerInAttackerList(sourcePlayer));
+ }
+ //if he attacks and he was in the potential attackers list, remove him
+ if (!potentialPlayersAttackingMe.isEmpty() && potentialPlayersAttackingMe.contains(findPlayerInPotentialList(sourcePlayer))) {
+ removePlayerFromPotentialContainer(findPlayerInPotentialList(sourcePlayer));
+ }
+ //if he's not in the attackers list, add him
+ if (findPlayerInAttackerList(sourcePlayer) == null) {
+ PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (config.attackerTargetTimeout() * 1000));
+ playersAttackingMe.add(container);
+ }
+ }
+ }
+ }
+
+ @Subscribe
+ protected void onInteractingChanged(InteractingChanged interactingChanged) {
+ //if someone interacts with you, add them to the potential attackers list
+ if ((interactingChanged.getSource() instanceof Player) && (interactingChanged.getTarget() instanceof Player)) {
+ Player sourcePlayer = (Player) interactingChanged.getSource();
+ Player targetPlayer = (Player) interactingChanged.getTarget();
+ if ((targetPlayer == client.getLocalPlayer()) && (findPlayerInPotentialList(sourcePlayer) == null)) { //we're being interacted with
+
+ //is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list
+ if (client.isFriended(sourcePlayer.getName(), true) && config.ignoreFriends()) return;
+ if (client.isClanMember(sourcePlayer.getName()) && config.ignoreClanMates()) return;
+
+ PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (config.potentialTargetTimeout() * 1000));
+ potentialPlayersAttackingMe.add(container);
+ }
+ }
+ }
+
+ @Subscribe
+ protected void onPlayerDespawned(PlayerDespawned playerDespawned) {
+ PlayerContainer container = findPlayerInAttackerList(playerDespawned.getPlayer());
+ PlayerContainer container2 = findPlayerInPotentialList(playerDespawned.getPlayer());
+ if (container != null) {
+ playersAttackingMe.remove(container);
+ }
+ if (container2 != null) {
+ potentialPlayersAttackingMe.remove(container2);
+ }
+ }
+
+ @Subscribe
+ protected void onPlayerSpawned(PlayerSpawned playerSpawned) {
+ if (config.markNewPlayer()) {
+ Player p = playerSpawned.getPlayer();
+
+ if (client.isFriended(p.getName(), true) && config.ignoreFriends()) return;
+ if (client.isClanMember(p.getName()) && config.ignoreClanMates()) return;
+
+ PlayerContainer container = findPlayerInPotentialList(p);
+ if (container == null) {
+ container = new PlayerContainer(p, System.currentTimeMillis(), (config.newSpawnTimeout() * 1000));
+ potentialPlayersAttackingMe.add(container);
+ }
+ }
+ }
+
+ PlayerContainer findPlayerInAttackerList(Player player) {
+ if (playersAttackingMe.isEmpty()) {
+ return null;
+ }
+ for (int i = 0 ; i < playersAttackingMe.size() ; i++) {
+ PlayerContainer container = playersAttackingMe.get(i);
+ if (container.getPlayer() == player) {
+ return container;
+ }
+ }
+ return null;
+ }
+
+ PlayerContainer findPlayerInPotentialList(Player player) {
+ if (potentialPlayersAttackingMe.isEmpty()) {
+ return null;
+ }
+ for (int i = 0 ; i < potentialPlayersAttackingMe.size() ; i++) {
+ PlayerContainer container = potentialPlayersAttackingMe.get(i);
+ if (container.getPlayer() == player) {
+ return container;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Resets player timer in case he attacks again, so his highlight doesn't go away so easily
+ * @param container
+ */
+ public void resetPlayerFromAttackerContainerTimer(PlayerContainer container) {
+ removePlayerFromAttackerContainer(container);
+ PlayerContainer newContainer = new PlayerContainer(container.getPlayer(), System.currentTimeMillis(), (config.attackerTargetTimeout() * 1000));
+ playersAttackingMe.add(newContainer);
+ }
+
+
+ public void removePlayerFromPotentialContainer(PlayerContainer container) {
+ if ((potentialPlayersAttackingMe != null) && (!potentialPlayersAttackingMe.isEmpty()) && (potentialPlayersAttackingMe.contains(container))) {
+ potentialPlayersAttackingMe.remove(container);
+ }
+ }
+
+ public void removePlayerFromAttackerContainer(PlayerContainer container) {
+ if ((playersAttackingMe != null) && (!playersAttackingMe.isEmpty()) && (playersAttackingMe.contains(container))) {
+ playersAttackingMe.remove(container);
+ }
+ }
+
+ private boolean isBlockAnimation(int anim) {
+ switch (anim) {
+ case AnimationID.BLOCK_DEFENDER:
+ case AnimationID.BLOCK_NO_SHIELD:
+ case AnimationID.BLOCK_SHIELD:
+ case AnimationID.BLOCK_SWORD:
+ case AnimationID.BLOCK_UNARMED:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public ArrayList getPotentialPlayersAttackingMe() { return potentialPlayersAttackingMe; }
+ public ArrayList getPlayersAttackingMe() { return playersAttackingMe; }
+
+ //All of the methods below are from the Zulrah plugin!!! Credits to it's respective owner
+ private void loadProtectionIcons() {
+ final IndexedSprite[] protectionIcons = {};
+ final IndexedSprite[] newProtectionIcons = Arrays.copyOf(protectionIcons, PROTECTION_ICONS.length);
+ int curPosition = 0;
+
+ for (int i = 0; i < PROTECTION_ICONS.length; i++, curPosition++)
+ {
+ final int resource = PROTECTION_ICONS[i];
+ ProtectionIcons[i] = rgbaToIndexedBufferedImage(ProtectionIconFromSprite(spriteManager.getSprite(resource, 0)));
+ newProtectionIcons[curPosition] = createIndexedSprite(client, ProtectionIcons[i]);
+ }
+ }
+
+ private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) {
+ final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel();
+
+ final int width = bufferedImage.getWidth();
+ final int height = bufferedImage.getHeight();
+ final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
+ final int[] palette = new int[indexedCM.getMapSize()];
+ indexedCM.getRGBs(palette);
+
+ final IndexedSprite newIndexedSprite = client.createIndexedSprite();
+ newIndexedSprite.setPixels(pixels);
+ newIndexedSprite.setPalette(palette);
+ newIndexedSprite.setWidth(width);
+ newIndexedSprite.setHeight(height);
+ newIndexedSprite.setOriginalWidth(width);
+ newIndexedSprite.setOriginalHeight(height);
+ newIndexedSprite.setOffsetX(0);
+ newIndexedSprite.setOffsetY(0);
+ return newIndexedSprite;
+ }
+
+ private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) {
+ final BufferedImage indexedImage = new BufferedImage(
+ sourceBufferedImage.getWidth(),
+ sourceBufferedImage.getHeight(),
+ BufferedImage.TYPE_BYTE_INDEXED);
+
+ final ColorModel cm = indexedImage.getColorModel();
+ final IndexColorModel icm = (IndexColorModel) cm;
+
+ final int size = icm.getMapSize();
+ final byte[] reds = new byte[size];
+ final byte[] greens = new byte[size];
+ final byte[] blues = new byte[size];
+ icm.getReds(reds);
+ icm.getGreens(greens);
+ icm.getBlues(blues);
+
+ final WritableRaster raster = indexedImage.getRaster();
+ final int pixel = raster.getSample(0, 0, 0);
+ final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel);
+ final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null);
+ resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null);
+ return resultIndexedImage;
+ }
+
+ private static BufferedImage ProtectionIconFromSprite(final BufferedImage freezeSprite) {
+ final BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, PROTECTION_ICON_DIMENSION.width, PROTECTION_ICON_DIMENSION.height);
+ return ImageUtil.outlineImage(freezeCanvas, PROTECTION_ICON_OUTLINE_COLOR);
+ }
+
+ BufferedImage getProtectionIcon(WeaponType weaponType) {
+ switch (weaponType) {
+ case WEAPON_RANGED:
+ return ProtectionIcons[0];
+ case WEAPON_MELEE:
+ return ProtectionIcons[1];
+ case WEAPON_MAGIC:
+ return ProtectionIcons[2];
+ }
+ return null;
+ }
+
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java
new file mode 100644
index 0000000000..1dc00c8311
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2019, gazivodag
+ * 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.prayagainstplayer;
+
+import net.runelite.api.Client;
+import net.runelite.api.ItemComposition;
+import net.runelite.api.Player;
+import net.runelite.api.kit.KitType;
+
+enum WeaponType {
+
+ WEAPON_MELEE,
+ WEAPON_RANGED,
+ WEAPON_MAGIC,
+ WEAPON_UNKNOWN;
+
+ /**
+ * im fully aware this could of been done better!!!
+ * @param client
+ * @param attacker
+ * @return
+ */
+ public static WeaponType checkWeaponOnPlayer (Client client, Player attacker) {
+ int itemId = attacker.getPlayerComposition().getEquipmentId(KitType.WEAPON);
+ ItemComposition itemComposition = client.getItemDefinition(itemId);
+ String weaponNameGivenLowerCase = itemComposition.getName().toLowerCase();
+
+ if (itemId == -1) return WEAPON_MELEE;
+ if (weaponNameGivenLowerCase == null || weaponNameGivenLowerCase.toLowerCase().contains("null")) return WEAPON_MELEE;
+
+ for (String meleeWeaponName : meleeWeaponNames) {
+ if (weaponNameGivenLowerCase.contains(meleeWeaponName) && !weaponNameGivenLowerCase.contains("thrownaxe")) {
+ return WEAPON_MELEE;
+ }
+ }
+
+ for (String rangedWeaponName : rangedWeaponNames) {
+ if (weaponNameGivenLowerCase.contains(rangedWeaponName)) {
+ return WEAPON_RANGED;
+ }
+ }
+
+ for (String magicWeaponName : magicWeaponNames) {
+ if (weaponNameGivenLowerCase.contains(magicWeaponName)) {
+ return WEAPON_MAGIC;
+ }
+ }
+
+ return WEAPON_UNKNOWN;
+
+ }
+
+ private static String[] meleeWeaponNames = {
+ "sword",
+ "scimitar",
+ "dagger",
+ "spear",
+ "mace",
+ "axe",
+ "whip",
+ "tentacle",
+ "-ket-",
+ "-xil-",
+ "warhammer",
+ "halberd",
+ "claws",
+ "hasta",
+ "scythe",
+ "maul",
+ "anchor",
+ "sabre",
+ "excalibur",
+ "machete",
+ "dragon hunter lance",
+ "event rpg",
+ "silverlight",
+ "darklight",
+ "arclight",
+ "flail",
+ "granite hammer",
+ "rapier",
+ "bulwark"
+ };
+
+ private static String[] rangedWeaponNames = {
+ "bow",
+ "blowpipe",
+ "xil-ul",
+ "knife",
+ "dart",
+ "thrownaxe",
+ "chinchompa",
+ "ballista"
+ };
+
+ private static String[] magicWeaponNames = {
+ "staff",
+ "trident",
+ "wand",
+ "dawnbringer"
+ };
+
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java
new file mode 100644
index 0000000000..c61fa5e81c
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java
@@ -0,0 +1,207 @@
+package net.runelite.client.plugins.slayermusiq;
+
+import net.runelite.client.util.LinkBrowser;
+import net.runelite.api.ChatMessageType;
+import net.runelite.api.events.ChatMessage;
+import net.runelite.client.chat.ChatColorType;
+import net.runelite.client.chat.ChatMessageBuilder;
+import net.runelite.client.chat.ChatMessageManager;
+import net.runelite.client.chat.QueuedMessage;
+
+public class QuestGuideLinks {
+ private static final Link[] QUEST_GUIDE_LINKS = {
+ // Free Quests
+ new Link("Cook's Assistant", "https://www.youtube.com/watch?v=ehmtDRelj3c"),
+ new Link("Romeo & Juliet", "https://www.youtube.com/watch?v=rH_biWSNWVY"),
+ new Link("Demon Slayer", "https://www.youtube.com/watch?v=hgACrzJSiQk"),
+ new Link("Shield of Arrav", "https://www.youtube.com/watch?v=a_imLDKUdzg"),
+ new Link("Sheep Shearer", "https://www.youtube.com/watch?v=XFG3aNwK68s"),
+ new Link("The Restless Ghost", "https://www.youtube.com/watch?v=UkWNcsG_pXM"),
+ new Link("Ernest the Chicken", "https://www.youtube.com/watch?v=cq8NIVhSqh4"),
+ new Link("Vampire Slayer", "https://www.youtube.com/watch?v=FcEuxsDJWCU"),
+ new Link("Imp Catcher", "https://www.youtube.com/watch?v=LHgnl0FbOzk"),
+ new Link("Prince Ali Rescue", "https://www.youtube.com/watch?v=hrSPl1GfFaw"),
+ new Link("Doric's Quest", "https://www.youtube.com/watch?v=5TYyxHU27a4"),
+ new Link("Black Knights' Fortress", "https://www.youtube.com/watch?v=aekoZi3f9cU"),
+ new Link("Witch's Potion", "https://www.youtube.com/watch?v=XV4i5sPUvXo"),
+ new Link("The Knight's Sword", "https://www.youtube.com/watch?v=UkBWaI0rOqE"),
+ new Link("Goblin Diplomacy", "https://www.youtube.com/watch?v=P9BKOb_dLoY"),
+ new Link("Pirate's Treasure", "https://www.youtube.com/watch?v=zcD87PQW8Qk"),
+ new Link("Dragon Slayer", "https://www.youtube.com/watch?v=bMtCjlFOaBI"),
+ new Link("Rune Mysteries", "https://www.youtube.com/watch?v=l8ZhaN8uoS0"),
+ new Link("Misthalin Mystery", "https://www.youtube.com/watch?v=QlFqVAobAlQ"),
+ new Link("The Corsair Curse", "https://www.youtube.com/watch?v=wi7mUAHExz4"),
+ new Link("X Marks the Spot", "https://www.youtube.com/watch?v=GhRgvEG5jxQ"),
+ // Members Quests
+ new Link("Druidic Ritual", "https://www.youtube.com/watch?v=QIfU6HSmH4w"),
+ new Link("Lost City", "https://www.youtube.com/watch?v=T-kQNUSjFZI"),
+ new Link("Witch's House", "https://www.youtube.com/watch?v=TLsg7Wa-LUA"),
+ new Link("Merlin's Crystal", "https://www.youtube.com/watch?v=ESX-qriNtCE"),
+ new Link("Heroes' Quest", "https://www.youtube.com/watch?v=hK2N0WLKviE"),
+ new Link("Scorpion Catcher", "https://www.youtube.com/watch?v=xpqdec7_ZWg"),
+ new Link("Family Crest", "https://www.youtube.com/watch?v=0mk_Cgjr738"),
+ new Link("Monk's Friend", "https://www.youtube.com/watch?v=avi4y4G3Hcw"),
+ new Link("Temple of Ikov", "https://www.youtube.com/watch?v=5K7jDgr_4Z4"),
+ new Link("Clock Tower", "https://www.youtube.com/watch?v=GUCkkQFzyDw"),
+ new Link("Holy Grail", "https://www.youtube.com/watch?v=cgXoV1QlYco"),
+ new Link("Tree Gnome Village", "https://www.youtube.com/watch?v=T6Su__yuyRI"),
+ new Link("Fight Arena", "https://www.youtube.com/watch?v=4Nqjep2E5pw"),
+ new Link("Hazeel Cult", "https://www.youtube.com/watch?v=2_fhFJW6cNY"),
+ new Link("Sheep Herder", "https://www.youtube.com/watch?v=akC9FeYCG1Q"),
+ new Link("Plague City", "https://www.youtube.com/watch?v=Hf2wQQZL5CU"),
+ new Link("Waterfall Quest", "https://www.youtube.com/watch?v=xWBSnGkQTi4"),
+ new Link("Jungle Potion", "https://www.youtube.com/watch?v=xqLKsFz08As"),
+ new Link("The Grand Tree", "https://www.youtube.com/watch?v=N5e_Jus_E-Y"),
+ new Link("Underground Pass", "https://www.youtube.com/watch?v=5klGJg1wY8k"),
+ new Link("Observatory Quest", "https://www.youtube.com/watch?v=yxa9B6svv44"),
+ new Link("Watchtower", "https://www.youtube.com/watch?v=Vb10GoYP7FE"),
+ new Link("Dwarf Cannon", "https://www.youtube.com/watch?v=pROFg5jcCR0"),
+ new Link("Murder Mystery", "https://www.youtube.com/watch?v=P1IDGCA2f9o"),
+ new Link("The Dig Site", "https://www.youtube.com/watch?v=TOdcWV4MzuU"),
+ new Link("Gertrude's Cat", "https://www.youtube.com/watch?v=g7S09wA8EAY"),
+ new Link("Legends' Quest", "https://www.youtube.com/watch?v=Lid8enDEF_U"),
+ new Link("Death Plateau", "https://www.youtube.com/watch?v=SIQFmTvnb6w"),
+ new Link("Big Chompy Bird Hunting", "https://www.youtube.com/watch?v=s2fytMOHJXI"),
+ new Link("Elemental Workshop I", "https://www.youtube.com/watch?v=tbZD2RDqvfQ"),
+ new Link("Nature Spirit", "https://www.youtube.com/watch?v=Enf8vUWb5o0"),
+ new Link("Priest in Peril", "https://www.youtube.com/watch?v=fyYri6wUQIU"),
+ new Link("Regicide", "https://www.youtube.com/watch?v=KkWM-ok3C4Y"),
+ new Link("Tai Bwo Wannai Trio", "https://www.youtube.com/watch?v=Mdair5mvZL0"),
+ new Link("Troll Stronghold", "https://www.youtube.com/watch?v=zqmUs-f3AKA"),
+ new Link("Horror from the Deep", "https://www.youtube.com/watch?v=9htK8kb6DR8"),
+ new Link("Throne of Miscellania", "https://www.youtube.com/watch?v=fzGMnv2skBE"),
+ new Link("Monkey Madness I", "https://www.youtube.com/watch?v=VnoRfeBnPFA"),
+ new Link("Haunted Mine", "https://www.youtube.com/watch?v=cIc6loJHm9Q"),
+ new Link("Troll Romance", "https://www.youtube.com/watch?v=j2zifZVu7Gc"),
+ new Link("In Search of the Myreque", "https://www.youtube.com/watch?v=5nmYFHdAXAQ"),
+ new Link("Creature of Fenkenstrain", "https://www.youtube.com/watch?v=swqUVIs7B7M"),
+ new Link("Roving Elves", "https://www.youtube.com/watch?v=J3qf9DnT9cA"),
+ new Link("One Small Favour", "https://www.youtube.com/watch?v=ix_0-W3e9ps"),
+ new Link("Mountain Daughter", "https://www.youtube.com/watch?v=HETx_LX7aiY"),
+ new Link("Between a Rock...", "https://www.youtube.com/watch?v=cB11I45EGgA"),
+ new Link("The Golem", "https://www.youtube.com/watch?v=qpEHpiO6lLw"),
+ new Link("Desert Treasure", "https://www.youtube.com/watch?v=BuIqulIsICo"),
+ new Link("Icthlarin's Little Helper", "https://www.youtube.com/watch?v=wpNKm8_vUOM"),
+ new Link("Tears of Guthix", "https://www.youtube.com/watch?v=EMonDNI0uPk"),
+ new Link("The Lost Tribe", "https://www.youtube.com/watch?v=spZErjRnCdc"),
+ new Link("The Giant Dwarf", "https://www.youtube.com/watch?v=Z7PsGpOYgxY"),
+ new Link("Recruitment Drive", "https://www.youtube.com/watch?v=sOuzMpA_xtw"),
+ new Link("Mourning's Ends Part I", "https://www.youtube.com/watch?v=vuzAdk-h3c0"),
+ new Link("Garden of Tranquillity", "https://www.youtube.com/watch?v=7hbCzYnLCsQ"),
+ new Link("A Tail of Two Cats", "https://www.youtube.com/watch?v=SgN9Yw_YqHk"),
+ new Link("Wanted!", "https://www.youtube.com/watch?v=ZHZAKDCfXGs"),
+ new Link("Mourning's Ends Part II", "https://www.youtube.com/watch?v=FK5sLogGbU8"),
+ new Link("Rum Deal", "https://www.youtube.com/watch?v=I14CIu5x2S8"),
+ new Link("Shadow of the Storm", "https://www.youtube.com/watch?v=5ZvWd3XCQjI"),
+ new Link("Ratcatchers", "https://www.youtube.com/watch?v=s7G22fEuhTc"),
+ new Link("Spirits of the Elid", "https://www.youtube.com/watch?v=A1zAX55hZC0"),
+ new Link("Devious Minds", "https://www.youtube.com/watch?v=_UtlFmrWt1w"),
+ new Link("Enakhra's Lament", "https://www.youtube.com/watch?v=Y3kEIPYVaVE"),
+ new Link("Cabin Fever", "https://www.youtube.com/watch?v=k5DtxNXhOaw"),
+ new Link("Fairytale I - Growing Pains", "https://www.youtube.com/watch?v=cfGI9qFOmsg"),
+ new Link("Recipe for Disaster", "https://www.youtube.com/watch?v=hrAyyInJaTA"),
+ new Link("In Aid of the Myreque", "https://www.youtube.com/watch?v=O2Ru2NmuTaA"),
+ new Link("A Soul's Bane", "https://www.youtube.com/watch?v=dp8dp79qp6I"),
+ new Link("Rag and Bone Man", "https://www.youtube.com/watch?v=3owXSeN56W8"),
+ new Link("Swan Song", "https://www.youtube.com/watch?v=IpmERThXv2g"),
+ new Link("Royal Trouble", "https://www.youtube.com/watch?v=bVWUlKzNXEg"),
+ new Link("Death to the Dorgeshuun", "https://www.youtube.com/watch?v=2XJHuLhig98"),
+ new Link("Fairytale II - Cure a Queen", "https://www.youtube.com/watch?v=P6KkRk4_e3U"),
+ new Link("Lunar Diplomacy", "https://www.youtube.com/watch?v=vmeSKb7IBgQ"),
+ new Link("The Eyes of Glouphrie", "https://www.youtube.com/watch?v=0YCPwmZcxKA"),
+ new Link("Darkness of Hallowvale", "https://www.youtube.com/watch?v=QziKl99qdtU"),
+ new Link("Elemental Workshop II", "https://www.youtube.com/watch?v=Bb4E7ecIgv0"),
+ new Link("My Arm's Big Adventure", "https://www.youtube.com/watch?v=xa1KWOewgYA"),
+ new Link("Enlightened Journey", "https://www.youtube.com/watch?v=XAPthC8d7k0"),
+ new Link("Eagles' Peak", "https://www.youtube.com/watch?v=KDxIrrwXp7U"),
+ new Link("Animal Magnetism", "https://www.youtube.com/watch?v=kUyjXA7TaFU"),
+ new Link("Contact!", "https://www.youtube.com/watch?v=czn-yWABBWs"),
+ new Link("Cold War", "https://www.youtube.com/watch?v=0m1KpP-qKWI"),
+ new Link("The Fremennik Isles", "https://www.youtube.com/watch?v=EvxhiOWmraY"),
+ new Link("The Great Brain Robbery", "https://www.youtube.com/watch?v=ImHFASuNUN8"),
+ new Link("What Lies Below", "https://www.youtube.com/watch?v=f_9nVMGTtuo"),
+ new Link("Olaf's Quest", "https://www.youtube.com/watch?v=mXV5bM1NFMM"),
+ new Link("Dream Mentor", "https://www.youtube.com/watch?v=XDLUu0Kf0sE"),
+ new Link("Grim Tales", "https://www.youtube.com/watch?v=dFB0Q6v8Apw"),
+ new Link("King's Ransom", "https://www.youtube.com/watch?v=UJz9ZfF3uCY"),
+ new Link("Shilo Village", "https://www.youtube.com/watch?v=bDvBi8FT-QI"),
+ new Link("Biohazard", "https://www.youtube.com/watch?v=n9k87LwOGMk"),
+ new Link("Tower of Life", "https://www.youtube.com/watch?v=KReMcWpeY3k"),
+ new Link("Rag and Bone Man II", "https://www.youtube.com/watch?v=KGdHiDDUX_U"),
+ new Link("Zogre Flesh Eaters", "https://www.youtube.com/watch?v=vzm4949kXP4"),
+ new Link("Monkey Madness II", "https://www.youtube.com/watch?v=ykE5LbjABaI"),
+ new Link("Client of Kourend", "https://www.youtube.com/watch?v=Y-KIHF-cL9w"),
+ new Link("The Queen of Thieves", "https://www.youtube.com/watch?v=W94zFZVrHkQ"),
+ new Link("Bone Voyage", "https://www.youtube.com/watch?v=-VTR4p8kPmI"),
+ new Link("Dragon Slayer II", "https://www.youtube.com/watch?v=4BMb3Zwzk_U"),
+ new Link("The Depths of Despair", "https://www.youtube.com/watch?v=CaVUk2eAsKs"),
+ new Link("A Taste of Hope", "https://www.youtube.com/watch?v=VjdgEIizdSc"),
+ new Link("Tale of the Righteous", "https://www.youtube.com/watch?v=99yiv0tPl58"),
+ new Link("Making Friends with My Arm", "https://www.youtube.com/watch?v=DltzzhIsM_Q"),
+ new Link("The Ascent of Arceuus", "https://www.youtube.com/watch?v=4VQnfrv6S18"),
+ new Link("The Forsaken Tower", "https://www.youtube.com/watch?v=con0sXl5NBY"),
+ new Link("Fishing Contest", "https://www.youtube.com/watch?v=XYSv37A_l5w"),
+ new Link("Tribal Totem", "https://www.youtube.com/watch?v=XkUEIjr886M"),
+ new Link("Sea Slug", "https://www.youtube.com/watch?v=oOZVfa5SkVQ"),
+ new Link("The Tourist Trap", "https://www.youtube.com/watch?v=0bmSCCepMvo"),
+ new Link("Eadgar's Ruse", "https://www.youtube.com/watch?v=aVQ3DjTElXg"),
+ new Link("Shades of Mort'ton", "https://www.youtube.com/watch?v=eF05R8OMxgg"),
+ new Link("The Fremennik Trials", "https://www.youtube.com/watch?v=YUIvEgcvl5c"),
+ new Link("Ghosts Ahoy", "https://www.youtube.com/watch?v=aNBkLOywDfM"),
+ new Link("The Feud", "https://www.youtube.com/watch?v=nlBSc9IUklA"),
+ new Link("Forgettable Tale...", "https://www.youtube.com/watch?v=3HvFd6AxNU0"),
+ new Link("Making History", "https://www.youtube.com/watch?v=bOTGi2zAuhs"),
+ new Link("The Hand in the Sand", "https://www.youtube.com/watch?v=gdNLcZ-l1Lw"),
+ new Link("The Slug Menace", "https://www.youtube.com/watch?v=BRQbdr3JEZ8"),
+ new Link("Another Slice of H.A.M.", "https://www.youtube.com/watch?v=Yq3db7827Lk")
+ };
+
+ private static class Link {
+
+ private String questName;
+ private String url;
+
+ public Link(String questName, String url) {
+ this.questName = questName;
+ this.url = url;
+ }
+
+ public String getQuestName() {
+ return questName;
+ }
+
+ public void openURL() {
+ LinkBrowser.browse(this.url);
+ }
+
+ }
+
+ private static boolean openGuide(String questName) {
+ for (Link link : QUEST_GUIDE_LINKS) {
+ if (link.getQuestName().equals(questName)) {
+ link.openURL();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static void logQuestNotFoundError(String questName, ChatMessageManager chatMessageManager) {
+ String chatMessage = new ChatMessageBuilder()
+ .append(ChatColorType.HIGHLIGHT)
+ .append("Could not find Slayermusiq1 guide for " + questName)
+ .build();
+
+ chatMessageManager.queue(QueuedMessage.builder()
+ .type(ChatMessageType.GAMEMESSAGE)
+ .runeLiteFormattedMessage(chatMessage)
+ .build());
+ }
+
+ public static void tryOpenGuide(String questName, ChatMessageManager chatMessageManager) {
+ boolean success = openGuide(questName);
+ if (!success) {
+ logQuestNotFoundError(questName, chatMessageManager);
+ }
+ }
+}
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java
new file mode 100644
index 0000000000..0689ba8289
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2018, Jeremy Berchtold
+ * 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.
+ */
+
+
+// Based off RuneLite's Wiki Plugin
+/*
+ * Copyright (c) 2018 Abex
+ * 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.slayermusiq;
+
+import com.google.inject.Provides;
+import com.google.common.primitives.Ints;
+import java.awt.Dimension;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.swing.SwingUtilities;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import net.runelite.api.Client;
+import net.runelite.api.MenuAction;
+import net.runelite.api.MenuEntry;
+import net.runelite.api.widgets.WidgetInfo;
+import net.runelite.api.events.MenuEntryAdded;
+import net.runelite.api.events.MenuOptionClicked;
+import net.runelite.client.plugins.PluginType;
+import net.runelite.client.util.Text;
+import net.runelite.client.chat.ChatMessageManager;
+import net.runelite.client.eventbus.Subscribe;
+import net.runelite.client.plugins.Plugin;
+import net.runelite.client.plugins.PluginDescriptor;
+
+@PluginDescriptor(
+ name = "Slayermusiq1 Guides",
+ description = "Adds a right-click option to go to Slayermusiq1's guides from the quest tab",
+ tags = {"quest", "guide", "slayermusiq"},
+ type = PluginType.UTILITY
+)
+@Slf4j
+public class SlayermusiqPlugin extends Plugin
+{
+
+ private static final int[] QUESTLIST_WIDGET_IDS = new int[]
+ {
+ WidgetInfo.QUESTLIST_FREE_CONTAINER.getId(),
+ WidgetInfo.QUESTLIST_MEMBERS_CONTAINER.getId(),
+ WidgetInfo.QUESTLIST_MINIQUEST_CONTAINER.getId(),
+ };
+
+ private static final String MENUOP_SLAYERMUSIQ = "Slayermusiq";
+
+ @Inject
+ private Client client;
+
+ @Inject
+ private ChatMessageManager chatMessageManager;
+
+ @Override
+ protected void startUp() throws Exception
+ {
+ //
+ }
+
+ @Override
+ protected void shutDown() throws Exception
+ {
+ //
+ }
+
+ @Subscribe
+ public void onMenuEntryAdded(MenuEntryAdded event)
+ {
+ int widgetID = event.getActionParam1();
+ if (Ints.contains(QUESTLIST_WIDGET_IDS, widgetID) && "Read Journal:".equals(event.getOption())) {
+ MenuEntry[] menuEntries = client.getMenuEntries();
+
+ MenuEntry newMenuEntry = createSlayermusiqOptionMenuEntry(event);
+ menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1);
+ menuEntries[menuEntries.length - 1] = newMenuEntry;
+
+ client.setMenuEntries(menuEntries);
+ }
+ }
+
+ @Subscribe
+ private void onMenuOptionClicked(MenuOptionClicked ev) {
+ if (ev.getMenuAction() == MenuAction.RUNELITE && ev.getMenuOption().equals(MENUOP_SLAYERMUSIQ)) {
+ ev.consume();
+ String quest = Text.removeTags(ev.getMenuTarget());
+ QuestGuideLinks.tryOpenGuide(quest, chatMessageManager);
+ }
+ }
+
+ private MenuEntry createSlayermusiqOptionMenuEntry(MenuEntryAdded event) {
+ int widgetIndex = event.getActionParam0();
+ int widgetID = event.getActionParam1();
+
+ MenuEntry menuEntry = new MenuEntry();
+ menuEntry.setTarget(event.getTarget());
+ menuEntry.setOption(MENUOP_SLAYERMUSIQ);
+ menuEntry.setParam0(widgetIndex);
+ menuEntry.setParam1(widgetID);
+ menuEntry.setType(MenuAction.RUNELITE.getId());
+
+ return menuEntry;
+ }
+
+}
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java
index 1a47110f61..9bc8e243f9 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java
@@ -78,8 +78,8 @@ public interface SpellbookConfig extends Config
@ConfigItem(
keyName = "filter",
name = "Unfiltered spells",
- description = "Spells you don't want to filter, seperated with a comma"
- )
+ description = "Spells you don't want to filter, seperated with a comma.
\"'s can be used in front and behind spells (eg: '\"c' matches all spells starting with a c"
+ ) // ^ JAJAJJAJAJAJAJA BRAZIL
default String filter()
{
return "";
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java
index 82181d6911..8175c05f3f 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java
@@ -81,6 +81,13 @@ public class SpellbookPlugin extends Plugin
private static final WidgetMenuOption RESIZABLE_MAGIC_TAB_UNLOCK = new WidgetMenuOption(UNLOCK, MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_MAGIC_TAB);
private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_MAGIC_TAB_LOCK = new WidgetMenuOption(LOCK, MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_TAB);
private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_MAGIC_TAB_UNLOCK = new WidgetMenuOption(UNLOCK, MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_TAB);
+ private enum WordFilterMode
+ {
+ CONTAINS,
+ EQUALS,
+ STARTSWITH,
+ ENDSWITH
+ }
@Inject
private Client client;
@@ -143,9 +150,7 @@ public class SpellbookPlugin extends Plugin
saveSpells();
config.canDrag(false);
mouseManager.unregisterMouseListener(mouseListener);
-
mouseManager.unregisterMouseWheelListener(mouseListener);
-
mouseListener = null;
}
@@ -168,16 +173,13 @@ public class SpellbookPlugin extends Plugin
String key = event.getKey();
- if ("canDrag".equals(key))
- {
- refreshMagicTabOption();
- }
- else if ("filter".equals(key))
+ if ("filter".equals(key))
{
loadFilter();
}
clientThread.invokeLater(this::runRebuild);
+ refreshMagicTabOption();
}
@Subscribe
@@ -241,7 +243,46 @@ public class SpellbookPlugin extends Plugin
return;
}
- iStack[iStackSize - 2] = notFilteredSpells.stream().anyMatch(spell::contains) ? 1 : 0;
+ for (String str : notFilteredSpells)
+ {
+ WordFilterMode mode = getFilterMode(str);
+ str = str.replaceAll("\"", "");
+
+ if (mode == WordFilterMode.CONTAINS)
+ {
+ if (spell.contains(str))
+ {
+ iStack[iStackSize - 2] = 1;
+ break;
+ }
+ }
+ else if (mode == WordFilterMode.STARTSWITH)
+ {
+ if (spell.startsWith(str))
+ {
+ iStack[iStackSize - 2] = 1;
+ break;
+ }
+ }
+ else if (mode == WordFilterMode.ENDSWITH)
+ {
+ if (spell.endsWith(str))
+ {
+ iStack[iStackSize - 2] = 1;
+ break;
+ }
+ }
+ else if (mode == WordFilterMode.EQUALS)
+ {
+ if (spell.equals(str))
+ {
+ iStack[iStackSize - 2] = 1;
+ break;
+ }
+ }
+
+ iStack[iStackSize - 2] = 0;
+ }
}
else if ("isMobileSpellbookEnabled".equals(event.getEventName()))
{
@@ -273,7 +314,7 @@ public class SpellbookPlugin extends Plugin
.map(Spell::getName)
.filter(s -> notFilteredSpells
.stream()
- .anyMatch(s::contains))
+ .anyMatch(s.replaceAll("\"", "" )::contains))
.count();
@@ -436,6 +477,24 @@ public class SpellbookPlugin extends Plugin
);
}
+ private static WordFilterMode getFilterMode(String s)
+ {
+ if (!s.contains("\""))
+ {
+ return WordFilterMode.CONTAINS;
+ }
+ if (s.startsWith("\""))
+ {
+ return s.endsWith("\"") ? WordFilterMode.EQUALS : WordFilterMode.STARTSWITH;
+ }
+ else if (s.endsWith("\""))
+ {
+ return WordFilterMode.ENDSWITH;
+ }
+
+ return WordFilterMode.CONTAINS; // but probably null soz
+ }
+
boolean isOnSpellWidget(java.awt.Point point)
{
Widget boundsWidget = client.getWidget(WidgetInfo.SPELLBOOK_FILTERED_BOUNDS);
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java
index cc17572eba..f049b722c7 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java
@@ -25,7 +25,7 @@ import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor(name = "Tick Counter",
description = "Counts combat activity for nearby players",
enabledByDefault = false,
- type = PluginType.UTILITY
+ type = PluginType.PVP
)
public class TickCounterPlugin extends Plugin {
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/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java
index eab7c91c30..cc88234686 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java
@@ -55,11 +55,22 @@ public interface XpGlobesConfig extends Config
return false;
}
+ @ConfigItem(
+ keyName = "Time to level",
+ name = "Display TTL",
+ description = "Displays time left to level",
+ position = 2
+ )
+ default boolean enableTimeToLevel()
+ {
+ return true;
+ }
+
@ConfigItem(
keyName = "enableCustomArcColor",
name = "Enable custom arc color",
description = "Enables the custom coloring of the globe's arc instead of using the skill's default color.",
- position = 2
+ position = 3
)
default boolean enableCustomArcColor()
{
@@ -71,7 +82,7 @@ public interface XpGlobesConfig extends Config
keyName = "Progress arc color",
name = "Progress arc color",
description = "Change the color of the progress arc in the xp orb",
- position = 3
+ position = 4
)
default Color progressArcColor()
{
@@ -83,7 +94,7 @@ public interface XpGlobesConfig extends Config
keyName = "Progress orb outline color",
name = "Progress orb outline color",
description = "Change the color of the progress orb outline",
- position = 4
+ position = 5
)
default Color progressOrbOutLineColor()
{
@@ -95,7 +106,7 @@ public interface XpGlobesConfig extends Config
keyName = "Progress orb background color",
name = "Progress orb background color",
description = "Change the color of the progress orb background",
- position = 5
+ position = 6
)
default Color progressOrbBackgroundColor()
{
@@ -106,7 +117,7 @@ public interface XpGlobesConfig extends Config
keyName = "Progress arc width",
name = "Progress arc width",
description = "Change the stroke width of the progress arc",
- position = 6
+ position = 7
)
default int progressArcStrokeWidth()
{
@@ -117,7 +128,7 @@ public interface XpGlobesConfig extends Config
keyName = "Orb size",
name = "Size of orbs",
description = "Change the size of the xp orbs",
- position = 7
+ position = 8
)
default int xpOrbSize()
{
@@ -128,7 +139,7 @@ public interface XpGlobesConfig extends Config
keyName = "Orb duration",
name = "Duration of orbs",
description = "Change the duration the xp orbs are visible",
- position = 8
+ position = 9
)
default int xpOrbDuration()
{
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java
index 81171840e1..168476b376 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java
@@ -293,12 +293,15 @@ public class XpGlobesOverlay extends Overlay
.build());
}
- String timeLeft = xpTrackerService.getTimeTillGoal(mouseOverSkill.getSkill());
- xpTooltip.getChildren().add(LineComponent.builder()
- .left("Time left:")
- .leftColor(Color.ORANGE)
- .right(timeLeft)
- .build());
+ if (config.enableTimeToLevel())
+ {
+ String timeLeft = xpTrackerService.getTimeTillGoal(mouseOverSkill.getSkill());
+ xpTooltip.getChildren().add(LineComponent.builder()
+ .left("Time left:")
+ .leftColor(Color.ORANGE)
+ .right(timeLeft)
+ .build());
+ }
}
xpTooltip.render(graphics);
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
diff --git a/runelite-client/src/main/scripts/437.hash b/runelite-client/src/main/scripts/437.hash
new file mode 100644
index 0000000000..22831dda47
--- /dev/null
+++ b/runelite-client/src/main/scripts/437.hash
@@ -0,0 +1 @@
+3A111DACE3611F4C4FB53F60FC180F863D5FC222D24EE301B08D49496658F802
\ No newline at end of file
diff --git a/runelite-client/src/main/scripts/437.rs2asm b/runelite-client/src/main/scripts/437.rs2asm
new file mode 100644
index 0000000000..d5cf4b8ae3
--- /dev/null
+++ b/runelite-client/src/main/scripts/437.rs2asm
@@ -0,0 +1,11 @@
+.id 437
+.int_stack_count 1
+.string_stack_count 0
+.int_var_count 1
+.string_var_count 1
+ sload 0
+ clan_joinchat
+ sconst "joinCC"
+ runelite_callback
+ return
+
diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClanMemberManagerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClanMemberManagerMixin.java
index 25e01ce1ca..aca7addbb5 100644
--- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClanMemberManagerMixin.java
+++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClanMemberManagerMixin.java
@@ -40,11 +40,16 @@ public abstract class RSClanMemberManagerMixin implements RSClanMemberManager
{
@Shadow("clientInstance")
private static RSClient client;
+ private RSNameable nameable;
+ private RSName name;
+ private RSName prevName;
@Inject
@Override
public void rl$add(RSName name, RSName prevName)
{
+ this.name = name;
+ this.prevName = prevName;
ClanMember member = findByName(name);
if (member == null)
{
@@ -59,6 +64,7 @@ public abstract class RSClanMemberManagerMixin implements RSClanMemberManager
@Override
public void rl$remove(RSNameable nameable)
{
+ this.nameable = nameable;
ClanMember member = findByName(nameable.getRsName());
if (member == null)
{