diff --git a/runelite-api/src/main/java/net/runelite/api/VarClientInt.java b/runelite-api/src/main/java/net/runelite/api/VarClientInt.java index 0652f3b0e0..b58e879437 100644 --- a/runelite-api/src/main/java/net/runelite/api/VarClientInt.java +++ b/runelite-api/src/main/java/net/runelite/api/VarClientInt.java @@ -45,6 +45,11 @@ public enum VarClientInt INPUT_TYPE(5), MEMBERSHIP_STATUS(103), + /** + * -1 = player inventory closed + * 3 = player inventory opened + */ + PLAYER_INVENTORY_OPENED(171), INVENTORY_TAB(171), diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index 3c46a0b71e..8c4c18bf91 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -349,6 +349,11 @@ public enum Varbits */ MULTICOMBAT_AREA(4605), + /** + * In the Wilderness + */ + IN_THE_WILDERNESS(5963), + /** * Kingdom Management */ diff --git a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java index bbacd1914a..ee7c67b20b 100644 --- a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java +++ b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java @@ -327,6 +327,27 @@ public class WorldPoint return ((x >> 6) << 8) | (y >> 6); } + /** + * Checks if user in within certain zone specified by upper and lower bound + * @param lowerBound + * @param upperBound + * @param userLocation + * @return + */ + public static boolean isInZone(WorldPoint lowerBound, WorldPoint upperBound, WorldPoint userLocation) + { + if (userLocation.getX() < lowerBound.getX() + || userLocation.getX() > upperBound.getX() + || userLocation.getY() < lowerBound.getY() + || userLocation.getY() > upperBound.getY() + || userLocation.getPlane() < lowerBound.getPlane() + || userLocation.getPlane() > upperBound.getPlane()) + { + return false; + } + return true; + } + /** * Converts the passed region ID and coordinates to a world coordinate */ diff --git a/runelite-api/src/main/java/net/runelite/api/events/InteractChanged.java b/runelite-api/src/main/java/net/runelite/api/events/InteractChanged.java new file mode 100644 index 0000000000..70f5452387 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/InteractChanged.java @@ -0,0 +1,34 @@ +/* + * 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.api.events; + +import lombok.Data; +import net.runelite.api.Actor; + +@Data +public class InteractChanged +{ + private Actor actor; +} \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index fb3825b8e1..471c0acbe4 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -552,6 +552,13 @@ public class WidgetID static final int ROLE_SPRITE = 11; static final int ROLE = 12; } + static class HLR + { + static final int TEAMMATE1 = 18; + static final int TEAMMATE2 = 22; + static final int TEAMMATE3 = 26; + static final int TEAMMATE4 = 30; + } static final int CORRECT_STYLE = 3; static final int CURRENT_WAVE_WIDGET = 4; static final int CURRENT_WAVE = 5; @@ -857,6 +864,9 @@ static final int WIND_STRIKE = 5; static class Pvp { + static final int PVP_WIDGET_CONTAINER = 54; // OUTDATED? + static final int SKULL = 56; // OUTDATED? + static final int ATTACK_RANGE = 59; // OUTDATED? static final int BOUNTY_HUNTER_INFO = 19; static final int KILLDEATH_RATIO = 15; static final int SKULL_CONTAINER = 62; diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index c6a818fc63..d345b27aa8 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -348,6 +348,11 @@ public enum WidgetInfo BA_HEAL_ROLE_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.ROLE), BA_HEAL_ROLE_SPRITE(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.ROLE_SPRITE), + BA_HEAL_TEAMMATE1(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.HLR.TEAMMATE1), + BA_HEAL_TEAMMATE2(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.HLR.TEAMMATE2), + BA_HEAL_TEAMMATE3(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.HLR.TEAMMATE3), + BA_HEAL_TEAMMATE4(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.HLR.TEAMMATE4), + BA_COLL_WAVE_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.CURRENT_WAVE), BA_COLL_CALL_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.TO_CALL), BA_COLL_LISTEN_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.CORRECT_STYLE), @@ -451,6 +456,17 @@ public enum WidgetInfo MINIGAME_TELEPORT_BUTTON(WidgetID.MINIGAME_TAB_ID, WidgetID.Minigames.TELEPORT_BUTTON), + PVP_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.PVP_WIDGET_CONTAINER), + PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER), + PVP_SKULL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL), + PVP_ATTACK_RANGE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.ATTACK_RANGE), + PVP_WORLD_SAFE_ZONE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SAFE_ZONE), + + PVP_WILDERNESS_LEVEL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.WILDERNESS_LEVEL), + + PVP_BOUNTY_HUNTER_INFO(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.BOUNTY_HUNTER_INFO), + PVP_KILLDEATH_COUNTER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.KILLDEATH_RATIO), + /* STANDARD SPELL BOOK WIDGETS*/ SPELL_LUMBRIDGE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.LUMBRIDGE_HOME_TELEPORT), SPELL_BIND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.BIND), @@ -502,13 +518,6 @@ public enum WidgetInfo /* END OF ANCIENT SPELL BOOK WIDGETS*/ - PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER), - PVP_WORLD_SAFE_ZONE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SAFE_ZONE), - - PVP_WILDERNESS_LEVEL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.WILDERNESS_LEVEL), - PVP_BOUNTY_HUNTER_INFO(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.BOUNTY_HUNTER_INFO), - PVP_KILLDEATH_COUNTER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.KILLDEATH_RATIO), - KOUREND_FAVOUR_OVERLAY(WidgetID.KOUREND_FAVOUR_GROUP_ID, WidgetID.KourendFavour.KOUREND_FAVOUR_OVERLAY), ZEAH_MESS_HALL_COOKING_DISPLAY(WidgetID.ZEAH_MESS_HALL_GROUP_ID, WidgetID.Zeah.MESS_HALL_COOKING_DISPLAY), diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 87f63d3826..7306ab0a51 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -602,6 +602,22 @@ public class ConfigManager { return Duration.ofMillis(Long.parseLong(str)); } + if (type == Map.class) + { + Map output = new HashMap<>(); + str = str.substring(1, str.length() - 1); + String[] splitStr = str.split(", "); + for (String s : splitStr) + { + String[] keyVal = s.split("="); + if (keyVal.length > 1) + { + output.put(keyVal[0], keyVal[1]); + } + } + + return output; + } return str; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginDescriptor.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginDescriptor.java index 540adecc24..78cb1d38d5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginDescriptor.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginDescriptor.java @@ -58,4 +58,6 @@ public @interface PluginDescriptor boolean developerPlugin() default false; boolean loadWhenOutdated() default false; + + String type() default ""; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoCounter.java new file mode 100644 index 0000000000..1e7b7cb3d4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoCounter.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 Hydrox6 + * 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.ammo; + +import java.awt.image.BufferedImage; +import lombok.Getter; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.ui.overlay.infobox.Counter; +import net.runelite.client.util.StackFormatter; + +public class AmmoCounter extends Counter +{ + @Getter + private int itemID; + + @Getter + private String name; + + public AmmoCounter(Plugin plugin, int itemID, int count, String name, BufferedImage image) + { + super(image, plugin, count); + this.itemID = itemID; + this.name = name; + } + + @Override + public String getText() + { + return StackFormatter.quantityToRSDecimalStack(getCount()); + } + + @Override + public String getTooltip() + { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoPlugin.java new file mode 100644 index 0000000000..b2466994a1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoPlugin.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2019 Hydrox6 + * 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.ammo; + +import java.awt.image.BufferedImage; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemComposition; +import net.runelite.api.ItemContainer; +import net.runelite.api.events.ItemContainerChanged; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; + +@PluginDescriptor( + name = "Ammo", + description = "Shows the current ammo the player has equipped", + tags = {"bolts", "darts", "chinchompa"}, + type = "utility" +) +public class AmmoPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private InfoBoxManager infoBoxManager; + + @Inject + private ItemManager itemManager; + + private AmmoCounter counterBox; + + @Override + public void startUp() throws Exception + { + clientThread.invokeLater(() -> + { + ItemContainer container = client.getItemContainer(InventoryID.EQUIPMENT); + if (container != null) + { + parseInventory(container.getItems()); + } + }); + } + + @Override + public void shutDown() throws Exception + { + infoBoxManager.removeInfoBox(counterBox); + counterBox = null; + } + + @Subscribe + public void onItemContainerChanged(ItemContainerChanged event) + { + if (event.getItemContainer() != client.getItemContainer(InventoryID.EQUIPMENT)) + { + return; + } + + parseInventory(event.getItemContainer().getItems()); + } + + private void parseInventory(Item[] items) + { + // Check for weapon slot items. This overrides the ammo slot, + // as the player will use the thrown weapon (eg. chinchompas, knives, darts) + if (items.length >= EquipmentInventorySlot.WEAPON.getSlotIdx() - 1) + { + final Item weapon = items[EquipmentInventorySlot.WEAPON.getSlotIdx()]; + final ItemComposition weaponComp = itemManager.getItemComposition(weapon.getId()); + if (weaponComp.isStackable()) + { + updateInfobox(weapon, weaponComp); + return; + } + } + + if (items.length <= EquipmentInventorySlot.AMMO.getSlotIdx()) + { + return; + } + + final Item ammo = items[EquipmentInventorySlot.AMMO.getSlotIdx()]; + final ItemComposition comp = itemManager.getItemComposition(ammo.getId()); + + if (!comp.isStackable()) + { + infoBoxManager.removeInfoBox(counterBox); + counterBox = null; + return; + } + + updateInfobox(ammo, comp); + } + + private void updateInfobox(Item item, ItemComposition comp) + { + if (counterBox != null && counterBox.getItemID() == item.getId()) + { + counterBox.setCount(item.getQuantity()); + return; + } + + infoBoxManager.removeInfoBox(counterBox); + final BufferedImage image = itemManager.getImage(item.getId(), 5, false); + counterBox = new AmmoCounter(this, item.getId(), item.getQuantity(), comp.getName(), image); + infoBoxManager.addInfoBox(counterBox); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java index 1bed02603e..764a988611 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java @@ -28,7 +28,12 @@ import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup("antiDrag") +/*@ConfigGroup( + keyName = "antiDrag", + name = "Anti Drag", + description = "Configuration for the anti drag plugin" +)*/ +@ConfigGroup("antidrag") public interface AntiDragConfig extends Config { @ConfigItem( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java index 26f926be4a..4dafc29b8c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java @@ -24,23 +24,22 @@ */ package net.runelite.client.plugins.antidrag; +import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import java.awt.event.KeyEvent; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.events.FocusChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @PluginDescriptor( - name = "Shift Anti Drag", - description = "Prevent dragging an item for a specified delay", - tags = {"antidrag", "delay", "inventory", "items"} -) + name = "Anti Drag", + type = "utility", + enabledByDefault = false) public class AntiDragPlugin extends Plugin implements KeyListener { private static final int DEFAULT_DELAY = 5; @@ -63,6 +62,7 @@ public class AntiDragPlugin extends Plugin implements KeyListener @Override protected void startUp() throws Exception { + client.setInventoryDragDelay(config.dragDelay()); keyManager.registerKeyListener(this); } @@ -79,30 +79,40 @@ public class AntiDragPlugin extends Plugin implements KeyListener } + public boolean toggleDrag = true; + @Override public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_SHIFT) + /*if (e.getKeyCode() == KeyEvent.VK_SHIFT) { client.setInventoryDragDelay(config.dragDelay()); } + client.setInventoryDragDelay(config.dragDelay());*/ } @Override public void keyReleased(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_SHIFT) - { + if (e.getKeyCode() == KeyEvent.VK_CONTROL && toggleDrag) { + + toggleDrag = false; client.setInventoryDragDelay(DEFAULT_DELAY); + + } else if (e.getKeyCode() == KeyEvent.VK_CONTROL && !toggleDrag) { + + toggleDrag = true; + client.setInventoryDragDelay(config.dragDelay()); + } } - @Subscribe + /*@Subscribe public void onFocusChanged(FocusChanged focusChanged) { if (!focusChanged.isFocused()) { client.setInventoryDragDelay(DEFAULT_DELAY); } - } + }*/ } 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 af1b361ec0..e9151c125e 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 @@ -28,9 +28,22 @@ import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; +import java.awt.*; + @ConfigGroup("aoe") public interface AoeWarningConfig extends Config { + @ConfigItem( + keyName = "pluginType", + name = "Plugin Type", + description = "Sets the group of this plugin", + hidden = true + ) + default String pluginTyoe() + { + return "PVM"; + } + @ConfigItem( keyName = "enabled", name = "AoE Warnings Enabled", 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 c3219d53b7..2fa20d725f 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 @@ -61,9 +61,10 @@ import java.util.Map; import java.util.logging.Logger; @PluginDescriptor( - name = "!AoE Warnings", + name = "AoE Warnings", description = "Shows the final destination for AoE Attack projectiles", - tags = {"bosses", "combat", "pve", "overlay"} + tags = {"bosses", "combat", "pve", "overlay"}, + type = "PVM" ) @Slf4j diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStyle.java b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStyle.java index 047363e1e4..c32ba11af3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStyle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStyle.java @@ -26,7 +26,7 @@ package net.runelite.client.plugins.attackstyles; import net.runelite.api.Skill; -enum AttackStyle +public enum AttackStyle { ACCURATE("Accurate", Skill.ATTACK), AGGRESSIVE("Aggressive", Skill.STRENGTH), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/WeaponType.java b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/WeaponType.java index ef9ba0a188..d74742fca8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/WeaponType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/WeaponType.java @@ -28,7 +28,7 @@ import java.util.HashMap; import java.util.Map; import static net.runelite.client.plugins.attackstyles.AttackStyle.*; -enum WeaponType +public enum WeaponType { TYPE_0(ACCURATE, AGGRESSIVE, null, DEFENSIVE), TYPE_1(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultOverlay.java index 5bc5959622..2cac64080d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultOverlay.java @@ -55,6 +55,11 @@ class BarbarianAssaultOverlay extends Overlay { private static final int MAX_EGG_DISTANCE = 2500; + + private final int HEALTH_BAR_HEIGHT = 20; + private final Color HEALTH_BAR_COLOR = new Color(225, 35, 0, 125); + private static final Color BACKGROUND = new Color(0, 0, 0, 150); + private final Client client; private final BarbarianAssaultPlugin plugin; private final BarbarianAssaultConfig config; @@ -156,7 +161,35 @@ class BarbarianAssaultOverlay extends Overlay } } - return null; + if (role == Role.HEALER) + { + for (HealerTeam teammate : HealerTeam.values()) + { + Widget widget = client.getWidget(teammate.getTeammate()); + if (widget == null) + { + continue; + } + + String[] teammateHealth = widget.getText().split(" / "); + final int curHealth = Integer.parseInt(teammateHealth[0]); + final int maxHealth = Integer.parseInt(teammateHealth[1]); + + int width = teammate.getWidth(); + final int filledWidth = getBarWidth(maxHealth, curHealth, width); + + int offsetX = teammate.getOffset().getX(); + int offsetY = teammate.getOffset().getY(); + int x = widget.getCanvasLocation().getX() - offsetX; + int y = widget.getCanvasLocation().getY() - offsetY; + + graphics.setColor(HEALTH_BAR_COLOR); + graphics.fillRect(x, y, filledWidth, HEALTH_BAR_HEIGHT); + } + } + + + return null; } private void renderEggLocation(Graphics2D graphics, WorldPoint location, int quantity, Color color) @@ -186,4 +219,16 @@ class BarbarianAssaultOverlay extends Overlay Point textPoint = Perspective.getCanvasTextLocation(client, graphics, groundPoint, quantityText, 0); OverlayUtil.renderTextLocation(graphics, textPoint, quantityText, Color.WHITE); } + + private static int getBarWidth(int base, int current, int size) + { + final double ratio = (double) current / base; + + if (ratio >= 1) + { + return size; + } + + return (int) Math.round(ratio * size); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/HealerTeam.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/HealerTeam.java new file mode 100644 index 0000000000..5521d620f7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/HealerTeam.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018, whartd + * 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.barbarianassault; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.runelite.api.Point; +import net.runelite.api.widgets.WidgetInfo; + +@Getter +@AllArgsConstructor +enum HealerTeam +{ + TEAMMATE1(WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2), 115), + TEAMMATE2(WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2), 115), + TEAMMATE3(WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2), 115), + TEAMMATE4(WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2), 115); + + private WidgetInfo teammate; + private Point offset; + private int width; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsPlugin.java index 7b9e195848..961e8760cb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsPlugin.java @@ -78,7 +78,8 @@ import net.runelite.client.util.Text; @PluginDescriptor( name = "BA Tools", description = "Custom tools for Barbarian Assault", - tags = {"minigame", "overlay", "timer"} + tags = {"minigame", "overlay", "timer"}, + type = "utility" ) public class BAToolsPlugin extends Plugin implements KeyListener { 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 506c9a58c0..f52ebd7260 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,89 +1,30 @@ -/* - * 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 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.Deque; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -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.Player; -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.VarClientStrChanged; -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.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; +import net.runelite.client.plugins.*; +import net.runelite.client.game.*; +import net.runelite.client.callback.*; -@PluginDescriptor( - name = "Clan Chat", - description = "Add rank icons to users talking in clan chat", - tags = {"icons", "rank", "recent"} -) +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.*; + +@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; @@ -91,508 +32,376 @@ public class ClanChatPlugin extends Plugin private static final String RECENT_TITLE = "Recent Clan Chats"; 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 = new ArrayList<>(); - private List clanMembers = new ArrayList<>(); + private List chats; + private static CopyOnWriteArrayList clanMembers; private ClanChatIndicator clanMemberCounter; - /** - * queue of temporary messages added to the client - */ - private final Deque clanJoinMessages = new ArrayDeque<>(); - private Map activityBuffer = new HashMap<>(); + private final Deque clanJoinMessages; + private Map activityBuffer; 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(); + } + @Provides - ClanChatConfig getConfig(ConfigManager configManager) - { + ClanChatConfig getConfig(final ConfigManager configManager) { return configManager.getConfig(ClanChatConfig.class); } - @Override - public void startUp() - { - chats = new ArrayList<>(Text.fromCSV(config.chatsData())); + public void startUp() { + this.chats = new ArrayList(Text.fromCSV(this.config.chatsData())); } - @Override - public void shutDown() - { - clanMembers.clear(); - removeClanCounter(); - resetClanChats(); + public void shutDown() { + ClanChatPlugin.clanMembers.clear(); + this.removeClanCounter(); + this.resetClanChats(); } @Subscribe - public void onConfigChanged(ConfigChanged configChanged) - { - if (configChanged.getGroup().equals("clanchat")) - { - if (!config.recentChats()) - { - resetClanChats(); + public void onConfigChanged(final ConfigChanged configChanged) { + if (configChanged.getGroup().equals("clanchat")) { + if (!this.config.recentChats()) { + this.resetClanChats(); } - - if (config.showClanCounter()) - { - clientThread.invoke(this::addClanCounter); + if (this.config.showClanCounter()) { + this.clientThread.invoke(this::addClanCounter); } - else - { - removeClanCounter(); + else { + this.removeClanCounter(); } } } @Subscribe - public void onClanMemberJoined(ClanMemberJoined event) - { + public void onClanMemberJoined(final ClanMemberJoined event) { final ClanMember member = event.getMember(); - - if (member.getWorld() == client.getWorld()) - { + if (member.getWorld() == this.client.getWorld()) { final String memberName = Text.toJagexName(member.getUsername()); - - for (final Player player : client.getPlayers()) - { - if (player != null && memberName.equals(Text.toJagexName(player.getName()))) - { - clanMembers.add(player); - addClanCounter(); + for (final Player player : this.client.getPlayers()) { + if (player != null && memberName.equals(Text.toJagexName(player.getName()))) { + ClanChatPlugin.clanMembers.add(player); + this.addClanCounter(); break; } } } - - // clan members getting initialized isn't relevant - if (clanJoinedTick == client.getTickCount()) - { + if (this.clanJoinedTick == this.client.getTickCount()) { return; } - - if (!config.showJoinLeave() || - member.getRank().getValue() < config.joinLeaveRank().getValue()) - { + if (!this.config.showJoinLeave() || member.getRank().getValue() < this.config.joinLeaveRank().getValue()) { return; } - - // 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); + if (!this.activityBuffer.containsKey(member.getUsername())) { + final ClanMemberActivity joinActivity = new ClanMemberActivity(ClanActivityType.JOINED, member, this.client.getTickCount()); + this.activityBuffer.put(member.getUsername(), joinActivity); } - else - { - activityBuffer.remove(member.getUsername()); + else { + this.activityBuffer.remove(member.getUsername()); } } @Subscribe - public void onClanMemberLeft(ClanMemberLeft event) - { + public void onClanMemberLeft(final ClanMemberLeft event) { final ClanMember member = event.getMember(); - - if (member.getWorld() == client.getWorld()) - { + if (member.getWorld() == this.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()))) - { + final Iterator each = ClanChatPlugin.clanMembers.iterator(); + while (each.hasNext()) { + if (memberName.equals(Text.toJagexName(each.next().getName()))) { each.remove(); - - if (clanMembers.isEmpty()) - { - removeClanCounter(); + if (ClanChatPlugin.clanMembers.isEmpty()) { + this.removeClanCounter(); + break; } - break; } } } - - if (!config.showJoinLeave() || - member.getRank().getValue() < config.joinLeaveRank().getValue()) - { + if (!this.config.showJoinLeave() || member.getRank().getValue() < this.config.joinLeaveRank().getValue()) { return; } - - if (!activityBuffer.containsKey(member.getUsername())) - { - ClanMemberActivity leaveActivity = new ClanMemberActivity(ClanActivityType.LEFT, - member, client.getTickCount()); - activityBuffer.put(member.getUsername(), leaveActivity); + if (!this.activityBuffer.containsKey(member.getUsername())) { + final ClanMemberActivity leaveActivity = new ClanMemberActivity(ClanActivityType.LEFT, member, this.client.getTickCount()); + this.activityBuffer.put(member.getUsername(), leaveActivity); } - else - { - activityBuffer.remove(member.getUsername()); + else { + this.activityBuffer.remove(member.getUsername()); } } @Subscribe - public void onGameTick(GameTick gameTick) - { - if (client.getGameState() != GameState.LOGGED_IN) - { + public void onGameTick(final GameTick gameTick) { + if (this.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)"); + 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 (config.recentChats() && clanChatList.getChildren() == null && !Strings.isNullOrEmpty(owner.getText())) - { - clanChatTitleWidget.setText(RECENT_TITLE); - - loadClanChats(); + else if (this.config.recentChats() && clanChatList.getChildren() == null && !Strings.isNullOrEmpty(owner.getText())) { + clanChatTitleWidget.setText("Recent Clan Chats"); + this.loadClanChats(); } } - - if (!config.showJoinLeave()) - { + if (!this.config.showJoinLeave()) { return; } - - timeoutClanMessages(); - - addClanActivityMessages(); + this.timeoutClanMessages(); + this.addClanActivityMessages(); } - private void timeoutClanMessages() - { - if (clanJoinMessages.isEmpty()) - { + private void timeoutClanMessages() { + if (this.clanJoinMessages.isEmpty()) { return; } - boolean removed = false; - - for (Iterator it = clanJoinMessages.iterator(); it.hasNext(); ) - { - ClanJoinMessage clanJoinMessage = it.next(); - MessageNode messageNode = clanJoinMessage.getMessageNode(); + final Iterator it = this.clanJoinMessages.iterator(); + while (it.hasNext()) { + final ClanJoinMessage clanJoinMessage = it.next(); + final MessageNode messageNode = clanJoinMessage.getMessageNode(); final int createdTick = clanJoinMessage.getTick(); - - 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 + if (this.client.getTickCount() <= createdTick + 20) { 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) - { - clientThread.invoke(() -> client.runScript(ScriptID.BUILD_CHATBOX)); + if (removed) { + this.clientThread.invoke(() -> this.client.runScript(216, new Object[0])); } } - private void addClanActivityMessages() - { - Iterator activityIt = activityBuffer.values().iterator(); - - while (activityIt.hasNext()) - { - ClanMemberActivity activity = activityIt.next(); - - if (activity.getTick() < client.getTickCount() - MESSAGE_DELAY) - { + 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) { activityIt.remove(); - addActivityMessage(activity.getMember(), activity.getActivityType()); + this.addActivityMessage(activity.getMember(), activity.getActivityType()); } } } - private void addActivityMessage(ClanMember member, ClanActivityType activityType) - { - final String activityMessage = activityType == ClanActivityType.JOINED ? " has joined." : " has left."; + private void addActivityMessage(final ClanMember member, final ClanActivityType activityType) { + final String activityMessage = (activityType == ClanActivityType.JOINED) ? " has joined." : " has left."; final ClanMemberRank rank = member.getRank(); - Color textColor = CHAT_CLAN_TEXT_OPAQUE_BACKGROUND; - Color channelColor = CHAT_CLAN_NAME_OPAQUE_BACKGROUND; + Color textColor = JagexColors.CHAT_CLAN_TEXT_OPAQUE_BACKGROUND; + Color channelColor = JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND; int rankIcon = -1; - - if (client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1) - { - textColor = CHAT_CLAN_TEXT_TRANSPARENT_BACKGROUND; - channelColor = CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND; + 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 (config.clanChatIcons() && rank != null && rank != ClanMemberRank.UNRANKED) - { - rankIcon = clanManager.getIconNumber(rank); + if (this.config.clanChatIcons() && rank != null && rank != ClanMemberRank.UNRANKED) { + rankIcon = this.clanManager.getIconNumber(rank); } - - ChatMessageBuilder message = new ChatMessageBuilder() - .append("[") - .append(channelColor, client.getClanChatName()); - if (rankIcon > -1) - { - message - .append(" ") - .img(rankIcon); + final ChatMessageBuilder message = new ChatMessageBuilder().append("[").append(channelColor, this.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(); - client.addChatMessage(ChatMessageType.FRIENDSCHATNOTIFICATION, "", messageString, ""); - - final ChatLineBuffer chatLineBuffer = client.getChatLineMap().get(ChatMessageType.FRIENDSCHATNOTIFICATION.getType()); + this.client.addChatMessage(ChatMessageType.FRIENDSCHATNOTIFICATION, "", messageString, ""); + final ChatLineBuffer chatLineBuffer = this.client.getChatLineMap().get(ChatMessageType.FRIENDSCHATNOTIFICATION.getType()); final MessageNode[] lines = chatLineBuffer.getLines(); final MessageNode line = lines[0]; - - ClanJoinMessage clanJoinMessage = new ClanJoinMessage(line, line.getId(), client.getTickCount()); - clanJoinMessages.addLast(clanJoinMessage); + final ClanJoinMessage clanJoinMessage = new ClanJoinMessage(line, line.getId(), this.client.getTickCount()); + this.clanJoinMessages.addLast(clanJoinMessage); } @Subscribe - public void onVarClientStrChanged(VarClientStrChanged strChanged) - { - if (strChanged.getIndex() == VarClientStr.RECENT_CLAN_CHAT.getIndex() && config.recentChats()) - { - updateRecentChat(client.getVar(VarClientStr.RECENT_CLAN_CHAT)); + 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)); } } @Subscribe - public void onChatMessage(ChatMessage chatMessage) - { - if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN) - { + public void onChatMessage(final ChatMessage chatMessage) { + if (this.client.getGameState() != GameState.LOADING && this.client.getGameState() != GameState.LOGGED_IN) { return; } - - if (client.getClanChatCount() <= 0) - { + if (this.client.getClanChatCount() <= 0) { return; } - - switch (chatMessage.getType()) - { + switch (chatMessage.getType()) { case PRIVATECHAT: - case MODPRIVATECHAT: - if (!config.privateMessageIcons()) - { + case MODPRIVATECHAT: { + if (!this.config.privateMessageIcons()) { return; } break; + } case PUBLICCHAT: - case MODCHAT: - if (!config.publicChatIcons()) - { + case MODCHAT: { + if (!this.config.publicChatIcons()) { return; } break; - case FRIENDSCHAT: - if (!config.clanChatIcons()) - { + } + case FRIENDSCHAT: { + if (!this.config.clanChatIcons()) { return; } break; - default: + } + default: { return; + } } - - insertClanRankIcon(chatMessage); + this.insertClanRankIcon(chatMessage); } @Subscribe - public void onGameStateChanged(GameStateChanged state) - { - GameState gameState = state.getGameState(); - - if (gameState == GameState.LOGIN_SCREEN || gameState == GameState.CONNECTION_LOST || gameState == GameState.HOPPING) - { - clanMembers.clear(); - removeClanCounter(); - - clanJoinMessages.clear(); + 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(); } } @Subscribe - public void onPlayerSpawned(PlayerSpawned event) - { - if (event.getPlayer().isClanMember()) - { - clanMembers.add(event.getPlayer()); - addClanCounter(); + public void onPlayerSpawned(final PlayerSpawned event) { + if (event.getPlayer().isClanMember()) { + ClanChatPlugin.clanMembers.add(event.getPlayer()); + this.addClanCounter(); } } @Subscribe - public void onPlayerDespawned(PlayerDespawned event) - { - if (clanMembers.remove(event.getPlayer()) && clanMembers.isEmpty()) - { - removeClanCounter(); + public void onPlayerDespawned(final PlayerDespawned event) { + if (ClanChatPlugin.clanMembers.remove(event.getPlayer()) && ClanChatPlugin.clanMembers.isEmpty()) { + this.removeClanCounter(); } } @Subscribe - public void onClanChanged(ClanChanged event) - { - if (event.isJoined()) - { - clanJoinedTick = client.getTickCount(); + public void onClanChanged(final ClanChanged event) { + if (event.isJoined()) { + this.clanJoinedTick = this.client.getTickCount(); } - else - { - clanMembers.clear(); - removeClanCounter(); + else { + ClanChatPlugin.clanMembers.clear(); + this.removeClanCounter(); } - - activityBuffer.clear(); + this.activityBuffer.clear(); } - int getClanAmount() - { - return clanMembers.size(); + int getClanAmount() { + return ClanChatPlugin.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); + 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); 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()); } - client.refreshChat(); + this.client.refreshChat(); } } - private void resetClanChats() - { - Widget clanChatList = client.getWidget(WidgetInfo.CLAN_CHAT_LIST); - Widget clanChatTitleWidget = client.getWidget(WidgetInfo.CLAN_CHAT_TITLE); - - if (clanChatList == null) - { + 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) { return; } - - if (client.getClanChatCount() == 0) - { + if (this.client.getClanChatCount() == 0) { clanChatList.setChildren(null); } - - clanChatTitleWidget.setText(CLAN_CHAT_TITLE); + clanChatTitleWidget.setText("Clan Chat"); } - private void loadClanChats() - { - Widget clanChatList = client.getWidget(WidgetInfo.CLAN_CHAT_LIST); - if (clanChatList == null) - { + private void loadClanChats() { + final Widget clanChatList = this.client.getWidget(WidgetInfo.CLAN_CHAT_LIST); + if (clanChatList == null) { return; } - int y = 2; clanChatList.setChildren(null); - for (String chat : Lists.reverse(chats)) - { - Widget widget = clanChatList.createChild(-1, WidgetType.TEXT); + for (final String chat : Lists.reverse(this.chats)) { + final Widget widget = clanChatList.createChild(-1, 4); widget.setFontId(494); - widget.setTextColor(0xffffff); + widget.setTextColor(16777215); widget.setText(chat); widget.setOriginalHeight(14); widget.setOriginalWidth(142); widget.setOriginalY(y); widget.setOriginalX(20); widget.revalidate(); - y += 14; } } - private void updateRecentChat(String s) - { - if (Strings.isNullOrEmpty(s)) - { + private void updateRecentChat(String s) { + if (Strings.isNullOrEmpty(s)) { return; } - s = Text.toJagexName(s); - - chats.removeIf(s::equalsIgnoreCase); - chats.add(s); - - while (chats.size() > MAX_CHATS) - { - chats.remove(0); + 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); } - - config.chatsData(Text.toCSV(chats)); + this.config.chatsData(Text.toCSV(this.chats)); } - private void removeClanCounter() - { - infoBoxManager.removeInfoBox(clanMemberCounter); - clanMemberCounter = null; + private void removeClanCounter() { + this.infoBoxManager.removeInfoBox(this.clanMemberCounter); + this.clanMemberCounter = null; } - private void addClanCounter() - { - if (!config.showClanCounter() || clanMemberCounter != null || clanMembers.isEmpty()) - { + private void addClanCounter() { + if (!this.config.showClanCounter() || this.clanMemberCounter != null || ClanChatPlugin.clanMembers.isEmpty()) { return; } + final BufferedImage image = this.spriteManager.getSprite(904, 0); + this.clanMemberCounter = new ClanChatIndicator(image, this); + this.infoBoxManager.addInfoBox(this.clanMemberCounter); + } - final BufferedImage image = spriteManager.getSprite(SpriteID.TAB_CLAN_CHAT, 0); - clanMemberCounter = new ClanChatIndicator(image, this); - infoBoxManager.addInfoBox(clanMemberCounter); + static { + ClanChatPlugin.clanMembers = new CopyOnWriteArrayList(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java index d71d054674..7821fd8946 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java @@ -22,9 +22,10 @@ import net.runelite.client.util.Text; import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( - name = "!Clan Man Mode", + name = "Clan Man Mode", description = "Assists in clan PVP scenarios", - tags = {"highlight", "minimap", "overlay", "players"} + tags = {"highlight", "minimap", "overlay", "players"}, + type = "PVP" ) public class ClanManModePlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 6f5712f4a8..6759c7fa58 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -82,6 +82,7 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginInstantiationException; import net.runelite.client.plugins.PluginManager; +import net.runelite.client.plugins.pluginsorter.PluginSorterPlugin; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.DynamicGridLayout; import net.runelite.client.ui.PluginPanel; @@ -112,7 +113,7 @@ public class ConfigPanel extends PluginPanel private final ScheduledExecutorService executorService; private final RuneLiteConfig runeLiteConfig; private final ChatColorConfig chatColorConfig; - private final List pluginList = new ArrayList<>(); + public static List pluginList = new ArrayList<>(); private final IconTextField searchBar = new IconTextField(); private final JPanel topPanel; @@ -187,40 +188,123 @@ public class ConfigPanel extends PluginPanel initializePluginList(); refreshPluginList(); + } private void initializePluginList() { final List pinnedPlugins = getPinnedPluginNames(); - // populate pluginList with all non-hidden plugins + List pvmPlugins = new ArrayList<>(); + // populate pluginList with all PVM Plugins pluginManager.getPlugins().stream() - .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden()) + .filter(plugin -> plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("PVM")) .forEach(plugin -> { final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class); final Config config = pluginManager.getPluginConfigProxy(plugin); final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config); - final PluginListItem listItem = new PluginListItem(this, plugin, descriptor, config, configDescriptor); + final PluginListItem listItem = new PluginListItem(this, configManager, plugin, descriptor, config, configDescriptor); + System.out.println("Started "+listItem.getName()); listItem.setPinned(pinnedPlugins.contains(listItem.getName())); - pluginList.add(listItem); + pvmPlugins.add(listItem); }); + pvmPlugins.sort(Comparator.comparing(PluginListItem::getName)); + for (PluginListItem plugin : pvmPlugins) + pluginList.add(plugin); + + List pvpPlugins = new ArrayList<>(); + // populate pluginList with all PVP Plugins + pluginManager.getPlugins().stream() + .filter(plugin -> plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("PVP")) + .forEach(plugin -> + { + final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class); + final Config config = pluginManager.getPluginConfigProxy(plugin); + final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config); + + final PluginListItem listItem = new PluginListItem(this, configManager, plugin, descriptor, config, configDescriptor); + System.out.println("Started "+listItem.getName()); + listItem.setPinned(pinnedPlugins.contains(listItem.getName())); + pvpPlugins.add(listItem); + }); + + pvpPlugins.sort(Comparator.comparing(PluginListItem::getName)); + for (PluginListItem plugin : pvpPlugins) + pluginList.add(plugin); + + List utilPlugins = new ArrayList<>(); + // populate pluginList with all PVP Plugins + pluginManager.getPlugins().stream() + .filter(plugin -> plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("utility")) + .forEach(plugin -> + { + final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class); + final Config config = pluginManager.getPluginConfigProxy(plugin); + final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config); + + final PluginListItem listItem = new PluginListItem(this, configManager, plugin, descriptor, config, configDescriptor); + System.out.println("Started "+listItem.getName()); + listItem.setPinned(pinnedPlugins.contains(listItem.getName())); + utilPlugins.add(listItem); + }); + + utilPlugins.sort(Comparator.comparing(PluginListItem::getName)); + for (PluginListItem plugin : utilPlugins) + pluginList.add(plugin); + + // populate pluginList with all vanilla RL plugins + List vanillaPlugins = new ArrayList<>(); + pluginManager.getPlugins().stream() + .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden()) + .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("PVM")) + .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("PVP")) + .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("utility")) + .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("pluginOrganizer")) + .forEach(plugin -> + { + final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class); + final Config config = pluginManager.getPluginConfigProxy(plugin); + final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config); + + final PluginListItem listItem = new PluginListItem(this, configManager, plugin, descriptor, config, configDescriptor); + listItem.setPinned(pinnedPlugins.contains(listItem.getName())); + vanillaPlugins.add(listItem); + } + ); + + vanillaPlugins.sort(Comparator.comparing(PluginListItem::getName)); + for (PluginListItem plugin : vanillaPlugins) + pluginList.add(plugin); + // add special entries for core client configurations - final PluginListItem runeLite = new PluginListItem(this, runeLiteConfig, + final PluginListItem runeLite = new PluginListItem(this, configManager, runeLiteConfig, configManager.getConfigDescriptor(runeLiteConfig), RUNELITE_PLUGIN, "RuneLite client settings", "client"); runeLite.setPinned(pinnedPlugins.contains(RUNELITE_PLUGIN)); pluginList.add(runeLite); - final PluginListItem chatColor = new PluginListItem(this, chatColorConfig, + final PluginListItem chatColor = new PluginListItem(this, configManager, chatColorConfig, configManager.getConfigDescriptor(chatColorConfig), CHAT_COLOR_PLUGIN, "Recolor chat text", "colour", "messages"); chatColor.setPinned(pinnedPlugins.contains(CHAT_COLOR_PLUGIN)); pluginList.add(chatColor); - pluginList.sort(Comparator.comparing(PluginListItem::getName)); + // Add plugin sorter to bottom + pluginManager.getPlugins().stream() + .filter(plugin -> plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("pluginOrganizer")) + .forEach(plugin -> + { + final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class); + final Config config = pluginManager.getPluginConfigProxy(plugin); + final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config); + + final PluginListItem listItem = new PluginListItem(this, configManager, plugin, descriptor, config, configDescriptor); + System.out.println("Started "+listItem.getName()); + pluginList.add(listItem); + }); } void refreshPluginList() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java index c6a23544c7..6f52c04660 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.annotation.Nullable; +import javax.inject.Inject; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; @@ -40,16 +41,20 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigDescriptor; +import net.runelite.client.config.ConfigItemDescriptor; +import net.runelite.client.config.ConfigManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.IconButton; +import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ImageUtil; import org.apache.commons.text.similarity.JaroWinklerDistance; -class PluginListItem extends JPanel +public class PluginListItem extends JPanel { private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance(); + public JLabel nameLabel; private static final ImageIcon CONFIG_ICON; private static final ImageIcon CONFIG_ICON_HOVER; @@ -59,6 +64,7 @@ class PluginListItem extends JPanel private static final ImageIcon OFF_STAR; private final ConfigPanel configPanel; + public final ConfigManager configManager; @Getter @Nullable @@ -70,7 +76,7 @@ class PluginListItem extends JPanel @Nullable @Getter(AccessLevel.PACKAGE) - private final ConfigDescriptor configDescriptor; + public final ConfigDescriptor configDescriptor; @Getter private final String name; @@ -120,26 +126,27 @@ class PluginListItem extends JPanel * Note that {@code config} and {@code configDescriptor} can be {@code null} * if there is no configuration associated with the plugin. */ - PluginListItem(ConfigPanel configPanel, Plugin plugin, PluginDescriptor descriptor, + PluginListItem(ConfigPanel configPanel, ConfigManager configManager, Plugin plugin, PluginDescriptor descriptor, @Nullable Config config, @Nullable ConfigDescriptor configDescriptor) { - this(configPanel, plugin, config, configDescriptor, + this(configPanel, configManager, plugin, config, configDescriptor, descriptor.name(), descriptor.description(), descriptor.tags()); } /** * Creates a new {@code PluginListItem} for a core configuration. */ - PluginListItem(ConfigPanel configPanel, Config config, ConfigDescriptor configDescriptor, + PluginListItem(ConfigPanel configPanel, ConfigManager configManager, Config config, ConfigDescriptor configDescriptor, String name, String description, String... tags) { - this(configPanel, null, config, configDescriptor, name, description, tags); + this(configPanel, configManager, null, config, configDescriptor, name, description, tags); } - private PluginListItem(ConfigPanel configPanel, @Nullable Plugin plugin, @Nullable Config config, + private PluginListItem(ConfigPanel configPanel, ConfigManager configManager, @Nullable Plugin plugin, @Nullable Config config, @Nullable ConfigDescriptor configDescriptor, String name, String description, String... tags) { this.configPanel = configPanel; + this.configManager = configManager; this.plugin = plugin; this.config = config; this.configDescriptor = configDescriptor; @@ -152,8 +159,7 @@ class PluginListItem extends JPanel setLayout(new BorderLayout(3, 0)); setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH, 20)); - JLabel nameLabel = new JLabel(name); - nameLabel.setForeground(Color.WHITE); + nameLabel = new JLabel(name); if (!description.isEmpty()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java index 8af1567609..5ea9ea76b6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java @@ -32,8 +32,10 @@ import java.util.*; import java.util.concurrent.ScheduledExecutorService; @PluginDescriptor( - name = "!Equipment Inspector", - enabledByDefault = false + name = "Equipment Inspector", + description = "Inspects enemy equipment", + enabledByDefault = false, + type = "utility" ) @Slf4j diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java index ec1f1acc45..0d1beab3e7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java @@ -87,4 +87,26 @@ public interface XpDropConfig extends Config return 0; } + @ConfigItem( + keyName = "showDamage", + name = "Show Damage on XP Drop", + description = "Show what you hit next to the XP drop", + position = 5 + ) + default boolean showDamage() + { + return false; + } + + @ConfigItem( + keyName = "damageColor", + name = "Damage Color", + description = "The color you want the text to be for damage", + position = 6 + ) + default Color getDamageColor() + { + return Color.RED; + } + } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropOverlay.java new file mode 100644 index 0000000000..119da63597 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropOverlay.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2017, honeyhoney + * 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.experiencedrop; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; + +import net.runelite.api.Actor; +import net.runelite.api.Point; +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; + +class XpDropOverlay extends Overlay +{ + private final XpDropPlugin plugin; + private final XpDropConfig config; + + @Inject + private XpDropOverlay(XpDropPlugin plugin, XpDropConfig config) + { + this.plugin = plugin; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.MED); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (config.showDamage()) + { + final Actor opponent = plugin.getLastOpponent(); + if (opponent != null) + { + int offset = opponent.getLogicalHeight() + 50; + String damageStr = String.valueOf(this.plugin.getDamage()); + Point textLocation = opponent.getCanvasTextLocation(graphics, damageStr, offset); + + if (textLocation != null && this.plugin.getDamage() != 0) + { + OverlayUtil.renderTextLocation(graphics, textLocation, damageStr, config.getDamageColor()); + } + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java index aca9477123..cb7c698195 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java @@ -25,26 +25,38 @@ package net.runelite.client.plugins.experiencedrop; import com.google.inject.Provides; + +import java.time.Duration; +import java.time.Instant; import java.util.Arrays; import java.util.EnumMap; import java.util.Map; import java.util.stream.IntStream; import javax.inject.Inject; -import net.runelite.api.Client; + +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.*; + import static net.runelite.api.ScriptID.XPDROP_DISABLED; -import net.runelite.api.Skill; -import net.runelite.api.SpriteID; -import net.runelite.api.Varbits; -import net.runelite.api.events.ExperienceChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.WidgetHiddenChanged; +import static net.runelite.client.plugins.attackstyles.AttackStyle.*; + +import net.runelite.api.events.*; 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.eventbus.Subscribe; +import net.runelite.client.game.HiscoreManager; +import net.runelite.client.game.NPCManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.attackstyles.AttackStyle; +import net.runelite.client.plugins.attackstyles.WeaponType; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.Text; +import net.runelite.http.api.hiscore.HiscoreEndpoint; +import net.runelite.http.api.hiscore.HiscoreResult; @PluginDescriptor( name = "XP Drop", @@ -54,6 +66,7 @@ import net.runelite.client.plugins.PluginDescriptor; public class XpDropPlugin extends Plugin { private static final int XPDROP_PADDING = 2; // space between xp drop icons + private static final Duration WAIT = Duration.ofSeconds(5); @Inject private Client client; @@ -63,11 +76,39 @@ public class XpDropPlugin extends Plugin private int tickCounter = 0; private int previousExpGained; + private boolean hasHit = false; private boolean hasDropped = false; private boolean correctPrayer; private Skill lastSkill = null; private Map previousSkillExpTable = new EnumMap<>(Skill.class); private PrayerType currentTickPrayer; + private AttackStyle attackStyle; + private int attackStyleVarbit = -1; + private int equippedWeaponTypeVarbit = -1; + private int castingModeVarbit = -1; + private int opponentHealth = -1; + private int xpGains = 0; + private AttackStyle[] offensiveStyles = {ACCURATE, AGGRESSIVE, DEFENSIVE, CONTROLLED, RANGING, LONGRANGE, CASTING, DEFENSIVE_CASTING}; + + @Getter(AccessLevel.PACKAGE) + private int damage = 0; + + @Getter(AccessLevel.PACKAGE) + private Actor lastOpponent; + + private Instant lastTime; + + @Inject + private OverlayManager overlayManager; + + @Inject + private XpDropOverlay overlay; + + @Inject + private NPCManager npcManager; + + @Inject + private HiscoreManager hiscoreManager; @Provides XpDropConfig provideConfig(ConfigManager configManager) @@ -75,6 +116,23 @@ public class XpDropPlugin extends Plugin return configManager.getConfig(XpDropConfig.class); } + @Override + protected void startUp() throws Exception + { + lastOpponent = null; + overlayManager.add(overlay); + if (client.getGameState() == GameState.LOGGED_IN) + { + attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE); + equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE); + castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE); + updateAttackStyle( + equippedWeaponTypeVarbit, + attackStyleVarbit, + castingModeVarbit); + } + } + @Subscribe public void onWidgetHiddenChanged(WidgetHiddenChanged event) { @@ -203,6 +261,42 @@ public class XpDropPlugin extends Plugin @Subscribe public void onGameTick(GameTick tick) { + // Detect hitting a 0 + if (lastOpponent != null) + { + int health = calculateHealth(lastOpponent); + if (health != -1 && opponentHealth != -1 && health == opponentHealth && hasHit) + { + damage = 0; + hasHit = false; + } + } + + // Handle getting XP gains + if (hasDropped) + { + if (xpGains != 0 && attackStyle.getSkills().length > 1 && attackStyle != LONGRANGE) + { + damage = (int) (xpGains / (attackStyle.getSkills().length * 1.3)); + } + else if (xpGains != 0) + { + damage = xpGains / 4; + } + + xpGains = 0; + hasDropped = false; + } + + // Clear opponent + if (lastOpponent != null && lastTime != null && client.getLocalPlayer().getInteracting() == null) + { + if (Duration.between(lastTime, Instant.now()).compareTo(WAIT) > 0) + { + lastOpponent = null; + } + } + currentTickPrayer = getActivePrayerType(); correctPrayer = false; @@ -240,9 +334,115 @@ public class XpDropPlugin extends Plugin Integer previous = previousSkillExpTable.put(skill, xp); if (previous != null) { + opponentHealth = calculateHealth(lastOpponent); previousExpGained = xp - previous; + if (skill != Skill.HITPOINTS && Arrays.stream(offensiveStyles).anyMatch(attackStyle::equals)) + { + xpGains += previousExpGained; + } + hasDropped = true; + hasHit = true; } } + private void updateAttackStyle(int equippedWeaponType, int attackStyleIndex, int castingMode) + { + AttackStyle[] attackStyles = WeaponType.getWeaponType(equippedWeaponType).getAttackStyles(); + if (attackStyleIndex < attackStyles.length) + { + attackStyle = attackStyles[attackStyleIndex]; + if (attackStyle == null) + { + attackStyle = OTHER; + } + else if ((attackStyle == CASTING) && (castingMode == 1)) + { + attackStyle = DEFENSIVE_CASTING; + } + } + } + + @Subscribe + public void onInteractingChanged(InteractingChanged event) + { + if (event.getSource() != client.getLocalPlayer()) + { + return; + } + + Actor opponent = event.getTarget(); + + if (opponent == null) + { + lastTime = Instant.now(); + return; + } + + damage = 0; + lastOpponent = opponent; + opponentHealth = calculateHealth(opponent); + } + + private int calculateHealth(Actor target) + { + if (target == null || target.getName() == null) + { + return -1; + } + + final int healthScale = target.getHealth(); + final int healthRatio = target.getHealthRatio(); + final String targetName = Text.removeTags(target.getName()); + + Integer maxHealth = -1; + if (target instanceof NPC) + { + maxHealth = npcManager.getHealth(targetName, target.getCombatLevel()); + } + else if (target instanceof Player) + { + final HiscoreResult hiscoreResult = hiscoreManager.lookupAsync(targetName, HiscoreEndpoint.NORMAL); + if (hiscoreResult != null) + { + final int hp = hiscoreResult.getHitpoints().getLevel(); + if (hp > 0) + { + maxHealth = hp; + } + } + } + + if (healthRatio < 0 || healthScale <= 0 || maxHealth == null) + { + return -1; + } + + return (int)((maxHealth * healthRatio / healthScale) + 0.5f); + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + if (attackStyleVarbit == -1 || attackStyleVarbit != client.getVar(VarPlayer.ATTACK_STYLE)) + { + attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE); + updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), attackStyleVarbit, + client.getVar(Varbits.DEFENSIVE_CASTING_MODE)); + } + + if (equippedWeaponTypeVarbit == -1 || equippedWeaponTypeVarbit != client.getVar(Varbits.EQUIPPED_WEAPON_TYPE)) + { + equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE); + updateAttackStyle(equippedWeaponTypeVarbit, client.getVar(VarPlayer.ATTACK_STYLE), + client.getVar(Varbits.DEFENSIVE_CASTING_MODE)); + } + + if (castingModeVarbit == -1 || castingModeVarbit != client.getVar(Varbits.DEFENSIVE_CASTING_MODE)) + { + castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE); + updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), client.getVar(VarPlayer.ATTACK_STYLE), + castingModeVarbit); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperPlugin.java index 4eeb311101..8488545015 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperPlugin.java @@ -15,9 +15,10 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( - name = "!Fight Cave - Jad", + name = "Fight Cave - Jad", description = "Show what to pray against Jad", tags = {"bosses", "combat", "minigame", "overlay", "prayer", "pve", "pvm"}, + type = "PVM", enabledByDefault = false ) public class FightCaveJadHelperPlugin extends Plugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperPlugin.java index d06451a9d0..b3321a3b33 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperPlugin.java @@ -45,9 +45,10 @@ import net.runelite.client.ui.overlay.OverlayManager; import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( - name = "!Fight Cave - Waves", + name = "Fight Cave - Waves", description = "Displays current and upcoming wave monsters in the Fight Caves", tags = {"bosses", "combat", "minigame", "overlay", "pve", "pvm", "jad", "fire", "cape", "wave"}, + type = "PVM", enabledByDefault = false ) public class FightCaveWaveHelperPlugin extends Plugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingConfig.java new file mode 100644 index 0000000000..cb66dc3e54 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingConfig.java @@ -0,0 +1,58 @@ +package net.runelite.client.plugins.fkeyremapping; + +import net.runelite.client.config.Config; + +import java.awt.event.KeyEvent; + +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.Keybind; + +@ConfigGroup("fkeyremapping") +public interface fKeyRemappingConfig extends Config { + @ConfigItem( + position = 1, + keyName = "F1", + name = "F1 Key", + description = "The key which will replace F1." + ) + default Keybind f1() + { + return new Keybind(KeyEvent.VK_Q, 0); + } + + @ConfigItem( + position = 2, + keyName = "F2", + name = "F2 key", + description = "The key which will replace F2." + ) + default Keybind f2() + { + return new Keybind(KeyEvent.VK_W, 0); + } + + @ConfigItem( + position = 3, + keyName = "F3", + name = "F3 key", + description = "The key which will replace F3." + ) + default Keybind f3() + { + return new Keybind(KeyEvent.VK_E, 0); + } + + @ConfigItem( + position = 4, + keyName = "F4", + name = "F4 Key key", + description = "The key which will replace F4." + ) + default Keybind f4() + { + return new Keybind(KeyEvent.VK_R, 0); + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingListener.java new file mode 100644 index 0000000000..6b2ac82124 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingListener.java @@ -0,0 +1,95 @@ +package net.runelite.client.plugins.fkeyremapping; + +import java.awt.event.KeyEvent; +import java.util.HashMap; +import java.util.Map; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.input.KeyListener; +import net.runelite.client.input.MouseAdapter; + +class fKeyRemappingListener extends MouseAdapter implements KeyListener +{ + @Inject + private fKeyRemappingPlugin plugin; + + @Inject + private fKeyRemappingConfig config; + + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + private final Map modified = new HashMap<>(); + + @Override + public void keyTyped(KeyEvent e) + { + } + + @Override + public void keyPressed(KeyEvent e) + { + if (client.getGameState() != GameState.LOGGED_IN || !plugin.chatboxFocused()) + { + return; + } + + + if (config.f1().matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F1); + e.setKeyCode(KeyEvent.VK_F1); + } + else if (config.f2().matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F2); + e.setKeyCode(KeyEvent.VK_F2); + } + else if (config.f3().matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F3); + e.setKeyCode(KeyEvent.VK_F3); + } + else if (config.f4().matches(e)) + { + modified.put(e.getKeyCode(), KeyEvent.VK_F4); + e.setKeyCode(KeyEvent.VK_F4); + } + + + } + + @Override + public void keyReleased(KeyEvent e) + { + if (client.getGameState() != GameState.LOGGED_IN || !plugin.chatboxFocused()) + { + return; + } + + modified.remove(e.getKeyCode()); + + if (config.f1().matches(e)) + { + e.setKeyCode(KeyEvent.VK_F1); + } + else if (config.f2().matches(e)) + { + e.setKeyCode(KeyEvent.VK_F2); + } + else if (config.f3().matches(e)) + { + e.setKeyCode(KeyEvent.VK_F3); + } + else if (config.f4().matches(e)) + { + e.setKeyCode(KeyEvent.VK_F4); + } + + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java new file mode 100644 index 0000000000..78199bfcc5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java @@ -0,0 +1,83 @@ +package net.runelite.client.plugins.fkeyremapping; + +import com.google.inject.Provides; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.VarClientInt; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.input.KeyManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +@PluginDescriptor( + name = "fKeyRemapping", + description = "Used for interface hotkeys", + tags = {"hotkey", "remapping"}, + enabledByDefault = true +) +public class fKeyRemappingPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private KeyManager keyManager; + + @Inject + private fKeyRemappingListener inputListener; + + + @Override + protected void startUp() throws Exception + { + keyManager.registerKeyListener(inputListener); + + + } + + @Override + protected void shutDown() throws Exception + { + + + keyManager.unregisterKeyListener(inputListener); + } + + @Provides + fKeyRemappingConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(fKeyRemappingConfig.class); + } + + boolean chatboxFocused() + { + Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT); + if (chatboxParent == null || chatboxParent.getOnKeyListener() == null) + { + return false; + } + + // the search box on the world map can be focused, and chat input goes there, even + // though the chatbox still has its key listener. + Widget worldMapSearch = client.getWidget(WidgetInfo.WORLD_MAP_SEARCH); + if (worldMapSearch != null && client.getVar(VarClientInt.WORLD_MAP_SEARCH_FOCUSED) == 1) + { + return false; + } + + return true; + } + + + + + + + +} 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 878270bfd4..50f81cf94f 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 @@ -57,9 +57,10 @@ import net.runelite.client.util.ImageUtil; import org.slf4j.Logger; @PluginDescriptor( - name = "!Freeze Timers", + name = "Freeze Timers", description = "PVP Freeze Timers", - tags = {"PvP", "Freeze", "Timers"} + tags = {"PvP", "Freeze", "Timers"}, + type = "PVP" ) public class FreezeTimersPlugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java index d6df9dc49f..a7f59a7bed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java @@ -30,9 +30,10 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( - name = "!Grotesque Guardians", + name = "Grotesque Guardians", description = "Display tile indicators for the Grotesque Guardian special attacks", - tags = {"grotesque", "guardians", "gargoyle", "garg"} + tags = {"grotesque", "guardians", "gargoyle", "garg"}, + type = "PVM" ) public class GrotesqueGuardiansPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java index 768d90b51b..ec1814bde4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java @@ -43,7 +43,6 @@ import net.runelite.client.ui.overlay.OverlayUtil; public class GroundMarkerOverlay extends Overlay { - private static final int MAX_DRAW_DISTANCE = 32; private final Client client; private final GroundMarkerConfig config; @@ -87,12 +86,6 @@ public class GroundMarkerOverlay extends Overlay private void drawTile(Graphics2D graphics, WorldPoint point, Color color) { - WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); - - if (point.distanceTo(playerLocation) >= MAX_DRAW_DISTANCE) - { - return; - } LocalPoint lp = LocalPoint.fromWorld(client, point); if (lp == null) 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 df473a5d0d..61f9b91b44 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 @@ -20,8 +20,9 @@ import java.util.Objects; import java.util.stream.Collectors; @PluginDescriptor( - name = "!Hide Prayers", - description = "Hides specific Prayers in the Prayer tab." + name = "Hide Prayers", + description = "Hides specific Prayers in the Prayer tab.", + type = "utility" ) public class HidePrayersPlugin extends Plugin { private static final int PRAYER_COUNT = Prayer.values().length; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPlugin.java index ba8c0317a7..f976a9cd2b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPlugin.java @@ -17,7 +17,8 @@ import java.util.Map; @PluginDescriptor( name = "Hydra", description = "Hydra Helper", - tags = {"Hydra", "Helper"} + tags = {"Hydra", "Helper"}, + type = "PVM" ) public class HydraPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerConfig.java new file mode 100644 index 0000000000..38ff6d6e3d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerConfig.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019 Hydrox6 + * 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.inventoryviewer; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup(InventoryViewerPlugin.CONFIG_GROUP_KEY) +public interface InventoryViewerConfig extends Config +{ + @ConfigItem( + keyName = "viewerMode", + name = "Mode", + description = "The mode to display the inventory viewer with" + ) + default InventoryViewerMode viewerMode() + { + return InventoryViewerMode.FULL; + } + + @ConfigItem( + keyName = "showFreeSlots", + name = "Show Free Slots", + description = "Whether to show a label with the free slots in the inventory" + ) + default boolean showFreeSlots() + { + return false; + } + + @ConfigItem( + keyName = "hideWhenInvOpen", + name = "Hide when inventory is open", + description = "Hide the inventory viewer when the player's inventory is open" + ) + default boolean hideWhenInvOpen() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerMode.java new file mode 100644 index 0000000000..562ae8c972 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerMode.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019 Hydrox6 + * 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.inventoryviewer; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum InventoryViewerMode +{ + FULL("Full"), + GROUPED("Grouped"); + + private final String name; + + @Override + public String toString() + { + return name; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerOverlay.java index 71da3492aa..d66718f4c0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerOverlay.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 AWPH-I + * Copyright (c) 2019 Hydrox6 * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,9 +25,12 @@ */ package net.runelite.client.plugins.inventoryviewer; +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Rectangle; import java.awt.image.BufferedImage; import javax.inject.Inject; import net.runelite.api.Client; @@ -34,11 +38,14 @@ import net.runelite.api.InventoryID; import net.runelite.api.Item; import net.runelite.api.ItemComposition; import net.runelite.api.ItemContainer; +import net.runelite.api.VarClientInt; import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ComponentConstants; import net.runelite.client.ui.overlay.components.ImageComponent; import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; class InventoryViewerOverlay extends Overlay { @@ -49,23 +56,49 @@ class InventoryViewerOverlay extends Overlay private final Client client; private final ItemManager itemManager; + private final InventoryViewerConfig config; - private final PanelComponent panelComponent = new PanelComponent(); + private final PanelComponent wrapperComponent = new PanelComponent(); + private final PanelComponent inventoryComponent = new PanelComponent(); + private final TitleComponent freeSlotsComponent = TitleComponent.builder().build(); @Inject - private InventoryViewerOverlay(Client client, ItemManager itemManager) + private InventoryViewerOverlay(Client client, ItemManager itemManager, InventoryViewerConfig config) { setPosition(OverlayPosition.BOTTOM_RIGHT); - panelComponent.setWrapping(4); - panelComponent.setGap(new Point(6, 4)); - panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + + inventoryComponent.setWrapping(4); + inventoryComponent.setGap(new Point(6, 4)); + inventoryComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + inventoryComponent.setBackgroundColor(null); + inventoryComponent.setBorder(new Rectangle( + 0, + ComponentConstants.STANDARD_BORDER, + 0, + ComponentConstants.STANDARD_BORDER)); + + wrapperComponent.setOrientation(PanelComponent.Orientation.VERTICAL); + wrapperComponent.setWrapping(2); + wrapperComponent.setBorder(new Rectangle( + ComponentConstants.STANDARD_BORDER * 2, + ComponentConstants.STANDARD_BORDER, + ComponentConstants.STANDARD_BORDER * 2, + ComponentConstants.STANDARD_BORDER)); + this.itemManager = itemManager; this.client = client; + this.config = config; } @Override public Dimension render(Graphics2D graphics) { + if (config.hideWhenInvOpen() + && client.getVar(VarClientInt.PLAYER_INVENTORY_OPENED) == 3) + { + return null; + } + final ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY); if (itemContainer == null) @@ -73,10 +106,50 @@ class InventoryViewerOverlay extends Overlay return null; } - panelComponent.getChildren().clear(); + inventoryComponent.getChildren().clear(); + wrapperComponent.getChildren().clear(); final Item[] items = itemContainer.getItems(); + if (config.viewerMode() == InventoryViewerMode.GROUPED) + { + Multiset totals = HashMultiset.create(); + for (Item item : items) + { + if (item.getId() != -1) + { + totals.add(item.getId(), item.getQuantity()); + } + } + + final long remaining = INVENTORY_SIZE - totals.size(); + if (remaining == INVENTORY_SIZE) + { + return null; + } + + for (Multiset.Entry cursor : totals.entrySet()) + { + final BufferedImage image = itemManager.getImage(cursor.getElement(), cursor.getCount(), true); + if (image != null) + { + inventoryComponent.getChildren().add(new ImageComponent(image)); + } + } + wrapperComponent.getChildren().add(inventoryComponent); + + if (config.showFreeSlots()) + { + freeSlotsComponent.setText(remaining + " free"); + wrapperComponent.setPreferredSize(new Dimension(Math.min(totals.elementSet().size(), 4) * (PLACEHOLDER_WIDTH + 6) + ComponentConstants.STANDARD_BORDER * 2, 0)); + wrapperComponent.getChildren().add(freeSlotsComponent); + } + + return wrapperComponent.render(graphics); + } + + int remaining = 28; + for (int i = 0; i < INVENTORY_SIZE; i++) { if (i < items.length) @@ -84,20 +157,30 @@ class InventoryViewerOverlay extends Overlay final Item item = items[i]; if (item.getQuantity() > 0) { + remaining -= 1; final BufferedImage image = getImage(item); if (image != null) { - panelComponent.getChildren().add(new ImageComponent(image)); + inventoryComponent.getChildren().add(new ImageComponent(image)); continue; } } } // put a placeholder image so each item is aligned properly and the panel is not resized - panelComponent.getChildren().add(PLACEHOLDER_IMAGE); + inventoryComponent.getChildren().add(PLACEHOLDER_IMAGE); } - return panelComponent.render(graphics); + wrapperComponent.getChildren().add(inventoryComponent); + + if (config.showFreeSlots()) + { + freeSlotsComponent.setText(remaining + " free"); + wrapperComponent.setPreferredSize(new Dimension(4 * (PLACEHOLDER_WIDTH + 6) + ComponentConstants.STANDARD_BORDER * 2, 0)); + wrapperComponent.getChildren().add(freeSlotsComponent); + } + + return wrapperComponent.render(graphics); } private BufferedImage getImage(Item item) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerPlugin.java index a9aa9f6453..71032a10c7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerPlugin.java @@ -24,7 +24,9 @@ */ package net.runelite.client.plugins.inventoryviewer; +import com.google.inject.Provides; import javax.inject.Inject; +import net.runelite.client.config.ConfigManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -37,12 +39,20 @@ import net.runelite.client.ui.overlay.OverlayManager; ) public class InventoryViewerPlugin extends Plugin { + static final String CONFIG_GROUP_KEY = "inventoryviewer"; + @Inject private InventoryViewerOverlay overlay; @Inject private OverlayManager overlayManager; + @Provides + InventoryViewerConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(InventoryViewerConfig.class); + } + @Override public void startUp() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java index 921dcd4a46..45ef04e0d2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java @@ -14,9 +14,10 @@ import net.runelite.api.Client; import javax.inject.Inject; @PluginDescriptor( - name = "!Kitten Notifier", + name = "Kitten Notifier", description = "Sends a notification when your kitten needs food, attention, or is grown.", - tags = {"kitten, notifications"} + tags = {"kitten, notifications"}, + type = "utility" ) public class KittenNotifierPlugin extends Plugin{ @Inject @@ -51,10 +52,11 @@ public class KittenNotifierPlugin extends Plugin{ } @Subscribe public void onNpcActionChanged(NpcActionChanged event) { + if (event.getNpcComposition()!=null) if (!config.catOwned()) { for (NPC npc : client.getNpcs()) { if (npc.getInteracting() != null) { - if (npc.getName().contentEquals("Cat") && !config.catOwned()) { + if (npc.getName().equals("Cat") && !config.catOwned()) { // If this if statement is included in previous it could null. if (npc.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) { config.catOwned(true); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java index e6b3923fea..6b93885523 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java @@ -19,10 +19,11 @@ import java.util.Map; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( - name = "!Lizard Shamans", + name = "Lizard Shamans", description = "Configures timer for lizardmen shaman spawns.", enabledByDefault = false, - tags = {"shaman", "lizard", "lizardmen"} + tags = {"shaman", "lizard", "lizardmen"}, + type = "PVM" ) @Slf4j public class LizardmenShamanPlugin extends Plugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierPlugin.java index dc5b9e7a27..fedf163a55 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierPlugin.java @@ -25,10 +25,11 @@ import java.util.Iterator; import java.util.List; @PluginDescriptor( - name = "!Menu Modifier", + name = "Menu Modifier", description = "Changes right click menu for players", tags = { "menu", "modifier", "right", "click", "pk", "bogla" }, - enabledByDefault = false + enabledByDefault = false, + type = "utility" ) public class MenuModifierPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MapLocations.java similarity index 99% rename from runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java rename to runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MapLocations.java index 81e8e0f527..09cdabf83f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MapLocations.java @@ -22,7 +22,7 @@ * (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.zoneIndicators; +package net.runelite.client.plugins.multiindicators; import java.awt.Polygon; import java.awt.Rectangle; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsConfig.java similarity index 96% rename from runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java rename to runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsConfig.java index 370533dac7..0436d936ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsConfig.java @@ -22,15 +22,15 @@ * (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.zoneIndicators; +package net.runelite.client.plugins.multiindicators; import java.awt.Color; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup("zoneIndicators") -public interface ZoneIndicatorsConfig extends Config +@ConfigGroup("multiindicators") +public interface MultiIndicatorsConfig extends Config { @ConfigItem( keyName = "multicombatZoneVisibility", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsMinimapOverlay.java similarity index 94% rename from runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java rename to runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsMinimapOverlay.java index 699b0f0ddf..a0d87a4691 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsMinimapOverlay.java @@ -22,7 +22,7 @@ * (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.zoneIndicators; +package net.runelite.client.plugins.multiindicators; import java.awt.Color; import java.awt.Dimension; @@ -40,7 +40,7 @@ import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; -public class ZoneIndicatorsMinimapOverlay extends Overlay +public class MultiIndicatorsMinimapOverlay extends Overlay { private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; @@ -48,13 +48,13 @@ public class ZoneIndicatorsMinimapOverlay extends Overlay private Client client; @Inject - private ZoneIndicatorsPlugin plugin; + private MultiIndicatorsPlugin plugin; @Inject - private ZoneIndicatorsConfig config; + private MultiIndicatorsConfig config; @Inject - public ZoneIndicatorsMinimapOverlay() + public MultiIndicatorsMinimapOverlay() { setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ALWAYS_ON_TOP); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsOverlay.java similarity index 95% rename from runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java rename to runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsOverlay.java index 0f52222e8b..242effb5aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsOverlay.java @@ -22,7 +22,7 @@ * (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.zoneIndicators; +package net.runelite.client.plugins.multiindicators; import java.awt.BasicStroke; import java.awt.Color; @@ -41,7 +41,7 @@ import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; -public class ZoneIndicatorsOverlay extends Overlay +public class MultiIndicatorsOverlay extends Overlay { private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; @@ -49,13 +49,13 @@ public class ZoneIndicatorsOverlay extends Overlay private Client client; @Inject - private ZoneIndicatorsPlugin plugin; + private MultiIndicatorsPlugin plugin; @Inject - private ZoneIndicatorsConfig config; + private MultiIndicatorsConfig config; @Inject - public ZoneIndicatorsOverlay() + public MultiIndicatorsOverlay() { setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_SCENE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsPlugin.java similarity index 95% rename from runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java rename to runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsPlugin.java index 5f3397e900..8410d96d40 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsPlugin.java @@ -22,7 +22,7 @@ * (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.zoneIndicators; +package net.runelite.client.plugins.multiindicators; import net.runelite.client.eventbus.Subscribe; import com.google.inject.Provides; @@ -52,12 +52,13 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( - name = "!MultiLines", + name = "Multi-Lines", description = "Show borders of multicombat and PvP safezones", tags = {"multicombat", "lines", "pvp", "deadman", "safezones", "bogla"}, - enabledByDefault = false + enabledByDefault = false, + type = "PVP" ) -public class ZoneIndicatorsPlugin extends Plugin +public class MultiIndicatorsPlugin extends Plugin { @Inject private Client client; @@ -66,13 +67,13 @@ public class ZoneIndicatorsPlugin extends Plugin private ClientThread clientThread; @Inject - private ZoneIndicatorsConfig config; + private MultiIndicatorsConfig config; @Inject - private ZoneIndicatorsOverlay overlay; + private MultiIndicatorsOverlay overlay; @Inject - private ZoneIndicatorsMinimapOverlay minimapOverlay; + private MultiIndicatorsMinimapOverlay minimapOverlay; @Inject private OverlayManager overlayManager; @@ -92,9 +93,9 @@ public class ZoneIndicatorsPlugin extends Plugin private int currentPlane; @Provides - ZoneIndicatorsConfig getConfig(ConfigManager configManager) + MultiIndicatorsConfig getConfig(ConfigManager configManager) { - return configManager.getConfig(ZoneIndicatorsConfig.class); + return configManager.getConfig(MultiIndicatorsConfig.class); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/ZoneVisibility.java similarity index 96% rename from runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java rename to runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/ZoneVisibility.java index 9a457d9e50..93ca7e8e26 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/ZoneVisibility.java @@ -22,7 +22,7 @@ * (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.zoneIndicators; +package net.runelite.client.plugins.multiindicators; import lombok.RequiredArgsConstructor; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java index ccece4d4a4..ce6c1ca925 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java @@ -16,10 +16,11 @@ import net.runelite.client.ui.overlay.OverlayManager; import javax.inject.Inject; @PluginDescriptor( - name = "!Next Hit Notifier", + name = "Next Hit Notifier", description = "Shows estimated next hit based on xp drop.", tags = { "experience", "damage", "overlay", "pking", "bogla" }, - enabledByDefault = false + enabledByDefault = false, + type = "utility" ) public class NextHitNotifierPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionConfig.java deleted file mode 100644 index 74a733a7eb..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.runelite.client.plugins.pkvision; - -import java.awt.Color; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("pkvision") -public interface PKVisionConfig extends Config -{ - @ConfigItem(position = 0, keyName = "drawOwnName", name = "Highlight own player", description = "Configures whether or not your own player should be highlighted") - default boolean highlightOwnPlayer() - { - return false; - } - - @ConfigItem(position = 1, keyName = "ownNameColor", name = "Own player color", description = "Color of your own player") - default Color getOwnPlayerColor() - { - return new Color(0, 184, 212); - } - - @ConfigItem(position = 2, keyName = "drawFriendNames", name = "Highlight friends", description = "Configures whether or not friends should be highlighted") - default boolean highlightFriends() - { - return true; - } - - @ConfigItem(position = 3, keyName = "friendNameColor", name = "Friend color", description = "Color of friend names" ) - default Color getFriendColor() - { - return new Color(0, 200, 80); - } - - @ConfigItem(position = 4, keyName = "drawPlayerTiles", name = "Draw tiles under players", description = "Configures whether or not tiles under highlighted players should be drawn") - default boolean drawTiles() - { - return false; - } - - @ConfigItem(position = 5, keyName = "drawPlayerNames", name = "Draw names above players", description = "Configures whether or not player names should be drawn above players") - default boolean drawPlayerNames() { return true; } - - @ConfigItem(position = 6, keyName = "drawPlayerLevels", name = "Draw levels above players", description = "Configures whether or not player levels should be drawn above players") - default boolean drawPlayerLevels() - { - return true; - } - - //@ConfigItem(position = 7, keyName = "drawPlayerHealth", name = "Draw health above players", description = "Configures whether or not player levels should be drawn above players") - //default boolean drawPlayerHealth() - //{ - // return true; - //} -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionMinimapOverlay.java deleted file mode 100644 index fc844eb734..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionMinimapOverlay.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.runelite.client.plugins.pkvision; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import javax.inject.Inject; -import javax.inject.Singleton; -import net.runelite.api.Player; -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; - -@Singleton -public class PKVisionMinimapOverlay extends Overlay -{ - private final PKVisionService pkVisionService; - - @Inject - private PKVisionMinimapOverlay(PKVisionService pkVisionService) - { - this.pkVisionService = pkVisionService; - setLayer(OverlayLayer.ABOVE_WIDGETS); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGH); - } - - @Override - public Dimension render(Graphics2D graphics) - { - pkVisionService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); - return null; -} - - private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) - { - final net.runelite.api.Point minimapLocation = actor.getMinimapLocation(); - - if (minimapLocation != null) - OverlayUtil.renderTextLocation(graphics, minimapLocation, Integer.toString(actor.getCombatLevel()), color); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionOverlay.java deleted file mode 100644 index b36b91da7b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionOverlay.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.runelite.client.plugins.pkvision; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import javax.inject.Inject; -import javax.inject.Singleton; - -import net.runelite.api.Player; -import net.runelite.api.Point; -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; - -@Singleton -public class PKVisionOverlay extends Overlay -{ - private final PKVisionService pkVisionService; - private final PKVisionConfig config; - - @Inject - private PKVisionOverlay(PKVisionConfig config, PKVisionService pkVisionService, PKVisionPlugin pkVisionPlugin) - { - this.config = config; - this.pkVisionService = pkVisionService; - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) - { - pkVisionService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); - return null; - } - - private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) - { - if (!config.drawPlayerNames() && !config.drawPlayerLevels()) - return; - - String text = ""; - if (config.drawPlayerLevels()) - text += "(" + actor.getCombatLevel() + ") "; - - if (config.drawPlayerNames()) - text += actor.getName().replace('\u00A0', ' '); - - Point textLocation = actor.getCanvasTextLocation(graphics, text, actor.getLogicalHeight() + 40); - - if (textLocation != null) - OverlayUtil.renderTextLocation(graphics, textLocation, text, color); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionPlugin.java deleted file mode 100644 index 6fc74fb2c2..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionPlugin.java +++ /dev/null @@ -1,135 +0,0 @@ -package net.runelite.client.plugins.pkvision; - -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import java.awt.Color; -import javax.inject.Inject; -import net.runelite.api.Client; -import static net.runelite.api.MenuAction.*; -import net.runelite.api.MenuEntry; -import net.runelite.api.Player; -import net.runelite.api.events.MenuEntryAdded; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.ColorUtil; -import net.runelite.client.util.MiscUtils; -import net.runelite.client.util.Text; - -@PluginDescriptor( - name = "!PK Vision", - description = "Highlight players on-screen and/or on the minimap", - tags = {"highlight", "minimap", "overlay", "players", "pk", "helper", "vision", "bogla"}, - enabledByDefault = false -) -public class PKVisionPlugin extends Plugin -{ - @Inject - private OverlayManager overlayManager; - - @Inject - private PKVisionConfig config; - - @Inject - private PKVisionOverlay pkVisionOverlay; - - @Inject - private PKVisionTileOverlay pkVisionTileOverlay; - - @Inject - private PKVisionMinimapOverlay pkVisionMinimapOverlay; - - @Inject - private Client client; - - @Provides - PKVisionConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(PKVisionConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(pkVisionOverlay); - overlayManager.add(pkVisionTileOverlay); - overlayManager.add(pkVisionMinimapOverlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(pkVisionOverlay); - overlayManager.remove(pkVisionTileOverlay); - overlayManager.remove(pkVisionMinimapOverlay); - } - - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) - { - int type = menuEntryAdded.getType(); - String option = Text.removeTags(menuEntryAdded.getOption()).toLowerCase(); - - if (type >= 2000) - type -= 2000; - - int identifier = menuEntryAdded.getIdentifier(); - if (type == FOLLOW.getId() || type == TRADE.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 == SPELL_CAST_ON_PLAYER.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; - - Color color = null; - - if (config.highlightFriends() && (player.isFriend() || player.isClanMember())) - { - color = config.getFriendColor(); - } - else if (!player.isFriend() && !player.isClanMember()) - { - int lvlDelta = player.getCombatLevel() - localPlayer.getCombatLevel(); - int wildyLvl = MiscUtils.getWildernessLevelFrom(client, player.getWorldLocation()); - - if (wildyLvl <= 0) - return; - - int R = MiscUtils.clamp((int)(((float)(lvlDelta + wildyLvl) / (float)(wildyLvl * 2)) * 255.f), 0, 255); - int G = MiscUtils.clamp(255 - R, 0, 255); - - if (Math.abs(lvlDelta) <= wildyLvl) - color = Color.getHSBColor(Color.RGBtoHSB(R, G, 0, null)[0], 1.f, 1.f); - } - - if (color != null) - { - MenuEntry[] menuEntries = client.getMenuEntries(); - MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; - - // strip out existing '); - if (idx != -1) - target = target.substring(idx + 1); - - lastEntry.setTarget(ColorUtil.prependColorTag(target, color)); - - - client.setMenuEntries(menuEntries); - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionService.java b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionService.java deleted file mode 100644 index 770cbd6505..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionService.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.runelite.client.plugins.pkvision; - -import java.awt.Color; -import java.util.function.BiConsumer; -import javax.inject.Inject; -import javax.inject.Singleton; -import net.runelite.api.Client; -import net.runelite.api.Player; -import net.runelite.client.util.MiscUtils; - -@Singleton -public class PKVisionService -{ - private final Client client; - private final PKVisionConfig config; - - @Inject - private PKVisionService(Client client, PKVisionConfig config) - { - this.config = config; - this.client = client; - } - - public void forEachPlayer(final BiConsumer consumer) - { - final Player localPlayer = client.getLocalPlayer(); - - for (Player player : client.getPlayers()) - { - if (player == null || player.getName() == null) - continue; - - if (player == localPlayer) - { - if (config.highlightOwnPlayer()) - consumer.accept(player, config.getOwnPlayerColor()); - - continue; - } - - if (config.highlightFriends() && (player.isFriend() || player.isClanMember())) - { - consumer.accept(player, config.getFriendColor()); - } - else if (player != localPlayer && !player.isFriend() && !player.isClanMember()) - { - int lvlDelta = player.getCombatLevel() - localPlayer.getCombatLevel(); - int wildyLvl = MiscUtils.getWildernessLevelFrom(client, player.getWorldLocation()); - - if (wildyLvl <= 0) - continue; - - if (Math.abs(lvlDelta) > wildyLvl) - continue; - - int R = MiscUtils.clamp((int)(((float)(lvlDelta + wildyLvl) / (float)(wildyLvl * 2)) * 255.f), 0, 255); - int G = MiscUtils.clamp(255 - R, 0, 255); - - consumer.accept(player, Color.getHSBColor(Color.RGBtoHSB(R, G, 0, null)[0], 1.f, 1.f)); - } - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionTileOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionTileOverlay.java deleted file mode 100644 index aba6c3fad6..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionTileOverlay.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.runelite.client.plugins.pkvision; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; -import javax.inject.Inject; -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; - -public class PKVisionTileOverlay extends Overlay -{ - private final PKVisionService pkVisionService; - private final PKVisionConfig config; - - @Inject - private PKVisionTileOverlay(PKVisionConfig config, PKVisionService pkVisionService) - { - this.config = config; - this.pkVisionService = pkVisionService; - setLayer(OverlayLayer.ABOVE_SCENE); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!config.drawTiles()) - return null; - - pkVisionService.forEachPlayer((player, color) -> - { - final Polygon poly = player.getCanvasTilePoly(); - - if (poly != null) - OverlayUtil.renderPolygon(graphics, poly, color); - }); - - return null; - } -} 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 6b032bc8ee..f218bf5cbf 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 @@ -137,13 +137,48 @@ public interface PlayerIndicatorsConfig extends Config name = "Non-clan member color", description = "Color of non-clan member names" ) - default Color getNonClanMemberColor() + 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() { - return Color.RED; + return false; } @ConfigItem( - position = 10, + 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, keyName = "drawPlayerTiles", name = "Draw tiles under players", description = "Configures whether or not tiles under highlighted players should be drawn" @@ -154,18 +189,29 @@ public interface PlayerIndicatorsConfig extends Config } @ConfigItem( - position = 11, - keyName = "playerNamePosition", - name = "Name position", - description = "Configures the position of drawn player names, or if they should be disabled" + position = 15, + keyName = "drawOverheadPlayerNames", + name = "Draw names above players", + description = "Configures whether or not player names should be drawn above players" ) - default PlayerNameLocation playerNamePosition() + default boolean drawOverheadPlayerNames() { - return PlayerNameLocation.ABOVE_HEAD; + return true; } @ConfigItem( - position = 12, + 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, keyName = "drawMinimapNames", name = "Draw names on minimap", description = "Configures whether or not minimap names for players with rendered names should be drawn" @@ -176,7 +222,7 @@ public interface PlayerIndicatorsConfig extends Config } @ConfigItem( - position = 13, + position = 18, keyName = "colorPlayerMenu", name = "Colorize player menu", description = "Color right click menu for players" @@ -187,7 +233,7 @@ public interface PlayerIndicatorsConfig extends Config } @ConfigItem( - position = 14, + position = 19, keyName = "clanMenuIcons", name = "Show clan ranks", description = "Add clan rank to right click menu and next to player names" @@ -196,4 +242,109 @@ 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" + ) + default boolean drawHighlightedNames() + { + return false; + } + + @ConfigItem( + keyName = "highlightedNames", + name = "Highlighted names", + description = "Clan caller names separated by a comma" + ) + 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() + { + return false; + } + + @ConfigItem( + position = 23, + keyName = "highlightedTargetColor", + name = "Highlighted target color", + description = "Color of highlighted target names" + ) + 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() + { + return false; + } + + @ConfigItem( + position = 25, + keyName = "level", + name = "Level", + description = "The level to limit players shown +-x" + ) + default int intLevel() + { + return 5; + } + + @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( + 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.") + + default boolean rightClickOverhead() { return false; } } 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 5373fc1eb4..e582694a9f 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,6 +1,5 @@ /* * 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,6 +31,7 @@ import java.awt.image.BufferedImage; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.ClanMemberRank; +import net.runelite.api.Client; import net.runelite.api.Player; import net.runelite.api.Point; import net.runelite.client.game.ClanManager; @@ -39,18 +39,17 @@ 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.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; + @Inject + private Client client; + @Inject private PlayerIndicatorsOverlay(PlayerIndicatorsConfig config, PlayerIndicatorsService playerIndicatorsService, ClanManager clanManager) @@ -71,78 +70,68 @@ public class PlayerIndicatorsOverlay extends Overlay private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) { - final PlayerNameLocation drawPlayerNamesConfig = config.playerNamePosition(); - if (drawPlayerNamesConfig == PlayerNameLocation.DISABLED) + if (!config.drawOverheadPlayerNames() && !config.drawOverheadLevels()) { return; } - final int zOffset; - switch (drawPlayerNamesConfig) + String namee = actor.getName().replace('\u00A0', ' '); + String combatLevel = Integer.toString(actor.getCombatLevel()); + String playerInfo = ""; + + if (config.drawOverheadPlayerNames()) { - case MODEL_CENTER: - case MODEL_RIGHT: - zOffset = actor.getLogicalHeight() / 2; - break; - default: - zOffset = actor.getLogicalHeight() + ACTOR_OVERHEAD_TEXT_MARGIN; + playerInfo = namee; } - final String name = Text.sanitize(actor.getName()); - Point textLocation = actor.getCanvasTextLocation(graphics, name, zOffset); - - if (drawPlayerNamesConfig == PlayerNameLocation.MODEL_RIGHT) + if (config.drawOverheadLevels()) { - textLocation = actor.getCanvasTextLocation(graphics, "", zOffset); + if (!playerInfo.isEmpty()) + { + playerInfo = playerInfo.concat("(" + combatLevel + ")"); + } + else + { + playerInfo = combatLevel; + } + } - if (textLocation == null) + if (config.limitLevel()) + { + if (!(client.getLocalPlayer().getCombatLevel() >= actor.getCombatLevel() - config.intLevel() && client.getLocalPlayer().getCombatLevel() <= actor.getCombatLevel() + config.intLevel())) { return; } - - textLocation = new Point(textLocation.getX() + ACTOR_HORIZONTAL_TEXT_MARGIN, textLocation.getY()); } - if (textLocation == null) - { - return; - } + String name = actor.getName().replace('\u00A0', ' ') + (config.limitLevel() ? " Lvl: " + actor.getCombatLevel() : ""); + int offset = actor.getLogicalHeight() + 40; + Point textLocation = actor.getCanvasTextLocation(graphics, playerInfo, offset); - if (config.showClanRanks() && actor.isClanMember()) + if (textLocation != null) { - final ClanMemberRank rank = clanManager.getRank(name); - - if (rank != ClanMemberRank.UNRANKED) + if (config.showClanRanks() && actor.isClanMember()) { - final BufferedImage clanchatImage = clanManager.getClanImage(rank); + ClanMemberRank rank = clanManager.getRank(name); - if (clanchatImage != null) + if (rank != ClanMemberRank.UNRANKED) { - final int clanImageWidth = clanchatImage.getWidth(); - final int clanImageTextMargin; - final int clanImageNegativeMargin; + BufferedImage clanchatImage = clanManager.getClanImage(rank); - if (drawPlayerNamesConfig == PlayerNameLocation.MODEL_RIGHT) + if (clanchatImage != null) { - clanImageTextMargin = clanImageWidth; - clanImageNegativeMargin = 0; - } - else - { - clanImageTextMargin = clanImageWidth / 2; - clanImageNegativeMargin = clanImageWidth / 2; - } + 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); - 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()); + // move text + textLocation = new Point(textLocation.getX() + width / 2, textLocation.getY()); + } } } - } - OverlayUtil.renderTextLocation(graphics, textLocation, name, color); + OverlayUtil.renderTextLocation(graphics, textLocation, playerInfo, 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 e545f92dff..fd56c88fea 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 @@ -27,13 +27,16 @@ package net.runelite.client.plugins.playerindicators; import com.google.inject.Provides; import java.awt.Color; import javax.inject.Inject; -import net.runelite.api.ClanMemberRank; + +import net.runelite.api.*; + import static net.runelite.api.ClanMemberRank.UNRANKED; -import net.runelite.api.Client; import static net.runelite.api.MenuAction.*; -import net.runelite.api.MenuEntry; -import net.runelite.api.Player; + +import net.runelite.api.coords.WorldPoint; 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; @@ -41,14 +44,25 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; 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; + @PluginDescriptor( name = "Player Indicators", description = "Highlight players on-screen and/or on the minimap", - tags = {"highlight", "minimap", "overlay", "players"} + tags = {"highlight", "minimap", "overlay", "players"}, + type = "utility" ) public class PlayerIndicatorsPlugin extends Plugin { + private static final Splitter COMMA_SPLITTER = Splitter.on(Pattern.compile("\\s*,\\s*")); @Inject private OverlayManager overlayManager; @@ -70,6 +84,8 @@ public class PlayerIndicatorsPlugin extends Plugin @Inject private ClanManager clanManager; + private Map highlightedPlayers = new HashMap<>(); + @Provides PlayerIndicatorsConfig provideConfig(ConfigManager configManager) { @@ -82,6 +98,7 @@ public class PlayerIndicatorsPlugin extends Plugin overlayManager.add(playerIndicatorsOverlay); overlayManager.add(playerIndicatorsTileOverlay); overlayManager.add(playerIndicatorsMinimapOverlay); + updateHighlightList(); } @Override @@ -92,9 +109,60 @@ public class PlayerIndicatorsPlugin extends Plugin overlayManager.remove(playerIndicatorsMinimapOverlay); } + @Subscribe + public void onInteractChanged(InteractChanged event) + { + Actor actor = event.getActor(); + if (actor != null + && actor.getName() != null + && isHighlighted(actor)) + { + highlightedPlayers.put(actor.getName().toLowerCase(), actor.getInteracting()); + } + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals("playerindicators") && event.getKey().equals("highlightedNames")) + { + updateHighlightList(); + } + } + + private void updateHighlightList() + { + highlightedPlayers.clear(); + for (String player : COMMA_SPLITTER.splitToList(config.getHighlightedNames().toLowerCase().trim())) + { + highlightedPlayers.put(player, null); + } + } + + boolean isHighlighted(Actor player) + { + for (Map.Entry map : highlightedPlayers.entrySet()) + { + if (WildcardMatcher.matches(map.getKey(), 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) @@ -154,6 +222,37 @@ public class PlayerIndicatorsPlugin extends Plugin { 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)) { + image = 29; + } else if (player.getOverheadIcon().equals((Object)HeadIcon.RANGED)) { + image = 30; + } else if (player.getOverheadIcon().equals((Object)HeadIcon.MELEE)) { + image = 31; + } else if (player.getOverheadIcon().equals((Object)HeadIcon.REDEMPTION)) { + image = 32; + } else if (player.getOverheadIcon().equals((Object)HeadIcon.RETRIBUTION)) { + image = 33; + } else if (player.getOverheadIcon().equals((Object)HeadIcon.SMITE)) { + image = 34; + } + } if (image != -1 || color != null) { @@ -182,4 +281,57 @@ public class PlayerIndicatorsPlugin extends Plugin } } } + + 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; + } + } 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 769c7e3aed..74b1c5a58b 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,62 +30,96 @@ 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; @Singleton -public class PlayerIndicatorsService -{ +public class PlayerIndicatorsService { private final Client client; private final PlayerIndicatorsConfig config; @Inject - private PlayerIndicatorsService(Client client, PlayerIndicatorsConfig config) - { + private PlayerIndicatorsService(Client client, PlayerIndicatorsConfig config) { this.config = config; this.client = client; } - public void forEachPlayer(final BiConsumer consumer) - { - if (!config.highlightOwnPlayer() && !config.drawClanMemberNames() - && !config.highlightFriends() && !config.highlightNonClanMembers()) + public void forEachPlayer(final BiConsumer consumer) { + + if (config.showInWildernessOnly() && client.getVar(Varbits.IN_THE_WILDERNESS) != 1) { return; } + if (!config.highlightOwnPlayer() && !config.drawClanMemberNames() + && !config.highlightFriends() && !config.highlightNonClanMembers() + && !config.highlightAttackablePlayers() && !config.highlightAttackerPlayers()) { + 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()) - { + } else if (config.highlightFriends() && player.isFriend()) { 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); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterConfig.java new file mode 100644 index 0000000000..2287b5a0ef --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterConfig.java @@ -0,0 +1,60 @@ +package net.runelite.client.plugins.pluginsorter; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +import java.awt.*; + +@ConfigGroup("runelit") +public interface PluginSorterConfig extends Config { + + Color rlDefault = new Color(250, 155, 23); + + boolean pluginsHidden = false; + + @ConfigItem( + position = 0, + keyName = "hidePlugins", + name = "Hide Plugins", + description = "Hides all 3rd party plugins if checked" + ) + default boolean hidePlugins() + { + return pluginsHidden; + } + + @ConfigItem( + position = 1, + keyName = "pvmColor", + name = "PVM color", + description = "Configure the color of PVM related plugins" + ) + default Color pvmColor() + { + return Color.GREEN; + } + + @ConfigItem( + position = 2, + keyName = "pvpColor", + name = "PVP color", + description = "Configure the color of PVP related plugins" + ) + default Color pvpColor() + { + return Color.RED; + } + + @ConfigItem( + position = 3, + keyName = "utilityColor", + name = "Utility color", + description = "Configure the color of utility related plugins" + ) + default Color utilityColor() + { + return Color.CYAN; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java new file mode 100644 index 0000000000..ca7f54c836 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java @@ -0,0 +1,125 @@ +package net.runelite.client.plugins.pluginsorter; + +import com.google.inject.Provides; +import net.runelite.api.GameState; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.client.config.ConfigItemDescriptor; +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.config.ConfigPanel; +import net.runelite.client.plugins.config.PluginListItem; + +import javax.inject.Inject; +import java.awt.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +@PluginDescriptor( + name = "Plugin Organizer", + description = "Hides and colors 3rd party plugins for better control", + tags = {"Fuck RL","Abex is shit :p"}, + type = "pluginOrganizer" +) +public class PluginSorterPlugin extends Plugin { + + //Cache the hidden plugins + public static List removedPlugins = new ArrayList<>(); + + @Inject + private PluginSorterConfig config; + + @Provides + PluginSorterConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(PluginSorterConfig.class); + } + + @Override + protected void startUp() throws Exception + { + updateColors(); + } + + @Override + protected void shutDown() throws Exception + { + + } + + @Subscribe + public void onGameStateChanged (GameStateChanged gameStateChanged) + { + if (gameStateChanged.getGameState()== GameState.LOGIN_SCREEN) { + if (config.hidePlugins()) + hidePlugins(); + updateColors(); + } + } + + @Subscribe + public void onConfigChanged(ConfigChanged configChanged) { + if (configChanged.getKey().equals("hidePlugins")) { + if (config.hidePlugins()) { + hidePlugins(); + } else { + showPlugins(); + } + } + updateColors(); + } + + public void updateColors() { + for (PluginListItem pli : ConfigPanel.pluginList) { + if (pli.getPlugin()!=null) { + if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type()!=null) + if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("PVM")) + pli.nameLabel.setForeground(config.pvmColor()); + else if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("PVP")) + pli.nameLabel.setForeground(config.pvpColor()); + else if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("utility")) + pli.nameLabel.setForeground(config.utilityColor()); + else + pli.nameLabel.setForeground(Color.WHITE); + } + } + } + + public void hidePlugins() { + Iterator iter = ConfigPanel.pluginList.iterator(); + while (iter.hasNext()) { + PluginListItem pli = iter.next(); + if (pli.getPlugin() != null) { + if (!pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("")) + if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("PVM")) { + iter.remove(); + removedPlugins.add(pli); + } + if (!pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("")) + if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("PVP")) { + iter.remove(); + removedPlugins.add(pli); + } + if (!pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("")) + if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("utility")) { + iter.remove(); + removedPlugins.add(pli); + } + } + } + } + + public void showPlugins() { + List tempList = new ArrayList<>(); + for (PluginListItem pli : removedPlugins) { + tempList.add(pli); + } + for (PluginListItem pli : ConfigPanel.pluginList) { + tempList.add(pli); + } + ConfigPanel.pluginList = tempList; + } +} 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 index 5664621b60..c0dc2644a1 100644 --- 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 @@ -42,9 +42,10 @@ import java.util.ArrayList; import java.util.Arrays; @PluginDescriptor( - name = "!Pray Against Player", + name = "Pray Against Player", description = "Use plugin in PvP situations for best results!!", - tags = {"highlight", "pvp", "overlay", "players"} + tags = {"highlight", "pvp", "overlay", "players"}, + type = "PVP" ) /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/CurrentPlayersJFrame.java b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/CurrentPlayersJFrame.java new file mode 100644 index 0000000000..e61b94fc95 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/CurrentPlayersJFrame.java @@ -0,0 +1,74 @@ +/* + * Decompiled with CFR 0.139. + */ +package net.runelite.client.plugins.pvptools; + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.LayoutManager; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; +import java.util.function.Consumer; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import net.runelite.api.Client; +import net.runelite.client.plugins.pvptools.PvpToolsPlugin; +import net.runelite.client.ui.FontManager; + +public class CurrentPlayersJFrame +extends JFrame { + public JList currentPlayersJList; + + CurrentPlayersJFrame(Client client, PvpToolsPlugin pvpToolsPlugin, List list) { + int x = client.getCanvas().getLocationOnScreen().x + client.getCanvas().getWidth(); + int y = client.getCanvas().getLocationOnScreen().y; + JPanel scrollContainerCurrent = new JPanel(new BorderLayout()); + JScrollPane jScrollPane = new JScrollPane(scrollContainerCurrent); + JButton refreshJButton = new JButton("Refresh"); + refreshJButton.addActionListener(pvpToolsPlugin.currentPlayersActionListener); + JButton copyJButton = new JButton("Copy List"); + this.currentPlayersJList = new JList(list.toArray()); + ActionListener copyButtonActionListener = e -> { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringBuilder stringBuilder = new StringBuilder(); + list.forEach(s -> { + stringBuilder.append((String)s); + stringBuilder.append(System.getProperty("line.separator")); + }); + StringSelection stringSelection = new StringSelection(stringBuilder.toString()); + clipboard.setContents(stringSelection, stringSelection); + }; + copyJButton.addActionListener(copyButtonActionListener); + this.setTitle("Current CC Members"); + this.setDefaultCloseOperation(2); + JLabel titleLabel = new JLabel("Current CC Members"); + titleLabel.setFont(FontManager.getRunescapeFont().deriveFont(1, 18.0f)); + this.currentPlayersJList.setFont(new Font("Arial", 0, 14)); + scrollContainerCurrent.add((Component)refreshJButton, "North"); + scrollContainerCurrent.add((Component)titleLabel, "Center"); + JPanel footerPanel = new JPanel(new BorderLayout()); + footerPanel.add((Component)this.currentPlayersJList, "North"); + footerPanel.add((Component)copyJButton, "Center"); + scrollContainerCurrent.add((Component)footerPanel, "South"); + this.add(jScrollPane); + this.setLocation(x, y); + this.setMaximumSize(Toolkit.getDefaultToolkit().getScreenSize()); + this.pack(); + this.setVisible(true); + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/MissingPlayersJFrame.java b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/MissingPlayersJFrame.java new file mode 100644 index 0000000000..324db3869a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/MissingPlayersJFrame.java @@ -0,0 +1,74 @@ +/* + * Decompiled with CFR 0.139. + */ +package net.runelite.client.plugins.pvptools; + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.LayoutManager; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; +import java.util.function.Consumer; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import net.runelite.api.Client; +import net.runelite.client.plugins.pvptools.PvpToolsPlugin; +import net.runelite.client.ui.FontManager; + +public class MissingPlayersJFrame +extends JFrame { + public JList missingPlayersJList; + + MissingPlayersJFrame(Client client, PvpToolsPlugin pvpToolsPlugin, List list) { + int x = client.getCanvas().getLocationOnScreen().x + client.getCanvas().getWidth(); + int y = client.getCanvas().getLocationOnScreen().y; + JPanel scrollConatiner = new JPanel(new BorderLayout()); + JScrollPane jScrollPane = new JScrollPane(scrollConatiner); + JButton refreshJButton = new JButton("Refresh"); + refreshJButton.addActionListener(pvpToolsPlugin.playersButtonActionListener); + JButton copyJButton = new JButton("Copy List"); + this.missingPlayersJList = new JList(list.toArray()); + ActionListener copyButtonActionListener = e -> { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringBuilder stringBuilder = new StringBuilder(); + list.forEach(s -> { + stringBuilder.append((String)s); + stringBuilder.append(System.getProperty("line.separator")); + }); + StringSelection stringSelection = new StringSelection(stringBuilder.toString()); + clipboard.setContents(stringSelection, stringSelection); + }; + copyJButton.addActionListener(copyButtonActionListener); + this.setTitle("Missing CC Members"); + this.setDefaultCloseOperation(2); + JLabel titleLabel = new JLabel("Missing CC Members"); + titleLabel.setFont(FontManager.getRunescapeFont().deriveFont(1, 18.0f)); + this.missingPlayersJList.setFont(new Font("Arial", 0, 14)); + scrollConatiner.add((Component)refreshJButton, "North"); + scrollConatiner.add((Component)titleLabel, "Center"); + JPanel footerPanel = new JPanel(new BorderLayout()); + footerPanel.add((Component)this.missingPlayersJList, "North"); + footerPanel.add((Component)copyJButton, "Center"); + scrollConatiner.add((Component)footerPanel, "South"); + this.add(jScrollPane); + this.setLocation(x, y); + this.setMaximumSize(Toolkit.getDefaultToolkit().getScreenSize()); + this.pack(); + this.setVisible(true); + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsConfig.java new file mode 100644 index 0000000000..d88182db0e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsConfig.java @@ -0,0 +1,69 @@ +/* + * Decompiled with CFR 0.139. + */ +package net.runelite.client.plugins.pvptools; + +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(value="pvptools") +public interface PvpToolsConfig +extends Config { + @ConfigItem(keyName="countPlayers", name="Count Players", description="When in PvP zones, counts the attackable players in and not in player's CC", position=3) + default public boolean countPlayers() { + return true; + } + + @ConfigItem(keyName="countOverHeads", name="Count Enemy Overheads", description="Counts the number of each protection prayer attackable targets not in your CC are currently using", position=4) + default public boolean countOverHeads() { + return true; + } + + @ConfigItem(keyName="fallInHelper", name="Fall In Helper", description="Hides all non-friendly player entities other than the one that is attacking you.", position=5) + default public boolean fallInHelper() { + return true; + } + + @ConfigItem(keyName="hotkey", name="Fall In Hotkey", description="Turns the fall in helper on or off when you press this hotkey", position=6) + default public Keybind hotkey() { + return Keybind.NOT_SET; + } + + @ConfigItem(keyName="attackOptionsClan", name="Hide CC Attack Option", description="Hides the attack option for people in the same CC", position=7) + default public boolean attackOptionsClan() { + return false; + } + + @ConfigItem(keyName="attackOptionsFriend", name="Hide Friend Attack Options", description="Hides the attack option for people on your friends list", position=8) + default public boolean attackOptionsFriend() { + return false; + } + + @ConfigItem(keyName="attackOptionsHotkey", name="Attack Option Hotkey", description="Enables a hotkey for attack options to disable or enable hiding quickly", position=10) + default public Keybind attackOptionsHotkey() { + return Keybind.CTRL; + } + + @ConfigItem(keyName="levelRangeAttackOptions", name="Hide Other Attack Options", description="Hides the attack option for people that are outside your level range", position=9) + default public boolean levelRangeAttackOptions() { + return false; + } + + @ConfigItem(keyName="riskCalculator", name="Risk Calculator", description="Enables a panel in the PvP Tools Panel that shows the players current risk", position=13) + default public boolean riskCalculatorEnabled() { + return true; + } + + @ConfigItem(keyName="missingPlayers", name="Missing CC Players", description="Adds a button to the PvP Tools panel that opens a window showing which CC members are not at the current players location", position=14) + default public boolean missingPlayersEnabled() { + return true; + } + + @ConfigItem(keyName="currentPlayers", name="Current CC Players", description="Adds a button to the PvP Tools panel that opens a window showing which CC members currently at the players location", position=15) + default public boolean currentPlayersEnabled() { + return true; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsOverlay.java new file mode 100644 index 0000000000..b24b66dab7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsOverlay.java @@ -0,0 +1,61 @@ +/* + * Decompiled with CFR 0.139. + */ +package net.runelite.client.plugins.pvptools; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.Shape; +import java.awt.Stroke; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.client.plugins.pvptools.PvpToolsConfig; +import net.runelite.client.plugins.pvptools.PvpToolsPlugin; +import net.runelite.client.ui.FontManager; +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; + +public class PvpToolsOverlay +extends Overlay { + private PvpToolsPlugin pvpToolsPlugin; + private PvpToolsConfig pvpToolsConfig; + private Client client; + + @Inject + private PvpToolsOverlay(PvpToolsConfig pvpToolsConfig, PvpToolsPlugin pvpToolsPlugin, Client client) { + this.pvpToolsPlugin = pvpToolsPlugin; + this.pvpToolsConfig = pvpToolsConfig; + this.client = client; + this.setLayer(OverlayLayer.ABOVE_WIDGETS); + this.setPriority(OverlayPriority.HIGH); + this.setPosition(OverlayPosition.DYNAMIC); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (this.pvpToolsConfig.fallInHelper() && this.pvpToolsPlugin.fallinHelperEnabled) { + graphics.setFont(FontManager.getRunescapeFont().deriveFont(28)); + OverlayUtil.renderTextLocation(graphics, new Point(200, 80), "FALL IN HELPER ENABLED", Color.YELLOW); + } + return null; + } + + private void renderPoly(Graphics2D graphics, Color color, Polygon polygon) { + if (polygon != null) { + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2.0f)); + 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/pvptools/PvpToolsPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPanel.java new file mode 100644 index 0000000000..8856c37b32 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPanel.java @@ -0,0 +1,138 @@ +/* + * Decompiled with CFR 0.139. + */ +package net.runelite.client.plugins.pvptools; + +import com.google.common.base.MoreObjects; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.LayoutManager; +import javax.inject.Inject; +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import net.runelite.client.RuneLiteProperties; +import net.runelite.client.plugins.info.JRichTextPane; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.PluginPanel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PvpToolsPanel +extends PluginPanel { + private static final Logger log = LoggerFactory.getLogger(PvpToolsPanel.class); + private final JLabel loggedLabel = new JLabel(); + private final JRichTextPane emailLabel = new JRichTextPane(); + public JLabel numCC = new JLabel(); + public JLabel numOther = new JLabel(); + public JLabel numMageJLabel = new JLabel(" "); + public JLabel numRangeJLabel = new JLabel(" "); + public JLabel numMeleeJLabel = new JLabel(" "); + public JLabel totalRiskLabel = new JLabel(" "); + public JLabel riskProtectingItem = new JLabel(" "); + public JLabel biggestItemLabel = new JLabel("Protected Item: "); + public JButton missingPlayers = new JButton("Show missing CC members"); + public JButton currentPlayers = new JButton("Show current CC members"); + public JLabel numBrews = new JLabel(); + @Inject + private JPanel pvpToolsPanel = new JPanel(new GridLayout(11, 1)); + private JPanel missingPlayersPanel = new JPanel(); + private JPanel currentPlayersPanel = new JPanel(); + + public static String htmlLabel(String key, String value) { + return "" + key + "" + value + ""; + } + + void init() { + this.setLayout(new BorderLayout()); + this.setBackground(ColorScheme.DARK_GRAY_COLOR); + this.setBorder(new EmptyBorder(10, 10, 10, 10)); + JPanel versionPanel = new JPanel(); + versionPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + versionPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); + versionPanel.setLayout(new GridLayout(0, 1)); + JPanel riskPanel = new JPanel(); + riskPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + riskPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); + riskPanel.setLayout(new GridLayout(0, 1)); + Font smallFont = FontManager.getRunescapeSmallFont(); + this.numCC.setText(PvpToolsPanel.htmlLabel("Friendly Player Count: ", "0")); + this.numOther.setText(PvpToolsPanel.htmlLabel("Other Player Count: ", "0")); + this.numBrews.setText(PvpToolsPanel.htmlLabel("Player brew count: ", "0")); + this.numMageJLabel.setText(PvpToolsPanel.htmlLabel("Enemies Praying Mage: ", "0")); + this.numMageJLabel.setFont(FontManager.getRunescapeFont()); + this.numRangeJLabel.setText(PvpToolsPanel.htmlLabel("Enemies Praying Range: ", "0")); + this.numRangeJLabel.setFont(FontManager.getRunescapeFont()); + this.numMeleeJLabel.setText(PvpToolsPanel.htmlLabel("Enemies Praying Melee: ", "0")); + this.numMeleeJLabel.setFont(FontManager.getRunescapeFont()); + this.totalRiskLabel.setText(PvpToolsPanel.htmlLabel("Total risk: ", "0")); + this.totalRiskLabel.setFont(FontManager.getRunescapeFont()); + this.riskProtectingItem.setText(PvpToolsPanel.htmlLabel("Risk Protecting Item: ", "0")); + this.riskProtectingItem.setFont(FontManager.getRunescapeFont()); + this.biggestItemLabel.setText("Most Valuable Item: "); + JLabel revision = new JLabel(); + revision.setFont(smallFont); + revision.setText("Oldschool revision: "); + JLabel launcher = new JLabel(PvpToolsPanel.htmlLabel("Launcher version: ", MoreObjects.firstNonNull(RuneLiteProperties.getLauncherVersion(), "Unknown"))); + launcher.setFont(smallFont); + this.loggedLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + this.loggedLabel.setFont(smallFont); + this.emailLabel.setForeground(Color.WHITE); + this.emailLabel.setFont(smallFont); + versionPanel.add(this.numCC); + versionPanel.add(this.numOther); + versionPanel.add(this.numBrews); + versionPanel.add(this.numMageJLabel); + versionPanel.add(this.numRangeJLabel); + versionPanel.add(this.numMeleeJLabel); + versionPanel.add(Box.createGlue()); + versionPanel.add(this.loggedLabel); + versionPanel.add(this.emailLabel); + riskPanel.add(this.totalRiskLabel); + riskPanel.add(this.riskProtectingItem); + riskPanel.add(this.biggestItemLabel); + this.add((Component)versionPanel, "North"); + this.add((Component)riskPanel, "Center"); + this.currentPlayers.setVisible(false); + this.missingPlayers.setVisible(false); + this.missingPlayersPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + this.missingPlayersPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); + this.missingPlayersPanel.setLayout(new GridLayout(0, 1)); + this.missingPlayersPanel.add((Component)this.missingPlayers, "Last"); + this.missingPlayersPanel.add((Component)this.currentPlayers, "Last"); + this.add((Component)this.missingPlayersPanel, "Last"); + } + + public void disablePlayerCount() { + this.numOther.setText("Disabled"); + this.numCC.setText("Disabled"); + this.numCC.repaint(); + this.numOther.repaint(); + } + + public void disablePrayerCount() { + this.numMageJLabel.setText("disabled"); + this.numRangeJLabel.setText("disabled"); + this.numMeleeJLabel.setText("disabled"); + this.numMageJLabel.repaint(); + this.numRangeJLabel.repaint(); + this.numMeleeJLabel.repaint(); + } + + public void disableRiskCalculator() { + this.totalRiskLabel.setText("disabled"); + this.riskProtectingItem.setText("disabled"); + this.biggestItemLabel.setText("disabled"); + this.totalRiskLabel.repaint(); + this.riskProtectingItem.repaint(); + this.biggestItemLabel.repaint(); + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPlugin.java new file mode 100644 index 0000000000..4bf40b3a9a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPlugin.java @@ -0,0 +1,475 @@ +package net.runelite.client.plugins.pvptools; + +import javax.inject.*; + +import com.google.inject.Inject; +import net.runelite.client.plugins.*; +import net.runelite.client.plugins.clanchat.*; +import java.util.function.*; +import java.awt.event.*; +import java.util.stream.*; +import java.util.concurrent.*; +import net.runelite.client.config.*; +import com.google.inject.*; +import net.runelite.client.ui.overlay.*; +import net.runelite.client.input.*; +import net.runelite.client.ui.*; +import java.awt.image.*; +import net.runelite.client.eventbus.*; +import org.apache.commons.lang3.*; +import net.runelite.api.events.*; +import net.runelite.client.util.*; +import net.runelite.api.*; +import net.runelite.client.game.*; +import java.util.*; + +@PluginDescriptor( + name = "PvP Tools", + description = "Enable the PvP Tools panel", + tags = { "panel", "pvp", "pk", "pklite" }, + type="PVP" +) +public class PvpToolsPlugin extends Plugin +{ + @Inject + PvpToolsOverlay pvpToolsOverlay; + boolean fallinHelperEnabled; + private PvpToolsPanel panel; + private MissingPlayersJFrame missingPlayersJFrame; + private CurrentPlayersJFrame currentPlayersJFrame; + private NavigationButton navButton; + private boolean attackHotKeyPressed; + private boolean hideAll; + @Inject + private ScheduledExecutorService executorService; + @Inject + private OverlayManager overlayManager; + @Inject + private Client client; + @Inject + private ItemManager itemManager; + private PvpToolsPlugin uhPvpToolsPlugin; + final ActionListener playersButtonActionListener; + final ActionListener currentPlayersActionListener; + @Inject + private ClientToolbar clientToolbar; + @Inject + private KeyManager keyManager; + @Inject + private PvpToolsConfig config; + @Inject + private PluginManager pluginManager; + @Inject + private ClanManager clanManager; + private ClanChatPlugin clanChatPlugin; + private final HotkeyListener hotkeyListener; + private final HotkeyListener attackOptionsHotKeyListener; + private int[] overheadCount; + private Comparator itemPriceComparator; + private String mtarget; + + public PvpToolsPlugin() { + this.fallinHelperEnabled = false; + this.uhPvpToolsPlugin = this; + this.playersButtonActionListener = new ActionListener() { + @Override + public void actionPerformed(final ActionEvent e) { + if (PvpToolsPlugin.this.missingPlayersJFrame != null) { + PvpToolsPlugin.this.missingPlayersJFrame.dispose(); + PvpToolsPlugin.this.missingPlayersJFrame = null; + PvpToolsPlugin.this.missingPlayersJFrame = new MissingPlayersJFrame(PvpToolsPlugin.this.client, PvpToolsPlugin.this.uhPvpToolsPlugin, PvpToolsPlugin.this.getMissingMembers()); + } + else { + PvpToolsPlugin.this.missingPlayersJFrame = new MissingPlayersJFrame(PvpToolsPlugin.this.client, PvpToolsPlugin.this.uhPvpToolsPlugin, PvpToolsPlugin.this.getMissingMembers()); + } + } + }; + this.currentPlayersActionListener = new ActionListener() { + @Override + public void actionPerformed(final ActionEvent e) { + if (PvpToolsPlugin.this.currentPlayersJFrame != null) { + PvpToolsPlugin.this.currentPlayersJFrame.dispose(); + PvpToolsPlugin.this.currentPlayersJFrame = null; + PvpToolsPlugin.this.currentPlayersJFrame = new CurrentPlayersJFrame(PvpToolsPlugin.this.client, PvpToolsPlugin.this.uhPvpToolsPlugin, PvpToolsPlugin.this.getCurrentMembers()); + } + else { + PvpToolsPlugin.this.currentPlayersJFrame = new CurrentPlayersJFrame(PvpToolsPlugin.this.client, PvpToolsPlugin.this.uhPvpToolsPlugin, PvpToolsPlugin.this.getCurrentMembers()); + } + } + }; + this.hotkeyListener = new HotkeyListener(() -> this.config.hotkey()) { + @Override + public void hotkeyPressed() { + PvpToolsPlugin.this.toggleFallinHelper(); + } + }; + this.attackOptionsHotKeyListener = new HotkeyListener(() -> this.config.attackOptionsHotkey()) { + long lastPress = 0L; + + @Override + public void keyPressed(final KeyEvent e) { + PvpToolsPlugin.this.attackHotKeyPressed = true; + } + + @Override + public void keyReleased(final KeyEvent e) { + PvpToolsPlugin.this.attackHotKeyPressed = (System.currentTimeMillis() - this.lastPress < 800L); + this.lastPress = System.currentTimeMillis(); + } + }; + this.overheadCount = new int[] { 0, 0, 0 }; + this.itemPriceComparator = new Comparator() { + @Override + public int compare(final Item o1, final Item o2) { + return PvpToolsPlugin.this.itemManager.getItemPrice(PvpToolsPlugin.this.itemManager.getItemComposition(o1.getId()).getPrice()) - PvpToolsPlugin.this.itemManager.getItemPrice(PvpToolsPlugin.this.itemManager.getItemComposition(o2.getId()).getPrice()); + } + }; + } + + public List getMissingMembers() { + CopyOnWriteArrayList ccMembers = ClanChatPlugin.getClanMembers(); + ArrayList missingMembers = new ArrayList(); + for (ClanMember clanMember : this.client.getClanMembers()) { + List arrayList; + if (Objects.isNull(clanMember) || (arrayList = ccMembers.stream().map(player -> Text.removeTags(Text.standardize(player.getName()))).collect(Collectors.toList())).contains(Text.removeTags(Text.standardize(clanMember.getUsername()))) || missingMembers.contains(clanMember.getUsername())) continue; + missingMembers.add("[W" + clanMember.getWorld() + "] - " + clanMember.getUsername()); + } + return missingMembers; + } + + public List getCurrentMembers() { + CopyOnWriteArrayList ccMembers = ClanChatPlugin.getClanMembers(); + ArrayList currentMembers = new ArrayList(); + for (ClanMember clanMember : this.client.getClanMembers()) { + List arrayList; + if (Objects.isNull(clanMember) || !(arrayList = ccMembers.stream().map(player -> Text.removeTags(Text.standardize(player.getName()))).collect(Collectors.toList())).contains(Text.removeTags(Text.standardize(clanMember.getUsername()))) || currentMembers.contains(clanMember.getUsername())) continue; + currentMembers.add(clanMember.getUsername()); + } + return currentMembers; + } + + @Provides + PvpToolsConfig config(final ConfigManager configManager) { + return configManager.getConfig(PvpToolsConfig.class); + } + + @Override + protected void startUp() throws Exception { + this.overlayManager.add(this.pvpToolsOverlay); + this.keyManager.registerKeyListener(this.hotkeyListener); + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(this.getClass(), "skull.png"); + (this.panel = new PvpToolsPanel()).init(); + this.navButton = NavigationButton.builder().tooltip("PvP Tools").icon(icon).priority(5).panel(this.panel).build(); + this.panel.missingPlayers.addActionListener(this.playersButtonActionListener); + this.panel.currentPlayers.addActionListener(this.currentPlayersActionListener); + this.clientToolbar.addNavigation(this.navButton); + this.keyManager.registerKeyListener(this.attackOptionsHotKeyListener); + if (this.config.missingPlayersEnabled()) { + this.panel.missingPlayers.setVisible(true); + } + if (this.config.currentPlayersEnabled()) { + this.panel.currentPlayers.setVisible(true); + } + } + + @Override + protected void shutDown() throws Exception { + this.overlayManager.remove(this.pvpToolsOverlay); + this.keyManager.unregisterKeyListener(this.hotkeyListener); + this.keyManager.unregisterKeyListener(this.attackOptionsHotKeyListener); + this.clientToolbar.removeNavigation(this.navButton); + } + + @Subscribe + public void onConfigChanged(final ConfigChanged configChanged) { + if (configChanged.getGroup().equals("pvptools")) { + final String key = configChanged.getKey(); + switch (key) { + case "countPlayers": { + if (this.config.countPlayers()) { + this.updatePlayers(); + } + if (!this.config.countPlayers()) { + this.panel.disablePlayerCount(); + break; + } + break; + } + case "countOverHeads": { + if (this.config.countOverHeads()) { + this.countOverHeads(); + } + if (!this.config.countOverHeads()) { + this.panel.disablePrayerCount(); + break; + } + break; + } + case "riskCalculator": { + if (this.config.riskCalculatorEnabled()) { + this.getCarriedWealth(); + } + if (!this.config.riskCalculatorEnabled()) { + this.panel.disableRiskCalculator(); + break; + } + break; + } + case "missingPlayers": { + if (this.config.missingPlayersEnabled()) { + this.panel.missingPlayers.setVisible(true); + break; + } + break; + } + case "currentPlayers": { + if (this.config.currentPlayersEnabled()) { + this.panel.currentPlayers.setVisible(true); + break; + } + break; + } + } + } + } + + @Subscribe + public void onItemContainerChanged(final ItemContainerChanged event) { + if (event.getItemContainer().equals(this.client.getItemContainer(InventoryID.INVENTORY)) && this.config.riskCalculatorEnabled()) { + this.getCarriedWealth(); + } + } + + @Subscribe + public void onGameStateChanged(final GameStateChanged event) { + if (event.getGameState().equals(GameState.LOGGED_IN) && this.config.riskCalculatorEnabled()) { + this.getCarriedWealth(); + } + if (event.getGameState().equals(GameState.LOGGED_IN) && this.config.countPlayers()) { + this.updatePlayers(); + } + } + + @Subscribe + public void onPlayerSpawned(final PlayerSpawned event) { + if (this.config.countPlayers() && PvPUtil.isAttackable(this.client, event.getPlayer())) { + this.updatePlayers(); + } + if (this.config.countOverHeads()) { + this.countOverHeads(); + } + } + + @Subscribe + public void onPlayerDespawned(final PlayerDespawned event) { + if (this.config.countPlayers() && PvPUtil.isAttackable(this.client, event.getPlayer())) { + this.updatePlayers(); + } + if (this.config.countOverHeads()) { + this.countOverHeads(); + } + } + + @Subscribe + public void onMenuEntryAdded(final MenuEntryAdded menuEntryAdded) { + if (!this.attackHotKeyPressed && (this.config.attackOptionsFriend() || this.config.attackOptionsClan() || this.config.levelRangeAttackOptions())) { + if (this.client.getGameState() != GameState.LOGGED_IN) { + return; + } + final Player[] players = this.client.getCachedPlayers(); + Player player = null; + final int identifier = menuEntryAdded.getIdentifier(); + if (identifier >= 0 && identifier < players.length) { + player = players[identifier]; + } + if (player == null) { + return; + } + final String option = Text.removeTags(menuEntryAdded.getOption()).toLowerCase(); + final String mtarget = Text.removeTags(menuEntryAdded.getTarget()).toLowerCase(); + if ((this.attackHotKeyPressed && this.config.attackOptionsClan()) || this.config.attackOptionsFriend() || this.config.levelRangeAttackOptions()) { + if (this.config.attackOptionsFriend() && player.isFriend()) { + this.moveEntry(mtarget); + } + if (this.config.attackOptionsClan() && player.isClanMember()) { + this.moveEntry(mtarget); + } + if (this.config.levelRangeAttackOptions() && !PvPUtil.isAttackable(this.client, player)) { + this.moveEntry(mtarget); + } + } + } + } + + private void moveEntry(final String mtarget) { + this.mtarget = mtarget; + MenuEntry[] menuEntries = this.client.getMenuEntries(); + final MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; + String target = lastEntry.getTarget(); + final int idx = target.indexOf(62); + if (idx != -1) { + target = target.substring(idx + 1); + } + if (menuEntries[menuEntries.length - 1] != null) {} + if (lastEntry.getOption().contains("attack".toLowerCase())) { + menuEntries = ArrayUtils.remove(menuEntries, menuEntries.length - 1); + } + if (lastEntry.getOption().equals("Attack")) { + menuEntries = ArrayUtils.remove(menuEntries, menuEntries.length - 1); + } + this.client.setMenuEntries(menuEntries); + } + + @Subscribe + public void onFocusChanged(final FocusChanged focusChanged) { + if (!focusChanged.isFocused()) { + this.setAttackHotKeyPressed(false); + } + } + + private void toggleFallinHelper() { + if (!this.fallinHelperEnabled) { + this.client.setIsHidingEntities(true); + this.client.setPlayersHidden(true); + this.fallinHelperEnabled = true; + } + else { + this.client.setIsHidingEntities(false); + this.client.setPlayersHidden(false); + this.fallinHelperEnabled = false; + } + } + + private void updatePrayerNumbers() { + this.panel.numMageJLabel.setText(PvpToolsPanel.htmlLabel("Enemies Praying Mage: ", String.valueOf(this.overheadCount[0]))); + this.panel.numRangeJLabel.setText(PvpToolsPanel.htmlLabel("Enemies Praying Range: ", String.valueOf(this.overheadCount[1]))); + this.panel.numMeleeJLabel.setText(PvpToolsPanel.htmlLabel("Enemies Praying Melee: ", String.valueOf(this.overheadCount[2]))); + this.panel.numMageJLabel.repaint(); + this.panel.numRangeJLabel.repaint(); + this.panel.numMeleeJLabel.repaint(); + } + + private void updatePlayers() { + if (this.config.countPlayers()) { + int cc = 0; + int other = 0; + for (final Player p : this.client.getPlayers()) { + if (Objects.nonNull(p) && PvPUtil.isAttackable(this.client, p)) { + if (p.isClanMember()) { + ++cc; + } + else { + ++other; + } + } + } + this.panel.numOther.setText(PvpToolsPanel.htmlLabel("Other Player Count: ", String.valueOf(other))); + this.panel.numCC.setText(PvpToolsPanel.htmlLabel("Friendly Player Count: ", String.valueOf(cc))); + this.panel.numCC.repaint(); + this.panel.numOther.repaint(); + } + } + + private void countOverHeads() { + this.overheadCount = new int[] { 0, 0, 0 }; + for (final Player p : this.client.getPlayers()) { + if (Objects.nonNull(p) && PvPUtil.isAttackable(this.client, p) && !p.isClanMember() && p.getOverheadIcon() != null) { + switch (p.getOverheadIcon()) { + case MAGIC: { + final int[] overheadCount = this.overheadCount; + final int n = 0; + ++overheadCount[n]; + continue; + } + case RANGED: { + final int[] overheadCount2 = this.overheadCount; + final int n2 = 1; + ++overheadCount2[n2]; + continue; + } + case MELEE: { + final int[] overheadCount3 = this.overheadCount; + final int n3 = 2; + ++overheadCount3[n3]; + continue; + } + } + } + } + this.updatePrayerNumbers(); + } + + private void getCarriedWealth() { + if (!this.config.riskCalculatorEnabled()) { + return; + } + if (this.client.getItemContainer(InventoryID.EQUIPMENT) == null) { + return; + } + if (this.client.getItemContainer(InventoryID.INVENTORY).getItems() == null) { + return; + } + final Item[] items = ArrayUtils.addAll(Objects.requireNonNull(this.client.getItemContainer(InventoryID.EQUIPMENT)).getItems(), Objects.requireNonNull(this.client.getItemContainer(InventoryID.INVENTORY)).getItems()); + final TreeMap priceMap = new TreeMap(Comparator.comparingInt(Integer::intValue)); + int wealth = 0; + for (final Item i : items) { + int value = this.itemManager.getItemPrice(i.getId()) * i.getQuantity(); + final ItemComposition itemComposition = this.itemManager.getItemComposition(i.getId()); + if (!itemComposition.isTradeable() && value == 0) { + value = itemComposition.getPrice() * i.getQuantity(); + priceMap.put(value, i); + } + else { + value = this.itemManager.getItemPrice(i.getId()) * i.getQuantity(); + if (i.getId() > 0 && value > 0) { + priceMap.put(value, i); + } + } + wealth += value; + } + this.panel.totalRiskLabel.setText(PvpToolsPanel.htmlLabel("Total risk: ", StackFormatter.quantityToRSDecimalStack(wealth))); + this.panel.totalRiskLabel.repaint(); + int itemLimit = 0; + if (this.client.getLocalPlayer().getSkullIcon() != null && this.client.getLocalPlayer().getSkullIcon() == SkullIcon.SKULL) { + itemLimit = 1; + } + if (this.client.getLocalPlayer().getSkullIcon() == null) { + itemLimit = 4; + } + AsyncBufferedImage itemImage = null; + final NavigableMap descendingMap = priceMap.descendingMap(); + for (int j = 0; j < itemLimit; ++j) { + if (j == 0) { + if (!descendingMap.isEmpty()) { + itemImage = this.itemManager.getImage(descendingMap.pollFirstEntry().getValue().getId()); + } + } + else if (!descendingMap.isEmpty()) { + this.itemManager.getItemComposition(priceMap.descendingMap().pollFirstEntry().getValue().getId()).getName(); + } + } + this.panel.riskProtectingItem.setText(PvpToolsPanel.htmlLabel("Risk Protecting Item: ", StackFormatter.quantityToRSDecimalStack(descendingMap.keySet().stream().mapToInt(Integer::intValue).sum()))); + this.panel.riskProtectingItem.repaint(); + this.panel.biggestItemLabel.setText("Most Valuable Item: "); + if (itemImage != null) { + itemImage.addTo(this.panel.biggestItemLabel); + } + this.panel.biggestItemLabel.repaint(); + } + + boolean isAttackHotKeyPressed() { + return this.attackHotKeyPressed; + } + + void setAttackHotKeyPressed(final boolean attackHotKeyPressed) { + this.attackHotKeyPressed = attackHotKeyPressed; + } + + boolean isHideAll() { + return this.hideAll; + } + + void setHideAll(final boolean hideAll) { + this.hideAll = hideAll; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/skull.png b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/skull.png new file mode 100644 index 0000000000..09869ea0e1 Binary files /dev/null and b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/skull.png differ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java index f4ff6078f1..954eb72b56 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java @@ -42,7 +42,8 @@ import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( name = "Shayzien Infirmary", description = "Shows the status of wounded soldiers", - tags = {"shayzien", "infirmary", "soldiers"} + tags = {"shayzien", "infirmary", "soldiers"}, + type = "utility" ) public class ShayzienInfirmaryPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java index aef2adb45e..cedc212d04 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java @@ -41,10 +41,11 @@ import javax.inject.Inject; * Shift Walker Plugin. Credit to MenuEntrySwapperPlugin for code some code structure used here. */ @PluginDescriptor( - name = "!Shift To Walk Here", + name = "Shift To Walk", description = "Use Shift to toggle the Walk Here menu option. While pressed you will Walk rather than interact with objects.", tags = {"npcs", "items", "objects"}, - enabledByDefault = false + enabledByDefault = false, + type = "utility" ) public class ShiftWalkerPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skybox/Skybox.java b/runelite-client/src/main/java/net/runelite/client/plugins/skybox/Skybox.java index e513166143..aa770f37f8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skybox/Skybox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skybox/Skybox.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.skybox; +import java.awt.Color; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.IOException; @@ -447,7 +448,7 @@ class Skybox } // Convert back to int range values, and bounds check while we are at it - byte ay = (byte) Math.min(Math.max(Math.round(Math.pow(ty / t, brightness) * 255.d), 0), 255); + byte ay = (byte) Math.min(Math.max(Math.round(ty / t * 255.d), 0), 255); byte aco = (byte) Math.min(Math.max(Math.round(tco * 128.d / t), -128), 127); byte acg = (byte) Math.min(Math.max(Math.round(tcg * 128.d / t), -128), 127); @@ -457,7 +458,11 @@ class Skybox int r = (tmp - (aco >> 1)) & 0xFF; int b = (r + aco) & 0xFF; - return r << 16 | g << 8 | b; + // increase brightness with HSB + float[] hsb = Color.RGBtoHSB(r, g, b, null); + hsb[2] = (float) Math.pow(hsb[2], brightness); + + return 0xFFFFFF & Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]); } /** 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 index 7e07a0564d..c856886cb2 100644 --- 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 @@ -76,9 +76,10 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @PluginDescriptor( - name = "!Slayermusiq1 Guides", + name = "Slayermusiq1 Guides", description = "Adds a right-click option to go to Slayermusiq1's guides from the quest tab", - tags = {"quest", "guide", "slayermusiq"} + tags = {"quest", "guide", "slayermusiq"}, + type = "utility" ) @Slf4j public class SlayermusiqPlugin extends Plugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java index 7d71cef371..4f4456e4fb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java @@ -21,7 +21,8 @@ import javax.inject.Inject; @PluginDescriptor( name = "Spellbook Fixer", description = "Resize and filter spellbook for PKing", - tags = {"resize", "spellbook", "magic", "spell", "pk", "book", "filter", "bogla"} + tags = {"resize", "spellbook", "magic", "spell", "pk", "book", "filter", "bogla"}, + type = "PVP" ) @Slf4j public class SpellbookFixerPlugin extends Plugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java index 99fd1d4286..2f2d7a8495 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java @@ -44,7 +44,8 @@ import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( name = "Temple Trekking", description = "Helpers for the Temple Trek minigame", - tags = {"minigame", "overlay", "temple trek"} + tags = {"minigame", "overlay", "temple trek"}, + type = "utility" ) public class TempleTrekPlugin extends Plugin { 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 fe2130285c..4e40b23ff3 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 @@ -21,9 +21,10 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -@PluginDescriptor(name = "!Tick Counter", +@PluginDescriptor(name = "Tick Counter", description = "Counts combat activity for nearby players", - enabledByDefault = false + enabledByDefault = false, + type = "utility" ) public class TickCounterPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java index d7cda5adff..7b49a30ece 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java @@ -56,6 +56,7 @@ import net.runelite.client.eventbus.Subscribe; description = "Gives you an estimation damage on a boss and taken after the fight is done" + "the damage will be posted in the chat", tags = {"combat", "npcs", "tob", "damage"}, + type = "PVM", enabledByDefault = false ) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vanguards/VanguardOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/vanguards/VanguardOverlay.java new file mode 100644 index 0000000000..a4a74ad8a6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vanguards/VanguardOverlay.java @@ -0,0 +1,119 @@ + +package net.runelite.client.plugins.vanguards; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; + +import net.runelite.api.Actor; +import net.runelite.api.NPC; +import net.runelite.api.Player; +import net.runelite.api.Client; +import net.runelite.client.game.NPCManager; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +import net.runelite.client.plugins.opponentinfo.OpponentInfoPlugin; +//import net.runelite.client.plugins.opponentinfo.OpponentInfoOverlay; + +import javax.inject.Inject; + +public class VanguardOverlay extends Overlay { + + private VanguardPlugin plugin; + private final PanelComponent panelComponent = new PanelComponent(); + + private static final int MAGE_VANGUARD_ID = 7529; + private static final int RANGE_VANGUARD_ID = 7528; + private static final int MELEE_VANGUARD_ID = 7527; + //private final NPCManager npcManager; + + private int mageHp = -1; + private float magePercent = 0; + + private int rangeHp = -1; + private float rangePercent = 0; + + private int meleeHp = -1; + private float meleePercent = 0; + + public String right_mage_str, right_range_str, right_melee_str = ""; + + @Inject + private Client client; + + + @Inject + public VanguardOverlay(VanguardPlugin plugin) { + super(plugin);//? + this.plugin = plugin; + + setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); + //this.opponentInfoPlugin = opponentInfoPlugin; + } + + @Override + public Dimension render(Graphics2D graphics) + { + Player p = client.getLocalPlayer(); //local player aka me + Actor opponent = p.getInteracting(); //get entity i am interacting with + //how to find its Id since it's an Actor not NPC specifically + //if(opponent.getName().equals("Vanguard") && opponent.getHealth() > 0)//might wana double check the name + //{ + if(opponent instanceof NPC) + { + int id = ((NPC) opponent).getId(); + String name = opponent.getName(); + + if(id == MAGE_VANGUARD_ID) //maybe check name.equals("Vanguard") + { + magePercent = (float)opponent.getHealthRatio() / opponent.getHealth() * 100; + mageHp = (int)magePercent; + right_mage_str = Integer.toString(mageHp); + System.out.println("mager"); + } + else if (id == RANGE_VANGUARD_ID) + { + rangePercent = (float)opponent.getHealthRatio() / opponent.getHealth() * 100; + rangeHp = (int)rangePercent; + right_range_str = Integer.toString(rangeHp); + + System.out.println("ranger"); + } + else if (id == MELEE_VANGUARD_ID) + { + meleePercent = (float)opponent.getHealthRatio()/opponent.getHealth() * 100; + meleeHp = (int)meleePercent; + right_melee_str = Integer.toString(meleeHp); + + + System.out.println("meleer"); + } + } + //} + + + //if (opponent == null) { + //} + + + panelComponent.getChildren().clear(); + String overlayTitle = "Vanguard HP"; + //title + panelComponent.getChildren().add(TitleComponent.builder().text(overlayTitle).color(Color.RED).build()); + + //size (width) + panelComponent.setPreferredSize(new Dimension(graphics.getFontMetrics().stringWidth(overlayTitle) + 30, 0)); + + panelComponent.getChildren().add(LineComponent.builder().left("Mage:").right(right_mage_str).build()); + + panelComponent.getChildren().add(LineComponent.builder().left("Range:").right(right_range_str).build()); + + panelComponent.getChildren().add(LineComponent.builder().left("Melee:").right(right_melee_str).build()); + + return panelComponent.render(graphics); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vanguards/VanguardPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/vanguards/VanguardPlugin.java new file mode 100644 index 0000000000..88cb075867 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vanguards/VanguardPlugin.java @@ -0,0 +1,45 @@ + +package net.runelite.client.plugins.vanguards; + +import javax.inject.Inject; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name= "Vanguard HP Overlay", + description= "tracks HP of all three vanguards", + tags= {"overlay", "vangs", "cox"}, + enabledByDefault = false, + type = "PVM" +) +public class VanguardPlugin extends Plugin { + private static final int MAGE_VANGUARD_ID = 7526; //i think + private static final int RANGE_VANGUARD_ID = 7527; + private static final int MELEE_VANGUARD_ID = 7528; + + + @Inject + private OverlayManager overlayManager; + + @Inject + private VanguardOverlay overlay; + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + overlay.right_mage_str = "-"; + overlay.right_range_str = "-"; + overlay.right_melee_str = "-"; + } + + +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java index 9df9a4fa57..847c1f3678 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java @@ -40,9 +40,10 @@ import java.util.HashMap; import java.util.Map; @PluginDescriptor( - name = "!Vetion", + name = "Vetion", description = "Tracks Vet'ion's special attacks", - tags = {"bosses", "combat", "pve", "overlay"} + tags = {"bosses", "combat", "pve", "overlay"}, + type = "PVM" ) public class VetionPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java index 1ba5e4b0e7..060a9d2246 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java @@ -14,9 +14,10 @@ import net.runelite.client.ui.overlay.OverlayManager; import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( - name = "!Vorkath", + name = "Vorkath", description = "Vorkath Helper", - tags = {"Vorkath", "Helper"} + tags = {"Vorkath", "Helper"}, + type = "PVM" ) public class VorkathPlugin extends Plugin { diff --git a/whalewatchers/WhaleWatchersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersConfig.java similarity index 100% rename from whalewatchers/WhaleWatchersConfig.java rename to runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersConfig.java diff --git a/whalewatchers/WhaleWatchersGloryOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersGloryOverlay.java similarity index 100% rename from whalewatchers/WhaleWatchersGloryOverlay.java rename to runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersGloryOverlay.java diff --git a/whalewatchers/WhaleWatchersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersOverlay.java similarity index 100% rename from whalewatchers/WhaleWatchersOverlay.java rename to runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersOverlay.java diff --git a/whalewatchers/WhaleWatchersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java similarity index 96% rename from whalewatchers/WhaleWatchersPlugin.java rename to runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java index 3d6fc5fe97..48a9b20581 100644 --- a/whalewatchers/WhaleWatchersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java @@ -14,7 +14,13 @@ import net.runelite.api.*; import net.runelite.api.events.*; import java.util.*; -@PluginDescriptor(name = "!Whale Watchers", description = "A Plugin to save help whales in the wild", tags = { "whale watchers", "whale", "protect item", "warning", "pklite" }, enabledByDefault = true, hidden = false, developerPlugin = false, loadWhenOutdated = false) +@PluginDescriptor( + name = "Whale Watchers", + description = "A Plugin to save help whales in the wild", + tags = { "whale watchers", "whale", "protect item", "warning", "pklite" }, + type = "PVP", + enabledByDefault = false +) public class WhaleWatchersPlugin extends Plugin { @Inject diff --git a/whalewatchers/WhaleWatchersProtOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersProtOverlay.java similarity index 100% rename from whalewatchers/WhaleWatchersProtOverlay.java rename to runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersProtOverlay.java diff --git a/whalewatchers/WhaleWatchersSmiteableOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersSmiteableOverlay.java similarity index 100% rename from whalewatchers/WhaleWatchersSmiteableOverlay.java rename to runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersSmiteableOverlay.java 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 0020f384f4..c698e5894a 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 @@ -25,7 +25,8 @@ import net.runelite.client.util.WildernessLocation; @PluginDescriptor(name="PvP Wild Locations", description="Indicates the players current location in the wild", - tags={"Wildy,", "Wilderness Location", "location", "loc", "pvp", "pklite"}) + tags={"Wildy,", "Wilderness Location", "location", "loc", "pvp", "pklite"}, + type = "PVP") public class WildernessLocationsPlugin extends Plugin { @Inject diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java index f7a75781fd..a88c9510b6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java @@ -112,4 +112,15 @@ public interface WorldHopperConfig extends Config { return SubscriptionFilterMode.BOTH; } + + @ConfigItem( + keyName = "showHistory", + name = "Show history tab", + description = "Shows the history tab", + position = 5 + ) + default boolean showHistory() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index a6d52f7025..88b6089f4a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -258,10 +258,49 @@ public class WorldHopperPlugin extends Plugin panel.setFilterMode(config.subscriptionFilter()); updateList(); break; + case "showHistory": + panel.updateLayout(); + break; } } } + boolean showHistory() + { + return config.showHistory(); + } + + Map getHistory() + { + Map history = configManager.getConfiguration(WorldHopperConfig.GROUP, "history", Map.class); + if (history == null) + { + history = new HashMap(); + } + + return history; + } + + void clearHistory() + { + Map history = getHistory(); + history.clear(); + configManager.setConfiguration(WorldHopperConfig.GROUP, "history", history); + } + + void addToHistory() + { + addToHistory(client.getWorld()); + } + + void addToHistory(int world) + { + long unixTime = System.currentTimeMillis() / 1000L; + Map history = getHistory(); + history.put(String.valueOf(world), String.valueOf(unixTime)); + configManager.setConfiguration(WorldHopperConfig.GROUP, "history", history); + } + private void setFavoriteConfig(int world) { configManager.setConfiguration(WorldHopperConfig.GROUP, "favorite_" + world, true); @@ -408,6 +447,12 @@ public class WorldHopperPlugin extends Plugin lastWorld = newWorld; } } + + if (gameStateChanged.getGameState() == GameState.LOGGED_IN) + { + addToHistory(client.getWorld()); + panel.updateList(); + } } @Subscribe @@ -644,6 +689,8 @@ public class WorldHopperPlugin extends Plugin quickHopTargetWorld = rsWorld; displaySwitcherAttempts = 0; + + addToHistory(worldId); } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java index b27f356dac..fbe8ecdbaa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java @@ -1,399 +1,637 @@ -/* - * Copyright (c) 2018, Psikoi - * 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.worldhopper; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.GridLayout; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import javax.swing.JPanel; -import javax.swing.SwingUtilities; -import lombok.AccessLevel; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.client.ui.ColorScheme; -import net.runelite.client.ui.DynamicGridLayout; -import net.runelite.client.ui.PluginPanel; -import net.runelite.http.api.worlds.World; -import net.runelite.http.api.worlds.WorldType; - -@Slf4j -class WorldSwitcherPanel extends PluginPanel -{ - private static final Color ODD_ROW = new Color(44, 44, 44); - - private static final int WORLD_COLUMN_WIDTH = 60; - private static final int PLAYERS_COLUMN_WIDTH = 40; - private static final int PING_COLUMN_WIDTH = 47; - - private final JPanel listContainer = new JPanel(); - - private WorldTableHeader worldHeader; - private WorldTableHeader playersHeader; - private WorldTableHeader activityHeader; - private WorldTableHeader pingHeader; - - private WorldOrder orderIndex = WorldOrder.WORLD; - private boolean ascendingOrder = true; - - private ArrayList rows = new ArrayList<>(); - private WorldHopperPlugin plugin; - @Setter(AccessLevel.PACKAGE) - private SubscriptionFilterMode filterMode; - - WorldSwitcherPanel(WorldHopperPlugin plugin) - { - this.plugin = plugin; - - setBorder(null); - setLayout(new DynamicGridLayout(0, 1)); - - JPanel headerContainer = buildHeader(); - - listContainer.setLayout(new GridLayout(0, 1)); - - add(headerContainer); - add(listContainer); - } - - void switchCurrentHighlight(int newWorld, int lastWorld) - { - for (WorldTableRow row : rows) - { - if (row.getWorld().getId() == newWorld) - { - row.recolour(true); - } - else if (row.getWorld().getId() == lastWorld) - { - row.recolour(false); - } - } - } - - void updateListData(Map worldData) - { - for (WorldTableRow worldTableRow : rows) - { - World world = worldTableRow.getWorld(); - Integer playerCount = worldData.get(world.getId()); - if (playerCount != null) - { - worldTableRow.updatePlayerCount(playerCount); - } - } - - // If the list is being ordered by player count, then it has to be re-painted - // to properly display the new data - if (orderIndex == WorldOrder.PLAYERS) - { - updateList(); - } - } - - void updatePing(int world, int ping) - { - for (WorldTableRow worldTableRow : rows) - { - if (worldTableRow.getWorld().getId() == world) - { - worldTableRow.setPing(ping); - - // If the panel is sorted by ping, re-sort it - if (orderIndex == WorldOrder.PING) - { - updateList(); - } - break; - } - } - } - - void hidePing() - { - for (WorldTableRow worldTableRow : rows) - { - worldTableRow.hidePing(); - } - } - - void showPing() - { - for (WorldTableRow worldTableRow : rows) - { - worldTableRow.showPing(); - } - } - - void updateList() - { - rows.sort((r1, r2) -> - { - switch (orderIndex) - { - case PING: - return Integer.compare(r1.getPing(), r2.getPing()) * (ascendingOrder ? 1 : -1); - case WORLD: - return Integer.compare(r1.getWorld().getId(), r2.getWorld().getId()) * (ascendingOrder ? 1 : -1); - case PLAYERS: - return Integer.compare(r1.getUpdatedPlayerCount(), r2.getUpdatedPlayerCount()) * (ascendingOrder ? 1 : -1); - case ACTIVITY: - return r1.getWorld().getActivity().compareTo(r2.getWorld().getActivity()) * -1 * (ascendingOrder ? 1 : -1); - default: - return 0; - } - }); - - // Leave empty activity worlds on the bottom of the list - if (orderIndex == WorldOrder.ACTIVITY) - { - rows.sort((r1, r2) -> r1.getWorld().getActivity().equals("-") ? 1 : -1); - } - - rows.sort((r1, r2) -> - { - boolean b1 = plugin.isFavorite(r1.getWorld()); - boolean b2 = plugin.isFavorite(r2.getWorld()); - return Boolean.compare(b2, b1); - }); - - listContainer.removeAll(); - - for (int i = 0; i < rows.size(); i++) - { - WorldTableRow row = rows.get(i); - row.setBackground(i % 2 == 0 ? ODD_ROW : ColorScheme.DARK_GRAY_COLOR); - listContainer.add(row); - } - - listContainer.revalidate(); - listContainer.repaint(); - } - - void updateFavoriteMenu(int world, boolean favorite) - { - for (WorldTableRow row : rows) - { - if (row.getWorld().getId() == world) - { - row.setFavoriteMenu(favorite); - } - } - } - - void resetAllFavoriteMenus() - { - for (WorldTableRow row : rows) - { - row.setFavoriteMenu(false); - } - - } - - void populate(List worlds) - { - rows.clear(); - - for (int i = 0; i < worlds.size(); i++) - { - World world = worlds.get(i); - - switch (filterMode) - { - case FREE: - if (world.getTypes().contains(WorldType.MEMBERS)) - { - continue; - } - break; - case MEMBERS: - if (!world.getTypes().contains(WorldType.MEMBERS)) - { - continue; - } - break; - } - - rows.add(buildRow(world, i % 2 == 0, world.getId() == plugin.getCurrentWorld() && plugin.getLastWorld() != 0, plugin.isFavorite(world))); - } - - updateList(); - } - - private void orderBy(WorldOrder order) - { - pingHeader.highlight(false, ascendingOrder); - worldHeader.highlight(false, ascendingOrder); - playersHeader.highlight(false, ascendingOrder); - activityHeader.highlight(false, ascendingOrder); - - switch (order) - { - case PING: - pingHeader.highlight(true, ascendingOrder); - break; - case WORLD: - worldHeader.highlight(true, ascendingOrder); - break; - case PLAYERS: - playersHeader.highlight(true, ascendingOrder); - break; - case ACTIVITY: - activityHeader.highlight(true, ascendingOrder); - break; - } - - orderIndex = order; - updateList(); - } - - /** - * Builds the entire table header. - */ - private JPanel buildHeader() - { - JPanel header = new JPanel(new BorderLayout()); - JPanel leftSide = new JPanel(new BorderLayout()); - JPanel rightSide = new JPanel(new BorderLayout()); - - pingHeader = new WorldTableHeader("Ping", orderIndex == WorldOrder.PING, ascendingOrder, plugin::refresh); - pingHeader.setPreferredSize(new Dimension(PING_COLUMN_WIDTH, 0)); - pingHeader.addMouseListener(new MouseAdapter() - { - @Override - public void mousePressed(MouseEvent mouseEvent) - { - if (SwingUtilities.isRightMouseButton(mouseEvent)) - { - return; - } - ascendingOrder = orderIndex != WorldOrder.PING || !ascendingOrder; - orderBy(WorldOrder.PING); - } - }); - - worldHeader = new WorldTableHeader("World", orderIndex == WorldOrder.WORLD, ascendingOrder, plugin::refresh); - worldHeader.setPreferredSize(new Dimension(WORLD_COLUMN_WIDTH, 0)); - worldHeader.addMouseListener(new MouseAdapter() - { - @Override - public void mousePressed(MouseEvent mouseEvent) - { - if (SwingUtilities.isRightMouseButton(mouseEvent)) - { - return; - } - ascendingOrder = orderIndex != WorldOrder.WORLD || !ascendingOrder; - orderBy(WorldOrder.WORLD); - } - }); - - playersHeader = new WorldTableHeader("#", orderIndex == WorldOrder.PLAYERS, ascendingOrder, plugin::refresh); - playersHeader.setPreferredSize(new Dimension(PLAYERS_COLUMN_WIDTH, 0)); - playersHeader.addMouseListener(new MouseAdapter() - { - @Override - public void mousePressed(MouseEvent mouseEvent) - { - if (SwingUtilities.isRightMouseButton(mouseEvent)) - { - return; - } - ascendingOrder = orderIndex != WorldOrder.PLAYERS || !ascendingOrder; - orderBy(WorldOrder.PLAYERS); - } - }); - - activityHeader = new WorldTableHeader("Activity", orderIndex == WorldOrder.ACTIVITY, ascendingOrder, plugin::refresh); - activityHeader.addMouseListener(new MouseAdapter() - { - @Override - public void mousePressed(MouseEvent mouseEvent) - { - if (SwingUtilities.isRightMouseButton(mouseEvent)) - { - return; - } - ascendingOrder = orderIndex != WorldOrder.ACTIVITY || !ascendingOrder; - orderBy(WorldOrder.ACTIVITY); - } - }); - - leftSide.add(worldHeader, BorderLayout.WEST); - leftSide.add(playersHeader, BorderLayout.CENTER); - - rightSide.add(activityHeader, BorderLayout.CENTER); - rightSide.add(pingHeader, BorderLayout.EAST); - - header.add(leftSide, BorderLayout.WEST); - header.add(rightSide, BorderLayout.CENTER); - - return header; - } - - /** - * Builds a table row, that displays the world's information. - */ - private WorldTableRow buildRow(World world, boolean stripe, boolean current, boolean favorite) - { - WorldTableRow row = new WorldTableRow(world, current, favorite, - world1 -> - { - plugin.hopTo(world1); - }, - (world12, add) -> - { - if (add) - { - plugin.addToFavorites(world12); - } - else - { - plugin.removeFromFavorites(world12); - } - - updateList(); - } - ); - row.setBackground(stripe ? ODD_ROW : ColorScheme.DARK_GRAY_COLOR); - return row; - } - - /** - * Enumerates the multiple ordering options for the world list. - */ - private enum WorldOrder - { - WORLD, - PLAYERS, - ACTIVITY, - PING - } -} +/* + * Copyright (c) 2018, Psikoi + * 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.worldhopper; + +import java.awt.Component; +import java.awt.GridBagConstraints; +import java.awt.GridLayout; +import java.awt.GridBagLayout; +import java.awt.Color; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.HashMap; +import java.util.stream.Collectors; +import javax.swing.JPanel; +import javax.swing.JButton; +import javax.swing.JTabbedPane; +import javax.swing.border.Border; +import javax.swing.BorderFactory; +import javax.swing.SwingUtilities; +import lombok.AccessLevel; +import lombok.Setter; + +import lombok.extern.slf4j.Slf4j; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.DynamicGridLayout; +import net.runelite.client.ui.PluginPanel; +import net.runelite.http.api.worlds.World; +import net.runelite.http.api.worlds.WorldType; + +@Slf4j +class WorldSwitcherPanel extends PluginPanel +{ + private static final Color ODD_ROW = new Color(44, 44, 44); + + private static final int WORLD_COLUMN_WIDTH = 60; + private static final int PLAYERS_COLUMN_WIDTH = 40; + private static final int PING_COLUMN_WIDTH = 47; + + private final JPanel headerContainer; + private final JPanel headerHistContainer; + private final JPanel listContainer = new JPanel(); + private final JPanel histContainer = new JPanel(); + + private WorldTableHeader worldHeader; + private WorldTableHeader playersHeader; + private WorldTableHeader activityHeader; + private WorldTableHeader pingHeader; + + private WorldOrder orderIndex = WorldOrder.WORLD; + private boolean ascendingOrder = true; + + private ArrayList rows = new ArrayList<>(); + private ArrayList histRows = new ArrayList<>(); + private WorldHopperPlugin plugin; + @Setter(AccessLevel.PACKAGE) + private SubscriptionFilterMode filterMode; + + WorldSwitcherPanel(WorldHopperPlugin plugin) + { + this.plugin = plugin; + + setBorder(null); + setLayout(new DynamicGridLayout(0, 1)); + + headerContainer = buildHeader(); + headerHistContainer = buildHistoryHeader(); + + listContainer.setLayout(new GridLayout(0, 1)); + histContainer.setLayout(new GridLayout(0, 1)); + + updateLayout(); + } + + void updateLayout() + { + if (this.getComponentCount() > 0) + { + for (Component c : this.getComponents()) + { + this.remove(c); + } + } + + if (plugin.showHistory()) + { + Component tabs = createTabs(); + add(tabs); + } + else + { + add(headerContainer); + add(listContainer); + } + } + + void switchCurrentHighlight(int newWorld, int lastWorld) + { + for (WorldTableRow row : rows) + { + if (row.getWorld().getId() == newWorld) + { + row.recolour(true); + } + else if (row.getWorld().getId() == lastWorld) + { + row.recolour(false); + } + } + + for (WorldTableRow row : histRows) + { + if (row.getWorld().getId() == newWorld) + { + row.recolour(true); + } + else if (row.getWorld().getId() == lastWorld) + { + row.recolour(false); + } + } + } + + void updateListData(Map worldData) + { + for (WorldTableRow worldTableRow : rows) + { + World world = worldTableRow.getWorld(); + Integer playerCount = worldData.get(world.getId()); + if (playerCount != null) + { + worldTableRow.updatePlayerCount(playerCount); + } + } + + for (WorldTableRow worldTableRow : histRows) + { + World world = worldTableRow.getWorld(); + Integer playerCount = worldData.get(world.getId()); + if (playerCount != null) + { + worldTableRow.updatePlayerCount(playerCount); + } + } + + // If the list is being ordered by player count, then it has to be re-painted + // to properly display the new data + if (orderIndex == WorldOrder.PLAYERS) + { + updateList(); + } + } + + void updatePing(int world, int ping) + { + for (WorldTableRow worldTableRow : rows) + { + if (worldTableRow.getWorld().getId() == world) + { + worldTableRow.setPing(ping); + + // If the panel is sorted by ping, re-sort it + if (orderIndex == WorldOrder.PING) + { + updateList(); + } + break; + } + } + + for (WorldTableRow worldTableRow : histRows) + { + if (worldTableRow.getWorld().getId() == world) + { + worldTableRow.setPing(ping); + + // If the panel is sorted by ping, re-sort it + if (orderIndex == WorldOrder.PING) + { + updateList(); + } + break; + } + } + } + + void hidePing() + { + for (WorldTableRow worldTableRow : rows) + { + worldTableRow.hidePing(); + } + + for (WorldTableRow worldTableRow : histRows) + { + worldTableRow.hidePing(); + } + } + + void showPing() + { + for (WorldTableRow worldTableRow : rows) + { + worldTableRow.showPing(); + } + + for (WorldTableRow worldTableRow : histRows) + { + worldTableRow.showPing(); + } + } + + void updateList() + { + rows.sort((r1, r2) -> + { + switch (orderIndex) + { + case PING: + return Integer.compare(r1.getPing(), r2.getPing()) * (ascendingOrder ? 1 : -1); + case WORLD: + return Integer.compare(r1.getWorld().getId(), r2.getWorld().getId()) * (ascendingOrder ? 1 : -1); + case PLAYERS: + return Integer.compare(r1.getUpdatedPlayerCount(), r2.getUpdatedPlayerCount()) * (ascendingOrder ? 1 : -1); + case ACTIVITY: + return r1.getWorld().getActivity().compareTo(r2.getWorld().getActivity()) * -1 * (ascendingOrder ? 1 : -1); + default: + return 0; + } + }); + + // Leave empty activity worlds on the bottom of the list + if (orderIndex == WorldOrder.ACTIVITY) + { + rows.sort((r1, r2) -> r1.getWorld().getActivity().equals("-") ? 1 : -1); + } + + rows.sort((r1, r2) -> + { + boolean b1 = plugin.isFavorite(r1.getWorld()); + boolean b2 = plugin.isFavorite(r2.getWorld()); + return Boolean.compare(b2, b1); + }); + + listContainer.removeAll(); + histContainer.removeAll(); + + Map history = plugin.getHistory(); + Map matchedHist = new HashMap<>(); + for (int i = 0; i < rows.size(); i++) + { + WorldTableRow row = rows.get(i); + row.setBackground(i % 2 == 0 ? ODD_ROW : ColorScheme.DARK_GRAY_COLOR); + listContainer.add(row); + + String worldNum = String.valueOf(row.getWorld().getId()); + if (history.containsKey(worldNum)) + { + // Add toa list that we can sort later + matchedHist.put(worldNum, history.get(worldNum)); + } + } + + // Sort by ascending + matchedHist = matchedHist.entrySet().stream() + .sorted(Map.Entry.comparingByValue().reversed()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, + (e1, e2) -> e1, LinkedHashMap::new)); + + // Add matched rows to history list + Iterator it = matchedHist.entrySet().iterator(); + int histRowCount = 0; + while (it.hasNext()) + { + Map.Entry pair = (Map.Entry)it.next(); + for (WorldTableRow r : rows) + { + WorldTableRow histRow = r; + histRow.setBackground(histRowCount % 2 == 0 ? ODD_ROW : ColorScheme.DARK_GRAY_COLOR); + if (String.valueOf(r.getWorld().getId()).equals(pair.getKey())) + { + histContainer.add(r); + histRowCount++; + break; + } + } + it.remove(); + } + + listContainer.revalidate(); + listContainer.repaint(); + histContainer.revalidate(); + histContainer.repaint(); + } + + Component createTabs() + { + // Constraints for GB Layout + GridBagConstraints listConst = new GridBagConstraints(); + listConst.gridx = 0; + listConst.gridy = 1; + listConst.fill = GridBagConstraints.HORIZONTAL; + GridBagConstraints headConst = new GridBagConstraints(); + headConst.gridx = 0; + headConst.gridy = 0; + headConst.fill = GridBagConstraints.HORIZONTAL; + GridBagConstraints resetConst = new GridBagConstraints(); + resetConst.gridx = 0; + resetConst.gridy = 2; + resetConst.fill = GridBagConstraints.HORIZONTAL; + + // Border so that the scrollbar doesn't go over ping + Border paddingBorder = BorderFactory.createEmptyBorder(0, 0, 0, 5); + + // Clear history button + JButton resetBtn = new JButton("Clear History"); + resetBtn.addActionListener(e -> + { + plugin.clearHistory(); + plugin.addToHistory(); + updateList(); + }); + + // World Selector page + JPanel worldPanel = new JPanel(); + worldPanel.setBorder(paddingBorder); + worldPanel.setLayout(new GridBagLayout()); + worldPanel.add(headerContainer, headConst); + worldPanel.add(listContainer, listConst); + + // History page + JPanel histPanel = new JPanel(); + histPanel.setBorder(paddingBorder); + histPanel.setLayout(new GridBagLayout()); + histPanel.add(headerHistContainer, headConst); + histPanel.add(histContainer, listConst); + histPanel.add(resetBtn, resetConst); + + JTabbedPane worldTabs = new JTabbedPane(); + worldTabs.setName("tabs"); + worldTabs.addTab("Worlds", worldPanel); + worldTabs.addTab("History", histPanel); + + // This is a fix for preventing stretching of WorldTableRows + worldTabs.addChangeListener(e -> + { + switch (worldTabs.getSelectedIndex()) + { + case 0: + histPanel.remove(histContainer); + if (worldPanel.getComponentCount() < 2) + { + worldPanel.add(listContainer, listConst); + } + break; + case 1: + worldPanel.remove(listContainer); + if (histPanel.getComponentCount() < 3) + { + histPanel.add(histContainer, listConst); + } + break; + } + }); + + return worldTabs; + } + + void updateFavoriteMenu(int world, boolean favorite) + { + for (WorldTableRow row : rows) + { + if (row.getWorld().getId() == world) + { + row.setFavoriteMenu(favorite); + } + } + + for (WorldTableRow row : histRows) + { + if (row.getWorld().getId() == world) + { + row.setFavoriteMenu(favorite); + } + } + } + + void resetAllFavoriteMenus() + { + for (WorldTableRow row : rows) + { + row.setFavoriteMenu(false); + } + + for (WorldTableRow row : histRows) + { + row.setFavoriteMenu(false); + } + } + + void populate(List worlds) + { + rows.clear(); + + for (int i = 0; i < worlds.size(); i++) + { + World world = worlds.get(i); + + switch (filterMode) + { + case FREE: + if (world.getTypes().contains(WorldType.MEMBERS)) + { + continue; + } + break; + case MEMBERS: + if (!world.getTypes().contains(WorldType.MEMBERS)) + { + continue; + } + break; + } + + rows.add(buildRow(world, i % 2 == 0, world.getId() == plugin.getCurrentWorld() && plugin.getLastWorld() != 0, plugin.isFavorite(world))); + } + + updateList(); + } + + private void orderBy(WorldOrder order) + { + pingHeader.highlight(false, ascendingOrder); + worldHeader.highlight(false, ascendingOrder); + playersHeader.highlight(false, ascendingOrder); + activityHeader.highlight(false, ascendingOrder); + + switch (order) + { + case PING: + pingHeader.highlight(true, ascendingOrder); + break; + case WORLD: + worldHeader.highlight(true, ascendingOrder); + break; + case PLAYERS: + playersHeader.highlight(true, ascendingOrder); + break; + case ACTIVITY: + activityHeader.highlight(true, ascendingOrder); + break; + } + + orderIndex = order; + updateList(); + } + + /** + * Builds the entire table header. + */ + private JPanel buildHistoryHeader() + { + JPanel header = new JPanel(new BorderLayout()); + JPanel leftSide = new JPanel(new BorderLayout()); + JPanel rightSide = new JPanel(new BorderLayout()); + + WorldTableHeader pingHeader = new WorldTableHeader("Ping", false, ascendingOrder, plugin::refresh); + pingHeader.setPreferredSize(new Dimension(PING_COLUMN_WIDTH, 0)); + + WorldTableHeader worldHeader = new WorldTableHeader("World", false, ascendingOrder, plugin::refresh); + worldHeader.setPreferredSize(new Dimension(WORLD_COLUMN_WIDTH, 0)); + + WorldTableHeader playersHeader = new WorldTableHeader("#", false, ascendingOrder, plugin::refresh); + playersHeader.setPreferredSize(new Dimension(PLAYERS_COLUMN_WIDTH, 0)); + + WorldTableHeader activityHeader = new WorldTableHeader("Activity", false, ascendingOrder, plugin::refresh); + + leftSide.add(worldHeader, BorderLayout.WEST); + leftSide.add(playersHeader, BorderLayout.CENTER); + + rightSide.add(activityHeader, BorderLayout.CENTER); + rightSide.add(pingHeader, BorderLayout.EAST); + + header.add(leftSide, BorderLayout.WEST); + header.add(rightSide, BorderLayout.CENTER); + + return header; + } + + private JPanel buildHeader() + { + JPanel header = new JPanel(new BorderLayout()); + JPanel leftSide = new JPanel(new BorderLayout()); + JPanel rightSide = new JPanel(new BorderLayout()); + + pingHeader = new WorldTableHeader("Ping", orderIndex == WorldOrder.PING, ascendingOrder, plugin::refresh); + pingHeader.setPreferredSize(new Dimension(PING_COLUMN_WIDTH, 0)); + pingHeader.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + if (SwingUtilities.isRightMouseButton(mouseEvent)) + { + return; + } + ascendingOrder = orderIndex != WorldOrder.PING || !ascendingOrder; + orderBy(WorldOrder.PING); + } + }); + + worldHeader = new WorldTableHeader("World", orderIndex == WorldOrder.WORLD, ascendingOrder, plugin::refresh); + worldHeader.setPreferredSize(new Dimension(WORLD_COLUMN_WIDTH, 0)); + worldHeader.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + if (SwingUtilities.isRightMouseButton(mouseEvent)) + { + return; + } + ascendingOrder = orderIndex != WorldOrder.WORLD || !ascendingOrder; + orderBy(WorldOrder.WORLD); + } + }); + + playersHeader = new WorldTableHeader("#", orderIndex == WorldOrder.PLAYERS, ascendingOrder, plugin::refresh); + playersHeader.setPreferredSize(new Dimension(PLAYERS_COLUMN_WIDTH, 0)); + playersHeader.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + if (SwingUtilities.isRightMouseButton(mouseEvent)) + { + return; + } + ascendingOrder = orderIndex != WorldOrder.PLAYERS || !ascendingOrder; + orderBy(WorldOrder.PLAYERS); + } + }); + + activityHeader = new WorldTableHeader("Activity", orderIndex == WorldOrder.ACTIVITY, ascendingOrder, plugin::refresh); + activityHeader.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + if (SwingUtilities.isRightMouseButton(mouseEvent)) + { + return; + } + ascendingOrder = orderIndex != WorldOrder.ACTIVITY || !ascendingOrder; + orderBy(WorldOrder.ACTIVITY); + } + }); + + leftSide.add(worldHeader, BorderLayout.WEST); + leftSide.add(playersHeader, BorderLayout.CENTER); + + rightSide.add(activityHeader, BorderLayout.CENTER); + rightSide.add(pingHeader, BorderLayout.EAST); + + header.add(leftSide, BorderLayout.WEST); + header.add(rightSide, BorderLayout.CENTER); + + return header; + } + + /** + * Builds a table row, that displays the world's information. + */ + private WorldTableRow buildRow(World world, boolean stripe, boolean current, boolean favorite) + { + WorldTableRow row = new WorldTableRow(world, current, favorite, + world1 -> + { + plugin.hopTo(world1); + }, + (world12, add) -> + { + if (add) + { + plugin.addToFavorites(world12); + } + else + { + plugin.removeFromFavorites(world12); + } + + updateList(); + } + ); + row.setBackground(stripe ? ODD_ROW : ColorScheme.DARK_GRAY_COLOR); + return row; + } + + /** + * Enumerates the multiple ordering options for the world list. + */ + private enum WorldOrder + { + WORLD, + PLAYERS, + ACTIVITY, + PING + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java index 2d7ef01406..2b62fa4d88 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java @@ -31,12 +31,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import javax.annotation.Nonnull; -import javax.swing.BorderFactory; -import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; +import javax.swing.*; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import net.runelite.client.ui.ColorScheme; @@ -121,7 +116,7 @@ class WorldTableHeader extends JPanel add(textLabel, BorderLayout.WEST); add(arrowLabel, BorderLayout.EAST); - } +} /** * The labels inherit the parent's mouse listeners. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java index c23face9ba..a497da60e7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java @@ -96,6 +96,7 @@ class WorldTableRow extends JPanel this.world = world; this.onFavorite = onFavorite; this.updatedPlayerCount = world.getPlayers(); + this. setLayout(new BorderLayout()); setBorder(new EmptyBorder(2, 0, 2, 0)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java index afd2bba6a4..77157bb490 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java @@ -46,10 +46,8 @@ enum QuestStartLocation THE_RESTLESS_GHOST("The Restless Ghost", new WorldPoint(3240, 3210, 0)), RUNE_MYSTERIES("Rune Mysteries", new WorldPoint(3210, 3220, 0)), SHEEP_SHEARER("Sheep Shearer", new WorldPoint(3190, 3272, 0)), - SHIELD_OF_ARRAV_PHOENIX_GANG("Shield of Arrav (Phoenix Gang)", new WorldPoint(3208, 3495, 0)), SHIELD_OF_ARRAV_BLACK_ARM_GANG("Shield of Arrav (Black Arm Gang)", new WorldPoint(3208, 3392, 0)), - VAMPIRE_SLAYER("Vampire Slayer", new WorldPoint(3096, 3266, 0)), WITCHS_POTION("Witch's Potion", new WorldPoint(2967, 3203, 0)), X_MARKS_THE_SPOT("X Marks the Spot", new WorldPoint(3227, 3242, 0)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java index 8fa2ee2481..ee7cee5f4a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java @@ -26,9 +26,10 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( - name = "!Theatre of Blood", + name = "Theatre of Blood", description = "All-in-one plugin for Theatre of Blood", tags = {"ToB"}, + type = "PVM", enabledByDefault = false ) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java index 10c9f89e74..4fdbe3fa25 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java @@ -21,9 +21,10 @@ import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ImageUtil; @PluginDescriptor( - name = "!Zulrah", + name = "Zulrah", description = "Zulrah Helper", - tags = {"Zulrah", "Helper"} + tags = {"Zulrah", "Helper"}, + type = "PVM" ) public class ZulrahPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/util/PvPUtil.java b/runelite-client/src/main/java/net/runelite/client/util/PvPUtil.java new file mode 100644 index 0000000000..3a842c227f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/util/PvPUtil.java @@ -0,0 +1,61 @@ +package net.runelite.client.util; + +import net.runelite.api.ItemComposition; +import java.util.TreeMap; +import java.util.Comparator; +import org.apache.commons.lang3.ArrayUtils; +import java.util.Objects; +import net.runelite.api.ItemContainer; +import net.runelite.api.Item; +import net.runelite.api.InventoryID; +import net.runelite.client.game.ItemManager; +import net.runelite.api.Player; +import net.runelite.api.Client; +import net.runelite.api.coords.WorldPoint; + +public class PvPUtil +{ + public PvPUtil() { + super(); + } + + public static int getWildernessLevelFrom(final WorldPoint point) { + final int x = point.getX(); + final int y = point.getY(); + final int underLevel = (y - 9920) / 8 + 1; + final int upperLevel = (y - 3520) / 8 + 1; + return (y > 6400) ? underLevel : upperLevel; + } + + public static boolean isAttackable(final Client c, final Player p) { + return Math.abs(c.getLocalPlayer().getCombatLevel() - p.getCombatLevel()) < getWildernessLevelFrom(c.getLocalPlayer().getWorldLocation()); + } + + public static int calculateRisk(final Client client, final ItemManager itemManager) { + if (client.getItemContainer(InventoryID.EQUIPMENT) == null) { + return 0; + } + if (client.getItemContainer(InventoryID.INVENTORY).getItems() == null) { + return 0; + } + final Item[] items = (Item[])ArrayUtils.addAll(((ItemContainer)Objects.requireNonNull(client.getItemContainer(InventoryID.EQUIPMENT))).getItems(), ((ItemContainer)Objects.requireNonNull(client.getItemContainer(InventoryID.INVENTORY))).getItems()); + final TreeMap priceMap = new TreeMap(Comparator.comparingInt(Integer::intValue)); + int wealth = 0; + for (final Item i : items) { + int value = itemManager.getItemPrice(i.getId()) * i.getQuantity(); + final ItemComposition itemComposition = itemManager.getItemComposition(i.getId()); + if (!itemComposition.isTradeable() && value == 0) { + value = itemComposition.getPrice() * i.getQuantity(); + priceMap.put(Integer.valueOf(value), i); + } + else { + value = itemManager.getItemPrice(i.getId()) * i.getQuantity(); + if (i.getId() > 0 && value > 0) { + priceMap.put(Integer.valueOf(value), i); + } + } + wealth += value; + } + return Integer.parseInt(StackFormatter.quantityToRSDecimalStack(priceMap.keySet().stream().mapToInt(Integer::intValue).sum())); + } +} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/pvptools/skull.png b/runelite-client/src/main/resources/net/runelite/client/plugins/pvptools/skull.png new file mode 100644 index 0000000000..09869ea0e1 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/pvptools/skull.png differ diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java index 7c2d19323f..714b1dcd17 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java @@ -135,9 +135,9 @@ public abstract class RSActorMixin implements RSActor public WorldPoint getWorldLocation() { return WorldPoint.fromLocal(client, - this.getPathX()[0] * Perspective.LOCAL_TILE_SIZE + Perspective.LOCAL_TILE_SIZE / 2, - this.getPathY()[0] * Perspective.LOCAL_TILE_SIZE + Perspective.LOCAL_TILE_SIZE / 2, - client.getPlane()); + this.getPathX()[0] * Perspective.LOCAL_TILE_SIZE + Perspective.LOCAL_TILE_SIZE / 2, + this.getPathY()[0] * Perspective.LOCAL_TILE_SIZE + Perspective.LOCAL_TILE_SIZE / 2, + client.getPlane()); } @Inject