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 360f1a556c..b532865c86 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 @@ -547,6 +547,7 @@ public class WidgetID static final int SPELL_ICON = 27; static final int SPELL_TEXT = 28; static final int AUTO_RETALIATE = 29; + static final int SPECIAL_ATTACK_BAR = 34; } static class VolcanicMine 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 9872efeb23..16b2002bc2 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 @@ -319,6 +319,7 @@ public enum WidgetInfo COMBAT_SPELL_ICON(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPELL_ICON), COMBAT_SPELL_TEXT(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPELL_TEXT), COMBAT_AUTO_RETALIATE(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.AUTO_RETALIATE), + COMBAT_SPECIAL_ATTACK(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPECIAL_ATTACK_BAR), DIALOG_OPTION(WidgetID.DIALOG_OPTION_GROUP_ID, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/DuelingRingMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/DuelingRingMode.java new file mode 100644 index 0000000000..0e06ddd4da --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/DuelingRingMode.java @@ -0,0 +1,18 @@ +package net.runelite.client.plugins.easyscape; + +public enum DuelingRingMode { + DUEL_ARENA("Duel Arena"), + CASTLE_WARS("Castle Wars"), + CLAN_WARS("Clan Wars"); + + private final String name; + + DuelingRingMode(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/EasyscapePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/EasyscapePlugin.java new file mode 100644 index 0000000000..27e56ba62f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/EasyscapePlugin.java @@ -0,0 +1,368 @@ +package net.runelite.client.plugins.easyscape; + +import com.google.inject.Provides; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; +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.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginManager; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.util.Text; +import org.apache.commons.lang3.ArrayUtils; + +import javax.inject.Inject; + +import java.util.*; + +import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; +import static net.runelite.api.MenuAction.WALK; + + +@PluginDescriptor( + name = "!Easyscape", + description = "Easyscape.", + tags = {"Easyscape"}, + enabledByDefault = false, + type = PluginType.UTILITY +) + +@Slf4j +public class EasyscapePlugin extends Plugin { + + private static final int PURO_PURO_REGION_ID = 10307; + private static final int HOUSE_REGION_ID = 7513; + + private Set swapping; + private MenuEntry[] entries; + + @Inject + private Client client; + + @Inject + private EasyscapePluginConfig config; + + @Provides + EasyscapePluginConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(EasyscapePluginConfig.class); + } + + @Override + public void startUp() { + log.debug("Easyscape Started."); + swapping = new HashSet<>(); + } + + @Override + public void shutDown() { + log.debug("Easyscape Stopped."); + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) { + + if (client.getGameState() != GameState.LOGGED_IN) { + return; + } + + Widget loginScreenOne = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN); + Widget loginScreenTwo = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY); + + if (loginScreenOne != null || loginScreenTwo != null) { + return; + } + + final String option = Text.removeTags(event.getOption()).toLowerCase(); + final String target = Text.removeTags(event.getTarget()).toLowerCase(); + + entries = client.getMenuEntries(); + + if (config.getRemoveExamine()) { + for (int i = entries.length - 1; i >= 0; i--) { + if (entries[i].getOption().equals("Examine")) { + entries = ArrayUtils.remove(entries, i); + i--; + } + } + client.setMenuEntries(entries); + } + + if (config.getRemoveObjects() && !config.getRemovedObjects().equals("")) { + for (String removed : config.getRemovedObjects().split(",")) { + removed = removed.trim(); + if (target.contains("->")) { + String trimmed = target.split("->")[1].trim(); + if (trimmed.length() >= removed.length() && trimmed.substring(0, removed.length()).equalsIgnoreCase(removed)) { + delete(event.getIdentifier()); + break; + } + } + if (target.length() >= removed.length() && target.substring(0, removed.length()).equalsIgnoreCase(removed)) { + delete(event.getIdentifier()); + break; + } + } + } + + if (config.getSwapPuro() && isPuroPuro()) { + if (event.getType() == WALK.getId()) { + MenuEntry menuEntry = entries[entries.length - 1]; + menuEntry.setType(MenuAction.WALK.getId() + MENU_ACTION_DEPRIORITIZE_OFFSET); + client.setMenuEntries(entries); + } + else if (option.equalsIgnoreCase("examine")) { + swap("push-through", option, target); + } + else if (option.equalsIgnoreCase("use")) { + swap("escape", option, target); + } + } + + if (config.getEasyConstruction() && !config.getConstructionItems().equals("")) { + if (event.getType() == WALK.getId()) { + MenuEntry menuEntry = entries[entries.length - 1]; + menuEntry.setType(MenuAction.WALK.getId() + MENU_ACTION_DEPRIORITIZE_OFFSET); + client.setMenuEntries(entries); + } + + swap("Build", option, target); + + for (int i = entries.length - 1; i >= 0; i--) { + for (String item : config.getConstructionItems().split(",")) { + if (item.trim().equalsIgnoreCase(Text.removeTags(entries[i].getTarget()))) { + if (!entries[i].getOption().equalsIgnoreCase("remove")) { + entries = ArrayUtils.remove(entries, i); + i--; + } + } + } + } + + client.setMenuEntries(entries); + } + + if (config.getSwapShop() && !config.getSwappedItems().equals("")) { + for (String item : config.getSwappedItems().split(",")) { + if (target.equalsIgnoreCase(item.trim())) { + swap("Buy 50", option, target); + } + } + } + + if (config.getSwapSmithing()) { + if (option.equalsIgnoreCase("Smith 1")) { + swap("Smith All", option, target); + } else if (option.equalsIgnoreCase("Smith 1 Set")) { + swap("Smith All Sets", option, target); + } + } + + if (config.getSwapTanning() && option.equalsIgnoreCase("Tan 1")) { + swap("Tan All", option, target); + } + + if (config.getSwapCrafting() && option.equalsIgnoreCase("Make-1")) { + swap("Make-All", option, target); + } + + if (config.getSwapSawmill() && target.equalsIgnoreCase("Sawmill operator")) { + swap("Buy-plank", option, target); + } + + if (config.getSwapSawmillPlanks() && option.equalsIgnoreCase("Buy 1")) { + swap("Buy All", option, target); + } + + if (config.getSwapStairs() && option.equalsIgnoreCase("Climb Stairs")) { + swap("Climb Up Stairs", option, target); + } + + if (option.equalsIgnoreCase("Clear-All") && target.equalsIgnoreCase("Bank Filler")) { + swap("Clear", option, target); + } + + if (target.toLowerCase().contains("ardougne cloak") && config.getSwapArdougneCape()) { + swap("Kandarin Monastery", option, target); + swap("Monastery Teleport", option, target); + } + + if (config.getSwapEssencePouch()) { + if (isEssencePouch(target)) { + Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR); + switch (config.getEssenceMode()) { + case RUNECRAFTING: + if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden()) { + swap("Empty", option, target); + } else { + swap("Fill", option, target); + } + break; + case ESSENCE_MINING: + if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden()) { + swap("Fill", option, target); + } else { + swap("Empty", option, target); + } + break; + default: + break; + } + } + } + + if (config.getGamesNecklace()) { + if (target.toLowerCase().contains("games necklace")) { + switch (config.getGamesNecklaceMode()) { + case BURTHORPE: + swap(GamesNecklaceMode.BURTHORPE.toString(), option, target); + break; + case BARBARIAN_OUTPOST: + swap(GamesNecklaceMode.BARBARIAN_OUTPOST.toString(), option, target); + break; + case CORPOREAL_BEAST: + swap(GamesNecklaceMode.CORPOREAL_BEAST.toString(), option, target); + break; + case TEARS_OF_GUTHIX: + swap(GamesNecklaceMode.TEARS_OF_GUTHIX.toString(), option, target); + break; + case WINTERTODT: + swap(GamesNecklaceMode.WINTERTODT.toString(), option, target); + break; + default: + break; + } + } + } + + if (config.getDuelingRing()) { + if (target.toLowerCase().contains("ring of dueling")) { + switch (config.getDuelingRingMode()) { + case DUEL_ARENA: + swap(DuelingRingMode.DUEL_ARENA.toString(), option, target); + break; + case CASTLE_WARS: + swap(DuelingRingMode.CASTLE_WARS.toString(), option, target); + break; + case CLAN_WARS: + swap(DuelingRingMode.CLAN_WARS.toString(), option, target); + break; + default: + break; + } + } + } + + if (config.getWealthRing()) { + if (target.toLowerCase().contains("ring of wealth")) { + switch (config.getWealthRingMode()) { + case MISCELLANIA: + swap(WealthRingMode.MISCELLANIA.toString(), option, target); + break; + case GRAND_EXCHANGE: + swap(WealthRingMode.GRAND_EXCHANGE.toString(), option, target); + break; + case FALADOR: + swap(WealthRingMode.FALADOR.toString(), option, target); + break; + case DONDAKAN: + swap(WealthRingMode.DONDAKAN.toString(), option, target); + break; + default: + break; + } + } + } + + if (config.getGlory()) { + if (target.toLowerCase().contains("amulet of glory")) { + switch (config.getGloryMode()) { + case EDGEVILLE: + swap(GloryMode.EDGEVILLE.toString(), option, target); + break; + case KARAMJA: + swap(GloryMode.KARAMJA.toString(), option, target); + break; + case DRAYNOR_VILLAGE: + swap(GloryMode.DRAYNOR_VILLAGE.toString(), option, target); + break; + case AL_KHARID: + swap(GloryMode.AL_KHARID.toString(), option, target); + break; + default: + break; + } + } + } + + startSwap(); + performSwap(); + } + + private void swap(String optionA, String optionB, String target) { + swapping.add(new Swapper(target, optionA, optionB)); + } + + private void startSwap() { + int index = 0; + for (MenuEntry entry : entries) { + String target = Text.removeTags(entry.getTarget()).toLowerCase(); + for (Swapper swap : swapping) { + if (swap.getTarget().equalsIgnoreCase(target)) { + if (entry.getOption().equalsIgnoreCase(swap.getOptionOne())) { + swap.setIndexOne(index); + } else if (entry.getOption().equalsIgnoreCase(swap.getOptionTwo())) { + swap.setIndexTwo(index); + } + } + } + index++; + } + } + + private void performSwap() { + for (Swapper swap : swapping) { + if (swap.isReady()) { + MenuEntry entry = entries[swap.getIndexOne()]; + entries[swap.getIndexOne()] = entries[swap.getIndexTwo()]; + entries[swap.getIndexTwo()] = entry; + } + } + client.setMenuEntries(entries); + swapping.clear(); + } + + private void delete(int target) { + for (int i = entries.length - 1; i >= 0; i--) { + if (entries[i].getIdentifier() == target) { + entries = ArrayUtils.remove(entries, i); + i--; + } + } + client.setMenuEntries(entries); + } + + private boolean isEssencePouch(String target) { + return (target.equalsIgnoreCase("Small Pouch") || target.equalsIgnoreCase("Medium Pouch") || target.equalsIgnoreCase("Large Pouch") || target.equalsIgnoreCase("Giant Pouch")); + } + + private boolean isHouse() { + return client.getMapRegions()[0] == HOUSE_REGION_ID; + } + + private boolean isPuroPuro() { + Player player = client.getLocalPlayer(); + + if (player == null) { + return false; + } else { + WorldPoint location = player.getWorldLocation(); + return location.getRegionID() == PURO_PURO_REGION_ID; + } + } + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/EasyscapePluginConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/EasyscapePluginConfig.java new file mode 100644 index 0000000000..ef1074a4bd --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/EasyscapePluginConfig.java @@ -0,0 +1,268 @@ +package net.runelite.client.plugins.easyscape; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("easyscape") +public interface EasyscapePluginConfig extends Config { + + @ConfigItem( + keyName = "removeExamine", + name = "Remove Examine", + description = "", + position = 0 + ) + default boolean getRemoveExamine() { + return true; + } + + @ConfigItem( + keyName = "swapShop", + name = "Easy Shop", + description = "Enables swapping of items in the shop with their buy-50 option.", + position = 1 + ) + default boolean getSwapShop() { + return true; + } + + @ConfigItem( + keyName = "swappedItems", + name = "Shop Items", + description = "Items listed here will have their value and buy-50 options swapped.", + position = 2 + ) + default String getSwappedItems() { + return ""; + } + + @ConfigItem( + keyName = "easyConstruction", + name = "Easy Construction", + description = "", + position = 3 + ) + + default boolean getEasyConstruction() { + return true; + } + + @ConfigItem( + keyName = "constructionItems", + name = "Construction Items", + description = "", + position = 4 + ) + + default String getConstructionItems() { + return ""; + } + + @ConfigItem( + keyName = "removeObjects", + name = "Remove Objects", + description = "", + position = 5 + ) + default boolean getRemoveObjects() { + return true; + } + + @ConfigItem( + keyName = "removedObjects", + name = "Removed Objects", + description = "", + position = 6 + ) + default String getRemovedObjects() { + return ""; + } + + @ConfigItem( + keyName = "swapSmithing", + name = "Swap Smithing", + description = "Enables swapping of smith-1 and smith-all options.", + position = 7 + ) + default boolean getSwapSmithing() { + return true; + } + + @ConfigItem( + keyName = "swapTanning", + name = "Swap Tanning", + description = "Enables swapping of tan-1 and tan-all options.", + position = 8 + ) + default boolean getSwapTanning() { + return true; + } + + @ConfigItem( + keyName = "swapCrafting", + name = "Swap Crafting", + description = "", + position = 9 + ) + default boolean getSwapCrafting() { + return true; + } + + @ConfigItem( + keyName = "swapArdougneCape", + name = "Swap Ardougne Cape", + description = "Enables swapping of teleport and wear.", + position = 10 + ) + default boolean getSwapArdougneCape() { + return true; + } + + @ConfigItem( + keyName = "swapStairs", + name = "Swap Stairs", + description = "", + position = 11 + ) + + default boolean getSwapStairs() { + return true; + } + + @ConfigItem( + keyName = "swapSawmill", + name = "Swap Sawmill Operator", + description = "", + position = 12 + ) + default boolean getSwapSawmill() { + return true; + } + + @ConfigItem( + keyName = "swapSawmillPlanks", + name = "Swap Buy Planks", + description = "", + position = 13 + ) + + default boolean getSwapSawmillPlanks() { + return true; + } + + @ConfigItem( + keyName = "swapPuroPuro", + name = "Swap Puro Puro Wheat", + description = "", + position = 14 + ) + default boolean getSwapPuro() { + return true; + } + + @ConfigItem( + keyName = "swapEssencePounch", + name = "Swap Essence Pouch", + description = "Enables swapping of fill and empty for essence pounch.", + position = 15 + ) + default boolean getSwapEssencePouch() { + return true; + } + + @ConfigItem( + keyName = "essenceMode", + name = "Essence Pouch Mode", + description = "Runecrafting or essence mining mode.", + position = 16 + ) + + default EssenceMode getEssenceMode() { + return EssenceMode.RUNECRAFTING; + } + + @ConfigItem( + keyName = "swapGamesNecklace", + name = "Swap Games Necklace", + description = "Enables swapping of games necklace.", + position = 17 + ) + default boolean getGamesNecklace() { + return true; + } + + @ConfigItem( + keyName = "gamesNecklaceMode", + name = "Games Necklace Mode", + description = "Teleport location mode.", + position = 18 + ) + + default GamesNecklaceMode getGamesNecklaceMode() { + return GamesNecklaceMode.BURTHORPE; + } + + @ConfigItem( + keyName = "swapDuelingRing", + name = "Swap Dueling Ring", + description = "Enables swapping of dueling ring.", + position = 19 + ) + default boolean getDuelingRing() { + return true; + } + + @ConfigItem( + keyName = "duelingRingMode", + name = "Dueling Ring Mode", + description = "Teleport location mode.", + position = 20 + ) + + default DuelingRingMode getDuelingRingMode() { + return DuelingRingMode.DUEL_ARENA; + } + + @ConfigItem( + keyName = "swapGlory", + name = "Swap Glory", + description = "Enables swapping of Amulet of Glory.", + position = 21 + ) + default boolean getGlory() { + return true; + } + + @ConfigItem( + keyName = "gloryMode", + name = "Glory Mode", + description = "Teleport location mode.", + position = 22 + ) + + default GloryMode getGloryMode() { + return GloryMode.EDGEVILLE; + } + + @ConfigItem( + keyName = "swapWealthRing", + name = "Swap Ring of Wealth", + description = "Enables swapping of Ring of Wealth.", + position = 23 + ) + default boolean getWealthRing() { + return true; + } + @ConfigItem( + keyName = "WealthRingMode", + name = "Wealth Ring Mode", + description = "Teleport location mode.", + position = 24 + ) + + default WealthRingMode getWealthRingMode() { + return WealthRingMode.GRAND_EXCHANGE; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/EssenceMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/EssenceMode.java new file mode 100644 index 0000000000..8cb09d94c3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/EssenceMode.java @@ -0,0 +1,17 @@ +package net.runelite.client.plugins.easyscape; + +public enum EssenceMode { + RUNECRAFTING("Runecrafting"), + ESSENCE_MINING("Essence Mining"); + + private final String name; + + EssenceMode(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/GamesNecklaceMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/GamesNecklaceMode.java new file mode 100644 index 0000000000..ca52de44f8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/GamesNecklaceMode.java @@ -0,0 +1,20 @@ +package net.runelite.client.plugins.easyscape; + +public enum GamesNecklaceMode { + BURTHORPE("Burthorpe"), + BARBARIAN_OUTPOST("Barbarian Outpost"), + CORPOREAL_BEAST("Corporeal Beast"), + TEARS_OF_GUTHIX("Tears of Guthix"), + WINTERTODT("Wintertodt Camp"); + + private final String name; + + GamesNecklaceMode(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/GloryMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/GloryMode.java new file mode 100644 index 0000000000..4926c9d829 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/GloryMode.java @@ -0,0 +1,19 @@ +package net.runelite.client.plugins.easyscape; + +public enum GloryMode { + EDGEVILLE("Edgeville"), + KARAMJA("Karamja"), + DRAYNOR_VILLAGE("Draynor Village"), + AL_KHARID("Al Kharid"); + + private final String name; + + GloryMode(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/Swapper.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/Swapper.java new file mode 100644 index 0000000000..6ddd92d33d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/Swapper.java @@ -0,0 +1,36 @@ +package net.runelite.client.plugins.easyscape; + +import lombok.Getter; +import lombok.Setter; + +public class Swapper { + + @Getter + private String target; + + @Getter + private String optionOne; + + @Getter + private String optionTwo; + + @Getter + @Setter + private int indexOne; + + @Getter + @Setter + private int indexTwo; + + public Swapper(String target, String optionOne, String optionTwo) { + this.target = target; + this.optionOne = optionOne; + this.optionTwo = optionTwo; + this.indexOne = -1; + this.indexTwo = -1; + } + + public boolean isReady() { + return this.indexOne != -1 && this.indexTwo != -1; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/WealthRingMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/WealthRingMode.java new file mode 100644 index 0000000000..d20e454f06 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/WealthRingMode.java @@ -0,0 +1,19 @@ +package net.runelite.client.plugins.easyscape; + +public enum WealthRingMode { + MISCELLANIA ("Miscellania"), + GRAND_EXCHANGE ("Grand Exchange"), + FALADOR ("Falador"), + DONDAKAN ("Dondakan"); + + private final String name; + + WealthRingMode(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specbar/SpecBarPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specbar/SpecBarPlugin.java new file mode 100644 index 0000000000..7630f0292a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specbar/SpecBarPlugin.java @@ -0,0 +1,75 @@ +package net.runelite.client.plugins.specbar; + +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.WidgetHiddenChanged; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginManager; +import net.runelite.client.plugins.PluginType; + +@PluginDescriptor( + name = "Spec Bar", + description = "Adds a spec bar to every weapon", + tags = {"spec bar", "special attack", "spec", "bar", "pklite"}, + enabledByDefault = false, + type = PluginType.PVP +) +public class SpecBarPlugin extends Plugin +{ + + @Inject + private Client client; + + @Override + protected void startUp() throws Exception + { + } + + @Override + protected void shutDown() throws Exception + { + } + + @Subscribe + private void onWidgetHiddenChanged(WidgetHiddenChanged event) + { + if (WidgetInfo.TO_GROUP(event.getWidget().getId()) == WidgetID.COMBAT_GROUP_ID) + { + hideSpecBar(); + } + } + + @Subscribe + private void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState().equals(GameState.LOGGING_IN)) + { + hideSpecBar(); + } + + } + + /** + * Displays the special attack bar + */ + private void hideSpecBar() + { + try + { + Widget specBar = client.getWidget(WidgetInfo.COMBAT_SPECIAL_ATTACK); + specBar.setHidden(false); + specBar.revalidate(); + } + catch (NullPointerException e) + { + // Stops the nulls that occur before the spec bar is loaded by player equipping a spec wep + } + } +}