From e3138db499273f0565a6f763be0d74f59129b868 Mon Sep 17 00:00:00 2001 From: Ron Young Date: Wed, 17 Apr 2019 09:08:33 -0500 Subject: [PATCH 01/75] skybox: calculate brightness increase in HSB format --- .../java/net/runelite/client/plugins/skybox/Skybox.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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]); } /** From d7e0e11e73f090fa5d8fd837d6ea3244f60c88ef Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Fri, 19 Apr 2019 13:51:40 +0100 Subject: [PATCH 02/75] mixins: renderWidgetLayer: skip hidden widgets --- .../src/main/java/net/runelite/mixins/RSClientMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 56b9190ead..11ae361a9b 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1335,7 +1335,7 @@ public abstract class RSClientMixin implements RSClient for (Widget rlWidget : widgets) { RSWidget widget = (RSWidget) rlWidget; - if (widget == null || widget.getRSParentId() != parentId) + if (widget == null || widget.getRSParentId() != parentId || widget.isSelfHidden()) { continue; } From a45ab3c88744a9ff28067f3a32d871af5cd5cade Mon Sep 17 00:00:00 2001 From: xDemoN Date: Fri, 19 Apr 2019 12:19:36 -0400 Subject: [PATCH 03/75] World Map: Identify Both Shield of Arrav Quest Start Points (#8442) Closes #8437 --- .../runelite/client/plugins/worldmap/QuestStartLocation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 c1d9e9fb88..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,7 +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("Shield of Arrav", new WorldPoint(3208, 3495, 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)), From 8bfc0f2b211191f9c0ca812369fd76df34fee424 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 19 Apr 2019 14:27:49 -0400 Subject: [PATCH 04/75] widgetitem: associate Widget with WidgetItem --- .../net/runelite/api/widgets/WidgetItem.java | 48 ++++++------------- .../net/runelite/mixins/RSClientMixin.java | 2 +- .../net/runelite/mixins/RSWidgetMixin.java | 2 +- 3 files changed, 16 insertions(+), 36 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetItem.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetItem.java index 51f63ad40f..c39e961f81 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetItem.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetItem.java @@ -26,6 +26,7 @@ package net.runelite.api.widgets; import java.awt.Rectangle; import lombok.AllArgsConstructor; +import lombok.Getter; import lombok.ToString; import net.runelite.api.Point; @@ -34,55 +35,34 @@ import net.runelite.api.Point; */ @AllArgsConstructor @ToString +@Getter public class WidgetItem { - private final int id; - private final int quantity; - private final int index; - private final Rectangle canvasBounds; - /** - * Gets the ID of the item represented. + * The ID of the item represented. * - * @return the items ID * @see net.runelite.api.ItemID */ - public int getId() - { - return id; - } - + private final int id; /** - * Gets the quantity of the represented item. - * - * @return the items quantity + * The quantity of the represented item. */ - public int getQuantity() - { - return quantity; - } - + private final int quantity; /** - * Gets the index position of this WidgetItem inside its parents + * The index position of this WidgetItem inside its parents * WidgetItem array. * - * @return the index in the parent widget * @see Widget#getWidgetItems() */ - public int getIndex() - { - return index; - } - + private final int index; /** - * Gets the area where the widget is drawn on the canvas. - * - * @return the occupied area of the widget + * The area where the widget is drawn on the canvas. */ - public Rectangle getCanvasBounds() - { - return canvasBounds; - } + private final Rectangle canvasBounds; + /** + * The widget which contains this item. + */ + private final Widget widget; /** * Gets the upper-left coordinate of where the widget is being drawn diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 11ae361a9b..7c934a265d 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1355,7 +1355,7 @@ public abstract class RSClientMixin implements RSClient { if (renderX >= minX && renderX <= maxX && renderY >= minY && renderY <= maxY) { - WidgetItem widgetItem = new WidgetItem(widget.getItemId(), widget.getItemQuantity(), -1, widget.getBounds()); + WidgetItem widgetItem = new WidgetItem(widget.getItemId(), widget.getItemQuantity(), -1, widget.getBounds(), widget); callbacks.drawItem(widget.getItemId(), widgetItem); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java index 4130ce5930..1b4bda7fc6 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java @@ -300,7 +300,7 @@ public abstract class RSWidgetMixin implements RSWidget int itemY = widgetCanvasLocation.getY() + ((ITEM_SLOT_SIZE + yPitch) * row); Rectangle bounds = new Rectangle(itemX - 1, itemY - 1, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE); - return new WidgetItem(itemId - 1, itemQuantity, index, bounds); + return new WidgetItem(itemId - 1, itemQuantity, index, bounds, this); } @Inject From 3f13d4c620dd15f577d3a0c970e10566aae5d19d Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 19 Apr 2019 14:28:32 -0400 Subject: [PATCH 05/75] widgetitem overlay: allow configuring which interfaces to overlay Update overlays to behave consistent with how they behaved before removal of query api, with the exception of adding the rune pouch overlay to the bank. --- .../inventorytags/InventoryTagsOverlay.java | 2 + .../itemcharges/ItemChargeOverlay.java | 2 + .../plugins/runepouch/RunepouchOverlay.java | 2 + .../client/plugins/slayer/SlayerOverlay.java | 2 + .../client/ui/overlay/WidgetItemOverlay.java | 58 ++++++++++++++++++- 5 files changed, 64 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java index 99798156ad..14fe723a71 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java @@ -43,6 +43,8 @@ public class InventoryTagsOverlay extends WidgetItemOverlay { this.itemManager = itemManager; this.plugin = plugin; + showOnEquipment(); + showOnInventory(); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java index a37570aa22..5082ab2ccd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java @@ -51,6 +51,8 @@ class ItemChargeOverlay extends WidgetItemOverlay { this.itemChargePlugin = itemChargePlugin; this.config = config; + showOnInventory(); + showOnEquipment(); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java index 17486efe0d..a7e2fd86d7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java @@ -69,6 +69,8 @@ public class RunepouchOverlay extends WidgetItemOverlay this.tooltipManager = tooltipManager; this.client = client; this.config = config; + showOnInventory(); + showOnBank(); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java index e8c49b20a0..97a191d608 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java @@ -87,6 +87,8 @@ class SlayerOverlay extends WidgetItemOverlay { this.plugin = plugin; this.config = config; + showOnInventory(); + showOnEquipment(); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java index 0eaae6e50b..9cf6f39217 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java @@ -26,15 +26,33 @@ package net.runelite.client.ui.overlay; import java.awt.Dimension; import java.awt.Graphics2D; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import lombok.AccessLevel; import lombok.Setter; +import net.runelite.api.widgets.Widget; +import static net.runelite.api.widgets.WidgetID.BANK_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.BANK_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.DEPOSIT_BOX_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.EQUIPMENT_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.EQUIPMENT_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.GUIDE_PRICES_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.SHOP_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetInfo.TO_GROUP; import net.runelite.api.widgets.WidgetItem; public abstract class WidgetItemOverlay extends Overlay { @Setter(AccessLevel.PACKAGE) private OverlayManager overlayManager; + /** + * Interfaces to draw overlay over. + */ + private final Set interfaceGroups = new HashSet<>(); protected WidgetItemOverlay() { @@ -49,13 +67,49 @@ public abstract class WidgetItemOverlay extends Overlay public Dimension render(Graphics2D graphics) { final List itemWidgets = overlayManager.getItemWidgets(); - for (WidgetItem widget : itemWidgets) + for (WidgetItem widgetItem : itemWidgets) { - renderItemOverlay(graphics, widget.getId(), widget); + Widget widget = widgetItem.getWidget(); + int interfaceGroup = TO_GROUP(widget.getId()); + + // Don't draw if this widget isn't one of the allowed + if (!interfaceGroups.contains(interfaceGroup)) + { + continue; + } + + renderItemOverlay(graphics, widgetItem.getId(), widgetItem); } return null; } + protected void showOnInventory() + { + showOnInterfaces( + DEPOSIT_BOX_GROUP_ID, + BANK_INVENTORY_GROUP_ID, + SHOP_INVENTORY_GROUP_ID, + GRAND_EXCHANGE_INVENTORY_GROUP_ID, + GUIDE_PRICES_INVENTORY_GROUP_ID, + EQUIPMENT_INVENTORY_GROUP_ID, + INVENTORY_GROUP_ID); + } + + protected void showOnBank() + { + showOnInterfaces(BANK_GROUP_ID); + } + + protected void showOnEquipment() + { + showOnInterfaces(EQUIPMENT_GROUP_ID); + } + + protected void showOnInterfaces(int... ids) + { + Arrays.stream(ids).forEach(interfaceGroups::add); + } + // Don't allow setting position, priority, or layer @Override From 7a49aa154023115e5dddc778d8c31725de078fc0 Mon Sep 17 00:00:00 2001 From: zeruth Date: Fri, 19 Apr 2019 18:58:04 -0400 Subject: [PATCH 06/75] Revert "Plugins update (#7)" This reverts commit 216f7d94d15d96eb575d214c6e56714ad06af5b0. --- .../src/main/java/net/runelite/api/Actor.java | 6 - .../java/net/runelite/api/AnimationID.java | 45 +- .../java/net/runelite/api/ClanMemberRank.java | 25 +- .../java/net/runelite/api/InventoryID.java | 4 - .../java/net/runelite/api/ProjectileID.java | 8 +- .../main/java/net/runelite/api/SpriteID.java | 5 +- .../java/net/runelite/api/VarClientInt.java | 6 - .../main/java/net/runelite/api/Varbits.java | 116 +- .../runelite/api/events/CannonballFired.java | 32 - .../java/net/runelite/api/kit/KitType.java | 1 - .../runelite/api/queries/BankItemQuery.java | 78 - .../api/queries/EquipmentItemQuery.java | 102 - .../api/queries/InventoryWidgetItemQuery.java | 95 - .../runelite/api/queries/ShopItemQuery.java | 71 - .../runelite/api/queries/WidgetItemQuery.java | 74 - .../net/runelite/api/widgets/WidgetID.java | 142 +- .../net/runelite/api/widgets/WidgetInfo.java | 68 +- .../plugins/antidrag/AntiDragConfig.java | 50 - .../plugins/antidrag/AntiDragOverlay.java | 47 - .../plugins/antidrag/AntiDragPlugin.java | 63 +- .../plugins/aoewarnings/AoeProjectile.java | 58 - .../aoewarnings/AoeProjectileInfo.java | 128 - .../plugins/aoewarnings/AoeWarningConfig.java | 213 - .../aoewarnings/AoeWarningOverlay.java | 166 - .../plugins/aoewarnings/AoeWarningPlugin.java | 307 -- .../plugins/aoewarnings/BombOverlay.java | 178 - .../plugins/aoewarnings/CrystalBomb.java | 64 - .../BarbarianAssaultConfig.java | 46 +- .../BarbarianAssaultOverlay.java | 98 +- .../BarbarianAssaultPlugin.java | 257 +- .../client/plugins/batools/BAToolsConfig.java | 124 - .../plugins/batools/BAToolsOverlay.java | 126 - .../client/plugins/batools/BAToolsPlugin.java | 643 --- .../client/plugins/batools/Calls.java | 84 - .../client/plugins/batools/CycleCounter.java | 14 - .../client/plugins/batools/Healer.java | 84 - .../client/plugins/batools/HealerCode.java | 34 - .../client/plugins/cannon/CannonConfig.java | 20 - .../client/plugins/cannon/CannonPlugin.java | 15 +- .../plugins/clanchat/ClanChatConfig.java | 33 - .../plugins/clanchat/ClanChatPlugin.java | 100 +- .../clanchat/discord/DiscordClient.java | 63 - .../clanchat/discord/DiscordMessage.java | 12 - .../clanmanmode/ClanManModeConfig.java | 168 - .../ClanManModeMinimapOverlay.java | 52 - .../clanmanmode/ClanManModeOverlay.java | 63 - .../clanmanmode/ClanManModePlugin.java | 137 - .../clanmanmode/ClanManModeService.java | 157 - .../clanmanmode/ClanManModeTileOverlay.java | 48 - .../client/plugins/config/ConfigPanel.java | 3 +- .../client/plugins/config/PluginListItem.java | 2 - .../client/plugins/cox/CoxConfig.java | 83 - .../client/plugins/cox/CoxOverlay.java | 79 - .../client/plugins/cox/CoxOverlayAbove.java | 124 - .../client/plugins/cox/CoxPlugin.java | 129 - .../easyscape/bank/EasyBankConfig.java | 133 - .../easyscape/bank/EasyBankPlugin.java | 133 - .../plugins/easyscape/pvp/EasyPvpConfig.java | 56 - .../plugins/easyscape/pvp/EasyPvpOverlay.java | 102 - .../plugins/easyscape/pvp/EasyPvpPlugin.java | 197 - .../easyscape/scape/EasyScapeConfig.java | 43 - .../easyscape/scape/EasyScapePlugin.java | 111 - .../easyscape/shop/EasyShopConfig.java | 186 - .../easyscape/shop/EasyShopPlugin.java | 140 - .../easyscape/swap/EasySwapConfig.java | 201 - .../easyscape/swap/EasySwapPlugin.java | 236 -- .../easyscape/util/DuelingRingMode.java | 18 - .../plugins/easyscape/util/EssenceMode.java | 17 - .../easyscape/util/GamesNecklaceMode.java | 20 - .../plugins/easyscape/util/GloryMode.java | 19 - .../plugins/easyscape/util/Markable.java | 28 - .../plugins/easyscape/util/Swappable.java | 38 - .../plugins/easyscape/util/Swapper.java | 67 - .../easyscape/zulrah/EasyZulrahConfig.java | 4 - .../easyscape/zulrah/EasyZulrahPlugin.java | 4 - .../EquipmentInspectorConfig.java | 65 - .../EquipmentInspectorPanel.java | 98 - .../EquipmentInspectorPlugin.java | 240 -- .../plugins/equipmentinspector/ItemPanel.java | 52 - .../plugins/equipmentinspector/normal.png | Bin 624 -> 0 bytes .../FightCaveJadHelperOverlay.java | 63 - .../FightCaveJadHelperPlugin.java | 89 - .../plugins/fightcavejadhelper/JadAttack.java | 29 - .../FightCaveWaveHelperConfig.java | 43 - .../FightCaveWaveHelperPlugin.java | 173 - .../fightcavewavehelper/WaveDisplayMode.java | 43 - .../fightcavewavehelper/WaveMonster.java | 47 - .../fightcavewavehelper/WaveOverlay.java | 125 - .../client/plugins/freezetimers/Barrage.java | 43 - .../freezetimers/FreezeTimersConfig.java | 51 - .../freezetimers/FreezeTimersOverlay.java | 157 - .../freezetimers/FreezeTimersPlugin.java | 402 -- .../freezetimers/FreezeTimersService.java | 81 - .../freezetimers/FreezeTimersTileOverlay.java | 46 - .../freezetimers/PlayerSpellEffect.java | 35 - .../client/plugins/freezetimers/Spell.java | 34 - .../friendtagging/FriendTaggingPlugin.java | 162 - .../GrotesqueGuardiansOverlay.java | 100 - .../GrotesqueGuardiansPlugin.java | 56 - .../hideprayers/HidePrayersConfig.java | 35 - .../hideprayers/HidePrayersPlugin.java | 169 - .../plugins/hideprayers/PrayerTabState.java | 8 - .../client/plugins/hydra/HydraConfig.java | 41 - .../plugins/hydra/HydraIndicatorOverlay.java | 52 - .../client/plugins/hydra/HydraOverlay.java | 76 - .../client/plugins/hydra/HydraPlugin.java | 145 - .../plugins/hydra/HydraPrayOverlay.java | 100 - .../inventorysetups/InventorySetup.java | 15 - .../InventorySetupBankOverlay.java | 113 - .../inventorysetups/InventorySetupConfig.java | 84 - .../inventorysetups/InventorySetupItem.java | 15 - .../inventorysetups/InventorySetupPlugin.java | 402 -- .../ui/InventorySetupContainerPanel.java | 109 - .../ui/InventorySetupEquipmentPanel.java | 91 - .../ui/InventorySetupInventoryPanel.java | 78 - .../ui/InventorySetupPluginPanel.java | 287 -- .../ui/InventorySetupSlot.java | 45 - .../InventoryViewerConfig.java | 19 - .../InventoryViewerOverlay.java | 13 +- .../InventoryViewerPlugin.java | 8 - .../kittennotifier/KittenNotifierConfig.java | 27 - .../kittennotifier/KittenNotifierPlugin.java | 84 - .../LizardmenShamanConfig.java | 32 - .../LizardmenShamanPlugin.java | 91 - .../lizardmenshaman/LizardmenShamanSpawn.java | 18 - .../lizardmenshaman/ShamanSpawnOverlay.java | 90 - .../LootingBagViewerOverlay.java | 123 - .../LootingBagViewerPlugin.java | 59 - .../MenuEntrySwapperConfig.java | 592 ++- .../MenuEntrySwapperPlugin.java | 44 +- .../menumodifier/MenuModifierConfig.java | 24 - .../MenuModifierInputListener.java | 39 - .../menumodifier/MenuModifierPlugin.java | 168 - .../client/plugins/mining/MinedRock.java | 76 - .../client/plugins/mining/MiningConfig.java | 123 - .../client/plugins/mining/MiningOverlay.java | 156 - .../client/plugins/mining/MiningPlugin.java | 361 -- .../plugins/mining/MiningRockOverlay.java | 124 - .../client/plugins/mining/MiningRockType.java | 132 - .../client/plugins/mining/MiningSession.java | 80 - .../mining/MiningSessionRockStats.java | 87 - .../client/plugins/mining/MiningWorld.java | 78 - .../mining/MiningWorldHopperOverlay.java | 122 - .../plugins/mining/MiningWorldTracker.java | 68 - .../musicmodifier/MidiFileAdjuster.java | 165 - .../musicmodifier/MusicCustomizerPlugin.java | 355 -- .../musicmodifier/RealTimeMIDIPlayer.java | 229 -- .../NextHitNotifierConfig.java | 11 - .../NextHitNotifierOverlay.java | 59 - .../NextHitNotifierPlugin.java | 116 - .../plugins/pkvision/PKVisionConfig.java | 55 - .../pkvision/PKVisionMinimapOverlay.java | 43 - .../plugins/pkvision/PKVisionOverlay.java | 55 - .../plugins/pkvision/PKVisionPlugin.java | 135 - .../plugins/pkvision/PKVisionService.java | 63 - .../plugins/pkvision/PKVisionTileOverlay.java | 44 - .../plankmakehelper/PlankMakeOverlay.java | 88 - .../plankmakehelper/PlankMakePlugin.java | 49 - .../PlayerIndicatorsConfig.java | 11 - .../PlayerIndicatorsOverlay.java | 11 +- .../PlayerIndicatorsPlugin.java | 8 +- .../prayagainstplayer/PlayerContainer.java | 56 - .../PrayAgainstPlayerConfig.java | 183 - .../PrayAgainstPlayerOverlay.java | 158 - .../PrayAgainstPlayerOverlayPrayerTab.java | 101 - .../PrayAgainstPlayerPlugin.java | 327 -- .../plugins/prayagainstplayer/WeaponType.java | 125 - .../client/plugins/profiles/ProfilePanel.java | 132 - .../plugins/profiles/ProfilesConfig.java | 36 - .../plugins/profiles/ProfilesPanel.java | 248 -- .../plugins/profiles/ProfilesPlugin.java | 135 - .../client/plugins/profiles/delete_icon.png | Bin 208 -> 0 bytes .../client/plugins/profiles/profiles_icon.png | Bin 77 -> 0 bytes .../ProtectItemReminderConfig.java | 15 - .../ProtectItemReminderOverlay.java | 49 - .../ProtectItemReminderPlugin.java | 99 - .../plugins/pyramidplunder/Obstacles.java | 40 - .../pyramidplunder/PyramidPlunderConfig.java | 66 - .../pyramidplunder/PyramidPlunderOverlay.java | 131 - .../pyramidplunder/PyramidPlunderPlugin.java | 271 -- .../pyramidplunder/PyramidPlunderTimer.java | 39 - .../client/plugins/raids/RaidsConfig.java | 158 - .../client/plugins/raids/RaidsOverlay.java | 262 +- .../client/plugins/raids/RaidsPlugin.java | 113 +- .../raidsthieving/BatSolver/BatSolver.java | 193 - .../BatSolver/ChestIdentifier.java | 261 -- .../raidsthieving/BatSolver/SolutionSet.java | 165 - .../BatSolver/ThievingRoomType.java | 61 - .../plugins/raidsthieving/ChestOverlay.java | 172 - .../plugins/raidsthieving/InstancePoint.java | 98 - .../raidsthieving/RaidsThievingConfig.java | 67 - .../raidsthieving/RaidsThievingConstants.java | 35 - .../raidsthieving/RaidsThievingPlugin.java | 270 -- .../plugins/raidsthieving/ThievingChest.java | 78 - .../rememberclan/RememberClanConfig.java | 48 - .../rememberclan/RememberClanPlugin.java | 77 - .../ShayzienInfirmaryOverlay.java | 100 - .../ShayzienInfirmaryPlugin.java | 121 - .../shiftwalker/ShiftWalkerConfig.java | 66 - .../shiftwalker/ShiftWalkerGroups.java | 32 - .../shiftwalker/ShiftWalkerInputListener.java | 61 - .../shiftwalker/ShiftWalkerPlugin.java | 208 - .../plugins/slayermusiq/QuestGuideLinks.java | 207 - .../slayermusiq/SlayermusiqPlugin.java | 152 - .../spellbookfixer/SpellbookFixerConfig.java | 110 - .../spellbookfixer/SpellbookFixerPlugin.java | 170 - .../plugins/suppliestracker/ActionType.java | 36 - .../suppliestracker/BlowpipeDartType.java | 46 - .../plugins/suppliestracker/ItemType.java | 77 - .../plugins/suppliestracker/MenuAction.java | 60 - .../plugins/suppliestracker/SuppliesBox.java | 341 -- .../SuppliesTrackerConfig.java | 43 - .../suppliestracker/SuppliesTrackerItem.java | 42 - .../suppliestracker/SuppliesTrackerPanel.java | 217 - .../SuppliesTrackerPlugin.java | 781 ---- .../templetrek/TempleTrekBogOverlay.java | 68 - .../plugins/templetrek/TempleTrekConfig.java | 55 - .../plugins/templetrek/TempleTrekOverlay.java | 78 - .../plugins/templetrek/TempleTrekPlugin.java | 136 - .../tickcounter/TickCounterConfig.java | 71 - .../tickcounter/TickCounterOverlay.java | 69 - .../tickcounter/TickCounterPlugin.java | 193 - .../tobdamagecount/DamageCounterPlugin.java | 356 -- .../client/plugins/vetion/VetionConfig.java | 44 - .../client/plugins/vetion/VetionOverlay.java | 93 - .../client/plugins/vetion/VetionPlugin.java | 95 - .../client/plugins/vorkath/TileHighlight.java | 8 - .../client/plugins/vorkath/VorkathConfig.java | 51 - .../vorkath/VorkathIndicatorOverlay.java | 53 - .../plugins/vorkath/VorkathOverlay.java | 84 - .../client/plugins/vorkath/VorkathPlugin.java | 157 - .../warindicators/WarIndicatorConfig.java | 164 - .../WarIndicatorMiniMapOverlay.java | 87 - .../warindicators/WarIndicatorOverlay.java | 101 - .../warindicators/WarIndicatorPlugin.java | 170 - .../warindicators/WarIndicatorService.java | 106 - .../WildernessLocationsOverlay.java | 38 - .../WildernessLocationsPlugin.java | 127 - .../plugins/worldmap/QuestStartLocation.java | 252 +- .../plugins/worldmap/QuestStartPoint.java | 4 +- .../plugins/worldmap/TransportationPoint.java | 20 +- .../worldmap/TransportationPointLocation.java | 314 +- .../worldmap/WayPointWorldMapListener.java | 121 - .../worldmap/WayPointWorldMapPoint.java | 49 - .../plugins/worldmap/WorldMapConfig.java | 165 +- .../plugins/worldmap/WorldMapPlugin.java | 318 +- .../plugins/zoneIndicators/MapLocations.java | 3479 ----------------- .../zoneIndicators/ZoneIndicatorsConfig.java | 111 - .../ZoneIndicatorsMinimapOverlay.java | 116 - .../zoneIndicators/ZoneIndicatorsOverlay.java | 113 - .../zoneIndicators/ZoneIndicatorsPlugin.java | 297 -- .../zoneIndicators/ZoneVisibility.java | 43 - .../client/plugins/ztob/TheatreConfig.java | 138 - .../client/plugins/ztob/TheatreOverlay.java | 347 -- .../client/plugins/ztob/TheatrePlugin.java | 766 ---- .../client/plugins/zulrah/ZulrahConfig.java | 24 - .../client/plugins/zulrah/ZulrahOverlay.java | 72 - .../client/plugins/zulrah/ZulrahPlugin.java | 640 --- .../plugins/zulrah/ZulrahTileOverlay.java | 120 - .../net/runelite/client/util/Clipboard.java | 36 - .../net/runelite/client/util/MiscUtils.java | 79 - .../net/runelite/client/util/QueryRunner.java | 43 - .../runelite/client/util/ScreenCapture.java | 206 - .../client/util/WildernessLocation.java | 98 - .../plugins/equipmentinspector/normal.png | Bin 624 -> 0 bytes .../plugins/inventorysetups/add_icon.png | Bin 121 -> 0 bytes .../inventorysetups/inventorysetups_icon.png | Bin 765 -> 0 bytes .../plugins/inventorysetups/remove_icon.png | Bin 299 -> 0 bytes .../client/plugins/profiles/delete_icon.png | Bin 208 -> 0 bytes .../client/plugins/profiles/profiles_icon.png | Bin 77 -> 0 bytes .../plugins/suppliestracker/back_icon.png | Bin 15109 -> 0 bytes .../plugins/suppliestracker/panel_icon.png | Bin 1095 -> 0 bytes .../plugins/suppliestracker/plus_icon.png | Bin 179 -> 0 bytes .../plugins/suppliestracker/sarabrew.jpg | Bin 1714 -> 0 bytes .../plugins/worldmap/quest_complete_icon.png | Bin 315 -> 0 bytes .../plugins/worldmap/quest_started_icon.png | Bin 303 -> 0 bytes .../plugins/worldmap/waypoint_marker.png | Bin 958 -> 0 bytes 277 files changed, 860 insertions(+), 31791 deletions(-) delete mode 100644 runelite-api/src/main/java/net/runelite/api/events/CannonballFired.java delete mode 100644 runelite-api/src/main/java/net/runelite/api/queries/BankItemQuery.java delete mode 100644 runelite-api/src/main/java/net/runelite/api/queries/EquipmentItemQuery.java delete mode 100644 runelite-api/src/main/java/net/runelite/api/queries/InventoryWidgetItemQuery.java delete mode 100644 runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java delete mode 100644 runelite-api/src/main/java/net/runelite/api/queries/WidgetItemQuery.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectile.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/Calls.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/CycleCounter.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/Healer.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/HealerCode.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanchat/discord/DiscordClient.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanchat/discord/DiscordMessage.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeMinimapOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeService.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeTileOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxOverlayAbove.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/bank/EasyBankConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/bank/EasyBankPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/scape/EasyScapeConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/scape/EasyScapePlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/shop/EasyShopConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/shop/EasyShopPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/swap/EasySwapConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/swap/EasySwapPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/DuelingRingMode.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/EssenceMode.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/GamesNecklaceMode.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/GloryMode.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Markable.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Swappable.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Swapper.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/zulrah/EasyZulrahConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/easyscape/zulrah/EasyZulrahPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/normal.png delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/JadAttack.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveDisplayMode.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveMonster.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraIndicatorOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPrayOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanSpawn.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/ShamanSpawnOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierInputListener.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MinedRock.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningRockOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningRockType.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningSession.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningSessionRockStats.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorld.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorldHopperOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorldTracker.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MidiFileAdjuster.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MusicCustomizerPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/RealTimeMIDIPlayer.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionMinimapOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionService.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionTileOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/delete_icon.png delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/profiles_icon.png delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/protectitemreminder/ProtectItemReminderConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/protectitemreminder/ProtectItemReminderOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/protectitemreminder/ProtectItemReminderPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/Obstacles.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderTimer.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerGroups.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerInputListener.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ActionType.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/BlowpipeDartType.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ItemType.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/MenuAction.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesBox.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerItem.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/TileHighlight.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathIndicatorOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WayPointWorldMapListener.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WayPointWorldMapPoint.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahTileOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/util/Clipboard.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/util/MiscUtils.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/util/QueryRunner.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/util/ScreenCapture.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/util/WildernessLocation.java delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/equipmentinspector/normal.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/inventorysetups/add_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/inventorysetups/inventorysetups_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/inventorysetups/remove_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/profiles/delete_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/profiles/profiles_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/back_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/panel_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/plus_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/sarabrew.jpg delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/quest_complete_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/quest_started_icon.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/waypoint_marker.png diff --git a/runelite-api/src/main/java/net/runelite/api/Actor.java b/runelite-api/src/main/java/net/runelite/api/Actor.java index b0bd59aec1..6357a91ebc 100644 --- a/runelite-api/src/main/java/net/runelite/api/Actor.java +++ b/runelite-api/src/main/java/net/runelite/api/Actor.java @@ -38,12 +38,6 @@ import net.runelite.api.coords.WorldPoint; */ public interface Actor extends Renderable { - /** - * Used by the "Tick Counter Plugin - */ - int getActionFrame(); - int getActionFrameCycle(); - /** * Gets the combat level of the actor. * diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java index 02b3fd786c..e3fa08fd88 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -154,26 +154,10 @@ public final class AnimationID public static final int PISCARILIUS_CRANE_REPAIR = 7199; public static final int HOME_MAKE_TABLET = 4067; - //block animations for players and perhaps npcs as well? - public static final int BLOCK_DEFENDER = 4177; - public static final int BLOCK_NO_SHIELD = 420; - public static final int BLOCK_SHIELD = 1156; - public static final int BLOCK_SWORD = 388; - public static final int BLOCK_UNARMED = 424; - // NPC animations public static final int TZTOK_JAD_MAGIC_ATTACK = 2656; public static final int TZTOK_JAD_RANGE_ATTACK = 2652; public static final int HELLHOUND_DEFENCE = 6566; - public static final int VORKATH_WAKE_UP = 7950; - public static final int VORKATH_DEATH = 7949; - public static final int VORKATH_SLASH_ATTACK = 7951; - public static final int VORKATH_ATTACK = 7952; - public static final int VORKATH_FIRE_BOMB_ATTACK = 7960; - public static final int VORKATH_ACID_ATTACK = 7957; - public static final int BLACKJACK_KO = 838; - public static final int VETION_EARTHQUAKE = 5507; - public static final int ZULRAH_DEATH = 5804; // Farming public static final int FARMING_HARVEST_FRUIT_TREE = 2280; @@ -210,31 +194,4 @@ public final class AnimationID // POH Animations public static final int INCENSE_BURNER = 3687; - - // Weapons - public static final int LOW_LEVEL_MAGIC_ATTACK = 1162; - public static final int HIGH_LEVEL_MAGIC_ATTACK = 1167; - public static final int BLOWPIPE_ATTACK = 5061; - - // Hydra - public static final int HYDRA_POISON_1 = 8234; - public static final int HYDRA_RANGED_1 = 8235; - public static final int HYDRA_MAGIC_1 = 8236; - public static final int HYDRA_1_1 = 8237; - public static final int HYDRA_1_2 = 8238; - public static final int HYDRA_LIGHTNING = 8241; - public static final int HYDRA_RANGED_2 = 8242; - public static final int HYDRA_MAGIC_2 = 8243; - public static final int HYDRA_2_1 = 8244; - public static final int HYDRA_2_2 = 8245; - public static final int HYDRA_FIRE = 8248; - public static final int HYDRA_RANGED_3 = 8249; - public static final int HYDRA_MAGIC_3 = 8250; - public static final int HYDRA_3_1 = 8251; - public static final int HYDRA_3_2 = 8252; - public static final int HYDRA_MAGIC_4 = 8254; - public static final int HYDRA_POISON_4 = 8254; - public static final int HYDRA_RANGED_4 = 8255; - public static final int HYDRA_4_1 = 8257; - public static final int HYDRA_4_2 = 8258; -} \ No newline at end of file +} diff --git a/runelite-api/src/main/java/net/runelite/api/ClanMemberRank.java b/runelite-api/src/main/java/net/runelite/api/ClanMemberRank.java index 7f5a29873a..c919e343c7 100644 --- a/runelite-api/src/main/java/net/runelite/api/ClanMemberRank.java +++ b/runelite-api/src/main/java/net/runelite/api/ClanMemberRank.java @@ -39,43 +39,43 @@ public enum ClanMemberRank /** * Not in a clan. */ - UNRANKED(-1, "", -1), + UNRANKED(-1), /** * Friend rank. */ - FRIEND(0, "https://cdn.discordapp.com/attachments/556184918770843649/557023638826778635/1004.png", SpriteID.CLAN_CHAT_RANK_SMILEY_FRIEND), + FRIEND(0), /** * Recruit rank. */ - RECRUIT(1, "https://cdn.discordapp.com/attachments/556184918770843649/557023639111991306/1012-0.png", SpriteID.CLAN_CHAT_RANK_SINGLE_CHEVRON_RECRUIT), + RECRUIT(1), /** * Corporal rank. */ - CORPORAL(2, "https://cdn.discordapp.com/attachments/556184918770843649/557023638889431052/1011-0.png", SpriteID.CLAN_CHAT_RANK_DOUBLE_CHEVRON_CORPORAL), + CORPORAL(2), /** * Sergeant rank. */ - SERGEANT(3, "https://cdn.discordapp.com/attachments/556184918770843649/557023641968312321/1010-0.png", SpriteID.CLAN_CHAT_RANK_TRIPLE_CHEVRON_SERGEANT), + SERGEANT(3), /** * Lieutenant rank. */ - LIEUTENANT(4, "https://cdn.discordapp.com/attachments/556184918770843649/557023638893756416/1009-0.png", SpriteID.CLAN_CHAT_RANK_BRONZE_STAR_LIEUTENANT), + LIEUTENANT(4), /** * Captain rank. */ - CAPTAIN(5, "https://cdn.discordapp.com/attachments/556184918770843649/557023638910664734/1008-0.png", SpriteID.CLAN_CHAT_RANK_SILVER_STAR_CAPTAIN), + CAPTAIN(5), /** * General rank. */ - GENERAL(6, "https://cdn.discordapp.com/attachments/556184918770843649/557023638835036170/1007-0.png", SpriteID.CLAN_CHAT_RANK_GOLD_STAR_GENERAL), + GENERAL(6), /** * Channel owner rank. */ - OWNER(7, "https://cdn.discordapp.com/attachments/556184918770843649/557023638822453248/1006-0.png", SpriteID.CLAN_CHAT_RANK_KEY_CHANNEL_OWNER), + OWNER(7), /** * JMod rank. */ - JMOD(127, "", SpriteID.CLAN_CHAT_RANK_CROWN_JAGEX_MODERATOR); + JMOD(127); private static final Map RANKS = new HashMap<>(); @@ -87,8 +87,6 @@ public enum ClanMemberRank } } - - /** * Utility method that maps the rank value to its respective * {@link ClanMemberRank} value. @@ -101,11 +99,8 @@ public enum ClanMemberRank return RANKS.get(rank); } - /** * The value of the clan rank. */ private final int value; - private final String discavatar; - private final int spriteID; } diff --git a/runelite-api/src/main/java/net/runelite/api/InventoryID.java b/runelite-api/src/main/java/net/runelite/api/InventoryID.java index 8ce1f884b0..000bb8aa52 100644 --- a/runelite-api/src/main/java/net/runelite/api/InventoryID.java +++ b/runelite-api/src/main/java/net/runelite/api/InventoryID.java @@ -57,10 +57,6 @@ public enum InventoryID * Chambers of Xeric chest inventory. */ CHAMBERS_OF_XERIC_CHEST(581), - /** - * Looting Bag inventory - */ - LOOTING_BAG(516), /** * Theater of Blood reward chest inventory (Raids 2) */ diff --git a/runelite-api/src/main/java/net/runelite/api/ProjectileID.java b/runelite-api/src/main/java/net/runelite/api/ProjectileID.java index def8bed3e9..34d5c54f3a 100644 --- a/runelite-api/src/main/java/net/runelite/api/ProjectileID.java +++ b/runelite-api/src/main/java/net/runelite/api/ProjectileID.java @@ -44,7 +44,7 @@ public class ProjectileID public static final int VASA_RANGED_AOE = 1329; public static final int TEKTON_METEOR_AOE = 660; - public static final int OLM_FALLING_CRYSTAL_AOE = 1357; + public static final int OLM_FALLING_CRYSTAL_AOE = -1; //please help public static final int OLM_BURNING_AOE = -1; public static final int VORKATH_BOMB_AOE = 1481; @@ -84,10 +84,4 @@ public class ProjectileID public static final int VORKATH_PRAYER_DISABLE = 1471; public static final int VORKATH_VENOM = 1470; public static final int VORKATH_ICE = 350; - - public static final int HYDRA_MAGIC = 1662; - public static final int HYDRA_RANGED = 1663; - public static final int HYDRA_POISON = 1644; - public static final int HYDRA_LIGHTNING = 1664; - public static final int HYDRA_LIGHTNING_2 = 1665; } diff --git a/runelite-api/src/main/java/net/runelite/api/SpriteID.java b/runelite-api/src/main/java/net/runelite/api/SpriteID.java index e83c268535..e707854c12 100644 --- a/runelite-api/src/main/java/net/runelite/api/SpriteID.java +++ b/runelite-api/src/main/java/net/runelite/api/SpriteID.java @@ -431,7 +431,7 @@ public final class SpriteID public static final int SPELL_FIRE_SURGE_DISABLED = 415; /* Unmapped: 416, 417, 418 */ public static final int UNKNOWN_STANCE_ICON_1 = 419; - public static final int UNKNOWN_STANCE_ICON_2 = 420; + public static final int UNKNOWN_STANCE_ICON_2 = 320; public static final int UNKNOWN_STANCE_ICON_3 = 421; public static final int MINIMAP_DESTINATION_FLAG = 422; public static final int CHATBOX_BADGE_CROWN_PLAYER_MODERATOR = 423; @@ -1566,7 +1566,4 @@ public final class SpriteID public static final int MOBILE_YELLOW_TOUCH_ANIMATION_2 = 1626; public static final int TAB_MAGIC_SPELLBOOK_ARCEUUS_UNUSED = 1708; public static final int TAB_MAGIC_SPELLBOOK_ARCEUUS = 1711; - public static final int BIG_ASS_GUTHIX_SPELL = 1774; - public static final int BIG_SUPERHEAT = 1800; - public static final int BIG_SPEC_TRANSFER = 1959; } 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 45354e55d2..0652f3b0e0 100644 --- a/runelite-api/src/main/java/net/runelite/api/VarClientInt.java +++ b/runelite-api/src/main/java/net/runelite/api/VarClientInt.java @@ -48,12 +48,6 @@ public enum VarClientInt INVENTORY_TAB(171), - /** - * -1 = player inventory closed - * 3 = player inventory opened - */ - PLAYER_INVENTORY_OPENED(171), - WORLD_MAP_SEARCH_FOCUSED(190); private final int index; 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 8a42e1247f..88ce84f272 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -212,9 +212,6 @@ public enum Varbits * Barbarian Assault */ IN_GAME_BA(3923), - COLL_BAG_EGG1(3259), - COLL_BAG_EGG2(3260), - COLL_BAG_EGG3(3269), /** * 0 = Outside wilderness @@ -296,7 +293,6 @@ public enum Varbits */ NMZ_ABSORPTION(3956), NMZ_POINTS(3949), - NMZ_OVERLOAD(3955), /** * Blast Furnace @@ -353,17 +349,17 @@ public enum Varbits */ MULTICOMBAT_AREA(4605), - /** - * Wilderness area - */ - WILDERNESS_AREA(5963), - /** * Kingdom Management */ KINGDOM_FAVOR(72), KINGDOM_COFFER(74), + /** + * The Hand in the Sand quest status + */ + QUEST_THE_HAND_IN_THE_SAND(1527), + /** * Daily Tasks (Collection availability) */ @@ -474,19 +470,6 @@ public enum Varbits BANK_TAB_EIGHT_COUNT(4178), BANK_TAB_NINE_COUNT(4179), - /* - * Spells being auto-casted - * */ - AUTO_CAST_SPELL(276), - - /** - * Temple Trekking - */ - TREK_POINTS(1955), - TREK_STARTED(1956), - TREK_EVENT(1958), - TREK_STATUS(6719), - /** * Type of GE offer currently being created * 0 = buy @@ -494,95 +477,6 @@ public enum Varbits */ GE_OFFER_CREATION_TYPE(4397), - /** - * f2p Quest varbits, these don't hold the completion value. - */ - QUEST_DEMON_SLAYER(2561), - QUEST_GOBLIN_DIPLOMACY(2378), - QUEST_MISTHALIN_MYSTERY(3468), - QUEST_THE_CORSAIR_CURSE(6071), - QUEST_X_MARKS_THE_SPOT(8063), - - /** - * member Quest varbits, these don't hold the completion value. - */ - QUEST_ANIMAL_MAGNETISM(3185), - QUEST_BETWEEN_A_ROCK(299), - QUEST_CONTACT(3274), - QUEST_ZOGRE_FLESH_EATERS(487), - QUEST_DARKNESS_OF_HALLOWVALE(2573), - QUEST_DEATH_TO_THE_DORGESHUUN(2258), - QUEST_DESERT_TREASURE(358), - QUEST_DEVIOUS_MINDS(1465), - QUEST_EAGLES_PEAK(2780), - QUEST_ELEMENTAL_WORKSHOP_II(2639), - QUEST_ENAKHRAS_LAMENT(1560), - QUEST_ENLIGHTENED_JOURNEY(2866), - QUEST_THE_EYES_OF_GLOUPHRIE(2497), - QUEST_FAIRYTALE_I_GROWING_PAINS(1803), - QUEST_FAIRYTALE_II_CURE_A_QUEEN(2326), - QUEST_THE_FEUD(334), - QUEST_FORGETTABLE_TALE(822), - QUEST_GARDEN_OF_TRANQUILLITY(961), - QUEST_GHOSTS_AHOY(217), - QUEST_THE_GIANT_DWARF(571), - QUEST_THE_GOLEM(346), - QUEST_THE_HAND_IN_THE_SAND(1527), - QUEST_HORROR_FROM_THE_DEEP(34), - QUEST_ICTHLARINS_LITTLE_HELPER(418), - QUEST_IN_AID_OF_THE_MYREQUE(1990), - QUEST_THE_LOST_TRIBE(532), - QUEST_LUNAR_DIPLOMACY(2448), - QUEST_MAKING_HISTORY(1383), - QUEST_MOUNTAIN_DAUGHTER(260), - QUEST_MOURNINGS_ENDS_PART_II(1103), - QUEST_MY_ARMS_BIG_ADVENTURE(2790), - QUEST_RATCATCHERS(1404), - QUEST_RECIPE_FOR_DISASTER(1850), - QUEST_RECRUITMENT_DRIVE(657), - QUEST_ROYAL_TROUBLE(2140), - QUEST_THE_SLUG_MENACE(2610), - QUEST_SHADOW_OF_THE_STORM(1372), - QUEST_A_SOULS_BANE(2011), - QUEST_SPIRITS_OF_THE_ELID(1444), - QUEST_SWAN_SONG(2098), - QUEST_A_TAIL_OF_TWO_CATS(1028), - QUEST_TEARS_OF_GUTHIX(451), - QUEST_WANTED(1051), - QUEST_COLD_WAR(3293), - QUEST_THE_FREMENNIK_ISLES(3311), - QUEST_TOWER_OF_LIFE(3337), - QUEST_WHAT_LIES_BELOW(3523), - QUEST_OLAFS_QUEST(3534), - QUEST_ANOTHER_SLICE_OF_HAM(3550), - QUEST_DREAM_MENTOR(3618), - QUEST_GRIM_TALES(2783), - QUEST_KINGS_RANSOM(3888), - QUEST_MONKEY_MADNESS_II(5027), - QUEST_CLIENT_OF_KOUREND(5619), - QUEST_BONE_VOYAGE(5795), - QUEST_THE_QUEEN_OF_THIEVES(6037), - QUEST_THE_DEPTHS_OF_DESPAIR(6027), - QUEST_DRAGON_SLAYER_II(6104), - QUEST_TALE_OF_THE_RIGHTEOUS(6358), - QUEST_A_TASTE_OF_HOPE(6396), - QUEST_MAKING_FRIENDS_WITH_MY_ARM(6528), - QUEST_THE_ASCENT_OF_ARCEUUS(7856), - QUEST_THE_FORSAKEN_TOWER(7796), - - /** - * mini-quest varbits, these don't hold the completion value. - */ - QUEST_ARCHITECTURAL_ALLIANCE(4982), - QUEST_BEAR_YOUR_SOUL(5078), - QUEST_CURSE_OF_THE_EMPTY_LORD(821), - QUEST_ENCHANTED_KEY(1391), - QUEST_THE_GENERALS_SHADOW(3330), - QUEST_SKIPPY_AND_THE_MOGRES(1344), - QUEST_LAIR_OF_TARN_RAZORLOR(3290), - QUEST_FAMILY_PEST(5347), - QUEST_THE_MAGE_ARENA_II(6067), - /** * The active tab within the quest interface */ diff --git a/runelite-api/src/main/java/net/runelite/api/events/CannonballFired.java b/runelite-api/src/main/java/net/runelite/api/events/CannonballFired.java deleted file mode 100644 index 077a88096d..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/events/CannonballFired.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2019, Davis Cook - * 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; - -/** - * an event posted when a cannonball is fired - */ -public class CannonballFired -{ -} diff --git a/runelite-api/src/main/java/net/runelite/api/kit/KitType.java b/runelite-api/src/main/java/net/runelite/api/kit/KitType.java index e52167c563..fdbf92ebfd 100644 --- a/runelite-api/src/main/java/net/runelite/api/kit/KitType.java +++ b/runelite-api/src/main/java/net/runelite/api/kit/KitType.java @@ -36,7 +36,6 @@ import net.runelite.api.PlayerComposition; */ public enum KitType { - HELM(0), CAPE(1), AMULET(2), WEAPON(3), diff --git a/runelite-api/src/main/java/net/runelite/api/queries/BankItemQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/BankItemQuery.java deleted file mode 100644 index b0131dce32..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/queries/BankItemQuery.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2017, Devin French - * 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.queries; - -import net.runelite.api.Client; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.widgets.WidgetItem; - -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Objects; - -public class BankItemQuery extends WidgetItemQuery -{ - private static final int ITEM_EMPTY = 6512; - - @Override - public WidgetItem[] result(Client client) - { - Collection widgetItems = getBankItems(client); - if (widgetItems != null) - { - return widgetItems.stream() - .filter(Objects::nonNull) - .filter(predicate) - .toArray(WidgetItem[]::new); - } - return new WidgetItem[0]; - } - - private Collection getBankItems(Client client) - { - Collection widgetItems = new ArrayList<>(); - Widget bank = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER); - if (bank != null && !bank.isHidden()) - { - Widget[] children = bank.getDynamicChildren(); - for (int i = 0; i < children.length; i++) - { - Widget child = children[i]; - if (child.getItemId() == ITEM_EMPTY || child.isSelfHidden()) - { - continue; - } - // set bounds to same size as default inventory - Rectangle bounds = child.getBounds(); - bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32); - // Index is set to 0 because the widget's index does not correlate to the order in the bank - widgetItems.add(new WidgetItem(child.getItemId(), child.getItemQuantity(), 0, bounds)); - } - } - return widgetItems; - } -} diff --git a/runelite-api/src/main/java/net/runelite/api/queries/EquipmentItemQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/EquipmentItemQuery.java deleted file mode 100644 index 210fc1e8d0..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/queries/EquipmentItemQuery.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2017, Devin French - * 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.queries; - -import net.runelite.api.Client; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.widgets.WidgetItem; - -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Objects; - -public class EquipmentItemQuery extends WidgetItemQuery -{ - private static final WidgetInfo[] ALL_EQUIPMENT_WIDGET_INFOS = - { - WidgetInfo.EQUIPMENT_HELMET, - WidgetInfo.EQUIPMENT_CAPE, - WidgetInfo.EQUIPMENT_AMULET, - WidgetInfo.EQUIPMENT_WEAPON, - WidgetInfo.EQUIPMENT_BODY, - WidgetInfo.EQUIPMENT_SHIELD, - WidgetInfo.EQUIPMENT_LEGS, - WidgetInfo.EQUIPMENT_GLOVES, - WidgetInfo.EQUIPMENT_BOOTS, - WidgetInfo.EQUIPMENT_RING, - WidgetInfo.EQUIPMENT_AMMO, - }; - - private final Collection slots = new ArrayList<>(); - - public EquipmentItemQuery slotEquals(WidgetInfo... slotWidgetInfo) - { - slots.addAll(Arrays.asList(slotWidgetInfo)); - return this; - } - - @Override - public WidgetItem[] result(Client client) - { - Collection widgetItems = getEquippedItems(client); - if (widgetItems != null) - { - return widgetItems.stream() - .filter(Objects::nonNull) - .filter(predicate) - .toArray(WidgetItem[]::new); - } - return new WidgetItem[0]; - } - - private Collection getEquippedItems(Client client) - { - Collection widgetItems = new ArrayList<>(); - Widget equipment = client.getWidget(WidgetInfo.EQUIPMENT); - if (equipment != null && !equipment.isHidden()) - { - if (slots.isEmpty()) - { - slots.addAll(Arrays.asList(ALL_EQUIPMENT_WIDGET_INFOS)); - } - for (WidgetInfo slot : slots) - { - Widget parentWidget = client.getWidget(slot); - Widget itemWidget = parentWidget.getChild(1); - // Check if background icon is hidden. if hidden, item is equipped. - boolean equipped = parentWidget.getChild(2).isSelfHidden(); - // set bounds to same size as default inventory - Rectangle bounds = itemWidget.getBounds(); - bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32); - // Index is set to 0 because there is no set in stone order of equipment slots - widgetItems.add(new WidgetItem(equipped ? itemWidget.getItemId() : -1, itemWidget.getItemQuantity(), 0, bounds)); - } - } - return widgetItems; - } -} diff --git a/runelite-api/src/main/java/net/runelite/api/queries/InventoryWidgetItemQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/InventoryWidgetItemQuery.java deleted file mode 100644 index 1872eeed65..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/queries/InventoryWidgetItemQuery.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2017, Devin French - * 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.queries; - -import net.runelite.api.Client; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.widgets.WidgetItem; - -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Objects; - -public class InventoryWidgetItemQuery extends WidgetItemQuery -{ - private static final WidgetInfo[] INVENTORY_WIDGET_INFOS = - { - WidgetInfo.DEPOSIT_BOX_INVENTORY_ITEMS_CONTAINER, - WidgetInfo.BANK_INVENTORY_ITEMS_CONTAINER, - WidgetInfo.SHOP_INVENTORY_ITEMS_CONTAINER, - WidgetInfo.GRAND_EXCHANGE_INVENTORY_ITEMS_CONTAINER, - WidgetInfo.GUIDE_PRICES_INVENTORY_ITEMS_CONTAINER, - WidgetInfo.EQUIPMENT_INVENTORY_ITEMS_CONTAINER, - WidgetInfo.INVENTORY - }; - - @Override - public WidgetItem[] result(Client client) - { - Collection widgetItems = getInventoryItems(client); - if (widgetItems != null) - { - return widgetItems.stream() - .filter(Objects::nonNull) - .filter(predicate) - .toArray(WidgetItem[]::new); - } - return new WidgetItem[0]; - } - - private Collection getInventoryItems(Client client) - { - Collection widgetItems = new ArrayList<>(); - for (WidgetInfo widgetInfo : INVENTORY_WIDGET_INFOS) - { - Widget inventory = client.getWidget(widgetInfo); - if (inventory == null || inventory.isHidden()) - { - continue; - } - if (widgetInfo == WidgetInfo.INVENTORY) - { - widgetItems.addAll(inventory.getWidgetItems()); - break; - } - else - { - Widget[] children = inventory.getDynamicChildren(); - for (int i = 0; i < children.length; i++) - { - Widget child = children[i]; - // set bounds to same size as default inventory - Rectangle bounds = child.getBounds(); - bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32); - widgetItems.add(new WidgetItem(child.getItemId(), child.getItemQuantity(), i, bounds)); - } - break; - } - } - return widgetItems; - } -} diff --git a/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java deleted file mode 100644 index cd037f0a28..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2017, Devin French - * 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.queries; - -import net.runelite.api.Client; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.widgets.WidgetItem; - -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Objects; - -public class ShopItemQuery extends WidgetItemQuery -{ - @Override - public WidgetItem[] result(Client client) - { - Collection widgetItems = getShopItems(client); - if (widgetItems != null) - { - return widgetItems.stream() - .filter(Objects::nonNull) - .filter(predicate) - .toArray(WidgetItem[]::new); - } - return new WidgetItem[0]; - } - - private Collection getShopItems(Client client) - { - Collection widgetItems = new ArrayList<>(); - Widget shop = client.getWidget(WidgetInfo.SHOP_ITEMS_CONTAINER); - if (shop != null && !shop.isHidden()) - { - Widget[] children = shop.getDynamicChildren(); - for (int i = 1; i < children.length; i++) - { - Widget child = children[i]; - // set bounds to same size as default inventory - Rectangle bounds = child.getBounds(); - bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32); - widgetItems.add(new WidgetItem(child.getItemId(), child.getItemQuantity(), i - 1, bounds)); - } - } - return widgetItems; - } -} diff --git a/runelite-api/src/main/java/net/runelite/api/queries/WidgetItemQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/WidgetItemQuery.java deleted file mode 100644 index 9a71a9bf3c..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/queries/WidgetItemQuery.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2017, Devin French - * 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.queries; - -import net.runelite.api.Client; -import net.runelite.api.Query; -import net.runelite.api.widgets.WidgetItem; - -public abstract class WidgetItemQuery extends Query -{ - - public WidgetItemQuery idEquals(int... ids) - { - predicate = and(item -> - { - for (int id : ids) - { - if (item.getId() == id) - { - return true; - } - } - return false; - }); - return this; - } - - public WidgetItemQuery indexEquals(int... indexes) - { - predicate = and(item -> - { - for (int index : indexes) - { - if (item.getIndex() == index) - { - return true; - } - } - return false; - }); - return this; - } - - public WidgetItemQuery quantityEquals(int quantity) - { - predicate = and(item -> item.getQuantity() == quantity); - return this; - } - - @Override - public abstract WidgetItem[] result(Client client); -} 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 e115364f10..d84bae473e 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 @@ -129,7 +129,6 @@ public class WidgetID public static final int SKILLS_GROUP_ID = 320; public static final int QUESTTAB_GROUP_ID = 629; public static final int MUSIC_GROUP_ID = 239; - public static final int MUSICTAB_GROUP_ID = 239; public static final int BARROWS_PUZZLE_GROUP_ID = 25; static class WorldMap @@ -556,7 +555,7 @@ public class WidgetID static final int CURRENT_WAVE_WIDGET = 4; static final int CURRENT_WAVE = 5; static final int CALL_WIDGET = 6; - static final int HEARD_CALL = 7; + static final int CALL_TEXT = 7; static final int TO_CALL_WIDGET = 8; static final int TO_CALL = 9; static final int ROLE_SPRITE = 10; @@ -564,7 +563,6 @@ public class WidgetID static final int REWARD_TEXT = 57; } - static class LevelUp { static final int SKILL = 1; @@ -703,154 +701,16 @@ public class WidgetID static class StandardSpellBook { static final int LUMBRIDGE_HOME_TELEPORT = 4; - static final int WIND_STRIKE = 5; - static final int CONFUSE = 6; - static final int ENCHANT_CROSSBOW_BOLT = 7; - static final int WATER_STRIKE = 8; - static final int LVL_1_ENCHANT = 9; - static final int EARTH_STRIKE = 10; - static final int WEAKEN = 11; - static final int FIRE_STRIKE = 12; - static final int BONES_TO_BANANAS = 13; - static final int WIND_BOLT = 14; - static final int CURSE = 15; - static final int BIND = 16; - static final int LOW_LEVEL_ALCHEMY = 17; - static final int WATER_BOLT = 18; - static final int VARROCK_TELEPORT = 19; - static final int LVL_2_ENCHANT = 20; - static final int EARTH_BOLT = 21; - static final int LUMBRIDGE_TELEPORT = 22; - static final int TELEKINETIC_GRAB = 23; - static final int FIRE_BOLT = 24; - static final int FALADOR_TELEPORT = 25; - static final int CRUMBLE_UNDEAD = 26; - static final int TELEPORT_TO_HOUSE = 27; - static final int WIND_BLAST = 28; - static final int SUPERHEAT_ITEM = 29; - static final int CAMELOT_TELEPORT = 30; - static final int WATER_BLAST = 31; - static final int LVL_3_ENCHANT = 32; - static final int IBAN_BLAST = 33; - static final int SNARE = 34; - static final int MAGIC_DART = 35; - static final int ARDOUGNE_TELEPORT = 36; - static final int EARTH_BLAST = 37; - static final int HIGH_LEVEL_ALCHEMY = 38; - static final int CHARGE_WATER_ORB = 39; - static final int LVL_4_ENCHANT = 40; - static final int WATCHTOWER_TELEPORT = 41; - static final int FIRE_BLAST = 42; - static final int CHARGE_EARTH_ORB = 43; - static final int BONES_TO_PEACHES = 44; - static final int SARADOMIN_STRIKE = 45; - static final int CLAWS_OF_GUTHIX = 46; - static final int FLAMES_OF_ZAMORAK = 47; - static final int TROLLHEIM_TELEPORT = 48; - static final int WIND_WAVE = 49; - static final int HARGE_FIRE_ORB = 50; - static final int TELEPORT_TO_APE_ATOLL = 51; - static final int WATER_WAVE = 52; - static final int CHARGE_AIR_ORB = 53; - static final int VULNERABILITY = 54; - static final int LVL_5_ENCHANT = 55; - static final int TELEPORT_TO_KOUREND = 56; - static final int EARTH_WAVE = 57; - static final int ENFEEBLE = 58; - static final int TELEOTHER_LUMBRIDGE = 59; - static final int FIRE_WAVE = 60; - static final int ENTANGLE = 61; - static final int STUN = 62; - static final int CHARGE = 63; - static final int WIND_SURGE = 64; - static final int TELEOTHER_FALADOR = 65; - static final int WATER_SURGE = 66; - static final int TELE_BLOCK = 67; - static final int BOUNTY_TARGET_TELEPORT = 68; - static final int LVL_6_ENCHANT = 69; - static final int TELEOTHER_CAMELOT = 70; - static final int EARTH_SURGE = 71; - static final int LVL_7_ENCHANT = 72; - static final int FIRE_SURGE = 73; } static class AncientSpellBook { - static final int BOUNTY_TARGET_TELEPORT = 68; - static final int ICE_RUSH = 74; - static final int ICE_BLITZ = 75; - static final int ICE_BURST = 76; - static final int ICE_BARRAGE = 77; - static final int BLOOD_RUSH = 78; - static final int BLOOD_BLITZ = 79; - static final int BLOOD_BURST = 80; - static final int BLOOD_BARRAGE = 81; - static final int SMOKE_RUSH = 82; - static final int SMOKE_BLITZ = 83; - static final int SMOKE_BURST = 84; - static final int SMOKE_BARRAGE = 85; - static final int SHADOW_RUSH = 86; - static final int SHADOW_BLITZ = 87; - static final int SHADOW_BURST = 88; - static final int SHADOW_BARRAGE = 89; - static final int PADDEWWA_TELEPORT = 90; - static final int SENNTISTEN_TELEPORT = 91; - static final int KHARYRLL_TELEPORT = 92; - static final int LASSAR_TELEPORT = 93; - static final int DAREEYAK_TELEPORT = 94; - static final int CARRALLANGER_TELEPORT = 95; - static final int ANNAKARL_TELEPORT = 96; - static final int GHORROCK_TELEPORT = 97; static final int EDGEVILLE_HOME_TELEPORT = 98; } static class LunarSpellBook { - static final int BOUNTY_TARGET_TELEPORT = 68; static final int LUNAR_HOME_TELEPORT = 99; - static final int BAKE_PIE = 100; - static final int CURE_PLANT = 101; - static final int MONSTER_EXAMINE = 102; - static final int NPC_CONTACT = 103; - static final int CURE_OTHER = 104; - static final int HUMIDIFY = 105; - static final int MOONCLAN_TELEPORT = 106; - static final int TELE_GROUP_MOONCLAN = 107; - static final int CURE_ME = 108; - static final int HUNTER_KIT = 109; - static final int WATERBIRTH_TELEPORT = 110; - static final int TELE_GROUP_WATERBIRTH = 111; - static final int CURE_GROUP = 112; - static final int STAT_SPY = 113; - static final int BARBARIAN_TELEPORT = 114; - static final int TELE_GROUP_BARBARIAN = 115; - static final int SUPERGLASS_MAKE = 116; - static final int TAN_LEATHER = 117; - static final int KHAZARD_TELEPORT = 118; - static final int TELE_GROUP_KHAZARD = 119; - static final int DREAM = 120; - static final int STRING_JEWELLERY = 121; - static final int STAT_RESTORE_POT_SHARE = 122; - static final int MAGIC_IMBUE = 123; - static final int FERTILE_SOIL = 124; - static final int BOOST_POTION_SHARE = 125; - static final int FISHING_GUILD_TELEPORT = 126; - static final int TELE_GROUP_FISHING_GUILD = 127; - static final int PLANK_MAKE = 128; - static final int CATHERBY_TELEPORT = 129; - static final int TELE_GROUP_CATHERBY = 130; - static final int RECHARGE_DRAGONSTONE = 131; - static final int ICE_PLATEAU_TELEPORT = 132; - static final int TELE_GROUP_ICE_PLATEAU = 133; - static final int ENERGY_TRANSFER = 134; - static final int HEAL_OTHER = 135; - static final int VENGEANCE_OTHER = 136; - static final int VENGEANCE = 137; - static final int HEAL_GROUP = 138; - static final int SPELLBOOK_SWAP = 139; - static final int GEOMANCY = 140; - static final int SPIN_FLAX = 141; - static final int OURANIA_TELEPORT = 142; } static class ArceuusSpellBook 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 88c1677891..5f12519d5d 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 @@ -351,7 +351,6 @@ public enum WidgetInfo 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), - BA_COLL_HEARD_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.HEARD_CALL), BA_COLL_ROLE_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.ROLE), BA_COLL_ROLE_SPRITE(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.ROLE_SPRITE), @@ -451,56 +450,10 @@ public enum WidgetInfo MINIGAME_TELEPORT_BUTTON(WidgetID.MINIGAME_TAB_ID, WidgetID.Minigames.TELEPORT_BUTTON), - /* 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), - SPELL_SNARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.SNARE), - SPELL_ENTANGLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.ENTANGLE), - SPELL_TELE_BLOCK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.TELE_BLOCK), - SPELL_FIRE_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.FIRE_SURGE), - SPELL_BOUNTY_TARGET_TELEPORT2(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.BOUNTY_TARGET_TELEPORT), - /* END OF STANDARD SPELL BOOK WIDGETS*/ - - /* LUNAR SPELL BOOK WIDGETS*/ - SPELL_LUNAR_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.LUNAR_HOME_TELEPORT), - SPELL_VENGEANCE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.VENGEANCE_OTHER), - SPELL_VENGEANCE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.VENGEANCE), - SPELL_BOUNTY_TARGET_TELEPORT3(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.BOUNTY_TARGET_TELEPORT), - /* LUNA SPELL BOOK WIDGETS*/ - - /* ARCEUUS SPELL BOOK WIDGETS*/ - SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.ArceuusSpellBook.ARCEUUS_HOME_TELEPORT), - /* END OF ARCEUUS SPELL BOOK WIDGETS*/ - - /* ANCIENT SPELL BOOK WIDGETS*/ - SPELL_ICE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_RUSH), - SPELL_ICE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BLITZ), - SPELL_ICE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BURST), - SPELL_ICE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BARRAGE), - SPELL_BLOOD_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_RUSH), - SPELL_BLOOD_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BLITZ), - SPELL_BLOOD_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BURST), - SPELL_BLOOD_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BARRAGE), - SPELL_SMOKE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_RUSH), - SPELL_SMOKE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BLITZ), - SPELL_SMOKE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BURST), - SPELL_SMOKE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BARRAGE), - SPELL_SHADOW_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_RUSH), - SPELL_SHADOW_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BLITZ), - SPELL_SHADOW_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BURST), - SPELL_SHADOW_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BARRAGE), - SPELL_PADDEWWA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.PADDEWWA_TELEPORT), - SPELL_SENNTISTEN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SENNTISTEN_TELEPORT), - SPELL_KHARYRLL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.KHARYRLL_TELEPORT), - SPELL_LASSAR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.LASSAR_TELEPORT), - SPELL_DAREEYAK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.DAREEYAK_TELEPORT), - SPELL_CARRALLANGER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.CARRALLANGER_TELEPORT), - SPELL_ANNAKARL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ANNAKARL_TELEPORT), - SPELL_GHORROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.GHORROCK_TELEPORT), SPELL_EDGEVILLE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.EDGEVILLE_HOME_TELEPORT), - SPELL_BOUNTY_TARGET_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BOUNTY_TARGET_TELEPORT), - - /* END OF ANCIENT SPELL BOOK WIDGETS*/ + SPELL_LUNAR_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.LUNAR_HOME_TELEPORT), + SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.ArceuusSpellBook.ARCEUUS_HOME_TELEPORT), PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER), PVP_WORLD_SAFE_ZONE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SAFE_ZONE), @@ -520,25 +473,12 @@ public enum WidgetInfo QUESTLIST_BOX(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.BOX), QUESTLIST_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.CONTAINER), - QUESTLIST_SCROLLBAR(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.SCROLLBAR), + QUESTLIST_SCROLLBAR(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.SCROLLBAR), QUESTLIST_FREE_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.FREE_CONTAINER), QUESTLIST_MEMBERS_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.MEMBERS_CONTAINER), QUESTLIST_MINIQUEST_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.MINIQUEST_CONTAINER), - QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB), - MUSICTAB_INTERFACE(WidgetID.MUSICTAB_GROUP_ID, 1), - MUSICTAB_SONG_BOX(WidgetID.MUSICTAB_GROUP_ID, 2), - MUSICTAB_ALL_SONGS(WidgetID.MUSICTAB_GROUP_ID, 3), - MUSICTAB_SCROLLBAR(WidgetID.MUSICTAB_GROUP_ID, 4), - MUSICTAB_PLAYING(WidgetID.MUSICTAB_GROUP_ID, 5), - MUSICTAB_CURRENT_SONG_NAME(WidgetID.MUSICTAB_GROUP_ID, 6), - MUSICTAB_AUTO_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 7), - MUSICTAB_AUTO_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 8), - MUSICTAB_MANUAL_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 9), - MUSICTAB_MANUAL_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 10), - MUSICTAB_LOOP_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 11), - MUSICTAB_LOOP_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 12), - MUSICTAB_UNLOCKED_SONGS(WidgetID.MUSICTAB_GROUP_ID, 13); + QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB); private final int groupId; private final int childId; 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 5124905378..1bed02603e 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 @@ -24,14 +24,9 @@ */ package net.runelite.client.plugins.antidrag; -import java.awt.Color; -import java.awt.event.KeyEvent; -import net.runelite.client.config.Alpha; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -import net.runelite.client.config.Keybind; -import net.runelite.client.config.ModifierlessKeybind; @ConfigGroup("antiDrag") public interface AntiDragConfig extends Config @@ -46,49 +41,4 @@ public interface AntiDragConfig extends Config { return 600 / 20; // one game tick } - - @ConfigItem( - keyName = "keybind", - name = "keybind", - description = "The keybind you want to use for antidrag", - position = 2 - ) - default Keybind key() - { - return new ModifierlessKeybind(KeyEvent.VK_SHIFT, 0); - } - - @ConfigItem( - keyName = "reqfocus", - name = "Reset on focus loss", - description = "Disable antidrag when losing focus (like alt tabbing)", - position = 3 - ) - default boolean reqfocus() - { - return false; - } - - @ConfigItem( - keyName = "overlay", - name = "Enable overlay", - description = "Do you really need a description?", - position = 4 - ) - default boolean overlay() - { - return true; - } - - @Alpha - @ConfigItem( - keyName = "color", - name = "Overlay color", - description = "Change the overlay color, duh", - position = 5 - ) - default Color color() - { - return new Color(255, 0, 0, 30); - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragOverlay.java deleted file mode 100644 index c19fc3d6c1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragOverlay.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.runelite.client.plugins.antidrag; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import net.runelite.api.Client; -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; - -@Singleton -public class AntiDragOverlay extends Overlay -{ - private static final int RADIUS = 20; - - private Client client; - private AntiDragConfig config; - - @Inject - private AntiDragOverlay(Client client, AntiDragConfig config) - { - this.config = config; - this.client = client; - setPosition(OverlayPosition.TOOLTIP); - setPriority(OverlayPriority.HIGHEST); - setLayer(OverlayLayer.ALWAYS_ON_TOP); - } - - @Override - public Dimension render(Graphics2D g) - { - final Color color = config.color(); - g.setColor(color); - - final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition(); - final Point mousePosition = new Point(mouseCanvasPosition.getX() - RADIUS, mouseCanvasPosition.getY() - RADIUS); - final Rectangle bounds = new Rectangle(mousePosition.x, mousePosition.y, 2 * RADIUS, 2 * RADIUS); - g.fillOval(bounds.x, bounds.y, bounds.height, bounds.width); - - return bounds.getSize(); - } -} 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 de431ff051..26f926be4a 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 @@ -25,26 +25,25 @@ package net.runelite.client.plugins.antidrag; 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; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.HotkeyListener; @PluginDescriptor( name = "Shift Anti Drag", description = "Prevent dragging an item for a specified delay", tags = {"antidrag", "delay", "inventory", "items"} ) -public class AntiDragPlugin extends Plugin +public class AntiDragPlugin extends Plugin implements KeyListener { private static final int DEFAULT_DELAY = 5; - private boolean toggleDrag; @Inject private Client client; @@ -52,12 +51,6 @@ public class AntiDragPlugin extends Plugin @Inject private AntiDragConfig config; - @Inject - private AntiDragOverlay overlay; - - @Inject - private OverlayManager overlayManager; - @Inject private KeyManager keyManager; @@ -70,50 +63,46 @@ public class AntiDragPlugin extends Plugin @Override protected void startUp() throws Exception { - keyManager.registerKeyListener(hotkeyListener); - toggleDrag = false; - + keyManager.registerKeyListener(this); } @Override protected void shutDown() throws Exception { client.setInventoryDragDelay(DEFAULT_DELAY); - keyManager.unregisterKeyListener(hotkeyListener); - toggleDrag = false; - overlayManager.remove(overlay); + keyManager.unregisterKeyListener(this); } - private final HotkeyListener hotkeyListener = new HotkeyListener(() -> config.key()) + @Override + public void keyTyped(KeyEvent e) { - @Override - public void hotkeyPressed() - { - toggleDrag = !toggleDrag; - if (toggleDrag) - { - if (config.overlay()) - { - overlayManager.add(overlay); - } - client.setInventoryDragDelay(config.dragDelay()); - } - else - { - overlayManager.remove(overlay); - client.setInventoryDragDelay(DEFAULT_DELAY); - } + } + + @Override + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_SHIFT) + { + client.setInventoryDragDelay(config.dragDelay()); } - }; + } + + @Override + public void keyReleased(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_SHIFT) + { + client.setInventoryDragDelay(DEFAULT_DELAY); + } + } @Subscribe public void onFocusChanged(FocusChanged focusChanged) { - if (!focusChanged.isFocused() && config.reqfocus()) + if (!focusChanged.isFocused()) { client.setInventoryDragDelay(DEFAULT_DELAY); - overlayManager.remove(overlay); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectile.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectile.java deleted file mode 100644 index 8bd41f2610..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectile.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * 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.aoewarnings; - -import net.runelite.api.coords.LocalPoint; - -import java.time.Instant; - -public class AoeProjectile -{ - private final Instant startTime; - private final LocalPoint targetPoint; - private final AoeProjectileInfo aoeProjectileInfo; - - public AoeProjectile(Instant startTime, LocalPoint targetPoint, AoeProjectileInfo aoeProjectileInfo) - { - this.startTime = startTime; - this.targetPoint = targetPoint; - this.aoeProjectileInfo = aoeProjectileInfo; - } - - public Instant getStartTime() - { - return startTime; - } - - public LocalPoint getTargetPoint() - { - return targetPoint; - } - - public AoeProjectileInfo getAoeProjectileInfo() - { - return aoeProjectileInfo; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java deleted file mode 100644 index 4d4f59a650..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java +++ /dev/null @@ -1,128 +0,0 @@ -package net.runelite.client.plugins.aoewarnings; - -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; -import net.runelite.api.ProjectileID; - -public enum AoeProjectileInfo -{ - LIZARDMAN_SHAMAN_AOE(ProjectileID.LIZARDMAN_SHAMAN_AOE, 3000, 3), - CRAZY_ARCHAEOLOGIST_AOE(ProjectileID.CRAZY_ARCHAEOLOGIST_AOE, 3000, 3), - ICE_DEMON_RANGED_AOE(ProjectileID.ICE_DEMON_RANGED_AOE, 3000, 3), - /** - * When you don't have pray range on ice demon does an ice barrage - */ - ICE_DEMON_ICE_BARRAGE_AOE(ProjectileID.ICE_DEMON_ICE_BARRAGE_AOE, 3000, 3), - /** - * The AOE when vasa first starts - */ - VASA_AWAKEN_AOE(ProjectileID.VASA_AWAKEN_AOE, 4500, 3), - VASA_RANGED_AOE(ProjectileID.VASA_RANGED_AOE, 3000, 3), - TEKTON_METEOR_AOE(ProjectileID.TEKTON_METEOR_AOE, 4000, 3), - - /** - * The AOEs of Vorkath - */ - VORKATH_BOMB(ProjectileID.VORKATH_BOMB_AOE, 2400, 3), - VORKATH_POISON_POOL(ProjectileID.VORKATH_POISON_POOL_AOE, 1800, 1), - VORKATH_SPAWN(ProjectileID.VORKATH_SPAWN_AOE, 3000, 1), //extra tick because hard to see otherwise - VORKATH_TICK_FIRE(ProjectileID.VORKATH_TICK_FIRE_AOE, 600, 1), - - /** - * the AOEs of Galvek - */ - GALVEK_MINE(ProjectileID.GALVEK_MINE, 3600, 3), - GALVEK_BOMB(ProjectileID.GALVEK_BOMB, 2400, 3), - - DAWN_FREEZE(ProjectileID.DAWN_FREEZE, 3000, 3), - DUSK_CEILING(ProjectileID.DUSK_CEILING, 3000, 3), - - /** - * the AOE of Vet'ion - */ - VETION_LIGHTNING(ProjectileID.VETION_LIGHTNING, 3000, 1), - - /** - * the AOE of Chaos Fanatic - */ - CHAOS_FANATIC(ProjectileID.CHAOS_FANATIC_AOE, 3000, 1), - - /** - * the AOE of the Corporeal Beast - */ - - CORPOREAL_BEAST(ProjectileID.CORPOREAL_BEAST_AOE, 3000, 1), - CORPOREAL_BEAST_DARK_CORE(ProjectileID.CORPOREAL_BEAST_DARK_CORE_AOE, 3000, 3), - - /** - * the AOEs of The Great Olm - * missing ids and length, please help - */ - OLM_FALLING_CRYSTAL(1357, 3000, 3), - OLM_BURNING(1349, 2400, 1), - OLM_FALLING_CRYSTAL_TRAIL(1352, 2400, 1), - OLM_ACID_TRAIL(1354, 2400, 1), - OLM_FIRE_LINE(1347, 2400, 1), - - /** - * the AOE of the Wintertodt snow that falls - */ - WINTERTODT_SNOW_FALL(1310, 4000, 3); - - - /** - * The id of the projectile to trigger this AoE warning - */ - private final int id; - - /** - * How long the indicator should last for this AoE warning This might - * need to be a bit longer than the projectile actually takes to land as - * there is a fade effect on the warning - */ - private final Duration lifeTime; - - /** - * The size of the splash radius of the AoE warning Ex. Lizardman shaman - * AoE is a 3x3, so aoeSize = 3 - */ - private final int aoeSize; - - private static final Map map = new HashMap<>(); - - static - { - for (AoeProjectileInfo aoe : values()) - { - map.put(aoe.id, aoe); - } - } - - AoeProjectileInfo(int id, int lifeTimeMillis, int aoeSize) - { - this.id = id; - this.lifeTime = Duration.ofMillis(lifeTimeMillis); - this.aoeSize = aoeSize; - } - - public Duration getLifeTime() - { - return lifeTime; - } - - public int getId() - { - return id; - } - - public int getAoeSize() - { - return aoeSize; - } - - public static AoeProjectileInfo getById(int id) - { - return map.get(id); - } -} 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 deleted file mode 100644 index af1b361ec0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningConfig.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * 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.aoewarnings; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("aoe") -public interface AoeWarningConfig extends Config -{ - @ConfigItem( - keyName = "enabled", - name = "AoE Warnings Enabled", - description = "Configures whether or not AoE Projectile Warnings plugin is displayed" - ) - default boolean enabled() - { - return true; - } - - @ConfigItem( - keyName = "lizardmanaoe", - name = "Lizardman Shamans", - description = "Configures whether or not AoE Projectile Warnings for Lizardman Shamans is displayed" - ) - default boolean isShamansEnabled() - { - return true; - } - - @ConfigItem( - keyName = "archaeologistaoe", - name = "Crazy Archaeologist", - description = "Configures whether or not AoE Projectile Warnings for Archaeologist is displayed" - ) - default boolean isArchaeologistEnabled() - { - return true; - } - - @ConfigItem( - keyName = "icedemon", - name = "Ice Demon", - description = "Configures whether or not AoE Projectile Warnings for Ice Demon is displayed" - ) - default boolean isIceDemonEnabled() - { - return true; - } - - @ConfigItem( - keyName = "vasa", - name = "Vasa", - description = "Configures whether or not AoE Projectile Warnings for Vasa is displayed" - ) - default boolean isVasaEnabled() - { - return true; - } - - @ConfigItem( - keyName = "tekton", - name = "Tekton", - description = "Configures whether or not AoE Projectile Warnings for Tekton is displayed" - ) - default boolean isTektonEnabled() - { - return true; - } - - @ConfigItem( - keyName = "vorkath", - name = "Vorkath", - description = "Configures whether or not AoE Projectile Warnings for Vorkath are displayed" - ) - default boolean isVorkathEnabled() - { - return true; - } - - @ConfigItem( - keyName = "galvek", - name = "Galvek", - description = "Configures whether or not AoE Projectile Warnings for Galvek are displayed" - ) - default boolean isGalvekEnabled() - { - return true; - } - - @ConfigItem( - keyName = "gargboss", - name = "Gargoyle Boss", - description = "Configs whether or not AoE Projectile Warnings for Dawn/Dusk are displayed" - ) - default boolean isGargBossEnabled() - { - return true; - } - - @ConfigItem( - keyName = "vetion", - name = "Vet'ion", - description = "Configures whether or not AoE Projectile Warnings for Vet'ion are displayed" - ) - default boolean isVetionEnabled() - { - return true; - } - - @ConfigItem( - keyName = "chaosfanatic", - name = "Chaos Fanatic", - description = "Configures whether or not AoE Projectile Warnings for Chaos Fanatic are displayed" - ) - default boolean isChaosFanaticEnabled() - { - return true; - } - - @ConfigItem( - keyName = "olm", - name = "Great Olm", - description = "Configures whether or not AoE Projectile Warnings for The Great Olm are displayed" - ) - default boolean isOlmEnabled() - { - return true; - } - - @ConfigItem( - keyName = "bombDisplay", - name = "Display crystal phase bomb tracker", - description = "Display a timer and colour-coded AoE for Olm's crystal-phase bombs." - ) - default boolean bombDisplay() - { - return true; - } - - @ConfigItem( - keyName = "corp", - name = "Corporeal Beast", - description = "Configures whether or not AoE Projectile Warnings for the Corporeal Beast are displayed" - ) - default boolean isCorpEnabled() - { - return true; - } - - @ConfigItem( - keyName = "wintertodt", - name = "Wintertodt Snow Fall", - description = "Configures whether or not AOE Projectile Warnings for the Wintertodt snow fall are displayed" - ) - default boolean isWintertodtEnabled() - { - return true; - } - - @ConfigItem( - keyName = "outline", - name = "Display Outline", - description = "Configures whether or not AoE Projectile Warnings have an outline" - ) - default boolean isOutlineEnabled() - { - return true; - } - - @ConfigItem( - keyName = "lightning", - name = "Show Lightning Trails", - description = "Show Lightning Trails" - ) - default boolean LightningTrail() - { - return true; - } - - @ConfigItem( - keyName = "fade", - name = "Fade Warnings", - description = "Configures whether or not AoE Projectile Warnings fade over time" - ) - default boolean isFadeEnabled() - { - return true; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java deleted file mode 100644 index 7e6dd2409a..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * 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.aoewarnings; - -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Projectile; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; - -import javax.annotation.Nullable; -import javax.inject.Inject; -import java.awt.*; -import java.time.Instant; -import java.util.Iterator; -import java.util.Map; - -public class AoeWarningOverlay extends Overlay -{ - private static final int FILL_START_ALPHA = 25; - private static final int OUTLINE_START_ALPHA = 255; - - private final Client client; - private final AoeWarningPlugin plugin; - private final AoeWarningConfig config; - - @Inject - public AoeWarningOverlay(@Nullable Client client, AoeWarningPlugin plugin, AoeWarningConfig config) - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.UNDER_WIDGETS); - this.client = client; - this.plugin = plugin; - this.config = config; - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!config.enabled()) - { - return null; - } - for (WorldPoint point : plugin.getLightningTrail()) - { - drawTile(graphics, point, new Color(0,150,200), 2, 150, 50); - } - for (WorldPoint point : plugin.getAcidTrail()) - { - drawTile(graphics, point, new Color(69, 241, 44), 2, 150, 50); - } - for (WorldPoint point : plugin.getCrystalSpike()) - { - drawTile(graphics, point, new Color(255, 0, 84), 2, 150, 50); - } - - Instant now = Instant.now(); - Map projectiles = plugin.getProjectiles(); - for (Iterator it = projectiles.values().iterator(); it.hasNext();) - { - AoeProjectile aoeProjectile = it.next(); - - if (now.isAfter(aoeProjectile.getStartTime().plus(aoeProjectile.getAoeProjectileInfo().getLifeTime()))) - { - it.remove(); - continue; - } - - Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, aoeProjectile.getTargetPoint(), aoeProjectile.getAoeProjectileInfo().getAoeSize()); - if (tilePoly == null) - { - continue; - } - - // how far through the projectiles lifetime between 0-1. - double progress = (System.currentTimeMillis() - aoeProjectile.getStartTime().toEpochMilli()) / (double) aoeProjectile.getAoeProjectileInfo().getLifeTime().toMillis(); - - int fillAlpha, outlineAlpha; - if (config.isFadeEnabled()) - { - fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA);//alpha drop off over lifetime - outlineAlpha = (int) ((1 - progress) * OUTLINE_START_ALPHA); - } - else - { - fillAlpha = FILL_START_ALPHA; - outlineAlpha = OUTLINE_START_ALPHA; - } - - if (fillAlpha < 0) - { - fillAlpha = 0; - } - if (outlineAlpha < 0) - { - outlineAlpha = 0; - } - - if (fillAlpha > 255) - { - fillAlpha = 255; - } - if (outlineAlpha > 255) - { - outlineAlpha = 255;//Make sure we don't pass in an invalid alpha - } - - if (config.isOutlineEnabled()) - { - graphics.setColor(new Color(0, 150, 200, outlineAlpha)); - graphics.drawPolygon(tilePoly); - } - - graphics.setColor(new Color(0, 150, 200, fillAlpha)); - graphics.fillPolygon(tilePoly); - } - return null; - } - - private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) { - WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); - if (point.distanceTo(playerLocation) >= 32) { - return; - } - LocalPoint lp = LocalPoint.fromWorld(client, point); - if (lp == null) { - return; - } - - Polygon poly = Perspective.getCanvasTilePoly(client, lp); - if (poly == null) { - return; - } - //OverlayUtil.renderPolygon(graphics, poly, color); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); - graphics.setStroke(new BasicStroke(strokeWidth)); - graphics.draw(poly); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); - graphics.fill(poly); - } -} 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 deleted file mode 100644 index c3219d53b7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * 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.aoewarnings; - -import com.google.inject.Provides; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.GameObject; -import net.runelite.api.GameState; -import net.runelite.api.GraphicID; -import net.runelite.api.GraphicsObject; -import net.runelite.api.ObjectID; -import net.runelite.api.Projectile; -import net.runelite.api.Client; -import net.runelite.api.Tile; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.GameObjectDespawned; -import net.runelite.api.events.GameObjectSpawned; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.GraphicsObjectCreated; -import net.runelite.api.events.ProjectileMoved; -import net.runelite.client.Notifier; -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.ui.overlay.OverlayManager; - -import javax.inject.Inject; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Logger; - -@PluginDescriptor( - name = "!AoE Warnings", - description = "Shows the final destination for AoE Attack projectiles", - tags = {"bosses", "combat", "pve", "overlay"} -) - -@Slf4j -public class AoeWarningPlugin extends Plugin -{ - - @Inject - private OverlayManager overlayManager; - - @Inject - private AoeWarningOverlay coreOverlay; - - @Inject - public AoeWarningConfig config; - - @Inject - private BombOverlay bombOverlay; - - @Inject - private Client client; - - @Inject - private Notifier notifier; - - @Getter - private final Map bombs = new HashMap<>(); - @Getter(AccessLevel.PACKAGE) - private List LightningTrail = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private List AcidTrail = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private List CrystalSpike = new ArrayList<>(); - - - @Provides - AoeWarningConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(AoeWarningConfig.class); - } - - - private final Map projectiles = new HashMap<>(); - - public Map getProjectiles() - { - return projectiles; - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(coreOverlay); - overlayManager.add(bombOverlay); - LightningTrail.clear(); - AcidTrail.clear(); - CrystalSpike.clear(); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(coreOverlay); - overlayManager.remove(bombOverlay); - } - - @Subscribe - public void onProjectileMoved(ProjectileMoved event) - { - Projectile projectile = event.getProjectile(); - - int projectileId = projectile.getId(); - AoeProjectileInfo aoeProjectileInfo = AoeProjectileInfo.getById(projectileId); - if (aoeProjectileInfo != null && isConfigEnabledForProjectileId(projectileId)) - { - LocalPoint targetPoint = event.getPosition(); - AoeProjectile aoeProjectile = new AoeProjectile(Instant.now(), targetPoint, aoeProjectileInfo); - projectiles.put(projectile, aoeProjectile); - } - } - - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) - { - final GameObject gameObject = event.getGameObject(); - final WorldPoint bombLocation = gameObject.getWorldLocation(); - - switch (gameObject.getId()) - { - case ObjectID.CRYSTAL_BOMB: - bombs.put(bombLocation, new CrystalBomb(gameObject, client.getTickCount())); - break; - case ObjectID.ACID_POOL: - AcidTrail.add(bombLocation); - break; - case ObjectID.SMALL_CRYSTALS: - //todo - CrystalSpike.add(bombLocation); - break; - } - } - - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) - { - GameObject gameObject = event.getGameObject(); - WorldPoint bombLocation = gameObject.getWorldLocation(); - switch (gameObject.getId()) - { - case ObjectID.CRYSTAL_BOMB: - //might as well check the ObjectID to save some time. - purgeBombs(bombs); - break; - case ObjectID.ACID_POOL: - AcidTrail.remove(bombLocation); - break; - case ObjectID.SMALL_CRYSTALS: - //todo - CrystalSpike.remove(bombLocation); - break; - } - } - - @Subscribe - public void onGameStateChanged(GameStateChanged delta) - { - if (client.getGameState() == GameState.LOGGED_IN) - { - purgeBombs(bombs); - } - } - - @Subscribe - public void onGameTick(GameTick event) - { - if (config.LightningTrail()) - { - LightningTrail.clear(); - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == 1356) - { - LightningTrail.add(WorldPoint.fromLocal(client, o.getLocation())); - } - } - } - - Iterator> it = bombs.entrySet().iterator(); - - while (it.hasNext()) - { - Map.Entry entry = it.next(); - CrystalBomb bomb = entry.getValue(); - bomb.bombClockUpdate(); - //bombClockUpdate smooths the shown timer; not using this results in 1.2 --> .6 vs. 1.2 --> 1.1, etc. - } - } - - private void purgeBombs(Map bombs) - { - Iterator> it = bombs.entrySet().iterator(); - Tile[][][] tiles = client.getScene().getTiles(); - - while (it.hasNext()) - { - Map.Entry entry = it.next(); - WorldPoint world = entry.getKey(); - LocalPoint local = LocalPoint.fromWorld(client, world); - Tile tile = tiles[world.getPlane()][local.getSceneX()][local.getSceneY()]; - GameObject[] objects = tile.getGameObjects(); - boolean containsObjects = false; - - for (GameObject object : objects) - { - if (object != null) - { - containsObjects = true; - } - } - - if (!containsObjects) - { - it.remove(); - } - - } - } - - private boolean isConfigEnabledForProjectileId(int projectileId) - { - AoeProjectileInfo projectileInfo = AoeProjectileInfo.getById(projectileId); - if (projectileInfo == null) - { - return false; - } - - switch (projectileInfo) - { - case LIZARDMAN_SHAMAN_AOE: - return config.isShamansEnabled(); - case CRAZY_ARCHAEOLOGIST_AOE: - return config.isArchaeologistEnabled(); - case ICE_DEMON_RANGED_AOE: - case ICE_DEMON_ICE_BARRAGE_AOE: - return config.isIceDemonEnabled(); - case VASA_AWAKEN_AOE: - case VASA_RANGED_AOE: - return config.isVasaEnabled(); - case TEKTON_METEOR_AOE: - return config.isTektonEnabled(); - case VORKATH_BOMB: - case VORKATH_POISON_POOL: - case VORKATH_SPAWN: - case VORKATH_TICK_FIRE: - return config.isVorkathEnabled(); - case VETION_LIGHTNING: - return config.isVetionEnabled(); - case CHAOS_FANATIC: - return config.isChaosFanaticEnabled(); - case GALVEK_BOMB: - case GALVEK_MINE: - return config.isGalvekEnabled(); - case DAWN_FREEZE: - case DUSK_CEILING: - return config.isGargBossEnabled(); - case OLM_FALLING_CRYSTAL: - case OLM_BURNING: - case OLM_FALLING_CRYSTAL_TRAIL: - case OLM_ACID_TRAIL: - case OLM_FIRE_LINE: - return config.isOlmEnabled(); - case CORPOREAL_BEAST: - case CORPOREAL_BEAST_DARK_CORE: - return config.isCorpEnabled(); - case WINTERTODT_SNOW_FALL: - return config.isWintertodtEnabled(); - } - - return false; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java deleted file mode 100644 index 0ee6162a76..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2018, PallasDieKatze (Pallas Cat) - * 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.aoewarnings; - -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Player; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.aoewarnings.CrystalBomb; -import net.runelite.client.ui.overlay.*; -import javax.inject.Inject; -import java.awt.Graphics2D; -import java.awt.Dimension; -import java.awt.Color; -import java.awt.Polygon; -import java.awt.BasicStroke; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.time.Instant; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; - -@Slf4j -public class BombOverlay extends Overlay -{ - - private static final String SAFE = "#00cc00"; - //safe - private static final String CAUTION = "#ffff00"; - //1 tile in range (minor damage) - private static final String WARNING = "#ff9933"; - //2 tiles in range (moderate damage) - private static final String DANGER = "#ff6600"; - //3 tiles in range/adjacent to bomb (major damage) - private static final String LETHAL = "#cc0000"; - //On the bomb, using it as a makeshift space launch vehicle. (massive damage) - - private static final int BOMB_AOE = 7; - private static final int BOMB_DETONATE_TIME = 8; - //This is in ticks. It should be 10, but it varies from 8 to 11. - private static final double ESTIMATED_TICK_LENGTH = .6; - //Thank you Woox & co. for this assumption. .6 seconds/tick. - - - //Utilized from the npc highlight code for formatting text being displayed on the client canvas. - private static final NumberFormat TIME_LEFT_FORMATTER = - DecimalFormat.getInstance(Locale.US); - - static - { - ((DecimalFormat) TIME_LEFT_FORMATTER).applyPattern("#0.0"); - } - - private final Client client; - private final AoeWarningConfig config; - private final AoeWarningPlugin plugin; - - @Inject - public BombOverlay(Client client, AoeWarningPlugin plugin, AoeWarningConfig config) - { - this.client = client; - this.plugin = plugin; - this.config = config; - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (config.bombDisplay()) - { - drawBombs(graphics); - } - return null; - } - - private void drawBombs(Graphics2D graphics) - //I can condense drawDangerZone into this. Ambivalent though. - { - Iterator> it = plugin.getBombs().entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry entry = it.next(); - CrystalBomb bomb = entry.getValue(); - drawDangerZone(graphics, bomb); - } - } - - private void drawDangerZone(Graphics2D graphics, CrystalBomb bomb) - { - final Player localPlayer = client.getLocalPlayer(); - LocalPoint localLoc = LocalPoint.fromWorld(client, bomb.getWorldLocation()); - double distance_x = Math.abs(bomb.getWorldLocation().getX() - localPlayer.getWorldLocation().getX()); - double distance_y = Math.abs(bomb.getWorldLocation().getY() - localPlayer.getWorldLocation().getY()); - Color color_code = Color.decode(SAFE); - //defaults to this unless conditionals met below. - - if (distance_x < 1 && distance_y < 1) - { - color_code = Color.decode(LETHAL); - } - else if (distance_x < 2 && distance_y < 2) - { - color_code = Color.decode(DANGER); - } - else if (distance_x < 3 && distance_y < 3) - { - color_code = Color.decode(WARNING); - } - else if (distance_x < 4 && distance_y < 4) - { - color_code = Color.decode(CAUTION); - } - LocalPoint CenterPoint = new LocalPoint(localLoc.getX() + 0, localLoc.getY() + 0); - Polygon poly = Perspective.getCanvasTileAreaPoly(client, CenterPoint, BOMB_AOE); - - if (poly != null) - { - //manually generating the polygon so as to assign a custom alpha value. Request adtl' arg for alpha maybe? - graphics.setColor(color_code); - graphics.setStroke(new BasicStroke(1)); - graphics.drawPolygon(poly); - graphics.setColor(new Color(0, 0, 0, 10)); - graphics.fillPolygon(poly); - } - - Instant now = Instant.now(); - double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() - - bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) - - (now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0; - //divided by 1000.00 because of milliseconds :) - - timeLeft = Math.max(0.0, timeLeft); - String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft); - int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString); - int textHeight = graphics.getFontMetrics().getAscent(); - Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(), - localLoc.getY(), bomb.getWorldLocation().getPlane()); - - if (canvasPoint != null) - { - Point canvasCenterPoint = new Point( - canvasPoint.getX() - textWidth / 2, - canvasPoint.getY() + textHeight / 2); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code); - } - - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java deleted file mode 100644 index d138aed20c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2018, PallasDieKatze (Pallas Cat) - * 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.aoewarnings; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.GameObject; -import net.runelite.api.coords.WorldPoint; -import java.time.Instant; - -@Slf4j -public class CrystalBomb -{ - @Getter - private Instant plantedOn; - - @Getter - private Instant lastClockUpdate; - - @Getter - private int objectId; - - @Getter - private int tickStarted; - // - - @Getter - private WorldPoint worldLocation; - - public CrystalBomb(GameObject gameObject, int startTick) - { - this.plantedOn = Instant.now(); - this.objectId = gameObject.getId(); - this.worldLocation = gameObject.getWorldLocation(); - this.tickStarted = startTick; - } - - public void bombClockUpdate() - { - lastClockUpdate = Instant.now(); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultConfig.java index 1a0b8ef4ab..52d6a18af5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultConfig.java @@ -37,53 +37,17 @@ public interface BarbarianAssaultConfig extends Config name = "Show call change timer", description = "Show time to next call change" ) - default boolean showTimer() { return true; } + default boolean showTimer() + { + return true; + } @ConfigItem( keyName = "waveTimes", name = "Show wave and game duration", description = "Displays wave and game duration" - ) - default boolean waveTimes() { return true; } - @ConfigItem( - keyName = "showEggCountMessage", - name = "Show count of eggs collected as collector.", - description = "Display egg count as collector after each wave", - position = 0 - ) - default boolean showEggCount() { return false; } - - @ConfigItem( - keyName = "showEggCountOverlay", - name = "Overlay of eggs counted", - description = "Display current egg count as collector", - position = 1 - ) - default boolean showEggCountOverlay() { return false; } - - @ConfigItem( - keyName = "showHpCountMessage", - name = "Show count of Hp healed as healer.", - description = "Display healed count as healer after each wave", - position = 2 - ) - default boolean showHpCount() { return false; } - - @ConfigItem( - keyName = "showHpCountOverlay", - name = "Overlay of Hp counted", - description = "Display current healed count as healer", - position = 3 - ) - default boolean showHpCountOverlay() { return false; } - - - @ConfigItem( - keyName = "highlightCollectorEggs", - name = "Highlight collector eggs", - description = "Highlight called egg colors" ) - default boolean highlightCollectorEggs() + default boolean waveTimes() { return true; } 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..0fdf9edc2e 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 @@ -24,37 +24,24 @@ */ package net.runelite.client.plugins.barbarianassault; -import java.awt.BasicStroke; -import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; -import java.awt.Polygon; import java.awt.Rectangle; -import java.awt.Stroke; -import java.util.Map; import javax.inject.Inject; import lombok.Getter; import lombok.Setter; import net.runelite.api.Client; import net.runelite.api.GameState; import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; -import net.runelite.api.Perspective; -import net.runelite.api.Player; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldPoint; import net.runelite.api.widgets.Widget; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayUtil; class BarbarianAssaultOverlay extends Overlay { - private static final int MAX_EGG_DISTANCE = 2500; - private final Client client; private final BarbarianAssaultPlugin plugin; private final BarbarianAssaultConfig config; @@ -95,95 +82,12 @@ class BarbarianAssaultOverlay extends Overlay if (config.showTimer() && roleText != null && roleSprite != null) { - if (config.showEggCountOverlay() && role.equals(Role.COLLECTOR)) - { - roleText.setText(String.format("(%d) 00:%02d", plugin.getCollectedEggCount(), currentRound.getTimeToChange())); - } - else if (config.showHpCountOverlay() && role.equals(Role.HEALER)) - { - roleText.setText(String.format("(%d) 00:%02d", plugin.getHpHealed(), currentRound.getTimeToChange())); - } - else - { - roleText.setText(String.format("00:%02d", currentRound.getTimeToChange())); - } + roleText.setText(String.format("00:%02d", currentRound.getTimeToChange())); Rectangle spriteBounds = roleSprite.getBounds(); roleSprite.setHidden(true); graphics.drawImage(plugin.getClockImage(), spriteBounds.x, spriteBounds.y, null); } - if (role == Role.COLLECTOR && config.highlightCollectorEggs()) - { - String heardCall = plugin.getCollectorHeardCall(); - Color highlightColor; - Map calledEggMap; - - Map yellowEggMap = plugin.getYellowEggs(); - - switch (heardCall) - { - case "Red eggs": - calledEggMap = plugin.getRedEggs(); - highlightColor = Color.RED; - break; - case "Green eggs": - calledEggMap = plugin.getGreenEggs(); - highlightColor = Color.GREEN; - break; - case "Blue eggs": - calledEggMap = plugin.getBlueEggs(); - highlightColor = Color.BLUE; - break; - default: - calledEggMap = null; - highlightColor = null; - } - - if (calledEggMap != null) - { - for (WorldPoint worldPoint : calledEggMap.keySet()) - { - int quantity = calledEggMap.get(worldPoint); - renderEggLocation(graphics, worldPoint, quantity, highlightColor); - } - } - - // Always show yellow eggs - for (WorldPoint worldPoint : yellowEggMap.keySet()) - { - int quantity = yellowEggMap.get(worldPoint); - renderEggLocation(graphics, worldPoint, quantity, highlightColor); - } - } - return null; } - - private void renderEggLocation(Graphics2D graphics, WorldPoint location, int quantity, Color color) - { - LocalPoint groundPoint = LocalPoint.fromWorld(client, location); - Player player = client.getLocalPlayer(); - - if (groundPoint == null || player == null) - { - return; - } - - if (player.getLocalLocation().distanceTo(groundPoint) > MAX_EGG_DISTANCE) - { - return; - } - - Polygon poly = Perspective.getCanvasTilePoly(client, groundPoint); - final Stroke originalStroke = graphics.getStroke(); - - graphics.setColor(color); - graphics.setStroke(new BasicStroke(2)); - graphics.drawPolygon(poly); - graphics.setStroke(originalStroke); - - String quantityText = "x" + quantity; - Point textPoint = Perspective.getCanvasTextLocation(client, graphics, groundPoint, quantityText, 0); - OverlayUtil.renderTextLocation(graphics, textPoint, quantityText, Color.WHITE); - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java index 89ef526630..985ef626f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java @@ -28,23 +28,13 @@ package net.runelite.client.plugins.barbarianassault; import com.google.inject.Provides; import java.awt.Font; import java.awt.Image; -import java.util.HashMap; import javax.inject.Inject; -import lombok.Getter; -import lombok.AccessLevel; -import lombok.Getter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.ItemID; -import net.runelite.api.Player; -import net.runelite.api.Tile; import net.runelite.api.Varbits; -import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; -import net.runelite.api.events.ItemDespawned; -import net.runelite.api.events.ItemDespawned; -import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.kit.KitType; @@ -68,38 +58,18 @@ import net.runelite.client.util.ImageUtil; description = "Show a timer to the next call change and game/wave duration in chat.", tags = {"minigame", "overlay", "timer"} ) -public class BarbarianAssaultPlugin extends Plugin { +public class BarbarianAssaultPlugin extends Plugin +{ private static final int BA_WAVE_NUM_INDEX = 2; private static final String START_WAVE = "1"; private static final String ENDGAME_REWARD_NEEDLE_TEXT = "
5"; - @Getter - private int collectedEggCount = 0; - @Getter - private int HpHealed = 0; - @Getter - private int totalCollectedEggCount = 0; - @Getter - private int totalHpHealed = 0; - private Font font; private Image clockImage; private int inGameBit = 0; private String currentWave = START_WAVE; private GameTimer gameTime; - @Getter(AccessLevel.PACKAGE) - private HashMap redEggs; - - @Getter(AccessLevel.PACKAGE) - private HashMap greenEggs; - - @Getter(AccessLevel.PACKAGE) - private HashMap blueEggs; - - @Getter(AccessLevel.PACKAGE) - private HashMap yellowEggs; - @Inject private Client client; @@ -116,90 +86,74 @@ public class BarbarianAssaultPlugin extends Plugin { private BarbarianAssaultOverlay overlay; @Provides - BarbarianAssaultConfig provideConfig(ConfigManager configManager) { + BarbarianAssaultConfig provideConfig(ConfigManager configManager) + { return configManager.getConfig(BarbarianAssaultConfig.class); } @Override - protected void startUp() throws Exception { + protected void startUp() throws Exception + { overlayManager.add(overlay); font = FontManager.getRunescapeFont() - .deriveFont(Font.BOLD, 24); + .deriveFont(Font.BOLD, 24); clockImage = ImageUtil.getResourceStreamFromClass(getClass(), "clock.png"); - - redEggs = new HashMap<>(); - greenEggs = new HashMap<>(); - blueEggs = new HashMap<>(); - yellowEggs = new HashMap<>(); } @Override - protected void shutDown() throws Exception { + protected void shutDown() throws Exception + { overlayManager.remove(overlay); gameTime = null; currentWave = START_WAVE; inGameBit = 0; - collectedEggCount = 0; - HpHealed = 0; } @Subscribe - public void onWidgetLoaded(WidgetLoaded event) { - if (event.getGroupId() == WidgetID.BA_REWARD_GROUP_ID) { + public void onWidgetLoaded(WidgetLoaded event) + { + if (event.getGroupId() == WidgetID.BA_REWARD_GROUP_ID) + { Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT); - String amt,type,totalMsg,total; - amt=type=totalMsg=total=""; - if (config.waveTimes() && rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null) { - if (config.showHpCount() && HpHealed > 0) { - totalMsg = "; Total Healed: "; - total = ""+totalHpHealed; - } - else if (config.showEggCount() && collectedEggCount > 0) { - totalMsg = "; Total Collected: "; - total = ""+totalCollectedEggCount; - } - announceTime("Game finished, duration: ", gameTime.getTime(false),type, amt, totalMsg, total); + + if (config.waveTimes() && rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null) + { + announceTime("Game finished, duration: ", gameTime.getTime(false)); } } } @Subscribe - public void onChatMessage(ChatMessage event) { + public void onChatMessage(ChatMessage event) + { if (event.getType() == ChatMessageType.GAMEMESSAGE - && event.getMessage().startsWith("---- Wave:")) { + && event.getMessage().startsWith("---- Wave:")) + { String[] message = event.getMessage().split(" "); currentWave = message[BA_WAVE_NUM_INDEX]; - collectedEggCount = 0; - HpHealed = 0; - if (currentWave.equals(START_WAVE)) { + if (currentWave.equals(START_WAVE)) + { gameTime = new GameTimer(); - totalHpHealed = 0; - totalCollectedEggCount = 0; - } else if (gameTime != null) { - gameTime.setWaveStartTime(); } - } else if (event.getType() == ChatMessageType.GAMEMESSAGE - && event.getMessage().contains("egg explode")) { - collectedEggCount -= 2; - } else if (event.getType() == ChatMessageType.GAMEMESSAGE - && event.getMessage().contains("healed")) { - String message = event.getMessage(); - String[] tokens = message.split(" "); - if (Integer.parseInt(tokens[2]) > 0) { - int Hp = Integer.parseInt(tokens[2]); - HpHealed += Hp; + else if (gameTime != null) + { + gameTime.setWaveStartTime(); } } } @Subscribe - public void onGameTick(GameTick event) { - if (client.getVar(Varbits.IN_GAME_BA) == 0 || client.getLocalPlayer() == null || overlay.getCurrentRound() != null) { + public void onGameTick(GameTick event) + { + if (client.getVar(Varbits.IN_GAME_BA) == 0 || client.getLocalPlayer() == null || overlay.getCurrentRound() != null) + { return; } - switch (client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.CAPE)) { + + switch (client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.CAPE)) + { case ItemID.ATTACKER_ICON: overlay.setCurrentRound(new Round(Role.ATTACKER)); break; @@ -216,146 +170,39 @@ public class BarbarianAssaultPlugin extends Plugin { } @Subscribe - public void onVarbitChanged(VarbitChanged event) { + public void onVarbitChanged(VarbitChanged event) + { int inGame = client.getVar(Varbits.IN_GAME_BA); - String amt,type,totalMsg,total; - amt=type=totalMsg=total=""; - if (inGameBit != inGame) { - if (inGameBit == 1) { + + if (inGameBit != inGame) + { + if (inGameBit == 1) + { overlay.setCurrentRound(null); - if (config.waveTimes() && gameTime != null) { - totalCollectedEggCount += collectedEggCount; - totalHpHealed += HpHealed; - if (config.showHpCount() && HpHealed > 0) { - amt = "" + HpHealed; - type = "; Healed: "; - totalMsg = "; Total Healed: "; - total = ""+totalHpHealed; - } - else if (config.showEggCount() && collectedEggCount > 0) { - amt = "" + collectedEggCount; - type = "; Collected: "; - totalMsg = "; Total Collected: "; - total = ""+totalCollectedEggCount; - } - if (currentWave.equals("10")) - { - totalMsg=total=""; - } - announceTime("Wave " + currentWave + " duration: ", gameTime.getTime(true), type, amt, totalMsg, total); + if (config.waveTimes() && gameTime != null) + { + announceTime("Wave " + currentWave + " duration: ", gameTime.getTime(true)); } - } } inGameBit = inGame; } - @Subscribe - public void onItemSpawned(ItemSpawned itemSpawned) - { - int itemId = itemSpawned.getItem().getId(); - WorldPoint worldPoint = itemSpawned.getTile().getWorldLocation(); - HashMap eggMap = getEggMap(itemId); - - if (eggMap != null) - { - Integer existingQuantity = eggMap.putIfAbsent(worldPoint, 1); - if (existingQuantity != null) - { - eggMap.put(worldPoint, existingQuantity + 1); - } - } - } - - @Subscribe - public void onItemDespawned(ItemDespawned event) + private void announceTime(String preText, String time) { - if (client.getVar(Varbits.IN_GAME_BA) == 0 || !isEgg(event.getItem().getId())) - { - return; - } - if (isUnderPlayer(event.getTile())) - { - collectedEggCount++; - } - } - - String getCollectorHeardCall() - { - Widget widget = client.getWidget(WidgetInfo.BA_COLL_HEARD_TEXT); - String call = null; - - if (widget != null) - { - call = widget.getText(); - } - - return call; - } - - - private HashMap getEggMap(int itemID) - { - switch (itemID) - { - case ItemID.RED_EGG: - return redEggs; - case ItemID.GREEN_EGG: - return greenEggs; - case ItemID.BLUE_EGG: - return blueEggs; - case ItemID.YELLOW_EGG: - return yellowEggs; - default: - return null; - } - } - - - private void announceTime(String preText, String time, String type, String amt, String totalMsg, String total) { - - final String chatMessage = new ChatMessageBuilder() - .append(ChatColorType.NORMAL) - .append(preText) - .append(ChatColorType.HIGHLIGHT) - .append(time) - .append(ChatColorType.NORMAL) - .append(type) - .append(ChatColorType.HIGHLIGHT) - .append(amt) - .append(ChatColorType.NORMAL) - .append(totalMsg) - .append(ChatColorType.HIGHLIGHT) - .append(total) - .build(); + .append(ChatColorType.NORMAL) + .append(preText) + .append(ChatColorType.HIGHLIGHT) + .append(time) + .build(); chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.CONSOLE) - .runeLiteFormattedMessage(chatMessage) - .build()); - } - - private boolean isEgg(int itemID) - { - if (itemID == ItemID.RED_EGG || itemID == ItemID.GREEN_EGG - || itemID == ItemID.BLUE_EGG || itemID == ItemID.YELLOW_EGG) - { - return true; - } - return false; - } - - private boolean isUnderPlayer(Tile tile) { - Player local = client.getLocalPlayer(); - if (local == null) - { - return false; - } - - return (tile.getWorldLocation().equals(local.getWorldLocation())); + .type(ChatMessageType.CONSOLE) + .runeLiteFormattedMessage(chatMessage) + .build()); } public Font getFont() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsConfig.java deleted file mode 100644 index 64cf45dc8f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsConfig.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2018, Cameron - * Copyright (c) 2018, Jacob M - * 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.batools; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("BATools") -public interface BAToolsConfig extends Config -{ - @ConfigItem( - keyName = "defTimer", - name = "Defender Tick Timer", - description = "Shows the current cycle tick of runners." - ) - default boolean defTimer() - { - return false; - } - - @ConfigItem( - keyName = "calls", - name = "Remove Incorrect Calls", - description = "Remove incorrect calls." - ) - default boolean calls() - { - return false; - } - - @ConfigItem( - keyName = "swapLadder", - name = "Swap ladder option", - description = "Swap Climb-down with Quick-start in the wave lobbies" - ) - default boolean swapLadder() - { - return true; - } - - @ConfigItem( - keyName = "healerCodes", - name = "Healer Codes", - description = "Overlay to show healer codes" - ) - default boolean healerCodes() - { - return false; - } - - @ConfigItem( - keyName = "healerMenuOption", - name = "Healer menu options", - description = "asd" - ) - default boolean healerMenuOption() - { - return false; - } - - @ConfigItem( - keyName = "antiDrag", - name = "Anti Drag", - description = "asd" - ) - default boolean antiDrag() - { - return false; - } - - @ConfigItem( - keyName = "antiDragDelay", - name = "Anti Drag Delay", - description = "asd" - ) - default int antiDragDelay() - { - return 5; - } - - @ConfigItem( - keyName = "eggBoi", - name = "Collector helper", - description = "asd" - ) - default boolean eggBoi() - { - return false; - } - - @ConfigItem( - keyName = "osHelp", - name = "Shift OS", - description = "asd" - ) - default boolean osHelp() - { - return false; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsOverlay.java deleted file mode 100644 index 43a7bf4e7f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsOverlay.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.batools; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import net.runelite.api.NPCComposition; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.client.ui.overlay.OverlayUtil; -import net.runelite.client.ui.overlay.Overlay; -import java.time.Duration; -import java.time.Instant; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import lombok.extern.slf4j.Slf4j; -@Slf4j - -public class BAToolsOverlay extends Overlay -{ - private static final Color RED = new Color(221, 44, 0); - private static final Color GREEN = new Color(0, 200, 83); - private static final Color ORANGE = new Color(255, 109, 0); - private static final Color YELLOW = new Color(255, 214, 0); - private static final Color CYAN = new Color(0, 184, 212); - private static final Color BLUE = new Color(41, 98, 255); - private static final Color DEEP_PURPLE = new Color(98, 0, 234); - private static final Color PURPLE = new Color(170, 0, 255); - private static final Color GRAY = new Color(158, 158, 158); - - private final BAToolsConfig config; - private Client client; - private BAToolsPlugin plugin; - - @Inject - public BAToolsOverlay(Client client, BAToolsPlugin plugin, BAToolsConfig config) - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - this.config = config; - this.client = client; - this.plugin = plugin; - } - - - @Override - public Dimension render(Graphics2D graphics) - { - if(!config.healerCodes()) - { - return null; - } - - for (Healer healer : plugin.getHealers().values()) - { - NPCComposition composition = healer.getNpc().getComposition(); - Color color = composition.getCombatLevel() > 1 ? YELLOW : ORANGE; - if (composition.getConfigs() != null) - { - NPCComposition transformedComposition = composition.transform(); - if (transformedComposition == null) - { - color = GRAY; - } - else - { - composition = transformedComposition; - } - } - int timeLeft = healer.getLastFoodTime() - (int)Duration.between(plugin.getWave_start(), Instant.now()).getSeconds(); - timeLeft = timeLeft < 1 ? 0 : timeLeft; - - if(healer.getFoodRemaining() > 1) - { - color = GREEN; - } - else if(healer.getFoodRemaining() == 1) - { - if(timeLeft > 0) - { - color = RED; - } - else - { - color = GREEN; - } - } - else - { - continue; - } - - String text = String.format("%d %d", - healer.getFoodRemaining(), - timeLeft); - - - - OverlayUtil.renderActorOverlay(graphics, healer.getNpc(), text, color); - } - return null; - } -} \ No newline at end of file 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 deleted file mode 100644 index 7b9e195848..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsPlugin.java +++ /dev/null @@ -1,643 +0,0 @@ -/* - * Copyright (c) 2018, Cameron - * Copyright (c) 2018, Jacob M - * 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.batools; - -import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import java.awt.event.KeyEvent; -import java.awt.image.BufferedImage; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.inject.Inject; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Actor; -import net.runelite.api.ChatMessageType; -import net.runelite.api.Client; -import static net.runelite.api.Constants.CHUNK_SIZE; -import net.runelite.api.ItemID; -import net.runelite.api.MenuEntry; -import net.runelite.api.NPC; -import net.runelite.api.NpcID; -import net.runelite.api.Varbits; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.ChatMessage; -import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.HitsplatApplied; -import net.runelite.api.events.InteractingChanged; -import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.NpcDespawned; -import net.runelite.api.events.NpcSpawned; -import net.runelite.api.events.VarbitChanged; -import net.runelite.api.events.WidgetLoaded; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetID; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.game.ItemManager; -import net.runelite.client.input.KeyListener; -import net.runelite.client.input.KeyManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.ui.overlay.infobox.InfoBoxManager; -import net.runelite.client.util.Text; - -@Slf4j -@PluginDescriptor( - name = "BA Tools", - description = "Custom tools for Barbarian Assault", - tags = {"minigame", "overlay", "timer"} -) -public class BAToolsPlugin extends Plugin implements KeyListener -{ - int inGameBit = 0; - int tickNum; - int pastCall = 0; - private int currentWave = 1; - private static final int BA_WAVE_NUM_INDEX = 2; - private final List entries = new ArrayList<>(); - private HashMap foodPressed = new HashMap<>(); - private CycleCounter counter; - private Actor lastInteracted; - - private boolean shiftDown; - - @Inject - private Client client; - - @Inject - private ConfigManager configManager; - - @Inject - private ChatMessageManager chatMessageManager; - - @Inject - private OverlayManager overlayManager; - - @Inject - private BAToolsConfig config; - - @Inject - private ItemManager itemManager; - - @Inject - private InfoBoxManager infoBoxManager; - - @Inject - private BAToolsOverlay overlay; - - @Getter - private Map healers; - - @Getter - private Instant wave_start; - - @Inject - private KeyManager keyManager; - - - @Provides - BAToolsConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(BAToolsConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - healers = new HashMap<>(); - wave_start = Instant.now(); - lastInteracted = null; - foodPressed.clear(); - client.setInventoryDragDelay(config.antiDragDelay()); - keyManager.registerKeyListener(this); - } - - @Override - protected void shutDown() throws Exception - { - removeCounter(); - healers.clear(); - inGameBit = 0; - lastInteracted = null; - overlayManager.remove(overlay); - client.setInventoryDragDelay(5); - keyManager.unregisterKeyListener(this); - shiftDown = false; - } - - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) - { - switch (event.getGroupId()) - { - case WidgetID.BA_REWARD_GROUP_ID: - { - Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT); - - if (rewardWidget != null && rewardWidget.getText().contains("
5")) - { - tickNum = 0; - } - } - } - } - - @Subscribe - public void onGameTick(GameTick event) - { - if (config.antiDrag()) - { - client.setInventoryDragDelay(config.antiDragDelay()); - } - - Widget callWidget = getWidget(); - - if (callWidget != null) - { - if (callWidget.getTextColor() != pastCall && callWidget.getTextColor() == 16316664) - { - tickNum = 0; - } - pastCall = callWidget.getTextColor(); - } - if (inGameBit == 1) - { - if (tickNum > 9) - { - tickNum = 0; - } - if (counter == null) - { - addCounter(); - } - //counter.setText(String.valueOf(tickNum)); - counter.setCount(tickNum); - if (config.defTimer()) - { - log.info("" + tickNum++); - } - } - } - - private Widget getWidget() - { - if (client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT) != null) - { - return client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT); - } - else if (client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT) != null) - { - return client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT); - } - else if (client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT) != null) - { - return client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT); - } - else if (client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) != null) - { - return client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT); - } - return null; - } - - @Subscribe - public void onVarbitChanged(VarbitChanged event) - { - int inGame = client.getVar(Varbits.IN_GAME_BA); - - if (inGameBit != inGame) - { - if (inGameBit == 1) - { - pastCall = 0; - removeCounter(); - foodPressed.clear(); - } - else - { - addCounter(); - } - } - - inGameBit = inGame; - } - - @Subscribe - public void onChatMessage(ChatMessage event) - { - if (event.getType() == ChatMessageType.CONSOLE - && event.getMessage().startsWith("---- Wave:")) - { - String[] message = event.getMessage().split(" "); - currentWave = Integer.parseInt(message[BA_WAVE_NUM_INDEX]); - wave_start = Instant.now(); - healers.clear(); - } - } - - @Subscribe - public void onNpcSpawned(NpcSpawned event) - { - NPC npc = event.getNpc(); - - if (isNpcHealer(npc.getId())) - { - if (checkNewSpawn(npc) || Duration.between(wave_start, Instant.now()).getSeconds() < 16) - { - int spawnNumber = healers.size(); - healers.put(npc, new Healer(npc, spawnNumber, currentWave)); - log.info("spawn number: " + spawnNumber + " on wave " + currentWave); - } - } - } - - @Subscribe - public void onHitsplatApplied(HitsplatApplied hitsplatApplied) - { - Actor actor = hitsplatApplied.getActor(); - - if (healers.isEmpty() && !(actor instanceof NPC) && lastInteracted == null) - { - return; - } - - for (Healer healer : healers.values()) - { - if (healer.getNpc() == actor && actor == lastInteracted) - { - healer.setFoodRemaining(healer.getFoodRemaining() - 1); - } - } - } - - @Subscribe - public void onNpcDespawned(NpcDespawned event) - { - if (healers.remove(event.getNpc()) != null && healers.isEmpty()) - { - healers.clear(); - } - } - - @Subscribe - public void onInteractingChanged(InteractingChanged event) - { - Actor opponent = event.getTarget(); - - if (opponent != null && opponent instanceof NPC && isNpcHealer(((NPC) opponent).getId()) && event.getSource() != client.getLocalPlayer()) - { - lastInteracted = opponent; - } - } - - public static boolean isNpcHealer(int npcId) - { - return npcId == NpcID.PENANCE_HEALER || - npcId == NpcID.PENANCE_HEALER_5766 || - npcId == NpcID.PENANCE_HEALER_5767 || - npcId == NpcID.PENANCE_HEALER_5768 || - npcId == NpcID.PENANCE_HEALER_5769 || - npcId == NpcID.PENANCE_HEALER_5770 || - npcId == NpcID.PENANCE_HEALER_5771 || - npcId == NpcID.PENANCE_HEALER_5772 || - npcId == NpcID.PENANCE_HEALER_5773 || - npcId == NpcID.PENANCE_HEALER_5774; - } - - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) - { - if (config.calls() && getWidget() != null && event.getTarget().endsWith("horn") && !event.getTarget().contains("Unicorn")) - { - MenuEntry[] menuEntries = client.getMenuEntries(); - Widget callWidget = getWidget(); - String call = Calls.getOption(callWidget.getText()); - MenuEntry correctCall = null; - - entries.clear(); - for (MenuEntry entry : menuEntries) - { - String option = entry.getOption(); - if (option.equals(call)) - { - correctCall = entry; - } - else if (!option.startsWith("Tell-")) - { - entries.add(entry); - } - } - - if (correctCall != null) //&& callWidget.getTextColor()==16316664) - { - entries.add(correctCall); - client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()])); - } - } - else if (config.calls() && event.getTarget().endsWith("horn")) - { - entries.clear(); - client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()])); - } - - String option = Text.removeTags(event.getOption()).toLowerCase(); - String target = Text.removeTags(event.getTarget()).toLowerCase(); - - if (config.swapLadder() && option.equals("climb-down") && target.equals("ladder")) - { - swap("quick-start", option, target, true); - } - - if (inGameBit == 1 && config.healerMenuOption() && event.getTarget().contains("Penance Healer")) - { - - MenuEntry[] menuEntries = client.getMenuEntries(); - MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; - String targett = lastEntry.getTarget(); - - if (foodPressed.containsKey(lastEntry.getIdentifier())) - { - lastEntry.setTarget(lastEntry.getTarget().split("\\(")[0] + "(" + Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() + ")"); - if (Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() > 20) - { - lastEntry.setTarget(lastEntry.getTarget().replace("", "")); - } - } - else - { - lastEntry.setTarget(targett.replace("", "")); - - } - - client.setMenuEntries(menuEntries); - } - - if (client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT) != null && inGameBit == 1 && config.eggBoi() && event.getTarget().endsWith("egg") && shiftDown) - { - String[] currentCall = client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT).getText().split(" "); - log.info("1 " + currentCall[0]); - MenuEntry[] menuEntries = client.getMenuEntries(); - MenuEntry correctEgg = null; - entries.clear(); - - for (MenuEntry entry : menuEntries) - { - if (entry.getTarget().contains(currentCall[0]) && entry.getOption().equals("Take")) - { - correctEgg = entry; - } - } - if (correctEgg != null) - { - entries.add(correctEgg); - client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()])); - } - } - - if (client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT) != null && inGameBit == 1 && config.osHelp() && event.getTarget().equals("Healer item machine") && shiftDown) - { - String[] currentCall = client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT).getText().split(" "); - - if (!currentCall[0].contains("Pois.")) - { - return; - } - - MenuEntry[] menuEntries = client.getMenuEntries(); - MenuEntry correctEgg = null; - entries.clear(); - - for (MenuEntry entry : menuEntries) - { - if (entry.getOption().equals("Take-" + currentCall[1])) - { - correctEgg = entry; - } - } - if (correctEgg != null) - { - entries.add(correctEgg); - client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()])); - } - } - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (!config.healerMenuOption() || !event.getMenuTarget().contains("Penance Healer") || client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) == null) - { - return; - } - - String currentCall = client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT).getText(); - String target = event.getMenuTarget(); - - if ((currentCall.equals("Pois. Worms") && (target.contains("Poisoned worms") && target.contains("->") && target.contains("Penance Healer"))) - || (currentCall.equals("Pois. Meat") && (target.contains("Poisoned meat") && target.contains("->") && target.contains("Penance Healer"))) - || (currentCall.equals("Pois. Tofu") && (target.contains("Poisoned tofu") && target.contains("->") && target.contains("Penance Healer")))) - { - foodPressed.put(event.getId(), Instant.now()); - } - - if (target.contains("->") && target.contains("Penance Healer")) - { - foodPressed.put(event.getId(), Instant.now()); - } - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (config.antiDrag()) - { - client.setInventoryDragDelay(config.antiDragDelay()); - } - } - - - private void addCounter() - { - if (!config.defTimer() || counter != null) - { - return; - } - - int itemSpriteId = ItemID.FIGHTER_TORSO; - - BufferedImage taskImg = itemManager.getImage(itemSpriteId); - counter = new CycleCounter(taskImg, this, tickNum); - - infoBoxManager.addInfoBox(counter); - } - - private void removeCounter() - { - if (counter == null) - { - return; - } - - infoBoxManager.removeInfoBox(counter); - counter = null; - } - - private void swap(String optionA, String optionB, String target, boolean strict) - { - MenuEntry[] entries = client.getMenuEntries(); - - int idxA = searchIndex(entries, optionA, target, strict); - int idxB = searchIndex(entries, optionB, target, strict); - - if (idxA >= 0 && idxB >= 0) - { - MenuEntry entry = entries[idxA]; - entries[idxA] = entries[idxB]; - entries[idxB] = entry; - - client.setMenuEntries(entries); - } - } - - private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict) - { - for (int i = entries.length - 1; i >= 0; i--) - { - MenuEntry entry = entries[i]; - String entryOption = Text.removeTags(entry.getOption()).toLowerCase(); - String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase(); - - if (strict) - { - if (entryOption.equals(option) && entryTarget.equals(target)) - { - return i; - } - } - else - { - if (entryOption.contains(option.toLowerCase()) && entryTarget.equals(target)) - { - return i; - } - } - } - - return -1; - } - - private static WorldPoint rotate(WorldPoint point, int rotation) - { - int chunkX = point.getX() & ~(CHUNK_SIZE - 1); - int chunkY = point.getY() & ~(CHUNK_SIZE - 1); - int x = point.getX() & (CHUNK_SIZE - 1); - int y = point.getY() & (CHUNK_SIZE - 1); - switch (rotation) - { - case 1: - return new WorldPoint(chunkX + y, chunkY + (CHUNK_SIZE - 1 - x), point.getPlane()); - case 2: - return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - x), chunkY + (CHUNK_SIZE - 1 - y), point.getPlane()); - case 3: - return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - y), chunkY + x, point.getPlane()); - } - return point; - } - - private boolean checkNewSpawn(NPC npc) - { - int regionId = 7509; - int regionX = 42; - int regionY = 46; - int z = 0; - - // world point of the tile marker - WorldPoint worldPoint = new WorldPoint( - ((regionId >>> 8) << 6) + regionX, - ((regionId & 0xff) << 6) + regionY, - z - ); - - int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks(); - for (int x = 0; x < instanceTemplateChunks[z].length; ++x) - { - for (int y = 0; y < instanceTemplateChunks[z][x].length; ++y) - { - int chunkData = instanceTemplateChunks[z][x][y]; - int rotation = chunkData >> 1 & 0x3; - int templateChunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE; - int templateChunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE; - if (worldPoint.getX() >= templateChunkX && worldPoint.getX() < templateChunkX + CHUNK_SIZE - && worldPoint.getY() >= templateChunkY && worldPoint.getY() < templateChunkY + CHUNK_SIZE) - { - WorldPoint p = new WorldPoint(client.getBaseX() + x * CHUNK_SIZE + (worldPoint.getX() & (CHUNK_SIZE - 1)), - client.getBaseY() + y * CHUNK_SIZE + (worldPoint.getY() & (CHUNK_SIZE - 1)), - worldPoint.getPlane()); - p = rotate(p, rotation); - if (p.distanceTo(npc.getWorldLocation()) < 5) - { - return true; - } - } - } - } - return false; - } - - @Override - public void keyTyped(KeyEvent e) - { - } - - @Override - public void keyPressed(KeyEvent e) - { - if (e.getKeyCode() == KeyEvent.VK_SHIFT) - { - shiftDown = true; - } - } - - @Override - public void keyReleased(KeyEvent e) - { - if (e.getKeyCode() == KeyEvent.VK_SHIFT) - { - shiftDown = false; - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/Calls.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/Calls.java deleted file mode 100644 index 0c273f5be5..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/batools/Calls.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2018, Cameron - * 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.batools; - -import java.util.HashMap; -import java.util.Map; - -public enum Calls -{ - //Attacker Calls - RED_EGG("Red egg", "Tell-red"), - GREEN_EGG("Green egg", "Tell-green"), - BLUE_EGG("Blue egg", "Tell-blue"), - //Collector Calls - CONTROLLED("Controlled/Bullet/Wind", "Tell-controlled"), - ACCURATE("Accurate/Field/Water", "Tell-accurate"), - AGGRESSIVE("Aggressive/Blunt/Earth", "Tell-aggressive"), - DEFENSIVE("Defensive/Barbed/Fire", "Tell-defensive"), - //Healer Calls - TOFU("Tofu", "Tell-tofu"), - CRACKERS("Crackers", "Tell-crackers"), - WORMS("Worms", "Tell-worms"), - //Defender Calls - POIS_WORMS("Pois. Worms", "Tell-worms"), - POIS_TOFU("Pois. Tofu", "Tell-tofu"), - POIS_MEAT("Pois. Meat", "Tell-meat"); - - private final String call; - private final String option; - - private static final Map CALL_MENU = new HashMap<>(); - - static - { - for (Calls s : values()) - { - CALL_MENU.put(s.getCall(), s.getOption()); - } - } - - Calls(String call, String option) - { - this.call = call; - this.option = option; - } - - public String getCall() - { - return call; - } - - public String getOption() - { - return option; - } - - public static String getOption(String call) - { - return CALL_MENU.get(call); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/CycleCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/CycleCounter.java deleted file mode 100644 index e8f6e3e639..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/batools/CycleCounter.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.runelite.client.plugins.batools; - -import net.runelite.client.plugins.Plugin; -import net.runelite.client.ui.overlay.infobox.Counter; - -import java.awt.image.BufferedImage; - -public class CycleCounter extends Counter -{ - public CycleCounter(BufferedImage img, Plugin plugin, int tick) - { - super(img, plugin, tick); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/Healer.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/Healer.java deleted file mode 100644 index 9fb07e90e8..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/batools/Healer.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.runelite.client.plugins.batools; - - -import lombok.Getter; -import lombok.Setter; - -import net.runelite.api.NPC; -import net.runelite.api.Actor; - - -public class Healer -{ - - @Getter - private NPC npc; - - @Getter - @Setter - private int wave; - - @Getter - @Setter - private int spawnNumber; - - @Getter - @Setter - private int foodRemaining; - - @Getter - @Setter - private int lastFoodTime; - - @Getter - @Setter - private int firstCallFood; - - @Getter - @Setter - private int secondCallFood; - - - - public Healer(NPC npc, int spawnNumber, int wave) - { - this.npc = npc; - this.wave = wave; - this.spawnNumber = spawnNumber; - this.firstCallFood = getCode(wave).getFirstCallFood()[spawnNumber]; - this.secondCallFood = getCode(wave).getSecondCallFood()[spawnNumber]; - this.foodRemaining = firstCallFood + secondCallFood; - this.lastFoodTime = getCode(wave).getSpacing()[spawnNumber]; - } - - private HealerCode getCode(int wave) - { - switch(wave) - { - case 1: - return HealerCode.WAVEONE; - case 2: - return HealerCode.WAVETWO; - case 3: - return HealerCode.WAVETHREE; - case 4: - return HealerCode.WAVEFOUR; - case 5: - return HealerCode.WAVEFIVE; - case 6: - return HealerCode.WAVESIX; - case 7: - return HealerCode.WAVESEVEN; - case 8: - return HealerCode.WAVEEIGHT; - case 9: - return HealerCode.WAVENINE; - case 10: - return HealerCode.WAVETEN; - default: return null; - } - } - - - -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/HealerCode.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/HealerCode.java deleted file mode 100644 index ee7f492585..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/batools/HealerCode.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.runelite.client.plugins.batools; - -import lombok.Getter; - - -enum HealerCode -{ - - WAVEONE(new int[] {1,1}, new int[] {0,0}, new int[] {0,0}), - WAVETWO(new int[] {1,1,2}, new int[] {0,0,0}, new int[] {0,0,21}), - WAVETHREE(new int[] {1,6,2}, new int[] {0,0,0}, new int[] {0,0,0}), - WAVEFOUR(new int[] {2,5,2,0}, new int[] {0,0,7,10}, new int[] {0,0,0,0}), - WAVEFIVE(new int[] {2,5,2,3,0}, new int[] {0,0,0,0,7}, new int[] {0,0,21,30,0}), - WAVESIX(new int[] {3,5,3,1,0,0}, new int[] {0,0,0,2,9,10}, new int[] {18,0,0,0,0,0}), - WAVESEVEN(new int[] {5,2,1,1,0,0,0}, new int[] {0,0,0,0,6,8,10}, new int[] {27,33,0,0,51,0,0}), - WAVEEIGHT(new int[] {2,8,1,1,0,0,0}, new int[] {1,0,1,1,3,1,10}, new int[] {36,0,33,39,45,48,0}), - WAVENINE(new int[] {2,8,1,1,0,0,0,0}, new int[] {1,1,1,1,1,1,1,10}, new int[] {0,21,0,0,0,0,0,0,0}), - WAVETEN(new int[] {5,2,1,1,0,0,0}, new int[] {0,1,1,1,3,3,10}, new int[] {27,33,0,0,51,0,0}); - - - @Getter - private final int[] firstCallFood; - @Getter - private final int[] secondCallFood; - @Getter - private final int[] spacing; - - HealerCode(int[] firstCallFood, int[] secondCallFood, int[] spacing) - { - this.firstCallFood = firstCallFood; - this.secondCallFood = secondCallFood; - this.spacing = spacing; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonConfig.java index 15f50725e6..29a1496f85 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonConfig.java @@ -83,24 +83,4 @@ public interface CannonConfig extends Config { return true; } - - @ConfigItem( - keyName = "ammoAmount", - name = "Ammo left", - description = "Configure to set the amount of ammo left to receive ammo left notification" - ) - default int ammoAmount() - { - return 5; - } - - @ConfigItem( - keyName = "notifyAmmoLeft", - name = "Ammo left notification", - description = "Sends a notification when cannon ammo is under the specified amount" - ) - default boolean notifyAmmoLeft() - { - return true; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java index 9e7b460fa5..de44d67c59 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java @@ -46,7 +46,12 @@ import net.runelite.api.Projectile; import static net.runelite.api.ProjectileID.CANNONBALL; import static net.runelite.api.ProjectileID.GRANITE_CANNONBALL; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.*; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameObjectSpawned; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.ItemContainerChanged; +import net.runelite.api.events.ProjectileMoved; import net.runelite.client.Notifier; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; @@ -270,7 +275,6 @@ public class CannonPlugin extends Plugin if (!skipProjectileCheckThisTick) { cballsLeft--; - client.getCallbacks().post(new CannonballFired()); } } } @@ -375,13 +379,6 @@ public class CannonPlugin extends Plugin { return Color.orange; } - else if (cballsLeft <= config.ammoAmount()) - { - if (config.notifyAmmoLeft()) - { - notifier.notify("Your cannon has " + config.ammoAmount() + " balls left!"); - } - } return Color.red; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java index f60f143f06..5fdd7996be 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java @@ -126,37 +126,4 @@ public interface ClanChatConfig extends Config { return false; } - - @ConfigItem( - keyName = "discord", - name = "Discord", - description = "Send clan chats to a discord webhook
See https://support.discordapp.com/hc/en-us/articles/228383668", - position = 8 - ) - default boolean discord() - { - return false; - } - - @ConfigItem( - keyName = "discordPath", - name = "Webhook path", - description = "Your webhook id and webhook token
(the part after \"/webhooks/\")", - position = 9 - ) - default String discordPath() - { - return ""; - } - - @ConfigItem( - keyName = "discordAccount", - name = "Discord/RS account", - description = "The login username (not rsn!) of the runescape account you want to use this on", - position = 10 - ) - default String discordAccount() - { - return ""; - } } 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 e9cf3d698b..506c9a58c0 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 @@ -39,7 +39,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import javax.inject.Inject; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatLineBuffer; import net.runelite.api.ChatMessageType; import net.runelite.api.ClanMember; @@ -73,22 +72,18 @@ 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 net.runelite.client.plugins.clanchat.discord.DiscordClient; -import net.runelite.client.plugins.clanchat.discord.DiscordMessage; 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 static net.runelite.client.util.Text.removeTags; @PluginDescriptor( name = "Clan Chat", description = "Add rank icons to users talking in clan chat", tags = {"icons", "rank", "recent"} ) -@Slf4j public class ClanChatPlugin extends Plugin { private static final int MAX_CHATS = 10; @@ -118,9 +113,6 @@ public class ClanChatPlugin extends Plugin private List chats = new ArrayList<>(); private List clanMembers = new ArrayList<>(); private ClanChatIndicator clanMemberCounter; - - private DiscordClient discordClient; - /** * queue of temporary messages added to the client */ @@ -146,7 +138,6 @@ public class ClanChatPlugin extends Plugin clanMembers.clear(); removeClanCounter(); resetClanChats(); - stopDiscordClient(); } @Subscribe @@ -167,15 +158,6 @@ public class ClanChatPlugin extends Plugin { removeClanCounter(); } - - if (config.discord()) - { - startDiscordClient(); - } - else - { - stopDiscordClient(); - } } } @@ -303,38 +285,6 @@ public class ClanChatPlugin extends Plugin addClanActivityMessages(); } - private void submitMessage(String message, String user, String url) - { - if (discordClient == null) - { - return; - } - - DiscordMessage discordMessage = new DiscordMessage(); - - message = removeTags(message); - if (!user.contains("") && !user.contains("")) - { - discordMessage.setContent(message); - } - else if (user.contains("img=10")) - { - discordMessage.setContent("<:hcim:557056153834487819> " + message); - } - else - { - discordMessage.setContent("<:iron:557056153729630209> " + message); - } - discordMessage.setUsername(removeTags(user)); - discordMessage.setAvatar_url(url); - - discordClient.submit(discordMessage, config.discordPath()); - } - private void submitMessage(String message) - { - submitMessage(message, "", ""); - } - private void timeoutClanMessages() { if (clanJoinMessages.isEmpty()) @@ -396,7 +346,7 @@ public class ClanChatPlugin extends Plugin private void addActivityMessage(ClanMember member, ClanActivityType activityType) { - final String activityMessage = activityType == ClanActivityType.JOINED ? " has joined. " : " has left. "; + 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; @@ -408,7 +358,7 @@ public class ClanChatPlugin extends Plugin channelColor = CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND; } - if (config.clanChatIcons() && rank != ClanMemberRank.UNRANKED) + if (config.clanChatIcons() && rank != null && rank != ClanMemberRank.UNRANKED) { rankIcon = clanManager.getIconNumber(rank); } @@ -428,10 +378,6 @@ public class ClanChatPlugin extends Plugin final String messageString = message.build(); client.addChatMessage(ChatMessageType.FRIENDSCHATNOTIFICATION, "", messageString, ""); - if (discordClient != null) - { - submitMessage(member.getUsername() + activityMessage + client.getClanChatCount() + " people online."); - } final ChatLineBuffer chatLineBuffer = client.getChatLineMap().get(ChatMessageType.FRIENDSCHATNOTIFICATION.getType()); final MessageNode[] lines = chatLineBuffer.getLines(); @@ -453,7 +399,12 @@ public class ClanChatPlugin extends Plugin @Subscribe public void onChatMessage(ChatMessage chatMessage) { - if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN || client.getClanChatCount() <= 0) + if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + if (client.getClanChatCount() <= 0) { return; } @@ -475,12 +426,6 @@ public class ClanChatPlugin extends Plugin } break; case FRIENDSCHAT: - if (discordClient != null) - { - String url = clanManager.getRank(chatMessage.getName()).getDiscavatar(); - submitMessage(chatMessage.getMessage(), chatMessage.getName(), url); - } - if (!config.clanChatIcons()) { return; @@ -502,12 +447,8 @@ public class ClanChatPlugin extends Plugin { clanMembers.clear(); removeClanCounter(); - clanJoinMessages.clear(); - if (gameState == GameState.LOGIN_SCREEN) - { - stopDiscordClient(); - } + clanJoinMessages.clear(); } } @@ -536,11 +477,6 @@ public class ClanChatPlugin extends Plugin if (event.isJoined()) { clanJoinedTick = client.getTickCount(); - - if (config.discord()) - { - startDiscordClient(); - } } else { @@ -659,22 +595,4 @@ public class ClanChatPlugin extends Plugin clanMemberCounter = new ClanChatIndicator(image, this); infoBoxManager.addInfoBox(clanMemberCounter); } - - private void startDiscordClient() - { - if (discordClient == null && config.discordAccount().equals(client.getUsername())) - { - discordClient = new DiscordClient(); - submitMessage("Started\n\n" + client.getLocalPlayer().getName() + " has joined."); - } - } - - private void stopDiscordClient() - { - if (discordClient != null) - { - submitMessage(client.getLocalPlayer().getName() + " has left.\n\nStopped"); - discordClient = null; - } - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/discord/DiscordClient.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/discord/DiscordClient.java deleted file mode 100644 index ec523710e1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/discord/DiscordClient.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.runelite.client.plugins.clanchat.discord; - -import com.google.gson.Gson; -import java.io.IOException; -import static java.lang.Integer.parseInt; -import java.time.Instant; -import lombok.extern.slf4j.Slf4j; -import net.runelite.http.api.RuneLiteAPI; -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; - -@Slf4j -public class DiscordClient -{ - private static final MediaType JSON = MediaType.parse("application/json"); - private static final Gson GSON = RuneLiteAPI.GSON; - private int rateLimit = 1; - private Instant rateReset = Instant.EPOCH; - - public void submit(DiscordMessage message, String path) - { - if (rateLimit < 1 && Instant.now().isBefore(rateReset)) - { - return; - } - - final HttpUrl url = new HttpUrl.Builder() - .scheme("https") - .host("discordapp.com") - .addPathSegments("api/webhooks") - .addPathSegments(path) - .build(); - - Request request = new Request.Builder() - .post(RequestBody.create(JSON, GSON.toJson(message))) - .url(url) - .build(); - - RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback() - { - @Override - public void onFailure(Call call, IOException e) - { - log.debug("discord message failed", e); - } - - @Override - public void onResponse(Call call, Response response) - { - rateLimit = parseInt(response.header("X-RateLimit-Remaining")); - rateReset = Instant.ofEpochSecond((parseInt(response.header("X-RateLimit-Reset")))); - log.debug("Submitted discord message, limit: {}, reset: {}", rateLimit, rateReset); - response.close(); - } - }); - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/discord/DiscordMessage.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/discord/DiscordMessage.java deleted file mode 100644 index f4f037824c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/discord/DiscordMessage.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.runelite.client.plugins.clanchat.discord; - -import lombok.Data; - -@Data -public class DiscordMessage -{ - private String username; - private String content; - private String avatar_url; -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeConfig.java deleted file mode 100644 index 3f2d8da467..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeConfig.java +++ /dev/null @@ -1,168 +0,0 @@ -package net.runelite.client.plugins.clanmanmode; - -import java.awt.Color; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("clanmanmode") -public interface ClanManModeConfig extends Config -{ - @ConfigItem( - position = 0, - keyName = "highlightattackable", - name = "Highlight attackable targets", - description = "Highlights targets attackable by all clan members" - ) - default boolean highlightAttackable() - { - return false; - } - - @ConfigItem( - position = 1, - keyName = "attackablecolor", - name = "Attackable target c olor", - description = "Color of targets all clan members can target" - ) - default Color getAttackableColor() - { - return new Color(0, 184, 212); - } - - @ConfigItem( - position = 2, - keyName = "highlightattacked", - name = "Highlight clan targets", - description = "Highlights people being attacked by your clan" - ) - default boolean highlightAttacked() - { - return false; - } - - @ConfigItem( - position = 3, - keyName = "attackedcolor", - name = "Clan target color", - description = "Color of players being attacked by clan" - ) - default Color getClanAttackableColor() - { - return new Color(0, 184, 212); - } - - @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 = "drawOverheadPlayerNames", - name = "Draw names above players", - description = "Configures whether or not player names should be drawn above players" - ) - default boolean drawOverheadPlayerNames() - { - return true; - } - - @ConfigItem( - position = 6, - keyName = "drawMinimapNames", - name = "Draw names on minimap", - description = "Configures whether or not minimap names for players with rendered names should be drawn" - ) - default boolean drawMinimapNames() - { - return false; - } - - @ConfigItem( - position = 7, - keyName = "showtargets", - name = "Highlight My Attackers", - description = "Shows players interacting with you" - ) - default boolean showAttackers() - { - return false; - } - - @ConfigItem( - position = 8, - keyName = "attackcolor", - name = "Attacker Color", - description = "Color of attackers" - ) - default Color getAttackerColor() - { - return new Color(255, 0, 0); - } - - @ConfigItem( - position = 9, - keyName = "showbold", - name = "Bold names of clan targets", - description = "Turns names of clan targets bold" - ) - default boolean ShowBold() { return false; } - - @ConfigItem( - position = 10, - keyName = "hideafter", - name = "Hide attackable targets after login", - description = "Automatically disables attackable player highlighting after login" - ) - default boolean hideAttackable() { return false; } - - @ConfigItem( - position = 11, - keyName = "hidetime", - name = "Ticks to hide", - description = "How many ticks after you are logged in that attackbles are hidden (1 tick = 0.6 seconds)" - ) - default int hideTime() { return 5; } - - @ConfigItem( - position = 12, - keyName = "mycblvl", - name = "Calc targets on my own combat level", - description = "Calculates potential targets based off your own combat lvl instead of clans" - ) - default boolean CalcSelfCB() { return false; } - - @ConfigItem( - position = 13, - keyName = "hideatkopt", - name = "Hide attack option for clan members", - description = "Disables attack option for clan members" - ) - default boolean hideAtkOpt() { return false; } - - @ConfigItem( - position = 14, - keyName = "showclanmembers", - name = "Persistent Clan Members", - description = "Will highlight clan members even when not in clan chat" - ) - default boolean PersistentClan() { return false; } - - @ConfigItem( - position = 15, - keyName = "clancolor", - name = "Clan Member Color", - description = "Color of clan members" - ) - default Color getClanMemberColor() - { - return new Color(255, 0, 0); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeMinimapOverlay.java deleted file mode 100644 index be94ee06f3..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeMinimapOverlay.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.runelite.client.plugins.clanmanmode; - -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 ClanManModeMinimapOverlay extends Overlay -{ - private final ClanManModeService ClanManModeService; - private final ClanManModeConfig config; - - @Inject - private ClanManModeMinimapOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService) - { - this.config = config; - this.ClanManModeService = ClanManModeService; - setLayer(OverlayLayer.ABOVE_WIDGETS); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGH); - } - - @Override - public Dimension render(Graphics2D graphics) - { - ClanManModeService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); - return null; - } - - private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) - { - final String name = actor.getName().replace('\u00A0', ' '); - - if (config.drawMinimapNames()) - { - final net.runelite.api.Point minimapLocation = actor.getMinimapLocation(); - - if (minimapLocation != null) - { - OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeOverlay.java deleted file mode 100644 index ff058f675c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeOverlay.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.runelite.client.plugins.clanmanmode; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import javax.inject.Inject; -import javax.inject.Singleton; -import net.runelite.api.ClanMemberRank; -import net.runelite.api.Player; -import net.runelite.api.Point; -import net.runelite.client.game.ClanManager; -import net.runelite.client.ui.FontManager; -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 ClanManModeOverlay extends Overlay -{ - private final ClanManModeService ClanManModeService; - private final ClanManModeConfig config; - private final ClanManager clanManager; - - @Inject - private ClanManModeOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService, - ClanManager clanManager) - { - this.config = config; - this.ClanManModeService = ClanManModeService; - this.clanManager = clanManager; - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) - { - ClanManModeService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); - return null; - } - - private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) - { - if (!config.drawOverheadPlayerNames()) - { - return; - } - - String name = actor.getName().replace('\u00A0', ' '); - int offset = actor.getLogicalHeight() + 40; - Point textLocation = actor.getCanvasTextLocation(graphics, name, offset); - - if (textLocation != null) - { - if (config.getClanAttackableColor().equals(color) && config.ShowBold()) { - graphics.setFont(FontManager.getRunescapeBoldFont()); - } - OverlayUtil.renderTextLocation(graphics, textLocation, name, color); - } - } -} 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 deleted file mode 100644 index d71d054674..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java +++ /dev/null @@ -1,137 +0,0 @@ -package net.runelite.client.plugins.clanmanmode; - -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.inject.Inject; -import net.runelite.api.*; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.MenuEntryAdded; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.game.ClanManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.Text; -import org.apache.commons.lang3.ArrayUtils; - -@PluginDescriptor( - name = "!Clan Man Mode", - description = "Assists in clan PVP scenarios", - tags = {"highlight", "minimap", "overlay", "players"} -) -public class ClanManModePlugin extends Plugin -{ - @Inject - private OverlayManager overlayManager; - - @Inject - private ClanManModeConfig config; - - @Inject - private ClanManModeOverlay ClanManModeOverlay; - - @Inject - private ClanManModeTileOverlay ClanManModeTileOverlay; - - @Inject - private ClanManModeMinimapOverlay ClanManModeMinimapOverlay; - - @Inject - private Client client; - - @Inject - private ClanManager clanManager; - - @Provides - ClanManModeConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(ClanManModeConfig.class); - } - - int wildernessLevel; - int clanmin; - int clanmax; - int inwildy; - int ticks; - Map clan = new HashMap<>(); - - @Override - protected void startUp() throws Exception { - overlayManager.add(ClanManModeOverlay); - overlayManager.add(ClanManModeTileOverlay); - overlayManager.add(ClanManModeMinimapOverlay); - } - - @Override - protected void shutDown() throws Exception { - overlayManager.remove(ClanManModeOverlay); - overlayManager.remove(ClanManModeTileOverlay); - overlayManager.remove(ClanManModeMinimapOverlay); - clan.clear(); - ticks = 0; - wildernessLevel = 0; - clanmin = 0; - clanmax = 0; - inwildy = 0; - } - - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) { - if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN || gameStateChanged.getGameState() == GameState.HOPPING) { - ticks = 0; - } - } - - @Subscribe - public void onGameTick(GameTick event) { - ticks++; - final Player localPlayer = client.getLocalPlayer(); - if (!clan.containsKey(localPlayer.getName())) { - clan.put(localPlayer.getName(), localPlayer.getCombatLevel()); - } - WorldPoint a = localPlayer.getWorldLocation(); - int underLevel = ((a.getY() - 9920) / 8) + 1; - int upperLevel = ((a.getY() - 3520) / 8) + 1; - wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel; - inwildy = client.getVar(Varbits.IN_WILDERNESS); - if (clan.size() > 0) { - clanmin = Collections.min(clan.values()); - clanmax = Collections.max(clan.values()); - } - } - - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) { - if (!config.hideAtkOpt()) { - return; - } - if (client.getGameState() != GameState.LOGGED_IN) { - return; - } - - final String option = Text.removeTags(event.getOption()).toLowerCase(); - - if (option.equals("attack")) { - final Pattern ppattern = Pattern.compile("(.+?) interactors = new HashMap<>(); - - public void forEachPlayer(final BiConsumer consumer) - { - int minatk = plugin.clanmax - plugin.wildernessLevel; - int maxatk = plugin.clanmin + plugin.wildernessLevel; - final Player localPlayer = client.getLocalPlayer(); - final String localName = localPlayer.getName(); - int selfmin = localPlayer.getCombatLevel() - plugin.wildernessLevel; - int selfmax = localPlayer.getCombatLevel() + plugin.wildernessLevel; - for (Player player : client.getPlayers()) - { - if (player == null || player.getName() == null) { - continue; - } - - if (player == localPlayer) { - continue; - } - - boolean isClanMember = player.isClanMember(); - Actor interacting = player.getInteracting(); - Player interactor = null; - if (interacting != null && !(interacting instanceof NPC)) { - interactor = ((Player) interacting); - } - - if (config.showAttackers()) { - if (interactor != null) { - if (interactor.getName().equals(localName)) { - consumer.accept(player, config.getAttackerColor()); - } - } - } - - if (plugin.inwildy == 1) { - if (isClanMember) { - if (!plugin.clan.containsKey(player.getName())) { - plugin.clan.put(player.getName(), player.getCombatLevel()); - } - if (config.highlightAttacked()) { - if (interactor != null) { - if (!interactors.containsKey(interactor.getName())) { - WorldPoint a = interactor.getWorldLocation(); - int underLevel = ((a.getY() - 9920) / 8) + 1; - int upperLevel = ((a.getY() - 3520) / 8) + 1; - int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel; - int wildydiff = plugin.wildernessLevel - wildernessLevel; - if (wildydiff < 0) { - wildydiff = 0; - } - if (config.CalcSelfCB()) { - if (interacting.getCombatLevel() <= selfmax && interacting.getCombatLevel() - wildydiff >= selfmin && !interactor.isClanMember()) { - interactors.put(interactor.getName(), player.getName()); - consumer.accept(interactor, config.getClanAttackableColor()); - } - } else { - if (interacting.getCombatLevel() <= maxatk && interacting.getCombatLevel() - wildydiff >= minatk && !interactor.isClanMember()) { - interactors.put(interactor.getName(), player.getName()); - consumer.accept(interactor, config.getClanAttackableColor()); - } - } - } - } - } - } else { - if (config.PersistentClan()) { - if (plugin.clan.containsKey(player.getName())) { - consumer.accept(player, config.getClanMemberColor()); - } - } - if (config.highlightAttacked()) { - if (interactors.containsKey(player.getName())) { - String attackername = interactors.get(player.getName()); - Boolean found = false; - for (Player attacker : client.getPlayers()) { - if (attacker == null || attacker.getName() == null) { - continue; - } - if (attacker.getName().equals(attackername)) { - found = true; - Actor ainteract = attacker.getInteracting(); - if (ainteract != null) { - if (ainteract.getName().equals(player.getName())) { - consumer.accept(player, config.getClanAttackableColor()); - } else { - interactors.remove(player.getName()); - } - } else { - interactors.remove(player.getName()); - } - break; - } - } - if (!found) { - interactors.remove(player.getName()); - } - continue; - } - } - if (config.highlightAttackable()) { - if ((config.hideAttackable() && plugin.ticks >= config.hideTime()) || plugin.clan.containsKey(player.getName())) { - continue; - } - WorldPoint a = player.getWorldLocation(); - int underLevel = ((a.getY() - 9920) / 8) + 1; - int upperLevel = ((a.getY() - 3520) / 8) + 1; - int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel; - int wildydiff = plugin.wildernessLevel - wildernessLevel; - if (wildydiff < 0) { - wildydiff = 0; - } - if (config.CalcSelfCB()) { - if (player.getCombatLevel() <= selfmax && player.getCombatLevel() - wildydiff >= selfmin) { - consumer.accept(player, config.getAttackableColor()); - } - } else { - if (player.getCombatLevel() <= maxatk && player.getCombatLevel() - wildydiff >= minatk) { - consumer.accept(player, config.getAttackableColor()); - } - } - } - } - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeTileOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeTileOverlay.java deleted file mode 100644 index 5aea2e108f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeTileOverlay.java +++ /dev/null @@ -1,48 +0,0 @@ -package net.runelite.client.plugins.clanmanmode; - -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 ClanManModeTileOverlay extends Overlay -{ - private final ClanManModeService ClanManModeService; - private final ClanManModeConfig config; - - @Inject - private ClanManModeTileOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService) - { - this.config = config; - this.ClanManModeService = ClanManModeService; - setLayer(OverlayLayer.ABOVE_SCENE); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!config.drawTiles()) - { - return null; - } - - ClanManModeService.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/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 8770e593dc..b71d5e8b0e 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 @@ -310,8 +310,7 @@ public class ConfigPanel extends PluginPanel String name = listItem.getName(); JLabel title = new JLabel(name); title.setForeground(Color.WHITE); - title.setText("" + name +""); - title.setToolTipText("" + ":
" + listItem.getDescription() + ""); + title.setToolTipText("" + name + ":
" + listItem.getDescription() + ""); topPanel.add(title); for (ConfigItemDescriptor cid : cd.getItems()) 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 0655b08846..64b97a6ab8 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 @@ -153,10 +153,8 @@ class PluginListItem extends JPanel setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH, 20)); JLabel nameLabel = new JLabel(name); - nameLabel.setText("" + name +""); nameLabel.setForeground(Color.WHITE); - if (!description.isEmpty()) { nameLabel.setToolTipText("" + name + ":
" + description + ""); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxConfig.java deleted file mode 100644 index 8922ebf867..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxConfig.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2019, Jacky - * 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.cox; - -import java.awt.Color; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; -import net.runelite.client.config.Range; - -@ConfigGroup("hydra") -public interface CoxConfig extends Config -{ - @ConfigItem( - position = 0, - keyName = "showHydraTile", - name = "Hydra's Size Box ", - description = "Displays hydra's size box for luring over vents" - ) - default boolean showHydraTile() - { - return false; - } - - @ConfigItem( - position = 1, - keyName = "tileColour", - name = "Color of hydra tile size", - description = "Configures the color of hydra's size" - ) - default Color hydraTileColour() - { - return Color.ORANGE; - } - - @Range( - min = -1000, - max = 1000 - ) - @ConfigItem( - position = 2, - keyName = "prayerHeight", - name = "Sets hydra's prayer height", - description = "The height of the prayer indicator over Hydra" - ) - default int prayerHeight() - { - return 450; - } - - @ConfigItem( - position = 3, - keyName = "showHydraPrayer", - name = "Hydra's Attack Style Indicator", - description = "Displays hydra's size box for luring over vents" - ) - default boolean showPrayer() - { - return false; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxOverlay.java deleted file mode 100644 index 1a227b7ec5..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxOverlay.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2019, Jacky - * 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.cox; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import javax.inject.Inject; -import net.runelite.api.Client; -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; - -public class CoxOverlay extends Overlay -{ - private final Client client; - private final CoxPlugin plugin; - - private final PanelComponent panelComponent = new PanelComponent(); - - @Inject - public CoxOverlay(Client client, CoxPlugin plugin) - { - this.client = client; - this.plugin = plugin; - setPosition(OverlayPosition.TOP_LEFT); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!client.isInInstancedRegion()) return null; - - panelComponent.getChildren().clear(); - { - if (plugin.getOlm() != null) - { - if (plugin.getAttackStyle() == 0) - { - panelComponent.getChildren().add(LineComponent.builder() - .left("Pray: ") - .right("Mage") - .build()); - } - - if (plugin.getAttackStyle() == 1) - { - panelComponent.getChildren().add(LineComponent.builder() - .left("Pray: ") - .right("Ranged") - .build()); - } - } - } - return panelComponent.render(graphics); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxOverlayAbove.java b/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxOverlayAbove.java deleted file mode 100644 index 3942055ec1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxOverlayAbove.java +++ /dev/null @@ -1,124 +0,0 @@ -package net.runelite.client.plugins.cox; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; -import java.util.List; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.Constants; -import net.runelite.api.GameObject; -import net.runelite.api.GraphicsObject; -import net.runelite.api.Perspective; -import net.runelite.api.Player; -import net.runelite.api.Scene; -import net.runelite.api.Tile; -import net.runelite.api.coords.LocalPoint; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayUtil; - -public class CoxOverlayAbove extends Overlay -{ - private final Client client; - private final CoxPlugin plugin; - private CoxConfig config; - - @Inject - public CoxOverlayAbove(Client client, CoxPlugin plugin, CoxConfig config) - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - this.client = client; - this.config = config; - this.plugin = plugin; - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!client.isInInstancedRegion() && plugin.getOlm() == null) return null; - - renderGroundObject(graphics); - - renderTileObjects(graphics); - - return null; - } - - // renders special attack ground objects - private void renderGroundObject(Graphics2D graphics) - { - List graphicsObjects = client.getGraphicsObjects(); - - for (GraphicsObject graphicsObject : graphicsObjects) - { - if (graphicsObject.getId() == 1447 || graphicsObject.getId() == 1356) - { - LocalPoint lp = graphicsObject.getLocation(); - Polygon poly = Perspective.getCanvasTilePoly(client, lp); - - if (poly != null) - { - OverlayUtil.renderPolygon(graphics, poly, Color.RED); - } - } - } - } - - private void renderGameObjects(Graphics2D graphics, Tile tile, Player player) - { - GameObject[] gameObjects = tile.getGameObjects(); - if (gameObjects != null) - { - for (GameObject gameObject : gameObjects) - { - if (gameObject != null && gameObject.getId() == 30033) - { - if (player.getLocalLocation().distanceTo(gameObject.getLocalLocation()) <= 5) - { - // Draw a polygon around the convex hull - // of the model vertices - Polygon p = gameObject.getConvexHull(); - if (p != null) - { - graphics.drawPolygon(p); - } - } - } - } - } - } - - private void renderTileObjects(Graphics2D graphics) - { - Scene scene = client.getScene(); - Tile[][][] tiles = scene.getTiles(); - - int z = client.getPlane(); - - for (int x = 0; x < Constants.SCENE_SIZE; ++x) - { - for (int y = 0; y < Constants.SCENE_SIZE; ++y) - { - Tile tile = tiles[z][x][y]; - - if (tile == null) - { - continue; - } - - Player player = client.getLocalPlayer(); - if (player == null) - { - continue; - } - - renderGameObjects(graphics, tile, player); - } - } - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxPlugin.java deleted file mode 100644 index afc3d095a7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cox/CoxPlugin.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2019, Jacky - * 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.cox; - -import com.google.inject.Provides; -import java.util.List; -import javax.inject.Inject; -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.NPC; -import net.runelite.api.Projectile; -import net.runelite.api.events.GameTick; -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.ui.overlay.OverlayManager; - -@PluginDescriptor( - name = "Cox", - description = "COX Helper", - tags = {"combat", "overlay", "pve", "pvm"} -) -public class CoxPlugin extends Plugin -{ - @Getter - private NPC olm = null; - - @Getter - private int attackStyle = 0; // 0 - mage // 1 - range - - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private CoxOverlay coxOverlay; - - @Inject CoxOverlayAbove coxOverlayAbove; - - @Inject - private CoxConfig config; - - - @Provides - CoxConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(CoxConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(coxOverlay); - overlayManager.add(coxOverlayAbove); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(coxOverlay); - overlayManager.remove(coxOverlayAbove); - } - - @Subscribe - public void onGameTick(GameTick event) - { - if (!client.isInInstancedRegion()) - { - olm = null; - return; - } - - if (client.getPlane() != 0) return; - - List npcs = client.getNpcs(); - - for (NPC npc : npcs) - { - if (npc.getId() == 7554) - { - olm = npc; - } - } - - if (olm == null) return; - - List projectiles = client.getProjectiles(); - - for (Projectile projectile : projectiles) - { - if (projectile.getId() == 1339) - { - // mage - attackStyle = 0; - } - - if (projectile.getId() == 1340) - { - // range - attackStyle = 1; - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/bank/EasyBankConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/bank/EasyBankConfig.java deleted file mode 100644 index ef9382fe66..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/bank/EasyBankConfig.java +++ /dev/null @@ -1,133 +0,0 @@ -package net.runelite.client.plugins.easy.bank; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - - -@ConfigGroup("easybank") -public interface EasyBankConfig extends Config { - - @ConfigItem( - keyName = "withdrawOne", - name = "Withdraw/Deposit One", - description = "", - position = 0 - ) - - default boolean getWithdrawOne() { - return true; - } - - @ConfigItem( - keyName = "withdrawOneItems", - name = "Items", - description = "", - position = 1 - ) - - default String getWithdrawOneItems() { - return ""; - } - - @ConfigItem( - keyName = "withdrawFive", - name = "Withdraw/Deposit Five", - description = "", - position = 2 - ) - - default boolean getWithdrawFive() { - return true; - } - - @ConfigItem( - keyName = "withdrawFiveItems", - name = "Items", - description = "", - position = 3 - ) - - default String getWithdrawFiveItems() { - return ""; - } - - @ConfigItem( - keyName = "withdrawTen", - name = "Withdraw/Deposit Ten", - description = "", - position = 4 - ) - - default boolean getWithdrawTen() { - return true; - } - - @ConfigItem( - keyName = "withdrawTenItems", - name = "Items", - description = "", - position = 5 - ) - - default String getWithdrawTenItems() { - return ""; - } - - @ConfigItem( - keyName = "withdrawX", - name = "Withdraw/Deposit X", - description = "", - position = 6 - ) - - default boolean getWithdrawX() { - return true; - } - - @ConfigItem( - keyName = "withdrawXAmount", - name = "Amount", - description = "", - position = 7 - ) - - default String getWithdrawXAmount() { - return ""; - } - - @ConfigItem( - keyName = "withdrawXItems", - name = "Items", - description = "", - position = 8 - ) - - default String getWithdrawXItems() { - return ""; - } - - @ConfigItem( - keyName = "withdrawAll", - name = "Withdraw/Deposit All", - description = "", - position = 9 - ) - - default boolean getWithdrawAll() { - return true; - } - - @ConfigItem( - keyName = "withdrawAllItems", - name = "Items", - description = "", - position = 10 - ) - - default String getWithdrawAllItems() { - return ""; - } - - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/bank/EasyBankPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/bank/EasyBankPlugin.java deleted file mode 100644 index 4ef7e40d83..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/bank/EasyBankPlugin.java +++ /dev/null @@ -1,133 +0,0 @@ -package net.runelite.client.plugins.easy.bank; - -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.MenuEntry; -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.easy.util.Swapper; -import net.runelite.client.util.Text; - -import javax.inject.Inject; - - -@PluginDescriptor( - name = "EasyBank", - description = "EasyBank.", - tags = {"EasyBank", "easy"} -) - -@Slf4j -public class EasyBankPlugin extends Plugin { - - private Swapper swapper = new Swapper(); - private MenuEntry[] entries; - - @Inject - private Client client; - - @Inject - private EasyBankConfig config; - - @Provides - EasyBankConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(EasyBankConfig.class); - } - - @Override - public void startUp() { - log.debug("EasyBank Started."); - } - - @Override - public void shutDown() { - log.debug("EasyBank 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(); - - Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR); - - swapper.setEntries(client.getMenuEntries()); - - if (!(widgetBankTitleBar == null) && !widgetBankTitleBar.isHidden()) { - - if (config.getWithdrawOne()) { - for (String item : config.getWithdrawOneItems().split(",")) { - item = item.trim(); - if (target.equalsIgnoreCase(item)) { - swapper.markForSwap("Withdraw-1", option, target); - swapper.markForSwap("Deposit-1", option, target); - } - } - } - - if (config.getWithdrawFive()) { - for (String item : config.getWithdrawFiveItems().split(",")) { - item = item.trim(); - if (target.equalsIgnoreCase(item)) { - swapper.markForSwap("Withdraw-5", option, target); - swapper.markForSwap("Deposit-5", option, target); - } - } - } - - if (config.getWithdrawTen()) { - for (String item : config.getWithdrawTenItems().split(",")) { - item = item.trim(); - if (target.equalsIgnoreCase(item)) { - swapper.markForSwap("Withdraw-10", option, target); - swapper.markForSwap("Deposit-10", option, target); - } - } - } - - if (config.getWithdrawX()) { - for (String item : config.getWithdrawXItems().split(",")) { - item = item.trim(); - if (target.equalsIgnoreCase(item)) { - swapper.markForSwap("Withdraw-" + config.getWithdrawXAmount(), option, target); - swapper.markForSwap("Deposit-" + config.getWithdrawXAmount(), option, target); - } - } - } - - if (config.getWithdrawAll()) { - for (String item : config.getWithdrawAllItems().split(",")) { - item = item.trim(); - if (target.equalsIgnoreCase(item)) { - swapper.markForSwap("Withdraw-All", option, target); - swapper.markForSwap("Deposit-All", option, target); - } - } - } - - } - - swapper.startSwap(); - client.setMenuEntries(swapper.getEntries()); - } - -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpConfig.java deleted file mode 100644 index 536fe4e343..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpConfig.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.runelite.client.plugins.easy.pvp; - - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("easypvp") -public interface EasyPvpConfig extends Config { - - @ConfigItem( - keyName = "showWildernessRange", - name = "Show Wilderness Range", - description = "", - position = 0 - ) - - default boolean getShowWildernessRange() { - return true; - } - - @ConfigItem( - keyName = "ShowAttackablePlayers", - name = "Show Attackable Players", - description = "", - position = 1 - ) - - default boolean getShowAttackablePlayers() { - return true; - } - - @ConfigItem( - keyName = "warnProtectItemOff", - name = "Warn Protect Item Off", - description = "", - position = 2 - ) - - default boolean getWarnProtectItemOff() { - return true; - } - - @ConfigItem( - keyName = "showFreezeTimers", - name = "Show Freeze Timers", - description = "", - position = 3 - ) - - default boolean getShowFreezeTimers() { - return true; - } - - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpOverlay.java deleted file mode 100644 index 81553cd787..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpOverlay.java +++ /dev/null @@ -1,102 +0,0 @@ -package net.runelite.client.plugins.easy.pvp; - -import com.google.inject.Inject; -import net.runelite.api.Client; -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; - -import java.awt.*; - -public class EasyPvpOverlay extends Overlay { - - private final Client client; - private final EasyPvpPlugin plugin; - private final EasyPvpConfig config; - - @Inject - private EasyPvpOverlay(Client client, EasyPvpPlugin plugin, EasyPvpConfig config) { - this.client = client; - this.plugin = plugin; - this.config = config; - - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (config.getShowAttackablePlayers()) { - for (Player player : plugin.getTargets()) { - OverlayUtil.renderPolygon(graphics, player.getConvexHull(), Color.RED); - - Point minimapLocation = player.getMinimapLocation(); - if (minimapLocation != null) { - OverlayUtil.renderMinimapLocation(graphics, minimapLocation, Color.RED.darker()); - OverlayUtil.renderTextLocation(graphics, minimapLocation, player.getName(), Color.RED); - } - } - } - - // - - - return null; - } -} -// @Override -// public Dimension render(Graphics2D graphics) -// { -// if (config.getShowWildernessRange()) -// { -//// plugin.getDeadNpcsToDisplay().forEach((id, npc) -> renderNpcRespawn(npc, graphics)); -// } -// -// if (config.getShowAttackablePlayers()) -// -// for (Player player : plugin.getAttackablePlayers()) { -// if (player != null) { -// renderNpcOverlay(graphics, player, player.getName(), Color.RED); -// } else { -// plugin.getAttackablePlayers().remove(player); -// } -// } -// -// return null; -// } - -// private void renderNpcOverlay(Graphics2D graphics, Player actor, String name, Color color) -// { -// LocalPoint lp = actor.getLocalLocation(); -//// Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, 1); -// -// renderTile(graphics, lp, color); -//// renderMinimap(); -// -//// if (config.drawNames()) -//// { -//// Point textLocation = actor.getCanvasTextLocation(graphics, name, actor.getLogicalHeight() + 40); -//// -//// if (textLocation != null) -//// { -//// OverlayUtil.renderTextLocation(graphics, textLocation, name, color); -//// } -//// } -// } - -// private void renderTile(final Graphics2D graphics, final LocalPoint dest, final Color color) -// { -// if (dest == null) -// { -// return; -// } -// final Polygon poly = Perspective.getCanvasTilePoly(client, dest); -// if (poly == null) -// { -// return; -// } -// OverlayUtil.renderPolygon(graphics, poly, color); -// } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpPlugin.java deleted file mode 100644 index bca9c2b5a5..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/pvp/EasyPvpPlugin.java +++ /dev/null @@ -1,197 +0,0 @@ -package net.runelite.client.plugins.easy.pvp; - -import com.google.inject.Inject; -import com.google.inject.Provides; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.Player; -import net.runelite.api.Varbits; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.GameTick; -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.ui.overlay.OverlayManager; - -import java.util.HashSet; -import java.util.Set; - -@PluginDescriptor( - name = "EasyPvP", - description = "EasyPvP.", - tags = {"EasyPVP", "easy"} -) - -@Slf4j -public class EasyPvpPlugin extends Plugin { - - private int inWildy; - - @Inject - private Client client; - - @Inject - private EasyPvpConfig config; - - @Inject - private OverlayManager overlayManager; - - @Inject - private EasyPvpOverlay overlay; - - @Getter(AccessLevel.PACKAGE) - private Set targets = new HashSet<>(); - - private String target; - private boolean prayMage; - private WorldPoint location; - private String spell; - private int currentExperience; - private int gainedExperience; - - @Provides - EasyPvpConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(EasyPvpConfig.class); - } - - @Override - public void startUp() { - prayMage = false; - spell = ""; - overlayManager.add(overlay); - log.debug("EasyPvP Started."); - } - - @Override - public void shutDown() { - overlayManager.remove(overlay); - log.debug("EasyPvP Stopped."); - } - - @Subscribe - public void onGameTick(GameTick event) { - - inWildy = client.getVar(Varbits.IN_WILDERNESS); - - if (inWildy == 0) { - targets.clear(); - return; - } - - Widget wildyText = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL); - - if (wildyText == null) { - return; - } - - int wildyLevel = Integer.parseInt(wildyText.getText().split(":")[1].trim()); - - - if (config.getShowAttackablePlayers()) { - for (Player player : client.getPlayers()) { - if (Math.abs(player.getCombatLevel() - client.getLocalPlayer().getCombatLevel()) <= wildyLevel) { // && !player.equals(client.getLocalPlayer()) - targets.add(player); - } else targets.remove(player); - } - } - } - -// @Subscribe -// public void onGameStateChanged(GameStateChanged event) { -// if (event.getGameState() == GameState.LOGGED_IN) { -// currentExperience = client.getSkillExperience(Skill.MAGIC); -// } -// } -// -// @Subscribe -// public void onMenuOptionClicked(MenuOptionClicked event) { -// if (event.getMenuTarget().contains("->")) { -// target = Text.removeTags(event.getMenuTarget()).split(" -> ")[1]; -// spell = Text.removeTags(event.getMenuTarget()).split(" -> ")[0]; -// log.debug("{} - {}", spell, target); -// prayMage = false; -// } -// } -// -// @Subscribe -// public void onExperienceChanged(ExperienceChanged event) { -// if (event.getSkill() == Skill.MAGIC) { -// gainedExperience = client.getSkillExperience(Skill.MAGIC) - currentExperience; -// currentExperience = client.getSkillExperience(Skill.MAGIC); -// long frozenTime = calculateFreezeTime(gainedExperience, spell, prayMage); -// if (frozenTime > 0) { -// for (Player player : client.getPlayers()) { -// if (player.getName().equals(target)) { -// location = player.getWorldLocation(); -// if (player.getOverheadIcon() != null && player.getOverheadIcon().equals(HeadIcon.MAGIC)) { -// prayMage = true; -// break; -// } -// targets.add(new Markable(player, location, System.currentTimeMillis(), frozenTime)); -// log.debug("Marked Target {}", player.getName()); -// } -// } -// } -// } -// } -// -// public long calculateFreezeTime(int experience, String spell, boolean protectionPrayer) { -// long freezeTime = 0; -// switch (spell) { -// case "Bind": -// if (experience > 30) { -// if (protectionPrayer) { -// freezeTime = 2500; -// } else { -// freezeTime = 5000; -// } -// } -// break; -// case "Snare": -// if (experience > 60) { -// if (protectionPrayer) { -// freezeTime = 5000; -// } else { -// freezeTime = 10000; -// } -// } -// break; -// case "Entangle": -// if (experience > 89) { -// if (protectionPrayer) { -// freezeTime = 7500; -// } else { -// freezeTime = 15000; -// } -// } -// break; -// case "Ice Rush": -// if (experience > 34) { -// freezeTime = 5000; -// } -// break; -// case "Ice Burst": -// if (experience > 40) { -// freezeTime = 10000; -// } -// break; -// case "Ice Blitz": -// if (experience > 46) { -// freezeTime = 15000; -// } -// break; -// case "Ice Barrage": -// if (experience > 52) { -// freezeTime = 20000; -// } -// break; -// } -// return freezeTime; -// } - -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/scape/EasyScapeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/scape/EasyScapeConfig.java deleted file mode 100644 index 6e1bf5da09..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/scape/EasyScapeConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.runelite.client.plugins.easy.scape; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("easyscape") -public interface EasyScapeConfig extends Config { - - @ConfigItem( - keyName = "removeExamine", - name = "Remove Examine", - description = "Removes Examine from the list of options.", - position = 0 - ) - - default boolean getRemoveExamine() { - return true; - } - - @ConfigItem( - keyName = "removeObjects", - name = "Remove Objects", - description = "Removes interaction with the listed objects.", - position = 1 - ) - - default boolean getRemoveObjects() { - return true; - } - - @ConfigItem( - keyName = "removedObjects", - name = "Objects", - description = "Objects listed here will have all interaction be removed.", - position = 2 - ) - - default String getRemovedObjects() { - return ""; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/scape/EasyScapePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/scape/EasyScapePlugin.java deleted file mode 100644 index 9db0b3e0c5..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/scape/EasyScapePlugin.java +++ /dev/null @@ -1,111 +0,0 @@ -package net.runelite.client.plugins.easy.scape; - -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.MenuEntry; -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.util.Text; -import org.apache.commons.lang3.ArrayUtils; - -import javax.inject.Inject; - -@PluginDescriptor( - name = "EasyScape", - description = "EasyScape.", - tags = {"EasyScape"}, - enabledByDefault = false -) - -@Slf4j -public class EasyScapePlugin extends Plugin { - - private MenuEntry[] entries; - - @Inject - private Client client; - - @Inject - private EasyScapeConfig config; - - @Provides - EasyScapeConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(EasyScapeConfig.class); - } - - @Override - public void startUp() { - log.debug("EasyScape Started."); - } - - @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 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("(") && target.split(" \\(")[0].equalsIgnoreCase(removed)) { - delete(event.getIdentifier()); - } else 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; - } - } else if (target.length() >= removed.length() && target.substring(0, removed.length()).equalsIgnoreCase(removed)) { - delete(event.getIdentifier()); - break; - } - } - } - - } - - 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); - } - -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/shop/EasyShopConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/shop/EasyShopConfig.java deleted file mode 100644 index ec86c4c85c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/shop/EasyShopConfig.java +++ /dev/null @@ -1,186 +0,0 @@ -package net.runelite.client.plugins.easy.shop; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("easyshop") -public interface EasyShopConfig extends Config { - - @ConfigItem( - keyName = "swapBuyOne", - name = "Swappable Buy One", - description = "", - position = 0 - ) - - default boolean getSwapBuyOne() { - return true; - } - - @ConfigItem( - keyName = "buyOneItems", - name = "Items", - description = "", - position = 1 - ) - - default String getBuyOneItems() { - return ""; - } - - @ConfigItem( - keyName = "swapBuyFive", - name = "Swappable Buy Five", - description = "", - position = 2 - ) - - default boolean getSwapBuyFive() { - return true; - } - - @ConfigItem( - keyName = "buyFiveItems", - name = "Items", - description = "", - position = 3 - ) - - default String getBuyFiveItems() { - return ""; - } - - @ConfigItem( - keyName = "swapBuyTen", - name = "Swappable Buy Ten", - description = "", - position = 4 - ) - - default boolean getSwapBuyTen() { - return true; - } - - @ConfigItem( - keyName = "buyTenItems", - name = "Items", - description = "", - position = 5 - ) - - default String getBuyTenItems() { - return ""; - } - - @ConfigItem( - keyName = "swapBuyFifty", - name = "Swappable Buy Fifty", - description = "", - position = 6 - ) - - default boolean getSwapBuyFifty() { - return true; - } - - @ConfigItem( - keyName = "buyFiftyItems", - name = "Items", - description = "", - position = 7 - ) - - default String getBuyFiftyItems() { - return ""; - } - - @ConfigItem( - keyName = "swapSellOne", - name = "Swappable Sell One", - description = "", - position = 8 - ) - - default boolean getSwapSellOne() { - return true; - } - - @ConfigItem( - keyName = "sellOneItems", - name = "Items", - description = "", - position = 9 - ) - - default String getSellOneItems() { - return ""; - } - - @ConfigItem( - keyName = "swapSellFive", - name = "Swappable Sell Five", - description = "", - position = 10 - ) - - default boolean getSwapSellFive() { - return true; - } - - @ConfigItem( - keyName = "sellFiveItems", - name = "Items", - description = "", - position = 11 - ) - - default String getSellFiveItems() { - return ""; - } - - @ConfigItem( - keyName = "swapSellTen", - name = "Swappable Sell Ten", - description = "", - position = 12 - ) - - default boolean getSwapSellTen() { - return true; - } - - @ConfigItem( - keyName = "sellTenItems", - name = "Items", - description = "", - position = 13 - ) - - default String getSellTenItems() { - return ""; - } - - @ConfigItem( - keyName = "swapSellFifty", - name = "Swappable Sell Fifty", - description = "", - position = 14 - ) - - default boolean getSwapSellFifty() { - return true; - } - - @ConfigItem( - keyName = "sellFiftyItems", - name = "Items", - description = "", - position = 15 - ) - - default String getSellFiftyItems() { - return ""; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/shop/EasyShopPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/shop/EasyShopPlugin.java deleted file mode 100644 index e13a97ff5d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/shop/EasyShopPlugin.java +++ /dev/null @@ -1,140 +0,0 @@ -package net.runelite.client.plugins.easy.shop; - - -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameState; -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.easy.util.Swapper; -import net.runelite.client.util.Text; - -import javax.inject.Inject; - -@PluginDescriptor( - name = "EasyShop", - description = "EasyShop.", - tags = {"EasyShop", "easy"} -) - -@Slf4j -public class EasyShopPlugin extends Plugin { - - private Swapper swapper = new Swapper(); - - @Inject - private Client client; - - @Inject - private EasyShopConfig config; - - @Provides - EasyShopConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(EasyShopConfig.class); - } - - @Override - public void startUp() { - log.debug("EasyShop Started."); - } - - @Override - public void shutDown() { - log.debug("EasyShop 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(); - - swapper.setEntries(client.getMenuEntries()); - - if (config.getSwapBuyOne() && !config.getBuyOneItems().equals("")) { - for (String item : config.getBuyOneItems().split(",")) { - if (target.equalsIgnoreCase(item.trim())) { - swapper.markForSwap("Buy 1", option, target); - } - } - } - - if (config.getSwapBuyFive() && !config.getBuyFiveItems().equals("")) { - for (String item : config.getBuyFiveItems().split(",")) { - if (target.equalsIgnoreCase(item.trim())) { - swapper.markForSwap("Buy 5", option, target); - } - } - } - - if (config.getSwapBuyTen() && !config.getBuyTenItems().equals("")) { - for (String item : config.getBuyTenItems().split(",")) { - if (target.equalsIgnoreCase(item.trim())) { - swapper.markForSwap("Buy 10", option, target); - } - } - } - - if (config.getSwapBuyFifty() && !config.getBuyFiftyItems().equals("")) { - for (String item : config.getBuyFiftyItems().split(",")) { - if (target.equalsIgnoreCase(item.trim())) { - swapper.markForSwap("Buy 50", option, target); - } - } - } - - if (config.getSwapSellOne() && !config.getSellOneItems().equals("")) { - for (String item : config.getSellOneItems().split(",")) { - if (target.equalsIgnoreCase(item.trim())) { - swapper.markForSwap("Sell 1", option, target); - } - } - } - - if (config.getSwapSellFive() && !config.getSellFiveItems().equals("")) { - for (String item : config.getSellFiveItems().split(",")) { - if (target.equalsIgnoreCase(item.trim())) { - swapper.markForSwap("Sell 5", option, target); - } - } - } - - if (config.getSwapSellTen() && !config.getSellTenItems().equals("")) { - for (String item : config.getSellTenItems().split(",")) { - if (target.equalsIgnoreCase(item.trim())) { - swapper.markForSwap("Sell 10", option, target); - } - } - } - - if (config.getSwapSellFifty() && !config.getSellFiftyItems().equals("")) { - for (String item : config.getSellFiftyItems().split(",")) { - if (target.equalsIgnoreCase(item.trim())) { - swapper.markForSwap("Sell 50", option, target); - } - } - } - - swapper.startSwap(); - client.setMenuEntries(swapper.getEntries()); - } - - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/swap/EasySwapConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/swap/EasySwapConfig.java deleted file mode 100644 index 3e8cc6a41a..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/swap/EasySwapConfig.java +++ /dev/null @@ -1,201 +0,0 @@ -package net.runelite.client.plugins.easy.swap; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; -import net.runelite.client.plugins.easy.util.DuelingRingMode; -import net.runelite.client.plugins.easy.util.EssenceMode; -import net.runelite.client.plugins.easy.util.GamesNecklaceMode; -import net.runelite.client.plugins.easy.util.GloryMode; - -@ConfigGroup("easyswap") -public interface EasySwapConfig extends Config { - - @ConfigItem( - keyName = "easyConstruction", - name = "Easy Construction", - description = "Makes \"Remove\" the default option for listed items in build mode.", - position = 0 - ) - - default boolean getEasyConstruction() { - return true; - } - - @ConfigItem( - keyName = "constructionItems", - name = "Construction Items", - description = "Items listed here will have the default option set to \"Removed\" in build mode.", - position = 1 - ) - - default String getConstructionItems() { - return ""; - } - - - @ConfigItem( - keyName = "swapSmithing", - name = "Swap Smithing", - description = "Enables swapping of smith-1 and smith-all options.", - position = 2 - ) - - default boolean getSwapSmithing() { - return true; - } - - @ConfigItem( - keyName = "swapTanning", - name = "Swap Tanning", - description = "Enables swapping of tan-1 and tan-all options.", - position = 3 - ) - - default boolean getSwapTanning() { - return true; - } - - @ConfigItem( - keyName = "swapCrafting", - name = "Swap Crafting", - description = "Enables swapping of Make-1 and Make-all options.", - position = 4 - ) - - default boolean getSwapCrafting() { - return true; - } - - @ConfigItem( - keyName = "swapArdougneCape", - name = "Swap Ardougne Cape", - description = "Enables swapping of teleport and wear.", - position = 5 - ) - - default boolean getSwapArdougneCape() { - return true; - } - - @ConfigItem( - keyName = "swapSawmill", - name = "Swap Sawmill Operator", - description = "Makes Buy-plank the default option on the sawmill operator.", - position = 6 - ) - - default boolean getSwapSawmill() { - return true; - } - - @ConfigItem( - keyName = "swapSawmillPlanks", - name = "Swap Buy Planks", - description = "Makes Buy All the default option in buy planks.", - position = 7 - ) - - default boolean getSwapSawmillPlanks() { - return true; - } - - @ConfigItem( - keyName = "swapPuroPuro", - name = "Swap Puro Puro Wheat", - description = "", - position = 8 - ) - - default boolean getSwapPuro() { - return true; - } - - @ConfigItem( - keyName = "swapEssencePounch", - name = "Swap Essence Pouch", - description = "", - position = 9 - ) - - default boolean getSwapEssencePouch() { - return true; - } - - @ConfigItem( - keyName = "essenceMode", - name = "Mode", - description = "", - position = 10 - ) - - default EssenceMode getEssenceMode() { - return EssenceMode.RUNECRAFTING; - } - - @ConfigItem( - keyName = "swapGamesNecklace", - name = "Swap Games Necklace", - description = "", - position = 11 - ) - default boolean getGamesNecklace() { - return true; - } - - @ConfigItem( - keyName = "gamesNecklaceMode", - name = "Mode", - description = "", - position = 12 - ) - - default GamesNecklaceMode getGamesNecklaceMode() { - return GamesNecklaceMode.BURTHORPE; - } - - @ConfigItem( - keyName = "swapDuelingRing", - name = "Swap Dueling Ring", - description = "", - position = 13 - ) - - default boolean getDuelingRing() { - return true; - } - - @ConfigItem( - keyName = "duelingRingMode", - name = "Mode", - description = "", - position = 14 - ) - - default DuelingRingMode getDuelingRingMode() { - return DuelingRingMode.DUEL_ARENA; - } - - @ConfigItem( - keyName = "swapGlory", - name = "Swap Glory", - description = "", - position = 15 - ) - - default boolean getGlory() { - return true; - } - - @ConfigItem( - keyName = "gloryMode", - name = "Mode", - description = "", - position = 16 - ) - - default GloryMode getGloryMode() { - return GloryMode.EDGEVILLE; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/swap/EasySwapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/swap/EasySwapPlugin.java deleted file mode 100644 index ae89f2b3d8..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/swap/EasySwapPlugin.java +++ /dev/null @@ -1,236 +0,0 @@ -package net.runelite.client.plugins.easy.swap; - -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameObject; -import net.runelite.api.GameState; -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.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.easy.util.Swapper; -import net.runelite.client.util.Text; -import net.runelite.api.events.GameObjectSpawned; -import net.runelite.api.events.GameStateChanged; - -import javax.inject.Inject; - -import static net.runelite.api.MenuAction.WALK; -import static net.runelite.api.ObjectID.PORTAL_4525; - -@PluginDescriptor( - name = "EasySwap", - description = "EasySwap.", - tags = {"EasySwap", "easy"} -) - -@Slf4j -public class EasySwapPlugin extends Plugin { - - private static final int PURO_PURO_REGION_ID = 10307; - - private Swapper swapper = new Swapper(); - private boolean inHouse = false; - - @Inject - private Client client; - - @Inject - private EasySwapConfig config; - - @Provides - EasySwapConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(EasySwapConfig.class); - } - - @Override - public void startUp() { - log.debug("EasySwap Started."); - } - - @Override - public void shutDown() { - log.debug("EasySwap 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(); - - swapper.setEntries(client.getMenuEntries()); - - if (config.getSwapPuro() && isPuroPuro()) { - if (event.getType() == WALK.getId()) { - swapper.deprioritizeWalk(); - } else if (option.equalsIgnoreCase("examine")) { - swapper.markForSwap("push-through", option, target); - } else if (option.equalsIgnoreCase("use")) { - swapper.markForSwap("escape", option, target); - } - } - - if (config.getEasyConstruction() && !config.getConstructionItems().equals("") && inHouse) { - if (event.getType() == WALK.getId()) { - swapper.deprioritizeWalk(); - } - - swapper.markForSwap("Build", option, target); - - for (int i = swapper.getEntries().length - 1; i >= 0; i--) { - for (String item : config.getConstructionItems().split(",")) { - if (item.trim().equalsIgnoreCase(Text.removeTags(swapper.getEntries()[i].getTarget()))) { - if (!swapper.getEntries()[i].getOption().equalsIgnoreCase("remove")) { - swapper.removeIndex(i); - i--; - } - } - } - } - } - - if (config.getSwapSmithing()) { - if (option.equalsIgnoreCase("Smith 1")) { - swapper.markForSwap("Smith All", option, target); - } else if (option.equalsIgnoreCase("Smith 1 Set")) { - swapper.markForSwap("Smith All Sets", option, target); - } - } - - if (config.getSwapTanning() && option.equalsIgnoreCase("Tan 1")) { - swapper.markForSwap("Tan All", option, target); - } - - if (config.getSwapCrafting()) { - switch (option) { - case "Make-1": - swapper.markForSwap("Make-All", option, target); - break; - case "Craft 1": - swapper.markForSwap("Craft All", option, target); - break; - default: - break; - } - } - - if (config.getSwapSawmill() && target.equalsIgnoreCase("Sawmill operator")) { - swapper.markForSwap("Buy-plank", option, target); - } - - if (config.getSwapSawmillPlanks() && option.equalsIgnoreCase("Buy 1")) { - swapper.markForSwap("Buy All", option, target); - } - - if (option.equalsIgnoreCase("Clear-All") && target.equalsIgnoreCase("bank Filler")) { - swapper.markForSwap("Clear", option, target); - } - - if (target.toLowerCase().contains("ardougne cloak") && config.getSwapArdougneCape()) { - swapper.markForSwap("Kandarin Monastery", option, target); - swapper.markForSwap("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()) { - swapper.markForSwap("Empty", option, target); - } else { - swapper.markForSwap("Fill", option, target); - } - break; - case ESSENCE_MINING: - if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden()) { - swapper.markForSwap("Fill", option, target); - } else { - swapper.markForSwap("Empty", option, target); - } - break; - default: - break; - } - } - } - - if (config.getGamesNecklace()) { - if (target.toLowerCase().contains("games necklace")) { - swapper.markForSwap(config.getGamesNecklaceMode().toString(), option, target); - } - } - - if (config.getDuelingRing()) { - if (target.toLowerCase().contains("ring of dueling")) { - swapper.markForSwap(config.getDuelingRingMode().toString(), option, target); - } - } - - if (config.getGlory()) { - if (target.toLowerCase().contains("amulet of glory")) { - swapper.markForSwap(config.getGloryMode().toString(), option, target); - } - } - - swapper.startSwap(); - client.setMenuEntries(swapper.getEntries()); - } - - private boolean isEssencePouch(String target) { - return (target.equalsIgnoreCase("Small Pouch") || target.equalsIgnoreCase("Medium Pouch") || target.equalsIgnoreCase("Large Pouch") || target.equalsIgnoreCase("Giant Pouch")); - } - - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) - { - final GameObject gameObject = event.getGameObject(); - if (PORTAL_4525 == gameObject.getId()) - { - this.inHouse = true; - } - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOADING) - { - this.inHouse = false; - } - } - - private boolean isHouse() { - return this.inHouse; - } - - 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/util/DuelingRingMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/DuelingRingMode.java deleted file mode 100644 index 9aa0c47ad3..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/DuelingRingMode.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.runelite.client.plugins.easy.util; - -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/util/EssenceMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/EssenceMode.java deleted file mode 100644 index bdf5f75bd0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/EssenceMode.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.runelite.client.plugins.easy.util; - -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/util/GamesNecklaceMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/GamesNecklaceMode.java deleted file mode 100644 index e176207f63..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/GamesNecklaceMode.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.runelite.client.plugins.easy.util; - -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/util/GloryMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/GloryMode.java deleted file mode 100644 index 8f5a93c56f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/GloryMode.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.runelite.client.plugins.easy.util; - -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/util/Markable.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Markable.java deleted file mode 100644 index 696d57f542..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Markable.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.runelite.client.plugins.easy.util; - -import lombok.Getter; -import net.runelite.api.Player; -import net.runelite.api.coords.WorldPoint; - -public class Markable { - - @Getter - private Player player; - - @Getter - private WorldPoint location; - - @Getter - private long frozenTime; - - @Getter - private long frozenUntil; - - public Markable(Player player, WorldPoint location, long frozenTime, long frozenLength) { - this.player = player; - this.location = location; - this.frozenTime = frozenTime; - this.frozenUntil = frozenTime + frozenLength + 3000; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Swappable.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Swappable.java deleted file mode 100644 index 3fc3667a86..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Swappable.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.runelite.client.plugins.easy.util; - -import lombok.Getter; -import lombok.Setter; -import net.runelite.client.util.Text; - -public class Swappable { - - @Getter - private String target; - - @Getter - private String optionOne; - - @Getter - private String optionTwo; - - @Getter - @Setter - private int indexOne; - - @Getter - @Setter - private int indexTwo; - - public Swappable(String target, String optionOne, String optionTwo) { - this.target = Text.removeTags(target.toLowerCase()); - this.optionOne = Text.removeTags(optionOne); - this.optionTwo = Text.removeTags(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/util/Swapper.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Swapper.java deleted file mode 100644 index e0c05e8396..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/util/Swapper.java +++ /dev/null @@ -1,67 +0,0 @@ -package net.runelite.client.plugins.easy.util; - -import lombok.Getter; -import lombok.Setter; -import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; -import net.runelite.client.util.Text; -import org.apache.commons.lang3.ArrayUtils; - -import java.util.HashSet; -import java.util.Set; - -import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; - -public class Swapper { - - private Set swapping; - - @Getter - @Setter - private MenuEntry[] entries; - - public Swapper() { - this.swapping = new HashSet<>(); - } - - public void deprioritizeWalk() { - MenuEntry menuEntry = entries[entries.length - 1]; - menuEntry.setType(MenuAction.WALK.getId() + MENU_ACTION_DEPRIORITIZE_OFFSET); - } - - public void removeIndex(int index) { - entries = ArrayUtils.remove(entries, index); - } - - public void markForSwap(String optionA, String optionB, String target) { - swapping.add(new Swappable(target, optionA, optionB)); - } - - public void startSwap() { - int index = 0; - for (MenuEntry entry : entries) { - String target = Text.removeTags(entry.getTarget()).toLowerCase(); - String option = Text.removeTags(entry.getOption()).toLowerCase(); - for (Swappable swap : swapping) { - if (swap.getTarget().equalsIgnoreCase(target)) { - if (option.equalsIgnoreCase(swap.getOptionOne())) { - swap.setIndexOne(index); - } else if (option.equalsIgnoreCase(swap.getOptionTwo())) { - swap.setIndexTwo(index); - } - } - } - index++; - } - - for (Swappable swap : swapping) { - if (swap.isReady()) { - MenuEntry entry = entries[swap.getIndexOne()]; - entries[swap.getIndexOne()] = entries[swap.getIndexTwo()]; - entries[swap.getIndexTwo()] = entry; - } - } - swapping.clear(); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/zulrah/EasyZulrahConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/zulrah/EasyZulrahConfig.java deleted file mode 100644 index 491c02aaee..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/zulrah/EasyZulrahConfig.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.runelite.client.plugins.easy.zulrah; - -public class EasyZulrahConfig { -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/zulrah/EasyZulrahPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/zulrah/EasyZulrahPlugin.java deleted file mode 100644 index 4cd1d455b0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/easyscape/zulrah/EasyZulrahPlugin.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.runelite.client.plugins.easy.zulrah; - -public class EasyZulrahPlugin { -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java deleted file mode 100644 index 98392d4539..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2017, Aria - * 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.equipmentinspector; - -import java.awt.Color; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; -import net.runelite.client.plugins.grounditems.config.ItemHighlightMode; -import net.runelite.client.plugins.grounditems.config.MenuHighlightMode; -import net.runelite.client.plugins.grounditems.config.PriceDisplayMode; - -@ConfigGroup("grounditems") -public interface EquipmentInspectorConfig extends Config -{ - @ConfigItem( - keyName = "ShowValue", - name = "Show the total value of the items", - description = "shows the total value of the items", - position = 1 - ) - default boolean ShowValue() - { - return true; - } - @ConfigItem( - keyName = "protecteditems", - name = "# of protected items", - description = "Limit 4", - position = 2 - ) - default int protecteditems() - { return 1; } - @ConfigItem( - keyName = "ExactValue", - name = "Show exact value", - description = "shows the excact gp value", - position = 3 - ) - default boolean ExactValue() - { return false; } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java deleted file mode 100644 index e630c28b4f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java +++ /dev/null @@ -1,98 +0,0 @@ -package net.runelite.client.plugins.equipmentinspector; - -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.ItemComposition; -import net.runelite.api.kit.KitType; -import net.runelite.client.game.AsyncBufferedImage; -import net.runelite.client.game.ItemManager; -import net.runelite.client.ui.ColorScheme; -import net.runelite.client.ui.PluginPanel; - -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.swing.*; -import javax.swing.border.CompoundBorder; -import javax.swing.border.EmptyBorder; -import java.awt.*; -import java.util.HashMap; -import java.util.Map; - -@Slf4j -@Singleton -public class EquipmentInspectorPanel extends PluginPanel -{ - private final static String NO_PLAYER_SELECTED = "No player selected"; - - private GridBagConstraints c; - private JPanel equipmentPanels; - private JPanel header; - private JLabel nameLabel; - - @Inject - private ItemManager itemManager; - - public EquipmentInspectorPanel() - { - GroupLayout layout = new GroupLayout(this); - setLayout(layout); - setBorder(new EmptyBorder(10, 10, 10, 10)); - setBackground(ColorScheme.DARK_GRAY_COLOR); - - equipmentPanels = new JPanel(new GridBagLayout()); - c = new GridBagConstraints(); - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.gridx = 0; - c.gridy = 0; - - header = new JPanel(); - header.setLayout(new BorderLayout()); - header.setBorder(new CompoundBorder( - BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(58, 58, 58)), - BorderFactory.createEmptyBorder(0, 0, 10, 0))); - - nameLabel = new JLabel(NO_PLAYER_SELECTED); - nameLabel.setForeground(Color.WHITE); - - header.add(nameLabel, BorderLayout.CENTER); - - layout.setHorizontalGroup(layout.createParallelGroup() - .addComponent(equipmentPanels) - .addComponent(header) - ); - layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(header) - .addGap(10) - .addComponent(equipmentPanels) - ); - - update(new HashMap<>(), ""); - } - - public void update(Map playerEquipment, String playerName) - { - if (playerName.isEmpty() || playerName == null) - { - nameLabel.setText(NO_PLAYER_SELECTED); - } - else - { - nameLabel.setText("Player: " + playerName); - } - - SwingUtilities.invokeLater(() -> - { - equipmentPanels.removeAll(); - playerEquipment.forEach((kitType, itemComposition) -> - { - AsyncBufferedImage itemImage = itemManager.getImage(itemComposition.getId()); - equipmentPanels.add(new ItemPanel(itemComposition, kitType, itemImage), c); - c.gridy++; - - }); - header.revalidate(); - header.repaint(); - } - ); - } -} \ No newline at end of file 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 deleted file mode 100644 index 8af1567609..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java +++ /dev/null @@ -1,240 +0,0 @@ -package net.runelite.client.plugins.equipmentinspector; - - -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.*; -import net.runelite.api.events.PlayerMenuOptionClicked; -import net.runelite.api.kit.KitType; -import net.runelite.client.chat.ChatColorType; -import net.runelite.client.chat.ChatMessageBuilder; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.game.ItemManager; -import net.runelite.client.menus.MenuManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.ClientToolbar; -import net.runelite.client.ui.NavigationButton; -import net.runelite.client.util.Text; -import net.runelite.http.api.item.ItemPrice; - -import javax.annotation.Nullable; -import javax.imageio.ImageIO; -import javax.inject.Inject; -import javax.swing.*; -import java.awt.image.BufferedImage; -import java.lang.reflect.InvocationTargetException; -import java.text.NumberFormat; -import java.util.*; -import java.util.concurrent.ScheduledExecutorService; - -@PluginDescriptor( - name = "!Equipment Inspector", - enabledByDefault = false -) - -@Slf4j - -public class EquipmentInspectorPlugin extends Plugin { - - private static final String INSPECT_EQUIPMENT = "Gear"; - private static final String KICK_OPTION = "Kick"; - - @Inject - @Nullable - private Client client; - - @Inject - private ItemManager itemManager; - - @Inject - private EquipmentInspectorConfig config; - - @Inject - private ChatMessageManager chatMessageManager; - @Inject - private MenuManager menuManager; - - @Inject - private ScheduledExecutorService executor; - - @Inject - private ClientToolbar pluginToolbar; - - @Provides - EquipmentInspectorConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(EquipmentInspectorConfig.class); - } - - private NavigationButton navButton; - private EquipmentInspectorPanel equipmentInspectorPanel; - private int TotalPrice = 0; - private int Prot1 = 0; - private int Prot2 = 0; - private int Prot3 = 0; - private int Prot4 = 0; - - - @Override - protected void startUp() throws Exception - { - - equipmentInspectorPanel = injector.getInstance(EquipmentInspectorPanel.class); - if(client != null) { - menuManager.addPlayerMenuItem(INSPECT_EQUIPMENT); - } - - BufferedImage icon; - synchronized (ImageIO.class) - { - icon = ImageIO.read(getClass().getResourceAsStream("normal.png")); - } - - navButton = NavigationButton.builder() - .tooltip("Equipment Inspector") - .icon(icon) - .priority(5) - .panel(equipmentInspectorPanel) - .build(); - - - pluginToolbar.addNavigation(navButton); - - } - - @Override - protected void shutDown() throws Exception - { - - menuManager.removePlayerMenuItem(INSPECT_EQUIPMENT); - } - - @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) - { - if (event.getMenuOption().equals(INSPECT_EQUIPMENT)) - { - - - executor.execute(() -> - { - try - { - SwingUtilities.invokeAndWait(() -> - { - if (!navButton.isSelected()) - { - navButton.getOnSelect().run(); - } - }); - } - catch (InterruptedException | InvocationTargetException e) - { - - throw new RuntimeException(e); - - } - String playerName = Text.removeTags(event.getMenuTarget()); - // The player menu uses a non-breaking space in the player name, we need to replace this to compare - // against the playerName in the player cache. - String finalPlayerName = playerName.replace('\u00A0', ' '); - System.out.println(finalPlayerName); - List players = client.getPlayers(); - Optional targetPlayer = players.stream() - .filter(Objects::nonNull) - .filter(p -> p.getName().equals(finalPlayerName)).findFirst(); - - if (targetPlayer.isPresent()) - { - TotalPrice = 0; - Prot1 = 0; - Prot2 = 0; - Prot3 = 0; - Prot4 = 0; - Player p = targetPlayer.get(); - Map playerEquipment = new HashMap<>(); - - for (KitType kitType : KitType.values()) - { - int itemId = p.getPlayerComposition().getEquipmentId(kitType); - if (itemId != -1) - { - ItemComposition itemComposition = client.getItemDefinition(itemId); - playerEquipment.put(kitType, itemComposition); - int ItemPrice = itemManager.getItemPrice(itemId); - TotalPrice += ItemPrice; - if (ItemPrice > Prot1 ) { - Prot4 = Prot3; - Prot3 = Prot2; - Prot2 = Prot1; - - Prot1 = ItemPrice; - } else if (ItemPrice > Prot2){ - Prot4 = Prot3; - Prot3 = Prot2; - Prot2 = ItemPrice; - } else if (ItemPrice > Prot3){ - Prot4 = Prot3; - Prot3 = ItemPrice; - } else if (ItemPrice > Prot4){ - Prot4 = ItemPrice; - } - } - } - int IgnoredItems = config.protecteditems(); - if (IgnoredItems != 0 && IgnoredItems != 1 && IgnoredItems != 2 && IgnoredItems != 3) { - IgnoredItems = 4; - - } - if (config.ShowValue()) { - switch (IgnoredItems) { - case 1: - TotalPrice = TotalPrice - Prot1; - break; - case 2: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - - break; - case 3: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - TotalPrice = TotalPrice - Prot3; - break; - case 4: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - TotalPrice = TotalPrice - Prot3; - TotalPrice = TotalPrice - Prot4; - break; - } - String StringPrice = ""; - if (!config.ExactValue()) { - TotalPrice = TotalPrice / 1000; - StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); - StringPrice = StringPrice + 'K'; - } - if (config.ExactValue()) { - StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); - } - chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.FRIENDSCHATNOTIFICATION) - .runeLiteFormattedMessage(new ChatMessageBuilder() - .append(ChatColorType.HIGHLIGHT) - .append("Risked Value: ") - .append(ChatColorType.NORMAL) - .append(StringPrice) - .build()) - .build()); - } - equipmentInspectorPanel.update(playerEquipment, playerName); - - } - }); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java deleted file mode 100644 index 873bf058b6..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.runelite.client.plugins.equipmentinspector; - -import net.runelite.api.ItemComposition; -import net.runelite.api.kit.KitType; -import net.runelite.client.game.AsyncBufferedImage; -import net.runelite.client.ui.ColorScheme; -import net.runelite.client.ui.FontManager; -import org.apache.commons.lang3.StringUtils; - -import javax.swing.*; -import javax.swing.border.EmptyBorder; - -class ItemPanel extends JPanel -{ - - ItemPanel(ItemComposition item, KitType kitType, AsyncBufferedImage icon) - { - setBorder(new EmptyBorder(3, 3, 3, 3)); - setBackground(ColorScheme.DARK_GRAY_COLOR); - - GroupLayout layout = new GroupLayout(this); - this.setLayout(layout); - - JLabel name = new JLabel(item.getName()); - - JLabel location = new JLabel(StringUtils.capitalize(kitType.toString().toLowerCase())); - location.setFont(FontManager.getRunescapeSmallFont()); - - JLabel imageLabel = new JLabel(); - icon.addTo(imageLabel); - - layout.setVerticalGroup(layout.createParallelGroup() - .addComponent(imageLabel) - .addGroup(layout.createSequentialGroup() - .addComponent(name) - .addComponent(location) - ) - ); - - layout.setHorizontalGroup(layout.createSequentialGroup() - .addComponent(imageLabel) - .addGap(8) - .addGroup(layout.createParallelGroup() - .addComponent(name) - .addComponent(location) - ) - ); - - // AWT's Z order is weird. This put image at the back of the stack - setComponentZOrder(imageLabel, getComponentCount() - 1); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/normal.png b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/normal.png deleted file mode 100644 index 613f95e46d5235a49ec0843faaa35384e9b0896b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 624 zcmV-$0+0QPP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0tHD#K~z{r?Uuhw z!$1_rUmcyLn~P8fmrQ~BGyq5#M;t!sDe|AI9PCT z5L;*0n(yTB<#Ji>Y`9Ti3&7jKIc7LRzA=EB!@v>HuhtrJNg@rXeB>M9M-je0Kgy>A zylh?sDMIn)l}ej(`+H8v(E%7b5cc-@C3nN&w2Fwp-R+IopcXQj3?*h0Vy~0lOgpUz zIPDlH0yrEs;AVPiQm$;Ucia462~d@01* diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperOverlay.java deleted file mode 100644 index 3698b395c1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperOverlay.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.runelite.client.plugins.fightcavejadhelper; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.SpriteID; -import net.runelite.client.game.SpriteManager; -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.components.ComponentConstants; -import net.runelite.client.ui.overlay.components.ImageComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; - -public class FightCaveJadHelperOverlay extends Overlay -{ - private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150); - - private final Client client; - private final FightCaveJadHelperPlugin plugin; - private final SpriteManager spriteManager; - private final PanelComponent imagePanelComponent = new PanelComponent(); - - @Inject - private FightCaveJadHelperOverlay(Client client, FightCaveJadHelperPlugin plugin, SpriteManager spriteManager) - { - setPosition(OverlayPosition.BOTTOM_RIGHT); - setPriority(OverlayPriority.HIGH); - this.client = client; - this.plugin = plugin; - this.spriteManager = spriteManager; - } - - @Override - public Dimension render(Graphics2D graphics) - { - final JadAttack attack = plugin.getAttack(); - - if (attack == null) - { - return null; - } - - final BufferedImage prayerImage = getPrayerImage(attack); - - imagePanelComponent.getChildren().clear(); - imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); - imagePanelComponent.setBackgroundColor(client.isPrayerActive(attack.getPrayer()) - ? ComponentConstants.STANDARD_BACKGROUND_COLOR - : NOT_ACTIVATED_BACKGROUND_COLOR); - - return imagePanelComponent.render(graphics); - } - - private BufferedImage getPrayerImage(JadAttack attack) - { - final int prayerSpriteID = attack == JadAttack.MAGIC ? SpriteID.PRAYER_PROTECT_FROM_MAGIC : SpriteID.PRAYER_PROTECT_FROM_MISSILES; - return spriteManager.getSprite(prayerSpriteID, 0); - } -} \ No newline at end of file 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 deleted file mode 100644 index 4eeb311101..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperPlugin.java +++ /dev/null @@ -1,89 +0,0 @@ -package net.runelite.client.plugins.fightcavejadhelper; - -import javax.annotation.Nullable; -import javax.inject.Inject; -import lombok.AccessLevel; -import lombok.Getter; -import net.runelite.api.NPC; -import net.runelite.api.NpcID; -import net.runelite.api.events.AnimationChanged; -import net.runelite.api.events.NpcDespawned; -import net.runelite.api.events.NpcSpawned; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; - -@PluginDescriptor( - name = "!Fight Cave - Jad", - description = "Show what to pray against Jad", - tags = {"bosses", "combat", "minigame", "overlay", "prayer", "pve", "pvm"}, - enabledByDefault = false -) -public class FightCaveJadHelperPlugin extends Plugin -{ - @Inject - private OverlayManager overlayManager; - - @Inject - private FightCaveJadHelperOverlay overlay; - - @Getter(AccessLevel.PACKAGE) - @Nullable - private JadAttack attack; - - private NPC jad; - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - jad = null; - attack = null; - } - - @Subscribe - public void onNpcSpawned(final NpcSpawned event) - { - final int id = event.getNpc().getId(); - - if (id == NpcID.TZTOKJAD || id == NpcID.TZTOKJAD_6506) - { - jad = event.getNpc(); - } - } - - @Subscribe - public void onNpcDespawned(final NpcDespawned event) - { - if (jad == event.getNpc()) - { - jad = null; - attack = null; - } - } - - @Subscribe - public void onAnimationChanged(final AnimationChanged event) - { - if (event.getActor() != jad) - { - return; - } - - if (jad.getAnimation() == JadAttack.MAGIC.getAnimation()) - { - attack = JadAttack.MAGIC; - } - else if (jad.getAnimation() == JadAttack.RANGE.getAnimation()) - { - attack = JadAttack.RANGE; - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/JadAttack.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/JadAttack.java deleted file mode 100644 index 9d9ec47a4b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/JadAttack.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.runelite.client.plugins.fightcavejadhelper; - -import net.runelite.api.AnimationID; -import net.runelite.api.Prayer; - -public enum JadAttack -{ - MAGIC(AnimationID.TZTOK_JAD_MAGIC_ATTACK, Prayer.PROTECT_FROM_MAGIC), - RANGE(AnimationID.TZTOK_JAD_RANGE_ATTACK, Prayer.PROTECT_FROM_MISSILES); - - private final int animation; - private final Prayer prayer; - - JadAttack(int animation, Prayer prayer) - { - this.animation = animation; - this.prayer = prayer; - } - - public int getAnimation() - { - return animation; - } - - public Prayer getPrayer() - { - return prayer; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperConfig.java deleted file mode 100644 index 989c4965e8..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018, Jordan Atwood - * 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.fightcavewavehelper; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("Fight Cave - Wave Helper") -public interface FightCaveWaveHelperConfig extends Config -{ - @ConfigItem( - keyName = "waveDisplay", - name = "Wave display", - description = "Shows monsters that will spawn on the selected wave(s)." - ) - default WaveDisplayMode waveDisplay() - { - return WaveDisplayMode.BOTH; - } -} \ No newline at end of file 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 deleted file mode 100644 index d06451a9d0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperPlugin.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2018, Jordan Atwood - * 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.fightcavewavehelper; - -import com.google.inject.Provides; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.inject.Inject; -import lombok.Getter; -import net.runelite.api.ChatMessageType; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.events.ChatMessage; -import net.runelite.api.events.GameStateChanged; -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.ui.overlay.OverlayManager; -import org.apache.commons.lang3.ArrayUtils; - -@PluginDescriptor( - 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"}, - enabledByDefault = false -) -public class FightCaveWaveHelperPlugin extends Plugin -{ - private static final Pattern WAVE_PATTERN = Pattern.compile(".*Wave: (\\d+).*"); - private static final int FIGHT_CAVE_REGION = 9551; - private static final int MAX_MONSTERS_OF_TYPE_PER_WAVE = 2; - - static final int MAX_WAVE = 63; - - @Getter - static final List> WAVES = new ArrayList<>(); - - @Getter - private int currentWave = -1; - - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private WaveOverlay waveOverlay; - - static - { - final WaveMonster[] waveMonsters = WaveMonster.values(); - - // Add wave 1, future waves are derived from its contents - final EnumMap waveOne = new EnumMap<>(WaveMonster.class); - waveOne.put(waveMonsters[0], 1); - WAVES.add(waveOne); - - for (int wave = 1; wave < MAX_WAVE; wave++) - { - final EnumMap prevWave = WAVES.get(wave - 1).clone(); - int maxMonsterOrdinal = -1; - - for (int i = 0; i < waveMonsters.length; i++) - { - final int ordinalMonsterQuantity = prevWave.getOrDefault(waveMonsters[i], 0); - - if (ordinalMonsterQuantity == MAX_MONSTERS_OF_TYPE_PER_WAVE) - { - maxMonsterOrdinal = i; - break; - } - } - - if (maxMonsterOrdinal >= 0) - { - prevWave.remove(waveMonsters[maxMonsterOrdinal]); - } - - final int addedMonsterOrdinal = maxMonsterOrdinal >= 0 ? maxMonsterOrdinal + 1 : 0; - final WaveMonster addedMonster = waveMonsters[addedMonsterOrdinal]; - final int addedMonsterQuantity = prevWave.getOrDefault(addedMonster, 0); - - prevWave.put(addedMonster, addedMonsterQuantity + 1); - - WAVES.add(prevWave); - } - } - - @Provides - FightCaveWaveHelperConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(FightCaveWaveHelperConfig.class); - } - - @Override - public void startUp() - { - overlayManager.add(waveOverlay); - } - - @Override - public void shutDown() - { - overlayManager.remove(waveOverlay); - currentWave = -1; - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() != GameState.LOGGED_IN) - { - return; - } - - if (!inFightCave()) - { - currentWave = -1; - } - } - - @Subscribe - public void onChatMessage(ChatMessage event) - { - final Matcher waveMatcher = WAVE_PATTERN.matcher(event.getMessage()); - - if (event.getType() != ChatMessageType.GAMEMESSAGE - || !inFightCave() - || !waveMatcher.matches()) - { - return; - } - - currentWave = Integer.parseInt(waveMatcher.group(1)); - } - - boolean inFightCave() - { - return ArrayUtils.contains(client.getMapRegions(), FIGHT_CAVE_REGION); - } - - static String formatMonsterQuantity(final WaveMonster monster, final int quantity) - { - return String.format("%dx %s", quantity, monster); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveDisplayMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveDisplayMode.java deleted file mode 100644 index 79a9d8174e..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveDisplayMode.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018, Jordan Atwood - * 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.fightcavewavehelper; - -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public enum WaveDisplayMode -{ - CURRENT("Current wave"), - NEXT("Next wave"), - BOTH("Both"); - - 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/fightcavewavehelper/WaveMonster.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveMonster.java deleted file mode 100644 index df2fa9b7af..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveMonster.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2018, Jordan Atwood - * 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.fightcavewavehelper; - -import lombok.AllArgsConstructor; - -@AllArgsConstructor -enum WaveMonster -{ - TZ_KIH("Tz-Kih", 22), - TZ_KEK("Tz-Kek", 45), - TOK_XIL("Tok-Xil", 90), - YT_MEJKOT("Yt-MejKot", 180), - KET_ZEK("Ket-Zek", 360), - TZKOK_JAD("TzTok-Jad", 702); - - private final String name; - private final int level; - - @Override - public String toString() - { - return String.format("%s - Level %s", name, level); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveOverlay.java deleted file mode 100644 index b5e6878b02..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveOverlay.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2018, Jordan Atwood - * 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.fightcavewavehelper; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import javax.inject.Inject; -import net.runelite.client.ui.ColorScheme; -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; - -class WaveOverlay extends Overlay -{ - private static final Color HEADER_COLOR = ColorScheme.BRAND_ORANGE; - - private final FightCaveWaveHelperConfig config; - private final FightCaveWaveHelperPlugin plugin; - - private final PanelComponent panelComponent = new PanelComponent(); - - @Inject - private WaveOverlay(FightCaveWaveHelperConfig config, FightCaveWaveHelperPlugin plugin) - { - setPosition(OverlayPosition.TOP_RIGHT); - this.config = config; - this.plugin = plugin; - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!plugin.inFightCave() - || plugin.getCurrentWave() < 0) - { - return null; - } - - panelComponent.getChildren().clear(); - - final int currentWave = plugin.getCurrentWave(); - final int waveIndex = currentWave - 1; - - if (config.waveDisplay() == WaveDisplayMode.CURRENT - || config.waveDisplay() == WaveDisplayMode.BOTH) - { - final Map waveContents = FightCaveWaveHelperPlugin.getWAVES().get(waveIndex); - - addWaveInfo("Wave " + plugin.getCurrentWave(), waveContents); - } - - if ((config.waveDisplay() == WaveDisplayMode.NEXT - || config.waveDisplay() == WaveDisplayMode.BOTH) - && currentWave != FightCaveWaveHelperPlugin.MAX_WAVE) - { - final Map waveContents = FightCaveWaveHelperPlugin.getWAVES().get(waveIndex + 1); - - addWaveInfo("Next wave", waveContents); - } - - return panelComponent.render(graphics); - } - - private void addWaveInfo(final String headerText, final Map waveContents) - { - panelComponent.getChildren().add(TitleComponent.builder() - .text(headerText) - .color(HEADER_COLOR) - .build()); - - for (LineComponent line : buildWaveLines(waveContents)) - { - panelComponent.getChildren().add(line); - } - } - - private static Collection buildWaveLines(final Map wave) - { - final List> monsters = new ArrayList<>(wave.entrySet()); - monsters.sort(Map.Entry.comparingByKey()); - final List outputLines = new ArrayList<>(); - - for (Map.Entry monsterEntry : monsters) - { - final WaveMonster monster = monsterEntry.getKey(); - final int quantity = monsterEntry.getValue(); - final LineComponent line = LineComponent.builder() - .left(FightCaveWaveHelperPlugin.formatMonsterQuantity(monster, quantity)) - .build(); - - outputLines.add(line); - } - - return outputLines; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java deleted file mode 100644 index 6b80dd4ce3..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.runelite.client.plugins.freezetimers; - -import net.runelite.api.Actor; -import net.runelite.client.plugins.freezetimers.Spell; -import net.runelite.client.util.Text; - -public class Barrage -extends Spell { - public static final long DURATION = 20000L; - private long remainingTime; - private boolean isFinished; - - public Barrage(Actor affectedTarget, Actor caster) { - super(affectedTarget, caster); - } - - public long getRemainingTime() { - long elapsedTime = System.currentTimeMillis() - this.startTime; - if (Barrage.getDURATION() > elapsedTime) { - return Barrage.getDURATION() - elapsedTime; - } - this.isFinished = true; - return 0L; - } - - public boolean equals(Object o) { - if (o instanceof Barrage) { - Barrage barrage = (Barrage)o; - return Text.standardize(this.getAffectedTarget().getName()).equals(Text.standardize(((Barrage)o).getAffectedTarget().getName())) && this.getStartTime() == ((Barrage)o).getStartTime(); - } - return false; - } - - public static long getDURATION() { - return 20000L; - } - - @Override - public boolean isFinished() { - return this.isFinished; - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java deleted file mode 100644 index 512905759d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.runelite.client.plugins.freezetimers; - -import java.awt.Color; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup(value="freezetimers") -public interface FreezeTimersConfig -extends Config { - @ConfigItem(position=0, keyName="freezeenable", name="Enable PvP freeze timers", description="Configures whether or not to show freeze timers.") - default public boolean EnableFreezeTimers() { - return false; - } - - @ConfigItem(position=1, keyName="tilehighlight", name="Frozen opponent tile highlighting", description="Configures whether or not to highlight tiles frozen opponents are standing on.") - default public boolean drawTiles() { - return false; - } - - @ConfigItem(position=2, keyName="timercolor", name="Freeze Timer Color", description="Color of freeze timer") - default public Color FreezeTimerColor() { - return new Color(0, 184, 212); - } - - @ConfigItem(position=3, keyName="spellIcon", name="Show spell icon", description="Shows the spell icon for the freeze spell affecting the target") - default public boolean spellIcon() { - return true; - } - - @ConfigItem(position=4, keyName="refreezeTimer", name="Refreeze Timer", description="Show a timer that counts up until the target can be refrozen") - default public boolean refreezeTimer() { - return true; - } - - @ConfigItem(position=5, keyName="refreezeTimerColor", name="Refreeze color", description="The color for the timer that counts until the target can be refrozen") - default public Color RefreezeTimerColor() { - return Color.red; - } - - @ConfigItem(position = 6, keyName = "tbtimer", name = "Tele Block Timer", description = "Enables tele block timer") - default boolean TBTimer() { - return true; - } - - @ConfigItem(position = 7, keyName = "timerpos", name = "Freeze Timer Position", description = "Position of freeze timer") - default int FreezeTimerPos() { - return 80; - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java deleted file mode 100644 index 1d7dbd162e..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java +++ /dev/null @@ -1,157 +0,0 @@ -package net.runelite.client.plugins.freezetimers; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Stroke; -import java.awt.image.BufferedImage; -import java.util.function.BiConsumer; -import javax.inject.Inject; -import javax.inject.Singleton; -import net.runelite.api.Client; -import net.runelite.api.HeadIcon; -import net.runelite.api.Player; -import net.runelite.api.Point; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; -import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin; -import net.runelite.client.plugins.freezetimers.FreezeTimersService; -import net.runelite.client.ui.FontManager; -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 FreezeTimersOverlay -extends Overlay { - private final FreezeTimersService FreezeTimersService; - private final FreezeTimersConfig config; - private final FreezeTimersPlugin plugin; - private final SpriteManager spriteManager; - private final Client client; - - @Inject - private FreezeTimersOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2, FreezeTimersPlugin plugin, Client client, SpriteManager spriteManager) { - this.config = config; - this.FreezeTimersService = FreezeTimersService2; - this.plugin = plugin; - this.client = client; - this.spriteManager = spriteManager; - this.setPosition(OverlayPosition.DYNAMIC); - this.setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (!this.config.EnableFreezeTimers()) { - return null; - } - this.FreezeTimersService.forEachPlayer((player, color) -> this.renderPlayerOverlay(graphics, (Player)player, (Color)color)); - return null; - } - - private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) { - BufferedImage clanchatImage; - int timer = 0; - String name = actor.getName(); - int freezetype = this.plugin.freezetype(name); - boolean frozenoverlay = false; - int offset = 5; - long dtime = this.plugin.opponentfreezetime(name); - long tbed = plugin.istbed(name); - Point textLocation = null; - HeadIcon headIcon = actor.getOverheadIcon(); - int freezetime = 0; - if (freezetype == 1 || freezetype == 4) { - freezetime = 5000; - } else if (freezetype == 2 || freezetype == 5) { - freezetime = 10000; - } else if (freezetype == 3 || freezetype == 6) { - freezetime = 15000; - } else if (freezetype == 7) { - freezetime = 20000; - } else if (freezetype == 8) { - freezetime = 2500; - } else if (freezetype == 9) { - freezetime = 5000; - } else if (freezetype == 10) { - freezetime = 7500; - } - long currenttime = System.currentTimeMillis(); - long timediff = currenttime - dtime; - timer = (freezetime - (int)timediff) / 1000; - if (timediff < (long)freezetime) { - textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos()); - textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); - } else if (timediff < (long)(freezetime + 3000)) { - timer = Math.abs(timer); - ++timer; - if (this.config.refreezeTimer()) { - textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos()); - textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); - graphics.setFont(FontManager.getRunescapeBoldFont()); - if (headIcon != null) { - textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); - } - frozenoverlay = true; - OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), this.config.RefreezeTimerColor()); - return; - } - } else { - this.plugin.deleteopponent(name); - } - if (textLocation != null && (clanchatImage = this.plugin.GetFreezeIcon(freezetype - 1)) != null) { - int width = clanchatImage.getWidth(); - int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent(); - Point imageLocation = new Point(textLocation.getX(), textLocation.getY() - (config.FreezeTimerPos() / 2)); - graphics.setFont(FontManager.getRunescapeFont()); - graphics.setStroke(new BasicStroke(3.0f)); - if (this.config.spellIcon()) { - frozenoverlay = true; - graphics.drawOval(imageLocation.getX(), imageLocation.getY(), clanchatImage.getWidth(), clanchatImage.getHeight()); - OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); - OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), color); - } else { - graphics.setColor(Color.cyan); - graphics.drawOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight()); - graphics.setColor(Color.blue); - graphics.fillOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight()); - OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), Color.WHITE); - } - } - - if (config.TBTimer()) { - if (tbed > 0) { - int type = plugin.tbtype(name); - int tbexpiry; - if (type > 0) { - if (type == 1) { - tbexpiry = 300000; - } else if (type == 2) { - tbexpiry = 150000; - } else { - return; - } - long tbtime = currenttime - tbed; - int tbtimer = (tbexpiry - (int) tbtime) / 1000; - if (tbtime < tbexpiry) { - textLocation = actor.getCanvasTextLocation(graphics, Integer.toString(tbtimer), actor.getLogicalHeight() + config.FreezeTimerPos()); - if (frozenoverlay) { - textLocation = new Point(textLocation.getX() + 40, textLocation.getY() - config.FreezeTimerPos()); - } else { - textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); - } - } else { - plugin.deletetb(name); - } - } - - } - } - } -} - 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 deleted file mode 100644 index 878270bfd4..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java +++ /dev/null @@ -1,402 +0,0 @@ -package net.runelite.client.plugins.freezetimers; - - - - - -import com.google.inject.Provides; -import java.awt.*; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.image.*; -import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferByte; -import java.awt.image.ImageObserver; -import java.awt.image.IndexColorModel; -import java.awt.image.WritableRaster; -import java.util.*; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.inject.Inject; -import net.runelite.api.*; -import net.runelite.api.Actor; -import net.runelite.api.Client; -import net.runelite.api.events.*; -import net.runelite.api.GameState; -import net.runelite.api.HeadIcon; -import net.runelite.api.IndexedSprite; -import net.runelite.api.Player; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.AnimationChanged; -import net.runelite.api.events.ExperienceChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.freezetimers.Barrage; -import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; -import net.runelite.client.plugins.freezetimers.FreezeTimersOverlay; -import net.runelite.client.plugins.freezetimers.FreezeTimersTileOverlay; -import net.runelite.client.plugins.freezetimers.Spell; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.ImageUtil; -import org.slf4j.Logger; - -@PluginDescriptor( - name = "!Freeze Timers", - description = "PVP Freeze Timers", - tags = {"PvP", "Freeze", "Timers"} -) - -public class FreezeTimersPlugin -extends Plugin { - @Inject - private OverlayManager overlayManager; - @Inject - private FreezeTimersConfig config; - @Inject - private FreezeTimersOverlay FreezeTimersOverlay; - @Inject - private FreezeTimersTileOverlay FreezeTimersTileOverlay; - @Inject - private Client client; - @Inject - private SpriteManager spriteManager; - - private static final int[] FREEZE_ICONS = { - SpriteID.SPELL_BIND, - SpriteID.SPELL_SNARE, - SpriteID.SPELL_ENTANGLE, - SpriteID.SPELL_ICE_RUSH, - SpriteID.SPELL_ICE_BURST, - SpriteID.SPELL_ICE_BLITZ, - SpriteID.SPELL_ICE_BARRAGE, - SpriteID.SPELL_BIND, - SpriteID.SPELL_SNARE, - SpriteID.SPELL_ENTANGLE, - SpriteID.SPELL_TELE_BLOCK - }; - private static final Dimension FREEZE_ICON_DIMENSION = new Dimension(25, 25); - private static final Color FREEZE_ICON_OUTLINE_COLOR = new Color(33, 33, 33); - private final BufferedImage[] FreezeIcons = new BufferedImage[FREEZE_ICONS.length]; - private final int SPLASH_ID = 85; - Map tbedthings = new HashMap<>(); - Map tbtypes = new HashMap<>(); - Map testMap = new HashMap(); - Map frozenthings = new HashMap(); - Map frozenthingpoints = new HashMap(); - Map freezetype = new HashMap(); - Map magexp = new HashMap(); - int lastxp; - int ticks; - int currticks; - String currtarget; - String spell; - - @Provides - FreezeTimersConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(FreezeTimersConfig.class); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) { - if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { - this.loadFreezeIcons(); - } - } - - @Override - protected void startUp() throws Exception { - this.overlayManager.add(this.FreezeTimersOverlay); - this.overlayManager.add(this.FreezeTimersTileOverlay); - } - - @Override - protected void shutDown() throws Exception { - this.overlayManager.remove(this.FreezeTimersOverlay); - this.overlayManager.remove(this.FreezeTimersTileOverlay); - this.frozenthings.clear(); - this.frozenthingpoints.clear(); - this.tbedthings.clear(); - this.tbtypes.clear(); - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getMenuTarget().contains("->")) { - Pattern spattern = Pattern.compile(">(.+?)"); - Pattern ppattern = Pattern.compile("> (.+?) 0 && this.currtarget != null) { - if (this.frozenthings.containsKey(this.currtarget)) { - this.currtarget = null; - return; - } - WorldPoint targetPosition = null; - for (Player player : this.client.getPlayers()) { - String playerName; - if (player == null || !(playerName = player.getName()).equals(this.currtarget)) continue; - if (player.getOverheadIcon() != null && player.getOverheadIcon().equals((Object)HeadIcon.MAGIC)) { - praymage = true; - } - targetPosition = player.getWorldLocation(); - break; - } - if (targetPosition != null) { - if (this.spell.equals("Bind") && xp > 30) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - if (praymage) { - this.freezetype.put(this.currtarget, 8); - } else { - this.freezetype.put(this.currtarget, 1); - } - } else if (this.spell.equals("Snare") && xp > 60) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - if (praymage) { - this.freezetype.put(this.currtarget, 9); - } else { - this.freezetype.put(this.currtarget, 2); - } - } else if (this.spell.equals("Entangle") && xp >= 89) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - if (praymage) { - this.freezetype.put(this.currtarget, 10); - } else { - this.freezetype.put(this.currtarget, 3); - } - } else if (this.spell.equals("Ice Rush") && xp > 34) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - this.freezetype.put(this.currtarget, 4); - } else if (this.spell.equals("Ice Burst") && xp > 40) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - this.freezetype.put(this.currtarget, 5); - } else if (this.spell.equals("Ice Blitz") && xp > 46) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - this.freezetype.put(this.currtarget, 6); - } else if (this.spell.equals("Ice Barrage") && xp > 52) { - Barrage barrage = new Barrage(this.client.getLocalPlayer().getInteracting(), this.client.getLocalPlayer()); - this.testMap.put(this.currtarget, barrage); - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - this.freezetype.put(this.currtarget, 7); - } else if (spell.equals("Tele Block") && xp == 95) { - if (config.TBTimer()) { - if (praymage) { - this.tbtypes.put(this.currtarget, 2); - } else { - this.tbtypes.put(this.currtarget, 1); - } - this.tbedthings.put(this.currtarget, System.currentTimeMillis()); - } - } - } - } - if (this.currtarget != null && this.ticks > this.currticks + 1) { - Player local = this.client.getLocalPlayer(); - Actor interacting = local.getInteracting(); - if (interacting != null) { - if (!interacting.getName().equals(this.currtarget)) { - this.currtarget = null; - } - } else { - this.currtarget = null; - } - } - ++this.ticks; - } - - public long opponentfreezetime(String name) { - if (this.frozenthings.containsKey(name)) { - return this.frozenthings.get(name); - } - return 0L; - } - - public WorldPoint playerpos(String name) { - if (this.frozenthingpoints.containsKey(name)) { - return this.frozenthingpoints.get(name); - } - return null; - } - - public void updatePosition(String name, WorldPoint point) { - if (this.frozenthingpoints.containsKey(name)) { - this.frozenthingpoints.remove(name); - this.frozenthingpoints.put(name, point); - } - } - - public int freezetype(String name) { - if (this.freezetype.containsKey(name)) { - return this.freezetype.get(name); - } - return 0; - } - public long istbed(String name) { - if (this.tbedthings.containsKey(name)) { - return this.tbedthings.get(name); - } - return 0; - } - public int tbtype(String name) { - if (this.tbtypes.containsKey(name)) { - return this.tbtypes.get(name); - } - return 0; - } - public void deleteopponent(String name) { - if (this.frozenthings.containsKey(name)) { - this.frozenthings.remove(name); - } - if (this.frozenthingpoints.containsKey(name)) { - this.frozenthingpoints.remove(name); - } - if (this.freezetype.containsKey(name)) { - this.freezetype.remove(name); - } - } - public void deletetb(String name) { - if (this.tbedthings.containsKey(name)) { - this.tbedthings.remove(name); - } - if (this.tbtypes.containsKey(name)) { - this.tbtypes.remove(name); - } - } - private void loadFreezeIcons() { - IndexedSprite[] freezeIcons = new IndexedSprite[]{}; - IndexedSprite[] newfreezeIcons = Arrays.copyOf(freezeIcons, FREEZE_ICONS.length); - int curPosition = 0; - int i = 0; - while (i < FREEZE_ICONS.length) { - int resource = FREEZE_ICONS[i]; - this.FreezeIcons[i] = FreezeTimersPlugin.rgbaToIndexedBufferedImage(FreezeTimersPlugin.FreezeIconFromSprite(this.spriteManager.getSprite(resource, 0))); - newfreezeIcons[curPosition] = FreezeTimersPlugin.createIndexedSprite(this.client, this.FreezeIcons[i]); - ++i; - ++curPosition; - } - } - - private static IndexedSprite createIndexedSprite(Client client, BufferedImage bufferedImage) { - IndexColorModel indexedCM = (IndexColorModel)bufferedImage.getColorModel(); - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - byte[] pixels = ((DataBufferByte)bufferedImage.getRaster().getDataBuffer()).getData(); - int[] palette = new int[indexedCM.getMapSize()]; - indexedCM.getRGBs(palette); - IndexedSprite newIndexedSprite = client.createIndexedSprite(); - newIndexedSprite.setPixels(pixels); - newIndexedSprite.setPalette(palette); - newIndexedSprite.setWidth(width); - newIndexedSprite.setHeight(height); - newIndexedSprite.setOriginalWidth(width); - newIndexedSprite.setOriginalHeight(height); - newIndexedSprite.setOffsetX(0); - newIndexedSprite.setOffsetY(0); - return newIndexedSprite; - } - - private static BufferedImage rgbaToIndexedBufferedImage(BufferedImage sourceBufferedImage) { - BufferedImage indexedImage = new BufferedImage(sourceBufferedImage.getWidth(), sourceBufferedImage.getHeight(), 13); - ColorModel cm = indexedImage.getColorModel(); - IndexColorModel icm = (IndexColorModel)cm; - int size = icm.getMapSize(); - byte[] reds = new byte[size]; - byte[] greens = new byte[size]; - byte[] blues = new byte[size]; - icm.getReds(reds); - icm.getGreens(greens); - icm.getBlues(blues); - WritableRaster raster = indexedImage.getRaster(); - int pixel = raster.getSample(0, 0, 0); - IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); - BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); - resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); - return resultIndexedImage; - } - - private static BufferedImage FreezeIconFromSprite(BufferedImage freezeSprite) { - BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.width, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.height); - return ImageUtil.outlineImage(freezeCanvas, FREEZE_ICON_OUTLINE_COLOR); - } - - BufferedImage GetFreezeIcon(int id) { - return this.FreezeIcons[id]; - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java deleted file mode 100644 index 257aae69b8..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java +++ /dev/null @@ -1,81 +0,0 @@ -package net.runelite.client.plugins.freezetimers; - -import java.awt.Color; -import java.util.List; -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.api.coords.WorldPoint; -import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; -import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin; - -@Singleton -public class FreezeTimersService { - private final Client client; - private final FreezeTimersConfig config; - private final FreezeTimersPlugin plugin; - - @Inject - private FreezeTimersService(Client client, FreezeTimersConfig config, FreezeTimersPlugin plugin) { - this.config = config; - this.plugin = plugin; - this.client = client; - } - - public void forEachPlayer(BiConsumer consumer) { - for (Player player : this.client.getPlayers()) { - if (player == null || player.getName() == null) continue; - String name = player.getName(); - int freezetype = this.plugin.freezetype(name); - long tbed = plugin.istbed(name); - long dtime = this.plugin.opponentfreezetime(name); - int freezetime = 0; - if (freezetype == 1 || freezetype == 4) { - freezetime = 5000; - } else if (freezetype == 2 || freezetype == 5) { - freezetime = 10000; - } else if (freezetype == 3 || freezetype == 6) { - freezetime = 15000; - } else if (freezetype == 7) { - freezetime = 20000; - } else if (freezetype == 8) { - freezetime = 2500; - } else if (freezetype == 9) { - freezetime = 5000; - } else if (freezetype == 10) { - freezetime = 7500; - } - if (dtime <= 0L) continue; - long currenttime = System.currentTimeMillis(); - long timediff = currenttime - dtime; - if (timediff < (long)freezetime) { - WorldPoint lastWorldPoint; - WorldPoint currentWorldPoint = player.getWorldLocation(); - if (currentWorldPoint.equals(lastWorldPoint = this.plugin.playerpos(name))) { - consumer.accept(player, this.config.FreezeTimerColor()); - continue; - } - if (timediff < 605L) { - this.plugin.updatePosition(name, currentWorldPoint); - consumer.accept(player, this.config.FreezeTimerColor()); - continue; - } - this.plugin.deleteopponent(name); - continue; - } - if (timediff < (long)(freezetime + 3000)) { - consumer.accept(player, Color.YELLOW); - continue; - } else { - this.plugin.deleteopponent(name); - } - if (tbed > 0) { - consumer.accept(player, config.FreezeTimerColor()); - return; - } - } - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java deleted file mode 100644 index a945470c85..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java +++ /dev/null @@ -1,46 +0,0 @@ -package net.runelite.client.plugins.freezetimers; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; -import java.util.function.BiConsumer; -import javax.inject.Inject; -import net.runelite.api.Player; -import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; -import net.runelite.client.plugins.freezetimers.FreezeTimersService; -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 FreezeTimersTileOverlay -extends Overlay { - private final FreezeTimersService FreezeTimersService; - private final FreezeTimersConfig config; - - @Inject - private FreezeTimersTileOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2) { - this.config = config; - this.FreezeTimersService = FreezeTimersService2; - this.setLayer(OverlayLayer.ABOVE_SCENE); - this.setPosition(OverlayPosition.DYNAMIC); - this.setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (!this.config.drawTiles()) { - return null; - } - this.FreezeTimersService.forEachPlayer((player, color) -> { - 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/freezetimers/PlayerSpellEffect.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java deleted file mode 100644 index 8bc136fbb5..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.runelite.client.plugins.freezetimers; - -public enum PlayerSpellEffect { - BARRAGE("Ice Barrage", 20000, false), - BLITZ("Ice Blitz", 15000, false); - - private final String SPELL_NAME; - private long startTime; - private int duration; - private boolean halvable; - - private PlayerSpellEffect(String name, int duration, boolean halvable) { - this.SPELL_NAME = name; - this.duration = duration; - this.halvable = halvable; - this.startTime = System.currentTimeMillis(); - } - - public String getSPELL_NAME() { - return this.SPELL_NAME; - } - - public long getStartTime() { - return this.startTime; - } - - public int getDuration() { - return this.duration; - } - - public boolean isHalvable() { - return this.halvable; - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java deleted file mode 100644 index d9033a7c0d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.runelite.client.plugins.freezetimers; - -import net.runelite.api.Actor; - -public abstract class Spell { - private final Actor affectedTarget; - private final Actor caster; - public final long startTime; - private long remainingTime; - private boolean isFinished; - - protected Spell(Actor affectedTarget, Actor caster) { - this.affectedTarget = affectedTarget; - this.caster = caster; - this.startTime = System.currentTimeMillis(); - } - - public Actor getAffectedTarget() { - return this.affectedTarget; - } - - public Actor getCaster() { - return this.caster; - } - - public long getStartTime() { - return this.startTime; - } - - public boolean isFinished() { - return this.isFinished; - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java deleted file mode 100644 index c083887aca..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java +++ /dev/null @@ -1,162 +0,0 @@ -package net.runelite.client.plugins.friendtagging; - -import com.google.common.base.Strings; -import com.google.common.collect.ObjectArrays; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import javax.inject.Inject; -import lombok.NonNull; -import net.runelite.api.Client; -import net.runelite.api.Friend; -import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; -import net.runelite.api.Nameable; -import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.NameableNameChanged; -import net.runelite.api.events.RemovedFriend; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.game.chatbox.ChatboxPanelManager; -import net.runelite.client.game.chatbox.ChatboxTextInput; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.util.Text; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@PluginDescriptor( - name="Friend Tagging", - description="Tag people on your friends list." - ) - -public class FriendTaggingPlugin extends Plugin -{ - private static final Logger log = LoggerFactory.getLogger(FriendTaggingPlugin.class); - public static ConcurrentHashMap taggedFriends = new ConcurrentHashMap(); - private static final String CONFIG_GROUP = "friendtagging"; - private static final int CHARACTER_LIMIT = 30; - private static final String KEY_PREFIX = "tag_"; - private static final String ADD_TAG = "Add Tag"; - private static final String DELETE_TAG = "Delete Tag"; - @Inject - private Client client; - @Inject - private ConfigManager configManager; - @Inject - private ChatboxPanelManager chatboxPanelManager; - - @Override - protected void startUp() throws Exception { - this.loadFriendTags(); - } - - @Override - protected void shutDown() throws Exception { - super.shutDown(); - } - - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) { - int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); - if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) { - String friendName = Text.removeTags(event.getTarget()); - MenuEntry entry = new MenuEntry(); - entry.setOption(friendName == null || this.getTag(friendName) == null ? ADD_TAG : DELETE_TAG); - entry.setType(MenuAction.RUNELITE.getId()); - entry.setTarget(event.getTarget()); - entry.setParam0(event.getActionParam0()); - entry.setParam1(event.getActionParam1()); - MenuEntry[] menuEntries = ObjectArrays.concat(this.client.getMenuEntries(), entry); - this.client.setMenuEntries(menuEntries); - } - } - - @Subscribe - public void onRemovedFriend(RemovedFriend event) { - String displayName = event.getName().trim().toLowerCase(); - this.deleteTag(displayName); - } - - @Subscribe - public void onNameableNameChanged(NameableNameChanged event) { - Friend friend; - Nameable nameable = event.getNameable(); - if (nameable instanceof Friend && (friend = (Friend)nameable).getName() != null && friend.getPrevName() != null) { - this.migrateFriendTag(friend.getName(), friend.getPrevName()); - } - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) { - if (WidgetInfo.TO_GROUP(event.getWidgetId()) == WidgetInfo.FRIENDS_LIST.getGroupId()) { - if (Strings.isNullOrEmpty(event.getMenuTarget())) { - return; - } - String sanitizedTarget = Text.removeTags(event.getMenuTarget()); - if (event.getMenuOption().equals(ADD_TAG)) { - event.consume(); - ChatboxTextInput chatboxTextInput = this.chatboxPanelManager.openTextInput("Enter the tag").value("").onDone(content -> { - if (content == null) { - return; - } - content = Text.removeTags(content).trim(); - this.setTag(sanitizedTarget, (String)content); - }).build(); - } - if (event.getMenuOption().equals(DELETE_TAG)) { - event.consume(); - this.client.getLogger().info(sanitizedTarget); - taggedFriends.forEach((k, v) -> this.client.getLogger().info(k + ": ", v)); - this.deleteTag(sanitizedTarget); - } - } - } - - @NonNull - private String getTag(String name) { - name = name.trim().toLowerCase(); - String keyName = KEY_PREFIX + name; - return taggedFriends.get(keyName); - } - - private void setTag(String name, String tag) { - this.client.getLogger().info("SETTING " + name + ": " + tag); - name = name.trim().toLowerCase(); - String keyName = KEY_PREFIX + name; - if (tag.length() <= 30) { - taggedFriends.put(keyName, tag); - this.configManager.setConfiguration(CONFIG_GROUP, keyName, tag); - } - } - - private void deleteTag(String name) { - name = name.trim().toLowerCase(); - String keyName = KEY_PREFIX + name; - this.configManager.unsetConfiguration(CONFIG_GROUP, keyName); - taggedFriends.remove(keyName); - } - - private void loadFriendTags() { - String prefix = "friendtagging.tag_"; - for (String key : this.configManager.getConfigurationKeys(prefix)) { - String result = this.configManager.getConfiguration(CONFIG_GROUP, key = key.replace("friendtagging.", "")); - if (!Objects.nonNull(result) || result.equals("")) continue; - taggedFriends.put(key, this.configManager.getConfiguration(CONFIG_GROUP, key)); - } - } - - private void migrateFriendTag(String currentDisplayName, String prevDisplayName) { - String prevTag; - String currentTag = this.getTag(currentDisplayName); - if (currentTag == null && (prevTag = this.getTag(prevDisplayName)) != null) { - this.setTag(prevDisplayName, ""); - this.setTag(currentDisplayName, prevTag); - } - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansOverlay.java deleted file mode 100644 index 8f90c59363..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansOverlay.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2018, Damen - * 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.grotesqueguardians; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.GraphicsObject; -import net.runelite.api.Perspective; -import net.runelite.api.coords.LocalPoint; -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; - -class GrotesqueGuardiansOverlay extends Overlay -{ - private static final int GROTESQUE_GUARDIANS_REGION_ID = 6727; - private final Client client; - private static final int GROTESQUE_GUARDIANS_LIGHTNING_START = 1416; - private static final int GROTESQUE_GUARDIANS_LIGHTNING_END = 1431; - private static final int GROTESQUE_GUARDIANS_FALLING_ROCKS = 1436; - private static final int GROTESQUE_GUARDIANS_STONE_ORB = 160; - - @Inject - private GrotesqueGuardiansOverlay(Client client) - { - this.client = client; - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - setPriority(OverlayPriority.LOW); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!client.isInInstancedRegion() || client.getMapRegions()[0] != GROTESQUE_GUARDIANS_REGION_ID) - { - return null; - } - - // TODO: Awaiting GraphicsObjectDespawn event to be tracked to make this more efficient. - for (GraphicsObject graphicsObject : client.getGraphicsObjects()) - { - Color color = null; - - if (graphicsObject.getId() >= GROTESQUE_GUARDIANS_LIGHTNING_START && graphicsObject.getId() <= GROTESQUE_GUARDIANS_LIGHTNING_END) - { - color = Color.ORANGE; - } - else if (graphicsObject.getId() == GROTESQUE_GUARDIANS_STONE_ORB) - { - color = Color.GRAY; - } - else if (graphicsObject.getId() == GROTESQUE_GUARDIANS_FALLING_ROCKS) - { - color = Color.YELLOW; - } - else - { - continue; - } - - LocalPoint lp = graphicsObject.getLocation(); - Polygon poly = Perspective.getCanvasTilePoly(client, lp); - - if (poly != null) - { - OverlayUtil.renderPolygon(graphics, poly, color); - } - } - return null; - } -} 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 deleted file mode 100644 index d6df9dc49f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2018, Damen - * 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.grotesqueguardians; - -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 = "!Grotesque Guardians", - description = "Display tile indicators for the Grotesque Guardian special attacks", - tags = {"grotesque", "guardians", "gargoyle", "garg"} -) -public class GrotesqueGuardiansPlugin extends Plugin -{ - @Inject - private OverlayManager overlayManager; - - @Inject - private GrotesqueGuardiansOverlay overlay; - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java deleted file mode 100644 index 8a92bed779..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.runelite.client.plugins.hideprayers; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("hideprayers") -public interface HidePrayersConfig extends Config -{ - @ConfigItem( - position = 0, - keyName = "pk prayers", - name = "Hides none pk prayers", - description = "Hides widget icons." - ) - default boolean showPrayers() { return false; } - - @ConfigItem( - position = 1, - keyName = "eagle/mystic", - name = "Shows eagle and mystic prayers", - description = "Hides widget icons." - ) - default boolean showEagleMystic() { return false; } - - @ConfigItem( - position = 1, - keyName = "ultstr", - name = "Shows ultimate strength", - description = "Hides widget icons." - ) - default boolean showUltStrength() { return false; } - -} - 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 deleted file mode 100644 index df473a5d0d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java +++ /dev/null @@ -1,169 +0,0 @@ -package net.runelite.client.plugins.hideprayers; - -import com.google.common.collect.ImmutableList; -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import net.runelite.api.*; -import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.WidgetLoaded; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetID; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; - -import javax.inject.Inject; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -@PluginDescriptor( - name = "!Hide Prayers", - description = "Hides specific Prayers in the Prayer tab." -) -public class HidePrayersPlugin extends Plugin { - private static final int PRAYER_COUNT = Prayer.values().length; - - private static final List PRAYER_WIDGET_INFO_LIST = ImmutableList.of(WidgetInfo.PRAYER_THICK_SKIN, - WidgetInfo.PRAYER_BURST_OF_STRENGTH, WidgetInfo.PRAYER_CLARITY_OF_THOUGHT, WidgetInfo.PRAYER_SHARP_EYE, - WidgetInfo.PRAYER_MYSTIC_WILL, WidgetInfo.PRAYER_ROCK_SKIN, WidgetInfo.PRAYER_SUPERHUMAN_STRENGTH, - WidgetInfo.PRAYER_IMPROVED_REFLEXES, WidgetInfo.PRAYER_RAPID_RESTORE, WidgetInfo.PRAYER_RAPID_HEAL, - WidgetInfo.PRAYER_PROTECT_ITEM, WidgetInfo.PRAYER_HAWK_EYE, WidgetInfo.PRAYER_MYSTIC_LORE, - WidgetInfo.PRAYER_STEEL_SKIN, WidgetInfo.PRAYER_ULTIMATE_STRENGTH, WidgetInfo.PRAYER_INCREDIBLE_REFLEXES, - WidgetInfo.PRAYER_PROTECT_FROM_MAGIC, WidgetInfo.PRAYER_PROTECT_FROM_MISSILES, - WidgetInfo.PRAYER_PROTECT_FROM_MELEE, WidgetInfo.PRAYER_EAGLE_EYE, WidgetInfo.PRAYER_MYSTIC_MIGHT, - WidgetInfo.PRAYER_RETRIBUTION, WidgetInfo.PRAYER_REDEMPTION, WidgetInfo.PRAYER_SMITE, - WidgetInfo.PRAYER_PRESERVE, WidgetInfo.PRAYER_CHIVALRY, WidgetInfo.PRAYER_PIETY, WidgetInfo.PRAYER_RIGOUR, - WidgetInfo.PRAYER_AUGURY); - - @Inject - private Client client; - - @Inject - private HidePrayersConfig config; - - @Provides - HidePrayersConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(HidePrayersConfig.class); - } - - @Override - protected void startUp() throws Exception { - hidePrayers(); - } - - @Override - protected void shutDown() throws Exception { - restorePrayers(); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) { - if (event.getGameState() == GameState.LOGGED_IN) { - hidePrayers(); - } - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) { - if (event.getGroup().equals("hideprayers")) { - hidePrayers(); - } - } - - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) { - if (event.getGroupId() == WidgetID.PRAYER_GROUP_ID || event.getGroupId() == WidgetID.QUICK_PRAYERS_GROUP_ID) { - hidePrayers(); - } - } - - private PrayerTabState getPrayerTabState() { - HashTable componentTable = client.getComponentTable(); - for (WidgetNode widgetNode : componentTable.getNodes()) { - if (widgetNode.getId() == WidgetID.PRAYER_GROUP_ID) { - return PrayerTabState.PRAYERS; - } else if (widgetNode.getId() == WidgetID.QUICK_PRAYERS_GROUP_ID) { - return PrayerTabState.QUICK_PRAYERS; - } - } - return PrayerTabState.NONE; - } - - private void restorePrayers() { - if (client.getGameState() != GameState.LOGGED_IN) - return; - - PrayerTabState prayerTabState = getPrayerTabState(); - - if (prayerTabState == PrayerTabState.PRAYERS) { - List prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget) - .filter(Objects::nonNull).collect(Collectors.toList()); - - if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size()) - return; - - for (int index = 0; index < PRAYER_COUNT; index++) - prayerWidgets.get(Prayer.values()[index].ordinal()).setHidden(false); - } - } - - private void hidePrayers() { - if (client.getGameState() != GameState.LOGGED_IN) - return; - - PrayerTabState prayerTabState = getPrayerTabState(); - - if (prayerTabState == PrayerTabState.PRAYERS) { - List prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget) - .filter(Objects::nonNull).collect(Collectors.toList()); - - if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size()) - return; - - for (int index = 0; index < PRAYER_COUNT; index++) { - Prayer prayer = Prayer.values()[index]; - Widget prayerWidget = prayerWidgets.get(prayer.ordinal()); - - if (!config.showPrayers() && !config.showEagleMystic()) - prayerWidget.setHidden(false); - - if (config.showPrayers()) { - prayerWidget.setHidden(true); - prayerWidgets.get(Prayer.values()[10].ordinal()).setHidden(false);// protect item - prayerWidgets.get(Prayer.values()[16].ordinal()).setHidden(false);// mage - prayerWidgets.get(Prayer.values()[17].ordinal()).setHidden(false);// range - prayerWidgets.get(Prayer.values()[18].ordinal()).setHidden(false);// melee - prayerWidgets.get(Prayer.values()[23].ordinal()).setHidden(false);// smite - if (config.showEagleMystic()) { - prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour - prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury - } else { - prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(false);// rigour - prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(false);// augury - } - if (config.showUltStrength()) { - prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety - } else { - prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(false);// piety - } - } - if (config.showEagleMystic()) { - prayerWidget.setHidden(true); - prayerWidgets.get(Prayer.values()[19].ordinal()).setHidden(false);// eagle - prayerWidgets.get(Prayer.values()[20].ordinal()).setHidden(false);// mystic - prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour - prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury - } - if (config.showUltStrength()) { - prayerWidget.setHidden(true); - prayerWidgets.get(Prayer.values()[14].ordinal()).setHidden(false);// Ult Strength - prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety - } - - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java deleted file mode 100644 index 699300f8a9..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.runelite.client.plugins.hideprayers; - -public enum PrayerTabState -{ - NONE, - PRAYERS, - QUICK_PRAYERS -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraConfig.java deleted file mode 100644 index 8c3d8467b8..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraConfig.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.runelite.client.plugins.hydra; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("hydra") -public interface HydraConfig extends Config { - @ConfigItem( - position = 0, - keyName = "hydraenable", - name = "Enable Hydra (194 cb) Helper", - description = "Configures whether or not to enable Hydra Helper. (For use on regular hydra's only, will not work with Alchemical Hydra)." - ) - default boolean EnableHydra() { return true; } - - @ConfigItem( - position = 1, - keyName = "textindicators", - name = "Text Indicator", - description = "Configures if text indicator is shown above hydra's or not." - ) - default boolean TextIndicator() { return true; } - - @ConfigItem( - position = 2, - keyName = "countersize", - name = "Bold indicator", - description = "Configures if text indicator is bold or not." - ) - default boolean BoldText() { return false; } - - @ConfigItem( - position = 3, - keyName = "prayerhelper", - name = "Prayer Helper", - description = "Configures if prayer helper is shown or not." - ) - default boolean PrayerHelper() { return true; } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraIndicatorOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraIndicatorOverlay.java deleted file mode 100644 index 6c38c81b3f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraIndicatorOverlay.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.runelite.client.plugins.hydra; - -import java.awt.*; -import java.awt.image.BufferedImage; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.Point; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.ui.overlay.*; -import net.runelite.client.ui.overlay.components.ComponentConstants; -import net.runelite.client.ui.overlay.components.ImageComponent; -import net.runelite.client.ui.overlay.components.LineComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; - -import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; -import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; - -public class HydraIndicatorOverlay extends Overlay { - private final HydraConfig config; - private final HydraPlugin plugin; - - private final PanelComponent panelComponent = new PanelComponent(); - - @Inject - private HydraIndicatorOverlay(HydraConfig config, HydraPlugin plugin) { - this.config = config; - this.plugin = plugin; - setPosition(OverlayPosition.BOTTOM_RIGHT); - setPriority(OverlayPriority.MED); - panelComponent.setPreferredSize(new Dimension(14, 0)); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (!config.PrayerHelper()) { - return null; - } - - if (plugin.Hydra != null) { - if (plugin.hydras.containsKey(plugin.Hydra.getIndex())) { - int val = plugin.hydras.get(plugin.Hydra.getIndex()); - if (val != 0) { - panelComponent.getChildren().clear(); - panelComponent.getChildren().add(LineComponent.builder().right(Integer.toString(val)).build()); - return panelComponent.render(graphics); - } - } - } - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraOverlay.java deleted file mode 100644 index b499227ec2..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraOverlay.java +++ /dev/null @@ -1,76 +0,0 @@ -package net.runelite.client.plugins.hydra; - -import java.awt.*; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.Point; -import net.runelite.client.ui.FontManager; -import net.runelite.client.ui.overlay.*; -import net.runelite.client.ui.overlay.components.PanelComponent; - -public class HydraOverlay extends Overlay { - private final HydraConfig config; - private final HydraPlugin plugin; - private final PanelComponent panelComponent = new PanelComponent(); - - - @Inject - private Client client; - - @Inject - private HydraOverlay(HydraConfig config, HydraPlugin plugin) { - this.config = config; - this.plugin = plugin; - setLayer(OverlayLayer.ABOVE_SCENE); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.MED); - panelComponent.setPreferredSize(new Dimension(150, 0)); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (!config.TextIndicator()) { - return null; - } - - for (NPC hydra : client.getNpcs()) { - if (hydra == null || hydra.getName() == null) { - continue; - } - if (hydra.getName().equalsIgnoreCase("Hydra")) { - if (plugin.hydras.containsKey(hydra.getIndex())) { - int val = plugin.hydras.get(hydra.getIndex()); - if (val != 0) { - if (config.BoldText()) { - graphics.setFont(FontManager.getRunescapeBoldFont()); - } - if (plugin.hydraattacks.containsKey(hydra.getIndex())) { - int attack = plugin.hydraattacks.get(hydra.getIndex()); - if (attack == 8261) { - if (val == 3) { - OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "MAGE", hydra.getLogicalHeight() + 100), "MAGE", Color.BLUE); - } else { - OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "RANGE", hydra.getLogicalHeight() + 100), "RANGE", Color.GREEN); - } - } else if (attack == 8262) { - if (val == 3) { - OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "RANGE", hydra.getLogicalHeight() + 100), "RANGE", Color.GREEN); - } else { - OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "MAGE", hydra.getLogicalHeight() + 100), "MAGE", Color.BLUE); - } - } - } - Point runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam = hydra.getCanvasTextLocation(graphics, Integer.toString(val), hydra.getLogicalHeight() + 40); - if (runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam != null) { - OverlayUtil.renderTextLocation(graphics, runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam, Integer.toString(val), Color.WHITE); - } - } - } - } - - } - graphics.setFont(FontManager.getRunescapeFont()); - return null; - } -} 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 deleted file mode 100644 index ba8c0317a7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPlugin.java +++ /dev/null @@ -1,145 +0,0 @@ -package net.runelite.client.plugins.hydra; - -import net.runelite.api.events.*; -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import javax.inject.Inject; -import net.runelite.api.*; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; - -import java.util.HashMap; -import java.util.Map; - -@PluginDescriptor( - name = "Hydra", - description = "Hydra Helper", - tags = {"Hydra", "Helper"} -) -public class HydraPlugin extends Plugin -{ - @Inject - private OverlayManager overlayManager; - - @Inject - private HydraConfig config; - - @Inject - private HydraOverlay HydraOverlay; - - @Inject - private HydraPrayOverlay HydraPrayOverlay; - - @Inject - private HydraIndicatorOverlay HydraIndicatorOverlay; - - @Inject - private Client client; - - @Inject - private SpriteManager spriteManager; - - @Provides - HydraConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(HydraConfig.class); - } - - Map hydras = new HashMap<>(); - Map hydraattacks = new HashMap<>(); - NPC Hydra; - - @Override - protected void startUp() throws Exception { - overlayManager.add(HydraOverlay); - overlayManager.add(HydraPrayOverlay); - overlayManager.add(HydraIndicatorOverlay); - } - - @Override - protected void shutDown() throws Exception { - overlayManager.remove(HydraOverlay); - overlayManager.remove(HydraPrayOverlay); - overlayManager.remove(HydraIndicatorOverlay); - hydras.clear(); - hydraattacks.clear(); - } - - @Subscribe - public void onNpcSpawned(NpcSpawned event) { - if (!config.EnableHydra()) { - return; - } - NPC hydra = event.getNpc(); - if (hydra.getCombatLevel() != 0 && hydra.getName() != null) { - if (hydra.getName().equalsIgnoreCase("Hydra")) { - if (!hydras.containsKey(hydra.getIndex())) { - hydras.put(hydra.getIndex(), 3); - } - } - } - } - - @Subscribe - public void onNpcDespawned(NpcDespawned event) { - if (!config.EnableHydra()) { - return; - } - NPC hydra = event.getNpc(); - if (hydra.getCombatLevel() != 0 && hydra.getName() != null) { - if (hydra.getName().equalsIgnoreCase("Hydra")) { - if (hydras.containsKey(hydra.getIndex())) { - hydras.remove(hydra.getIndex()); - } - if (hydraattacks.containsKey(hydra.getIndex())) { - hydraattacks.remove(hydra.getIndex()); - } - } - } - } - - @Subscribe - public void onAnimationChanged(AnimationChanged event) { - Actor monster = event.getActor(); - Actor local = client.getLocalPlayer(); - if (monster instanceof NPC) { - NPC hydra = (NPC) monster; - if (hydra.getCombatLevel() != 0 && hydra.getName() != null) { - if (hydra.getName().equalsIgnoreCase("Hydra")) { - if (hydras.containsKey(hydra.getIndex())) { - if (hydra.getAnimation() == 8261 || hydra.getAnimation() == 8262) { - if (hydra.getInteracting().equals(local)) { - Hydra = hydra; - } - if (hydraattacks.containsKey(hydra.getIndex())) { - int lastattack = hydraattacks.get(hydra.getIndex()); - hydraattacks.replace(hydra.getIndex(), hydra.getAnimation()); - - if (lastattack != hydra.getAnimation()) { - hydras.replace(hydra.getIndex(), 2); - } else { - int currval = hydras.get(hydra.getIndex()); - if (currval == 1) { - hydras.replace(hydra.getIndex(), 3); - } else { - hydras.replace(hydra.getIndex(), currval - 1); - } - } - } else { - hydraattacks.put(hydra.getIndex(), hydra.getAnimation()); - int currval = hydras.get(hydra.getIndex()); - if (currval == 1) { - hydras.replace(hydra.getIndex(), 3); - } else { - hydras.replace(hydra.getIndex(), currval - 1); - } - } - } - } - } - } - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPrayOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPrayOverlay.java deleted file mode 100644 index 47a7657667..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPrayOverlay.java +++ /dev/null @@ -1,100 +0,0 @@ -package net.runelite.client.plugins.hydra; - -import java.awt.*; -import java.awt.image.BufferedImage; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.Point; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.ui.overlay.*; -import net.runelite.client.ui.overlay.components.ComponentConstants; -import net.runelite.client.ui.overlay.components.ImageComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; - -public class HydraPrayOverlay extends Overlay { - private final HydraConfig config; - private final HydraPlugin plugin; - - private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150); - - private final SpriteManager spriteManager; - private final PanelComponent imagePanelComponent = new PanelComponent(); - - - @Inject - private Client client; - - @Inject - private HydraPrayOverlay(HydraConfig config, HydraPlugin plugin, SpriteManager spriteManager) { - this.config = config; - this.plugin = plugin; - setPosition(OverlayPosition.BOTTOM_RIGHT); - setPriority(OverlayPriority.HIGH); - this.spriteManager = spriteManager; - } - - @Override - public Dimension render(Graphics2D graphics) { - if (!config.PrayerHelper()) { - return null; - } - - if (plugin.Hydra != null) { - if (plugin.hydras.containsKey(plugin.Hydra.getIndex())) { - int val = plugin.hydras.get(plugin.Hydra.getIndex()); - if (val != 0) { - if (plugin.hydraattacks.containsKey(plugin.Hydra.getIndex())) { - int attack = plugin.hydraattacks.get(plugin.Hydra.getIndex()); - if (attack == 8261) { - if (val == 3) { - final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0); - - imagePanelComponent.getChildren().clear(); - imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); - imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC) - ? ComponentConstants.STANDARD_BACKGROUND_COLOR - : NOT_ACTIVATED_BACKGROUND_COLOR); - - return imagePanelComponent.render(graphics); - } else { - final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0); - - imagePanelComponent.getChildren().clear(); - imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); - imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES) - ? ComponentConstants.STANDARD_BACKGROUND_COLOR - : NOT_ACTIVATED_BACKGROUND_COLOR); - - return imagePanelComponent.render(graphics); - } - } else if (attack == 8262) { - if (val == 3) { - final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0); - - imagePanelComponent.getChildren().clear(); - imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); - imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES) - ? ComponentConstants.STANDARD_BACKGROUND_COLOR - : NOT_ACTIVATED_BACKGROUND_COLOR); - - return imagePanelComponent.render(graphics); - } else { - final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0); - - imagePanelComponent.getChildren().clear(); - imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); - imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC) - ? ComponentConstants.STANDARD_BACKGROUND_COLOR - : NOT_ACTIVATED_BACKGROUND_COLOR); - - return imagePanelComponent.render(graphics); - } - } - } - } - } - } - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java deleted file mode 100644 index 043d22a30c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.ArrayList; - -@AllArgsConstructor -public class InventorySetup -{ - @Getter - private ArrayList inventory; - @Getter - private ArrayList equipment; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java deleted file mode 100644 index 34ba341fc7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java +++ /dev/null @@ -1,113 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.Point; -import net.runelite.api.Query; -import net.runelite.api.SpritePixels; -import net.runelite.api.queries.BankItemQuery; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.widgets.WidgetItem; -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.util.QueryRunner; - -import javax.inject.Inject; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.image.BufferedImage; -import java.util.Arrays; -import java.util.Objects; - -@Slf4j -public class InventorySetupBankOverlay extends Overlay -{ - private final Client client; - private final QueryRunner queryRunner; - private final InventorySetupPlugin plugin; - private final InventorySetupConfig config; - - @Inject - public InventorySetupBankOverlay(Client client, QueryRunner queryRunner, InventorySetupPlugin plugin, InventorySetupConfig config) - { - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.LOW); - setLayer(OverlayLayer.ABOVE_WIDGETS); - this.client = client; - this.queryRunner = queryRunner; - this.plugin = plugin; - this.config = config; - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (config.getBankHighlight()) - { - int[] ids = plugin.getCurrentInventorySetupIds(); - if (ids == null) - { - return null; - } - ids = Arrays.stream(ids) - .filter(Objects::nonNull) - .filter(id -> id != -1) - .toArray(); - final Query query = new BankItemQuery().idEquals(ids); - final WidgetItem[] widgetItems = queryRunner.runQuery(query); - final Widget bankContainer = client.getWidget(WidgetInfo.BANK_CONTAINER); - for (final WidgetItem item : widgetItems) - { - Point canvasLocation = item.getCanvasLocation(); - Rectangle canvasBounds = item.getCanvasBounds(); - Point windowLocation = bankContainer.getCanvasLocation(); - - if (canvasLocation == null || windowLocation == null) - { - return null; - } - - if (!(canvasLocation.getY() + 60 >= windowLocation.getY() + bankContainer.getHeight()) && !(canvasLocation.getY() + canvasBounds.getHeight() <= windowLocation.getY() + 90)) - { - final Color color = config.getBankHighlightColor(); - - if (color != null) - { - final BufferedImage outline = loadItemOutline(item.getId(), item.getQuantity(), color); - graphics.drawImage(outline, item.getCanvasLocation().getX() + 1, item.getCanvasLocation().getY() + 1, null); - if (item.getQuantity() > 1) - { - drawQuantity(graphics, item, Color.YELLOW); - } - else if (item.getQuantity() == 0) - { - drawQuantity(graphics, item, Color.YELLOW.darker()); - } - } - } - } - } - return null; - } - - private void drawQuantity(Graphics2D graphics, WidgetItem item, Color darker) - { - graphics.setColor(Color.BLACK); - graphics.drawString(String.valueOf(item.getQuantity()), item.getCanvasLocation().getX() + 2, item.getCanvasLocation().getY() + 11); - graphics.setColor(darker); - graphics.setFont(FontManager.getRunescapeSmallFont()); - graphics.drawString(String.valueOf(item.getQuantity()), item.getCanvasLocation().getX() + 1, item.getCanvasLocation().getY() + 10); - } - - private BufferedImage loadItemOutline(final int itemId, final int itemQuantity, final Color outlineColor) - { - final SpritePixels itemSprite = client.createItemSprite(itemId, itemQuantity, 2, 0, 0, true, 710); - return itemSprite.toBufferedOutline(outlineColor); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java deleted file mode 100644 index edcc47cd9c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -import java.awt.Color; - -@ConfigGroup("inventorysetups") -public interface InventorySetupConfig extends Config -{ - @ConfigItem( - keyName = "highlightDifferences", - name = "Highlight Differences", - description = "Highlight slots that don't match the selected setup", - position = 0 - ) - - default boolean getHighlightDifferences() - { - return false; - } - - @ConfigItem( - keyName = "highlightDifferenceColor", - name = "Highlight Color", - description = "The color used to highlight differences between setups", - position = 1 - ) - - default Color getHighlightColor() - { - return Color.RED; - } - - @ConfigItem( - keyName = "stackDifference", - name = "Stack Difference", - description = "Differences between setups will be highlighted if the stack size is different", - position = 2 - ) - - default boolean getStackDifference() - { - return false; - } - - @ConfigItem( - keyName = "variationDifference", - name = "Variation Difference", - description = "Variations of items (E.g., charged jewellery) will be counted as different", - position = 2 - ) - - default boolean getVariationDifference() - { - return false; - } - - @ConfigItem( - keyName = "bankHighlight", - name = "Bank Highlight", - description = "Highlight setup items in bank", - position = 4 - ) - - default boolean getBankHighlight() - { - return false; - } - - @ConfigItem( - keyName = "bankHighlightColor", - name = "Bank Highlight Color", - description = "The color used to highlight setup items in bank", - position = 5 - ) - - default Color getBankHighlightColor() - { - return Color.RED; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java deleted file mode 100644 index c1af4e68fd..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -public class InventorySetupItem -{ - @Getter - private final int id; - @Getter - private final String name; - @Getter - private final int quantity; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java deleted file mode 100644 index 0830ec834a..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java +++ /dev/null @@ -1,402 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameState; -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.ConfigChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.ItemContainerChanged; -import net.runelite.client.callback.ClientThread; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.game.ItemManager; -import net.runelite.client.game.ItemVariationMapping; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.inventorysetups.ui.InventorySetupPluginPanel; -import net.runelite.client.ui.ClientToolbar; -import net.runelite.client.ui.NavigationButton; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.ImageUtil; - -import javax.inject.Inject; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; -import java.awt.image.BufferedImage; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; - -@PluginDescriptor( - name = "Inventory Setups", - description = "Save inventory setups", - tags = { "items", "inventory", "setups"}, - enabledByDefault = false -) - -@Slf4j -public class InventorySetupPlugin extends Plugin -{ - - private static final String CONFIG_GROUP = "inventorysetups"; - private static final String CONFIG_KEY = "setups"; - private static final int NUM_INVENTORY_ITEMS = 28; - private static final int NUM_EQUIPMENT_ITEMS = 14; - - @Inject - private Client client; - - @Inject - private ItemManager itemManager; - - @Inject - private InventorySetupBankOverlay overlay; - - @Inject - private ClientToolbar clientToolbar; - - @Inject - private InventorySetupConfig config; - - @Inject - private OverlayManager overlayManager; - - @Inject - private ClientThread clientThread; - - @Inject - private ConfigManager configManager; - - private InventorySetupPluginPanel panel; - - private HashMap inventorySetups; - - private NavigationButton navButton; - - private boolean highlightDifference; - - @Override - public void startUp() - { - overlayManager.add(overlay); - - panel = new InventorySetupPluginPanel(this, itemManager); - - final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "inventorysetups_icon.png"); - - navButton = NavigationButton.builder() - .tooltip("Inventory Setups") - .icon(icon) - .priority(9) - .panel(panel) - .build(); - - clientToolbar.addNavigation(navButton); - - // load all the inventory setups from the config file - clientThread.invokeLater(() -> - { - if (client.getGameState() != GameState.LOGIN_SCREEN) - { - return false; - } - - loadConfig(); - panel.showNoSetupsPanel(); - return true; - }); - - } - - public void addInventorySetup() - { - final String name = JOptionPane.showInputDialog(panel, - "Enter the name of this setup.", - "Add New Setup", - JOptionPane.PLAIN_MESSAGE); - - // cancel button was clicked - if (name == null) - { - return; - } - - if (name.isEmpty()) - { - JOptionPane.showMessageDialog(panel, - "Invalid Setup Name", - "Names must not be empty.", - JOptionPane.PLAIN_MESSAGE); - return; - } - - if (inventorySetups.containsKey(name)) - { - String builder = "The setup " + name + " already exists. " + - "Would you like to replace it with the current setup?"; - int confirm = JOptionPane.showConfirmDialog(panel, - builder, - "Warning", - JOptionPane.OK_CANCEL_OPTION, - JOptionPane.PLAIN_MESSAGE); - - if (confirm == JOptionPane.CANCEL_OPTION) - { - return; - } - - // delete the old setup, no need to ask for confirmation - // because the user confirmed above - removeInventorySetup(name, false); - } - - clientThread.invoke(() -> - { - ArrayList inv = getNormalizedContainer(InventoryID.INVENTORY); - ArrayList eqp = getNormalizedContainer(InventoryID.EQUIPMENT); - - final InventorySetup invSetup = new InventorySetup(inv, eqp); - SwingUtilities.invokeLater(() -> - { - inventorySetups.put(name, invSetup); - panel.addInventorySetup(name); - panel.setCurrentInventorySetup(name); - - updateConfig(); - }); - }); - } - - public void removeInventorySetup(final String name, boolean askForConfirmation) - { - if (inventorySetups.containsKey(name)) - { - int confirm = JOptionPane.YES_OPTION; - - if (askForConfirmation) - { - confirm = JOptionPane.showConfirmDialog(panel, - "Are you sure you want to remove this setup?", - "Warning", - JOptionPane.YES_NO_OPTION, - JOptionPane.PLAIN_MESSAGE); - } - - if (confirm == JOptionPane.YES_OPTION) - { - inventorySetups.remove(name); - panel.removeInventorySetup(name); - } - - updateConfig(); - } - } - - public final InventorySetup getInventorySetup(final String name) - { - return inventorySetups.get(name); - } - - @Provides - InventorySetupConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(InventorySetupConfig.class); - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (event.getGroup().equals(CONFIG_GROUP)) - { - // only allow highlighting if the config is enabled and the player is logged in - highlightDifference = config.getHighlightDifferences() && client.getGameState() == GameState.LOGGED_IN; - final String setupName = panel.getSelectedInventorySetup(); - if (highlightDifference && !setupName.isEmpty()) - { - panel.setCurrentInventorySetup(setupName); - } - } - } - - private void updateConfig() - { - if (inventorySetups.isEmpty()) - { - configManager.unsetConfiguration(CONFIG_GROUP, CONFIG_KEY); - return; - } - - final Gson gson = new Gson(); - final String json = gson.toJson(inventorySetups); - configManager.setConfiguration(CONFIG_GROUP, CONFIG_KEY, json); - } - - private void loadConfig() - { - // serialize the internal data structure from the json in the configuration - final String json = configManager.getConfiguration(CONFIG_GROUP, CONFIG_KEY); - if (json == null || json.isEmpty()) - { - inventorySetups = new HashMap<>(); - } - else - { - // TODO add last resort?, serialize exception just make empty map - final Gson gson = new Gson(); - Type type = new TypeToken>() - { - - }.getType(); - inventorySetups = gson.fromJson(json, type); - } - - for (final String key : inventorySetups.keySet()) - { - panel.addInventorySetup(key); - } - - highlightDifference = false; - } - - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) - { - - if (!highlightDifference || client.getGameState() != GameState.LOGGED_IN) - { - return; - } - - // empty entry, no need to compare anything - final String selectedInventorySetup = panel.getSelectedInventorySetup(); - if (selectedInventorySetup.isEmpty()) - { - return; - } - - // check to see that the container is the equipment or inventory - ItemContainer container = event.getItemContainer(); - - if (container == client.getItemContainer(InventoryID.INVENTORY)) - { - ArrayList normContainer = getNormalizedContainer(InventoryID.INVENTORY); - final InventorySetup setup = inventorySetups.get(selectedInventorySetup); - panel.highlightDifferences(normContainer, setup, InventoryID.INVENTORY); - } - else if (container == client.getItemContainer(InventoryID.EQUIPMENT)) - { - ArrayList normContainer = getNormalizedContainer(InventoryID.EQUIPMENT); - final InventorySetup setup = inventorySetups.get(selectedInventorySetup); - panel.highlightDifferences(normContainer, setup, InventoryID.EQUIPMENT); - } - - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - switch (event.getGameState()) - { - // set the highlighting off if login screen shows up - case LOGIN_SCREEN: - highlightDifference = false; - final String setupName = panel.getSelectedInventorySetup(); - if (!setupName.isEmpty()) - { - panel.setCurrentInventorySetup(setupName); - } - break; - - // set highlighting - case LOGGED_IN: - highlightDifference = config.getHighlightDifferences(); - break; - } - } - - public ArrayList getNormalizedContainer(final InventoryID id) - { - assert id == InventoryID.INVENTORY || id == InventoryID.EQUIPMENT : "invalid inventory ID"; - - final ItemContainer container = client.getItemContainer(id); - - ArrayList newContainer = new ArrayList<>(); - - Item[] items = null; - if (container != null) - { - items = container.getItems(); - } - - int size = id == InventoryID.INVENTORY ? NUM_INVENTORY_ITEMS : NUM_EQUIPMENT_ITEMS; - - for (int i = 0; i < size; i++) - { - if (items == null || i >= items.length) - { - newContainer.add(new InventorySetupItem(-1, "", 0)); - } - else - { - final Item item = items[i]; - String itemName = ""; - if (client.isClientThread()) - { - itemName = itemManager.getItemComposition(item.getId()).getName(); - } - newContainer.add(new InventorySetupItem(item.getId(), itemName, item.getQuantity())); - } - } - - return newContainer; - } - - public final InventorySetupConfig getConfig() - { - return config; - } - - public boolean getHighlightDifference() - { - return highlightDifference; - } - - @Override - public void shutDown() - { - overlayManager.remove(overlay); - clientToolbar.removeNavigation(navButton); - } - - final int[] getCurrentInventorySetupIds() - { - InventorySetup setup = inventorySetups.get(panel.getSelectedInventorySetup()); - if (setup == null) - { - return null; - } - ArrayList items = new ArrayList<>(); - items.addAll(setup.getEquipment()); - items.addAll(setup.getInventory()); - ArrayList itemIds = new ArrayList<>(); - for (InventorySetupItem item : items) - { - int id = item.getId(); - ItemComposition itemComposition = itemManager.getItemComposition(id); - if (id > 0) - { - itemIds.add(ItemVariationMapping.map(id)); - itemIds.add(itemComposition.getPlaceholderId()); - } - - } - return itemIds.stream().mapToInt(i -> i).toArray(); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java deleted file mode 100644 index d5eda3697f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java +++ /dev/null @@ -1,109 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.client.game.AsyncBufferedImage; -import net.runelite.client.game.ItemManager; -import net.runelite.client.game.ItemVariationMapping; -import net.runelite.client.plugins.inventorysetups.InventorySetupConfig; -import net.runelite.client.plugins.inventorysetups.InventorySetupItem; -import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; -import net.runelite.client.ui.ColorScheme; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Color; -import java.util.ArrayList; - -public abstract class InventorySetupContainerPanel extends JPanel -{ - - protected ItemManager itemManager; - - private final InventorySetupPlugin plugin; - - InventorySetupContainerPanel(final ItemManager itemManager, final InventorySetupPlugin plugin, String captionText) - { - this.itemManager = itemManager; - this.plugin = plugin; - JPanel containerPanel = new JPanel(); - - final JPanel containerSlotsPanel = new JPanel(); - - setupContainerPanel(containerSlotsPanel); - - // caption - final JLabel caption = new JLabel(captionText); - caption.setHorizontalAlignment(JLabel.CENTER); - caption.setVerticalAlignment(JLabel.CENTER); - - // panel that holds the caption and any other graphics - final JPanel captionPanel = new JPanel(); - captionPanel.add(caption); - - containerPanel.setLayout(new BorderLayout()); - containerPanel.add(captionPanel, BorderLayout.NORTH); - containerPanel.add(containerSlotsPanel, BorderLayout.CENTER); - - add(containerPanel); - } - - void setContainerSlot(int index, - final InventorySetupSlot containerSlot, - final ArrayList items) - { - if (index >= items.size() || items.get(index).getId() == -1) - { - containerSlot.setImageLabel(null, null); - return; - } - - int itemId = items.get(index).getId(); - int quantity = items.get(index).getQuantity(); - final String itemName = items.get(index).getName(); - AsyncBufferedImage itemImg = itemManager.getImage(itemId, quantity, quantity > 1); - String toolTip = itemName; - if (quantity > 1) - { - toolTip += " (" + quantity + ")"; - } - containerSlot.setImageLabel(toolTip, itemImg); - } - - void highlightDifferentSlotColor(InventorySetupItem savedItem, - InventorySetupItem currItem, - final InventorySetupSlot containerSlot) - { - // important note: do not use item names for comparisons - // they are all empty to avoid clientThread usage when highlighting - - final InventorySetupConfig config = plugin.getConfig(); - final Color highlightColor = config.getHighlightColor(); - - if (config.getStackDifference() && currItem.getQuantity() != savedItem.getQuantity()) - { - containerSlot.setBackground(highlightColor); - return; - } - - int currId = currItem.getId(); - int checkId = savedItem.getId(); - - if (!config.getVariationDifference()) - { - currId = ItemVariationMapping.map(currId); - checkId = ItemVariationMapping.map(checkId); - } - - if (currId != checkId) - { - containerSlot.setBackground(highlightColor); - return; - } - - // set the color back to the original, because they match - containerSlot.setBackground(ColorScheme.DARKER_GRAY_COLOR); - } - - abstract public void setupContainerPanel(final JPanel containerSlotsPanel); - -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java deleted file mode 100644 index 7e0fecfa2b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java +++ /dev/null @@ -1,91 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.api.EquipmentInventorySlot; -import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.inventorysetups.InventorySetup; -import net.runelite.client.plugins.inventorysetups.InventorySetupItem; -import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; -import net.runelite.client.ui.ColorScheme; - -import javax.swing.JPanel; -import java.awt.GridLayout; -import java.util.ArrayList; -import java.util.HashMap; - -public class InventorySetupEquipmentPanel extends InventorySetupContainerPanel -{ - private HashMap equipmentSlots; - - InventorySetupEquipmentPanel(final ItemManager itemManager, final InventorySetupPlugin plugin) - { - super(itemManager, plugin, "Equipment"); - } - - @Override - public void setupContainerPanel(final JPanel containerSlotsPanel) - { - this.equipmentSlots = new HashMap<>(); - for (EquipmentInventorySlot slot : EquipmentInventorySlot.values()) - { - equipmentSlots.put(slot, new InventorySetupSlot(ColorScheme.DARKER_GRAY_COLOR)); - } - - final GridLayout gridLayout = new GridLayout(5, 3, 1, 1); - containerSlotsPanel.setLayout(gridLayout); - - // add the grid layouts, including invisible ones - containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.HEAD)); - containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.CAPE)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.AMULET)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.AMMO)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.WEAPON)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.BODY)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.SHIELD)); - containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.LEGS)); - containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.GLOVES)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.BOOTS)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.RING)); - - } - - void setEquipmentSetupSlots(final InventorySetup setup) - { - final ArrayList equipment = setup.getEquipment(); - - for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values()) - { - int i = slot.getSlotIdx(); - super.setContainerSlot(i, equipmentSlots.get(slot), equipment); - } - - validate(); - repaint(); - - } - - void highlightDifferences(final ArrayList currEquipment, final InventorySetup inventorySetup) - { - final ArrayList equipToCheck = inventorySetup.getEquipment(); - - assert currEquipment.size() == equipToCheck.size() : "size mismatch"; - - for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values()) - { - - int slotIdx = slot.getSlotIdx(); - super.highlightDifferentSlotColor(equipToCheck.get(slotIdx), currEquipment.get(slotIdx), equipmentSlots.get(slot)); - } - } - - void resetEquipmentSlotsColor() - { - for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values()) - { - equipmentSlots.get(slot).setBackground(ColorScheme.DARKER_GRAY_COLOR); - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java deleted file mode 100644 index 136f4603ea..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java +++ /dev/null @@ -1,78 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.inventorysetups.InventorySetup; -import net.runelite.client.plugins.inventorysetups.InventorySetupItem; -import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; -import net.runelite.client.ui.ColorScheme; - -import javax.swing.JPanel; -import java.awt.GridLayout; -import java.util.ArrayList; - -public class InventorySetupInventoryPanel extends InventorySetupContainerPanel -{ - - private static final int ITEMS_PER_ROW = 4; - private static final int NUM_INVENTORY_ITEMS = 28; - - private ArrayList inventorySlots; - - InventorySetupInventoryPanel(final ItemManager itemManager, final InventorySetupPlugin plugin) - { - super(itemManager, plugin, "Inventory"); - } - - - @Override - public void setupContainerPanel(final JPanel containerSlotsPanel) - { - this.inventorySlots = new ArrayList<>(); - for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) - { - inventorySlots.add(new InventorySetupSlot(ColorScheme.DARKER_GRAY_COLOR)); - } - - int numRows = (NUM_INVENTORY_ITEMS + ITEMS_PER_ROW - 1) / ITEMS_PER_ROW; - containerSlotsPanel.setLayout(new GridLayout(numRows, ITEMS_PER_ROW, 1, 1)); - for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) - { - containerSlotsPanel.add(inventorySlots.get(i)); - } - } - - void setInventorySetupSlots(final InventorySetup setup) - { - ArrayList inventory = setup.getInventory(); - - for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) - { - super.setContainerSlot(i, inventorySlots.get(i), inventory); - } - - validate(); - repaint(); - - } - - void highlightDifferentSlots(final ArrayList currInventory, final InventorySetup inventorySetup) - { - - final ArrayList inventoryToCheck = inventorySetup.getInventory(); - - assert currInventory.size() == inventoryToCheck.size() : "size mismatch"; - - for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) - { - super.highlightDifferentSlotColor(inventoryToCheck.get(i), currInventory.get(i), inventorySlots.get(i)); - } - } - - void resetInventorySlotsColor() - { - for (InventorySetupSlot inventorySlot : inventorySlots) - { - inventorySlot.setBackground(ColorScheme.DARKER_GRAY_COLOR); - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java deleted file mode 100644 index b1b88a02c7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java +++ /dev/null @@ -1,287 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.api.InventoryID; -import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.inventorysetups.InventorySetup; -import net.runelite.client.plugins.inventorysetups.InventorySetupItem; -import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; -import net.runelite.client.ui.PluginPanel; -import net.runelite.client.ui.components.PluginErrorPanel; -import net.runelite.client.util.ImageUtil; - -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.ImageIcon; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.border.EmptyBorder; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.event.ItemEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; -import java.util.ArrayList; - -public class InventorySetupPluginPanel extends PluginPanel -{ - - private static ImageIcon ADD_ICON; - private static ImageIcon ADD_HOVER_ICON; - private static ImageIcon REMOVE_ICON; - private static ImageIcon REMOVE_HOVER_ICON; - - private final JPanel noSetupsPanel; - private final JPanel invEqPanel; - - private final InventorySetupInventoryPanel invPanel; - private final InventorySetupEquipmentPanel eqpPanel; - - private final JComboBox setupComboBox; - - private final JLabel removeMarker; - - private final InventorySetupPlugin plugin; - - static - { - final BufferedImage addIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "add_icon.png"); - ADD_ICON = new ImageIcon(addIcon); - ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f)); - - final BufferedImage removeIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "remove_icon.png"); - REMOVE_ICON = new ImageIcon(removeIcon); - REMOVE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(removeIcon, 0.53f)); - } - - public InventorySetupPluginPanel(final InventorySetupPlugin plugin, final ItemManager itemManager) - { - super(false); - this.plugin = plugin; - this.removeMarker = new JLabel(REMOVE_ICON); - this.invPanel = new InventorySetupInventoryPanel(itemManager, plugin); - this.eqpPanel = new InventorySetupEquipmentPanel(itemManager, plugin); - this.noSetupsPanel = new JPanel(); - this.invEqPanel = new JPanel(); - this.setupComboBox = new JComboBox<>(); - - // setup the title - final JLabel addMarker = new JLabel(ADD_ICON); - final JLabel title = new JLabel(); - title.setText("Inventory Setups"); - title.setForeground(Color.WHITE); - - // setup the add marker (+ sign in the top right) - addMarker.setToolTipText("Add a new inventory setup"); - addMarker.addMouseListener(new MouseAdapter() - { - @Override - public void mouseClicked(MouseEvent e) - { - plugin.addInventorySetup(); - } - - @Override - public void mouseEntered(MouseEvent e) - { - addMarker.setIcon(ADD_HOVER_ICON); - } - - @Override - public void mouseExited(MouseEvent e) - { - addMarker.setIcon(ADD_ICON); - } - }); - - // setup the remove marker (X sign in the top right) - removeMarker.setToolTipText("Remove the current inventory setup"); - removeMarker.addMouseListener(new MouseAdapter() - { - @Override - public void mouseClicked(MouseEvent e) - { - final String name = (String)setupComboBox.getSelectedItem(); - plugin.removeInventorySetup(name, true); - } - - @Override - public void mouseEntered(MouseEvent e) - { - if (removeMarker.isEnabled()) - { - removeMarker.setIcon(REMOVE_HOVER_ICON); - } - } - - @Override - public void mouseExited(MouseEvent e) - { - removeMarker.setIcon(REMOVE_ICON); - } - }); - - // setup the combo box for selection switching - // add empty to indicate the empty position - setupComboBox.addItem(""); - setupComboBox.setSelectedIndex(0); - setupComboBox.addItemListener(e -> - { - if (e.getStateChange() == ItemEvent.SELECTED) - { - String selection = (String)e.getItem(); - setCurrentInventorySetup(selection); - } - }); - - // the panel on the top right that holds the add and delete buttons - final JPanel markersPanel = new JPanel(); - markersPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 0)); - markersPanel.add(removeMarker); - markersPanel.add(addMarker); - - // the top panel that has the title and the buttons - final JPanel titleAndMarkersPanel = new JPanel(); - titleAndMarkersPanel.setLayout(new BorderLayout()); - titleAndMarkersPanel.add(title, BorderLayout.WEST); - titleAndMarkersPanel.add(markersPanel, BorderLayout.EAST); - - // the panel that stays at the top and doesn't scroll - // contains the title, buttons, and the combo box - final JPanel northAnchoredPanel = new JPanel(); - northAnchoredPanel.setLayout(new BoxLayout(northAnchoredPanel, BoxLayout.Y_AXIS)); - northAnchoredPanel.setBorder(new EmptyBorder(0, 0, 10, 0)); - northAnchoredPanel.add(titleAndMarkersPanel); - northAnchoredPanel.add(Box.createRigidArea(new Dimension(0, 10))); - northAnchoredPanel.add(setupComboBox); - - // the panel that holds the inventory and equipment panels - final BoxLayout invEqLayout = new BoxLayout(invEqPanel, BoxLayout.Y_AXIS); - invEqPanel.setLayout(invEqLayout); - invEqPanel.add(invPanel); - invEqPanel.add(Box.createRigidArea(new Dimension(0, 10))); - invEqPanel.add(eqpPanel); - - // setup the error panel. It's wrapped around a normal panel - // so it doesn't stretch to fill the parent panel - final PluginErrorPanel errorPanel = new PluginErrorPanel(); - errorPanel.setContent("Inventory Setups", "Select or create an inventory setup."); - noSetupsPanel.add(errorPanel); - - // the panel that holds the inventory panels, and the error panel - final JPanel contentPanel = new JPanel(); - final BoxLayout contentLayout = new BoxLayout(contentPanel, BoxLayout.Y_AXIS); - contentPanel.setLayout(contentLayout); - contentPanel.add(invEqPanel); - contentPanel.add(noSetupsPanel); - - // wrapper for the main content panel to keep it from stretching - final JPanel contentWrapper = new JPanel(new BorderLayout()); - contentWrapper.add(Box.createGlue(), BorderLayout.CENTER); - contentWrapper.add(contentPanel, BorderLayout.NORTH); - final JScrollPane contentWrapperPane = new JScrollPane(contentWrapper); - contentWrapperPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - - setLayout(new BorderLayout()); - setBorder(new EmptyBorder(10, 10, 10, 10)); - add(northAnchoredPanel, BorderLayout.NORTH); - add(contentWrapperPane, BorderLayout.CENTER); - - // show the no setups panel on startup - showNoSetupsPanel(); - - } - - public void showNoSetupsPanel() - { - setupComboBox.setSelectedIndex(0); - removeMarker.setEnabled(false); - noSetupsPanel.setVisible(true); - invEqPanel.setVisible(false); - } - - private void showHasSetupPanel(final String name) - { - setupComboBox.setSelectedItem(name); - removeMarker.setEnabled(true); - noSetupsPanel.setVisible(false); - invEqPanel.setVisible(true); - } - - public void setCurrentInventorySetup(final String name) - { - if (name.isEmpty()) - { - showNoSetupsPanel(); - return; - } - - showHasSetupPanel(name); - - final InventorySetup inventorySetup = plugin.getInventorySetup(name); - - invPanel.setInventorySetupSlots(inventorySetup); - eqpPanel.setEquipmentSetupSlots(inventorySetup); - - if (plugin.getHighlightDifference()) - { - final ArrayList normInv = plugin.getNormalizedContainer(InventoryID.INVENTORY); - final ArrayList normEqp = plugin.getNormalizedContainer(InventoryID.EQUIPMENT); - - highlightDifferences(normInv, inventorySetup, InventoryID.INVENTORY); - highlightDifferences(normEqp, inventorySetup, InventoryID.EQUIPMENT); - } - else - { - invPanel.resetInventorySlotsColor(); - eqpPanel.resetEquipmentSlotsColor(); - } - - validate(); - repaint(); - } - - public void addInventorySetup(final String name) - { - setupComboBox.addItem(name); - } - - public void removeInventorySetup(final String name) - { - setupComboBox.removeItem(name); - showNoSetupsPanel(); - - invPanel.resetInventorySlotsColor(); - eqpPanel.resetEquipmentSlotsColor(); - - validate(); - repaint(); - } - - public void highlightDifferences(final ArrayList container, - final InventorySetup setupToCheck, - final InventoryID type) - { - switch (type) - { - case INVENTORY: - invPanel.highlightDifferentSlots(container, setupToCheck); - break; - - case EQUIPMENT: - eqpPanel.highlightDifferences(container, setupToCheck); - break; - } - } - - public final String getSelectedInventorySetup() - { - return (String)setupComboBox.getSelectedItem(); - } - - -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java deleted file mode 100644 index 13bbbaef14..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.client.game.AsyncBufferedImage; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.SwingConstants; -import java.awt.Color; -import java.awt.Dimension; - -public class InventorySetupSlot extends JPanel -{ - - private final JLabel imageLabel; - - public InventorySetupSlot(Color color) - { - imageLabel = new JLabel(); - imageLabel.setVerticalAlignment(SwingConstants.CENTER); - setPreferredSize(new Dimension(46, 42)); - setBackground(color); - add(imageLabel); - - } - - public void setImageLabel(String toolTip, AsyncBufferedImage itemImage) - { - if (itemImage == null || toolTip == null) - { - imageLabel.setToolTipText(""); - imageLabel.setIcon(null); - imageLabel.revalidate(); - return; - } - - imageLabel.setToolTipText(toolTip); - itemImage.addTo(imageLabel); - - validate(); - repaint(); - } - - - -} \ No newline at end of file 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 deleted file mode 100644 index 1dbc0f7901..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -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("inventoryviewer") -public interface InventoryViewerConfig extends Config -{ - @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/InventoryViewerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerOverlay.java index bb59bd41b4..71da3492aa 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 @@ -34,7 +34,6 @@ 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; @@ -49,32 +48,24 @@ class InventoryViewerOverlay extends Overlay private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(new BufferedImage(PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR)); private final Client client; - private final InventoryViewerConfig config; private final ItemManager itemManager; private final PanelComponent panelComponent = new PanelComponent(); @Inject - private InventoryViewerOverlay(Client client, InventoryViewerConfig config, ItemManager itemManager) + private InventoryViewerOverlay(Client client, ItemManager itemManager) { setPosition(OverlayPosition.BOTTOM_RIGHT); panelComponent.setWrapping(4); panelComponent.setGap(new Point(6, 4)); panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); - this.client = client; - this.config = config; this.itemManager = itemManager; + this.client = client; } @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) 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 01bc51dc33..a9aa9f6453 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 @@ -25,8 +25,6 @@ package net.runelite.client.plugins.inventoryviewer; import javax.inject.Inject; -import com.google.inject.Provides; -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; @@ -45,12 +43,6 @@ public class InventoryViewerPlugin extends Plugin @Inject private OverlayManager overlayManager; - @Provides - InventoryViewerConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(InventoryViewerConfig.class); - } - @Override public void startUp() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java deleted file mode 100644 index e9d28f6b26..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.runelite.client.plugins.kittennotifier; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("kittennotifier") -public interface KittenNotifierConfig extends Config{ - @ConfigItem( - keyName = "absolutelyNeeded", - name = "Notify only on Absolute Need", - description = "Only notify when kitten absolutely needs food or attention." - ) - default boolean absolutelyNeeded() { return false; } - @ConfigItem( - keyName = "catOwned", - name = "", - description = "", - hidden = true - ) - default boolean catOwned() { return false; } - @ConfigItem( - keyName = "catOwned", - name = "", - description = "" - ) - void catOwned(Boolean bool); -} 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 deleted file mode 100644 index 921dcd4a46..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.runelite.client.plugins.kittennotifier; -import com.google.inject.Provides; -import net.runelite.api.ChatMessageType; -import net.runelite.api.events.ChatMessage; -import net.runelite.api.events.NpcActionChanged; -import net.runelite.api.events.NpcSpawned; -import net.runelite.client.Notifier; -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.api.NPC; -import net.runelite.api.Client; -import javax.inject.Inject; - -@PluginDescriptor( - name = "!Kitten Notifier", - description = "Sends a notification when your kitten needs food, attention, or is grown.", - tags = {"kitten, notifications"} -) -public class KittenNotifierPlugin extends Plugin{ - @Inject - private Notifier notifier; - @Inject - private KittenNotifierConfig config; - @Inject - private Client client; - @Provides - KittenNotifierConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(KittenNotifierConfig.class); - } - @Subscribe - public void onChatMessage(ChatMessage event) { - if (event.getType() == ChatMessageType.ENGINE && !config.catOwned()) { - if (!config.absolutelyNeeded()) { - if (event.getMessage().contentEquals("Your kitten is hungry.")) { - notifier.notify("Your kitten is hungry."); - } - if (event.getMessage().contentEquals("Your kitten wants attention.")) { - notifier.notify("Your kitten wants attention."); - } - } - if (event.getMessage().contentEquals("Your kitten is very hungry.")) { - notifier.notify("Your kitten is very hungry."); - } - if (event.getMessage().contentEquals("Your kitten really wants attention.")) { - notifier.notify("Your kitten really wants attention."); - } - } - } - @Subscribe - public void onNpcActionChanged(NpcActionChanged event) { - if (!config.catOwned()) { - for (NPC npc : client.getNpcs()) { - if (npc.getInteracting() != null) { - if (npc.getName().contentEquals("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); - notifier.notify("Your kitten has grown into a cat."); - } - } - } - } - } - } - @Subscribe - public void onNpcSpawned(NpcSpawned event) { - NPC cat = event.getNpc(); - if (cat.getName() != null) { - if (cat.getName().equalsIgnoreCase("Kitten")) { - if (cat.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) { - config.catOwned(false); - } - } - else if (cat.getName().contentEquals("Cat")) { - if (cat.getInteracting().getName().equalsIgnoreCase(client.getLocalPlayer().getName())) { - config.catOwned(true); - } - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanConfig.java deleted file mode 100644 index 33e61c0d46..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanConfig.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.runelite.client.plugins.lizardmenshaman; - -import net.runelite.client.config.Config; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("shaman") -public interface LizardmenShamanConfig extends Config -{ - @ConfigItem( - position = 1, - keyName = "showTimer", - name = "Show timer", - description = "Display timer till for lizardman shaman spawns." - ) - default boolean showTimer() - { - return true; - } - - @ConfigItem( - position = 2, - keyName = "notifyOnSpawn", - name = "Notify on spawn", - description = "Notify user when lizardman summons spawns." - ) - default boolean notifyOnSpawn() - { - return 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 deleted file mode 100644 index e6b3923fea..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java +++ /dev/null @@ -1,91 +0,0 @@ -package net.runelite.client.plugins.lizardmenshaman; - -import com.google.common.eventbus.Subscribe; -import com.google.inject.Provides; -import javax.inject.Inject; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Actor; -import net.runelite.api.Client; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.events.AnimationChanged; -import net.runelite.client.Notifier; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import java.util.HashMap; -import java.util.Map; -import net.runelite.client.ui.overlay.OverlayManager; - -@PluginDescriptor( - name = "!Lizard Shamans", - description = "Configures timer for lizardmen shaman spawns.", - enabledByDefault = false, - tags = {"shaman", "lizard", "lizardmen"} -) -@Slf4j -public class LizardmenShamanPlugin extends Plugin -{ - private static final String SHAMAN = "Lizardman shaman"; - private static final String MESSAGE = "A Lizardman shaman has summoned his spawn!"; - - @Getter(AccessLevel.PACKAGE) - private final Map spawns = new HashMap<>(); - - @Inject - private OverlayManager overlayManager; - - @Inject - private ShamanSpawnOverlay overlay; - - @Inject - private LizardmenShamanConfig config; - - @Inject - private Notifier notifier; - - @Inject - private Client client; - - @Provides - LizardmenShamanConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(LizardmenShamanConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - spawns.clear(); - } - - @Subscribe - public void onAnimationChanged(AnimationChanged event) - { - Actor actor = event.getActor(); - if (actor == null || actor.getName() == null) - { - return; - } - else if (actor.getName().equals(SHAMAN) && actor.getAnimation() == 7157) - { - if (config.showTimer()) - { - spawns.put(event.getActor().getLocalLocation(), new LizardmenShamanSpawn(8.4, null)); - } - - if (config.notifyOnSpawn()) - { - notifier.notify(MESSAGE); - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanSpawn.java b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanSpawn.java deleted file mode 100644 index d4297ed624..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanSpawn.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.runelite.client.plugins.lizardmenshaman; - -import java.time.Instant; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; - -@Getter -@Setter -@RequiredArgsConstructor -@AllArgsConstructor -class LizardmenShamanSpawn -{ - private final Instant start = Instant.now(); - private double countdownTimer; - private Instant end; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/ShamanSpawnOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/ShamanSpawnOverlay.java deleted file mode 100644 index 4d363e72c4..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/ShamanSpawnOverlay.java +++ /dev/null @@ -1,90 +0,0 @@ -package net.runelite.client.plugins.lizardmenshaman; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.time.Duration; -import java.time.Instant; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.ProgressPieComponent; - -class ShamanSpawnOverlay extends Overlay -{ - private final Client client; - private final LizardmenShamanPlugin plugin; - - @Inject - private ShamanSpawnOverlay(Client client, LizardmenShamanPlugin plugin) - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - this.client = client; - this.plugin = plugin; - } - @Override - public Dimension render(Graphics2D graphics) - { - plugin.getSpawns().forEach((localPoint, spawn) -> - { - final Instant now = Instant.now(); - final long startCountdown = Duration.between(spawn.getStart(), now).getSeconds(); - final double certainSec = spawn.getCountdownTimer() - startCountdown; - - if (certainSec <= 0) - { - if (spawn.getEnd() == null) - { - spawn.setEnd(Instant.now()); - } - } - - final ProgressPieComponent pieComponent = new ProgressPieComponent(); - final Point loc = Perspective.localToCanvas(client, localPoint, client.getPlane()); - - if (loc == null || certainSec < 0) - { - return; - } - - pieComponent.setPosition(loc); - pieComponent.setProgress(certainSec / spawn.getCountdownTimer()); - if (certainSec > 4.8) - { - pieComponent.setFill(Color.GREEN); - pieComponent.setBorderColor(Color.GREEN); - pieComponent.render(graphics); - } - else if (certainSec > 3.6) - { - pieComponent.setFill(Color.YELLOW); - pieComponent.setBorderColor(Color.YELLOW); - pieComponent.render(graphics); - } - else if (certainSec > 2.4) - { - pieComponent.setFill(Color.ORANGE); - pieComponent.setBorderColor(Color.ORANGE); - pieComponent.render(graphics); - } - else if (certainSec > 1.2) - { - pieComponent.setFill(new Color(255, 140, 0)); - pieComponent.setBorderColor(new Color(255, 140, 0)); - pieComponent.render(graphics); - } - else - { - pieComponent.setFill(Color.RED); - pieComponent.setBorderColor(Color.RED); - pieComponent.render(graphics); - } - }); - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java deleted file mode 100644 index 85a07780de..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2018 AWPH-I - * 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.lootingbagviewer; - -import net.runelite.api.Client; -import net.runelite.api.InventoryID; -import net.runelite.api.Item; -import net.runelite.api.ItemContainer; -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.ImageComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; - -import javax.inject.Inject; -import java.awt.*; -import java.awt.image.BufferedImage; - -class LootingBagViewerOverlay extends Overlay -{ - private static final int INVENTORY_SIZE = 28; - private static final int PLACEHOLDER_WIDTH = 36; - private static final int PLACEHOLDER_HEIGHT = 32; - private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(new BufferedImage(PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR)); - - private final Client client; - private final ItemManager itemManager; - - private final PanelComponent panelComponent = new PanelComponent(); - - private ItemContainer itemContainer; - private Item[] items; - - @Inject - private LootingBagViewerOverlay(Client client, ItemManager itemManager) - { - setPosition(OverlayPosition.BOTTOM_RIGHT); - panelComponent.setWrapping(4); - panelComponent.setGap(new Point(6, 4)); - panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); - this.itemManager = itemManager; - this.client = client; - - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (itemContainer == null) - { - if(client.getItemContainer(InventoryID.LOOTING_BAG) != null) { - itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); - items = itemContainer.getItems(); - } - return null; - } - else if(itemContainer != null && client.getItemContainer(InventoryID.LOOTING_BAG) != null) - { - itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); - Item[] tempItems = itemContainer.getItems(); - - for(int i = 0; i < items.length; i++) - { - if(!items[i].equals(tempItems[i])) - { - items = tempItems; - } - } - } - - panelComponent.getChildren().clear(); - - for (int i = 0; i < INVENTORY_SIZE; i++) - { - if (i < items.length) - { - final Item item = items[i]; - if (item.getQuantity() > 0) - { - final BufferedImage image = getImage(item); - if (image != null) - { - panelComponent.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); - } - - return panelComponent.render(graphics); - } - - private BufferedImage getImage(Item item) - { - return itemManager.getImage(item.getId(), item.getQuantity(), item.getQuantity() > 1); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java deleted file mode 100644 index d9cfdd7bf9..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2018 AWPH-I - * 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.lootingbagviewer; - -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; - -import javax.inject.Inject; - -@PluginDescriptor( - name = "PvP Looting Bag Viewer", - description = "Add an overlay showing the contents of your looting bag", - tags = {"alternate", "items", "overlay", "second"}, - enabledByDefault = false -) -public class LootingBagViewerPlugin extends Plugin -{ - @Inject - private net.runelite.client.plugins.lootingbagviewer.LootingBagViewerOverlay overlay; - - @Inject - private OverlayManager overlayManager; - - @Override - public void startUp() - { - overlayManager.add(overlay); - } - - @Override - public void shutDown() - { - overlayManager.remove(overlay); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index e60824686c..23ab63df16 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -1,308 +1,284 @@ -/* - * Copyright (c) 2018, Adam - * 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.menuentryswapper; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("menuentryswapper") -public interface MenuEntrySwapperConfig extends Config -{ - @ConfigItem( - position = -2, - keyName = "shiftClickCustomization", - name = "Customizable shift-click", - description = "Allows customization of shift-clicks on items" - ) - default boolean shiftClickCustomization() - { - return true; - } - - @ConfigItem( - keyName = "swapAdmire", - name = "Admire", - description = "Swap Admire with Teleport, Spellbook and Perks (max cape) for mounted skill capes." - ) - default boolean swapAdmire() - { - return true; - } - - @ConfigItem( - keyName = "swapAssignment", - name = "Assignment", - description = "Swap Talk-to with Assignment for Slayer Masters. This will take priority over swapping Trade." - ) - default boolean swapAssignment() - { - return true; - } - - @ConfigItem( - keyName = "swapBanker", - name = "Bank", - description = "Swap Talk-to with Bank on Bank NPC
Example: Banker" - ) - default boolean swapBank() - { - return true; - } - - @ConfigItem( - keyName = "swapBirdhouseEmpty", - name = "Birdhouse", - description = "Swap Interact with Empty for birdhouses on Fossil Island" - ) - default boolean swapBirdhouseEmpty() - { - return true; - } - - @ConfigItem( - keyName = "swapBones", - name = "Bury", - description = "Swap Bury with Use on Bones" - ) - default boolean swapBones() - { - return false; - } - - @ConfigItem( - keyName = "swapContract", - name = "Contract", - description = "Swap Talk-to with Contract on Guildmaster Jane" - ) - default boolean swapContract() - { - return true; - } - - @ConfigItem( - keyName = "swapChase", - name = "Chase", - description = "Allows to left click your cat to chase" - ) - default boolean swapChase() - { - return true; - } - - @ConfigItem( - keyName = "claimSlime", - name = "Claim Slime", - description = "Swap Talk-to with Claim Slime from Morytania diaries" - ) - default boolean claimSlime() - { - return true; - } - - @ConfigItem( - keyName = "swapDarkMage", - name = "Repairs", - description = "Swap Talk-to with Repairs for Dark Mage" - ) - default boolean swapDarkMage() - { - return true; - } - - @ConfigItem( - keyName = "swapDecant", - name = "Decant", - description = "Swap Talk-to with Decant for Bob Barter and Murky Matt at the Grand Exchange." - ) - default boolean swapDecant() - { - return false; - } - - @ConfigItem( - keyName = "swapExchange", - name = "Exchange", - description = "Swap Talk-to with Exchange on NPC
Example: Grand Exchange Clerk, Tool Leprechaun, Void Knight" - ) - default boolean swapExchange() - { - return true; - } - - @ConfigItem( - keyName = "swapFairyRing", - name = "Fairy ring", - description = "Swap Zanaris with Last-destination or Configure on Fairy rings" - ) - default FairyRingMode swapFairyRing() - { - return FairyRingMode.LAST_DESTINATION; - } - - @ConfigItem( - keyName = "swapHarpoon", - name = "Harpoon", - description = "Swap Cage, Big Net with Harpoon on Fishing spot" - ) - default boolean swapHarpoon() - { - return false; - } - - @ConfigItem( - keyName = "swapHomePortal", - name = "Home", - description = "Swap Enter with Home or Build or Friend's house on Portal" - ) - default HouseMode swapHomePortal() - { - return HouseMode.HOME; - } - - @ConfigItem( - keyName = "swapPickpocket", - name = "Pickpocket on H.A.M.", - description = "Swap Talk-to with Pickpocket on H.A.M members" - ) - default boolean swapPickpocket() - { - return true; - } - - @ConfigItem( - keyName = "swapBlackjack", - name = "Blackjacking", - description = "Requires \"The Fued\" quest completed." - ) - - default boolean swapBlackjack() {return false; } - - - @ConfigItem( - keyName = "setDelay", - name = "Blackjacking Delay", - description = "Sets the delay for how long you can pickpocket after knocking target out in milliseconds" - ) - default int setDelay() - { - return 2000; - } - - - @ConfigItem( - keyName = "swapPay", - name = "Pay", - description = "Swap Talk-to with Pay on NPC
Example: Elstan, Heskel, Fayeth" - ) - - - - - default boolean swapPay() - { - return true; - } - - @ConfigItem( - keyName = "swapPrivate", - name = "Private", - description = "Swap Shared with Private on the Chambers of Xeric storage units." - ) - default boolean swapPrivate() - { - return false; - } - - @ConfigItem( - keyName = "swapPick", - name = "Pick", - description = "Swap Pick with Pick-lots of the Gourd tree in the Chambers of Xeric" - ) - default boolean swapPick() - { - return false; - } - - @ConfigItem( - keyName = "swapQuick", - name = "Quick Pass/Open/Start/Travel", - description = "Swap Pass with Quick-Pass, Open with Quick-Open, Ring with Quick-Start and Talk-to with Quick-Travel" - ) - default boolean swapQuick() - { - return true; - } - - @ConfigItem( - keyName = "swapBoxTrap", - name = "Reset", - description = "Swap Check with Reset on box trap" - ) - default boolean swapBoxTrap() - { - return true; - } - - @ConfigItem( - keyName = "swapTeleportItem", - name = "Teleport item", - description = "Swap Wear, Wield with Rub, Teleport on teleport item
Example: Amulet of glory, Explorer's ring, Chronicle" - ) - default boolean swapTeleportItem() - { - return false; - } - - @ConfigItem( - keyName = "swapAbyssTeleport", - name = "Teleport to Abyss", - description = "Swap Talk-to with Teleport for the Mage of Zamorak" - ) - default boolean swapAbyssTeleport() - { - return true; - } - - @ConfigItem( - keyName = "swapTrade", - name = "Trade", - description = "Swap Talk-to with Trade on NPC
Example: Shop keeper, Shop assistant" - ) - default boolean swapTrade() - { - return true; - } - - @ConfigItem( - keyName = "swapTravel", - name = "Travel", - description = "Swap Talk-to with Travel, Take-boat, Pay-fare, Charter on NPC
Example: Squire, Monk of Entrana, Customs officer, Trader Crewmember" - ) - default boolean swapTravel() - { - return true; - } -} +/* + * Copyright (c) 2018, Adam + * 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.menuentryswapper; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("menuentryswapper") +public interface MenuEntrySwapperConfig extends Config +{ + @ConfigItem( + position = -2, + keyName = "shiftClickCustomization", + name = "Customizable shift-click", + description = "Allows customization of shift-clicks on items" + ) + default boolean shiftClickCustomization() + { + return true; + } + + @ConfigItem( + keyName = "swapAdmire", + name = "Admire", + description = "Swap Admire with Teleport, Spellbook and Perks (max cape) for mounted skill capes." + ) + default boolean swapAdmire() + { + return true; + } + + @ConfigItem( + keyName = "swapAssignment", + name = "Assignment", + description = "Swap Talk-to with Assignment for Slayer Masters. This will take priority over swapping Trade." + ) + default boolean swapAssignment() + { + return true; + } + + @ConfigItem( + keyName = "swapBanker", + name = "Bank", + description = "Swap Talk-to with Bank on Bank NPC
Example: Banker" + ) + default boolean swapBank() + { + return true; + } + + @ConfigItem( + keyName = "swapBirdhouseEmpty", + name = "Birdhouse", + description = "Swap Interact with Empty for birdhouses on Fossil Island" + ) + default boolean swapBirdhouseEmpty() + { + return true; + } + + @ConfigItem( + keyName = "swapBones", + name = "Bury", + description = "Swap Bury with Use on Bones" + ) + default boolean swapBones() + { + return false; + } + + @ConfigItem( + keyName = "swapContract", + name = "Contract", + description = "Swap Talk-to with Contract on Guildmaster Jane" + ) + default boolean swapContract() + { + return true; + } + + @ConfigItem( + keyName = "swapChase", + name = "Chase", + description = "Allows to left click your cat to chase" + ) + default boolean swapChase() + { + return true; + } + + @ConfigItem( + keyName = "claimSlime", + name = "Claim Slime", + description = "Swap Talk-to with Claim Slime from Morytania diaries" + ) + default boolean claimSlime() + { + return true; + } + + @ConfigItem( + keyName = "swapDarkMage", + name = "Repairs", + description = "Swap Talk-to with Repairs for Dark Mage" + ) + default boolean swapDarkMage() + { + return true; + } + + @ConfigItem( + keyName = "swapDecant", + name = "Decant", + description = "Swap Talk-to with Decant for Bob Barter and Murky Matt at the Grand Exchange." + ) + default boolean swapDecant() + { + return false; + } + + @ConfigItem( + keyName = "swapExchange", + name = "Exchange", + description = "Swap Talk-to with Exchange on NPC
Example: Grand Exchange Clerk, Tool Leprechaun, Void Knight" + ) + default boolean swapExchange() + { + return true; + } + + @ConfigItem( + keyName = "swapFairyRing", + name = "Fairy ring", + description = "Swap Zanaris with Last-destination or Configure on Fairy rings" + ) + default FairyRingMode swapFairyRing() + { + return FairyRingMode.LAST_DESTINATION; + } + + @ConfigItem( + keyName = "swapHarpoon", + name = "Harpoon", + description = "Swap Cage, Big Net with Harpoon on Fishing spot" + ) + default boolean swapHarpoon() + { + return false; + } + + @ConfigItem( + keyName = "swapHomePortal", + name = "Home", + description = "Swap Enter with Home or Build or Friend's house on Portal" + ) + default HouseMode swapHomePortal() + { + return HouseMode.HOME; + } + + @ConfigItem( + keyName = "swapPickpocket", + name = "Pickpocket on H.A.M.", + description = "Swap Talk-to with Pickpocket on H.A.M members" + ) + default boolean swapPickpocket() + { + return true; + } + + @ConfigItem( + keyName = "swapPay", + name = "Pay", + description = "Swap Talk-to with Pay on NPC
Example: Elstan, Heskel, Fayeth" + ) + default boolean swapPay() + { + return true; + } + + @ConfigItem( + keyName = "swapPrivate", + name = "Private", + description = "Swap Shared with Private on the Chambers of Xeric storage units." + ) + default boolean swapPrivate() + { + return false; + } + + @ConfigItem( + keyName = "swapPick", + name = "Pick", + description = "Swap Pick with Pick-lots of the Gourd tree in the Chambers of Xeric" + ) + default boolean swapPick() + { + return false; + } + + @ConfigItem( + keyName = "swapQuick", + name = "Quick Pass/Open/Start/Travel", + description = "Swap Pass with Quick-Pass, Open with Quick-Open, Ring with Quick-Start and Talk-to with Quick-Travel" + ) + default boolean swapQuick() + { + return true; + } + + @ConfigItem( + keyName = "swapBoxTrap", + name = "Reset", + description = "Swap Check with Reset on box trap" + ) + default boolean swapBoxTrap() + { + return true; + } + + @ConfigItem( + keyName = "swapTeleportItem", + name = "Teleport item", + description = "Swap Wear, Wield with Rub, Teleport on teleport item
Example: Amulet of glory, Explorer's ring, Chronicle" + ) + default boolean swapTeleportItem() + { + return false; + } + + @ConfigItem( + keyName = "swapAbyssTeleport", + name = "Teleport to Abyss", + description = "Swap Talk-to with Teleport for the Mage of Zamorak" + ) + default boolean swapAbyssTeleport() + { + return true; + } + + @ConfigItem( + keyName = "swapTrade", + name = "Trade", + description = "Swap Talk-to with Trade on NPC
Example: Shop keeper, Shop assistant" + ) + default boolean swapTrade() + { + return true; + } + + @ConfigItem( + keyName = "swapTravel", + name = "Travel", + description = "Swap Talk-to with Travel, Take-boat, Pay-fare, Charter on NPC
Example: Squire, Monk of Entrana, Customs officer, Trader Crewmember" + ) + default boolean swapTravel() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index 0ff5e23915..b164d10b86 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -31,8 +31,19 @@ import java.util.Set; import javax.inject.Inject; import lombok.Getter; import lombok.Setter; -import net.runelite.api.*; -import net.runelite.api.events.*; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.ItemComposition; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; +import net.runelite.api.NPC; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.FocusChanged; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.MenuOpened; +import net.runelite.api.events.MenuOptionClicked; +import net.runelite.api.events.PostItemComposition; +import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; @@ -48,7 +59,7 @@ import net.runelite.client.util.Text; import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( - name = "!Menu Entry Swapper", + name = "Menu Entry Swapper", description = "Change the default option that is displayed when hovering over objects", tags = {"npcs", "inventory", "items", "objects"}, enabledByDefault = false @@ -89,9 +100,6 @@ public class MenuEntrySwapperPlugin extends Plugin MenuAction.NPC_FIFTH_OPTION, MenuAction.EXAMINE_NPC); - private static long timeSinceKnockout; - private static long timeSinceAggro; - @Inject private Client client; @@ -363,19 +371,6 @@ public class MenuEntrySwapperPlugin extends Plugin return; } - if (config.swapBlackjack() && (target.contains("bandit") | target.contains("menaphite thug"))) { - Quest quest = Quest.THE_FEUD; - if (quest.getState(client) == QuestState.FINISHED) { - if (System.currentTimeMillis() < (timeSinceKnockout + config.setDelay())) { - swap("pickpocket", option, target, true); - } - if (System.currentTimeMillis() < (timeSinceAggro + 1300)) { - swap("pickpocket", option, target, true); - } - swap("knock-out", option, target, true); - } - } - if (option.equals("talk-to")) { if (config.swapPickpocket() && target.contains("h.a.m.")) @@ -598,17 +593,6 @@ public class MenuEntrySwapperPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) { - if (event.getType() == ChatMessageType.SPAM) { - if (event.getMessage().contains("ou smack the bandit over the head and render them unconsci")) { - timeSinceKnockout = System.currentTimeMillis(); - } else if (event.getMessage().contains("our blow only glances off the bandi")) { - timeSinceAggro = System.currentTimeMillis(); - } - } - } - private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict) { for (int i = entries.length - 1; i >= 0; i--) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierConfig.java deleted file mode 100644 index 53f49012c2..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierConfig.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.runelite.client.plugins.menumodifier; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("menumodifier") -public interface MenuModifierConfig extends Config -{ - @ConfigItem(position = 0, keyName = "hideCancel", name = "Hide Cancel", description = "Hides the 'cancel' option from the right click menu") - default boolean hideCancel() { return true; } - - @ConfigItem(position = 1, keyName = "hideExamine", name = "Hide Examine", description = "Hides the 'examine' option from the right click menu") - default boolean hideExamine() { return true; } - - @ConfigItem(position = 2, keyName = "hideTradeWith", name = "Hide Trade With", description = "Hides the 'trade with' option from the right click menu") - default boolean hideTradeWith() { return true; } - - @ConfigItem(position = 3, keyName = "hideReport", name = "Hide Report", description = "Hides the 'report' option from the right click menu") - default boolean hideReport() { return true; } - - @ConfigItem(position = 4, keyName = "hideLookup", name = "Hide Lookup", description = "Hides the 'lookup' option from the right click menu") - default boolean hideLookup() { return true; } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierInputListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierInputListener.java deleted file mode 100644 index cbb15161f8..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierInputListener.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.runelite.client.plugins.menumodifier; - -import net.runelite.client.input.KeyListener; -import net.runelite.client.input.MouseAdapter; - -import javax.inject.Inject; -import java.awt.event.KeyEvent; - -public class MenuModifierInputListener extends MouseAdapter implements KeyListener -{ - private static final int HOTKEY = KeyEvent.VK_CONTROL; - - @Override - public void keyTyped(KeyEvent e) - { - - } - - @Inject - private MenuModifierPlugin plugin; - - @Override - public void keyPressed(KeyEvent e) - { - if (e.getKeyCode() == HOTKEY) - { - plugin.setHotKeyPressed(true); - } - } - - @Override - public void keyReleased(KeyEvent e) - { - if (e.getKeyCode() == HOTKEY) - { - plugin.setHotKeyPressed(false); - } - } -} 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 deleted file mode 100644 index dc5b9e7a27..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierPlugin.java +++ /dev/null @@ -1,168 +0,0 @@ -package net.runelite.client.plugins.menumodifier; - -import net.runelite.api.events.MenuOpened; -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Setter; -import net.runelite.api.Client; -import net.runelite.api.MenuEntry; -import net.runelite.api.Player; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.MenuEntryAdded; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.input.KeyManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.util.MiscUtils; -import net.runelite.client.util.Text; - -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -@PluginDescriptor( - name = "!Menu Modifier", - description = "Changes right click menu for players", - tags = { "menu", "modifier", "right", "click", "pk", "bogla" }, - enabledByDefault = false -) -public class MenuModifierPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private MenuModifierConfig config; - - @Inject - private MenuModifierInputListener inputListener; - - @Inject - private KeyManager keyManager; - - @Provides - MenuModifierConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(MenuModifierConfig.class); - } - - @Override - protected void startUp() throws Exception - { - keyManager.registerKeyListener(inputListener); - } - - @Override - protected void shutDown() throws Exception - { - keyManager.unregisterKeyListener(inputListener); - } - - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private boolean hotKeyPressed; - - @Subscribe - public void onMenuOpened(MenuOpened event) - { - Player localPlayer = client.getLocalPlayer(); - - if (localPlayer == null) - return; - - if (!(MiscUtils.getWildernessLevelFrom(client, localPlayer.getWorldLocation()) >= 0)) - return; - - if (hotKeyPressed) - return; - - List menu_entries = new ArrayList(); - - for (MenuEntry entry : event.getMenuEntries()) - { - String option = Text.removeTags(entry.getOption()).toLowerCase(); - - if (option.contains("trade with") && config.hideTradeWith()) - continue; - - if (option.contains("lookup") && config.hideLookup()) - continue; - - if (option.contains("report") && config.hideReport()) - continue; - - if (option.contains("examine") && config.hideExamine()) - continue; - - int identifier = entry.getIdentifier(); - - Player[] players = client.getCachedPlayers(); - Player player = null; - - if (identifier >= 0 && identifier < players.length) - player = players[identifier]; - - if (player == null) - { - menu_entries.add(entry); - continue; - } - - if ((option.contains("attack") || option.contains("cast")) && (player.isFriend() || player.isClanMember())) - continue; - - menu_entries.add(entry); - } - - MenuEntry[] updated_menu_entries = new MenuEntry[menu_entries.size()]; - updated_menu_entries = menu_entries.toArray(updated_menu_entries); - - client.setMenuEntries(updated_menu_entries); - } - - /*@Subscribe - public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) - { - if (true) - return; - - if (!inWilderness) - return; - - if (hotKeyPressed) - return; - - String option = Text.removeTags(menuEntryAdded.getOption()).toLowerCase(); - - if ((option.contains("trade with") && config.hideTradeWith()) - || (option.contains("lookup") && config.hideLookup()) - || (option.contains("report") && config.hideReport()) - || (option.contains("examine") && config.hideExamine()) - || (option.contains("cancel") && config.hideCancel())) - { - int identifier = menuEntryAdded.getIdentifier(); - - Player[] players = client.getCachedPlayers(); - Player player = null; - - if (identifier >= 0 && identifier < players.length) - player = players[identifier]; - - if (player == null) - return; - - //allow trading with friends/clanmates - if (option.contains("trade with") && (player.isFriend() || player.isClanMember())) - return; - - MenuEntry[] menuEntries = client.getMenuEntries(); - - if (menuEntries.length > 0) - client.setMenuEntries(Arrays.copyOf(menuEntries, menuEntries.length - 1)); - } - }*/ -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MinedRock.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MinedRock.java deleted file mode 100644 index e970077dfa..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MinedRock.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import lombok.AccessLevel; -import lombok.Getter; - -public class MinedRock -{ - - @Getter(AccessLevel.PACKAGE) - private final MiningRockType type; - - private final long minRespawnTime, maxRespawnTime; - - public MinedRock(MiningRockType type, boolean halve) - { - this.type = type; - this.minRespawnTime = System.currentTimeMillis() + (int)((halve ? type.getMinRespawnTime() / 2 : type.getMinRespawnTime()) * 1000); - this.maxRespawnTime = type.getMaxRespawnTime() == -1 ? -1 : System.currentTimeMillis() + (int)((halve ? type.getMaxRespawnTime() / 2 : type.getMaxRespawnTime()) * 1000); - } - - public int getMinSecondsUntilRespawn(boolean allowNegative) - { - long remaining = minRespawnTime - System.currentTimeMillis(); - if (remaining > 0 || allowNegative) - { - return (int) (remaining / 1000) + (remaining % 1000 > 0 ? 1 : 0); - } - else - { - return (maxRespawnTime > minRespawnTime) ? 0 : 1; - } - } - - public int getMaxSecondsUntilRespawn() - { - if (maxRespawnTime == -1) - { - return -1; - } - long remaining = maxRespawnTime - System.currentTimeMillis(); - if (remaining > 0 && maxRespawnTime > minRespawnTime) - { - return (int) (remaining / 1000) + (remaining % 1000 > 0 ? 1 : 0); - } - else - { - // Return -1 if the ore does not have a maximum respawn time (no range) - return 1; - } - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningConfig.java deleted file mode 100644 index 960542aff0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningConfig.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("miningplugin") -public interface MiningConfig extends Config -{ - - @ConfigItem( - position = 1, - keyName = "statTimeout", - name = "Reset stats (minutes)", - description = "The time until mining session data is reset in minutes." - ) - default int statTimeout() - { - return 5; - } - - @ConfigItem( - position = 2, - keyName = "showRespawn", - name = "Show ore respawn timers", - description = "If the amount of seconds left until a ore respawns should be shown." - ) - default boolean showRespawnTimer() - { - return true; - } - - @ConfigItem( - position = 3, - keyName = "showAllRespawns", - name = "Show timers for every ore", - description = "Show timers for every ore mined in your nearby vicinity" - ) - default boolean showAllRespawnTimers() - { - return false; - } - - @ConfigItem( - position = 4, - keyName = "showMiningStats", - name = "Show mining session stats", - description = "Configures whether to display mining session stats" - ) - default boolean showMiningStats() - { - return true; - } - - @ConfigItem( - position = 5, - keyName = "showMiningState", - name = "Show current mining state", - description = "Shows current mining state. 'You are currently mining' / 'You are currently NOT mining'" - ) - default boolean showMiningState() - { - return true; - } - - @ConfigItem( - position = 6, - keyName = "disableInMLM", - name = "Disable in MLM", - description = "Disables the trackers if you're in the motherloade mine" - ) - default boolean disableInMLM() - { - return true; - } - - @ConfigItem( - position = 7, - keyName = "trackWorldRock", - name = "World Tracker", - description = "Tracks the respawn time of a certain ore as you switch worlds" - ) - default MiningRockType.WorldRock trackWorldRock() - { - return MiningRockType.WorldRock.None; - } - - @ConfigItem( - position = 8, - keyName = "trackTimeout", - name = "Stop tracking (seconds)", - description = "The time a world will keep on displaying after the ore has respawned in seconds" - ) - default int trackTimeout() - { - return 60; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java deleted file mode 100644 index bf19cb9bb1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import com.google.common.collect.ImmutableSet; -import static net.runelite.api.AnimationID.MINING_3A_PICKAXE; -import static net.runelite.api.AnimationID.MINING_ADAMANT_PICKAXE; -import static net.runelite.api.AnimationID.MINING_BLACK_PICKAXE; -import static net.runelite.api.AnimationID.MINING_BRONZE_PICKAXE; -import static net.runelite.api.AnimationID.MINING_DRAGON_PICKAXE; -import static net.runelite.api.AnimationID.MINING_DRAGON_PICKAXE_ORN; -import static net.runelite.api.AnimationID.MINING_INFERNAL_PICKAXE; -import static net.runelite.api.AnimationID.MINING_IRON_PICKAXE; -import static net.runelite.api.AnimationID.MINING_MITHRIL_PICKAXE; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_ADAMANT; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_BLACK; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_BRONZE; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_DRAGON; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_DRAGON_ORN; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_INFERNAL; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_IRON; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_MITHRIL; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_RUNE; -import static net.runelite.api.AnimationID.MINING_MOTHERLODE_STEEL; -import static net.runelite.api.AnimationID.MINING_RUNE_PICKAXE; -import static net.runelite.api.AnimationID.MINING_STEEL_PICKAXE; -import net.runelite.api.Client; -import net.runelite.client.game.SkillIconManager; -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 javax.inject.Inject; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.time.Duration; -import java.time.Instant; -import java.util.Set; - -/** - * Displays information about the players current mining state and rocks mined - */ -public class MiningOverlay extends Overlay -{ - - private static final Set MINING_ANIMATION_IDS = ImmutableSet.of( - MINING_3A_PICKAXE, MINING_ADAMANT_PICKAXE, MINING_BLACK_PICKAXE, - MINING_BRONZE_PICKAXE, MINING_DRAGON_PICKAXE, MINING_DRAGON_PICKAXE_ORN, - MINING_INFERNAL_PICKAXE, MINING_IRON_PICKAXE, MINING_MITHRIL_PICKAXE, - MINING_RUNE_PICKAXE, MINING_STEEL_PICKAXE, MINING_MOTHERLODE_BRONZE, - MINING_MOTHERLODE_IRON, MINING_MOTHERLODE_STEEL, MINING_MOTHERLODE_BLACK, - MINING_MOTHERLODE_MITHRIL, MINING_MOTHERLODE_ADAMANT, MINING_MOTHERLODE_RUNE, - MINING_MOTHERLODE_DRAGON, MINING_MOTHERLODE_DRAGON_ORN, MINING_MOTHERLODE_INFERNAL - ); - - private final MiningConfig config; - private final Client client; - private final MiningPlugin plugin; - private final PanelComponent panelComponent = new PanelComponent(); - - @Inject - MiningOverlay(Client client, MiningPlugin plugin, MiningConfig config, SkillIconManager iconManager) - { - setPosition(OverlayPosition.TOP_LEFT); - this.client = client; - this.config = config; - this.plugin = plugin; - } - - @Override - public Dimension render(Graphics2D graphics) - { - // Prevents conflicts with the motherloade plugin - if (config.disableInMLM() && plugin.isInMlm()) - { - return null; - } - - panelComponent.getChildren().clear(); - - if (config.showMiningState()) - { - if (MINING_ANIMATION_IDS.contains(client.getLocalPlayer().getAnimation())) - { - panelComponent.getChildren().add(TitleComponent.builder() - .text("Mining") - .color(Color.GREEN) - .build()); - } - else - { - panelComponent.getChildren().add(TitleComponent.builder() - .text("NOT mining") - .color(Color.RED) - .build()); - } - } - - MiningSession session = plugin.getSession(); - if (session.getLastMined() != null) - { - Duration statTimeout = Duration.ofMinutes(config.statTimeout()); - Duration sinceCut = Duration.between(session.getLastMined(), Instant.now()); - if (sinceCut.compareTo(statTimeout) < 0) - { - if (config.showMiningStats()) - { - for (MiningRockType rock : MiningRockType.values()) - { - if (session.showRockRespawnTimes(rock)) - { - panelComponent.getChildren().add(LineComponent.builder() - .left(rock.getName() + " mined:") - .right(Integer.toString(session.getSessionStats().get(rock).getTotalMined())) - .build()); - panelComponent.getChildren().add(LineComponent.builder() - .left(rock.getName() + "/hr:") - .right(session.getSessionStats().get(rock).getRecentMined() > 2 ? Integer.toString(session.getSessionStats().get(rock).getPerHour()) : "") - .build()); - } - } - } - if (panelComponent.getChildren().size() > 0) - { - return panelComponent.render(graphics); - } - } - } - return null; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java deleted file mode 100644 index 4414464636..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import com.google.common.collect.ImmutableSet; -import com.google.inject.Provides; -import lombok.AccessLevel; -import lombok.Getter; -import net.runelite.api.ChatMessageType; -import net.runelite.api.Client; -import net.runelite.api.Experience; -import net.runelite.api.GameObject; -import net.runelite.api.GameState; -import net.runelite.api.Skill; -import net.runelite.api.TileObject; -import net.runelite.api.WallObject; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.ChatMessage; -import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.ExperienceChanged; -import net.runelite.api.events.GameObjectDespawned; -import net.runelite.api.events.GameObjectSpawned; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.WallObjectDespawned; -import net.runelite.api.events.WallObjectSpawned; -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.task.Schedule; -import net.runelite.client.ui.overlay.OverlayManager; -import javax.inject.Inject; -import java.time.Duration; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.HashMap; -import java.util.Set; - -@PluginDescriptor( - name = "Mining", - description = "Show helpful information when mining", - tags = {"mining", "mine"}, - enabledByDefault = false -) -public class MiningPlugin extends Plugin -{ - - @Inject - private OverlayManager overlayManager; - - @Inject - MiningRockOverlay oreOverlay; - - @Inject - MiningWorldHopperOverlay worldHopperOverlay; - - @Inject - MiningOverlay miningOverlay; - - @Inject - MiningConfig config; - - @Inject - private Client client; - - @Getter(AccessLevel.PACKAGE) - private int miningLevel; - - @Getter(AccessLevel.PACKAGE) - private final HashMap ores = new HashMap<>(); - - @Provides - MiningConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(MiningConfig.class); - } - - @Getter(AccessLevel.PACKAGE) - private MiningSession session; - - @Getter(AccessLevel.PUBLIC) - private MiningWorldTracker miningTracker; - - private static final Set MOTHERLODE_MAP_REGIONS = ImmutableSet.of(14679, 14680, 14681, 14935, 14936, 14937, 15191, 15192, 15193); - private static final int P2P_MINING_GUILD_REGION = 12183; - private final static int MINING_GUILD_RESPAWN_RATE_HALVE_Y = 9727; - - @Override - protected void startUp() - { - overlayManager.add(miningOverlay); - overlayManager.add(oreOverlay); - overlayManager.add(worldHopperOverlay); - session = new MiningSession(); - if (config.trackWorldRock() != MiningRockType.WorldRock.None) - { - miningTracker = new MiningWorldTracker(config.trackWorldRock()); - } - else - { - miningTracker = null; - } - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(miningOverlay); - overlayManager.remove(oreOverlay); - overlayManager.remove(worldHopperOverlay); - ores.clear(); - miningLevel = Experience.getLevelForXp(client.getSkillExperience(Skill.MINING)); - session = null; - miningTracker = null; - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (event.getKey().equals("trackWorldRock")) - { - MiningRockType.WorldRock worldRock = config.trackWorldRock(); - if (worldRock == MiningRockType.WorldRock.None) - { - miningTracker = null; - } - else - { - miningTracker = new MiningWorldTracker(config.trackWorldRock()); - } - } - } - - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) - { - GameObject object = event.getGameObject(); - MiningRockType rock = MiningRockType.getTypeFromID(object.getId()); - if (rock != null) - { - for (TileObject o : ores.keySet()) - { - if (o.getX() == object.getX() && o.getY() == object.getY()) - { - // Remove ground rock as it has respawned - ores.remove(o); - break; - } - } - } - } - - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) - { - Duration timeSinceStart = Duration.between(session.getIgnoreSpawn(), Instant.now()); - // Ignore anything spawned within 1 second of logging in or changing regions (prevents timers appearing on already mined rocks) - if (timeSinceStart.getSeconds() > 1) - { - GameObject object = event.getGameObject(); - MiningRockType rock = MiningRockType.getTypeFromID(object.getId()); - if (rock != null && miningLevel >= rock.getRequiredMiningLevel()) - { - if (!ores.containsKey(object)) - { - ores.put(object, new MinedRock(rock, isInMiningGuildPay2Play(object.getWorldLocation()))); - } - } - } - } - - @Subscribe - public void onWallObjectSpawned(WallObjectSpawned event) - { - Duration timeSinceStart = Duration.between(session.getIgnoreSpawn(), Instant.now()); - // Ignore anything spawned within 1 second of logging in or changing regions (prevents timers appearing on already mined rocks) - if (timeSinceStart.getSeconds() > 1) - { - WallObject object = event.getWallObject(); - MiningRockType rock = MiningRockType.getTypeFromID(object.getId()); - if (rock != null && miningLevel >= rock.getRequiredMiningLevel()) - { - if (!ores.containsKey(object)) - { - ores.put(object, new MinedRock(rock, isInMiningGuildPay2Play(object.getWorldLocation()))); - } - } - } - } - - @Subscribe - public void onWallObjectDespawned(WallObjectDespawned event) - { - WallObject object = event.getWallObject(); - MiningRockType rock = MiningRockType.getTypeFromID(object.getId()); - if (rock != null) - { - for (TileObject o : ores.keySet()) - { - if (o.getX() == object.getX() && o.getY() == object.getY()) - { - // Remove wall rock as it has respawned - ores.remove(o); - break; - } - } - } - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - GameState state = event.getGameState(); - if (state == GameState.HOPPING) - { - MiningRockType.WorldRock worldRock = config.trackWorldRock(); - if (worldRock != MiningRockType.WorldRock.None) - { - int world = client.getWorld(); - for (TileObject rock : ores.keySet()) - { - if (worldRock.getRockType() == ores.get(rock).getType()) - { - // If the type matches the multi-world rock then add to the mining tracker for this world - miningTracker.addTracked(world, rock, ores.get(rock)); - } - } - } - } - else if (state == GameState.LOADING) - { - ores.clear(); - session.setIgnoreSpawn(Instant.now()); - } - else if (state == GameState.LOGGED_IN) - { - int world = client.getWorld(); - if (miningTracker != null && miningTracker.getTrackedWorlds().containsKey(world)) - { - MiningWorld track = miningTracker.getTrackedWorlds().get(world); - track.clearNegativeRespawnTimes(); - // Load all the tracked ores in this world into the current session. Causing their respawn times to be rendered - for (TileObject o : track.getRocks().keySet()) - { - ores.put(o, track.getRocks().get(o)); - } - // We're on this world now, so don't track it in the world tracker anymore - miningTracker.getTrackedWorlds().remove(world); - } - } - } - - @Subscribe - public void onExperienceChanged(ExperienceChanged event) - { - if (event.getSkill() == Skill.MINING) - { - miningLevel = Experience.getLevelForXp(client.getSkillExperience(Skill.MINING)); - } - } - - @Subscribe - public void onChatMessage(ChatMessage event) - { - if (event.getType() != ChatMessageType.SPAM) - { - return; - } - if (event.getMessage().startsWith("You manage to mine some")) - { - String oreName = event.getMessage().substring(24).replace(".", ""); - MiningRockType rock = MiningRockType.getTypeFromName(oreName); - if (rock != null) - { - session.increaseRockMine(rock); - } - - } - } - - @Schedule( - period = 1, - unit = ChronoUnit.SECONDS - ) - public void checkIsMining() - { - for (MiningRockType rock : MiningRockType.values()) - { - if (session.getSessionStats().get(rock).getLastOreMined() != null) - { - Duration statTimeout = Duration.ofMinutes(config.statTimeout()); - Duration sinceMined = Duration.between(session.getSessionStats().get(rock).getLastOreMined(), Instant.now()); - if (sinceMined.compareTo(statTimeout) >= 0) - { - session.clearSessionFor(rock); - } - } - } - } - - public boolean isInMlm() - { - if (client.getGameState() != GameState.LOGGED_IN) - { - return false; - } - - int[] currentMapRegions = client.getMapRegions(); - // Verify that all regions exist in MOTHERLODE_MAP_REGIONS - for (int region : currentMapRegions) - { - if (!MOTHERLODE_MAP_REGIONS.contains(region)) - { - return false; - } - } - - return true; - } - - public boolean isInMiningGuildPay2Play(WorldPoint point) - { - if (client.getGameState() != GameState.LOGGED_IN) - { - return false; - } - - int[] currentMapRegions = client.getMapRegions(); - for (int region : currentMapRegions) - { - if (region == P2P_MINING_GUILD_REGION) - { - return (point.getY() <= MINING_GUILD_RESPAWN_RATE_HALVE_Y); - } - } - return false; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningRockOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningRockOverlay.java deleted file mode 100644 index 492e79b276..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningRockOverlay.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Player; -import net.runelite.api.Point; -import net.runelite.api.TileObject; -import net.runelite.api.coords.LocalPoint; -import net.runelite.client.game.SkillIconManager; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import javax.inject.Inject; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import net.runelite.client.ui.overlay.OverlayPosition; - -/** - * Displays respawn timers over rocks - */ -public class MiningRockOverlay extends Overlay -{ - - private static final int MAX_DISTANCE = 2350; - - private final MiningConfig config; - private final Client client; - private final MiningPlugin plugin; - - @Inject - MiningRockOverlay(Client client, MiningPlugin plugin, MiningConfig config, SkillIconManager iconManager) - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - this.client = client; - this.config = config; - this.plugin = plugin; - } - - @Override - public Dimension render(Graphics2D graphics) - { - Player local = client.getLocalPlayer(); - if (config.showRespawnTimer()) - { - renderRespawnTimers(graphics, local); - } - return null; - } - - private void renderRespawnTimers(Graphics2D graphics, Player local) - { - LocalPoint localLocation = local.getLocalLocation(); - for (TileObject ore : plugin.getOres().keySet()) - { - MinedRock rock = plugin.getOres().get(ore); - if ((config.showAllRespawnTimers() || plugin.getSession().showRockRespawnTimes(rock.getType())) && localLocation.distanceTo(ore.getLocalLocation()) <= MAX_DISTANCE) - { - // Check if we should display this rock to the user. Checks if the user has mined the rock within this session (or has all on within config) & is within range - renderRespawnTimerRock(graphics, ore, rock.getMinSecondsUntilRespawn(false), rock.getMaxSecondsUntilRespawn(), rock.getType().isGroundObject()); - } - } - } - - /** - * Renders a rocks respawn time - * @param rock The rock - * @param time Time until the rock respawns (minimum) - * @param max Maximum time until the rock respawns (-1 = no range) - * @param ground If the rock is on the ground (true = ground, false = wall) - used to offset the respawn time text - */ - private void renderRespawnTimerRock(Graphics2D graphics, TileObject rock, int time, int max, boolean ground) - { - Point canvasLoc = Perspective.getCanvasTextLocation(client, graphics, rock.getLocalLocation(), "" + time, ground ? 0 : 150); - if (canvasLoc != null) - { - String timeMessage = "" + time; - // Check if this rock has a respawn time range - if (max != -1) - { - // Check if the rock has reached the minimum respawn time - if (time <= 0) - { - // Display the maximum possible time remaining - timeMessage = "~" + max; - graphics.setColor(Color.CYAN); - } - else - { - // Rock has not yet reached the minimum respawn time of the range - timeMessage += "~"; - } - - } - graphics.drawString(timeMessage, canvasLoc.getX(), canvasLoc.getY()); - graphics.setColor(Color.WHITE); - } - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningRockType.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningRockType.java deleted file mode 100644 index e094fc66c4..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningRockType.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import static net.runelite.api.ObjectID.EMPTY_WALL; -import static net.runelite.api.ObjectID.ROCKS_7453; -import static net.runelite.api.ObjectID.ROCKS_7455; -import static net.runelite.api.ObjectID.ROCKS_7456; -import static net.runelite.api.ObjectID.ROCKS_7457; -import static net.runelite.api.ObjectID.ROCKS_7458; -import static net.runelite.api.ObjectID.ROCKS_7459; -import static net.runelite.api.ObjectID.ROCKS_7460; -import static net.runelite.api.ObjectID.ROCKS_7461; -import static net.runelite.api.ObjectID.ROCKS_7484; -import static net.runelite.api.ObjectID.ROCKS_7485; -import static net.runelite.api.ObjectID.ROCKS_7486; -import static net.runelite.api.ObjectID.ROCKS_7488; -import static net.runelite.api.ObjectID.ROCKS_7489; -import static net.runelite.api.ObjectID.ROCKS_7490; -import static net.runelite.api.ObjectID.ROCKS_7491; -import static net.runelite.api.ObjectID.ROCKS_7492; -import static net.runelite.api.ObjectID.ROCKS_7493; -import static net.runelite.api.ObjectID.ROCKS_7494; -import static net.runelite.api.ObjectID.DEPLETED_VEIN_26665; -import static net.runelite.api.ObjectID.DEPLETED_VEIN_26666; -import static net.runelite.api.ObjectID.DEPLETED_VEIN_26667; -import static net.runelite.api.ObjectID.DEPLETED_VEIN_26668; - -/** - * All the possible rock types the user can mine. - */ -@AllArgsConstructor -public enum MiningRockType -{ - - COPPER("Copper", 1, 2.5, -1, false, true, new int[] {ROCKS_7453, ROCKS_7484}), - TIN("Tin", 1, 2.5, -1, false, true, new int[] {ROCKS_7485, ROCKS_7486}), - IRON( "Iron", 15, 5.5, -1, false, true, new int[] {ROCKS_7455, ROCKS_7488}), - SILVER("Silver", 15, 60, -1, false, true, new int[] {ROCKS_7457, ROCKS_7490}), - COAL("Coal", 30, 29.5, -1, false, true, new int[] {ROCKS_7456, ROCKS_7489}), - GOLD("Gold", 40, 59.5, -1, false, true, new int[] {ROCKS_7458, ROCKS_7491}), - MITHRIL("Mithril", 55, 119.5, -1, false, true, new int[] {ROCKS_7459, ROCKS_7492}), - ADAMANTITE("Adamantite", 70, 239.5, -1, false, true, new int[] {ROCKS_7460, ROCKS_7493}), - RUNITE("Runite", 85, 720, -1, false, true, new int[] {ROCKS_7461, ROCKS_7494}), - AMETHYST("Amethyst", 92, 150, -1, true, false, new int[] {EMPTY_WALL}), - PAY_DIRT("Pay-Dirt", 30, 95, 125, true, false, new int[] {DEPLETED_VEIN_26665, DEPLETED_VEIN_26666, DEPLETED_VEIN_26667, DEPLETED_VEIN_26668}); - - @Getter(AccessLevel.PACKAGE) - private final String name; - - @Getter(AccessLevel.PACKAGE) - private final int requiredMiningLevel; - - @Getter(AccessLevel.PACKAGE) - private final double minRespawnTime, maxRespawnTime; - - @Getter(AccessLevel.PACKAGE) - private final boolean memberOnly; - - @Getter(AccessLevel.PACKAGE) - private final boolean groundObject; - - private final int[] rockIDs; - - public static MiningRockType getTypeFromID(int id) - { - for (MiningRockType type : values()) - { - for (int i : type.rockIDs) - { - if (i == id) - { - return type; - } - } - } - return null; - } - - public static MiningRockType getTypeFromName(String name) - { - for (MiningRockType type : values()) - { - if (type.getName().equalsIgnoreCase(name)) - { - return type; - } - } - return null; - } - - /** - * The rocks which can be tracked across worlds - */ - @AllArgsConstructor - public enum WorldRock - { - None(null), - Adamantite(MiningRockType.ADAMANTITE), - Gold(MiningRockType.GOLD), - Mithril(MiningRockType.MITHRIL), - Runite(MiningRockType.RUNITE); - - @Getter(AccessLevel.PACKAGE) - private final MiningRockType rockType; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningSession.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningSession.java deleted file mode 100644 index 9d45a1b67f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningSession.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Setter; -import java.time.Instant; -import java.util.HashMap; - -/** - * Holds information about the players current mining session - */ -public class MiningSession -{ - - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private Instant ignoreSpawn; - - @Getter(AccessLevel.PACKAGE) - private Instant lastMined; - - @Getter(AccessLevel.PACKAGE) - private HashMap sessionStats = new HashMap<>(); - - public MiningSession() - { - setupSession(); - } - - public void setupSession() - { - ignoreSpawn = Instant.now(); - for (MiningRockType rock : MiningRockType.values()) - { - sessionStats.put(rock, new MiningSessionRockStats()); - } - } - - public boolean showRockRespawnTimes(MiningRockType rock) - { - return sessionStats.get(rock).getRecentOreMined() != null; - } - - public void clearSessionFor(MiningRockType rock) - { - sessionStats.get(rock).clearSession(); - } - - public void increaseRockMine(MiningRockType rock) - { - Instant now = Instant.now(); - lastMined = now; - sessionStats.get(rock).increaseMined(); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningSessionRockStats.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningSessionRockStats.java deleted file mode 100644 index 523b1b18d1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningSessionRockStats.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import lombok.AccessLevel; -import lombok.Getter; - -import java.time.Duration; -import java.time.Instant; - -public class MiningSessionRockStats -{ - - private static final Duration HOUR = Duration.ofHours(1); - - @Getter(AccessLevel.PACKAGE) - private Instant lastOreMined; - - @Getter(AccessLevel.PACKAGE) - private Instant recentOreMined; - - @Getter(AccessLevel.PACKAGE) - private int totalMined; - - @Getter(AccessLevel.PACKAGE) - private int perHour; - - @Getter(AccessLevel.PACKAGE) - private int recentMined; - - public MiningSessionRockStats() - { - lastOreMined = null; - recentOreMined = null; - totalMined = 0; - perHour = 0; - recentMined = 0; - } - - public void clearSession() - { - recentOreMined = null; - perHour = 0; - recentMined = 0; - } - - public void increaseMined() - { - Instant now = Instant.now(); - lastOreMined = now; - totalMined++; - if (recentOreMined == null) - { - recentOreMined = now; - } - recentMined++; - - Duration timeSinceStart = Duration.between(recentOreMined, now); - if (!timeSinceStart.isZero()) - { - perHour = (int) ((double) recentMined * (double) HOUR.toMillis() / (double) timeSinceStart.toMillis()); - } - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorld.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorld.java deleted file mode 100644 index 7ad4e2a612..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorld.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import lombok.AccessLevel; -import lombok.Getter; -import net.runelite.api.TileObject; - -import java.util.ArrayList; - -/** - * Holds rocks mined in a certain world - */ -public class MiningWorld -{ - - @Getter(AccessLevel.PACKAGE) - private int world; - - @Getter(AccessLevel.PACKAGE) - private final BiMap rocks = HashBiMap.create(); - - public MiningWorld(int world) - { - this.world = world; - } - - public void clearNegativeRespawnTimes() - { - // Create a new array list, cause sometimes a concurrent modification occurs - for (MinedRock rock : new ArrayList<>(rocks.values())) - { - if (rock.getMinSecondsUntilRespawn(true) < 0) - { - rocks.inverse().remove(rock); - } - } - } - - public int getFirstSecondsUntilRespawn() - { - int least = Integer.MAX_VALUE; - for (MinedRock rock : rocks.values()) - { - int seconds = rock.getMinSecondsUntilRespawn(true); - if (seconds < least) - { - least = seconds; - } - } - return least; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorldHopperOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorldHopperOverlay.java deleted file mode 100644 index 96bf6bc6c9..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorldHopperOverlay.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import net.runelite.api.Client; -import net.runelite.client.game.SkillIconManager; -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 javax.inject.Inject; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.util.List; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.stream.Collectors; - -/** - * Displays respawn timers on a per-world base for any rock recently mined by the player as they're hopping worlds - */ -public class MiningWorldHopperOverlay extends Overlay -{ - - private final MiningConfig config; - private final Client client; - private final MiningPlugin plugin; - private final PanelComponent panelComponent = new PanelComponent(); - - @Inject - MiningWorldHopperOverlay(Client client, MiningPlugin plugin, MiningConfig config, SkillIconManager iconManager) - { - setPosition(OverlayPosition.TOP_LEFT); - this.client = client; - this.config = config; - this.plugin = plugin; - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (config.trackWorldRock() == MiningRockType.WorldRock.None) - { - return null; - } - - MiningWorldTracker tracker = plugin.getMiningTracker(); - for (int worldID : new ArrayList<>(tracker.getTrackedWorlds().keySet())) - { - MiningWorld world = tracker.getTrackedWorlds().get(worldID); - for (MinedRock rock : new ArrayList<>(world.getRocks().values())) - { - // If this rock has respawned & we've passed the config defined timeout, then remove this rock - if (rock.getMinSecondsUntilRespawn(true) < 0 - config.trackTimeout()) - { - world.getRocks().inverse().remove(rock); - } - } - if (world.getRocks().size() == 0) - { - tracker.getTrackedWorlds().remove(worldID); - } - } - if (tracker.getTrackedWorlds().size() == 0) - { - return null; - } - - panelComponent.getChildren().clear(); - panelComponent.getChildren().add(TitleComponent.builder() - .text("Respawn Tracker") - .build()); - - List worlds = tracker.getTrackedWorlds().values() - .stream() - .sorted(Comparator.comparing(MiningWorld::getFirstSecondsUntilRespawn)) - .collect(Collectors.toList()); - for (MiningWorld world : worlds) - { - // Go through every remaining world, if they're here it means they have a rock that has not yet respawned (or timeout not yet passed) - int id = world.getWorld(); - int seconds = world.getFirstSecondsUntilRespawn(); - if (seconds < 0) - { - // If the time left until the rock respawns is less than zero, then it means it has respawned. - // However if it's not yet been cleared, it means the timeout has not yet passed so we still need to display this world to the user - seconds = 0; - } - panelComponent.getChildren().add(LineComponent.builder() - .left("World " + id) - .right(Integer.toString(seconds)) - .rightColor(seconds == 0 ? Color.GREEN : Color.ORANGE) - .build()); - } - return panelComponent.render(graphics); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorldTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorldTracker.java deleted file mode 100644 index 290869c284..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningWorldTracker.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2018, Craftiii4 - * 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.mining; - -import lombok.AccessLevel; -import lombok.Getter; -import net.runelite.api.TileObject; - -import java.util.HashMap; - -/** - * Holds each world currently being tracked for respawn timers - */ -public class MiningWorldTracker -{ - - @Getter(AccessLevel.PACKAGE) - private MiningRockType.WorldRock trackingRock; - - @Getter(AccessLevel.PACKAGE) - private HashMap trackedWorlds = new HashMap<>(); - - public MiningWorldTracker(MiningRockType.WorldRock trackingRock) - { - this.trackingRock = trackingRock; - } - - /** - * Adds a tracked rock to a world. - * - * @param world World ID - * @param object The TileObject of the rock to track - * @param mined The MinedRock of the rock, containing the Type and respawn time - */ - public void addTracked(int world, TileObject object, MinedRock mined) - { - if (!trackedWorlds.containsKey(world)) - { - trackedWorlds.put(world, new MiningWorld(world)); - } - // Clear any rocks which have respawned, no point knowing about them if we are on this world & mining again - trackedWorlds.get(world).clearNegativeRespawnTimes(); - trackedWorlds.get(world).getRocks().put(object, mined); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MidiFileAdjuster.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MidiFileAdjuster.java deleted file mode 100644 index ee67b0a694..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MidiFileAdjuster.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2019, Rodolfo Ruiz-Velasco - * 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.musicmodifier; - -import javax.sound.midi.*; -import java.io.IOException; - -public class MidiFileAdjuster { - - private int bankLSBValue; - private int chPosition = -1; - - private boolean customBank = false; - - public Sequence reorderTracks(Sequence sequence) throws InvalidMidiDataException, IOException { - for (Track track : sequence.getTracks()) { - for (int i = 0; i < track.size(); i++) { - MidiEvent midiEvent = track.get(i); - MidiMessage midiMessage = midiEvent.getMessage(); - - if (midiMessage instanceof ShortMessage) { - ShortMessage sm = (ShortMessage) midiMessage; - - if (sm.getChannel() < 16) { - getBankLSB(sm); - - if (i == 0 & bankLSBValue != 1) { - chPosition++; - if (chPosition == 9) { - chPosition = 10; - } - } - - if (!customBank) { - - if (sm.getChannel() == 9) { - bankLSBValue = 1; - } - - if (sm.getChannel() != 9) { - bankLSBValue = 0; - } - } - } - - if (bankLSBValue == 1) { - - int drumChannel = 9; - if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) { - sm.setMessage(ShortMessage.PROGRAM_CHANGE, drumChannel, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) { - sm.setMessage(ShortMessage.CONTROL_CHANGE, drumChannel, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.NOTE_OFF) { - sm.setMessage(ShortMessage.NOTE_OFF, drumChannel, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.NOTE_ON) { - sm.setMessage(ShortMessage.NOTE_ON, drumChannel, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) { - sm.setMessage(ShortMessage.PROGRAM_CHANGE, drumChannel, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) { - sm.setMessage(ShortMessage.CONTROL_CHANGE, drumChannel, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.PITCH_BEND) { - sm.setMessage(ShortMessage.PITCH_BEND, drumChannel, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.CHANNEL_PRESSURE) { - sm.setMessage(ShortMessage.CHANNEL_PRESSURE, drumChannel, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.POLY_PRESSURE) { - sm.setMessage(ShortMessage.POLY_PRESSURE, drumChannel, sm.getData1(), sm.getData2()); - } - } else { - - if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) { - sm.setMessage(ShortMessage.PROGRAM_CHANGE, chPosition, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) { - sm.setMessage(ShortMessage.CONTROL_CHANGE, chPosition, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.NOTE_OFF) { - sm.setMessage(ShortMessage.NOTE_OFF, chPosition, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.NOTE_ON) { - sm.setMessage(ShortMessage.NOTE_ON, chPosition, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) { - sm.setMessage(ShortMessage.PROGRAM_CHANGE, chPosition, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) { - sm.setMessage(ShortMessage.CONTROL_CHANGE, chPosition, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.PITCH_BEND) { - sm.setMessage(ShortMessage.PITCH_BEND, chPosition, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.CHANNEL_PRESSURE) { - sm.setMessage(ShortMessage.CHANNEL_PRESSURE, chPosition, sm.getData1(), sm.getData2()); - } - - if (sm.getCommand() == ShortMessage.POLY_PRESSURE) { - sm.setMessage(ShortMessage.POLY_PRESSURE, chPosition, sm.getData1(), sm.getData2()); - } - } - } - } - } - return sequence; - } - - private void getBankLSB(ShortMessage sm) throws InvalidMidiDataException - { - if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) - { - if (sm.getData1() == 32) - { - bankLSBValue = sm.getData2(); - customBank = true; - } - if (sm.getData1() == 0) - { - sm.setMessage(sm.getCommand(), sm.getChannel(), sm.getData1(), bankLSBValue); - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MusicCustomizerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MusicCustomizerPlugin.java deleted file mode 100644 index a1202750bb..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MusicCustomizerPlugin.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2019, Rodolfo Ruiz-Velasco - * 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.musicmodifier; - -import net.runelite.api.*; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.WidgetLoaded; -import net.runelite.api.widgets.*; -import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.game.chatbox.ChatboxPanelManager; -import net.runelite.client.game.chatbox.ChatboxTextInput; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; - -import javax.inject.Inject; -import java.io.File; - -@PluginDescriptor( - name = "Music Track Customizer", - description = "Customize what track plays and how it sounds, with local files", - tags = {"music", "sound"}, - enabledByDefault = false -) - -public class MusicCustomizerPlugin extends Plugin -{ - - @Inject - private Client client; - - @Inject - private ChatboxPanelManager chatboxPanelManager; - - @Inject - private ClientThread clientThread; - - private RealTimeMIDIPlayer realTimeMIDIPlayer = new RealTimeMIDIPlayer(); - - private String songName = "Scape Main"; - - private ChatboxTextInput songInput; - - private Widget playlistModeButton; - - private Widget playlistBox; - - private Widget hidePlaylistButton; - - private Widget addPlaylistSongButton; - - private Widget playlistText; - - private Widget playlistSong; - - private String defaultUnlockedSongs; - - private boolean isLooping = true; - - private boolean playlistMode = false; - - private int newSongY = 34; - - private int playlistCount = 0; - - @Override - public void startUp() - { - playSong(songName); - } - - @Override - public void shutDown() - { - if (realTimeMIDIPlayer != null) - { - realTimeMIDIPlayer.stopSong(); - } - } - - @Subscribe - public void onGameTick(GameTick event) - { - try - { - if (!playlistMode) - { - String newSong = client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME).getText(); - - if (!newSong.equals(songName)) - { - songName = newSong; - playSongFromList(songName); - } - } - } catch (NullPointerException ignored) - { - - } - - } - - private void playSong(String song) - { - File midiMusicFile = new File(System.getProperty("user.home") + "/RuneLiteAudio/MIDI Files/" + - "Music/" + song + ".mid/"); - if (realTimeMIDIPlayer.midi == null) - { - realTimeMIDIPlayer.midi = midiMusicFile; - realTimeMIDIPlayer.run(); - } - - else - { - if (realTimeMIDIPlayer.isPlaying()) - { - realTimeMIDIPlayer.stopSong(); - } - realTimeMIDIPlayer.midi = midiMusicFile; - realTimeMIDIPlayer.run(); - } - } - - @Subscribe - private void onWidgetLoaded(WidgetLoaded widgetLoaded) - { - if (widgetLoaded.getGroupId() == WidgetID.MUSICTAB_GROUP_ID) - { - Widget musicPlayerSongs = client.getWidget(WidgetInfo.MUSICTAB_ALL_SONGS); - if (musicPlayerSongs != null) - { - playlistModeButton = musicPlayerSongs.createChild(-1, WidgetType.GRAPHIC); - playlistModeButton.setSpriteId(SpriteID.RS2_TAB_MUSIC); - playlistModeButton.setOriginalWidth(32); - playlistModeButton.setOriginalHeight(32); - playlistModeButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_RIGHT); - playlistModeButton.setOriginalX(0); - playlistModeButton.setOriginalY(0); - playlistModeButton.setHasListener(true); - playlistModeButton.setAction(1, "Open"); - playlistModeButton.setOnOpListener((JavaScriptCallback) e -> openPlaylist()); - playlistModeButton.setName("Playlist"); - playlistModeButton.setHidden(true); //Playlist is not enabled for this release (Unfinished). - playlistModeButton.revalidate(); - } - } - } - - private void openPlaylist() - { - playlistMode = true; - - Widget currentPlayingSong = client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME); - Widget allInGameSongs = client.getWidget(WidgetInfo.MUSICTAB_ALL_SONGS); - Widget musicScrollbar = client.getWidget(WidgetInfo.MUSICTAB_SCROLLBAR); - allInGameSongs.setHidden(true); - musicScrollbar.setHidden(true); - - defaultUnlockedSongs = client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).getText(); - - client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).setText(playlistCount + " / 10"); - - playlistBox = client.getWidget(WidgetInfo.MUSICTAB_INTERFACE); - - playlistText = playlistBox.createChild(-1, WidgetType.TEXT); - playlistText.setText("Music Playlist"); - playlistText.setFontId(497); - playlistText.setXPositionMode(WidgetPositionMode.ABSOLUTE_TOP); - playlistText.setOriginalX(40); - playlistText.setOriginalY(14); - playlistText.setOriginalHeight(1); - playlistText.setOriginalWidth(1); - playlistText.setTextColor(currentPlayingSong.getTextColor()); - playlistText.revalidate(); - - hidePlaylistButton = playlistBox.createChild(-1, WidgetType.GRAPHIC); - hidePlaylistButton.setSpriteId(SpriteID.RS2_TAB_MUSIC); - hidePlaylistButton.setOriginalWidth(32); - hidePlaylistButton.setOriginalHeight(32); - hidePlaylistButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_RIGHT); - hidePlaylistButton.setOriginalX(0); - hidePlaylistButton.setOriginalY(6); - hidePlaylistButton.setHasListener(true); - hidePlaylistButton.setAction(1, "Close"); - hidePlaylistButton.setOnOpListener((JavaScriptCallback) e -> closePlaylist()); - hidePlaylistButton.setName("Playlist"); - hidePlaylistButton.revalidate(); - - addPlaylistSongButton = playlistBox.createChild(-1, WidgetType.GRAPHIC); - addPlaylistSongButton.setSpriteId(SpriteID.BANK_ADD_TAB_ICON); - addPlaylistSongButton.setOriginalWidth(36); - addPlaylistSongButton.setOriginalHeight(32); - addPlaylistSongButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_LEFT); - addPlaylistSongButton.setOriginalX(0); - addPlaylistSongButton.setOriginalY(6); - addPlaylistSongButton.setHasListener(true); - addPlaylistSongButton.setAction(1, "Add to"); - addPlaylistSongButton.setOnOpListener((JavaScriptCallback) e -> addSongFromInput()); - addPlaylistSongButton.setName("Playlist"); - addPlaylistSongButton.revalidate(); - - if (playlistSong != null) - { - playlistSong.setHidden(false); - } - } - - private void closePlaylist() - { - playlistMode = false; - - Widget allInGameSongs = client.getWidget(WidgetInfo.MUSICTAB_ALL_SONGS); - Widget musicScrollbar = client.getWidget(WidgetInfo.MUSICTAB_SCROLLBAR); - allInGameSongs.setHidden(false); - musicScrollbar.setHidden(false); - - client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).setText(defaultUnlockedSongs); - playlistText.setHidden(true); - addPlaylistSongButton.setHidden(true); - hidePlaylistButton.setHidden(true); - - if (playlistSong != null) - { - playlistSong.setHidden(true); - } - } - - private void addSongFromInput() - { - addPlaylistSongButton.setAction(1, "Close search"); - addPlaylistSongButton.setOnOpListener((JavaScriptCallback) e -> closeInput()); - songInput = chatboxPanelManager.openTextInput("Please type a valid song name") - .onChanged(s -> clientThread.invokeLater(() -> updateSongs(s))) - .onClose(() -> - { - clientThread.invokeLater(() -> updateSongs(songInput.getValue())); - addPlaylistSongButton.setOnOpListener((JavaScriptCallback) e -> addSongFromInput()); - addPlaylistSongButton.setAction(1, "Add to"); - }) - .build(); - } - - private void updateSongs() - { - String song = ""; - if (chatboxIsOpen()) - { - song = songInput.getValue(); - } - updateSongs(song); - } - - private void updateSongs(String song) - { - if (playlistBox == null) - { - return; - } - - if (new File(System.getProperty("user.home") + "/RuneLiteAudio/MIDI Files/" + - "Music/" + song + ".mid/").exists()) - { - playListSongPlayer(song); - } - } - - private void playListSongPlayer(String song) - { - if (!song.equals(songName) && !chatboxIsOpen() && playlistCount < 10) - { - Widget playlistWidget = client.getWidget(WidgetInfo.MUSICTAB_INTERFACE); - playlistSong = playlistWidget.createChild(-1, WidgetType.TEXT); - playlistSong.setText(song); - playlistSong.setFontId(495); - playlistSong.setOriginalX(12); - playlistSong.setOriginalY(newSongY); - playlistSong.setOriginalWidth(120); - playlistSong.setOriginalHeight(16); - playlistSong.setTextColor(client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME).getTextColor()); - playlistSong.setHasListener(true); - playlistSong.setAction(1, "Play"); - playlistSong.setOnOpListener((JavaScriptCallback) e -> playSongFromList(song)); - playlistSong.setName(song); - playlistSong.revalidate(); - - newSongY = newSongY + 15; - - songName = song; - - playlistCount++; - client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).setText(playlistCount + " / 10"); - - if (playlistCount == 10) - { - addPlaylistSongButton.setHidden(true); - } - } - } - - private boolean chatboxIsOpen() - { - return songInput != null && chatboxPanelManager.getCurrentInput() == songInput; - } - - private void closeInput() - { - updateSongs(); - chatboxPanelManager.close(); - } - - private void playSongFromList(String song) - { - client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME).setName(song); - File midiMusicFile = new File(System.getProperty("user.home") + "/RuneLiteAudio/MIDI Files/" + - "Music/" + song + ".mid/"); - - if (realTimeMIDIPlayer.midi == null) - { - realTimeMIDIPlayer.midi = midiMusicFile; - realTimeMIDIPlayer.run(); - } - - else - { - if (realTimeMIDIPlayer.isPlaying()) - { - realTimeMIDIPlayer.stopSong(); - } - realTimeMIDIPlayer.midi = midiMusicFile; - realTimeMIDIPlayer.run(); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/RealTimeMIDIPlayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/RealTimeMIDIPlayer.java deleted file mode 100644 index 858c7465fd..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/RealTimeMIDIPlayer.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2019, Rodolfo Ruiz-Velasco - * 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.musicmodifier; - -import com.sun.media.sound.AudioSynthesizer; - -import javax.sound.midi.*; -import javax.sound.sampled.*; -import java.io.*; -import java.util.HashMap; -import java.util.Map; - -public class RealTimeMIDIPlayer implements Runnable -{ - private AudioFormat format; - - private Sequence midiSequence; - - private Soundbank soundbank; - - private SourceDataLine sdl; - - private MusicCustomizerPlugin customMusicPlugin; - - private MidiFileAdjuster adjuster; - - private Clip clip; - - public boolean looping = true; - - public File soundFont = new File(System.getProperty("user.home") + "/RuneLiteAudio/SoundFonts/" + - "RuneScape 2.sf2/"); - - public File midi; - - @Override - public void run() { - - try { - - adjuster = new MidiFileAdjuster(); //Unfinished class - - midiSequence = MidiSystem.getSequence(midi); - soundbank = MidiSystem.getSoundbank(soundFont); - init(); - } - catch (IOException | InvalidMidiDataException e) - { - e.printStackTrace(); - } - } - - public void stopSong() - { - if (sdl.isRunning()) - { - sdl.stop(); - } - } - - public static AudioSynthesizer findAudioSynthesizer() throws MidiUnavailableException - { - Synthesizer synth = MidiSystem.getSynthesizer(); - if (synth instanceof AudioSynthesizer) - return (AudioSynthesizer) synth; - - double gain = 0.8D; - - MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); - MidiChannel[] channels = synth.getChannels(); - - for (int i = 0; i < channels.length; i++) - { - channels[i].controlChange(7, ((int) (channels[i].getController(7) * gain))); - } - - for (int i = 0; i < infos.length; i++) - { - MidiDevice device = MidiSystem.getMidiDevice(infos[i]); - - if (device instanceof AudioSynthesizer) - return (AudioSynthesizer) device; - } - return null; - } - - public boolean isPlaying() - { - return sdl.isActive(); - } - - public static double send(Sequence sequence, Receiver receiver) { - float divtype = sequence.getDivisionType(); - assert (sequence.getDivisionType() == Sequence.PPQ); - Track[] tracks = sequence.getTracks(); - int[] trackspos = new int[tracks.length]; - int mpq = 500000; - int seqres = sequence.getResolution(); - long lasttick = 0; - long curtime = 0; - while (true) { - MidiEvent selevent = null; - int seltrack = -1; - for (int i = 0; i < tracks.length; i++) { - int trackpos = trackspos[i]; - Track track = tracks[i]; - if (trackpos < track.size()) { - MidiEvent event = track.get(trackpos); - if (selevent == null - || event.getTick() < selevent.getTick()) { - selevent = event; - seltrack = i; - } - } - } - if (seltrack == -1) - break; - trackspos[seltrack]++; - long tick = selevent.getTick(); - if (divtype == Sequence.PPQ) - curtime += ((tick - lasttick) * mpq) / seqres; - else - curtime = (long) ((tick * 1000000.0 * divtype) / seqres); - lasttick = tick; - MidiMessage msg = selevent.getMessage(); - if (msg instanceof MetaMessage) { - if (divtype == Sequence.PPQ) - if (((MetaMessage) msg).getType() == 0x51) { - byte[] data = ((MetaMessage) msg).getData(); - mpq = ((data[0] & 0xff) << 16) - | ((data[1] & 0xff) << 8) | (data[2] & 0xff); - } - } else { - if (receiver != null) - receiver.send(msg, curtime); - } - } - return curtime / 1000000.0; - } - - public void init() { - new Thread(new Runnable() { - @Override - public void run() { - - AudioSynthesizer synth = null; - try { - synth = findAudioSynthesizer(); - format = new AudioFormat(44100, 16, 2, true, false); - - Map info = new HashMap(); - info.put("resamplerType", "sinc"); - info.put("maxPolyphony", "8192"); - AudioInputStream ais = synth.openStream(format, info); - synth.unloadAllInstruments(synth.getDefaultSoundbank()); - synth.loadAllInstruments(soundbank); - double total = send(midiSequence, synth.getReceiver()); - long length = (long) (ais.getFormat().getFrameRate() * (total + 4)); - AudioInputStream stream = new AudioInputStream(ais, format, length); - sdl = AudioSystem.getSourceDataLine(format); - sdl.open(format); - sdl.start(); - writeAudio(sdl, stream); - } catch (LineUnavailableException | MidiUnavailableException e) { - e.printStackTrace(); - } - } - }).start(); - } - - public void writeAudio(SourceDataLine sdl, AudioInputStream stream) - { - new Thread(new Runnable() { - @Override - public void run() { - - byte[] sampledAudio = new byte[1024]; - - int numBytesRead = 0; - - while (numBytesRead != -1) { - try - { - numBytesRead = stream.read(sampledAudio, 0, sampledAudio.length); - - if (numBytesRead >= 0) { - sdl.write(sampledAudio, 0, numBytesRead); - } - } - - catch (IOException e) - { - e.printStackTrace(); - } - - finally { - - if (!isPlaying() && looping) - { - this.run(); - } - } - } - } - }).start(); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java deleted file mode 100644 index 8bce5b84b7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.runelite.client.plugins.nexthitnotifier; - - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; - -@ConfigGroup("nexthitnotifier") -public interface NextHitNotifierConfig extends Config -{ - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java deleted file mode 100644 index fe47f37307..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.runelite.client.plugins.nexthitnotifier; - -import net.runelite.api.Client; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.PanelComponent; -import net.runelite.client.ui.overlay.components.TitleComponent; -import net.runelite.client.util.MiscUtils; - -import javax.inject.Inject; -import java.awt.*; - -public class NextHitNotifierOverlay extends Overlay -{ - private final Client client; - private final NextHitNotifierPlugin plugin; - private final NextHitNotifierConfig config; - - private final PanelComponent panelComponent = new PanelComponent(); - private final Dimension panelSize = new Dimension(48, 0); - - @Inject - private NextHitNotifierOverlay(Client client, NextHitNotifierPlugin plugin, NextHitNotifierConfig config) - { - setPosition(OverlayPosition.BOTTOM_LEFT); - //setPosition(OverlayPosition.DYNAMIC); - //setPosition(OverlayPosition.DETACHED); - - this.client = client; - this.plugin = plugin; - this.config = config; - } - - @Override - public Dimension render(Graphics2D graphics) - { - panelComponent.getChildren().clear(); - panelComponent.setPreferredSize(panelSize); - - String lastHitText = Integer.toString(plugin.lastHit); - int lastHit = plugin.lastHit; - - if (plugin.showTime < 0) - { - lastHitText = "0"; - lastHit = 0; - } - - int g = (int)MiscUtils.clamp((float)Math.floor(lastHit / 30.f) * 255.f, 0.f, 255.f); - int r = 255 - g; - - Color textColor = Color.getHSBColor(Color.RGBtoHSB(r, g, 0, null)[0], 1.f, 1.f); - - panelComponent.getChildren().add(TitleComponent.builder().text("Next hit:").color(Color.YELLOW).build()); - panelComponent.getChildren().add(TitleComponent.builder().text(lastHitText).color(textColor).build()); - - return panelComponent.render(graphics); - } -} \ No newline at end of file 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 deleted file mode 100644 index ccece4d4a4..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java +++ /dev/null @@ -1,116 +0,0 @@ -package net.runelite.client.plugins.nexthitnotifier; - -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.Skill; -import net.runelite.api.events.ExperienceChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -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 javax.inject.Inject; - -@PluginDescriptor( - name = "!Next Hit Notifier", - description = "Shows estimated next hit based on xp drop.", - tags = { "experience", "damage", "overlay", "pking", "bogla" }, - enabledByDefault = false -) -public class NextHitNotifierPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private NextHitNotifierOverlay overlay; - - private int lastHpXp = 0; - int lastHit = 0; - int showTime = 0; - - @Provides - NextHitNotifierConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(NextHitNotifierConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - { - lastHpXp = client.getSkillExperience(Skill.HITPOINTS); - lastHit = 0; - showTime = 0; - } - else - { - lastHpXp = 0; - lastHit = 0; - showTime = 0; - } - } - - @Subscribe - public void onGameTick(GameTick event) - { - if (showTime > 0) - showTime--; - else - lastHit = 0; - } - - @Subscribe - public void onExperienceChanged(ExperienceChanged event) - { - if (client.getGameState() != GameState.LOGGED_IN) - { - lastHpXp = 0; - lastHit = 0; - showTime = 0; - return; - } - - final Skill skill = event.getSkill(); - - if (skill != Skill.HITPOINTS) - return; - - final int currentXp = client.getSkillExperience(skill); - - int gainedXp = currentXp - lastHpXp; - - //filter out big xp drops (such as login) - if (gainedXp > 1000) - { - lastHpXp = client.getSkillExperience(skill); - return; - } - - lastHit = (int)Math.rint(gainedXp / 1.33f); - lastHpXp = currentXp; - showTime = 3; - } - - -} 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/plankmakehelper/PlankMakeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java deleted file mode 100644 index 8295f294b1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java +++ /dev/null @@ -1,88 +0,0 @@ -package net.runelite.client.plugins.plankmakehelper; - -import net.runelite.api.*; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.widgets.WidgetItem; -import net.runelite.client.ui.overlay.*; - -import javax.inject.Inject; -import java.awt.*; - -public class PlankMakeOverlay extends Overlay { - - private final PlankMakePlugin plugin; - private final Client client; - - @Inject - public PlankMakeOverlay(final PlankMakePlugin plugin, final Client client) { - super(plugin); - this.plugin = plugin; - this.client = client; - - setPosition(OverlayPosition.DETACHED); - setLayer(OverlayLayer.ALWAYS_ON_TOP); - setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (hasPlankableItems()) { - renderInventory(graphics); - renderPlankMakeSpell(graphics); - } - return null; - } - - private void renderInventory(Graphics2D graphics) { - Widget inventory = client.getWidget(WidgetInfo.INVENTORY); - - int firstItemSeenIndex = -1; - - if (inventory != null) { - for (WidgetItem item : inventory.getWidgetItems()) { - if (PlankMakePlugin.isLogAndPlankable(item.getId())) { - if (firstItemSeenIndex == -1) { - firstItemSeenIndex = item.getIndex(); - } - if (!inventory.isHidden()) { - if (item.getIndex() != firstItemSeenIndex) { - OverlayUtil.renderPolygon(graphics, RectangleToPolygon(item.getCanvasBounds()), Color.BLUE); - } - } - } - } - if (firstItemSeenIndex != -1) { - OverlayUtil.renderPolygon(graphics, RectangleToPolygon(inventory.getWidgetItem(firstItemSeenIndex).getCanvasBounds()), Color.CYAN); - } - } - } - - private void renderPlankMakeSpell(Graphics2D graphics) { - Widget plankMakeSpell = client.getWidget(218,128); - if (plankMakeSpell != null && (plankMakeSpell.getCanvasLocation().getX() != 29 & plankMakeSpell.getCanvasLocation().getY() != 32)) { - OverlayUtil.renderPolygon(graphics, RectangleToPolygon(plankMakeSpell.getBounds()), Color.CYAN); - } - } - - private boolean hasPlankableItems() { - ItemContainer invo = client.getItemContainer(InventoryID.INVENTORY); - if (invo != null) { - if (invo.getItems().length > 0) { - for (Item item : invo.getItems()) { - if (PlankMakePlugin.isLogAndPlankable(item.getId())) { - return true; - } - } - } - } - return false; - } - - static Polygon RectangleToPolygon(Rectangle rect) { - int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x}; - int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height}; - return new Polygon(xpoints, ypoints, 4); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java deleted file mode 100644 index 4c5a72001e..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.runelite.client.plugins.plankmakehelper; - -import net.runelite.api.Client; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; - -import javax.inject.Inject; - -@PluginDescriptor( - name = "Plank Make Helper", - description = "Highlights planks and plank make spell", - tags = {"overlay", "plankmaking", "lunar", "money", "moneymaking", "gp"} -) - -public class PlankMakePlugin extends Plugin { - - @Inject - private OverlayManager overlayManager; - - @Inject - private Client client; - - @Inject - private PlankMakeOverlay overlay; - - @Override - protected void startUp() { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() { - overlayManager.remove(overlay); - } - - static boolean isLogAndPlankable(int itemID) { - switch (itemID) { - case 6332: //mahogany - case 1521: //oak - case 6333: //teak - case 1511: //plain - return true; - default: - return false; - } - } - -} 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 a0d6bf7223..6b032bc8ee 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 @@ -196,15 +196,4 @@ public interface PlayerIndicatorsConfig extends Config { return true; } - - @ConfigItem( - position = 15, - keyName = "showCombatLevels", - name = "Show combat levels", - description = "Add combat level to overhead name" - ) - default boolean showCombatLevels() - { - return true; - } } 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 98d88168a6..5373fc1eb4 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 @@ -46,6 +46,7 @@ public class PlayerIndicatorsOverlay extends Overlay { private static final int ACTOR_OVERHEAD_TEXT_MARGIN = 40; private static final int ACTOR_HORIZONTAL_TEXT_MARGIN = 10; + private final PlayerIndicatorsService playerIndicatorsService; private final PlayerIndicatorsConfig config; private final ClanManager clanManager; @@ -87,11 +88,7 @@ public class PlayerIndicatorsOverlay extends Overlay zOffset = actor.getLogicalHeight() + ACTOR_OVERHEAD_TEXT_MARGIN; } - String name = Text.sanitize(actor.getName()); - if (config.showCombatLevels()) - { - name = name + " (" + actor.getCombatLevel() + ")"; - } + final String name = Text.sanitize(actor.getName()); Point textLocation = actor.getCanvasTextLocation(graphics, name, zOffset); if (drawPlayerNamesConfig == PlayerNameLocation.MODEL_RIGHT) @@ -113,7 +110,7 @@ public class PlayerIndicatorsOverlay extends Overlay if (config.showClanRanks() && actor.isClanMember()) { - ClanMemberRank rank = clanManager.getRank(actor.getName()); + final ClanMemberRank rank = clanManager.getRank(name); if (rank != ClanMemberRank.UNRANKED) { @@ -148,4 +145,4 @@ public class PlayerIndicatorsOverlay extends Overlay OverlayUtil.renderTextLocation(graphics, textLocation, name, color); } -} \ No newline at end of file +} 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 d1c65649ad..e545f92dff 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 @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.playerindicators; -import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import java.awt.Color; import javax.inject.Inject; @@ -36,6 +35,7 @@ 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.eventbus.Subscribe; import net.runelite.client.game.ClanManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -43,7 +43,7 @@ import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ColorUtil; @PluginDescriptor( - name = "!Player Indicators", + name = "Player Indicators", description = "Highlight players on-screen and/or on the minimap", tags = {"highlight", "minimap", "overlay", "players"} ) @@ -93,7 +93,7 @@ public class PlayerIndicatorsPlugin extends Plugin } @Subscribe - public void onMenuEntryAdd(MenuEntryAdded menuEntryAdded) + public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) { int type = menuEntryAdded.getType(); @@ -132,7 +132,7 @@ public class PlayerIndicatorsPlugin extends Plugin int image = -1; Color color = null; - if (config.highlightFriends() && client.isFriended(player.getName(), false)) + if (config.highlightFriends() && player.isFriend()) { color = config.getFriendColor(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java deleted file mode 100644 index 6c1370ef76..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2019, gazivodag - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.client.plugins.prayagainstplayer; - -import net.runelite.api.Player; - -/** - * Contains a player object - * When they attacked me - * And (in milliseconds) when to expire the overlay around them - */ -public class PlayerContainer { - - private Player player; - private long whenTheyAttackedMe; - private int millisToExpireHighlight; - - public PlayerContainer(Player player, long whenTheyAttackedMe, int millisToExpireHighlight) { - this.player = player; - this.whenTheyAttackedMe = whenTheyAttackedMe; - this.millisToExpireHighlight = millisToExpireHighlight; - } - - - //getters - public Player getPlayer() { - return player; - } - public long getWhenTheyAttackedMe() { - return whenTheyAttackedMe; - } - public int getMillisToExpireHighlight() { return millisToExpireHighlight; }; - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java deleted file mode 100644 index ce453fd3d9..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2019, gazivodag - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.client.plugins.prayagainstplayer; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -import java.awt.*; - -@ConfigGroup("prayagainstplayer") -public interface PrayAgainstPlayerConfig extends Config { - @ConfigItem( - position = 0, - keyName = "attackerPlayerColor", - name = "Attacker color", - description = "This is the color that will be used to highlight attackers." - ) - default Color attackerPlayerColor() { return new Color(0xFF0006); } - - @ConfigItem( - position = 1, - keyName = "potentialPlayerColor", - name = "Potential Attacker color", - description = "This is the color that will be used to highlight potential attackers." - ) - default Color potentialPlayerColor() { return new Color(0xFFFF00); } - - //// - @ConfigItem( - position = 2, - keyName = "attackerTargetTimeout", - name = "Attacker Timeout", - description = "Seconds until attacker is no longer highlighted." - ) - default int attackerTargetTimeout() { return 10; } - - @ConfigItem( - position = 3, - keyName = "potentialTargetTimeout", - name = "Potential Attacker Timeout", - description = "Seconds until potential attacker is no longer highlighted." - ) - default int potentialTargetTimeout() { return 10; } - - @ConfigItem( - position = 4, - keyName = "newSpawnTimeout", - name = "New Player Timeout", - description = "Seconds until logged in/spawned player is no longer highlighted." - ) - default int newSpawnTimeout() { return 5; } - //// - - //// - @ConfigItem( - position = 5, - keyName = "ignoreFriends", - name = "Ignore Friends", - description = "This lets you decide whether you want friends to be highlighted by this plugin." - ) - default boolean ignoreFriends() { return true; } - - @ConfigItem( - position = 6, - keyName = "ignoreClanMates", - name = "Ignore Clan Mates", - description = "This lets you decide whether you want clan mates to be highlighted by this plugin." - ) - default boolean ignoreClanMates() { return true; } - //// - - @ConfigItem( - position = 7, - keyName = "markNewPlayer", - name = "Mark new player as potential attacker", - description = "Marks someone that logged in or teleported as a potential attacker for your safety\nDO NOT RUN THIS IN WORLD 1-2 GRAND EXCHANGE!" - ) - default boolean markNewPlayer() { return false; } - - @ConfigItem( - position = 8, - keyName = "drawTargetPrayAgainst", - name = "Draw what to pray on attacker", - description = "Tells you what to pray from what weapon the attacker is holding" - ) - default boolean drawTargetPrayAgainst() { return true; } - - @ConfigItem( - position = 9, - keyName = "drawPotentialTargetPrayAgainst", - name = "Draw what to pray on potential attacker", - description = "Tells you what to pray from what weapon the potential attacker is holding" - ) - default boolean drawPotentialTargetPrayAgainst() { return true; } - - @ConfigItem( - position = 10, - keyName = "drawTargetPrayAgainstPrayerTab", - name = "Draw what to pray from prayer tab", - description = "Tells you what to pray from what weapon the attacker is holding from the prayer tab" - ) - default boolean drawTargetPrayAgainstPrayerTab() { return false; } - - @ConfigItem( - position = 11, - keyName = "drawTargetsName", - name = "Draw name on attacker", - description = "Configures whether or not the attacker\'s name should be shown" - ) - default boolean drawTargetsName() { return true; } - - @ConfigItem( - position = 12, - keyName = "drawPotentialTargetsName", - name = "Draw name on potential attacker", - description = "Configures whether or not the potential attacker\'s name should be shown" - ) - default boolean drawPotentialTargetsName() { return true; } - - @ConfigItem( - position = 13, - keyName = "drawTargetHighlight", - name = "Draw highlight around attacker", - description = "Configures whether or not the attacker should be highlighted" - ) - default boolean drawTargetHighlight() { return true; } - - @ConfigItem( - position = 14, - keyName = "drawPotentialTargetHighlight", - name = "Draw highlight around potential attacker", - description = "Configures whether or not the potential attacker should be highlighted" - ) - default boolean drawPotentialTargetHighlight() { return true; } - - @ConfigItem( - position = 15, - keyName = "drawTargetTile", - name = "Draw tile under attacker", - description = "Configures whether or not the attacker\'s tile be highlighted" - ) - default boolean drawTargetTile() { return false; } - - @ConfigItem( - position = 16, - keyName = "drawPotentialTargetTile", - name = "Draw tile under potential attacker", - description = "Configures whether or not the potential attacker\'s tile be highlighted" - ) - default boolean drawPotentialTargetTile() { return false; } - - @ConfigItem( - position = 17, - keyName = "drawUnknownWeapons", - name = "Draw unknown weapons", - description = "Configures whether or not the unknown weapons should be shown when a player equips one" - ) - default boolean drawUnknownWeapons() { return false; } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java deleted file mode 100644 index e54efd8127..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2019, gazivodag - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.client.plugins.prayagainstplayer; - -import net.runelite.api.Client; -import net.runelite.api.ItemComposition; -import net.runelite.api.Player; -import net.runelite.api.kit.KitType; -import net.runelite.client.ui.overlay.*; -import net.runelite.client.util.Text; -import net.runelite.api.Point; - -import javax.inject.Inject; -import java.awt.*; -import java.awt.image.BufferedImage; -import java.util.ConcurrentModificationException; - -class PrayAgainstPlayerOverlay extends Overlay { - - private final PrayAgainstPlayerPlugin plugin; - private final PrayAgainstPlayerConfig config; - private final Client client; - - @Inject - private PrayAgainstPlayerOverlay(PrayAgainstPlayerPlugin plugin, PrayAgainstPlayerConfig config, Client client) { - super(plugin); - this.plugin = plugin; - this.config = config; - this.client = client; - - setLayer(OverlayLayer.ABOVE_SCENE); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGH); - } - - - @Override - public Dimension render(Graphics2D graphics) { - renderPotentialPlayers(graphics); - renderAttackingPlayers(graphics); - return null; - } - - private void renderPotentialPlayers(Graphics2D graphics) { - if (plugin.getPotentialPlayersAttackingMe() == null || !plugin.getPotentialPlayersAttackingMe().isEmpty()) { - try { - for (PlayerContainer container : plugin.getPotentialPlayersAttackingMe()) { - if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) { - plugin.removePlayerFromPotentialContainer(container); - } - if (config.drawPotentialTargetsName()) renderNameAboveHead(graphics, container.getPlayer(), config.potentialPlayerColor()); - if (config.drawPotentialTargetHighlight()) renderHighlightedPlayer(graphics, container.getPlayer(), config.potentialPlayerColor()); - if (config.drawPotentialTargetTile()) renderTileUnderPlayer(graphics, container.getPlayer(), config.potentialPlayerColor()); - if (config.drawPotentialTargetPrayAgainst()) renderPrayAgainstOnPlayer(graphics, container.getPlayer(), config.potentialPlayerColor()); - } - } catch (ConcurrentModificationException e) { - } - } - } - - private void renderAttackingPlayers(Graphics2D graphics) { - if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) { - try { - for (PlayerContainer container : plugin.getPlayersAttackingMe()) { - if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) { - plugin.removePlayerFromAttackerContainer(container); - } - - if (config.drawTargetsName()) renderNameAboveHead(graphics, container.getPlayer(), config.attackerPlayerColor()); - if (config.drawTargetHighlight()) renderHighlightedPlayer(graphics, container.getPlayer(), config.attackerPlayerColor()); - if (config.drawTargetTile()) renderTileUnderPlayer(graphics, container.getPlayer(), config.attackerPlayerColor()); - if (config.drawTargetPrayAgainst()) renderPrayAgainstOnPlayer(graphics, container.getPlayer(), config.attackerPlayerColor()); - } - } catch (ConcurrentModificationException e) { - } - } - } - - private void renderNameAboveHead(Graphics2D graphics, Player player, Color color) { - final String name = Text.sanitize(player.getName()); - final int offset = player.getLogicalHeight() + 40; - Point textLocation = player.getCanvasTextLocation(graphics, name, offset); - if (textLocation != null) { - OverlayUtil.renderTextLocation(graphics, textLocation, name, color); - } - } - - private void renderHighlightedPlayer(Graphics2D graphics, Player player, Color color) { - try { - OverlayUtil.renderPolygon(graphics, player.getConvexHull(), color); - } catch (NullPointerException e) { - } - } - - private void renderTileUnderPlayer(Graphics2D graphics, Player player, Color color) { - Polygon poly = player.getCanvasTilePoly(); - OverlayUtil.renderPolygon(graphics, poly, color); - } - - private void renderPrayAgainstOnPlayer(Graphics2D graphics, Player player, Color color) { - final int offset = (player.getLogicalHeight() / 2) + 75; - BufferedImage icon; - - switch (WeaponType.checkWeaponOnPlayer(client, player)) { - case WEAPON_MELEE: - icon = plugin.getProtectionIcon(WeaponType.WEAPON_MELEE); - break; - case WEAPON_MAGIC: - icon = plugin.getProtectionIcon(WeaponType.WEAPON_MAGIC); - break; - case WEAPON_RANGED: - icon = plugin.getProtectionIcon(WeaponType.WEAPON_RANGED); - break; - default: - icon = null; - break; - } - try { - if (icon != null) { - Point point = player.getCanvasImageLocation(icon, offset); - OverlayUtil.renderImageLocation(graphics, point, icon); - } else { - if (config.drawUnknownWeapons()) { - int itemId = player.getPlayerComposition().getEquipmentId(KitType.WEAPON); - ItemComposition itemComposition = client.getItemDefinition(itemId); - - final String str = itemComposition.getName().toUpperCase(); - Point point = player.getCanvasTextLocation(graphics, str, offset); - OverlayUtil.renderTextLocation(graphics, point, str, color); - } - } - } catch (Exception e) { - } - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java deleted file mode 100644 index 4e505675f6..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2019, gazivodag - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.client.plugins.prayagainstplayer; - -import net.runelite.api.Client; -import net.runelite.api.Player; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.ui.overlay.*; - -import javax.inject.Inject; -import java.awt.*; -import java.util.ConcurrentModificationException; - -class PrayAgainstPlayerOverlayPrayerTab extends Overlay { - - private final PrayAgainstPlayerPlugin plugin; - private final PrayAgainstPlayerConfig config; - private final Client client; - - @Inject - private PrayAgainstPlayerOverlayPrayerTab (PrayAgainstPlayerPlugin plugin, PrayAgainstPlayerConfig config, Client client) { - super(plugin); - this.plugin = plugin; - this.config = config; - this.client = client; - - setPosition(OverlayPosition.DETACHED); - setLayer(OverlayLayer.ALWAYS_ON_TOP); - setPriority(OverlayPriority.MED); - } - - - @Override - public Dimension render(Graphics2D graphics) { - if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) { - try { - for (PlayerContainer container : plugin.getPlayersAttackingMe()) { - if (plugin.getPlayersAttackingMe() != null && plugin.getPlayersAttackingMe().size() > 0) { - //no reason to show you what prayers to pray in your prayer tab if multiple people are attacking you - if ((plugin.getPlayersAttackingMe().size() == 1) && (config.drawTargetPrayAgainstPrayerTab())) { - renderPrayerToClick(graphics, container.getPlayer()); - } - } - } - } catch (ConcurrentModificationException e) { - } - } - return null; - } - - private void renderPrayerToClick(Graphics2D graphics, Player player) { - Widget PROTECT_FROM_MAGIC = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MAGIC); - Widget PROTECT_FROM_RANGED = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MISSILES); - Widget PROTECT_FROM_MELEE = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MELEE); - Color color = Color.RED; - if (PROTECT_FROM_MELEE.isHidden()) return; - switch (WeaponType.checkWeaponOnPlayer(client, player)) { - case WEAPON_MAGIC: - OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MAGIC.getBounds()), color); - break; - case WEAPON_MELEE: - OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MELEE.getBounds()), color); - break; - case WEAPON_RANGED: - OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_RANGED.getBounds()), color); - break; - default: - break; - } - } - - private static Polygon rectangleToPolygon(Rectangle rect) { - int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x}; - int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height}; - return new Polygon(xpoints, ypoints, 4); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java deleted file mode 100644 index 5664621b60..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2019, gazivodag - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.client.plugins.prayagainstplayer; - -import com.google.inject.Provides; -import net.runelite.api.*; -import net.runelite.api.events.*; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.ImageUtil; - -import javax.inject.Inject; -import java.awt.*; -import java.awt.image.*; -import java.util.ArrayList; -import java.util.Arrays; - -@PluginDescriptor( - name = "!Pray Against Player", - description = "Use plugin in PvP situations for best results!!", - tags = {"highlight", "pvp", "overlay", "players"} -) - -/** - * I am fully aware that there is plenty of overhead and is a MESS! - * If you'd like to contribute please do! - */ -public class PrayAgainstPlayerPlugin extends Plugin { - - private static final int[] PROTECTION_ICONS = { - SpriteID.PRAYER_PROTECT_FROM_MISSILES, - SpriteID.PRAYER_PROTECT_FROM_MELEE, - SpriteID.PRAYER_PROTECT_FROM_MAGIC - }; - private static final Dimension PROTECTION_ICON_DIMENSION = new Dimension(33, 33); - private static final Color PROTECTION_ICON_OUTLINE_COLOR = new Color(33, 33, 33); - public final BufferedImage[] ProtectionIcons = new BufferedImage[PROTECTION_ICONS.length]; - - private ArrayList potentialPlayersAttackingMe; - private ArrayList playersAttackingMe; - - @Inject - private Client client; - - @Inject - private SpriteManager spriteManager; - - @Inject - private OverlayManager overlayManager; - - @Inject - private PrayAgainstPlayerOverlay overlay; - - @Inject - private PrayAgainstPlayerOverlayPrayerTab overlayPrayerTab; - - @Inject - private PrayAgainstPlayerConfig config; - - @Provides - PrayAgainstPlayerConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(PrayAgainstPlayerConfig.class); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) { - if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { - loadProtectionIcons(); - } - } - - @Override - protected void startUp() { - potentialPlayersAttackingMe = new ArrayList<>(); - playersAttackingMe = new ArrayList<>(); - overlayManager.add(overlay); - overlayManager.add(overlayPrayerTab); - } - - @Override - protected void shutDown() throws Exception { - overlayManager.remove(overlay); - overlayManager.remove(overlayPrayerTab); - } - - @Subscribe - protected void onAnimationChanged(AnimationChanged animationChanged) { - if ((animationChanged.getActor() instanceof Player) && (animationChanged.getActor().getInteracting() instanceof Player) && (animationChanged.getActor().getInteracting() == client.getLocalPlayer())) { - Player sourcePlayer = (Player) animationChanged.getActor(); - - //is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list - if (client.isFriended(sourcePlayer.getName(), true) && config.ignoreFriends()) return; - if (client.isClanMember(sourcePlayer.getName()) && config.ignoreClanMates()) return; - - if ((sourcePlayer.getAnimation() != -1) && (!isBlockAnimation(sourcePlayer.getAnimation()))) { - //if attacker attacks again, reset his timer so overlay doesn't go away - if (findPlayerInAttackerList(sourcePlayer) != null) { - resetPlayerFromAttackerContainerTimer(findPlayerInAttackerList(sourcePlayer)); - } - //if he attacks and he was in the potential attackers list, remove him - if (!potentialPlayersAttackingMe.isEmpty() && potentialPlayersAttackingMe.contains(findPlayerInPotentialList(sourcePlayer))) { - removePlayerFromPotentialContainer(findPlayerInPotentialList(sourcePlayer)); - } - //if he's not in the attackers list, add him - if (findPlayerInAttackerList(sourcePlayer) == null) { - PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (config.attackerTargetTimeout() * 1000)); - playersAttackingMe.add(container); - } - } - } - } - - @Subscribe - protected void onInteractingChanged(InteractingChanged interactingChanged) { - //if someone interacts with you, add them to the potential attackers list - if ((interactingChanged.getSource() instanceof Player) && (interactingChanged.getTarget() instanceof Player)) { - Player sourcePlayer = (Player) interactingChanged.getSource(); - Player targetPlayer = (Player) interactingChanged.getTarget(); - if ((targetPlayer == client.getLocalPlayer()) && (findPlayerInPotentialList(sourcePlayer) == null)) { //we're being interacted with - - //is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list - if (client.isFriended(sourcePlayer.getName(), true) && config.ignoreFriends()) return; - if (client.isClanMember(sourcePlayer.getName()) && config.ignoreClanMates()) return; - - PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (config.potentialTargetTimeout() * 1000)); - potentialPlayersAttackingMe.add(container); - } - } - } - - @Subscribe - protected void onPlayerDespawned(PlayerDespawned playerDespawned) { - PlayerContainer container = findPlayerInAttackerList(playerDespawned.getPlayer()); - PlayerContainer container2 = findPlayerInPotentialList(playerDespawned.getPlayer()); - if (container != null) { - playersAttackingMe.remove(container); - } - if (container2 != null) { - potentialPlayersAttackingMe.remove(container2); - } - } - - @Subscribe - protected void onPlayerSpawned(PlayerSpawned playerSpawned) { - if (config.markNewPlayer()) { - Player p = playerSpawned.getPlayer(); - - if (client.isFriended(p.getName(), true) && config.ignoreFriends()) return; - if (client.isClanMember(p.getName()) && config.ignoreClanMates()) return; - - PlayerContainer container = findPlayerInPotentialList(p); - if (container == null) { - container = new PlayerContainer(p, System.currentTimeMillis(), (config.newSpawnTimeout() * 1000)); - potentialPlayersAttackingMe.add(container); - } - } - } - - PlayerContainer findPlayerInAttackerList(Player player) { - if (playersAttackingMe.isEmpty()) { - return null; - } - for (int i = 0 ; i < playersAttackingMe.size() ; i++) { - PlayerContainer container = playersAttackingMe.get(i); - if (container.getPlayer() == player) { - return container; - } - } - return null; - } - - PlayerContainer findPlayerInPotentialList(Player player) { - if (potentialPlayersAttackingMe.isEmpty()) { - return null; - } - for (int i = 0 ; i < potentialPlayersAttackingMe.size() ; i++) { - PlayerContainer container = potentialPlayersAttackingMe.get(i); - if (container.getPlayer() == player) { - return container; - } - } - return null; - } - - /** - * Resets player timer in case he attacks again, so his highlight doesn't go away so easily - * @param container - */ - public void resetPlayerFromAttackerContainerTimer(PlayerContainer container) { - removePlayerFromAttackerContainer(container); - PlayerContainer newContainer = new PlayerContainer(container.getPlayer(), System.currentTimeMillis(), (config.attackerTargetTimeout() * 1000)); - playersAttackingMe.add(newContainer); - } - - - public void removePlayerFromPotentialContainer(PlayerContainer container) { - if ((potentialPlayersAttackingMe != null) && (!potentialPlayersAttackingMe.isEmpty()) && (potentialPlayersAttackingMe.contains(container))) { - potentialPlayersAttackingMe.remove(container); - } - } - - public void removePlayerFromAttackerContainer(PlayerContainer container) { - if ((playersAttackingMe != null) && (!playersAttackingMe.isEmpty()) && (playersAttackingMe.contains(container))) { - playersAttackingMe.remove(container); - } - } - - private boolean isBlockAnimation(int anim) { - switch (anim) { - case AnimationID.BLOCK_DEFENDER: - case AnimationID.BLOCK_NO_SHIELD: - case AnimationID.BLOCK_SHIELD: - case AnimationID.BLOCK_SWORD: - case AnimationID.BLOCK_UNARMED: - return true; - default: - return false; - } - } - - public ArrayList getPotentialPlayersAttackingMe() { return potentialPlayersAttackingMe; } - public ArrayList getPlayersAttackingMe() { return playersAttackingMe; } - - //All of the methods below are from the Zulrah plugin!!! Credits to it's respective owner - private void loadProtectionIcons() { - final IndexedSprite[] protectionIcons = {}; - final IndexedSprite[] newProtectionIcons = Arrays.copyOf(protectionIcons, PROTECTION_ICONS.length); - int curPosition = 0; - - for (int i = 0; i < PROTECTION_ICONS.length; i++, curPosition++) - { - final int resource = PROTECTION_ICONS[i]; - ProtectionIcons[i] = rgbaToIndexedBufferedImage(ProtectionIconFromSprite(spriteManager.getSprite(resource, 0))); - newProtectionIcons[curPosition] = createIndexedSprite(client, ProtectionIcons[i]); - } - } - - private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) { - final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel(); - - final int width = bufferedImage.getWidth(); - final int height = bufferedImage.getHeight(); - final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); - final int[] palette = new int[indexedCM.getMapSize()]; - indexedCM.getRGBs(palette); - - final IndexedSprite newIndexedSprite = client.createIndexedSprite(); - newIndexedSprite.setPixels(pixels); - newIndexedSprite.setPalette(palette); - newIndexedSprite.setWidth(width); - newIndexedSprite.setHeight(height); - newIndexedSprite.setOriginalWidth(width); - newIndexedSprite.setOriginalHeight(height); - newIndexedSprite.setOffsetX(0); - newIndexedSprite.setOffsetY(0); - return newIndexedSprite; - } - - private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) { - final BufferedImage indexedImage = new BufferedImage( - sourceBufferedImage.getWidth(), - sourceBufferedImage.getHeight(), - BufferedImage.TYPE_BYTE_INDEXED); - - final ColorModel cm = indexedImage.getColorModel(); - final IndexColorModel icm = (IndexColorModel) cm; - - final int size = icm.getMapSize(); - final byte[] reds = new byte[size]; - final byte[] greens = new byte[size]; - final byte[] blues = new byte[size]; - icm.getReds(reds); - icm.getGreens(greens); - icm.getBlues(blues); - - final WritableRaster raster = indexedImage.getRaster(); - final int pixel = raster.getSample(0, 0, 0); - final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); - final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); - resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); - return resultIndexedImage; - } - - private static BufferedImage ProtectionIconFromSprite(final BufferedImage freezeSprite) { - final BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, PROTECTION_ICON_DIMENSION.width, PROTECTION_ICON_DIMENSION.height); - return ImageUtil.outlineImage(freezeCanvas, PROTECTION_ICON_OUTLINE_COLOR); - } - - BufferedImage getProtectionIcon(WeaponType weaponType) { - switch (weaponType) { - case WEAPON_RANGED: - return ProtectionIcons[0]; - case WEAPON_MELEE: - return ProtectionIcons[1]; - case WEAPON_MAGIC: - return ProtectionIcons[2]; - } - return null; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java deleted file mode 100644 index 1dc00c8311..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2019, gazivodag - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.client.plugins.prayagainstplayer; - -import net.runelite.api.Client; -import net.runelite.api.ItemComposition; -import net.runelite.api.Player; -import net.runelite.api.kit.KitType; - -enum WeaponType { - - WEAPON_MELEE, - WEAPON_RANGED, - WEAPON_MAGIC, - WEAPON_UNKNOWN; - - /** - * im fully aware this could of been done better!!! - * @param client - * @param attacker - * @return - */ - public static WeaponType checkWeaponOnPlayer (Client client, Player attacker) { - int itemId = attacker.getPlayerComposition().getEquipmentId(KitType.WEAPON); - ItemComposition itemComposition = client.getItemDefinition(itemId); - String weaponNameGivenLowerCase = itemComposition.getName().toLowerCase(); - - if (itemId == -1) return WEAPON_MELEE; - if (weaponNameGivenLowerCase == null || weaponNameGivenLowerCase.toLowerCase().contains("null")) return WEAPON_MELEE; - - for (String meleeWeaponName : meleeWeaponNames) { - if (weaponNameGivenLowerCase.contains(meleeWeaponName) && !weaponNameGivenLowerCase.contains("thrownaxe")) { - return WEAPON_MELEE; - } - } - - for (String rangedWeaponName : rangedWeaponNames) { - if (weaponNameGivenLowerCase.contains(rangedWeaponName)) { - return WEAPON_RANGED; - } - } - - for (String magicWeaponName : magicWeaponNames) { - if (weaponNameGivenLowerCase.contains(magicWeaponName)) { - return WEAPON_MAGIC; - } - } - - return WEAPON_UNKNOWN; - - } - - private static String[] meleeWeaponNames = { - "sword", - "scimitar", - "dagger", - "spear", - "mace", - "axe", - "whip", - "tentacle", - "-ket-", - "-xil-", - "warhammer", - "halberd", - "claws", - "hasta", - "scythe", - "maul", - "anchor", - "sabre", - "excalibur", - "machete", - "dragon hunter lance", - "event rpg", - "silverlight", - "darklight", - "arclight", - "flail", - "granite hammer", - "rapier", - "bulwark" - }; - - private static String[] rangedWeaponNames = { - "bow", - "blowpipe", - "xil-ul", - "knife", - "dart", - "thrownaxe", - "chinchompa", - "ballista" - }; - - private static String[] magicWeaponNames = { - "staff", - "trident", - "wand", - "dawnbringer" - }; - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java deleted file mode 100644 index 876d27ff55..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Decompiled with CFR 0.139. - */ -package net.runelite.client.plugins.profiles; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Image; -import java.awt.LayoutManager; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.image.BufferedImage; -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.SwingUtilities; -import javax.swing.border.Border; -import javax.swing.border.CompoundBorder; -import javax.swing.border.EmptyBorder; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.client.plugins.profiles.ProfilesConfig; -import net.runelite.client.plugins.profiles.ProfilesPanel; -import net.runelite.client.plugins.profiles.ProfilesPlugin; -import net.runelite.client.ui.ColorScheme; -import net.runelite.client.util.ImageUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class ProfilePanel -extends JPanel { - private static final Logger log = LoggerFactory.getLogger(ProfilePanel.class); - private static final ImageIcon DELETE_ICON; - private static final ImageIcon DELETE_HOVER_ICON; - private final String loginText; - private String password = null; - - ProfilePanel(final Client client, final String data, final ProfilesConfig config) { - String[] parts = data.split(":"); - this.loginText = parts[1]; - if (parts.length == 3) { - this.password = parts[2]; - } - final ProfilePanel panel = this; - this.setLayout(new BorderLayout()); - this.setBackground(ColorScheme.DARKER_GRAY_COLOR); - JPanel labelWrapper = new JPanel(new BorderLayout()); - labelWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR); - labelWrapper.setBorder(new CompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR), BorderFactory.createLineBorder(ColorScheme.DARKER_GRAY_COLOR))); - JPanel panelActions = new JPanel(new BorderLayout(3, 0)); - panelActions.setBorder(new EmptyBorder(0, 0, 0, 8)); - panelActions.setBackground(ColorScheme.DARKER_GRAY_COLOR); - final JLabel delete = new JLabel(); - delete.setIcon(DELETE_ICON); - delete.setToolTipText("Delete account profile"); - delete.addMouseListener(new MouseAdapter(){ - - @Override - public void mousePressed(MouseEvent e) { - panel.getParent().remove(panel); - ProfilesPanel.removeProfile(data); - } - - @Override - public void mouseEntered(MouseEvent e) { - delete.setIcon(DELETE_HOVER_ICON); - } - - @Override - public void mouseExited(MouseEvent e) { - delete.setIcon(DELETE_ICON); - } - }); - panelActions.add((Component)delete, "East"); - JLabel label = new JLabel(); - label.setText(parts[0]); - label.setBorder(null); - label.setBackground(ColorScheme.DARKER_GRAY_COLOR); - label.setPreferredSize(new Dimension(0, 24)); - label.setForeground(Color.WHITE); - label.setBorder(new EmptyBorder(0, 8, 0, 0)); - labelWrapper.add((Component)label, "Center"); - labelWrapper.add((Component)panelActions, "East"); - label.addMouseListener(new MouseAdapter(){ - - @Override - public void mousePressed(MouseEvent e) { - if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) { - client.setUsername(ProfilePanel.this.loginText); - if (config.rememberPassword() && ProfilePanel.this.password != null) { - client.setPassword(ProfilePanel.this.password); - } - } - } - }); - JPanel bottomContainer = new JPanel(new BorderLayout()); - bottomContainer.setBorder(new EmptyBorder(8, 0, 8, 0)); - bottomContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR); - bottomContainer.addMouseListener(new MouseAdapter(){ - - @Override - public void mousePressed(MouseEvent e) { - if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) { - client.setUsername(ProfilePanel.this.loginText); - } - } - }); - JLabel login = new JLabel(); - login.setText(config.isStreamerMode() ? "Hidden email" : this.loginText); - login.setBorder(null); - login.setPreferredSize(new Dimension(0, 24)); - login.setForeground(Color.WHITE); - login.setBorder(new EmptyBorder(0, 8, 0, 0)); - bottomContainer.add((Component)login, "Center"); - this.add((Component)labelWrapper, "North"); - this.add((Component)bottomContainer, "Center"); - } - - static { - BufferedImage deleteImg = ImageUtil.getResourceStreamFromClass(ProfilesPlugin.class, "delete_icon.png"); - DELETE_ICON = new ImageIcon(deleteImg); - DELETE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(deleteImg, -100)); - } - -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java deleted file mode 100644 index 2d6b171919..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Decompiled with CFR 0.139. - */ -package net.runelite.client.plugins.profiles; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup(value="profiles") -public interface ProfilesConfig -extends Config { - @ConfigItem(keyName="profilesData", name="", description="", hidden=true) - default public String profilesData() { - return ""; - } - - @ConfigItem(keyName="profilesData", name="", description="") - public void profilesData(String var1); - - @ConfigItem(keyName="rememberPassword", name="Remember Password", description="Remembers passwords for accounts") - default public boolean rememberPassword() { - return true; - } - - @ConfigItem(keyName="streamerMode", name="Hide email addresses", description="Hides your account emails") - default public boolean isStreamerMode() { - return false; - } - - @ConfigItem(keyName="switchPanel", name="Auto-open Panel", description="Automatically switch to the account switcher panel on the login screen") - default public boolean switchPanel() { - return true; - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java deleted file mode 100644 index f3f6da6b67..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Decompiled with CFR 0.139. - */ -package net.runelite.client.plugins.profiles; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.LayoutManager; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.Arrays; -import java.util.function.Consumer; -import javax.inject.Inject; -import javax.swing.JButton; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JTextField; -import javax.swing.border.Border; -import javax.swing.border.EmptyBorder; -import net.runelite.api.Client; -import net.runelite.client.plugins.profiles.ProfilePanel; -import net.runelite.client.plugins.profiles.ProfilesConfig; -import net.runelite.client.ui.ColorScheme; -import net.runelite.client.ui.PluginPanel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class ProfilesPanel -extends PluginPanel { - private static final Logger log = LoggerFactory.getLogger(ProfilesPanel.class); - private static final String ACCOUNT_USERNAME = "Account Username"; - private static final String ACCOUNT_LABEL = "Account Label"; - private static final String PASSWORD_LABEL = "Account Password"; - private static final Dimension PREFERRED_SIZE = new Dimension(205, 30); - private static final Dimension MINIMUM_SIZE = new Dimension(0, 30); - private final Client client; - private static ProfilesConfig profilesConfig; - private final JTextField txtAccountLabel = new JTextField("Account Label"); - private final JPasswordField txtAccountLogin = new JPasswordField("Account Username"); - private final JPasswordField txtPasswordLogin = new JPasswordField("Account Password"); - private final JPanel profilesPanel = new JPanel(); - private GridBagConstraints c; - - @Inject - public ProfilesPanel(Client client, final ProfilesConfig config) { - this.client = client; - profilesConfig = config; - this.setBorder(new EmptyBorder(18, 10, 0, 10)); - this.setBackground(ColorScheme.DARK_GRAY_COLOR); - this.setLayout(new GridBagLayout()); - this.c = new GridBagConstraints(); - this.c.fill = 2; - this.c.gridx = 0; - this.c.gridy = 0; - this.c.weightx = 1.0; - this.c.weighty = 0.0; - this.c.insets = new Insets(0, 0, 4, 0); - this.txtAccountLabel.setPreferredSize(PREFERRED_SIZE); - this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtAccountLabel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - this.txtAccountLabel.setMinimumSize(MINIMUM_SIZE); - this.txtAccountLabel.addFocusListener(new FocusListener(){ - - @Override - public void focusGained(FocusEvent e) { - if (ProfilesPanel.this.txtAccountLabel.getText().equals(ProfilesPanel.ACCOUNT_LABEL)) { - ProfilesPanel.this.txtAccountLabel.setText(""); - ProfilesPanel.this.txtAccountLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (ProfilesPanel.this.txtAccountLabel.getText().isEmpty()) { - ProfilesPanel.this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - ProfilesPanel.this.txtAccountLabel.setText(ProfilesPanel.ACCOUNT_LABEL); - } - } - }); - this.add((Component)this.txtAccountLabel, this.c); - ++this.c.gridy; - this.txtAccountLogin.setEchoChar('\u0000'); - this.txtAccountLogin.setPreferredSize(PREFERRED_SIZE); - this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtAccountLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR); - this.txtAccountLogin.setMinimumSize(MINIMUM_SIZE); - this.txtAccountLogin.addFocusListener(new FocusListener(){ - - @Override - public void focusGained(FocusEvent e) { - if (ProfilesPanel.ACCOUNT_USERNAME.equals(String.valueOf(ProfilesPanel.this.txtAccountLogin.getPassword()))) { - ProfilesPanel.this.txtAccountLogin.setText(""); - if (config.isStreamerMode()) { - ProfilesPanel.this.txtAccountLogin.setEchoChar('*'); - } - ProfilesPanel.this.txtAccountLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (ProfilesPanel.this.txtAccountLogin.getPassword().length == 0) { - ProfilesPanel.this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - ProfilesPanel.this.txtAccountLogin.setText(ProfilesPanel.ACCOUNT_USERNAME); - ProfilesPanel.this.txtAccountLogin.setEchoChar('\u0000'); - } - } - }); - this.add((Component)this.txtAccountLogin, this.c); - ++this.c.gridy; - this.txtPasswordLogin.setEchoChar('\u0000'); - this.txtPasswordLogin.setPreferredSize(PREFERRED_SIZE); - this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtPasswordLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR); - this.txtPasswordLogin.setToolTipText("Account password"); - this.txtPasswordLogin.setMinimumSize(MINIMUM_SIZE); - this.txtPasswordLogin.addFocusListener(new FocusListener(){ - - @Override - public void focusGained(FocusEvent e) { - if (ProfilesPanel.PASSWORD_LABEL.equals(String.valueOf(ProfilesPanel.this.txtPasswordLogin.getPassword()))) { - ProfilesPanel.this.txtPasswordLogin.setText(""); - ProfilesPanel.this.txtPasswordLogin.setEchoChar('*'); - ProfilesPanel.this.txtPasswordLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (ProfilesPanel.this.txtPasswordLogin.getPassword().length == 0) { - ProfilesPanel.this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - ProfilesPanel.this.txtPasswordLogin.setText(ProfilesPanel.PASSWORD_LABEL); - ProfilesPanel.this.txtPasswordLogin.setEchoChar('\u0000'); - } - } - }); - if (config.rememberPassword()) { - this.add((Component)this.txtPasswordLogin, this.c); - ++this.c.gridy; - } - this.c.insets = new Insets(0, 0, 15, 0); - final JButton btnAddAccount = new JButton("Add Account"); - btnAddAccount.setPreferredSize(PREFERRED_SIZE); - btnAddAccount.setBackground(ColorScheme.DARKER_GRAY_COLOR); - btnAddAccount.setMinimumSize(MINIMUM_SIZE); - btnAddAccount.addActionListener(e -> { - String labelText = String.valueOf(this.txtAccountLabel.getText()); - String loginText = String.valueOf(this.txtAccountLogin.getPassword()); - String passwordText = String.valueOf(this.txtPasswordLogin.getPassword()); - if (labelText.equals(ACCOUNT_LABEL) || loginText.equals(ACCOUNT_USERNAME)) { - return; - } - String data = config.rememberPassword() && this.txtPasswordLogin.getPassword() != null ? labelText + ":" + loginText + ":" + passwordText : labelText + ":" + loginText; - log.info(data); - this.addAccount(data); - ProfilesPanel.addProfile(data); - this.txtAccountLabel.setText(ACCOUNT_LABEL); - this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtAccountLogin.setText(ACCOUNT_USERNAME); - this.txtAccountLogin.setEchoChar('\u0000'); - this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtPasswordLogin.setText(PASSWORD_LABEL); - this.txtPasswordLogin.setEchoChar('\u0000'); - this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - }); - this.txtAccountLogin.addKeyListener(new KeyAdapter(){ - - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == 10) { - btnAddAccount.doClick(); - btnAddAccount.requestFocus(); - } - } - }); - this.txtAccountLogin.addMouseListener(new MouseListener(){ - - @Override - public void mouseClicked(MouseEvent e) { - } - - @Override - public void mousePressed(MouseEvent e) { - } - - @Override - public void mouseReleased(MouseEvent e) { - } - - @Override - public void mouseEntered(MouseEvent e) { - } - - @Override - public void mouseExited(MouseEvent e) { - } - }); - this.add((Component)btnAddAccount, this.c); - ++this.c.gridy; - this.profilesPanel.setLayout(new GridBagLayout()); - this.add((Component)this.profilesPanel, this.c); - this.c.gridy = 0; - this.c.insets = new Insets(0, 0, 5, 0); - this.addAccounts(config.profilesData()); - } - - void redrawProfiles() { - this.profilesPanel.removeAll(); - this.c.gridy = 0; - this.addAccounts(profilesConfig.profilesData()); - } - - private void addAccount(String data) { - ProfilePanel profile = new ProfilePanel(this.client, data, profilesConfig); - ++this.c.gridy; - this.profilesPanel.add((Component)profile, this.c); - this.revalidate(); - this.repaint(); - } - - void addAccounts(String data) { - if (!(data = data.trim()).contains(":")) { - return; - } - Arrays.stream(data.split("\\n")).forEach(this::addAccount); - } - - static void addProfile(String data) { - profilesConfig.profilesData(profilesConfig.profilesData() + data + "\n"); - } - - static void removeProfile(String data) { - profilesConfig.profilesData(profilesConfig.profilesData().replaceAll(data + "\\n", "")); - } - -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java deleted file mode 100644 index 467c2b820f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Decompiled with CFR 0.139. - */ -package net.runelite.client.plugins.profiles; - -import com.google.inject.Injector; -import com.google.inject.Provides; -import java.awt.image.BufferedImage; -import java.security.GeneralSecurityException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.NoSuchAlgorithmException; -import java.util.logging.Logger; -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.SecretKeySpec; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.GameStateChanged; -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.profiles.ProfilesConfig; -import net.runelite.client.plugins.profiles.ProfilesPanel; -import net.runelite.client.ui.ClientToolbar; -import net.runelite.client.ui.NavigationButton; -import net.runelite.client.ui.PluginPanel; -import net.runelite.client.util.ImageUtil; - -@PluginDescriptor(name="Account Switcher", description="Allow for a allows you to easily switch between multiple OSRS Accounts", tags={"profile", "account", "login", "log in"}) -public class ProfilesPlugin -extends Plugin { - @Inject - private ClientToolbar clientToolbar; - @Inject - private Client client; - @Inject - private ProfilesConfig config; - private ProfilesPanel panel; - private NavigationButton navButton; - String text = "Hello World"; - private static String key = "Bar12345Bar12345"; - private static Key aesKey = new SecretKeySpec(key.getBytes(), "AES"); - - @Provides - ProfilesConfig getConfig(ConfigManager configManager) { - return configManager.getConfig(ProfilesConfig.class); - } - - @Override - protected void startUp() throws Exception { - this.panel = this.injector.getInstance(ProfilesPanel.class); - BufferedImage icon = ImageUtil.getResourceStreamFromClass(this.getClass(), "profiles_icon.png"); - this.navButton = NavigationButton.builder().tooltip("Profiles").icon(icon).priority(8).panel(this.panel).build(); - this.clientToolbar.addNavigation(this.navButton); - } - - @Override - protected void shutDown() { - this.clientToolbar.removeNavigation(this.navButton); - } - - @Subscribe - private void onConfigChanged(ConfigChanged event) throws Exception { - if (event.getGroup().equals("profiles") && event.getKey().equals("rememberPassword")) { - this.panel = this.injector.getInstance(ProfilesPanel.class); - this.shutDown(); - this.startUp(); - } - } - - public static String decryptText(String text) { - byte[] bb = new byte[text.length()]; - for (int i = 0; i < text.length(); ++i) { - bb[i] = (byte)text.charAt(i); - } - Cipher cipher = null; - try { - cipher = Cipher.getInstance("AES"); - } - catch (NoSuchAlgorithmException | NoSuchPaddingException e) { - e.printStackTrace(); - } - try { - cipher.init(2, aesKey); - } - catch (InvalidKeyException e) { - e.printStackTrace(); - } - try { - Logger.getLogger("EncryptionLogger").info("Decrypted " + text + " to " + new String(cipher.doFinal(bb))); - return new String(cipher.doFinal(bb)); - } - catch (BadPaddingException | IllegalBlockSizeException e) { - e.printStackTrace(); - return ""; - } - } - - public static String encryptText(String text) { - try { - Cipher cipher = Cipher.getInstance("AES"); - cipher.init(1, aesKey); - byte[] encrypted = cipher.doFinal(text.getBytes()); - StringBuilder sb = new StringBuilder(); - for (byte b : encrypted) { - sb.append((char)b); - } - Logger.getLogger("EncryptionLogger").info("Encrypted " + text + " to " + sb.toString()); - return sb.toString(); - } - catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - catch (NoSuchPaddingException e) { - e.printStackTrace(); - } - catch (BadPaddingException e) { - e.printStackTrace(); - } - catch (IllegalBlockSizeException e) { - e.printStackTrace(); - } - catch (InvalidKeyException e) { - e.printStackTrace(); - } - return ""; - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/delete_icon.png b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/delete_icon.png deleted file mode 100644 index 18b67f23f3454d38f3758f3f42009f5a1fe03214..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mI14-?iy0WWg+Z8+Vb&Z8pkR}y zi(`n!#I+Y4xegf!uwHm1$rYQjwENzFCcRY^?Kw^_ZCjo@DfSu)EZIE!{CxZW=Xnk{ zrk0t8y?F6#(rwm@ApvTF-fT_0nwNcq%o6RzRhF1Xlr8;}zU|uD*fra3CC*fD`Z4$G zm*&4YE8bjNd$v^en6=-9QlIbhwx5yfWuHIW^8Xs~u!i*|FD#yH0lJ34)78&qol`;+ E08pz??f?J) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/profiles_icon.png b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/profiles_icon.png deleted file mode 100644 index a733eaf4a19343c3416d4b12cea60d735d9f7170..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77 zcmZ?wbhEHb6k!l#n8*ME|NsBLFxLl2D*j|)WME)s&;f~p!Protect Item Reminder", - description = "Reminds you to protect item when in the wilderness.", - tags = { "wilderness", "prayer", "protect", "item", "pking" }, - enabledByDefault = false -) -public class ProtectItemReminderPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private ProtectItemReminderOverlay overlay; - - @Inject - private ProtectItemReminderConfig config; - - private Player localPlayer; - - public boolean shouldRemind = false; - - @Provides - ProtectItemReminderConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(ProtectItemReminderConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - shouldRemind = false; - localPlayer = null; - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - { - localPlayer = client.getLocalPlayer(); - } - } - - @Subscribe - public void onGameTick(GameTick event) - { - if (client.getGameState() == GameState.LOGIN_SCREEN) - return; - - if (localPlayer == null) - { - shouldRemind = false; - return; - } - if (config.skulledOnly() && localPlayer.getSkullIcon() != SkullIcon.SKULL) - { - shouldRemind = false; - return; - } - if (MiscUtils.getWildernessLevelFrom(client, localPlayer.getWorldLocation()) <= 0) - { - shouldRemind = false; - return; - } - - int value = client.getVar(Prayer.PROTECT_ITEM.getVarbit()); - - if (value == 0) - shouldRemind = true; - else - shouldRemind = false; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/Obstacles.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/Obstacles.java deleted file mode 100644 index fff21802f0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/Obstacles.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2018, Steffen Hauge - * 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.pyramidplunder; - -import com.google.common.collect.ImmutableSet; -import java.util.Set; -import static net.runelite.api.ObjectID.SPEARTRAP_21280; - -public class Obstacles -{ - static final Set WALL_OBSTACLE_IDS = ImmutableSet.of( - 26618, 26619, 26620, 26621 - ); - - static final Set TRAP_OBSTACLE_IDS = ImmutableSet.of( - SPEARTRAP_21280 - ); -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderConfig.java deleted file mode 100644 index 4b3038762c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderConfig.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018, Steffen Hauge - * 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.pyramidplunder; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("pyramidplunder") -public interface PyramidPlunderConfig extends Config -{ - @ConfigItem( - position = 1, - keyName = "highlightDoors", - name = "Highlights doors", - description = "Highlights the four doors in each room" - ) - default boolean highlightDoors() - { - return true; - } - - @ConfigItem( - position = 2, - keyName = "highlightSpearTrap", - name = "Highlights spear traps", - description = "Highlights the spear traps in each room" - ) - default boolean highlightSpearTrap() - { - return false; - } - - @ConfigItem( - position = 3, - keyName = "showTimer", - name = "Display numerical timer", - description = "Displays a numerical timer instead of the default timer" - ) - default boolean showTimer() - { - return true; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderOverlay.java deleted file mode 100644 index fd61a03229..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderOverlay.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2018, Steffen Hauge - * 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.pyramidplunder; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.geom.Area; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.ObjectComposition; -import static net.runelite.api.ObjectID.SPEARTRAP_21280; -import static net.runelite.api.ObjectID.TOMB_DOOR_20948; -import static net.runelite.api.ObjectID.TOMB_DOOR_20949; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; - -public class PyramidPlunderOverlay extends Overlay -{ - private static final int MAX_DISTANCE = 2400; - private static final Color COLOR_DOOR = Color.GREEN; - private static final Color COLOR_SPEAR_TRAP = Color.ORANGE; - - private final Client client; - private final PyramidPlunderPlugin plugin; - private final PyramidPlunderConfig config; - - @Inject - private PyramidPlunderOverlay(Client client, PyramidPlunderPlugin plugin, PyramidPlunderConfig config) - { - this.client = client; - this.plugin = plugin; - this.config = config; - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - } - @Override - public Dimension render(Graphics2D graphics) - { - if (!plugin.isInGame()) - { - return null; - } - - LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation(); - Point mousePosition = client.getMouseCanvasPosition(); - - plugin.getObstacles().forEach((object, tile) -> - { - if (Obstacles.WALL_OBSTACLE_IDS.contains(object.getId()) && !config.highlightDoors() || - Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !config.highlightSpearTrap()) - { - return; - } - - if (tile.getPlane() == client.getPlane() && - object.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE) - { - int objectID = object.getId(); - if (Obstacles.WALL_OBSTACLE_IDS.contains(object.getId())) - { - //Impostor - ObjectComposition comp = client.getObjectDefinition(objectID); - ObjectComposition impostor = comp.getImpostor(); - - if (impostor == null) - { - return; - } - objectID = impostor.getId(); - } - - Area objectClickbox = object.getClickbox(); - if (objectClickbox != null) - { - Color configColor = Color.GREEN; - switch (objectID) - { - case SPEARTRAP_21280: - configColor = COLOR_SPEAR_TRAP; - break; - case TOMB_DOOR_20948: - case TOMB_DOOR_20949: - configColor = COLOR_DOOR; - break; - } - - if (objectClickbox.contains(mousePosition.getX(), mousePosition.getY())) - { - graphics.setColor(configColor.darker()); - } - else - { - graphics.setColor(configColor); - } - - graphics.draw(objectClickbox); - graphics.setColor(new Color(configColor.getRed(), configColor.getGreen(), configColor.getBlue(), 50)); - graphics.fill(objectClickbox); - } - } - }); - - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java deleted file mode 100644 index 64a009f2cb..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2018, Steffen Hauge - * 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.pyramidplunder; - -import com.google.common.eventbus.Subscribe; -import com.google.inject.Provides; -import java.time.temporal.ChronoUnit; -import java.util.HashMap; -import java.util.Map; -import javax.inject.Inject; -import lombok.Getter; -import net.runelite.api.Client; -import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE; -import net.runelite.api.Player; -import net.runelite.api.Tile; -import net.runelite.api.TileObject; -import net.runelite.api.Varbits; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.GameObjectChanged; -import net.runelite.api.events.GameObjectDespawned; -import net.runelite.api.events.GameObjectSpawned; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.VarbitChanged; -import net.runelite.api.events.WallObjectChanged; -import net.runelite.api.events.WallObjectDespawned; -import net.runelite.api.events.WallObjectSpawned; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.ui.overlay.infobox.InfoBoxManager; - -@PluginDescriptor( - name = "PyramidPlunder", - description = "Highlights doors and spear traps in pyramid plunder and adds a numerical timer", - tags = {"pyramidplunder", "pyramid", "plunder", "overlay", "skilling", "thieving"}, - enabledByDefault = false -) - -public class PyramidPlunderPlugin extends Plugin -{ - private static final int PYRAMIND_PLUNDER_REGION_ID = 7749; - private static final int PYRAMIND_PLUNDER_TIMER_MAX = 500; - private static final double GAMETICK_SECOND = 0.6; - - @Getter - private final Map obstacles = new HashMap<>(); - - @Inject - private Client client; - - @Inject - private PyramidPlunderConfig config; - - @Inject - private InfoBoxManager infoBoxManager; - - @Inject - private ItemManager itemManager; - - @Inject - private OverlayManager overlayManager; - - @Inject - private PyramidPlunderOverlay pyramidPlunderOverlay; - - @Getter - private boolean isInGame; - - private int pyramidTimer = 0; - - @Provides - PyramidPlunderConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(PyramidPlunderConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(pyramidPlunderOverlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(pyramidPlunderOverlay); - obstacles.clear(); - reset(); - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (!config.showTimer()) - { - removeTimer(); - } - - if (config.showTimer() && isInGame) - { - int remainingTime = PYRAMIND_PLUNDER_TIMER_MAX - pyramidTimer; - - if (remainingTime >= 2) - { - double timeInSeconds = remainingTime * GAMETICK_SECOND; - showTimer((int)timeInSeconds, ChronoUnit.SECONDS); - } - } - } - - private void removeTimer() - { - infoBoxManager.removeIf(infoBox -> infoBox instanceof PyramidPlunderTimer); - } - - private void showTimer() - { - showTimer(5, ChronoUnit.MINUTES); - } - - private void showTimer(int period, ChronoUnit chronoUnit) - { - removeTimer(); - infoBoxManager.addInfoBox(new PyramidPlunderTimer(this, itemManager.getImage(PHARAOHS_SCEPTRE), period, chronoUnit)); - } - - @Subscribe - public void onGameStateChange(GameStateChanged event) - { - switch (event.getGameState()) - { - case HOPPING: - case LOGIN_SCREEN: - reset(); - break; - case LOADING: - obstacles.clear(); - case LOGGED_IN: - if (!isInRegion()) - { - reset(); - } - break; - } - } - - private boolean isInRegion() - { - Player local = client.getLocalPlayer(); - if (local == null) - { - return false; - } - - WorldPoint location = local.getWorldLocation(); - if (location.getRegionID() != PYRAMIND_PLUNDER_REGION_ID) - { - return false; - } - - return true; - } - - @Subscribe - public void onVarbitChanged(VarbitChanged event) - { - int lastValue = pyramidTimer; - pyramidTimer = client.getVar(Varbits.PYRAMID_PLUNDER_TIMER); - - if (lastValue == pyramidTimer) - { - return; - } - - if (pyramidTimer == 0) - { - reset(); - } - if (pyramidTimer == 1) - { - isInGame = true; - if (config.showTimer()) - { - showTimer(); - } - } - } - - private void reset() - { - isInGame = false; - removeTimer(); - } - - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) - { - onTileObject(event.getTile(), null, event.getGameObject()); - } - - @Subscribe - public void onGameObjectChanged(GameObjectChanged event) - { - onTileObject(event.getTile(), event.getPrevious(), event.getGameObject()); - } - - @Subscribe - public void onGameObjectDeSpawned(GameObjectDespawned event) - { - onTileObject(event.getTile(), event.getGameObject(), null); - } - - @Subscribe - public void onWallObjectSpawned(WallObjectSpawned event) - { - onTileObject(event.getTile(), null, event.getWallObject()); - } - - @Subscribe - public void onWallObjectChanged(WallObjectChanged event) - { - onTileObject(event.getTile(), event.getPrevious(), event.getWallObject()); - } - - @Subscribe - public void onWallObjectDeSpawned(WallObjectDespawned event) - { - onTileObject(event.getTile(), event.getWallObject(), null); - } - - private void onTileObject(Tile tile, TileObject oldObject, TileObject newObject) - { - obstacles.remove(oldObject); - - if (newObject == null) - { - return; - } - - if (Obstacles.WALL_OBSTACLE_IDS.contains(newObject.getId()) || - Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId())) - { - obstacles.put(newObject, tile); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderTimer.java deleted file mode 100644 index a9f73cf8c3..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderTimer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2018, Steffen Hauge - * 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.pyramidplunder; - -import java.awt.image.BufferedImage; -import java.time.temporal.ChronoUnit; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.ui.overlay.infobox.Timer; - -public class PyramidPlunderTimer extends Timer -{ - PyramidPlunderTimer(Plugin plugin, BufferedImage image, int period, ChronoUnit chronoUnit) - { - super(period, chronoUnit, image, plugin); - setTooltip("Time left until minigame ends"); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java index 58a19463f3..2323a15a49 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java @@ -24,13 +24,9 @@ */ package net.runelite.client.plugins.raids; -import java.awt.Color; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; 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("raids") public interface RaidsConfig extends Config @@ -158,160 +154,6 @@ public interface RaidsConfig extends Config @ConfigItem( position = 11, - keyName = "showScavsFarms", - name = "Show scavengers and farming", - description = "Adds scavengers and farming to the room breakdown" - ) - default boolean showScavsFarms() - { - return false; - } - - @ConfigItem( - position = 12, - keyName = "enhanceScouterTitle", - name = "Enhance scouter title", - description = "Adds #combat and good puzzles to scouter title" - ) - default boolean enhanceScouterTitle() - { - return false; - } - - @ConfigItem( - position = 13, - keyName = "enableSharableImage", - name = "Enable sharable image", - description = "Use the specified hotkey to capture the raid scouter" - ) - default boolean enableSharableImage() - { - return false; - } - - @ConfigItem( - position = 14, - keyName = "hotkey", - name = "Capture hotkey", - description = "Hotkey used to capture the scouter" - ) - default Keybind hotkey() - { - return new Keybind(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK); - } - - @ConfigItem( - position = 15, - keyName = "enableTrayNotification", - name = "Enable tray notification", - description = "Adds a system tray notification on successful screen capture" - ) - default boolean enableTrayNotification() - { - return false; - } - - @ConfigItem( - position = 16, - keyName = "showRecommendedItems", - name = "Show recommended items", - description = "Adds overlay with recommended items to scouter" - ) - default boolean showRecommendedItems() - { - return false; - } - - @ConfigItem( - position = 17, - keyName = "recommendedItems", - name = "Recommended items", - description = "User-set recommended items in the form: [muttadiles,ice barrage,zamorak godsword],[tekton,elder maul], ..." - ) - default String recommendedItems() - { - return ""; - } - - @ConfigItem( - position = 18, - keyName = "scavsBeforeIce", - name = "Show last scavs for Ice Demon", - description = "Highlights final scavengers before Ice Demon" - ) - default boolean scavsBeforeIce() - { - return false; - } - - @ConfigItem( - position = 19, - keyName = "scavsBeforeOlm", - name = "Show last scavs for Olm", - description = "Highlights final scavengers before Olm" - ) - default boolean scavsBeforeOlm() - { - return false; - } - - @ConfigItem( - position = 20, - keyName = "scavPrepColor", - name = "Last scavs color", - description = "The color of the final scavs before Ice Demon/Olm" - ) - default Color scavPrepColor() - { - return new Color(130, 222, 255); //light blue - } - - @ConfigItem( - position = 21, - keyName = "alwaysShowWorldAndCC", - name = "Always show CC and World", - description = "The CC and World are not removed from being in the in-game scouter" - ) - default boolean alwaysShowWorldAndCC() - { - return false; - } - - @ConfigItem( - position = 22, - keyName = "colorTightrope", - name = "Color tightrope", - description = "Colors tightrope a separate color" - ) - default boolean colorTightrope() - { - return false; - } - - @ConfigItem( - position = 23, - keyName = "tightropeColor", - name = "Tightrope color", - description = "The color of tightropes" - ) - default Color tightropeColor() - { - return Color.MAGENTA; - } - - @ConfigItem( - position = 24, - keyName = "hideRopeless", - name = "Hide no Tightrope raids", - description = "Completely hides raids with no tightrope" - ) - default boolean hideRopeless() - { - return false; - } - - @ConfigItem( - position = 25, keyName = "layoutMessage", name = "Send raid layout message when entering raid", description = "Sends game message with raid layout on entering new raid" diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java index 9c851e5dc6..5ca7214b57 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java @@ -24,23 +24,12 @@ */ package net.runelite.client.plugins.raids; -import java.awt.Point; -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import lombok.Getter; -import lombok.Setter; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import javax.inject.Inject; +import lombok.Setter; import net.runelite.api.Client; -import net.runelite.api.SpriteID; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.game.ItemManager; -import net.runelite.client.game.SpriteManager; import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; import net.runelite.client.plugins.raids.solver.Room; import net.runelite.client.ui.overlay.Overlay; @@ -48,48 +37,24 @@ import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.components.ImageComponent; 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.util.ImageUtil; -import net.runelite.client.util.Text; public class RaidsOverlay extends Overlay { private static final int OLM_PLANE = 0; - private static final int BORDER_OFFSET = 2; - private static final int ICON_SIZE = 32; - private static final int SMALL_ICON_SIZE = 21; - //might need to edit these if they are not standard - private static final int TITLE_COMPONENT_HEIGHT = 20; - private static final int LINE_COMPONENT_HEIGHT = 16; private Client client; private RaidsPlugin plugin; private RaidsConfig config; private final PanelComponent panelComponent = new PanelComponent(); - private final ItemManager itemManager; - private final SpriteManager spriteManager; - private final PanelComponent panelImages = new PanelComponent(); - - @Setter - private boolean sharable = false; @Setter private boolean scoutOverlayShown = false; - @Getter - private boolean scouterActive = false; - - @Getter - private int width; - - @Getter - private int height; - @Inject - private RaidsOverlay(Client client, RaidsPlugin plugin, RaidsConfig config, ItemManager itemManager, SpriteManager spriteManager) + private RaidsOverlay(Client client, RaidsPlugin plugin, RaidsConfig config) { super(plugin); setPosition(OverlayPosition.TOP_LEFT); @@ -97,8 +62,6 @@ public class RaidsOverlay extends Overlay this.client = client; this.plugin = plugin; this.config = config; - this.itemManager = itemManager; - this.spriteManager = spriteManager; getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Raids overlay")); } @@ -110,7 +73,6 @@ public class RaidsOverlay extends Overlay return null; } - scouterActive = false; panelComponent.getChildren().clear(); if (plugin.getRaid() == null || plugin.getRaid().getLayout() == null) @@ -131,117 +93,19 @@ public class RaidsOverlay extends Overlay color = Color.RED; } - int combatCount = 0; - int roomCount = 0; - List iceRooms = new ArrayList<>(); - List scavRooms = new ArrayList<>(); - List scavsBeforeIceRooms = new ArrayList<>(); - boolean crabs = false; - boolean iceDemon = false; - boolean tightrope = false; - boolean thieving = false; - String puzzles = ""; - if (config.enhanceScouterTitle() || config.scavsBeforeIce() || sharable) - { - for (Room layoutRoom : plugin.getRaid().getLayout().getRooms()) - { - int position = layoutRoom.getPosition(); - RaidRoom room = plugin.getRaid().getRoom(position); - - if (room == null) - { - continue; - } - - switch (room.getType()) - { - case COMBAT: - combatCount++; - break; - case PUZZLE: - String roomName = room.getPuzzle().getName(); - switch (RaidRoom.Puzzle.fromString(roomName)) - { - case CRABS: - crabs = true; - break; - case ICE_DEMON: - iceDemon = true; - iceRooms.add(roomCount); - break; - case THIEVING: - thieving = true; - break; - case TIGHTROPE: - tightrope = true; - break; - } - break; - case SCAVENGERS: - scavRooms.add(roomCount); - break; - } - roomCount++; - } - if (tightrope) - puzzles = crabs ? "cr" : iceDemon ? "ri" : thieving ? "tr" : "?r"; - else if (config.hideRopeless()) - { - panelComponent.getChildren().add(TitleComponent.builder() - .text("No Tightrope!") - .color(Color.RED) - .build()); - - return panelComponent.render(graphics); - } - - scouterActive = true; - layout = (config.enhanceScouterTitle() ? "" + combatCount + "c " + puzzles + " " : "") + layout; - - for (Integer i : iceRooms) - { - int prev = 0; - for (Integer s : scavRooms) - { - if (s > i) - break; - prev = s; - } - scavsBeforeIceRooms.add(prev); - } - } - int lastScavs = scavRooms.get(scavRooms.size() - 1); panelComponent.getChildren().add(TitleComponent.builder() .text(layout) .color(color) .build()); - color = Color.ORANGE; - if (sharable || config.alwaysShowWorldAndCC()) - { - String clanOwner = Text.removeTags(client.getWidget(WidgetInfo.CLAN_CHAT_OWNER).getText()); - if (clanOwner.equals("None")) - { - clanOwner = "Open CC tab..."; - color = Color.RED; - } - panelComponent.getChildren().add(LineComponent.builder() - .left("W" + client.getWorld()) - .right("" + clanOwner) - .leftColor(Color.ORANGE) - .rightColor(color) - .build()); - } int bossMatches = 0; int bossCount = 0; - roomCount = 0; if (config.enableRotationWhitelist()) { bossMatches = plugin.getRotationMatches(); } - Set imageIds = new HashSet<>(); for (Room layoutRoom : plugin.getRaid().getLayout().getRooms()) { int position = layoutRoom.getPosition(); @@ -263,144 +127,38 @@ public class RaidsOverlay extends Overlay color = Color.GREEN; } else if (plugin.getRoomBlacklist().contains(room.getBoss().getName().toLowerCase()) - || config.enableRotationWhitelist() && bossCount > bossMatches) + || config.enableRotationWhitelist() && bossCount > bossMatches) { color = Color.RED; } - String bossName = room.getBoss().getName(); - String bossNameLC = bossName.toLowerCase(); - if (config.showRecommendedItems()) - { - if (plugin.getRecommendedItemsList().get(bossNameLC) != null) - imageIds.addAll(plugin.getRecommendedItemsList().get(bossNameLC)); - } - panelComponent.getChildren().add(LineComponent.builder() - .left(config.showRecommendedItems() ? "" : room.getType().getName()) - .right(bossName) + .left(room.getType().getName()) + .right(room.getBoss().getName()) .rightColor(color) .build()); break; case PUZZLE: - String puzzleName = room.getPuzzle().getName(); - String puzzleNameLC = puzzleName.toLowerCase(); - if (plugin.getRecommendedItemsList().get(puzzleNameLC) != null) - imageIds.addAll(plugin.getRecommendedItemsList().get(puzzleNameLC)); - if (plugin.getRoomWhitelist().contains(puzzleNameLC)) + if (plugin.getRoomWhitelist().contains(room.getPuzzle().getName().toLowerCase())) { color = Color.GREEN; } - else if (plugin.getRoomBlacklist().contains(puzzleNameLC)) + else if (plugin.getRoomBlacklist().contains(room.getPuzzle().getName().toLowerCase())) { color = Color.RED; } - if (config.colorTightrope() && puzzleNameLC.equals("tightrope")) - { - color = config.tightropeColor(); - } panelComponent.getChildren().add(LineComponent.builder() - .left(config.showRecommendedItems() ? "" : room.getType().getName()) - .right(puzzleName) + .left(room.getType().getName()) + .right(room.getPuzzle().getName()) .rightColor(color) .build()); break; - case FARMING: - if (config.showScavsFarms()) - { - panelComponent.getChildren().add(LineComponent.builder() - .left("") - .right(room.getType().getName()) - .rightColor(new Color(181, 230, 29)) //yellow green - .build()); - } - break; - case SCAVENGERS: - if (config.scavsBeforeOlm() && roomCount == lastScavs) - { - panelComponent.getChildren().add(LineComponent.builder() - .left(config.showRecommendedItems() ? "" : "OlmPrep") - .right("Scavs") - .rightColor(config.scavPrepColor()) - .build()); - } - else if (config.scavsBeforeIce() && scavsBeforeIceRooms.contains(roomCount)) - { - panelComponent.getChildren().add(LineComponent.builder() - .left(config.showRecommendedItems() ? "" : "IcePrep") - .right("Scavs") - .rightColor(config.scavPrepColor()) - .build()); - } - else if (config.showScavsFarms()) - { - panelComponent.getChildren().add(LineComponent.builder() - .left("") - .right("Scavs") - .rightColor(new Color(181, 230, 29)) //yellow green - .build()); - } - break; } - roomCount++; } - Dimension panelDims = panelComponent.render(graphics); - width = (int) panelDims.getWidth(); - height = (int) panelDims.getHeight(); - - //add recommended items - if (config.showRecommendedItems() && imageIds.size() > 0) - { - panelImages.getChildren().clear(); - Integer[] idArray = imageIds.toArray(new Integer[0]); - int imagesVerticalOffset = TITLE_COMPONENT_HEIGHT + (sharable || config.alwaysShowWorldAndCC() ? LINE_COMPONENT_HEIGHT : 0) - BORDER_OFFSET; - int imagesMaxHeight = height - 2 * BORDER_OFFSET - TITLE_COMPONENT_HEIGHT - (sharable || config.alwaysShowWorldAndCC() ? LINE_COMPONENT_HEIGHT : 0); - boolean smallImages = false; - - panelImages.setPreferredLocation(new Point(0, imagesVerticalOffset)); - panelImages.setBackgroundColor(null); - if (2 * (imagesMaxHeight / ICON_SIZE) >= idArray.length ) - { - panelImages.setWrapping(2); - } - else - { - panelImages.setWrapping(3); - smallImages = true; - } - - panelImages.setOrientation(PanelComponent.Orientation.HORIZONTAL); - for (Integer e : idArray) - { - final BufferedImage image = getImage(e, smallImages); - if (image != null) - { - panelImages.getChildren().add(new ImageComponent(image)); - } - } - - panelImages.render(graphics); - } - return panelDims; - } - - private BufferedImage getImage(int id, boolean small) - { - BufferedImage bim; - if (id != SpriteID.SPELL_ICE_BARRAGE) - bim = itemManager.getImage(id); - else - bim = spriteManager.getSprite(id, 0); - if (bim == null) - return null; - if (!small) - return ImageUtil.resizeCanvas(bim, ICON_SIZE, ICON_SIZE); - if (id != SpriteID.SPELL_ICE_BARRAGE) - return ImageUtil.resizeImage(bim, SMALL_ICON_SIZE, SMALL_ICON_SIZE); - return ImageUtil.resizeCanvas(bim, SMALL_ICON_SIZE, SMALL_ICON_SIZE); + return panelComponent.render(graphics); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index 80723bd0f5..34db989c71 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -26,18 +26,10 @@ package net.runelite.client.plugins.raids; import com.google.inject.Binder; import com.google.inject.Provides; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.image.BufferedImage; import java.text.DecimalFormat; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ScheduledExecutorService; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; @@ -47,11 +39,9 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.InstanceTemplates; -import net.runelite.api.ItemID; import net.runelite.api.NullObjectID; import static net.runelite.api.Perspective.SCENE_SIZE; import net.runelite.api.Point; -import net.runelite.api.SpriteID; import static net.runelite.api.SpriteID.TAB_QUESTS_BROWN_RAIDING_PARTY; import net.runelite.api.Tile; import net.runelite.api.VarPlayer; @@ -59,34 +49,27 @@ import net.runelite.api.Varbits; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.VarbitChanged; -import net.runelite.api.widgets.Widget; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.game.ItemManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.SpriteManager; -import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.raids.solver.Layout; import net.runelite.client.plugins.raids.solver.LayoutSolver; import net.runelite.client.plugins.raids.solver.RotationSolver; -import net.runelite.client.ui.DrawManager; -import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; -import net.runelite.client.util.ScreenCapture; import net.runelite.client.util.Text; -import net.runelite.client.util.HotkeyListener; @PluginDescriptor( name = "Chambers Of Xeric", description = "Show helpful information for the Chambers of Xeric raid", - tags = {"combat", "raid", "overlay", "pve", "pvm", "bosses", "cox", "olm"} + tags = {"combat", "raid", "overlay", "pve", "pvm", "bosses"} ) @Slf4j public class RaidsPlugin extends Plugin @@ -99,10 +82,6 @@ public class RaidsPlugin extends Plugin static final DecimalFormat POINTS_FORMAT = new DecimalFormat("#,###"); private static final String SPLIT_REGEX = "\\s*,\\s*"; private static final Pattern ROTATION_REGEX = Pattern.compile("\\[(.*?)]"); - private static final int LINE_COMPONENT_HEIGHT = 16; - - @Inject - private ItemManager itemManager; @Inject private ChatMessageManager chatMessageManager; @@ -113,12 +92,6 @@ public class RaidsPlugin extends Plugin @Inject private Client client; - @Inject - private DrawManager drawManager; - - @Inject - private ScheduledExecutorService executor; - @Inject private RaidsConfig config; @@ -137,12 +110,6 @@ public class RaidsPlugin extends Plugin @Inject private ClientThread clientThread; - @Inject - private KeyManager keyManager; - - @Inject - private ScreenCapture screenCapture; - @Getter private final ArrayList roomWhitelist = new ArrayList<>(); @@ -155,9 +122,6 @@ public class RaidsPlugin extends Plugin @Getter private final ArrayList layoutWhitelist = new ArrayList<>(); - @Getter - private final Map> recommendedItemsList = new HashMap<>(); - @Getter private Raid raid; @@ -184,7 +148,6 @@ public class RaidsPlugin extends Plugin overlayManager.add(overlay); updateLists(); clientThread.invokeLater(() -> checkRaidPresence(true)); - keyManager.registerKeyListener(hotkeyListener); } @Override @@ -195,7 +158,6 @@ public class RaidsPlugin extends Plugin inRaidChambers = false; raid = null; timer = null; - keyManager.unregisterKeyListener(hotkeyListener); } @Subscribe @@ -384,41 +346,6 @@ public class RaidsPlugin extends Plugin updateList(roomBlacklist, config.blacklistedRooms()); updateList(rotationWhitelist, config.whitelistedRotations()); updateList(layoutWhitelist, config.whitelistedLayouts()); - updateMap(recommendedItemsList, config.recommendedItems()); - } - - private void updateMap(Map> map, String input) - { - map.clear(); - - Matcher m = ROTATION_REGEX.matcher(input); - while (m.find()) - { - String everything = m.group(1).toLowerCase(); - int split = everything.indexOf(','); - if (split < 0) - continue; - String key = everything.substring(0, split); - if (key.length() < 1) - continue; - String[] itemNames = everything.substring(split).split(SPLIT_REGEX); - - map.computeIfAbsent(key, k -> new ArrayList<>()); - - for (String itemName : itemNames) - { - if (itemName.equals("")) - continue; - if (itemName.equals("ice barrage")) - map.get(key).add(SpriteID.SPELL_ICE_BARRAGE); - else if (itemName.startsWith("salve")) - map.get(key).add(ItemID.SALVE_AMULETEI); - else if (itemManager.search(itemName).size() > 0) - map.get(key).add(itemManager.search(itemName).get(0).getId()); - else - log.info("RaidsPlugin: Could not find an item ID for item: " + itemName); - } - } } private void updateList(ArrayList list, String input) @@ -675,42 +602,4 @@ public class RaidsPlugin extends Plugin return room; } - - private final HotkeyListener hotkeyListener = new HotkeyListener(() -> config.hotkey()) - { - @Override - public void hotkeyPressed() - { - initiateCopyImage(); - } - }; - - private void initiateCopyImage() - { - if (!config.enableSharableImage() || !overlay.isScouterActive()) - return; - - Rectangle overlaySize = overlay.getBounds(); - if (overlaySize.width <= 0 || overlaySize.height <= 0) - return; - if (!config.alwaysShowWorldAndCC()) - overlaySize.height += LINE_COMPONENT_HEIGHT; - - BufferedImage bim = new BufferedImage(overlaySize.width, overlaySize.height, BufferedImage.TYPE_INT_ARGB); - overlay.setSharable(true); - Graphics2D g = bim.createGraphics(); - g.setFont(FontManager.getRunescapeFont()); - - //this is needed to update the PanelComponent childDimensions, because they are a frame behind - if (!config.alwaysShowWorldAndCC()) - overlay.render(g); - g.setColor(Color.BLACK); - g.fillRect(0, 0, overlaySize.width, overlaySize.height); - - overlay.render(g); - screenCapture.takeScreenshot(bim, config.enableTrayNotification(), "Chambers"); - g.dispose(); - - overlay.setSharable(false); - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java deleted file mode 100644 index ebbad81a54..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2018, Tim Lehner - * 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.raidsthieving.BatSolver; - -import java.util.Map; -import java.util.HashSet; -import java.util.HashMap; -import java.util.TreeSet; -import java.util.List; -import java.util.ArrayList; -import static net.runelite.client.plugins.raidsthieving.BatSolver.SolutionSet.SOLUTION_SETS; - -public class BatSolver -{ - private Map numberOfSolutionsWithPoison; - private final SolutionSet solution; - - private final HashSet grubsChests; - - public BatSolver(ThievingRoomType roomType) - { - solution = new SolutionSet(roomType); - grubsChests = new HashSet<>(); - } - - public void addEmptyChest(int chestId) - { - // When a new empty chest is found, add it to the current solution set - solution.addEmptyChest(chestId); - calculateChanceOfPoison(); - } - - public void addGrubsChest(int chestId) - { - // When a chest with grubs is found, keep track of it to invalidate solutions - grubsChests.add(chestId); - calculateChanceOfPoison(); - } - - public TreeSet matchSolutions() - { - TreeSet possibleEmptyChests = new TreeSet<>(); - for (SolutionSet knownSolution : SolutionSet.SOLUTION_SETS) - { - if (knownSolution.getType() == solution.getType() && matchSolution(knownSolution)) - { - possibleEmptyChests.addAll(knownSolution.getEmptyChests()); - } - } - - return possibleEmptyChests; - } - - private boolean matchSolution(SolutionSet testSolution) - { - for (Integer grubsChest : grubsChests) - { - if (testSolution.containsChest(grubsChest)) - { - // If one of the chests is known to have grubs, it cannot be a solution - return false; - } - } - - boolean matchesAll = true; - boolean everMatched = false; - for (int i : solution.getEmptyChests()) - { - if (!testSolution.containsChest(i)) - { - matchesAll = false; - } - else - { - everMatched = true; - } - } - return matchesAll && everMatched; - } - - public ThievingRoomType getType() - { - return solution.getType(); - } - - - public void calculateChanceOfPoison() - { - if (getType() == null) - { - numberOfSolutionsWithPoison = null; - return; - } - - numberOfSolutionsWithPoison = new HashMap<>(); - for (SolutionSet sol : getPosssibleSolutions()) - { - if (getType() == sol.getType() && (solution.getEmptyChests().size() == 0 || matchSolution(sol))) - { - for (Integer i : sol.getEmptyChests()) - { - if (numberOfSolutionsWithPoison.containsKey(i)) - { - numberOfSolutionsWithPoison.put(i, numberOfSolutionsWithPoison.get(i) + 1); - } - else - { - numberOfSolutionsWithPoison.put(i, 1); - } - } - } - } - } - - private List getPosssibleSolutions() - { - List possibleSolutions = new ArrayList<>(); - for (SolutionSet soln : SOLUTION_SETS) - { - // Check if we've found grubs in one of the chests, invalidating it as an solution - boolean foundMatch = false; - for (int i : grubsChests) - { - if (soln.containsChest(i)) - { - foundMatch = true; - } - } - if (!foundMatch) - { - possibleSolutions.add(soln); - } - } - return possibleSolutions; - } - - public double relativeLikelihoodPoison(int chestId) - { - // Returns a double between 0 and 1 of how likely the chest has poison based on the number of possible solutions - // Uses a Sigmoid like function to give good contrast in drawn opacity, - // perhaps could be changed to something more accurate quantitavely. - if (numberOfSolutionsWithPoison == null) - { - calculateChanceOfPoison(); - } - if (numberOfSolutionsWithPoison == null) - { - return 1.0; - } - int mostFrequentPoison = 0; - for (Map.Entry entry : numberOfSolutionsWithPoison.entrySet()) - { - if (entry.getValue() > mostFrequentPoison) - { - mostFrequentPoison = entry.getValue(); - } - } - int timesFound = 0; - if (numberOfSolutionsWithPoison.containsKey(chestId)) - { - timesFound = numberOfSolutionsWithPoison.get(chestId); - } - double chestChance = (double) (timesFound) / (double) (mostFrequentPoison); - return 1. / (1 + Math.exp(5 - 10 * chestChance)); - } - - public int getNumberOfEmptyChests() - { - return solution.getEmptyChests().size(); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java deleted file mode 100644 index 7346e4ecf6..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2018, Tim Lehner - * 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.raidsthieving.BatSolver; - -import net.runelite.client.plugins.raidsthieving.InstancePoint; -import net.runelite.client.plugins.raidsthieving.ThievingChest; -import java.util.HashMap; -import java.util.Map; - -public class ChestIdentifier -{ - public ChestIdentifier(ThievingRoomType roomType) - { - chestIds = new HashMap<>(); - switch (roomType) - { - case LEFT_TURN: - chestIds.put(new InstancePoint(3283, 5379), 1); - chestIds.put(new InstancePoint(3285, 5380), 2); - chestIds.put(new InstancePoint(3279, 5381), 3); - chestIds.put(new InstancePoint(3287, 5382), 4); - chestIds.put(new InstancePoint(3281, 5382), 5); - chestIds.put(new InstancePoint(3284, 5383), 6); - chestIds.put(new InstancePoint(3283, 5384), 7); - chestIds.put(new InstancePoint(3286, 5384), 8); - chestIds.put(new InstancePoint(3288, 5384), 9); - chestIds.put(new InstancePoint(3277, 5385), 10); - chestIds.put(new InstancePoint(3280, 5385), 11); - chestIds.put(new InstancePoint(3285, 5386), 12); - chestIds.put(new InstancePoint(3290, 5386), 13); - chestIds.put(new InstancePoint(3275, 5387), 14); - chestIds.put(new InstancePoint(3287, 5387), 15); - chestIds.put(new InstancePoint(3288, 5387), 16); - chestIds.put(new InstancePoint(3281, 5388), 17); - chestIds.put(new InstancePoint(3291, 5388), 18); - chestIds.put(new InstancePoint(3280, 5389), 19); - chestIds.put(new InstancePoint(3285, 5389), 20); - chestIds.put(new InstancePoint(3289, 5389), 21); - chestIds.put(new InstancePoint(3283, 5390), 22); - chestIds.put(new InstancePoint(3285, 5390), 23); - chestIds.put(new InstancePoint(3288, 5390), 24); - chestIds.put(new InstancePoint(3290, 5390), 25); - chestIds.put(new InstancePoint(3282, 5391), 26); - chestIds.put(new InstancePoint(3289, 5391), 27); - chestIds.put(new InstancePoint(3292, 5391), 28); - chestIds.put(new InstancePoint(3279, 5392), 29); - chestIds.put(new InstancePoint(3276, 5393), 30); - chestIds.put(new InstancePoint(3279, 5393), 31); - chestIds.put(new InstancePoint(3284, 5393), 32); - chestIds.put(new InstancePoint(3285, 5393), 33); - chestIds.put(new InstancePoint(3291, 5393), 34); - chestIds.put(new InstancePoint(3275, 5394), 35); - chestIds.put(new InstancePoint(3277, 5394), 36); - chestIds.put(new InstancePoint(3288, 5394), 37); - chestIds.put(new InstancePoint(3276, 5395), 38); - chestIds.put(new InstancePoint(3281, 5395), 39); - chestIds.put(new InstancePoint(3285, 5395), 40); - chestIds.put(new InstancePoint(3287, 5395), 41); - chestIds.put(new InstancePoint(3289, 5395), 42); - chestIds.put(new InstancePoint(3274, 5396), 43); - chestIds.put(new InstancePoint(3283, 5396), 44); - chestIds.put(new InstancePoint(3285, 5396), 45); - chestIds.put(new InstancePoint(3288, 5396), 46); - chestIds.put(new InstancePoint(3272, 5397), 47); - chestIds.put(new InstancePoint(3280, 5397), 48); - chestIds.put(new InstancePoint(3277, 5398), 49); - chestIds.put(new InstancePoint(3281, 5398), 50); - chestIds.put(new InstancePoint(3284, 5398), 51); - chestIds.put(new InstancePoint(3276, 5399), 52); - chestIds.put(new InstancePoint(3278, 5399), 53); - chestIds.put(new InstancePoint(3283, 5399), 54); - chestIds.put(new InstancePoint(3285, 5399), 55); - chestIds.put(new InstancePoint(3277, 5400), 56); - chestIds.put(new InstancePoint(3284, 5400), 57); - chestIds.put(new InstancePoint(3288, 5400), 58); - chestIds.put(new InstancePoint(3281, 5401), 59); - chestIds.put(new InstancePoint(3286, 5401), 60); - chestIds.put(new InstancePoint(3279, 5402), 61); - chestIds.put(new InstancePoint(3285, 5402), 62); - chestIds.put(new InstancePoint(3280, 5403), 63); - chestIds.put(new InstancePoint(3283, 5403), 64); - break; - case RIGHT_TURN: - chestIds.put(new InstancePoint(3338, 5405), 1); - chestIds.put(new InstancePoint(3334, 5405), 2); - chestIds.put(new InstancePoint(3342, 5404), 3); - chestIds.put(new InstancePoint(3340, 5404), 4); - chestIds.put(new InstancePoint(3345, 5403), 5); - chestIds.put(new InstancePoint(3334, 5403), 6); - chestIds.put(new InstancePoint(3330, 5403), 7); - chestIds.put(new InstancePoint(3343, 5402), 8); - chestIds.put(new InstancePoint(3342, 5402), 9); - chestIds.put(new InstancePoint(3339, 5402), 10); - chestIds.put(new InstancePoint(3338, 5402), 11); - chestIds.put(new InstancePoint(3336, 5402), 12); - chestIds.put(new InstancePoint(3347, 5401), 13); - chestIds.put(new InstancePoint(3330, 5401), 14); - chestIds.put(new InstancePoint(3345, 5400), 15); - chestIds.put(new InstancePoint(3341, 5400), 16); - chestIds.put(new InstancePoint(3337, 5400), 17); - chestIds.put(new InstancePoint(3334, 5400), 18); - chestIds.put(new InstancePoint(3345, 5399), 19); - chestIds.put(new InstancePoint(3343, 5399), 20); - chestIds.put(new InstancePoint(3340, 5399), 21); - chestIds.put(new InstancePoint(3335, 5399), 22); - chestIds.put(new InstancePoint(3331, 5399), 23); - chestIds.put(new InstancePoint(3338, 5398), 24); - chestIds.put(new InstancePoint(3337, 5398), 25); - chestIds.put(new InstancePoint(3345, 5397), 26); - chestIds.put(new InstancePoint(3341, 5397), 27); - chestIds.put(new InstancePoint(3334, 5397), 28); - chestIds.put(new InstancePoint(3331, 5397), 29); - chestIds.put(new InstancePoint(3346, 5396), 30); - chestIds.put(new InstancePoint(3343, 5396), 31); - chestIds.put(new InstancePoint(3339, 5396), 32); - chestIds.put(new InstancePoint(3335, 5396), 33); - chestIds.put(new InstancePoint(3333, 5396), 34); - chestIds.put(new InstancePoint(3340, 5395), 35); - chestIds.put(new InstancePoint(3337, 5395), 36); - chestIds.put(new InstancePoint(3334, 5395), 37); - chestIds.put(new InstancePoint(3345, 5394), 38); - chestIds.put(new InstancePoint(3342, 5394), 39); - chestIds.put(new InstancePoint(3332, 5394), 40); - chestIds.put(new InstancePoint(3343, 5393), 41); - chestIds.put(new InstancePoint(3341, 5393), 42); - chestIds.put(new InstancePoint(3338, 5393), 43); - chestIds.put(new InstancePoint(3335, 5393), 44); - chestIds.put(new InstancePoint(3334, 5393), 45); - chestIds.put(new InstancePoint(3346, 5392), 46); - chestIds.put(new InstancePoint(3342, 5392), 47); - chestIds.put(new InstancePoint(3332, 5392), 48); - chestIds.put(new InstancePoint(3350, 5391), 49); - chestIds.put(new InstancePoint(3346, 5391), 50); - chestIds.put(new InstancePoint(3340, 5391), 51); - chestIds.put(new InstancePoint(3339, 5391), 52); - chestIds.put(new InstancePoint(3336, 5391), 53); - chestIds.put(new InstancePoint(3333, 5391), 54); - chestIds.put(new InstancePoint(3349, 5390), 55); - chestIds.put(new InstancePoint(3343, 5390), 56); - chestIds.put(new InstancePoint(3337, 5390), 57); - chestIds.put(new InstancePoint(3335, 5390), 58); - chestIds.put(new InstancePoint(3344, 5389), 59); - chestIds.put(new InstancePoint(3340, 5389), 60); - chestIds.put(new InstancePoint(3336, 5389), 61); - chestIds.put(new InstancePoint(3333, 5389), 62); - chestIds.put(new InstancePoint(3346, 5388), 63); - chestIds.put(new InstancePoint(3340, 5387), 64); - chestIds.put(new InstancePoint(3337, 5386), 65); - chestIds.put(new InstancePoint(3333, 5386), 66); - chestIds.put(new InstancePoint(3338, 5385), 67); - chestIds.put(new InstancePoint(3336, 5385), 68); - chestIds.put(new InstancePoint(3337, 5384), 69); - chestIds.put(new InstancePoint(3340, 5382), 70); - chestIds.put(new InstancePoint(3334, 5383), 71); - chestIds.put(new InstancePoint(3340, 5379), 72); - chestIds.put(new InstancePoint(3338, 5380), 73); - chestIds.put(new InstancePoint(3336, 5381), 74); - break; - case STRAIGHT: - chestIds.put(new InstancePoint(3308, 5378), 1); - chestIds.put(new InstancePoint(3305, 5379), 2); - chestIds.put(new InstancePoint(3307, 5379), 3); - chestIds.put(new InstancePoint(3304, 5381), 4); - chestIds.put(new InstancePoint(3310, 5381), 5); - chestIds.put(new InstancePoint(3302, 5382), 6); - chestIds.put(new InstancePoint(3307, 5382), 7); - chestIds.put(new InstancePoint(3312, 5382), 8); - chestIds.put(new InstancePoint(3317, 5382), 9); - chestIds.put(new InstancePoint(3319, 5382), 10); - chestIds.put(new InstancePoint(3304, 5383), 11); - chestIds.put(new InstancePoint(3305, 5383), 12); - chestIds.put(new InstancePoint(3307, 5383), 13); - chestIds.put(new InstancePoint(3310, 5383), 14); - chestIds.put(new InstancePoint(3315, 5383), 15); - chestIds.put(new InstancePoint(3320, 5383), 16); - chestIds.put(new InstancePoint(3300, 5384), 17); - chestIds.put(new InstancePoint(3309, 5384), 18); - chestIds.put(new InstancePoint(3311, 5384), 19); - chestIds.put(new InstancePoint(3313, 5384), 20); - chestIds.put(new InstancePoint(3317, 5384), 21); - chestIds.put(new InstancePoint(3318, 5384), 22); - chestIds.put(new InstancePoint(3302, 5385), 23); - chestIds.put(new InstancePoint(3306, 5385), 24); - chestIds.put(new InstancePoint(3310, 5385), 25); - chestIds.put(new InstancePoint(3313, 5385), 26); - chestIds.put(new InstancePoint(3320, 5385), 27); - chestIds.put(new InstancePoint(3302, 5386), 28); - chestIds.put(new InstancePoint(3305, 5386), 29); - chestIds.put(new InstancePoint(3316, 5386), 30); - chestIds.put(new InstancePoint(3321, 5386), 31); - chestIds.put(new InstancePoint(3300, 5387), 32); - chestIds.put(new InstancePoint(3308, 5387), 33); - chestIds.put(new InstancePoint(3314, 5387), 34); - chestIds.put(new InstancePoint(3317, 5387), 35); - chestIds.put(new InstancePoint(3301, 5388), 36); - chestIds.put(new InstancePoint(3306, 5388), 37); - chestIds.put(new InstancePoint(3312, 5388), 38); - chestIds.put(new InstancePoint(3322, 5388), 39); - chestIds.put(new InstancePoint(3309, 5389), 40); - chestIds.put(new InstancePoint(3311, 5389), 41); - chestIds.put(new InstancePoint(3313, 5389), 42); - chestIds.put(new InstancePoint(3316, 5389), 43); - chestIds.put(new InstancePoint(3320, 5389), 44); - chestIds.put(new InstancePoint(3300, 5390), 45); - chestIds.put(new InstancePoint(3303, 5390), 46); - chestIds.put(new InstancePoint(3304, 5390), 47); - chestIds.put(new InstancePoint(3312, 5390), 48); - chestIds.put(new InstancePoint(3320, 5390), 49); - chestIds.put(new InstancePoint(3307, 5391), 50); - chestIds.put(new InstancePoint(3310, 5391), 51); - chestIds.put(new InstancePoint(3317, 5391), 52); - chestIds.put(new InstancePoint(3318, 5391), 53); - chestIds.put(new InstancePoint(3323, 5391), 54); - chestIds.put(new InstancePoint(3301, 5392), 55); - chestIds.put(new InstancePoint(3303, 5392), 56); - chestIds.put(new InstancePoint(3309, 5392), 57); - chestIds.put(new InstancePoint(3314, 5392), 58); - chestIds.put(new InstancePoint(3322, 5392), 59); - chestIds.put(new InstancePoint(3305, 5393), 60); - chestIds.put(new InstancePoint(3307, 5393), 61); - chestIds.put(new InstancePoint(3316, 5393), 62); - chestIds.put(new InstancePoint(3309, 5394), 63); - chestIds.put(new InstancePoint(3312, 5394), 64); - chestIds.put(new InstancePoint(3322, 5394), 65); - chestIds.put(new InstancePoint(3310, 5379), 66); - break; - } - - } - - public int indentifyChest(ThievingChest chest) - { - int id = chestIds.get(chest.getInstancePoint()); - chest.setChestId(id); - return id; - } - - private Map chestIds; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java deleted file mode 100644 index dc1c3c3dc2..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2018, Tim Lehner - * 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.raidsthieving.BatSolver; - -import lombok.Getter; -import java.util.HashSet; -import java.util.Arrays; -import java.util.Set; - -// Each Thieving room has 4 empty chests -// User-reported data shows these 4 come in groups, -// -// e.g. if there is an empty chest in L room chest 1, the other empty chests could be 16, 17, 38, 54, 55 -// See https://dikkenoob.github.io/ for more information - -public class SolutionSet -{ - public static final SolutionSet[] SOLUTION_SETS = - { - new SolutionSet(ThievingRoomType.LEFT_TURN, 1, 16, 17, 55), - new SolutionSet(ThievingRoomType.LEFT_TURN, 1, 17, 38, 54), - new SolutionSet(ThievingRoomType.LEFT_TURN, 2, 7, 21, 37), - new SolutionSet(ThievingRoomType.LEFT_TURN, 3, 5, 19, 30), - new SolutionSet(ThievingRoomType.LEFT_TURN, 3, 11, 15, 40), - new SolutionSet(ThievingRoomType.LEFT_TURN, 4, 22, 27, 46), - new SolutionSet(ThievingRoomType.LEFT_TURN, 5, 9, 19, 45), - new SolutionSet(ThievingRoomType.LEFT_TURN, 6, 24, 26, 41), - new SolutionSet(ThievingRoomType.LEFT_TURN, 6, 26, 32, 52), - new SolutionSet(ThievingRoomType.LEFT_TURN, 7, 13, 44, 59), - new SolutionSet(ThievingRoomType.LEFT_TURN, 8, 14, 41, 43), - new SolutionSet(ThievingRoomType.LEFT_TURN, 8, 10, 28, 33), - new SolutionSet(ThievingRoomType.LEFT_TURN, 8, 31, 47, 50), - new SolutionSet(ThievingRoomType.LEFT_TURN, 10, 35, 54, 63), - new SolutionSet(ThievingRoomType.LEFT_TURN, 10, 30, 32, 59), - new SolutionSet(ThievingRoomType.LEFT_TURN, 12, 40, 53, 56), - new SolutionSet(ThievingRoomType.LEFT_TURN, 12, 13, 42, 54), - new SolutionSet(ThievingRoomType.LEFT_TURN, 13, 22, 27, 46), - new SolutionSet(ThievingRoomType.LEFT_TURN, 14, 18, 23, 51), - new SolutionSet(ThievingRoomType.LEFT_TURN, 15, 43, 44, 58), - new SolutionSet(ThievingRoomType.LEFT_TURN, 15, 16, 42, 45), - new SolutionSet(ThievingRoomType.LEFT_TURN, 20, 29, 45, 51), - new SolutionSet(ThievingRoomType.LEFT_TURN, 20, 25, 32, 34), - new SolutionSet(ThievingRoomType.LEFT_TURN, 20, 28, 51, 62), - new SolutionSet(ThievingRoomType.LEFT_TURN, 21, 39, 41, 58), - new SolutionSet(ThievingRoomType.LEFT_TURN, 22, 25, 54, 64), - new SolutionSet(ThievingRoomType.LEFT_TURN, 23, 31, 47, 55), - new SolutionSet(ThievingRoomType.LEFT_TURN, 23, 33, 37, 60), - new SolutionSet(ThievingRoomType.LEFT_TURN, 24, 34, 55), - new SolutionSet(ThievingRoomType.LEFT_TURN, 26, 50, 63, 27), - new SolutionSet(ThievingRoomType.LEFT_TURN, 29, 39, 41, 61), - new SolutionSet(ThievingRoomType.LEFT_TURN, 33, 46, 52, 57), - new SolutionSet(ThievingRoomType.LEFT_TURN, 34, 45, 49, 60), - new SolutionSet(ThievingRoomType.LEFT_TURN, 36, 40, 42, 62), - new SolutionSet(ThievingRoomType.LEFT_TURN, 37, 38, 51, 64), - new SolutionSet(ThievingRoomType.LEFT_TURN, 48, 53, 55, 56), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 1, 6, 28, 41), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 1, 42, 55, 60), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 2, 10, 31, 44), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 2, 33, 51, 68), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 3, 31, 43, 46), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 3, 5, 21, 48), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 4, 20, 24, 33), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 4, 38, 47), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 5, 21, 48), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 5, 17, 35, 63), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 7, 17, 45, 47), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 7, 37, 41, 52), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 8, 13, 40, 42), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 8, 20, 24, 30), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 9, 15, 23, 35), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 11, 13, 21, 50), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 11, 18, 37, 39), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 12, 14, 27, 34), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 14, 45, 67, 71), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 16, 22, 29, 32), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 18, 28, 31, 64), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 19, 21, 63, 69), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 20, 51, 68, 72), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 22, 29, 56, 61), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 23, 53, 66, 74), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 26, 35, 53, 59), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 27, 30, 55, 57), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 31, 58, 60, 73), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 34, 57, 58, 70), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 38, 56, 61, 70), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 40, 54, 65, 72), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 42, 46, 65), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 47, 49, 66, 67), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 48, 62, 69), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 9, 19, 32, 41), - new SolutionSet(ThievingRoomType.RIGHT_TURN, 16, 26, 36, 39), - new SolutionSet(ThievingRoomType.STRAIGHT, 1, 39, 43, 51), - new SolutionSet(ThievingRoomType.STRAIGHT, 2, 15, 20, 53), - new SolutionSet(ThievingRoomType.STRAIGHT, 3, 10, 42, 44), - new SolutionSet(ThievingRoomType.STRAIGHT, 4, 14, 38, 52), - new SolutionSet(ThievingRoomType.STRAIGHT, 5, 6, 35, 41), - new SolutionSet(ThievingRoomType.STRAIGHT, 7, 16, 34, 49), - new SolutionSet(ThievingRoomType.STRAIGHT, 9, 12, 26, 27), - new SolutionSet(ThievingRoomType.STRAIGHT, 13, 25, 30, 31), - new SolutionSet(ThievingRoomType.STRAIGHT, 15, 20, 53), - new SolutionSet(ThievingRoomType.STRAIGHT, 17, 24, 34, 58), - new SolutionSet(ThievingRoomType.STRAIGHT, 18, 23, 35, 57), - new SolutionSet(ThievingRoomType.STRAIGHT, 19, 26, 47, 65), - new SolutionSet(ThievingRoomType.STRAIGHT, 21, 33, 36, 61), - new SolutionSet(ThievingRoomType.STRAIGHT, 21, 54, 66), - new SolutionSet(ThievingRoomType.STRAIGHT, 22, 25, 46, 55), - new SolutionSet(ThievingRoomType.STRAIGHT, 24, 34, 58), - new SolutionSet(ThievingRoomType.STRAIGHT, 28, 40, 52, 62), - new SolutionSet(ThievingRoomType.STRAIGHT, 29, 41, 42, 63), - new SolutionSet(ThievingRoomType.STRAIGHT, 30, 32, 37, 64), - new SolutionSet(ThievingRoomType.STRAIGHT, 39, 43, 51), - new SolutionSet(ThievingRoomType.STRAIGHT, 43, 45, 50, 60), - new SolutionSet(ThievingRoomType.STRAIGHT, 51, 53, 56, 59) - }; - - SolutionSet(ThievingRoomType type) - { - this.type = type; - emptyChests = new HashSet<>(); - } - - private SolutionSet(ThievingRoomType type, Integer... emptyChests) - { - this.type = type; - this.emptyChests = new HashSet<>(Arrays.asList(emptyChests)); - } - - public void addEmptyChest(int chestId) - { - emptyChests.add(chestId); - } - - public boolean containsChest(int chestId) - { - return emptyChests.contains(chestId); - } - - @Getter - private ThievingRoomType type; - - @Getter - private Set emptyChests; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java deleted file mode 100644 index f709b2d435..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2018, Tim Lehner - * 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.raidsthieving.BatSolver; - -// There are three distinct Thieving rooms, distinguished by the position of the entrance relative to the exit -// e.g. If you enter the room and must turn left to get to the exit and trough, this is a LEFT_TURN - -import net.runelite.client.plugins.raidsthieving.InstancePoint; - -public enum ThievingRoomType -{ - LEFT_TURN(3271, 5389), - RIGHT_TURN(3350, 5399), - STRAIGHT(3317, 5397); - - private final int x; - private final int y; - - ThievingRoomType(int x, int y) - { - this.x = x; - this.y = y; - } - - public static ThievingRoomType IdentifyByInstancePoint(InstancePoint point) - { - for (ThievingRoomType type : ThievingRoomType.values()) - { - if (Math.abs(type.x - point.getX()) <= 1 && - Math.abs(type.y - point.getY()) <= 1) - { - return type; - } - } - - return null; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java deleted file mode 100644 index 5e09486f89..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2018, Tim Lehner - * 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.raidsthieving; - -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.raidsthieving.BatSolver.BatSolver; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.ProgressPieComponent; -import javax.inject.Inject; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.util.Map; -import java.util.TreeSet; - -/** - * Represents the overlay that shows timers on traps that are placed by the - * player. - */ -public class ChestOverlay extends Overlay -{ - - private final Client client; - private final RaidsThievingPlugin plugin; - private final RaidsThievingConfig config; - - @Inject - ChestOverlay(Client client, RaidsThievingPlugin plugin, RaidsThievingConfig config) - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - this.plugin = plugin; - this.config = config; - this.client = client; - } - - @Override - public Dimension render(Graphics2D graphics) - { - drawChests(graphics); - return null; - } - - /** - * Updates the timer colors. - */ - public void updateConfig() - { - } - - /** - * Iterates over all the traps that were placed by the local player, and - * draws a circle or a timer on the trap, depending on the trap state. - * - * @param graphics - */ - private void drawChests(Graphics2D graphics) - { - - for (Map.Entry entry : plugin.getChests().entrySet()) - { - ThievingChest chest = entry.getValue(); - WorldPoint pos = entry.getKey(); - - - if (chest != null) - { - if (!plugin.isBatsFound() && !chest.isEverOpened()) - { - if (shouldDrawChest(pos)) - { - Color drawColor = new Color(config.getPotentialBatColor().getRed(), - config.getPotentialBatColor().getGreen(), - config.getPotentialBatColor().getBlue(), - getChestOpacity(pos)); - drawCircleOnTrap(graphics, chest, drawColor); - } - } - if (chest.isPoison()) - { - drawCircleOnTrap(graphics, chest, config.getPoisonTrapColor()); - } - } - } - } - - private boolean shouldDrawChest(WorldPoint chestPos) - { - if (plugin.numberOfEmptyChestsFound() == 0) - { - return true; - } - int chestId = plugin.getChestId(chestPos); - BatSolver solver = plugin.getSolver(); - if (solver != null && chestId != -1) - { - TreeSet matches = solver.matchSolutions(); - return matches.contains(chestId) || matches.size() == 0; - } - return true; - } - - /** - * Draws a timer on a given trap. - * - * @param graphics - * @param chest The chest on which the circle needs to be drawn - * @param fill The fill color of the timer - */ - private void drawCircleOnTrap(Graphics2D graphics, ThievingChest chest, Color fill) - { - if (chest.getLocalPoint().getPlane() != client.getPlane()) - { - return; - } - LocalPoint localLoc = LocalPoint.fromWorld(client, chest.getLocalPoint()); - if (localLoc == null) - { - return; - } - Point loc = Perspective.localToCanvas(client, localLoc, chest.getLocalPoint().getPlane()); - - ProgressPieComponent pie = new ProgressPieComponent(); - pie.setFill(fill); - pie.setBorderColor(Color.BLACK); - pie.setPosition(loc); - pie.setProgress(1); - if (graphics != null && loc != null) - { - pie.render(graphics); - } - } - - private int getChestOpacity(WorldPoint chestPos) - { - int chestId = plugin.getChestId(chestPos); - BatSolver solver = plugin.getSolver(); - if (solver != null && chestId != -1) - { - return (int) (255 * solver.relativeLikelihoodPoison(chestId)); - } - return 255; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java deleted file mode 100644 index 0df80aeb65..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java +++ /dev/null @@ -1,98 +0,0 @@ -package net.runelite.client.plugins.raidsthieving; - -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.Point; -import net.runelite.api.coords.WorldPoint; - -import java.util.Objects; - -/** - * Represents a point in the instance chunk, invariant of rotation. - */ -@Getter -public class InstancePoint -{ - private static final int CHUNK_SIZE = 8; - private static final double CHUNK_OFFSET = 3.5; - - public InstancePoint(int x, int y, int rot) - { - this.x = x; - this.y = y; - this.rot = rot; - } - - public InstancePoint(int x, int y) - { - this.x = x; - this.y = y; - this.rot = 0; - } - - public static InstancePoint buildFromPoint(WorldPoint worldPoint, Client client) - { - Point point = new Point(worldPoint.getX(), worldPoint.getY()); - Point base = new Point(client.getBaseX(), client.getBaseY()); - int plane = worldPoint.getPlane(); - - int deltaX = point.getX() - base.getX(); - int deltaY = point.getY() - base.getY(); - int chunkIndexX = deltaX / CHUNK_SIZE; - int chunkIndexY = deltaY / CHUNK_SIZE; - - int chunkData = client.getInstanceTemplateChunks()[plane][chunkIndexX][chunkIndexY]; - int rotation = chunkData >> 1 & 0x3; - int y = (chunkData >> 3 & 0x7FF) * 8; - int x = (chunkData >> 14 & 0x3FF) * 8; - - return buildFromTile(base, point, rotation, new Point(x, y)); - } - - public static InstancePoint buildFromTile(Point base, Point tile, int rot, Point chunkOrigin) - { - int deltaX = tile.getX() - base.getX(); - int deltaY = tile.getY() - base.getY(); - - double chunkOffsetX = (deltaX % CHUNK_SIZE) - CHUNK_OFFSET; - double chunkOffsetY = (deltaY % CHUNK_SIZE) - CHUNK_OFFSET; - - for (int i = 0; i < rot; i++) - { - double temp = chunkOffsetX; - chunkOffsetX = -chunkOffsetY; - chunkOffsetY = temp; - } - - chunkOffsetX += CHUNK_OFFSET; - chunkOffsetY += CHUNK_OFFSET; - - int invariantChunkOffsetX = (int) chunkOffsetX; - int invariantChunkOffsetY = (int) chunkOffsetY; - - return new InstancePoint( - chunkOrigin.getX() + invariantChunkOffsetX, - chunkOrigin.getY() + invariantChunkOffsetY, - rot); - } - - @Override - public boolean equals(Object o) - { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - InstancePoint that = (InstancePoint) o; - return x == that.x && - y == that.y; - } - - @Override - public int hashCode() - { - return Objects.hash(x, y); - } - - private int x; - private int y; - private int rot; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java deleted file mode 100644 index bb055edf4e..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2017, Tim Lehner - * 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.raidsthieving; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; -import java.awt.Color; - -@ConfigGroup("raidsthievingplugin") -public interface RaidsThievingConfig extends Config -{ - @ConfigItem( - position = 1, - keyName = "hexColorPotentialBat", - name = "Potential Bat", - description = "Color of marker for chests which could have bat" - ) - default Color getPotentialBatColor() - { - return Color.YELLOW; - } - - @ConfigItem( - position = 2, - keyName = "hexColorPoison", - name = "Poison trap", - description = "Color of chest with poison" - ) - default Color getPoisonTrapColor() - { - return Color.GREEN; - } - - @ConfigItem( - position = 5, - keyName = "batNotify", - name = "Notify when found", - description = "Send notification if you see bats being found." - ) - default boolean batFoundNotify() - { - return false; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java deleted file mode 100644 index 965934a01b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2017, Tim Lehner - * 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.raidsthieving; - -public class RaidsThievingConstants -{ - public static final int CLOSED_CHEST_ID = 29742; - public static final int OPEN_EMPTY_CHEST = 29743; - public static final int OPEN_FULL_CHEST_1 = 29744; - public static final int OPEN_FULL_CHEST_2 = 29745; - public static final int EMPTY_TROUGH = 29746; - public static final int[] STORAGE = {29769, 29770, 29771, 29772}; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java deleted file mode 100644 index d9f7de646c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2017, Tim Lehner - * 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.raidsthieving; - -import com.google.inject.Provides; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameObject; -import net.runelite.api.GraphicsObject; -import net.runelite.api.Varbits; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.GameObjectSpawned; -import net.runelite.api.events.GraphicsObjectCreated; -import net.runelite.api.events.VarbitChanged; -import net.runelite.client.Notifier; -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.raidsthieving.BatSolver.BatSolver; -import net.runelite.client.plugins.raidsthieving.BatSolver.ChestIdentifier; -import net.runelite.client.plugins.raidsthieving.BatSolver.ThievingRoomType; -import net.runelite.client.ui.overlay.OverlayManager; -import javax.inject.Inject; -import java.text.MessageFormat; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; - -@Slf4j -@PluginDescriptor( - name = "!Raids Bat Finder", - description = "Tracks which chests need to be searched for bats and which poison", - tags = {"overlay", "skilling", "raid"} -) -public class RaidsThievingPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private ChestOverlay overlay; - - @Inject - private Notifier notifier; - - @Inject - private RaidsThievingConfig config; - - @Getter - private final Map chests = new HashMap<>(); - - @Getter - private Instant lastActionTime = Instant.ofEpochMilli(0); - - private boolean inRaidChambers; - - @Getter - private boolean batsFound; - - @Getter - private BatSolver solver; - - @Getter - private ChestIdentifier mapper; - - - @Provides - RaidsThievingConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(RaidsThievingConfig.class); - } - - @Override - protected void startUp() - { - overlayManager.add(overlay); - overlay.updateConfig(); - reset(); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - lastActionTime = Instant.ofEpochMilli(0); - chests.clear(); - } - - - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) - { - GameObject obj = event.getGameObject(); - WorldPoint loc = obj.getWorldLocation(); - InstancePoint absLoc = InstancePoint.buildFromPoint(loc, client); - - if (obj.getId() == RaidsThievingConstants.EMPTY_TROUGH) - { - ThievingRoomType type = ThievingRoomType.IdentifyByInstancePoint(absLoc); - - if (type != null) - { - solver = new BatSolver(type); - mapper = new ChestIdentifier(type); - for (ThievingChest chest : chests.values()) - { - mapper.indentifyChest(chest); - } - } - else - { - log.error(MessageFormat.format("Unable to identify room type with: {0} {1} {2} {3} {4}.", - loc.getX(), loc.getY(), absLoc.getX(), absLoc.getY(), absLoc.getRot())); - log.error("Please report this @https://github.com/runelite/runelite/pull/4914!"); - } - } - if (obj.getId() == RaidsThievingConstants.CLOSED_CHEST_ID) - { - if (!chests.containsKey(loc)) - { - ThievingChest chest = new ThievingChest(obj, absLoc); - - if (mapper != null) - { - mapper.indentifyChest(chest); - } - - chests.put(loc, chest); - } - else - { - checkForBats(); - } - } - - if (obj.getId() == RaidsThievingConstants.OPEN_FULL_CHEST_1 || - obj.getId() == RaidsThievingConstants.OPEN_FULL_CHEST_2) - { - ThievingChest chest = chests.get(obj.getWorldLocation()); - // We found a chest that has grubs - log.info(MessageFormat.format("Found grubs at {0}, {1} chestId: {2}", loc.getX(), loc.getY(), chest.getChestId())); - if (solver != null && chest.getChestId() != -1) - { - chest.setEverOpened(true); - solver.addGrubsChest(chest.getChestId()); - } - checkForBats(); - } - - if (obj.getId() == RaidsThievingConstants.OPEN_EMPTY_CHEST) - { - ThievingChest chest = chests.get(obj.getWorldLocation()); - // We found a chest that could have poison - if (solver != null && chest.getChestId() != -1) - { - chest.setEmpty(true); - chest.setEverOpened(true); - solver.addEmptyChest(chest.getChestId()); - } - } - } - - - @Subscribe - public void onGraphicsObjectCreated(GraphicsObjectCreated event) - { - GraphicsObject obj = event.getGraphicsObject(); - if (obj.getId() == 184) - { - log.debug("Found poison splat"); - WorldPoint loc = WorldPoint.fromLocal(client, obj.getLocation()); - chests.get(loc).setPoison(true); - } - } - - @Subscribe - public void onVarbitChanged(VarbitChanged event) - { - boolean setting = client.getVar(Varbits.IN_RAID) == 1; - - if (inRaidChambers != setting) - { - inRaidChambers = setting; - reset(); - } - - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (event.getGroup().equals("raidsthievingplugin")) - { - overlay.updateConfig(); - } - } - - private void reset() - { - chests.clear(); - batsFound = false; - solver = null; - mapper = null; - } - - public int numberOfEmptyChestsFound() - { - int total = 0; - for (ThievingChest chest : chests.values()) - { - if (chest.isEmpty()) - { - total++; - } - } - return total; - } - - - private boolean checkForBats() - { - for (ThievingChest chest : chests.values()) - { - if (chest.isEmpty() && !chest.isPoison()) - { - batsFound = true; - if (config.batFoundNotify()) - { - notifier.notify("Bats have been found!"); - } - return true; - } - } - return false; - } - - public int getChestId(WorldPoint worldPoint) - { - return chests.get(worldPoint).getChestId(); - } -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java deleted file mode 100644 index 05a58d554e..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2019, Tim Lehner - * 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.raidsthieving; - -import lombok.Getter; -import lombok.Setter; -import net.runelite.api.GameObject; -import net.runelite.api.coords.WorldPoint; - -/** - * Wrapper class for a GameObject that represents a chest in the thieving room of Chambers of Xeric. - */ -@Getter -public class ThievingChest -{ - /** - * If the chest has never been opened, it could have bats. - */ - @Setter - private boolean everOpened; - - /** - * If the chest is empty, it could have bats. - */ - @Setter - private boolean empty; - - /** - * If the chest contains a poison trap instead. - */ - @Setter - private boolean poison; - - - @Setter - private int chestId; - - private final WorldPoint localPoint; - private final InstancePoint instancePoint; - - /** - * Constructor for a ThievingChest object - * - * @param gameObject The gameobject thats corresponds with this trap. - */ - ThievingChest(GameObject gameObject, InstancePoint instancePoint) - { - this.everOpened = false; - this.poison = false; - this.empty = false; - localPoint = gameObject.getWorldLocation(); - this.instancePoint = instancePoint; - this.chestId = -1; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java deleted file mode 100644 index 20775b1d35..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2018, Infinitay - * Copyright (c) 2018, Shaun Dreclin - * - * 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.rememberclan; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("rememberclan") -public interface RememberClanConfig extends Config -{ - @ConfigItem( - position = 1, - keyName = "clanname", - name = "Clan Name", - description = "Clanname to always remember" - ) - default String clanname() - { - return ""; - } - - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java deleted file mode 100644 index 35d209a4f7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2018, Infinitay - * Copyright (c) 2018, Shaun Dreclin - * 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.rememberclan; - -import com.google.inject.Provides; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.vars.AccountType; -import net.runelite.client.chat.ChatColorType; -import net.runelite.client.chat.ChatMessageBuilder; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; - -@PluginDescriptor( - name = "!Remember Clan", - description = "Remembers a specific clan!" -) -public class RememberClanPlugin extends Plugin -{ - - @Inject - private Client client; - - @Inject - private RememberClanConfig config; - - @Inject - private ChatMessageManager chatMessageManager; - - private boolean loggingIn; - - @Provides - RememberClanConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(RememberClanConfig.class); - } - - @Subscribe - public void onGameTick(GameTick event) - { - client.setVar(VarClientStr.RECENT_CLAN_CHAT,config.clanname()); - - } - - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryOverlay.java deleted file mode 100644 index 726702f8eb..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryOverlay.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2019, Yani - * 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.shayzieninfirmary; - -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; -import java.awt.image.BufferedImage; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.ItemID; -import net.runelite.api.NPC; -import net.runelite.api.Point; -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.OverlayUtil; - -public class ShayzienInfirmaryOverlay extends Overlay -{ - private final ShayzienInfirmaryPlugin plugin; - private final Client client; - - private BufferedImage medPackImage; - - @Inject - public ShayzienInfirmaryOverlay(ShayzienInfirmaryPlugin plugin, Client client, ItemManager itemManager) - { - setPosition(OverlayPosition.DYNAMIC); - this.plugin = plugin; - this.client = client; - - medPackImage = itemManager.getImage(ItemID.SHAYZIEN_MEDPACK); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!plugin.isAtInfirmary()) - { - return null; - } - - for (NPC npc : plugin.getUnhealedSoldiers()) - { - - Polygon tilePoly = npc.getCanvasTilePoly(); - - if (tilePoly == null) - { - continue; - } - - OverlayUtil.renderPolygon(graphics, npc.getCanvasTilePoly(), Color.ORANGE); - - Point imageLocation = npc.getCanvasImageLocation(medPackImage, 25); - - if (imageLocation == null) - { - continue; - } - - Composite originalComposite = graphics.getComposite(); - Composite translucentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f); - - graphics.setComposite(translucentComposite); - - OverlayUtil.renderImageLocation(graphics, imageLocation, medPackImage); - - graphics.setComposite(originalComposite); - } - - return null; - } -} 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 deleted file mode 100644 index f4ff6078f1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2019, Yani - * 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.shayzieninfirmary; - -import java.util.ArrayList; -import java.util.List; -import javax.inject.Inject; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.NPC; -import net.runelite.api.events.GameTick; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; - -@Slf4j -@PluginDescriptor( - name = "Shayzien Infirmary", - description = "Shows the status of wounded soldiers", - tags = {"shayzien", "infirmary", "soldiers"} -) -public class ShayzienInfirmaryPlugin extends Plugin -{ - @Getter(AccessLevel.PACKAGE) - private List unhealedSoldiers = new ArrayList(); - - @Inject - private OverlayManager overlayManager; - - @Inject - private Client client; - - @Inject - private ShayzienInfirmaryOverlay overlay; - - @Override - protected void startUp() throws Exception - { - loadPlugin(); - } - - @Override - protected void shutDown() throws Exception - { - unloadPlugin(); - } - - private void loadPlugin() - { - overlayManager.add(overlay); - } - - private void unloadPlugin() - { - overlayManager.remove(overlay); - } - - @Subscribe - public void onGameTick(GameTick event) - { - if(!isAtInfirmary()) - { - return; - } - - unhealedSoldiers.clear(); - - for (NPC npc : client.getNpcs()) - { - if (isUnhealedSoldierId(npc.getId())) - { - unhealedSoldiers.add(npc); - } - } - } - - public boolean isSoldierId(int npcId) - { - return (npcId >= 6826 && npcId <= 6857); - } - - public boolean isUnhealedSoldierId(int npcId) - { - return (isSoldierId(npcId) && npcId % 2 == 0); - } - - public boolean isHealedSoldierId(int npcId) - { - return (isSoldierId(npcId) && npcId % 2 == 1); - } - - public boolean isAtInfirmary() - { - return client.getLocalPlayer().getWorldLocation().getRegionID() == 6200; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerConfig.java deleted file mode 100644 index dfd21986ba..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerConfig.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018, Plinko60 - * 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.shiftwalker; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("shiftwalkhere") -public interface ShiftWalkerConfig extends Config -{ - - @ConfigItem( - keyName = "shiftWalkEverything", - name = "Walk Under Everything", - description = "Enable this option when you do not want to interact with anything while Shift is pressed. " + - "If Walk Here is an option it will be the action taken." - ) - default boolean shiftWalkEverything() - { - return true; - } - - @ConfigItem( - keyName = "shiftWalkBoxTraps", - name = "Walk Under Box Traps", - description = "Press \"Shift\" to be able to walk under instead of picking up a Box Trap." - ) - default boolean shiftWalkBoxTraps() - { - return true; - } - - @ConfigItem( - keyName = "shiftWalkAttackOption", - name = "Walk Under Attack Options", - description = "Press \"Shift\" to be able to walk instead of attacking. Make sure Left Click Attack is on." - ) - default boolean shiftWalkAttackOption() - { - return true; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerGroups.java b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerGroups.java deleted file mode 100644 index aff9c0efdb..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerGroups.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.runelite.client.plugins.shiftwalker; - -import java.util.HashSet; - -public final class ShiftWalkerGroups -{ - //Specific Targets to limit the walking to - private static final String BOX_TRAP = "BOX TRAP"; - private static final String BOX_TRAP_SHAKING = "SHAKING BOX"; - - //Specific menu options to replace - private static final String BOX_TRAP_DISMANTLE = "DISMANTLE"; - private static final String BOX_TRAP_CHECK = "CHECK"; - - private static final String ATTACK_OPTIONS_ATTACK = "ATTACK"; - - public static final HashSet BOX_TRAP_TARGETS = new HashSet<>(); - public static final HashSet BOX_TRAP_KEYWORDS = new HashSet<>(); - public static final HashSet ATTACK_OPTIONS_KEYWORDS = new HashSet<>(); - - static - { - BOX_TRAP_TARGETS.add(BOX_TRAP); - BOX_TRAP_TARGETS.add(BOX_TRAP_SHAKING); - - BOX_TRAP_KEYWORDS.add(BOX_TRAP_DISMANTLE); - BOX_TRAP_KEYWORDS.add(BOX_TRAP_CHECK); - - ATTACK_OPTIONS_KEYWORDS.add(ATTACK_OPTIONS_ATTACK); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerInputListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerInputListener.java deleted file mode 100644 index 677f30357d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerInputListener.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2018, Plinko60 - * 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.shiftwalker; - -import net.runelite.client.input.KeyListener; - -import javax.inject.Inject; -import java.awt.event.KeyEvent; - -public class ShiftWalkerInputListener implements KeyListener -{ - - @Inject - private ShiftWalkerPlugin plugin; - - @Override - public void keyTyped(KeyEvent event) - { - - } - - @Override - public void keyPressed(KeyEvent event) - { - if (event.getKeyCode() == KeyEvent.VK_SHIFT) - { - plugin.setHotKeyPressed(true); - } - } - - @Override - public void keyReleased(KeyEvent event) - { - if (event.getKeyCode() == KeyEvent.VK_SHIFT) - { - plugin.setHotKeyPressed(false); - } - } -} 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 deleted file mode 100644 index aef2adb45e..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2018, Plinko60 - * 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.shiftwalker; - -import com.google.inject.Provides; -import lombok.Setter; -import net.runelite.api.*; -import net.runelite.api.events.*; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.input.KeyManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.util.Text; - -import javax.inject.Inject; - -/** - * Shift Walker Plugin. Credit to MenuEntrySwapperPlugin for code some code structure used here. - */ -@PluginDescriptor( - name = "!Shift To Walk Here", - 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 -) -public class ShiftWalkerPlugin extends Plugin -{ - - private static final String WALK_HERE = "WALK HERE"; - private static final String CANCEL = "CANCEL"; - - @Inject - private Client client; - - @Inject - private ShiftWalkerConfig config; - - @Inject - private ShiftWalkerInputListener inputListener; - - @Inject - private ConfigManager configManager; - - @Inject - private KeyManager keyManager; - - @Setter - private boolean hotKeyPressed = false; - - @Provides - ShiftWalkerConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(ShiftWalkerConfig.class); - } - - @Override - public void startUp() - { - keyManager.registerKeyListener(inputListener); - } - - @Override - public void shutDown() - { - keyManager.unregisterKeyListener(inputListener); - } - - @Subscribe - public void onFocusChanged(FocusChanged event) - { - if (!event.isFocused()) - { - hotKeyPressed = false; - } - } - - /** - * Event when a new menu entry was added. - * @param event {@link MenuEntryAdded}. - */ - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) - { - if (client.getGameState() != GameState.LOGGED_IN || !hotKeyPressed) - { - return; - } - - final String pOptionToReplace = Text.removeTags(event.getOption()).toUpperCase(); - - //If the option is already to walk there, or cancel we don't need to swap it with anything - if (pOptionToReplace.equals(CANCEL) || pOptionToReplace.equals(WALK_HERE)) - { - return; - } - - String target = Text.removeTags(event.getTarget().toUpperCase()); - - if (config.shiftWalkEverything()) - { - //swap(pOptionToReplace); //Swap everything with walk here - stripEntries(); - } - else if (config.shiftWalkBoxTraps() && ShiftWalkerGroups.BOX_TRAP_TARGETS.contains(target) - && ShiftWalkerGroups.BOX_TRAP_KEYWORDS.contains(pOptionToReplace)) - { - //swap(pOptionToReplace); //Swap only on box traps - stripEntries(); - } - else if (config.shiftWalkAttackOption() && ShiftWalkerGroups.ATTACK_OPTIONS_KEYWORDS.contains(pOptionToReplace)) - { - //swap(pOptionToReplace); //Swap on everything that has an attack keyword as the first option - stripEntries(); - } - } - - /** - * Strip everything except "Walk here" - * Other way was unconventional because if there was multiple targets in the menu entry it wouldn't swap correctly - */ - private void stripEntries() { - MenuEntry walkkHereEntry = null; - - for (MenuEntry entry : client.getMenuEntries()) { - switch (entry.getOption()) { - case "Walk here": - walkkHereEntry = entry; - break; - } - } - if (walkkHereEntry != null) { - MenuEntry[] newEntries = new MenuEntry[1]; - newEntries[0] = walkkHereEntry; - client.setMenuEntries(newEntries); - } - } - - /** - * Swaps menu entries if the entries could be found. This places Walk Here where the top level menu option was. - * @param pOptionToReplace The String containing the Menu Option that needs to be replaced. IE: "Attack", "Chop Down". - */ - private void swap(String pOptionToReplace) - { - MenuEntry[] entries = client.getMenuEntries(); - - Integer walkHereEntry = searchIndex(entries, WALK_HERE); - Integer entryToReplace = searchIndex(entries, pOptionToReplace); - - if (walkHereEntry != null - && entryToReplace != null) - { - MenuEntry walkHereMenuEntry = entries[walkHereEntry]; - entries[walkHereEntry] = entries[entryToReplace]; - entries[entryToReplace] = walkHereMenuEntry; - - client.setMenuEntries(entries); - } - } - - /** - * Finds the index of the menu that contains the verbiage we are looking for. - * @param pMenuEntries The list of {@link MenuEntry}s. - * @param pMenuEntryToSearchFor The Option in the menu to search for. - * @return The index location or null if it was not found. - */ - private Integer searchIndex(MenuEntry[] pMenuEntries, String pMenuEntryToSearchFor) - { - Integer indexLocation = 0; - - for (MenuEntry menuEntry : pMenuEntries) - { - String entryOption = Text.removeTags(menuEntry.getOption()).toUpperCase(); - - if (entryOption.equals(pMenuEntryToSearchFor)) - { - return indexLocation; - } - - indexLocation++; - } - - return null; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java deleted file mode 100644 index 078491bb4d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java +++ /dev/null @@ -1,207 +0,0 @@ -package net.runelite.client.plugins.slayermusiq; - -import net.runelite.client.util.LinkBrowser; -import net.runelite.api.ChatMessageType; -import net.runelite.api.events.ChatMessage; -import net.runelite.client.chat.ChatColorType; -import net.runelite.client.chat.ChatMessageBuilder; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.chat.QueuedMessage; - -public class QuestGuideLinks { - private static final Link[] QUEST_GUIDE_LINKS = { - // Free Quests - new Link("Cook's Assistant", "https://www.youtube.com/watch?v=ehmtDRelj3c"), - new Link("Romeo & Juliet", "https://www.youtube.com/watch?v=rH_biWSNWVY"), - new Link("Demon Slayer", "https://www.youtube.com/watch?v=hgACrzJSiQk"), - new Link("Shield of Arrav", "https://www.youtube.com/watch?v=a_imLDKUdzg"), - new Link("Sheep Shearer", "https://www.youtube.com/watch?v=XFG3aNwK68s"), - new Link("The Restless Ghost", "https://www.youtube.com/watch?v=UkWNcsG_pXM"), - new Link("Ernest the Chicken", "https://www.youtube.com/watch?v=cq8NIVhSqh4"), - new Link("Vampire Slayer", "https://www.youtube.com/watch?v=FcEuxsDJWCU"), - new Link("Imp Catcher", "https://www.youtube.com/watch?v=LHgnl0FbOzk"), - new Link("Prince Ali Rescue", "https://www.youtube.com/watch?v=hrSPl1GfFaw"), - new Link("Doric's Quest", "https://www.youtube.com/watch?v=5TYyxHU27a4"), - new Link("Black Knights' Fortress", "https://www.youtube.com/watch?v=aekoZi3f9cU"), - new Link("Witch's Potion", "https://www.youtube.com/watch?v=XV4i5sPUvXo"), - new Link("The Knight's Sword", "https://www.youtube.com/watch?v=UkBWaI0rOqE"), - new Link("Goblin Diplomacy", "https://www.youtube.com/watch?v=P9BKOb_dLoY"), - new Link("Pirate's Treasure", "https://www.youtube.com/watch?v=zcD87PQW8Qk"), - new Link("Dragon Slayer", "https://www.youtube.com/watch?v=bMtCjlFOaBI"), - new Link("Rune Mysteries", "https://www.youtube.com/watch?v=l8ZhaN8uoS0"), - new Link("Misthalin Mystery", "https://www.youtube.com/watch?v=QlFqVAobAlQ"), - new Link("The Corsair Curse", "https://www.youtube.com/watch?v=wi7mUAHExz4"), - new Link("X Marks the Spot", "https://www.youtube.com/watch?v=GhRgvEG5jxQ"), - // Members Quests - new Link("Druidic Ritual", "https://www.youtube.com/watch?v=QIfU6HSmH4w"), - new Link("Lost City", "https://www.youtube.com/watch?v=T-kQNUSjFZI"), - new Link("Witch's House", "https://www.youtube.com/watch?v=TLsg7Wa-LUA"), - new Link("Merlin's Crystal", "https://www.youtube.com/watch?v=ESX-qriNtCE"), - new Link("Heroes' Quest", "https://www.youtube.com/watch?v=hK2N0WLKviE"), - new Link("Scorpion Catcher", "https://www.youtube.com/watch?v=xpqdec7_ZWg"), - new Link("Family Crest", "https://www.youtube.com/watch?v=0mk_Cgjr738"), - new Link("Monk's Friend", "https://www.youtube.com/watch?v=avi4y4G3Hcw"), - new Link("Temple of Ikov", "https://www.youtube.com/watch?v=5K7jDgr_4Z4"), - new Link("Clock Tower", "https://www.youtube.com/watch?v=GUCkkQFzyDw"), - new Link("Holy Grail", "https://www.youtube.com/watch?v=cgXoV1QlYco"), - new Link("Tree Gnome Village", "https://www.youtube.com/watch?v=T6Su__yuyRI"), - new Link("Fight Arena", "https://www.youtube.com/watch?v=4Nqjep2E5pw"), - new Link("Hazeel Cult", "https://www.youtube.com/watch?v=2_fhFJW6cNY"), - new Link("Sheep Herder", "https://www.youtube.com/watch?v=akC9FeYCG1Q"), - new Link("Plague City", "https://www.youtube.com/watch?v=Hf2wQQZL5CU"), - new Link("Waterfall Quest", "https://www.youtube.com/watch?v=xWBSnGkQTi4"), - new Link("Jungle Potion", "https://www.youtube.com/watch?v=xqLKsFz08As"), - new Link("The Grand Tree", "https://www.youtube.com/watch?v=N5e_Jus_E-Y"), - new Link("Underground Pass", "https://www.youtube.com/watch?v=5klGJg1wY8k"), - new Link("Observatory Quest", "https://www.youtube.com/watch?v=yxa9B6svv44"), - new Link("Watchtower", "https://www.youtube.com/watch?v=Vb10GoYP7FE"), - new Link("Dwarf Cannon", "https://www.youtube.com/watch?v=pROFg5jcCR0"), - new Link("Murder Mystery", "https://www.youtube.com/watch?v=P1IDGCA2f9o"), - new Link("The Dig Site", "https://www.youtube.com/watch?v=TOdcWV4MzuU"), - new Link("Gertrude's Cat", "https://www.youtube.com/watch?v=g7S09wA8EAY"), - new Link("Legends' Quest", "https://www.youtube.com/watch?v=Lid8enDEF_U"), - new Link("Death Plateau", "https://www.youtube.com/watch?v=SIQFmTvnb6w"), - new Link("Big Chompy Bird Hunting", "https://www.youtube.com/watch?v=s2fytMOHJXI"), - new Link("Elemental Workshop I", "https://www.youtube.com/watch?v=tbZD2RDqvfQ"), - new Link("Nature Spirit", "https://www.youtube.com/watch?v=Enf8vUWb5o0"), - new Link("Priest in Peril", "https://www.youtube.com/watch?v=fyYri6wUQIU"), - new Link("Regicide", "https://www.youtube.com/watch?v=KkWM-ok3C4Y"), - new Link("Tai Bwo Wannai Trio", "https://www.youtube.com/watch?v=Mdair5mvZL0"), - new Link("Troll Stronghold", "https://www.youtube.com/watch?v=zqmUs-f3AKA"), - new Link("Horror from the Deep", "https://www.youtube.com/watch?v=9htK8kb6DR8"), - new Link("Throne of Miscellania", "https://www.youtube.com/watch?v=fzGMnv2skBE"), - new Link("Monkey Madness I", "https://www.youtube.com/watch?v=VnoRfeBnPFA"), - new Link("Haunted Mine", "https://www.youtube.com/watch?v=cIc6loJHm9Q"), - new Link("Troll Romance", "https://www.youtube.com/watch?v=j2zifZVu7Gc"), - new Link("In Search of the Myreque", "https://www.youtube.com/watch?v=5nmYFHdAXAQ"), - new Link("Creature of Fenkenstrain", "https://www.youtube.com/watch?v=swqUVIs7B7M"), - new Link("Roving Elves", "https://www.youtube.com/watch?v=J3qf9DnT9cA"), - new Link("One Small Favour", "https://www.youtube.com/watch?v=ix_0-W3e9ps"), - new Link("Mountain Daughter", "https://www.youtube.com/watch?v=HETx_LX7aiY"), - new Link("Between a Rock...", "https://www.youtube.com/watch?v=cB11I45EGgA"), - new Link("The Golem", "https://www.youtube.com/watch?v=qpEHpiO6lLw"), - new Link("Desert Treasure", "https://www.youtube.com/watch?v=BuIqulIsICo"), - new Link("Icthlarin's Little Helper", "https://www.youtube.com/watch?v=wpNKm8_vUOM"), - new Link("Tears of Guthix", "https://www.youtube.com/watch?v=EMonDNI0uPk"), - new Link("The Lost Tribe", "https://www.youtube.com/watch?v=spZErjRnCdc"), - new Link("The Giant Dwarf", "https://www.youtube.com/watch?v=Z7PsGpOYgxY"), - new Link("Recruitment Drive", "https://www.youtube.com/watch?v=sOuzMpA_xtw"), - new Link("Mourning's Ends Part I", "https://www.youtube.com/watch?v=vuzAdk-h3c0"), - new Link("Garden of Tranquillity", "https://www.youtube.com/watch?v=7hbCzYnLCsQ"), - new Link("A Tail of Two Cats", "https://www.youtube.com/watch?v=SgN9Yw_YqHk"), - new Link("Wanted!", "https://www.youtube.com/watch?v=ZHZAKDCfXGs"), - new Link("Mourning's Ends Part II", "https://www.youtube.com/watch?v=FK5sLogGbU8"), - new Link("Rum Deal", "https://www.youtube.com/watch?v=I14CIu5x2S8"), - new Link("Shadow of the Storm", "https://www.youtube.com/watch?v=5ZvWd3XCQjI"), - new Link("Ratcatchers", "https://www.youtube.com/watch?v=s7G22fEuhTc"), - new Link("Spirits of the Elid", "https://www.youtube.com/watch?v=A1zAX55hZC0"), - new Link("Devious Minds", "https://www.youtube.com/watch?v=_UtlFmrWt1w"), - new Link("Enakhra's Lament", "https://www.youtube.com/watch?v=Y3kEIPYVaVE"), - new Link("Cabin Fever", "https://www.youtube.com/watch?v=k5DtxNXhOaw"), - new Link("Fairytale I - Growing Pains", "https://www.youtube.com/watch?v=cfGI9qFOmsg"), - new Link("Recipe for Disaster", "https://www.youtube.com/watch?v=hrAyyInJaTA"), - new Link("In Aid of the Myreque", "https://www.youtube.com/watch?v=O2Ru2NmuTaA"), - new Link("A Soul's Bane", "https://www.youtube.com/watch?v=dp8dp79qp6I"), - new Link("Rag and Bone Man", "https://www.youtube.com/watch?v=3owXSeN56W8"), - new Link("Swan Song", "https://www.youtube.com/watch?v=IpmERThXv2g"), - new Link("Royal Trouble", "https://www.youtube.com/watch?v=bVWUlKzNXEg"), - new Link("Death to the Dorgeshuun", "https://www.youtube.com/watch?v=2XJHuLhig98"), - new Link("Fairytale II - Cure a Queen", "https://www.youtube.com/watch?v=P6KkRk4_e3U"), - new Link("Lunar Diplomacy", "https://www.youtube.com/watch?v=vmeSKb7IBgQ"), - new Link("The Eyes of Glouphrie", "https://www.youtube.com/watch?v=0YCPwmZcxKA"), - new Link("Darkness of Hallowvale", "https://www.youtube.com/watch?v=QziKl99qdtU"), - new Link("Elemental Workshop II", "https://www.youtube.com/watch?v=Bb4E7ecIgv0"), - new Link("My Arm's Big Adventure", "https://www.youtube.com/watch?v=xa1KWOewgYA"), - new Link("Enlightened Journey", "https://www.youtube.com/watch?v=XAPthC8d7k0"), - new Link("Eagles' Peak", "https://www.youtube.com/watch?v=KDxIrrwXp7U"), - new Link("Animal Magnetism", "https://www.youtube.com/watch?v=kUyjXA7TaFU"), - new Link("Contact!", "https://www.youtube.com/watch?v=czn-yWABBWs"), - new Link("Cold War", "https://www.youtube.com/watch?v=0m1KpP-qKWI"), - new Link("The Fremennik Isles", "https://www.youtube.com/watch?v=EvxhiOWmraY"), - new Link("The Great Brain Robbery", "https://www.youtube.com/watch?v=ImHFASuNUN8"), - new Link("What Lies Below", "https://www.youtube.com/watch?v=f_9nVMGTtuo"), - new Link("Olaf's Quest", "https://www.youtube.com/watch?v=mXV5bM1NFMM"), - new Link("Dream Mentor", "https://www.youtube.com/watch?v=XDLUu0Kf0sE"), - new Link("Grim Tales", "https://www.youtube.com/watch?v=dFB0Q6v8Apw"), - new Link("King's Ransom", "https://www.youtube.com/watch?v=UJz9ZfF3uCY"), - new Link("Shilo Village", "https://www.youtube.com/watch?v=bDvBi8FT-QI"), - new Link("Biohazard", "https://www.youtube.com/watch?v=n9k87LwOGMk"), - new Link("Tower of Life", "https://www.youtube.com/watch?v=KReMcWpeY3k"), - new Link("Rag and Bone Man II", "https://www.youtube.com/watch?v=KGdHiDDUX_U"), - new Link("Zogre Flesh Eaters", "https://www.youtube.com/watch?v=vzm4949kXP4"), - new Link("Monkey Madness II", "https://www.youtube.com/watch?v=ykE5LbjABaI"), - new Link("Client of Kourend", "https://www.youtube.com/watch?v=Y-KIHF-cL9w"), - new Link("The Queen of Thieves", "https://www.youtube.com/watch?v=W94zFZVrHkQ"), - new Link("Bone Voyage", "https://www.youtube.com/watch?v=-VTR4p8kPmI"), - new Link("Dragon Slayer II", "https://www.youtube.com/watch?v=4BMb3Zwzk_U"), - new Link("The Depths of Despair", "https://www.youtube.com/watch?v=CaVUk2eAsKs"), - new Link("A Taste of Hope", "https://www.youtube.com/watch?v=VjdgEIizdSc"), - new Link("Tale of the Righteous", "https://www.youtube.com/watch?v=99yiv0tPl58"), - new Link("Making Friends with My Arm", "https://www.youtube.com/watch?v=DltzzhIsM_Q"), - new Link("The Ascent of Arceuus", "https://www.youtube.com/watch?v=4VQnfrv6S18"), - new Link("The Forsaken Tower", "https://www.youtube.com/watch?v=con0sXl5NBY"), - new Link("Fishing Contest", "https://www.youtube.com/watch?v=XYSv37A_l5w"), - new Link("Tribal Totem", "https://www.youtube.com/watch?v=XkUEIjr886M"), - new Link("Sea Slug", "https://www.youtube.com/watch?v=oOZVfa5SkVQ"), - new Link("The Tourist Trap", "https://www.youtube.com/watch?v=0bmSCCepMvo"), - new Link("Eadgar's Ruse", "https://www.youtube.com/watch?v=aVQ3DjTElXg"), - new Link("Shades of Mort'ton", "https://www.youtube.com/watch?v=eF05R8OMxgg"), - new Link("The Fremennik Trials", "https://www.youtube.com/watch?v=YUIvEgcvl5c"), - new Link("Ghosts Ahoy", "https://www.youtube.com/watch?v=aNBkLOywDfM"), - new Link("The Feud", "https://www.youtube.com/watch?v=nlBSc9IUklA"), - new Link("Forgettable Tale...", "https://www.youtube.com/watch?v=3HvFd6AxNU0"), - new Link("Making History", "https://www.youtube.com/watch?v=bOTGi2zAuhs"), - new Link("The Hand in the Sand", "https://www.youtube.com/watch?v=gdNLcZ-l1Lw"), - new Link("The Slug Menace", "https://www.youtube.com/watch?v=BRQbdr3JEZ8"), - new Link("Another Slice of H.A.M.", "https://www.youtube.com/watch?v=Yq3db7827Lk") - }; - - private static class Link { - - private String questName; - private String url; - - public Link(String questName, String url) { - this.questName = questName; - this.url = url; - } - - public String getQuestName() { - return questName; - } - - public void openURL() { - LinkBrowser.browse(this.url); - } - - } - - private static boolean openGuide(String questName) { - for (Link link : QUEST_GUIDE_LINKS) { - if (link.getQuestName().equals(questName)) { - link.openURL(); - return true; - } - } - return false; - } - - private static void logQuestNotFoundError(String questName, ChatMessageManager chatMessageManager) { - String chatMessage = new ChatMessageBuilder() - .append(ChatColorType.HIGHLIGHT) - .append("Could not find Slayermusiq1 guide for " + questName) - .build(); - - chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.CONSOLE) - .runeLiteFormattedMessage(chatMessage) - .build()); - } - - public static void tryOpenGuide(String questName, ChatMessageManager chatMessageManager) { - boolean success = openGuide(questName); - if (!success) { - logQuestNotFoundError(questName, chatMessageManager); - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java deleted file mode 100644 index 7e07a0564d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2018, Jeremy Berchtold - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// Based off RuneLite's Wiki Plugin -/* - * Copyright (c) 2018 Abex - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.slayermusiq; - -import com.google.inject.Provides; -import com.google.common.primitives.Ints; -import java.awt.Dimension; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.inject.Inject; -import javax.swing.SwingUtilities; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.client.util.Text; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; - -@PluginDescriptor( - name = "!Slayermusiq1 Guides", - description = "Adds a right-click option to go to Slayermusiq1's guides from the quest tab", - tags = {"quest", "guide", "slayermusiq"} -) -@Slf4j -public class SlayermusiqPlugin extends Plugin -{ - - private static final int[] QUESTLIST_WIDGET_IDS = new int[] - { - WidgetInfo.QUESTLIST_FREE_CONTAINER.getId(), - WidgetInfo.QUESTLIST_MEMBERS_CONTAINER.getId(), - WidgetInfo.QUESTLIST_MINIQUEST_CONTAINER.getId(), - }; - - private static final String MENUOP_SLAYERMUSIQ = "Slayermusiq"; - - @Inject - private Client client; - - @Inject - private ChatMessageManager chatMessageManager; - - @Override - protected void startUp() throws Exception - { - // - } - - @Override - protected void shutDown() throws Exception - { - // - } - - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) - { - int widgetID = event.getActionParam1(); - if (Ints.contains(QUESTLIST_WIDGET_IDS, widgetID) && "Read Journal:".equals(event.getOption())) { - MenuEntry[] menuEntries = client.getMenuEntries(); - - MenuEntry newMenuEntry = createSlayermusiqOptionMenuEntry(event); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - menuEntries[menuEntries.length - 1] = newMenuEntry; - - client.setMenuEntries(menuEntries); - } - } - - @Subscribe - private void onMenuOptionClicked(MenuOptionClicked ev) { - if (ev.getMenuAction() == MenuAction.RUNELITE && ev.getMenuOption().equals(MENUOP_SLAYERMUSIQ)) { - ev.consume(); - String quest = Text.removeTags(ev.getMenuTarget()); - QuestGuideLinks.tryOpenGuide(quest, chatMessageManager); - } - } - - private MenuEntry createSlayermusiqOptionMenuEntry(MenuEntryAdded event) { - int widgetIndex = event.getActionParam0(); - int widgetID = event.getActionParam1(); - - MenuEntry menuEntry = new MenuEntry(); - menuEntry.setTarget(event.getTarget()); - menuEntry.setOption(MENUOP_SLAYERMUSIQ); - menuEntry.setParam0(widgetIndex); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - return menuEntry; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java deleted file mode 100644 index bb16cd3709..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.runelite.client.plugins.spellbookfixer; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("spellbookfixer") -public interface SpellbookFixerConfig extends Config -{ - @ConfigItem(position = 0, keyName = "shouldHideOthers", name = "Hide Others", description = "Toggle on to hide spells not useful for pking that cannot be filtered otherwise.") - default boolean shouldHideOthers() - { - return false; - } - - //ice blitz - @ConfigItem(position = 1, keyName = "shouldModifyIceBlitz", name = "Ice Blitz", description = "Toggle on to enable Ice Blitz modifications.") - default boolean shouldModifyIceBlitz() { return false; } - @ConfigItem(position = 2, keyName = "getBlitzPositionX", name = "Ice Blitz Pos X", description = "Modifies the X-axis position of Ice Blitz.") - default int getBlitzPositionX() - { - return 0; - } - @ConfigItem(position = 3, keyName = "getBlitzPositionY", name = "Ice Blitz Pos Y", description = "Modifies the Y-axis position of Ice Blitz.") - default int getBlitzPositionY() - { - return 118; - } - @ConfigItem(position = 4, keyName = "getBlitzSize", name = "Ice Blitz Size", description = "Modifies the width of Ice Blitz.") - default int getBlitzSize() - { - return 80; - } - - //ice barrage - @ConfigItem(position = 5, keyName = "shouldModifyIceBarrage", name = "Ice Barrage", description = "Toggle on to enable Ice Barrage modifications.") - default boolean shouldModifyIceBarrage() { return false; } - @ConfigItem(position = 6, keyName = "getBarragePositionX", name = "Ice Barrage Pos X", description = "Modifies the X-axis position of Ice Barrage.") - default int getBarragePositionX() - { - return 0; - } - @ConfigItem(position = 7, keyName = "getBarragePositionY", name = "Ice Barrage Pos X", description = "Modifies the X-axis position of Ice Barrage.") - default int getBarragePositionY() - { - return 0; - } - @ConfigItem(position = 8, keyName = "getBarrageSize", name = "Ice Barrage Size", description = "Modifies the width position of Ice Barrage.") - default int getBarrageSize() - { - return 80; - } - - //vengeance - @ConfigItem(position = 9, keyName = "shouldModifyVengeance", name = "Vengeance", description = "Toggle on to enable Vengeance modifications.") - default boolean shouldModifyVengeance() { return false; } - @ConfigItem(position = 10, keyName = "getVengeancePositionX", name = "Vengeance Pos X", description = "Modifies the X-axis position of Vengeance.") - default int getVengeancePositionX() - { - return 0; - } - @ConfigItem(position = 11, keyName = "getVengeancePositionY", name = "Vengeance Pos X", description = "Modifies the X-axis position of Vengeance.") - default int getVengeancePositionY() - { - return 0; - } - @ConfigItem(position = 12, keyName = "getVengeanceSize", name = "Vengeance Size", description = "Modifies the width position of Vengeance.") - default int getVengeanceSize() - { - return 80; - } - - //teleblock - @ConfigItem(position = 13, keyName = "shouldModifyTeleBlock", name = "TeleBlock", description = "Toggle on to enable TeleBlock modifications.") - default boolean shouldModifyTeleBlock() { return false; } - @ConfigItem(position = 14, keyName = "getTeleBlockPositionX", name = "TeleBlock Pos X", description = "Modifies the X-axis position of TeleBlock.") - default int getTeleBlockPositionX() - { - return 0; - } - @ConfigItem(position = 15, keyName = "getTeleBlockPositionY", name = "TeleBlock Pos X", description = "Modifies the X-axis position of TeleBlock.") - default int getTeleBlockPositionY() - { - return 0; - } - @ConfigItem(position = 16, keyName = "getTeleBlockSize", name = "TeleBlock Size", description = "Modifies the width position of TeleBlock.") - default int getTeleBlockSize() - { - return 80; - } - - //entangle - @ConfigItem(position = 17, keyName = "shouldModifyEntangle", name = "Entangle", description = "Toggle on to enable Entangle modifications.") - default boolean shouldModifyEntangle() { return false; } - @ConfigItem(position = 18, keyName = "getEntanglePositionX", name = "Entangle Pos X", description = "Modifies the X-axis position of Entangle.") - default int getEntanglePositionX() - { - return 0; - } - @ConfigItem(position = 19, keyName = "getEntanglePositionY", name = "Entangle Pos X", description = "Modifies the X-axis position of Entangle.") - default int getEntanglePositionY() - { - return 118; - } - @ConfigItem(position = 20, keyName = "getEntangleSize", name = "Entangle Size", description = "Modifies the width position of Entangle.") - default int getEntangleSize() - { - return 80; - } -} 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 deleted file mode 100644 index 7d71cef371..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java +++ /dev/null @@ -1,170 +0,0 @@ -package net.runelite.client.plugins.spellbookfixer; - -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.WidgetLoaded; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetID; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; - -import javax.inject.Inject; - - -@PluginDescriptor( - name = "Spellbook Fixer", - description = "Resize and filter spellbook for PKing", - tags = {"resize", "spellbook", "magic", "spell", "pk", "book", "filter", "bogla"} -) -@Slf4j -public class SpellbookFixerPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - SpellbookFixerConfig config; - - @Provides - SpellbookFixerConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(SpellbookFixerConfig.class); } - - @Override - protected void startUp() throws Exception - { - adjustSpellbook(); - } - - @Override - protected void shutDown() throws Exception - { - resetSpellbook(); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - adjustSpellbook(); - } - - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) - { - if (event.getGroupId() == WidgetID.SPELLBOOK_GROUP_ID) - adjustSpellbook(); - } - - @Subscribe - public void onGameTick(GameTick event) - { - adjustSpellbook(); - } - - private void adjustSpellbook() - { - if (client.getGameState() != GameState.LOGGED_IN) - return; - - try - { - if (config.shouldModifyIceBarrage()) - modifySpell(WidgetInfo.SPELL_ICE_BARRAGE, config.getBarragePositionX(), config.getBarragePositionY(), config.getBarrageSize()); - - if (config.shouldModifyIceBlitz()) - modifySpell(WidgetInfo.SPELL_ICE_BLITZ, config.getBlitzPositionX(), config.getBlitzPositionY(), config.getBlitzSize()); - - if (config.shouldModifyVengeance()) - modifySpell(WidgetInfo.SPELL_VENGEANCE, config.getVengeancePositionX(), config.getVengeancePositionY(), config.getVengeanceSize()); - - if (config.shouldModifyTeleBlock()) - modifySpell(WidgetInfo.SPELL_TELE_BLOCK, config.getTeleBlockPositionX(), config.getTeleBlockPositionY(), config.getTeleBlockSize()); - - if (config.shouldModifyEntangle()) - modifySpell(WidgetInfo.SPELL_ENTANGLE, config.getEntanglePositionX(), config.getEntanglePositionY(), config.getEntangleSize()); - - setSpellHidden(WidgetInfo.SPELL_BLOOD_BLITZ, config.shouldHideOthers()); - setSpellHidden(WidgetInfo.SPELL_VENGEANCE_OTHER, config.shouldHideOthers()); - setSpellHidden(WidgetInfo.SPELL_BIND, config.shouldHideOthers()); - setSpellHidden(WidgetInfo.SPELL_SNARE, config.shouldHideOthers()); - } - catch (Exception e) - { - //swallow - } - - - } - - private void resetSpellbook() - { - if (client.getGameState() != GameState.LOGGED_IN) - return; - - try - { - if (config.shouldModifyIceBarrage()) - modifySpell(WidgetInfo.SPELL_ICE_BARRAGE, config.getBarragePositionX(), config.getBarragePositionY(), 24); - - if (config.shouldModifyIceBlitz()) - modifySpell(WidgetInfo.SPELL_ICE_BLITZ, config.getBlitzPositionX(), config.getBlitzPositionY(), 24); - - if (config.shouldModifyVengeance()) - modifySpell(WidgetInfo.SPELL_VENGEANCE, config.getVengeancePositionX(), config.getVengeancePositionY(), 24); - - if (config.shouldModifyTeleBlock()) - modifySpell(WidgetInfo.SPELL_TELE_BLOCK, config.getTeleBlockPositionX(), config.getTeleBlockPositionY(), 24); - - if (config.shouldModifyEntangle()) - modifySpell(WidgetInfo.SPELL_ENTANGLE, config.getEntanglePositionX(), config.getEntanglePositionY(), 24); - - setSpellHidden(WidgetInfo.SPELL_BLOOD_BLITZ, false); - setSpellHidden(WidgetInfo.SPELL_VENGEANCE_OTHER, false); - setSpellHidden(WidgetInfo.SPELL_BIND, false); - setSpellHidden(WidgetInfo.SPELL_SNARE, false); - } - catch (Exception e) - { - //swallow - } - } - - private void modifySpell(WidgetInfo widgetInfo, int posX, int posY, int size) - { - Widget widget = client.getWidget(widgetInfo); - - if (widget == null) - return; - - try - { - widget.setOriginalX(posX); - widget.setOriginalY(posY); - widget.setOriginalWidth(size); - widget.setOriginalHeight(size); - widget.revalidate(); - } - catch (Exception e) - { - //swallow - } - - } - - private void setSpellHidden(WidgetInfo widgetInfo, boolean hidden) - { - Widget widget = client.getWidget(widgetInfo); - - if (widget == null) - return; - - widget.setHidden(hidden); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ActionType.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ActionType.java deleted file mode 100644 index b801e8b2a8..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ActionType.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018, Davis Cook - * Copyright (c) 2018, Daddy Dozer - * 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.suppliestracker; - -/** - * Type of action performed in a menu - */ -public enum ActionType -{ - - CONSUMABLE, TELEPORT, CAST; - -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/BlowpipeDartType.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/BlowpipeDartType.java deleted file mode 100644 index 09182d6cde..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/BlowpipeDartType.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018, Davis Cook - * 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.suppliestracker; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import static net.runelite.api.ItemID.*; - -/** - * Type of darts that can be put into the blowpipe - */ -@AllArgsConstructor -public enum BlowpipeDartType -{ - BRONZE(BRONZE_DART), IRON(IRON_DART), - STEEL(STEEL_DART), MITHRIL(MITHRIL_DART), - ADAMANT(ADAMANT_DART), RUNE(RUNE_DART), - DRAGON(DRAGON_DART); - - @Getter - private int dartID; - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ItemType.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ItemType.java deleted file mode 100644 index 8479937589..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ItemType.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2018, Davis Cook - * Copyright (c) 2018, Daddy Dozer - * 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.suppliestracker; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * The potential types that supplies can be along with a categorization function - * that assigns the supplies to these categories - */ -@AllArgsConstructor -public enum ItemType -{ - FOOD("Food"), - POTION("Potions"), - RUNE("Runes"), - AMMO("Ammo"), - TELEPORT("Teleports"); - - @Getter - private String label; - - /** - * Takes an item and determines what ItemType it should categorize into - * @param item the item to determine category for - * @return our best guess for what category this item goes into - * note that if the guess is wrong (per say) it won't break anything because it will be - * consistently wrong but it could have an item that is clearly not food in the food section - */ - public static ItemType categorize(SuppliesTrackerItem item) - { - if (item.getName().contains("(4)")) - { - return ItemType.POTION; - } - if (item.getName().toLowerCase().contains("bolt") || item.getName().toLowerCase().contains("dart") - || item.getName().toLowerCase().contains("arrow") || item.getName().toLowerCase().contains("javelin") - || item.getName().toLowerCase().contains("knive") || item.getName().toLowerCase().contains("throwing") - || item.getName().toLowerCase().contains("zulrah's scale") || item.getName().toLowerCase().contains("cannonball")) - { - return ItemType.AMMO; - } - if (item.getName().contains("rune")) - { - return ItemType.RUNE; - } - if (item.getName().toLowerCase().contains("teleport")) - { - return ItemType.TELEPORT; - } - return ItemType.FOOD; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/MenuAction.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/MenuAction.java deleted file mode 100644 index 42a942e74b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/MenuAction.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2018, Davis Cook - * 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.suppliestracker; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import net.runelite.api.Item; - -/** - * Data class that tracks all info related to a menu click action - */ -@AllArgsConstructor -public class MenuAction -{ - - @Getter - private ActionType type; - @Getter - private Item[] oldInventory; - - public static class ItemAction extends MenuAction - { - - @Getter - private int itemID; - @Getter - private int slot; - - public ItemAction(ActionType type, Item[] oldInventory, int itemID, int slot) - { - super(type, oldInventory); - this.itemID = itemID; - this.slot = slot; - } - - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesBox.java deleted file mode 100644 index 76dc060a9f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesBox.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2018, Davis Cook - * Copyright (c) 2018, Daddy Dozer - * 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.suppliestracker; - -import lombok.AccessLevel; -import lombok.Getter; -import net.runelite.client.game.AsyncBufferedImage; -import net.runelite.client.game.ItemManager; -import net.runelite.client.ui.ColorScheme; -import net.runelite.client.ui.FontManager; -import net.runelite.client.util.StackFormatter; -import net.runelite.client.util.Text; -import net.runelite.http.api.item.ItemPrice; - -import javax.swing.*; -import javax.swing.border.EmptyBorder; -import java.awt.*; -import java.util.ArrayList; -import java.util.List; - -import static net.runelite.api.ItemID.*; -import static net.runelite.api.ItemID.HALF_A_MEAT_PIE; - -public class SuppliesBox extends JPanel -{ - private static final int ITEMS_PER_ROW = 5; - - private final JPanel itemContainer = new JPanel(); - private final JLabel priceLabel = new JLabel(); - private final JLabel subTitleLabel = new JLabel(); - private final ItemManager itemManager; - @Getter(AccessLevel.PACKAGE) - private final String id; - private final SuppliesTrackerPlugin plugin; - private final SuppliesTrackerPanel panel; - - @Getter - private final List trackedItems = new ArrayList<>(); - - private long totalPrice; - - @Getter - private final ItemType type; - - SuppliesBox(final ItemManager itemManager, final String id, - final SuppliesTrackerPlugin plugin, final SuppliesTrackerPanel panel, - final ItemType type) - { - this.id = id; - this.itemManager = itemManager; - this.plugin = plugin; - this.panel = panel; - this.type = type; - - setLayout(new BorderLayout(0, 1)); - setBorder(new EmptyBorder(5, 0, 0, 0)); - - final JPanel logTitle = new JPanel(new BorderLayout(5, 0)); - logTitle.setBorder(new EmptyBorder(7, 7, 7, 7)); - logTitle.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - - final JLabel titleLabel = new JLabel(Text.removeTags(id)); - titleLabel.setFont(FontManager.getRunescapeSmallFont()); - titleLabel.setForeground(Color.WHITE); - - logTitle.add(titleLabel, BorderLayout.WEST); - - subTitleLabel.setFont(FontManager.getRunescapeSmallFont()); - subTitleLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); - logTitle.add(subTitleLabel, BorderLayout.CENTER); - - priceLabel.setFont(FontManager.getRunescapeSmallFont()); - priceLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); - logTitle.add(priceLabel, BorderLayout.EAST); - - add(logTitle, BorderLayout.NORTH); - add(itemContainer, BorderLayout.CENTER); - - // Create popup menu - final JPopupMenu popupMenu = new JPopupMenu(); - popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5)); - setComponentPopupMenu(popupMenu); - - // Create reset menu - final JMenuItem reset = new JMenuItem("Reset Category"); - reset.addActionListener(e -> - { - for (SuppliesTrackerItem item : trackedItems) - { - plugin.clearItem(item.getId()); - } - clearAll(); - rebuild(); - panel.updateOverall(); - }); - - popupMenu.add(reset); - - setVisible(false); - } - - void update(SuppliesTrackerItem item) - { - trackedItems.removeIf(r -> r.getId() == item.getId()); - trackedItems.add(item); - setVisible(trackedItems.size() > 0); - } - - void remove(SuppliesTrackerItem item) - { - trackedItems.removeIf(r -> r.getId() == item.getId()); - plugin.clearItem(item.getId()); - setVisible(trackedItems.size() > 0); - } - - void clearAll() - { - trackedItems.clear(); - setVisible(false); - } - - public long getTotalSupplies() - { - long totalSupplies = 0; - for (SuppliesTrackerItem item : trackedItems) - { - totalSupplies += item.getQuantity(); - } - return totalSupplies; - } - - public long getTotalPrice() - { - return totalPrice; - } - - void rebuild() - { - buildItems(); - - priceLabel.setText(StackFormatter.quantityToStackSize(totalPrice) + " gp"); - priceLabel.setToolTipText(StackFormatter.formatNumber(totalPrice) + " gp"); - - final long supplies = getTotalSupplies(); - if (supplies > 0) - { - subTitleLabel.setText("x " + supplies); - } - else - { - subTitleLabel.setText(""); - } - - validate(); - repaint(); - } - - private void buildItems() - { - final List items = new ArrayList<>(trackedItems); - totalPrice = 0; - - for (SuppliesTrackerItem item : items) - { - totalPrice += item.getPrice(); - } - - items.sort((i1, i2) -> Long.compare(i2.getPrice(), i1.getPrice())); - - // calculates how many rows need to be displayed to fit all item - final int rowSize = ((items.size() % ITEMS_PER_ROW == 0) ? 0 : 1) + items.size() / ITEMS_PER_ROW; - - itemContainer.removeAll(); - itemContainer.setLayout(new GridLayout(rowSize, ITEMS_PER_ROW, 1, 1)); - - for (int i = 0; i < rowSize * ITEMS_PER_ROW; i++) - { - final JPanel slotContainer = new JPanel(); - slotContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR); - - if (i < items.size()) - { - final SuppliesTrackerItem item = items.get(i); - final JLabel imageLabel = new JLabel(); - imageLabel.setToolTipText(buildToolTip(item)); - imageLabel.setVerticalAlignment(SwingConstants.CENTER); - imageLabel.setHorizontalAlignment(SwingConstants.CENTER); - - AsyncBufferedImage itemImage = itemManager.getImage(getModifiedItemId(item.getName(), item.getId()), item.getQuantity(), item.getQuantity() > 1); - itemImage.addTo(imageLabel); - slotContainer.add(imageLabel); - - // create popup menu - final JPopupMenu popupMenu = new JPopupMenu(); - popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5)); - slotContainer.setComponentPopupMenu(popupMenu); - - final JMenuItem reset = new JMenuItem("Reset"); - reset.addActionListener(e -> - { - remove(item); - rebuild(); - panel.updateOverall(); - }); - - popupMenu.add(reset); - } - itemContainer.add(slotContainer); - } - itemContainer.repaint(); - } - - private int getModifiedItemId(String name, int itemId) - { - if (SuppliesTrackerPlugin.isPotion(name)) - { - return getSingleDose(name); - } - if (SuppliesTrackerPlugin.isCake(name, itemId)) - { - return getSlice(itemId); - } - if (SuppliesTrackerPlugin.isPizzaPie(name)) - { - return getHalf(itemId); - } - - return itemId; - } - - //Switches full cake ids to get the image for slice - private int getSlice(int itemId) - { - switch (itemId) - { - case CAKE: - itemId = SLICE_OF_CAKE; - break; - case CHOCOLATE_CAKE: - itemId = CHOCOLATE_SLICE; - break; - } - return itemId; - } - - //Switches full pizza and pie ids to get the image for half - private int getHalf(int itemId) - { - switch (itemId) - { - case ANCHOVY_PIZZA: - itemId = _12_ANCHOVY_PIZZA; - break; - case MEAT_PIZZA: - itemId = _12_MEAT_PIZZA; - break; - case PINEAPPLE_PIZZA: - itemId = _12_PINEAPPLE_PIZZA; - break; - case PLAIN_PIZZA: - itemId = _12_PLAIN_PIZZA; - break; - case REDBERRY_PIE: - itemId = HALF_A_REDBERRY_PIE; - break; - case GARDEN_PIE: - itemId = HALF_A_GARDEN_PIE; - break; - case SUMMER_PIE: - itemId = HALF_A_SUMMER_PIE; - break; - case FISH_PIE: - itemId = HALF_A_FISH_PIE; - break; - case BOTANICAL_PIE: - itemId = HALF_A_BOTANICAL_PIE; - break; - case MUSHROOM_PIE: - itemId = HALF_A_MUSHROOM_PIE; - break; - case ADMIRAL_PIE: - itemId = HALF_AN_ADMIRAL_PIE; - break; - case WILD_PIE: - itemId = HALF_A_WILD_PIE; - break; - case APPLE_PIE: - itemId = HALF_AN_APPLE_PIE; - break; - case MEAT_PIE: - itemId = HALF_A_MEAT_PIE; - break; - - } - return itemId; - } - - private int getSingleDose(String name) - { - String nameModified = name.replace("(4)", "(1)"); - int itemId = 0; - List itemList = itemManager.search(nameModified); - for (ItemPrice item: itemList) - { - itemId = item.getId(); - } - return itemId; - } - - private static String buildToolTip(SuppliesTrackerItem item) - { - final String name = item.getName(); - final int quantity = item.getQuantity(); - final long price = item.getPrice(); - return name + " x " + quantity + " (" + StackFormatter.quantityToStackSize(price) + ") "; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerConfig.java deleted file mode 100644 index f14160db15..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018, Davis Cook - * 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.suppliestracker; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("suppliestracker") -public interface SuppliesTrackerConfig extends Config -{ - @ConfigItem( - keyName = "blowpipeAmmo", - name = "Ammo used in your blowpipe", - description = "What type of dart are you using in your toxic blowpipe" - ) - default BlowpipeDartType blowpipeAmmo() - { - return BlowpipeDartType.MITHRIL; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerItem.java deleted file mode 100644 index 270d3b08b1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerItem.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2018, Daddy Dozer - * 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.suppliestracker; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor - -class SuppliesTrackerItem -{ - @Getter - private int id; - @Getter - private String name; - @Getter - private int quantity; - @Getter - private long price; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java deleted file mode 100644 index 6eea00105f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2018, Psikoi - * Copyright (c) 2018, Tomas Slusny - * Copyright (c) 2018, Daddy Dozer - * 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.suppliestracker; - -import net.runelite.client.game.ItemManager; -import net.runelite.client.ui.ColorScheme; -import net.runelite.client.ui.FontManager; -import net.runelite.client.ui.PluginPanel; -import net.runelite.client.ui.components.PluginErrorPanel; -import net.runelite.client.util.ColorUtil; -import net.runelite.client.util.StackFormatter; -import javax.swing.BoxLayout; -import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.border.EmptyBorder; -import java.awt.BorderLayout; -import java.awt.GridLayout; -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ScheduledExecutorService; - - -class SuppliesTrackerPanel extends PluginPanel -{ - private static final String HTML_LABEL_TEMPLATE = - "%s%s"; - - // Handle loot logs - private final JPanel logsContainer = new JPanel(); - - private final List boxList = new ArrayList<>(); - - private final PluginErrorPanel errorPanel = new PluginErrorPanel(); - - private final ScheduledExecutorService executor; - - // Handle overall session data - private final JPanel overallPanel = new JPanel(); - private final JLabel overallSuppliesUsedLabel = new JLabel(); - private final JLabel overallCostLabel = new JLabel(); - private final JLabel overallIcon = new JLabel(); - private final ItemManager itemManager; - private final SuppliesTrackerPlugin plugin; - private int overallSuppliesUsed; - private int overallCost; - - SuppliesTrackerPanel(final ItemManager itemManager, ScheduledExecutorService executor, SuppliesTrackerPlugin plugin) - { - this.executor = executor; - this.itemManager = itemManager; - this.plugin = plugin; - setBorder(new EmptyBorder(6, 6, 6, 6)); - setBackground(ColorScheme.DARK_GRAY_COLOR); - setLayout(new BorderLayout()); - - // Create layout panel for wrapping - final JPanel layoutPanel = new JPanel(); - layoutPanel.setLayout(new BoxLayout(layoutPanel, BoxLayout.Y_AXIS)); - add(layoutPanel, BorderLayout.NORTH); - - // Create panel that will contain overall data - overallPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); - overallPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - overallPanel.setLayout(new BorderLayout()); - overallPanel.setVisible(true); - - // Add icon and contents - final JPanel overallInfo = new JPanel(); - overallInfo.setBackground(ColorScheme.DARKER_GRAY_COLOR); - overallInfo.setLayout(new GridLayout(2, 1)); - overallInfo.setBorder(new EmptyBorder(0, 10, 0, 0)); - overallSuppliesUsedLabel.setFont(FontManager.getRunescapeSmallFont()); - overallCostLabel.setFont(FontManager.getRunescapeSmallFont()); - overallInfo.add(overallSuppliesUsedLabel); - overallInfo.add(overallCostLabel); - overallPanel.add(overallIcon, BorderLayout.WEST); - overallPanel.add(overallInfo, BorderLayout.CENTER); - - for (ItemType type : ItemType.values()) - { - SuppliesBox newBox = new SuppliesBox(itemManager, type.getLabel(), plugin, this, type); - logsContainer.add(newBox); - boxList.add(newBox); - } - - // Create reset all menu - final JMenuItem reset = new JMenuItem("Reset All"); - reset.addActionListener(e -> - { - overallSuppliesUsed = 0; - overallCost = 0; - plugin.clearSupplies(); - for (SuppliesBox box : boxList) - { - box.clearAll(); - } - updateOverall(); - logsContainer.repaint(); - }); - - // Create popup menu - final JPopupMenu popupMenu = new JPopupMenu(); - popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5)); - popupMenu.add(reset); - overallPanel.setComponentPopupMenu(popupMenu); - - // Create Supply Rows wrapper - logsContainer.setLayout(new BoxLayout(logsContainer, BoxLayout.Y_AXIS)); - layoutPanel.add(overallPanel); - layoutPanel.add(logsContainer); - - errorPanel.setContent("Supply trackers", "You have not used any supplies yet."); - add(errorPanel); - overallPanel.setVisible(false); - } - - /** - * loads an img to the icon on the header - * @param img the img for the header icon - */ - public void loadHeaderIcon(BufferedImage img) - { - overallIcon.setIcon(new ImageIcon(img)); - } - - /** - * convert key value pair to html formatting needed to display nicely - * @param key key - * @param value value - * @return key: value in html - */ - private static String htmlLabel(String key, long value) - { - final String valueStr = StackFormatter.quantityToStackSize(value); - return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), key, valueStr); - } - - /** - * Add an item to the supply panel by placing it into the correct box - * @param item the item to add - */ - public void addItem(SuppliesTrackerItem item) - { - ItemType category = ItemType.categorize(item); - for (SuppliesBox box : boxList) - { - if (box.getType() == category) - { - box.update(item); - box.rebuild(); - break; - } - } - updateOverall(); - } - - /** - * Updates overall stats to calculate overall used and overall cost from - * the info in each box - */ - public void updateOverall() - { - overallSuppliesUsed = 0; - for (SuppliesBox box : boxList) - { - overallSuppliesUsed += box.getTotalSupplies(); - } - - overallCost = 0; - for (SuppliesBox box : boxList) - { - overallCost += box.getTotalPrice(); - } - - overallSuppliesUsedLabel.setText(htmlLabel("Total Supplies: ", overallSuppliesUsed)); - overallCostLabel.setText(htmlLabel("Total Cost: ", overallCost)); - - if (overallSuppliesUsed <= 0) - { - add(errorPanel); - overallPanel.setVisible(false); - } - else - { - remove(errorPanel); - overallPanel.setVisible(true); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java deleted file mode 100644 index f7034af63f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java +++ /dev/null @@ -1,781 +0,0 @@ -/* - * Copyright (c) 2018, Psikoi - * Copyright (c) 2018, Adam - * Copyright (c) 2018, Sir Girion - * Copyright (c) 2018, Davis Cook - * Copyright (c) 2018, Daddy Dozer - * 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.suppliestracker; - - -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.*; -import net.runelite.api.events.*; -import net.runelite.client.callback.ClientThread; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.game.ItemManager; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.ClientToolbar; -import net.runelite.client.ui.NavigationButton; -import net.runelite.client.util.ImageUtil; -import net.runelite.http.api.item.ItemPrice; - -import static net.runelite.api.AnimationID.*; -import static net.runelite.api.ItemID.*; -import static net.runelite.client.plugins.suppliestracker.ActionType.CONSUMABLE; -import static net.runelite.client.plugins.suppliestracker.ActionType.TELEPORT; -import static net.runelite.client.plugins.suppliestracker.ActionType.CAST; - -import java.util.*; -import java.util.concurrent.ScheduledExecutorService; -import java.util.regex.Pattern; -import javax.inject.Inject; -import javax.swing.SwingUtilities; -import java.awt.image.BufferedImage; - - -@PluginDescriptor( - name = "Supplies Used Tracker", - description = "Tracks supplies used during the session", - tags = {"cost"}, - enabledByDefault = false -) -@Slf4j -public class SuppliesTrackerPlugin extends Plugin -{ - - private static final String POTION_PATTERN = "[(]\\d[)]"; - - private static final String EAT_PATTERN = "^eat"; - private static final String DRINK_PATTERN = "^drink"; - private static final String TELEPORT_PATTERN = "^teleport"; - private static final String TELETAB_PATTERN = "^break"; - private static final String SPELL_PATTERN = "^cast|^grand\\sexchange|^outside|^seers|^yanille"; - - private static final int EQUIPMENT_MAINHAND_SLOT = EquipmentInventorySlot.WEAPON.getSlotIdx(); - private static final int EQUIPMENT_AMMO_SLOT = EquipmentInventorySlot.AMMO.getSlotIdx(); - private static final int EQUIPMENT_CAPE_SLOT = EquipmentInventorySlot.CAPE.getSlotIdx(); - - private static final double NO_AVAS_PERCENT = 1.0; - private static final double ASSEMBLER_PERCENT = 0.20; - private static final double ACCUMULATOR_PERCENT = 0.28; - private static final double ATTRACTOR_PERCENT = 0.40; - - private static final int BLOWPIPE_TICKS_RAPID_PVM = 2; - private static final int BLOWPIPE_TICKS_RAPID_PVP = 3; - private static final int BLOWPIPE_TICKS_NORMAL_PVM = 3; - private static final int BLOWPIPE_TICKS_NORMAL_PVP = 4; - - private static final double SCALES_PERCENT = 0.66; - - private static final int POTION_DOSES = 4, CAKE_DOSES = 3, PIZZA_PIE_DOSES = 2; - - private static final Random random = new Random(); - - private static final int[] THROWING_IDS = new int[]{BRONZE_DART, IRON_DART, STEEL_DART, BLACK_DART, MITHRIL_DART, ADAMANT_DART, RUNE_DART, DRAGON_DART, BRONZE_KNIFE, IRON_KNIFE, STEEL_KNIFE, BLACK_KNIFE, MITHRIL_KNIFE, ADAMANT_KNIFE, RUNE_KNIFE, BRONZE_THROWNAXE, IRON_THROWNAXE, STEEL_THROWNAXE, MITHRIL_THROWNAXE, ADAMANT_THROWNAXE, RUNE_THROWNAXE, DRAGON_KNIFE, DRAGON_KNIFE_22812, DRAGON_KNIFE_22814, DRAGON_KNIFEP_22808, DRAGON_KNIFEP_22810, DRAGON_KNIFEP , DRAGON_THROWNAXE, CHINCHOMPA_10033, RED_CHINCHOMPA_10034, BLACK_CHINCHOMPA}; - private static final int[] RUNE_IDS = new int[]{AIR_RUNE, WATER_RUNE, EARTH_RUNE, MIND_RUNE, BODY_RUNE, COSMIC_RUNE, CHAOS_RUNE, NATURE_RUNE, LAW_RUNE, DEATH_RUNE, ASTRAL_RUNE, BLOOD_RUNE, SOUL_RUNE, WRATH_RUNE, MIST_RUNE, DUST_RUNE, MUD_RUNE, SMOKE_RUNE, STEAM_RUNE, LAVA_RUNE}; - - //Hold Supply Data - private static HashMap suppliesEntry = new HashMap<>(); - private ItemContainer old; - private Deque actionStack = new ArrayDeque<>(); - private int ammoId = 0; - private int ammoAmount = 0; - private int thrownId = 0; - private int thrownAmount = 0; - private boolean ammoLoaded = false; - private boolean throwingAmmoLoaded = false; - private boolean mainHandThrowing = false; - private int mainHand = 0; - private SuppliesTrackerPanel panel; - private NavigationButton navButton; - private String[] RAIDS_CONSUMABLES = new String[]{"xeric's", "elder", "twisted", "revitalisation", "overload", "prayer enhance", "pysk", "suphi", "leckish", "brawk", "mycil", "roqed", "kyren", "guanic", "prael", "giral", "phluxia", "kryket", "murng", "psykk"}; - - private int attackStyleVarbit = -1; - private int ticks = 0; - private int ticksInAnimation; - - @Inject - private ClientToolbar clientToolbar; - - @Inject - private ItemManager itemManager; - - @Inject - private SpriteManager spriteManager; - - @Inject - private SuppliesTrackerConfig config; - - @Inject - private Client client; - - @Inject - private ScheduledExecutorService executorService; - - @Inject - private ClientThread clientThread; - - - @Override - protected void startUp() throws Exception - { - panel = new SuppliesTrackerPanel(itemManager, executorService, this); - final BufferedImage header = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); - panel.loadHeaderIcon(header); - final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); - - navButton = NavigationButton.builder() - .tooltip("Supplies Tracker") - .icon(icon) - .priority(5) - .panel(panel) - .build(); - - clientToolbar.addNavigation(navButton); - } - - @Override - protected void shutDown() - { - clientToolbar.removeNavigation(navButton); - } - - @Provides - SuppliesTrackerConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(SuppliesTrackerConfig.class); - } - - @Subscribe - public void onGameTick(GameTick tick) - { - Player player = client.getLocalPlayer(); - if (player.getAnimation() == BLOWPIPE_ATTACK) - { - ticks++; - } - if (ticks == ticksInAnimation && (player.getAnimation() == BLOWPIPE_ATTACK)) - { - double ava_percent = getAccumulatorPercent(); - double scale_percent = SCALES_PERCENT; - // randomize the usage of supplies since we CANNOT actually get real supplies used - if (random.nextDouble() <= ava_percent) - { - buildEntries(config.blowpipeAmmo().getDartID()); - - } - if (random.nextDouble() <= scale_percent) - { - buildEntries(ZULRAHS_SCALES); - } - ticks = 0; - } - } - - /** - * checks the player's cape slot to determine what percent of their darts are lost - * - where lost means either break or drop to floor - * @return the percent lost - */ - private double getAccumulatorPercent() - { - double percent = NO_AVAS_PERCENT; - ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT); - if (equipment.getItems().length > EQUIPMENT_CAPE_SLOT) - { - int capeID = equipment.getItems()[EQUIPMENT_CAPE_SLOT].getId(); - switch (capeID) - { - case AVAS_ASSEMBLER: - case ASSEMBLER_MAX_CAPE: - percent = ASSEMBLER_PERCENT; - break; - case AVAS_ACCUMULATOR: - case ACCUMULATOR_MAX_CAPE: - // TODO: the ranging cape can be used as an attractor so this could be wrong - case RANGING_CAPE: - percent = ACCUMULATOR_PERCENT; - break; - case AVAS_ATTRACTOR: - percent = ATTRACTOR_PERCENT; - break; - } - } - return percent; - } - - @Subscribe - public void onVarbitChanged(VarbitChanged event) - { - if (attackStyleVarbit == -1 || attackStyleVarbit != client.getVar(VarPlayer.ATTACK_STYLE)) - { - attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE); - if (attackStyleVarbit == 0 || attackStyleVarbit == 3) - { - ticksInAnimation = BLOWPIPE_TICKS_NORMAL_PVM; - if (client.getLocalPlayer() != null && - client.getLocalPlayer().getInteracting() instanceof Player) { - ticksInAnimation = BLOWPIPE_TICKS_NORMAL_PVP; - } - } - else if (attackStyleVarbit == 1) - { - ticksInAnimation = BLOWPIPE_TICKS_RAPID_PVM; - if (client.getLocalPlayer() != null && - client.getLocalPlayer().getInteracting() instanceof Player) { - ticksInAnimation = BLOWPIPE_TICKS_RAPID_PVP; - } - } - } - } - - /** - * Checks for changes between the provided inventories in runes specifically to add those runes - * to the supply tracker - * - * we can't in general just check for when inventory slots change but this method is only run - * immediately after the player performs a cast animation or cast menu click/entry - * @param itemContainer the new inventory - * @param oldInv the old inventory - */ - private void checkUsedRunes(ItemContainer itemContainer, Item[] oldInv) - { - for (int i = 0; i < itemContainer.getItems().length; i++) - { - Item newItem = itemContainer.getItems()[i]; - Item oldItem = oldInv[i]; - boolean isRune = false; - for (int j = 0; j < RUNE_IDS.length; j++) - { - if (oldItem.getId() == RUNE_IDS[j]) - { - isRune = true; - } - } - if (isRune && (newItem.getId() != oldItem.getId() || newItem.getQuantity() != oldItem.getQuantity())) - { - int quantity = oldItem.getQuantity(); - if (newItem.getId() == oldItem.getId()) - { - quantity -= newItem.getQuantity(); - } - buildEntries(oldItem.getId(), quantity); - } - } - } - - @Subscribe - public void onCannonballFired(CannonballFired cannonballFired) - { - buildEntries(CANNONBALL); - } - - @Subscribe - public void onAnimationChanged(AnimationChanged animationChanged) - { - if (animationChanged.getActor() == client.getLocalPlayer()) - { - if (animationChanged.getActor().getAnimation() == HIGH_LEVEL_MAGIC_ATTACK) - { - //Trident of the seas - if (mainHand == TRIDENT_OF_THE_SEAS || mainHand == TRIDENT_OF_THE_SEAS_E || mainHand == TRIDENT_OF_THE_SEAS_FULL ) - { - buildEntries(CHAOS_RUNE); - buildEntries(DEATH_RUNE); - buildEntries(FIRE_RUNE, 5); - buildEntries(COINS_995, 10); - } - //Trident of the swamp - else if (mainHand == TRIDENT_OF_THE_SWAMP_E || mainHand == TRIDENT_OF_THE_SWAMP || mainHand == UNCHARGED_TOXIC_TRIDENT_E || mainHand == UNCHARGED_TOXIC_TRIDENT) - { - buildEntries(CHAOS_RUNE); - buildEntries(DEATH_RUNE); - buildEntries(FIRE_RUNE, 5); - buildEntries(ZULRAHS_SCALES); - } - //Sang Staff - else if (mainHand == SANGUINESTI_STAFF || mainHand == SANGUINESTI_STAFF_UNCHARGED) - { - buildEntries(BLOOD_RUNE, 3); - } - else - { - old = client.getItemContainer(InventoryID.INVENTORY); - - if (old.getItems() != null && !actionStack.stream().anyMatch(a -> - a.getType() == CAST)) - { - MenuAction newAction = new MenuAction(CAST, old.getItems()); - actionStack.push(newAction); - } - } - } - else if (animationChanged.getActor().getAnimation() == LOW_LEVEL_MAGIC_ATTACK) - { - old = client.getItemContainer(InventoryID.INVENTORY); - - if (old.getItems() != null && !actionStack.stream().anyMatch(a -> - a.getType() == CAST)) - { - MenuAction newAction = new MenuAction(CAST, old.getItems()); - actionStack.push(newAction); - } - } - } - } - - @Subscribe - public void onItemContainerChanged(ItemContainerChanged itemContainerChanged) - { - ItemContainer itemContainer = itemContainerChanged.getItemContainer(); - - for (MenuAction action : actionStack) - { - System.out.println(action.getType()); - } - - if (itemContainer == client.getItemContainer(InventoryID.INVENTORY) && old != null && !actionStack.isEmpty()) - { - while (!actionStack.isEmpty()) - { - MenuAction frame = actionStack.pop(); - ActionType type = frame.getType(); - MenuAction.ItemAction itemFrame; - Item[] oldInv = frame.getOldInventory(); - switch (type) - { - case CONSUMABLE: - itemFrame = (MenuAction.ItemAction) frame; - int nextItem = itemFrame.getItemID(); - int nextSlot = itemFrame.getSlot(); - if (itemContainer.getItems()[nextSlot].getId() != oldInv[nextSlot].getId()) - { - buildEntries(nextItem); - } - break; - case TELEPORT: - itemFrame = (MenuAction.ItemAction) frame; - int teleid = itemFrame.getItemID(); - int slot = itemFrame.getSlot(); - if (itemContainer.getItems()[slot].getId() != oldInv[slot].getId() || itemContainer.getItems()[slot].getQuantity() != oldInv[slot].getQuantity()) - { - buildEntries(teleid); - } - break; - case CAST: - checkUsedRunes(itemContainer, oldInv); - break; - } - } - } - - if (itemContainer == client.getItemContainer(InventoryID.EQUIPMENT)) - { - //set mainhand for trident tracking - if (itemContainer.getItems().length > EQUIPMENT_MAINHAND_SLOT) - { - mainHand = itemContainer.getItems()[EQUIPMENT_MAINHAND_SLOT].getId(); - net.runelite.api.Item mainHandItem = itemContainer.getItems()[EQUIPMENT_MAINHAND_SLOT]; - for (int throwingIDs: THROWING_IDS) - { - if (mainHand == throwingIDs) - { - mainHandThrowing = true; - break; - } - else - { - mainHandThrowing = false; - } - } - if (mainHandThrowing) - { - if (throwingAmmoLoaded) - { - if (thrownId == mainHandItem.getId()) - { - if (thrownAmount - 1 == mainHandItem.getQuantity()) - { - buildEntries(mainHandItem.getId()); - thrownAmount = mainHandItem.getQuantity(); - } - else - { - thrownAmount = mainHandItem.getQuantity(); - } - } - else - { - thrownId = mainHandItem.getId(); - thrownAmount = mainHandItem.getQuantity(); - } - } - else - { - thrownId = mainHandItem.getId(); - thrownAmount = mainHandItem.getQuantity(); - throwingAmmoLoaded = true; - } - } - } - //Ammo tracking - if (itemContainer.getItems().length > EQUIPMENT_AMMO_SLOT) - { - net.runelite.api.Item ammoSlot = itemContainer.getItems()[EQUIPMENT_AMMO_SLOT]; - if (ammoSlot != null) - { - if (ammoLoaded) - { - if (ammoId == ammoSlot.getId()) - { - if (ammoAmount - 1 == ammoSlot.getQuantity()) - { - buildEntries(ammoSlot.getId()); - ammoAmount = ammoSlot.getQuantity(); - } - else - { - ammoAmount = ammoSlot.getQuantity(); - } - } - else - { - ammoId = ammoSlot.getId(); - ammoAmount = ammoSlot.getQuantity(); - } - } - else - { - ammoId = ammoSlot.getId(); - ammoAmount = ammoSlot.getQuantity(); - ammoLoaded = true; - } - } - } - - } - } - - @Subscribe - public void onMenuOptionClicked(final MenuOptionClicked event) - { - System.out.println(event.getMenuAction().getId()); - System.out.println(event.getActionParam()); - System.out.println(event.getMenuOption()); - System.out.println(event.getMenuTarget()); - - // Uses stacks to push/pop for tick eating - // Create pattern to find eat/drink at beginning - Pattern eatPattern = Pattern.compile(EAT_PATTERN); - Pattern drinkPattern = Pattern.compile(DRINK_PATTERN); - if (eatPattern.matcher(event.getMenuTarget().toLowerCase()).find() || drinkPattern.matcher(event.getMenuTarget().toLowerCase()).find()) - { - if (!actionStack.stream().anyMatch(a -> - { - if (a instanceof MenuAction.ItemAction) - { - MenuAction.ItemAction i = (MenuAction.ItemAction) a; - return i.getItemID() == event.getId(); - } - return false; - })) - { - old = client.getItemContainer(InventoryID.INVENTORY); - int slot = event.getActionParam(); - if (old.getItems() != null) - { - int pushItem = old.getItems()[event.getActionParam()].getId(); - MenuAction newAction = new MenuAction.ItemAction(CONSUMABLE, old.getItems(), pushItem, slot); - actionStack.push(newAction); - } - } - } - - // Create pattern for teleport scrolls and tabs - Pattern teleportPattern = Pattern.compile(TELEPORT_PATTERN); - Pattern teletabPattern = Pattern.compile(TELETAB_PATTERN); - if (teleportPattern.matcher(event.getMenuTarget().toLowerCase()).find() || - teletabPattern.matcher(event.getMenuTarget().toLowerCase()).find()) - { - old = client.getItemContainer(InventoryID.INVENTORY); - - // Makes stack only contains one teleport type to stop from adding multiple of one teleport - if (old.getItems() != null && !actionStack.stream().anyMatch(a -> - a.getType() == TELEPORT)) - { - int teleid = event.getId(); - MenuAction newAction = new MenuAction.ItemAction(TELEPORT, old.getItems(), teleid, event.getActionParam()); - actionStack.push(newAction); - } - } - - // Create pattern for spell cast - Pattern spellPattern = Pattern.compile(SPELL_PATTERN); - // note that here we look at the menuOption not menuTarget b/c the option for all spells is cast - // but the target differs based on each spell name - if (spellPattern.matcher(event.getMenuOption().toLowerCase()).find()) - { - old = client.getItemContainer(InventoryID.INVENTORY); - - if (old.getItems() != null && !actionStack.stream().anyMatch(a -> - a.getType() == CAST)) - { - MenuAction newAction = new MenuAction(CAST, old.getItems()); - actionStack.push(newAction); - } - } - } - - /** - * Checks if item name is potion - * @param name the name of the item - * @return if the item is a potion - i.e. has a (1) (2) (3) or (4) in the name - */ - static boolean isPotion(String name) - { - return name.contains("(4)") || name.contains("(3)") || name.contains("(2)") || name.contains("(1)"); - } - - /** - * Checks if item name is pizza or pie - * @param name the name of the item - * @return if the item is a pizza or a pie - i.e. has pizza or pie in the name - */ - static boolean isPizzaPie(String name) - { - return name.toLowerCase().contains("pizza") || name.toLowerCase().contains(" pie"); - } - - static boolean isCake(String name, int itemId) - { - return name.toLowerCase().contains("cake") || itemId == ItemID.CHOCOLATE_SLICE; - } - - /** - * correct prices for potions, pizzas pies, and cakes - * tracker tracks each dose of a potion/pizza/pie/cake as an entire one - * so must divide price by total amount of doses in each - * this is necessary b/c the most correct/accurate price for these resources is the - * full price not the 1-dose price - * @param name the item name - * @param itemId the item id - * @param price the current calculated price - * @return the price modified by the number of doses - */ - private long scalePriceByDoses(String name, int itemId, long price) - { - if (isPotion(name)) - { - return price / POTION_DOSES; - } - if (isPizzaPie(name)) - { - return price / PIZZA_PIE_DOSES; - } - if (isCake(name, itemId)) - { - return price / CAKE_DOSES; - } - return price; - } - - /** - * Add an item to the supply tracker (with 1 count for that item) - * @param itemId the id of the item - */ - void buildEntries(int itemId) - { - buildEntries(itemId, 1); - } - - /** - * Add an item to the supply tracker - * @param itemId the id of the item - * @param count the amount of the item to add to the tracker - */ - void buildEntries(int itemId, int count) - { - final ItemComposition itemComposition = itemManager.getItemComposition(itemId); - String name = itemComposition.getName(); - long calculatedPrice; - - for (String raidsConsumables: RAIDS_CONSUMABLES) - { - if (name.toLowerCase().contains(raidsConsumables)) return; - } - - // convert potions, pizzas/pies, and cakes to their full equivalents - // e.g. a half pizza becomes full pizza, 3 dose potion becomes 4, etc... - if (isPotion(name)) - { - name = name.replaceAll(POTION_PATTERN, "(4)"); - itemId = getPotionID(name); - } - if (isPizzaPie(name)) - { - itemId = getFullVersionItemID(itemId); - name = itemManager.getItemComposition(itemId).getName(); - } - if (isCake(name, itemId)) - { - itemId = getFullVersionItemID(itemId); - name = itemManager.getItemComposition(itemId).getName(); - } - - int newQuantity; - if (suppliesEntry.containsKey(itemId)) - { - newQuantity = suppliesEntry.get(itemId).getQuantity() + count; - } - else - { - newQuantity = count; - } - - // calculate price for amount of doses used - calculatedPrice = ((long) itemManager.getItemPrice(itemId)) * ((long) newQuantity); - calculatedPrice = scalePriceByDoses(name, itemId, calculatedPrice); - - // write the new quantity and calculated price for this entry - SuppliesTrackerItem newEntry = new SuppliesTrackerItem( - itemId, - name, - newQuantity, - calculatedPrice); - - suppliesEntry.put(itemId, newEntry); - SwingUtilities.invokeLater(() -> - { - panel.addItem(newEntry); - }); - } - - /** - * reset all item stacks - */ - public void clearSupplies() - { - suppliesEntry.clear(); - } - - /** - * reset an individual item stack - * @param itemId the id of the item stack - */ - public void clearItem(int itemId) - { - suppliesEntry.remove(itemId); - } - - /** - * Gets the item id that matches the provided name within the itemManager - * @param name the given name - * @return the item id for this name - */ - private int getPotionID(String name) - { - int itemId = 0; - - List items = itemManager.search(name); - for (ItemPrice item: items) - { - if (item.getName().contains(name)) - { - itemId = item.getId(); - } - } - return itemId; - } - - /** - * Takes the item id of a partial item (e.g. 1 dose potion, 1/2 a pizza, etc...) and returns - * the corresponding full item - * @param itemId the partial item id - * @return the full item id - */ - private int getFullVersionItemID(int itemId) - { - switch (itemId) - { - case _12_ANCHOVY_PIZZA: - itemId = ANCHOVY_PIZZA; - break; - case _12_MEAT_PIZZA: - itemId = MEAT_PIZZA; - break; - case _12_PINEAPPLE_PIZZA: - itemId = PINEAPPLE_PIZZA; - break; - case _12_PLAIN_PIZZA: - itemId = PLAIN_PIZZA; - break; - case HALF_A_REDBERRY_PIE: - itemId = REDBERRY_PIE; - break; - case HALF_A_GARDEN_PIE: - itemId = GARDEN_PIE; - break; - case HALF_A_SUMMER_PIE: - itemId = SUMMER_PIE; - break; - case HALF_A_FISH_PIE: - itemId = FISH_PIE; - break; - case HALF_A_BOTANICAL_PIE: - itemId = BOTANICAL_PIE; - break; - case HALF_A_MUSHROOM_PIE: - itemId = MUSHROOM_PIE; - break; - case HALF_AN_ADMIRAL_PIE: - itemId = ADMIRAL_PIE; - break; - case HALF_A_WILD_PIE: - itemId = WILD_PIE; - break; - case HALF_AN_APPLE_PIE: - itemId = APPLE_PIE; - break; - case HALF_A_MEAT_PIE: - itemId = MEAT_PIE; - break; - // note behavior of case means both below cases return CAKE - case _23_CAKE: - case SLICE_OF_CAKE: - itemId = CAKE; - break; - case _23_CHOCOLATE_CAKE: - case CHOCOLATE_SLICE: - itemId = CHOCOLATE_CAKE; - break; - } - return itemId; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java deleted file mode 100644 index 119a70f245..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2018, Frosty Fridge - * 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.templetrek; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; -import javax.inject.Inject; -import net.runelite.api.GroundObject; -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; - -public class TempleTrekBogOverlay extends Overlay -{ - private final TempleTrekConfig config; - private final TempleTrekPlugin plugin; - - private static final Color GREEN = new Color(0, 200, 83); - - @Inject - private TempleTrekBogOverlay(TempleTrekConfig config, TempleTrekPlugin plugin) - { - super(plugin); - this.config = config; - this.plugin = plugin; - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.LOW); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (config.bogMapActive()) - { - for (GroundObject bog : plugin.getBogList()) - { - Polygon bogPoly = bog.getCanvasTilePoly(); - OverlayUtil.renderPolygon(graphics, bogPoly, GREEN); - } - } - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java deleted file mode 100644 index 090d1a9cab..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2018, Frosty Fridge - * 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.templetrek; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("templetrek") -public interface TempleTrekConfig extends Config -{ - @ConfigItem( - keyName = "bogMapActive", - name = "Bog Map", - description = "Marks out a safe route through the bog event", - position = 0 - ) - default boolean bogMapActive() - { - return true; - } - - @ConfigItem( - keyName = "pointTrackerActive", - name = "Point Tracker", - description = "Track your Temple Trek reward points, which determine the size of your reward.", - position = 1 - ) - default boolean pointTrackerActive() - { - return true; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java deleted file mode 100644 index afbf4c88a5..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2018, Frosty Fridge - * 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.templetrek; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import javax.inject.Inject; -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.components.LineComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; - -public class TempleTrekOverlay extends Overlay -{ - private final TempleTrekConfig config; - private final TempleTrekPlugin plugin; - - private final PanelComponent panelComponent = new PanelComponent(); - - @Inject - private TempleTrekOverlay(TempleTrekConfig config, TempleTrekPlugin plugin) - { - super(plugin); - this.config = config; - this.plugin = plugin; - setPosition(OverlayPosition.TOP_LEFT); - setPriority(OverlayPriority.LOW); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (config.pointTrackerActive() && plugin.isInTrek()) - { - int points = plugin.getRewardPoints(); - double percentage = plugin.getRewardPercentage() * 100; - panelComponent.getChildren().clear(); - panelComponent.getChildren().add(LineComponent.builder() - .left("Trek Points: ") - .right(Integer.toString(points)) - .rightColor(percentage < 25 ? Color.RED : percentage >= 25 && percentage < 50 ? Color.YELLOW : - percentage >= 50 && percentage < 75 ? Color.BLUE : Color.GREEN) - .build()); - panelComponent.getChildren().add(LineComponent.builder() - .left("Reward %: ") - .right(String.format("%.2f", percentage) + "%") - .rightColor(percentage < 25 ? Color.RED : percentage >= 25 && percentage < 50 ? Color.YELLOW : - percentage >= 50 && percentage < 75 ? Color.BLUE : Color.GREEN) - .build()); - return panelComponent.render(graphics); - } - return null; - } -} 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 deleted file mode 100644 index 99fd1d4286..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2018, Frosty Fridge - * 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.templetrek; - -import com.google.inject.Provides; -import java.util.HashSet; -import java.util.Set; -import javax.inject.Inject; -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.GroundObject; -import net.runelite.api.ObjectID; -import net.runelite.api.Varbits; -import net.runelite.api.events.GroundObjectSpawned; -import net.runelite.api.events.VarbitChanged; -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.ui.overlay.OverlayManager; - -@PluginDescriptor( - name = "Temple Trekking", - description = "Helpers for the Temple Trek minigame", - tags = {"minigame", "overlay", "temple trek"} -) -public class TempleTrekPlugin extends Plugin -{ - - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private TempleTrekOverlay overlay; - - @Inject - private TempleTrekBogOverlay bogOverlay; - - @Inject - private TempleTrekConfig config; - - @Getter - private final Set bogList = new HashSet(); - - @Getter - private boolean inTrek = false; - - @Provides - TempleTrekConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(TempleTrekConfig.class); - } - - @Override - protected void startUp() - { - overlayManager.add(overlay); - overlayManager.add(bogOverlay); - } - - @Override - protected void shutDown() - { - overlayManager.remove(overlay); - overlayManager.remove(bogOverlay); - bogList.clear(); - } - - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) - { - GroundObject obj = event.getGroundObject(); - if (obj.getId() == ObjectID.BOG) - { - bogList.add(obj); - } - } - - //onGroundObjectDespawned is having issues handling this, so bogmap removal is here instead. - @Subscribe - public void onVarbitChanged(VarbitChanged event) - { - if (!bogList.isEmpty() && client.getVar(Varbits.TREK_EVENT) == 0) - { - bogList.clear(); - } - if (!inTrek && client.getVar(Varbits.TREK_STARTED) == 1) - { - inTrek = true; - } - else if (inTrek) - { - if (client.getVar(Varbits.TREK_STATUS) == 0 && client.getVar(Varbits.TREK_POINTS) == 0) - { - inTrek = false; - } - } - } - - protected int getRewardPoints() - { - return client.getVar(Varbits.TREK_POINTS); - } - - protected double getRewardPercentage() - { - double percentage = 0.000126945 * getRewardPoints() - 0.0357188951; - return Math.max(percentage, 0); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java deleted file mode 100644 index 79e90dc38d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.runelite.client.plugins.tickcounter; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -import java.awt.*; - -@ConfigGroup("tickcounter") -public interface TickCounterConfig extends Config { - @ConfigItem( - keyName = "resetInstance", - name = "Reset on new instances", - description = "", - position = 1 - ) - default boolean instance() - { - return true; - } - @ConfigItem( - keyName = "selfColor", - name = "Your color", - description = "", - position = 4 - ) - default Color selfColor() - { - return Color.green; - } - @ConfigItem( - keyName = "totalColor", - name = "Total color", - description = "", - position = 6 - ) - default Color totalColor() - { - return Color.RED; - } - @ConfigItem( - keyName = "otherColor", - name = "Other players color", - description = "", - position = 5 - ) - default Color otherColor() - { - return Color.white; - } - @ConfigItem( - keyName = "bgColor", - name = "Background color", - description = "", - position = 3 - ) - default Color bgColor() - { - return new Color(70, 61, 50, 156); - } - @ConfigItem( - keyName = "titleColor", - name = "Title color", - description = "", - position = 2 - ) - default Color titleColor() - { - return Color.white; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java deleted file mode 100644 index 33e22fe1fa..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.runelite.client.plugins.tickcounter; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map.Entry; - -import javax.inject.Inject; - -import net.runelite.api.Client; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity; -import net.runelite.client.ui.overlay.components.LineComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; -import net.runelite.client.ui.overlay.components.TitleComponent; - -public class TickCounterOverlay extends Overlay { - - private TickCounterPlugin plugin; - private TickCounterConfig config; - private Client client; - private PanelComponent panelComponent = new PanelComponent(); - - @Inject - public TickCounterOverlay(TickCounterPlugin plugin,Client client,TickCounterConfig config) { - super(plugin); - setPosition(OverlayPosition.DYNAMIC); - setPosition(OverlayPosition.DETACHED); - setPosition(OverlayPosition.BOTTOM_RIGHT); - this.plugin = plugin; - this.client = client; - this.config = config; - } - - @Override - public Dimension render(Graphics2D g) { - List elems = panelComponent.getChildren(); - elems.clear(); - panelComponent.setBackgroundColor(config.bgColor()); - elems.add(TitleComponent.builder().text("Combat counter").color(config.titleColor()).build()); - List> list = new ArrayList<>(plugin.activity.entrySet()); - list.sort(new Comparator>() { - @Override - public int compare(Entry o1, Entry o2) { - int value = -Integer.compare(o1.getValue(), o2.getValue()); - if (value == 0) - value = o1.getKey().compareTo(o2.getKey()); - return value; - } - }); - int total = 0; - for (Entry e : list) { - total += e.getValue(); - if(e.getKey().equals(client.getLocalPlayer().getName())){ - elems.add(LineComponent.builder().leftColor(config.selfColor()).rightColor(config.selfColor()).left(e.getKey()).right(e.getValue().toString()).build()); - }else{ - elems.add(LineComponent.builder().left(e.getKey()).right(e.getValue().toString()).leftColor(config.otherColor()).rightColor(config.otherColor()).build()); - - } - } - elems.add(LineComponent.builder().left("Total").leftColor(config.totalColor()).rightColor(config.totalColor()).right(String.valueOf(total)).build()); - return this.panelComponent.render(g); - } - -} 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 deleted file mode 100644 index fe2130285c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java +++ /dev/null @@ -1,193 +0,0 @@ -package net.runelite.client.plugins.tickcounter; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.inject.Inject; - -import com.google.inject.Provides; -import net.runelite.api.Actor; -import net.runelite.api.Client; -import net.runelite.api.Player; -import net.runelite.api.events.AnimationChanged; -import net.runelite.api.events.ClientTick; -import net.runelite.api.events.GameTick; -import net.runelite.api.kit.KitType; -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.ui.overlay.OverlayManager; - -@PluginDescriptor(name = "!Tick Counter", - description = "Counts combat activity for nearby players", - enabledByDefault = false -) -public class TickCounterPlugin extends Plugin { - - @Inject - private OverlayManager overlayManager; - @Inject - private TickCounterConfig config; - @Inject - private Client client; - @Provides - TickCounterConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(TickCounterConfig.class); - } - @Inject - private TickCounterOverlay overlay; - - Map activity = new HashMap<>(); - - private List blowpiping = new ArrayList<>(); - boolean instanced = false; - boolean prevInstance = false; - - @Override - protected void startUp() throws Exception { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() throws Exception { - overlayManager.remove(overlay); - activity.clear(); - } - - @Subscribe - public void onAnimationChanged(AnimationChanged e) { - if (!(e.getActor() instanceof Player)) - return; - Player p = (Player) e.getActor(); - int weapon = -1; - if (p.getPlayerComposition() != null) - weapon = p.getPlayerComposition().getEquipmentId(KitType.WEAPON); - int delta = 0; - switch (p.getAnimation()) { - case 7617: // rune knife - case 8194: // dragon knife - case 8291: // dragon knife spec - case 5061: // blowpipe - if (weapon == 12926) - { - blowpiping.add(p); - } - else - { - delta = 2; - } - break; - case 2323: // rpg - case 7618: // chin - delta = 3; - break; - case 426: // bow shoot - if (weapon == 20997) // twisted bow - delta = 5; - else // shortbow - delta = 3; - break; - case 376: // dds poke - case 377: // dds slash - case 422: // punch - case 423: // kick - case 386: // lunge - case 390: // generic slash - case 1062: // dds spec - case 1067: // claw stab - case 1074: // msb spec - case 1167: // trident cast - case 1658: // whip - case 2890: // arclight spec - case 3294: // abby dagger slash - case 3297: // abby dagger poke - case 3298: // bludgeon attack - case 3299: // bludgeon spec - case 3300: // abby dagger spec - case 7514: // claw spec - case 7515: // d sword spec - case 8145: // rapier stab - case 8288: // dhl stab - case 8289: // dhl slash - case 8290: // dhl crush - delta = 4; - break; - case 393: // staff bash - if (weapon == 13652) { // claw scratch - delta = 4; - break; - } - case 395: // axe autos - case 400: // pick smash - case 1379: //burst or blitz - case 1979: // barrage spell cast - case 1162: // strike/bolt spells - case 7552: // generic crossbow - case 7855: // surge spells - case 8056: // scythe swing - delta = 5; - break; - case 401: - if (weapon == 13576) // dwh bop - delta = 6; - else // used by pickaxe and axe - delta = 5; - break; - case 1378: - case 7045: - case 7054: - case 7055: // godsword autos - case 7511: // dinh's attack - case 7516: // maul attack - case 7555: // ballista attack - case 7638: // zgs spec - case 7640: // sgs spec - case 7642: // bgs spec - case 7643: // bgs spec - case 7644: // ags spec - delta = 6; - break; - case 428: // chally swipe - case 440: // chally jab - case 1203: // chally spec - delta = 7; - break; - case -1: - blowpiping.remove(p); - break; - } - if (delta > 0) { - String name = p.getName(); - this.activity.put(name, this.activity.getOrDefault(name, 0) + delta); - } - } - - @Subscribe - public void onClientTick(ClientTick e) { - /* - * Hack for blowpipe since the AnimationChanged event doesn't fire when using a - * blowpipe because of its speed. If blowpipe animation restarts, then add 2 - */ - for (Player p : blowpiping) { - Actor rsp = p; - if (rsp.getActionFrame() == 0 && rsp.getActionFrameCycle() == 1) { - String name = p.getName(); - int activity = this.activity.getOrDefault(name, 0).intValue(); - this.activity.put(name, activity + 2); - } - } - } - @Subscribe - public void onGameTick(GameTick tick){ - if(!config.instance())return; - prevInstance = instanced; - instanced = client.isInInstancedRegion(); - if(!prevInstance && instanced){ - activity.clear(); - } - } -} 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 deleted file mode 100644 index d7cda5adff..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (c) 2018, Bryan Chau(RSN:Laura Brehm) - * 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.tobdamagecount; - -import javax.inject.Inject; -import java.text.DecimalFormat; - -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.NPC; -import net.runelite.api.NpcID; -import net.runelite.api.Skill; -import net.runelite.api.ChatMessageType; -import net.runelite.api.Actor; -import net.runelite.api.Player; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.HitsplatApplied; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.NpcDespawned; -import net.runelite.api.events.LocalPlayerDeath; -import net.runelite.client.chat.ChatColorType; -import net.runelite.client.chat.ChatMessageBuilder; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.eventbus.Subscribe; - - -@PluginDescriptor( - name = "ToB Damage Counter", - 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"}, - enabledByDefault = false -) - -public class DamageCounterPlugin extends Plugin -{ - private int currentWorld = -1; - private int DamageCount = 0; - private int currenthpxp = -1; // checking the current hp xp so be easier to find - private String BossName = null; //to ID the boss to calculate the damage - private int DamageTaken = 0; - private boolean status = true; //default boolean alive = true, dead = false - //formatting the number for damage taken and dealt with to look beeter - private static final DecimalFormat DAMAGEFORMAT = new DecimalFormat("#,###"); - private static final double XP_RATIO = 1.3333; - private static final double BOSS_MODIFIER = 1.05; - private static final int MAIDENHP = 3500; - private static final int BLOATHP = 2000; - private static final int NYLOHP = 2500; - private static final int SOTHP = 4000; - private static final int XARPUSHP = 5080; - private static final int VERZIKHP = 8500; - private static final boolean ALIVE = true; // - private static final boolean DEAD = false; //if they're dead they cannot "recreate" the message of being alive - //locations at ToB - private static final int MAIDEN_REGION = 12613; - private static final int MAIDEN_REGION_1 = 12869; - private static final int BLOAT_REGION = 13125; - private static final int NYLOCAS_REGION = 13122; - private static final int SOTETSEG_REGION = 13123; - private static final int SOTETSEG_REGION2 = 13379; - private static final int XARPUS_REGION = 12612; - private static final int VERZIK_REGION = 12611; - private static final int[] ToB_Region = {MAIDEN_REGION, MAIDEN_REGION_1, BLOAT_REGION, NYLOCAS_REGION, - SOTETSEG_REGION, SOTETSEG_REGION2, XARPUS_REGION, VERZIK_REGION}; - //setting up the array for a check list - private static int[] NPCARRAY = {NpcID.THE_MAIDEN_OF_SUGADINTI, NpcID.THE_MAIDEN_OF_SUGADINTI_8361, - NpcID.THE_MAIDEN_OF_SUGADINTI_8362, NpcID.THE_MAIDEN_OF_SUGADINTI_8363, NpcID.THE_MAIDEN_OF_SUGADINTI_8364, - NpcID.THE_MAIDEN_OF_SUGADINTI_8365, NpcID.PESTILENT_BLOAT, NpcID.NYLOCAS_VASILIAS, - NpcID.NYLOCAS_VASILIAS_8355, NpcID.NYLOCAS_VASILIAS_8356, NpcID.NYLOCAS_VASILIAS_8357, NpcID.SOTETSEG, - NpcID.SOTETSEG_8388, NpcID.XARPUS, NpcID.XARPUS_8339, NpcID.XARPUS_8340, NpcID.XARPUS_8341, - NpcID.VERZIK_VITUR, NpcID.VERZIK_VITUR_8369, NpcID.VERZIK_VITUR_8370, NpcID.VERZIK_VITUR_8371, - NpcID.VERZIK_VITUR_8372, NpcID.VERZIK_VITUR_8373, NpcID.VERZIK_VITUR_8374, NpcID.VERZIK_VITUR_8375}; - - private int[] HEALTHARRAY = {MAIDENHP, NYLOHP, VERZIKHP}; - - @Inject - private Client client; - @Inject - private ChatMessageManager chatMessangerManager; - //every game tick it will go through methods - @Subscribe - private void onGameTick(GameTick tick) - { - if (client.getGameState() != GameState.LOGGED_IN) - { - ResetCounter(); - return; - } - checkInterAction(); - DamageCounting(); - currenthpxp = client.getSkillExperience(Skill.HITPOINTS); - } - //checks for npcID and put the boss name into a string be easier to ID it - //once the boss is found it will never check it - private void checkInterAction() - { - Player localPlayer = client.getLocalPlayer(); - Actor interacting = localPlayer.getInteracting(); - if (client.getGameState() == GameState.LOGGED_IN) - { - if (BossName == null) - { - if (interacting instanceof NPC) - { - int interactingId = ((NPC) interacting).getId(); - String interactingName = interacting.getName(); - for (int aNPCARRAY : NPCARRAY) - { - if (aNPCARRAY == interactingId) - { - BossName = interactingName; - } - } - } - } - } - } - - @Subscribe - //if you hop it will reset the counter - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - { - if (currentWorld == -1) - { - currentWorld = client.getWorld(); - } - else if (currentWorld != client.getWorld()) - { - currentWorld = client.getWorld(); - ResetCounter(); - } - } - } - - //grabbing the xp and calculating the damage - private int XPtoDamage() - { - int NewXp; - double damageOutput = 0; - int XPdrop; - if (currenthpxp != -1) - { - XPdrop = client.getSkillExperience(Skill.HITPOINTS); - NewXp = XPdrop - currenthpxp; - currenthpxp = -1; - damageOutput = NewXp / XP_RATIO; - } - //returns the damage you have done - return (int) Math.floor(damageOutput); - } - - //adding up the damage for the print message checks every tick(aka attack tick) - private void DamageCounting() - { - Player localPlayer = client.getLocalPlayer(); - Actor interacting = localPlayer.getInteracting(); - if (client.getGameState() == GameState.LOGGED_IN) - { - if (interacting instanceof NPC) - { - String interactingName = interacting.getName(); - int NPC = ((NPC) interacting).getId(); - if (interactingName.equals(BossName)) - { - DamageCount += (XPtoDamage() * BOSS_MODIFIER); - - } - } - } - } - - - @Subscribe - //will add the damage that you have taken from the current boss fight - private void onHitsplatApplied(HitsplatApplied Hit) - { - if (Hit.getActor().equals(client.getLocalPlayer())) - { - DamageTaken += Hit.getHitsplat().getAmount(); - } - - } - - //will check for the monster if it died works only on ToB Bosses - /*Verzik has three phases so the program will add up all the damage and prints it into one message - because every time she phases she "dies" so making sure the counter doesn't print out the damage for phase 1, 2, - and 3. - */ - @Subscribe - public void onNpcDespawned(NpcDespawned npc) - { - NPC actor = npc.getNpc(); - double Percent = calculatePercent(WorldPoint.fromLocalInstance(client, - client.getLocalPlayer().getLocalLocation()).getRegionID()); - if (actor.isDead() && actor.getId() == NpcID.VERZIK_VITUR_8375 && status) - { - DamagePrint(actor, Percent); - ResetCounter(); - } - else if (actor.isDead() && actor.getName().equals(BossName) && actor.getId() != NpcID.VERZIK_VITUR_8374 && - actor.getId() != NpcID.VERZIK_VITUR_8372 && actor.getId() != NpcID.VERZIK_VITUR_8370 && - status) - { - DamagePrint(actor, Percent); - ResetCounter(); - } - //will reset the counter after the boss dies and if you died during the fight - else if (actor.isDead() && actor.getName().equals(BossName) && !status) - { - ResetCounter(); - } - } - - private double calculatePercent(int id) - { - double percent = 0; - if (DamageCount != 0) { - if (id == MAIDEN_REGION || id == MAIDEN_REGION_1) - { - percent = (DamageCount / (double) MAIDENHP) * 100; - } - else if (id == BLOAT_REGION) - { - percent = (DamageCount / (double) BLOATHP) * 100; - } - else if (id == NYLOCAS_REGION) - { - percent = (DamageCount / (double) NYLOHP) * 100; - } - else if (id == SOTETSEG_REGION || id == SOTETSEG_REGION2) - { - percent = (DamageCount / (double) SOTHP) * 100; - } - else if (id == XARPUS_REGION) - { - percent = (DamageCount / (double) XARPUSHP) * 100; - } - else if (id == VERZIK_REGION) - { - percent = (DamageCount / (double) VERZIKHP) * 100; - } - } - return percent; - } - - //just reset the counter for the next fight and status - private void ResetCounter() - { - DamageCount = 0; - DamageTaken = 0; - BossName = null; - status = ALIVE; - } - - //print out the damage after the boss have died - //prevent people from spectating to get the damage message, it is impossible for them to get damage - private void DamagePrint(NPC actor, double percent) - { - String MessageDamage; - if (percent >= 50) - { - MessageDamage = "Well done carrying the team!" + - "WOWIE!! You did" + DAMAGEFORMAT.format(DamageCount) + " damage to " + - actor.getName() + "! You did %" + String.format("%.2f", percent) + " of the damage"; - } - else if (percent >= 25) - { - MessageDamage = "Well done carrying some dead weight in your team! " + - "Awesome! You did " + DAMAGEFORMAT.format(DamageCount) + " damage to " + - actor.getName() + "! You did %" + String.format("%.2f", percent) + " of the damage"; - } - else if (percent >= 1) - { - MessageDamage = "Well done everyone is pulling their weight! " + - "You did " + DAMAGEFORMAT.format(DamageCount) + " damage to " + - actor.getName() + "! You did %" + String.format("%.2f", percent) + " of the damage"; - } - else - { - MessageDamage = "Didn't do much" + - "Fucking leech did " + DAMAGEFORMAT.format(DamageCount) + " damage to " + - actor.getName() + "! You did %" + String.format("%.2f", percent) + " of the damage"; - } - - sendChatMessage(MessageDamage); - String MessageTaken = "You have taken " + DAMAGEFORMAT.format(DamageTaken) + " damage from this fight!"; - sendChatMessage(MessageTaken); - } - - @Subscribe - //whenever you have died in tob you will get a death message with damage - // made sure the message works at ToB area or else it will message every where - private void onLocalPlayerDeath(LocalPlayerDeath death) - { - String DeathMessage = "You have died! You did " + DAMAGEFORMAT.format(DamageCount) + " damage to " + - BossName + "!"; - String MessageTaken = "You have taken " + DAMAGEFORMAT.format(DamageTaken) + " damage from this fight!"; - for (int i = 0; i < ToB_Region.length; i++) - { - if (WorldPoint.fromLocalInstance(client, - client.getLocalPlayer().getLocalLocation()).getRegionID() == ToB_Region[i]) - { - sendChatMessage(DeathMessage); - sendChatMessage(MessageTaken); - ResetCounter(); - //status will become "dead" after you died in the fight - status = DEAD; - } - } - } - - //sends a message saying this "You have done XYZ damage to boss name! or the death message - // "Well done! you have done your best, you have done XYZ damage to boss name - private void sendChatMessage(String chatMessage) - { - final String message = new ChatMessageBuilder() - .append(ChatColorType.HIGHLIGHT) - .append(chatMessage) - .build(); - chatMessangerManager.queue( - QueuedMessage.builder() - .type(ChatMessageType.CONSOLE) - .runeLiteFormattedMessage(message) - .build()); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionConfig.java deleted file mode 100644 index b97e73b318..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2019, Frosty Fridge - * 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.vetion; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("vetion") -public interface VetionConfig extends Config -{ - @ConfigItem( - keyName = "earthquakeTimerActive", - name = "Vet'ion Earthquake Timer", - description = "Configures whether or not a timer is shown to track the cooldown of Vet'ion's earthquake attack", - position = 0 - ) - default boolean eartquakeTimerActive() - { - return true; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionOverlay.java deleted file mode 100644 index dcc51b0929..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionOverlay.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2019, Frosty Fridge - * 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.vetion; - -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.ProgressPieComponent; - -import javax.inject.Inject; -import java.awt.*; -import java.time.Duration; -import java.time.Instant; - -public class VetionOverlay extends Overlay{ - - private static final Color RED_ALPHA = new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue(), 100); - private static final Duration MAX_TIME = Duration.ofSeconds(9); - private final VetionPlugin plugin; - private Client client; - - @Inject - private VetionOverlay(Client client, VetionPlugin plugin) - { - this.plugin = plugin; - this.client = client; - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - } - - @Override - public Dimension render(Graphics2D graphics) - { - plugin.getVetions().forEach((actor, timer) -> - { - LocalPoint localPos = actor.getLocalLocation(); - if (localPos != null) - { - Point position = Perspective.localToCanvas(client, localPos, client.getPlane(), - actor.getLogicalHeight() + 96); - if (position != null) - { - position = new Point(position.getX(), position.getY()); - - final ProgressPieComponent progressPie = new ProgressPieComponent(); - progressPie.setDiameter(30); - progressPie.setFill(RED_ALPHA); - progressPie.setBorderColor(Color.RED); - progressPie.setPosition(position); - - final Duration duration = Duration.between(timer, Instant.now()); - progressPie.setProgress(1 - (duration.compareTo(MAX_TIME) < 0 - ? (double) duration.toMillis() / MAX_TIME.toMillis() - : 1)); - - progressPie.render(graphics); - if (1 - duration.compareTo(MAX_TIME) < 0) - { - plugin.getVetions().remove(actor); - } - } - } - }); - - return null; - } -} \ No newline at end of file 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 deleted file mode 100644 index 9df9a4fa57..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2019, Frosty Fridge - * 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.vetion; - -import com.google.inject.Provides; -import lombok.Getter; -import net.runelite.api.*; -import net.runelite.api.events.AnimationChanged; -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.ui.overlay.OverlayManager; - -import javax.inject.Inject; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; - -@PluginDescriptor( - name = "!Vetion", - description = "Tracks Vet'ion's special attacks", - tags = {"bosses", "combat", "pve", "overlay"} -) -public class VetionPlugin extends Plugin { - - @Inject - private Client client; - - @Inject - private VetionConfig config; - - @Inject - private OverlayManager overlayManager; - - @Inject - private VetionOverlay overlay; - - @Getter - private Map vetions; - - @Provides - VetionConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(VetionConfig.class); - } - - @Override - protected void startUp() - { - vetions = new HashMap<>(); - overlayManager.add(overlay); - } - - @Override - protected void shutDown() - { - overlayManager.remove(overlay); - vetions = null; - } - - - @Subscribe - public void onAnimationChanged(AnimationChanged event) - { - if (config.eartquakeTimerActive() && event.getActor().getAnimation() == AnimationID.VETION_EARTHQUAKE) - { - Actor vet = event.getActor(); - vetions.remove(vet, Instant.now()); - vetions.put(vet, Instant.now()); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/TileHighlight.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/TileHighlight.java deleted file mode 100644 index c6e5623450..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/TileHighlight.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.runelite.client.plugins.vorkath; - -public enum TileHighlight -{ - None, - Single, - All -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java deleted file mode 100644 index 927b9b1997..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.runelite.client.plugins.vorkath; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -import java.awt.*; - -@ConfigGroup("vorkath") -public interface VorkathConfig extends Config { - @ConfigItem( - position = 0, - keyName = "Vorkathenable", - name = "Enable Vorkath Helper", - description = "Configures whether or not to enable Vorkath Helper." - ) - default boolean EnableVorkath() { return true; } - - @ConfigItem( - position = 1, - keyName = "countercolor", - name = "Indicator color", - description = "Configures color of text displaying Vorkath hits left to special attack." - ) - default Color CounterColor() { return Color.YELLOW; } - - @ConfigItem( - position = 2, - keyName = "countersize", - name = "Bold indicator", - description = "Configures if text indicator is bold or not." - ) - default boolean BoldText() { return true; } - - @ConfigItem( - position = 3, - keyName = "enumConfig", - name = "Fireball Tile Highlight", - description = "Select how to apply tile highlighting for Vorkath's fireball attack" - ) - default TileHighlight TileHighlight() { return TileHighlight.All; } - - @ConfigItem( - position = 4, - keyName = "overlayindicators", - name = "Overlay Indicators", - description = "Configures if an overlay box displaying vorkath information should be displayed." - ) - default boolean VorkathBox() { return false; } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathIndicatorOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathIndicatorOverlay.java deleted file mode 100644 index 77403dab97..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathIndicatorOverlay.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.runelite.client.plugins.vorkath; - -import java.awt.*; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldArea; -import net.runelite.client.ui.FontManager; -import net.runelite.client.ui.overlay.*; -import net.runelite.client.ui.overlay.components.LineComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; - -public class VorkathIndicatorOverlay extends Overlay { - private final VorkathConfig config; - private final VorkathPlugin plugin; - private final PanelComponent panelComponent = new PanelComponent(); - - - @Inject - private Client client; - - @Inject - private VorkathIndicatorOverlay(VorkathConfig config, VorkathPlugin plugin) { - this.config = config; - this.plugin = plugin; - setPosition(OverlayPosition.BOTTOM_RIGHT); - setPriority(OverlayPriority.MED); - panelComponent.setPreferredSize(new Dimension(150, 0)); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (!config.EnableVorkath()) { - return null; - } - - NPC Vorkath = plugin.Vorkath; - if (Vorkath != null) { - if (config.VorkathBox()) { - panelComponent.getChildren().clear(); - if (plugin.venomticks != 0) { - if (plugin.venomticks + 5 <= plugin.ticks) { - panelComponent.getChildren().add(LineComponent.builder().left("Quickfire Barrage:").right(Integer.toString(30 - (plugin.ticks - plugin.venomticks))).rightColor(Color.ORANGE).build()); - } - } - panelComponent.getChildren().add(LineComponent.builder().left("Special Attack:").right(Integer.toString(7 - plugin.hits)).rightColor(config.CounterColor()).build()); - return panelComponent.render(graphics); - } - } - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java deleted file mode 100644 index 0773141574..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.runelite.client.plugins.vorkath; - -import java.awt.*; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldArea; -import net.runelite.client.ui.FontManager; -import net.runelite.client.ui.overlay.*; -import net.runelite.client.ui.overlay.components.PanelComponent; - -public class VorkathOverlay extends Overlay { - private final VorkathConfig config; - private final VorkathPlugin plugin; - private final PanelComponent panelComponent = new PanelComponent(); - - - @Inject - private Client client; - - @Inject - private VorkathOverlay(VorkathConfig config, VorkathPlugin plugin) { - this.config = config; - this.plugin = plugin; - setLayer(OverlayLayer.ABOVE_SCENE); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.MED); - panelComponent.setPreferredSize(new Dimension(150, 0)); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (!config.EnableVorkath()) { - return null; - } - Actor local = client.getLocalPlayer(); - - WorldArea area = local.getWorldArea(); - if (area == null) - { - return null; - } - - NPC Vorkath = plugin.Vorkath; - if (Vorkath != null) { - if (plugin.fireball != null) { - if (config.TileHighlight() == TileHighlight.Single) { - final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.fireball); - if (poly != null) { - OverlayUtil.renderPolygon(graphics, poly, Color.RED); - } - } else if (config.TileHighlight() == TileHighlight.All) { - for (int dx = -1; dx <= 1; dx++) { - for (int dy = -1; dy <= 1; dy++) { - if (dx == 0 && dy == 0) { - continue; - } - LocalPoint lp = new LocalPoint(plugin.fireball.getX() + dx * Perspective.LOCAL_TILE_SIZE + dx * Perspective.LOCAL_TILE_SIZE * (area.getWidth() - 1) / 2, plugin.fireball.getY() + dy * Perspective.LOCAL_TILE_SIZE + dy * Perspective.LOCAL_TILE_SIZE * (area.getHeight() - 1) / 2); - Polygon polyadj = Perspective.getCanvasTilePoly(client, lp); - if (polyadj != null) { - OverlayUtil.renderPolygon(graphics, polyadj, Color.ORANGE); - } - } - } - } - } - - if (config.BoldText()) { - graphics.setFont(FontManager.getRunescapeBoldFont()); - } - - if (plugin.venomticks != 0) { - if (plugin.venomticks + 5 <= plugin.ticks) { - OverlayUtil.renderTextLocation(graphics, Vorkath.getCanvasTextLocation(graphics, Integer.toString(30 - (plugin.ticks - plugin.venomticks)), Vorkath.getLogicalHeight() + 150), Integer.toString(30 - (plugin.ticks - plugin.venomticks)), Color.ORANGE); - } - } - - OverlayUtil.renderTextLocation(graphics, Vorkath.getCanvasTextLocation(graphics, Integer.toString(7 - plugin.hits), Vorkath.getLogicalHeight() + 40), Integer.toString(7 - plugin.hits), config.CounterColor()); - graphics.setFont(FontManager.getRunescapeFont()); - } - return null; - } -} 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 deleted file mode 100644 index 1ba5e4b0e7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java +++ /dev/null @@ -1,157 +0,0 @@ -package net.runelite.client.plugins.vorkath; - -import net.runelite.api.events.*; -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import javax.inject.Inject; -import net.runelite.api.*; -import net.runelite.api.coords.LocalPoint; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; -import org.apache.commons.lang3.ArrayUtils; - -@PluginDescriptor( - name = "!Vorkath", - description = "Vorkath Helper", - tags = {"Vorkath", "Helper"} -) -public class VorkathPlugin extends Plugin -{ - @Inject - private OverlayManager overlayManager; - - @Inject - private VorkathConfig config; - - @Inject - private VorkathOverlay VorkathOverlay; - - @Inject - private VorkathIndicatorOverlay VorkathIndicatorOverlay; - - @Inject - private Client client; - - @Inject - private SpriteManager spriteManager; - - @Provides - VorkathConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(VorkathConfig.class); - } - - NPC Vorkath; - int hits; - int ticks; - Boolean ice = false; - LocalPoint fireball; - int fireballticks = 0; - int lastattack; - int venomticks; - - int[] VorkathIDs = {393, 395, 1470, 1471, 1477, 1479}; - - @Override - protected void startUp() throws Exception { - overlayManager.add(VorkathOverlay); - overlayManager.add(VorkathIndicatorOverlay); - } - - @Override - protected void shutDown() throws Exception { - overlayManager.remove(VorkathOverlay); - overlayManager.remove(VorkathIndicatorOverlay); - Vorkath = null; - hits = 0; - fireball = null; - fireballticks = 0; - ice = false; - lastattack = 0; - } - - @Subscribe - public void onGameTick(GameTick event) { - if (!config.EnableVorkath()) { - return; - } - ticks++; - if (ticks - fireballticks > 5) { - fireballticks = 0; - fireball = null; - } - - if (venomticks + 30 <= ticks) { - venomticks = 0; - } - - boolean foundVorkath = false; - for (NPC monster : client.getNpcs()) - { - if (monster == null || monster.getName() == null || monster.getCombatLevel() == 0) - { - continue; - } - if (monster.getName().equalsIgnoreCase("Vorkath")) { - foundVorkath = true; - Vorkath = monster; - break; - } - } - if (!foundVorkath) { - Vorkath = null; - hits = 0; - fireball = null; - fireballticks = 0; - ice = false; - lastattack = 0; - } - } - - @Subscribe - public void onProjectileMoved(ProjectileMoved event) { - if (Vorkath != null) { - Projectile ball = event.getProjectile(); - if (ArrayUtils.contains(VorkathIDs, ball.getId())) { - if (ticks - lastattack > 4) { - if (ball.getId() == 395) { - ice = true; - } - hits++; - lastattack = ticks; - if (hits == 7) { - hits = 0; - } - } - } - } - } - - @Subscribe - public void onAnimationChanged(AnimationChanged event) { - Actor vorki = event.getActor(); - Actor local = client.getLocalPlayer(); - if (vorki instanceof NPC) { - if (vorki.equals(Vorkath)) { - if (vorki.getAnimation() != -1 && vorki.getAnimation() != 7948 && vorki.getAnimation() != 7952) { - if (ice) { - ice = false; - } else { - hits++; - if (hits == 7) { - venomticks = ticks; - hits = 0; - } - if (vorki.getAnimation() == 7960) { - fireball = local.getLocalLocation(); - fireballticks = ticks; - } - } - } - - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java deleted file mode 100644 index c665baaa70..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2018, Andrew EP | ElPinche256 - * 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.warindicators; - -import java.awt.Color; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("warIndicators") - -public interface WarIndicatorConfig extends Config -{ - @ConfigItem( - position = 0, - keyName = "highLightCallers", - name = "Highlight Callers", - description = "Highlight listed caller(s)" - ) - default boolean highLightCallers() - { - return true; - } - - @ConfigItem( - position = 1, - keyName = "callerColor", - name = "Caller(s) Color", - description = "Color to highlight caller's name" - ) - default Color getCallerColor() - { - return new Color(36, 255, 237); - } - - @ConfigItem( - position = 2, - keyName = "callerMinimap", - name = "Callers on Minimap", - description = "Show your caller(s) on the minimap" - ) - default boolean callerMinimap() - { - return false; - } - - - @ConfigItem( - position = 3, - keyName = "callerTile", - name = "Show Caller's Tile", - description = "Show the tile your target is standing on" - ) - default boolean callerTile() - { - return false; - } - - @ConfigItem( - position = 4, - keyName = "activeCallers", - name = "Callers", - description = "Adds a user to your caller list. Format: (caller), (caller)" - ) - default String getActiveCallers() - { - return ""; - } - - @ConfigItem( - position = 5, - keyName = "activeCallers", - name = "", - description = "" - ) - void setActiveCallers(String key); - - - @ConfigItem( - position = 6, - keyName = "highlightSnipes", - name = "Highlight Targets", - description = "Highlight listed target(s)" - ) - default boolean highlightSnipes() - { - return true; - } - - @ConfigItem( - position = 7, - keyName = "snipeColor", - name = "Target(s) Color", - description = "Color to highlight target name" - ) - default Color getSnipeColor() - { - return new Color(255, 0, 0); - } - - @ConfigItem( - position = 8, - keyName = "snipeMinimap", - name = "Targets on Minimap", - description = "Show your target on the minimap" - ) - default boolean snipeMinimap() - { - return false; - } - - @ConfigItem( - position = 9, - keyName = "snipeTile", - name = "Show Target's Tile", - description = "Show the tile your target is standing on" - ) - default boolean snipeTile() - { - return false; - } - - @ConfigItem( - position = 10, - keyName = "targetedSnipes", - name = "Targets", - description = "Adds a user to your snipe list. Format: (target), (target)" - ) - default String getTargetedSnipes() - { - return ""; - } - - @ConfigItem( - position = 11, - keyName = "targetedSnipes", - name = "", - description = "" - ) - - void setTargetedSnipe(String key); -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java deleted file mode 100644 index d7fa0cc92a..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2018, Andrew EP | ElPinche256 - * 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.warindicators; - -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; -import org.apache.commons.lang3.ArrayUtils; - -@Singleton -public class WarIndicatorMiniMapOverlay extends Overlay -{ - private final WarIndicatorService warIndicatorService; - private final WarIndicatorConfig config; - - @Inject - private WarIndicatorMiniMapOverlay(WarIndicatorConfig config, WarIndicatorService warIndicatorService) - { - this.config = config; - this.warIndicatorService = warIndicatorService; - setLayer(OverlayLayer.ABOVE_WIDGETS); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGH); - } - - @Override - public Dimension render(Graphics2D graphics) - { - warIndicatorService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); - return null; - } - - private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) - { - final String name = actor.getName().replace('\u00A0', ' '); - final net.runelite.api.Point minimapLocation = actor.getMinimapLocation(); - - String[] callers = config.getActiveCallers().split(", "); - String[] targets = config.getTargetedSnipes().split(", "); - - if (config.callerMinimap() && ArrayUtils.contains(callers, actor.getName())) - { - if (minimapLocation != null) - { - OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); - } - } - - if (config.snipeMinimap() && ArrayUtils.contains(targets, actor.getName())) - { - if (minimapLocation != null) - { - OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); - } - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java deleted file mode 100644 index 7ca7cc20c0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2018, Andrew EP | ElPinche256 - * 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.warindicators; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; -import javax.inject.Inject; -import javax.inject.Singleton; -import org.apache.commons.lang3.ArrayUtils; -import net.runelite.api.Player; -import net.runelite.api.Point; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.OverlayUtil; - -@Singleton -public class WarIndicatorOverlay extends Overlay -{ - private final WarIndicatorService warIndicatorService; - private final WarIndicatorConfig config; - - @Inject - private WarIndicatorOverlay(WarIndicatorConfig config, WarIndicatorService warIndicatorService) - { - this.config = config; - this.warIndicatorService = warIndicatorService; - setLayer(OverlayLayer.ABOVE_SCENE); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGH); - } - - @Override - public Dimension render(Graphics2D graphics) - { - warIndicatorService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); - return null; - } - - private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) - { - if (!config.highlightSnipes() && !config.highLightCallers()) - { - return; - } - - Polygon poly = actor.getCanvasTilePoly(); - String[] callers = config.getActiveCallers().split(", "); - String[] targets = config.getTargetedSnipes().split(", "); - - if (config.callerTile() && ArrayUtils.contains(callers, actor.getName())) - { - if (poly != null) - { - OverlayUtil.renderPolygon(graphics, poly, color); - } - } - - if (config.snipeTile() && ArrayUtils.contains(targets, actor.getName())) - { - if (poly != null) - { - OverlayUtil.renderPolygon(graphics, poly, color); - } - } - - String name = actor.getName().replace('\u00A0', ' '); - int offset = actor.getLogicalHeight() + 40; - Point textLocation = actor.getCanvasTextLocation(graphics, name, offset); - - if (textLocation != null) - { - OverlayUtil.renderTextLocation(graphics, textLocation, name, color); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java deleted file mode 100644 index af7cf94ab7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2018, Andrew EP | ElPinche256 - * 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.warindicators; - -import com.google.common.collect.Sets; -import com.google.common.eventbus.Subscribe; -import com.google.inject.Provides; -import java.awt.Color; -import java.util.Collection; -import javax.inject.Inject; -import org.apache.commons.lang3.ArrayUtils; -import net.runelite.api.Client; -import static net.runelite.api.MenuAction.FOLLOW; -import static net.runelite.api.MenuAction.ITEM_USE_ON_PLAYER; -import static net.runelite.api.MenuAction.PLAYER_EIGTH_OPTION; -import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION; -import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION; -import static net.runelite.api.MenuAction.PLAYER_FOURTH_OPTION; -import static net.runelite.api.MenuAction.PLAYER_SECOND_OPTION; -import static net.runelite.api.MenuAction.PLAYER_SEVENTH_OPTION; -import static net.runelite.api.MenuAction.PLAYER_SIXTH_OPTION; -import static net.runelite.api.MenuAction.PLAYER_THIRD_OPTION; -import static net.runelite.api.MenuAction.SPELL_CAST_ON_PLAYER; -import static net.runelite.api.MenuAction.TRADE; -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.Overlay; -import net.runelite.client.ui.overlay.OverlayManager; - -@PluginDescriptor( - name = "!War", - description = "War War War.", - tags = {"skill", "total", "max", "PVP"}, - enabledByDefault = false -) -public class WarIndicatorPlugin extends Plugin -{ - @Inject - private OverlayManager overlayManager; - - @Inject - private WarIndicatorConfig config; - - @Inject - private WarIndicatorOverlay warIndicatorOverlay; - - @Inject - private WarIndicatorMiniMapOverlay warIndicatorMiniMapOverlay; - - @Inject - private Client client; - - @Provides - WarIndicatorConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(WarIndicatorConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(warIndicatorOverlay); - overlayManager.add(warIndicatorMiniMapOverlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(warIndicatorOverlay); - overlayManager.remove(warIndicatorMiniMapOverlay); - } - - @Subscribe - public void onMenuEntryAdd(MenuEntryAdded menuEntryAdded) - { - int type = menuEntryAdded.getType(); - - if (type >= 2000) - { - type -= 2000; - } - - int identifier = menuEntryAdded.getIdentifier(); - if (type == FOLLOW.getId() || type == TRADE.getId() - || type == SPELL_CAST_ON_PLAYER.getId() - || type == ITEM_USE_ON_PLAYER.getId() - || type == PLAYER_FIRST_OPTION.getId() - || type == PLAYER_SECOND_OPTION.getId() - || type == PLAYER_THIRD_OPTION.getId() - || type == PLAYER_FOURTH_OPTION.getId() - || type == PLAYER_FIFTH_OPTION.getId() - || type == PLAYER_SIXTH_OPTION.getId() - || type == PLAYER_SEVENTH_OPTION.getId() - || type == PLAYER_EIGTH_OPTION.getId()) - { - Player[] players = client.getCachedPlayers(); - Player player = null; - String player2 = null; - - String[] callers = config.getActiveCallers().split(", "); - String[] targets = config.getTargetedSnipes().split(", "); - - if (identifier >= 0 && identifier < players.length) - { - player = players[identifier]; - player2 = players[identifier].getName(); - } - - if (player == null) - { - return; - } - - Color color = null; - - if (config.highLightCallers() && ArrayUtils.contains(callers, player2)) - { - color = config.getCallerColor(); - } - - if (config.highlightSnipes() && ArrayUtils.contains(targets, player2)) - { - color = config.getSnipeColor(); - } - - if (color != null) - { - MenuEntry[] menuEntries = client.getMenuEntries(); - MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; - String target = lastEntry.getTarget(); - - int idx = target.indexOf('>'); - if (idx != -1) - { - target = target.substring(idx + 1); - } - - lastEntry.setTarget("" + target); - client.setMenuEntries(menuEntries); - } - - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java deleted file mode 100644 index cb6c8127b5..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2018, Andrew EP | ElPinche256 - * 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.warindicators; - -import net.runelite.api.Client; -import net.runelite.api.Player; -import javax.inject.Inject; -import javax.inject.Singleton; -import java.awt.*; -import java.util.function.BiConsumer; - -@Singleton -public class WarIndicatorService -{ - private final Client client; - private final WarIndicatorConfig config; - - @Inject - private WarIndicatorService(Client client, WarIndicatorConfig config) - { - this.config = config; - this.client = client; - } - - public void forEachPlayer(final BiConsumer consumer) - { - if (!config.highlightSnipes() && !config.highLightCallers()) - { - return; - } - - if (config.highlightSnipes()) - { - for (Player player : client.getPlayers()) - { - if (player == null || player.getName() == null) - { - continue; - } - - String[] targets = config.getTargetedSnipes().split(", "); - - if (targets == null) - { - return; - } - - for (int i = 0; i < targets.length; i++) - { - if (player.getName().equalsIgnoreCase(targets[i])) - { - consumer.accept(player, config.getSnipeColor()); - } - } - } - } - - if (config.highLightCallers()) - { - for (Player player : client.getPlayers()) - { - if (player == null || player.getName() == null) - { - continue; - } - - String[] callers = config.getActiveCallers().split(", "); - - if (callers == null) - { - return; - } - - for (int i = 0; i < callers.length; i++) - { - if (player.getName().equalsIgnoreCase(callers[i])) - { - consumer.accept(player, config.getCallerColor()); - } - } - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java deleted file mode 100644 index 69668fcbd6..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java +++ /dev/null @@ -1,38 +0,0 @@ - -package net.runelite.client.plugins.wildernesslocations; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.client.plugins.wildernesslocations.WildernessLocationsPlugin; -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.components.TextComponent; - -public class WildernessLocationsOverlay -extends Overlay { - private final WildernessLocationsPlugin plugin; - private TextComponent textComponent; - - @Inject - public WildernessLocationsOverlay(Client client, WildernessLocationsPlugin plugin) { - this.plugin = plugin; - setLayer(OverlayLayer.ABOVE_WIDGETS); - setPriority(OverlayPriority.HIGH); - setPosition(OverlayPosition.BOTTOM_RIGHT); - textComponent = new TextComponent(); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (plugin.isRenderLocation()) { - textComponent.setText(plugin.getLocationString()); - return textComponent.render(graphics); - } - return null; - } -} - 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 deleted file mode 100644 index 0020f384f4..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java +++ /dev/null @@ -1,127 +0,0 @@ - -package net.runelite.client.plugins.wildernesslocations; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.Consumer; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.Player; -import net.runelite.api.Varbits; -import net.runelite.api.coords.WorldArea; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.GameTick; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.wildernesslocations.WildernessLocationsOverlay; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayManager; -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"}) - -public class WildernessLocationsPlugin extends Plugin { - @Inject - private Client client; - @Inject - OverlayManager overlayManager; - @Inject - private WildernessLocationsOverlay overlay; - private final HashMap wildLocs; - private boolean renderLocation; - private String locationString; - private WorldPoint worldPoint; - private static int UPDATE_INTERVAL = 3; - - public WildernessLocationsPlugin() { - overlay = new WildernessLocationsOverlay(client, this); - wildLocs = WildernessLocationsPlugin.getLocationMap(); - locationString = ""; - worldPoint = null; - } - - @Override - protected void startUp() throws Exception { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() throws Exception { - overlayManager.add(overlay); - } - - @Subscribe - public void onGameTick(GameTick event) { - if (UPDATE_INTERVAL > 0) { - --UPDATE_INTERVAL; - return; - } - boolean bl = renderLocation = client.getVar(Varbits.IN_WILDERNESS) == 1; - if (renderLocation) { - if (client.getLocalPlayer().getWorldLocation() != worldPoint) { - locationString = location(); - worldPoint = client.getLocalPlayer().getWorldLocation(); - } - } else { - worldPoint = null; - locationString = ""; - } - UPDATE_INTERVAL = 3; - } - - private String location() { - int dist = 10000; - String s = ""; - WorldArea closestArea = null; - for (Map.Entry entry : wildLocs.entrySet()) { - WorldArea worldArea = entry.getKey(); - if (worldArea.toWorldPointList().contains(client.getLocalPlayer().getWorldLocation())) { - s = entry.getValue(); - return s; - } - int distTo = worldArea.distanceTo(client.getLocalPlayer().getWorldLocation()); - if (distTo >= dist) continue; - dist = distTo; - closestArea = worldArea; - } - if (client.getLocalPlayer().getWorldLocation().getY() > ((WorldArea)Objects.requireNonNull(closestArea)).toWorldPoint().getY() + closestArea.getHeight()) { - s = s + "N"; - } - if (client.getLocalPlayer().getWorldLocation().getY() < closestArea.toWorldPoint().getY()) { - s = s + "S"; - } - if (client.getLocalPlayer().getWorldLocation().getX() < closestArea.toWorldPoint().getX()) { - s = s + "W"; - } - if (client.getLocalPlayer().getWorldLocation().getX() > closestArea.toWorldPoint().getX() + closestArea.getWidth()) { - s = s + "E"; - } - s = s + " of "; - if ((s = s + wildLocs.get(closestArea)).startsWith(" of ")) { - s = s.substring(3); - } - return s; - } - - private static HashMap getLocationMap() { - HashMap hashMap = new HashMap(); - Arrays.stream(WildernessLocation.values()).forEach(wildernessLocation -> hashMap.put(wildernessLocation.getWorldArea(), wildernessLocation.getName())); - return hashMap; - } - - public boolean isRenderLocation() { - return renderLocation; - } - - public String getLocationString() { - return locationString; - } -} - 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 1a3e1cba4f..c1d9e9fb88 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 @@ -27,141 +27,140 @@ package net.runelite.client.plugins.worldmap; import lombok.Getter; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.Quest; enum QuestStartLocation { //Free Quests - COOKS_ASSISTANT_RFD(Quest.COOKS_ASSISTANT, new WorldPoint(3211, 3216, 0)), - THE_CORSAIR_CURSE(Quest.THE_CORSAIR_CURSE, new WorldPoint(3029, 3273, 0)), - DEMON_SLAYER(Quest.DEMON_SLAYER, new WorldPoint(3204, 3424, 0)), - DORICS_QUEST(Quest.DORICS_QUEST, new WorldPoint(2952, 3450, 0)), - DRAGON_SLAYER(Quest.DRAGON_SLAYER, new WorldPoint(3190, 3362, 0)), - ERNEST_THE_CHICKEN(Quest.ERNEST_THE_CHICKEN, new WorldPoint(3109, 3330, 0)), - GOBLIN_DIPLOMACY(Quest.GOBLIN_DIPLOMACY, new WorldPoint(2957, 3509, 0)), - IMP_CATCHER(Quest.IMP_CATCHER, new WorldPoint(3108, 3160, 0)), - THE_KNIGHTS_SWORD(Quest.THE_KNIGHTS_SWORD, new WorldPoint(2976, 3342, 0)), - MISTHALIN_MYSTERY(Quest.MISTHALIN_MYSTERY, new WorldPoint(3234, 3155, 0)), - PIRATES_TREASURE(Quest.PIRATES_TREASURE, new WorldPoint(3051, 3252, 0)), - PRINCE_ALI_RESCUE(Quest.PRINCE_ALI_RESCUE, new WorldPoint(3301, 3163, 0)), - THE_RESTLESS_GHOST(Quest.THE_RESTLESS_GHOST, new WorldPoint(3240, 3210, 0)), - RUNE_MYSTERIES(Quest.RUNE_MYSTERIES, new WorldPoint(3210, 3220, 0)), - SHEEP_SHEARER(Quest.SHEEP_SHEARER, new WorldPoint(3190, 3272, 0)), - SHIELD_OF_ARRAV(Quest.SHIELD_OF_ARRAV, new WorldPoint(3208, 3495, 0)), - VAMPIRE_SLAYER(Quest.VAMPIRE_SLAYER, new WorldPoint(3096, 3266, 0)), - WITCHS_POTION(Quest.WITCHS_POTION, new WorldPoint(2967, 3203, 0)), + COOKS_ASSISTANT_RFD("Cook's Assistant", new WorldPoint(3211, 3216, 0)), + THE_CORSAIR_CURSE("The Corsair Curse", new WorldPoint(3029, 3273, 0)), + DEMON_SLAYER("Demon Slayer", new WorldPoint(3204, 3424, 0)), + DORICS_QUEST("Doric's Quest", new WorldPoint(2952, 3450, 0)), + DRAGON_SLAYER("Dragon Slayer", new WorldPoint(3190, 3362, 0)), + ERNEST_THE_CHICKEN("Ernest the Chicken", new WorldPoint(3109, 3330, 0)), + GOBLIN_DIPLOMACY("Goblin Diplomacy", new WorldPoint(2957, 3509, 0)), + IMP_CATCHER("Imp Catcher", new WorldPoint(3108, 3160, 0)), + THE_KNIGHTS_SWORD("The Knight's Sword", new WorldPoint(2976, 3342, 0)), + MISTHALIN_MYSTERY("Misthalin Mystery", new WorldPoint(3234, 3155, 0)), + PIRATES_TREASURE("Pirate's Treasure", new WorldPoint(3050, 3248, 0)), + PRINCE_ALI_RESCUE("Prince Ali Rescue", new WorldPoint(3301, 3163, 0)), + 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("Shield of Arrav", new WorldPoint(3208, 3495, 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)), //Members' Quests - ANIMAL_MAGNETISM(Quest.ANIMAL_MAGNETISM, new WorldPoint(3094, 3360, 0)), - ANOTHER_SLICE_OF_HAM(Quest.ANOTHER_SLICE_OF_HAM, new WorldPoint(2799, 5428, 0)), - THE_ASCENT_OF_ARCEUUS(Quest.THE_ASCENT_OF_ARCEUUS, new WorldPoint(1700, 3742, 0)), - BETWEEN_A_ROCK(Quest.BETWEEN_A_ROCK, new WorldPoint(2823, 10168, 0)), - BIG_CHOMPY_BIRD_HUNTING(Quest.BIG_CHOMPY_BIRD_HUNTING, new WorldPoint(2629, 2981, 0)), - BIOHAZARD(Quest.BIOHAZARD, new WorldPoint(2591, 3335, 0)), - BONE_VOYAGE(Quest.BONE_VOYAGE, new WorldPoint(3259, 3450, 0)), - CABIN_FEVER(Quest.CABIN_FEVER, new WorldPoint(3674, 3496, 0)), - CLIENT_OF_KOUREND(Quest.CLIENT_OF_KOUREND, new WorldPoint(1823, 3690, 0)), - CLOCK_TOWER(Quest.CLOCK_TOWER, new WorldPoint(2568, 3249, 0)), - COLD_WAR(Quest.COLD_WAR, new WorldPoint(2593, 3265, 0)), - CONTACT(Quest.CONTACT, new WorldPoint(3280, 2770, 0)), - CREATURE_OF_FENKENSTRAIN(Quest.CREATURE_OF_FENKENSTRAIN, new WorldPoint(3487, 3485, 0)), - DARKNESS_OF_HALLOWVALE(Quest.DARKNESS_OF_HALLOWVALE, new WorldPoint(3494, 9628, 0)), - DEATH_PLATEAU_TROLL_STRONGHOLD("Death plateau & Troll stronghold", new WorldPoint(2895, 3528, 0)), - DEATH_TO_THE_DORGESHUUN(Quest.DEATH_TO_THE_DORGESHUUN, new WorldPoint(3316, 9613, 0)), - THE_DEPTHS_OF_DESPAIR(Quest.THE_DEPTHS_OF_DESPAIR, new WorldPoint(1846, 3556, 0)), - DESERT_TREASURE(Quest.DESERT_TREASURE, new WorldPoint(3177, 3043, 0)), - DEVIOUS_MINDS(Quest.DEVIOUS_MINDS, new WorldPoint(3405, 3492, 0)), - THE_DIG_SITE(Quest.THE_DIG_SITE, new WorldPoint(3363, 3337, 0)), - DRAGON_SLAYER_II(Quest.DRAGON_SLAYER_II, new WorldPoint(2456, 2868, 0)), - DREAM_MENTOR(Quest.DREAM_MENTOR, new WorldPoint(2144, 10346, 0)), - DRUIDIC_RITUAL(Quest.DRUIDIC_RITUAL, new WorldPoint(2916, 3484, 0)), - DWARF_CANNON(Quest.DWARF_CANNON, new WorldPoint(2566, 3461, 0)), - EADGARS_RUSE(Quest.EADGARS_RUSE, new WorldPoint(2896, 3426, 0)), - EAGLES_PEAK(Quest.EAGLES_PEAK, new WorldPoint(2605, 3264, 0)), - ELEMENTAL_WORKSHOP("Elemental I & II", new WorldPoint(2714, 3482, 0)), - ENAKHRAS_LAMENT(Quest.ENAKHRAS_LAMENT, new WorldPoint(3190, 2926, 0)), - ENLIGHTENED_JOURNEY(Quest.ENLIGHTENED_JOURNEY, new WorldPoint(2809, 3356, 0)), - THE_EYES_OF_GLOUPHRIE(Quest.THE_EYES_OF_GLOUPHRIE, new WorldPoint(2400, 3419, 0)), + ANIMAL_MAGNETISM("Animal Magnetism", new WorldPoint(3094, 3360, 0)), + ANOTHER_SLICE_OF_HAM("Another Slice of H.A.M.", new WorldPoint(2799, 5428, 0)), + THE_ASCENT_OF_ARCEUUS("The Ascent of Arceuus", new WorldPoint(1700, 3742, 0)), + BETWEEN_A_ROCK("Between a Rock...", new WorldPoint(2823, 10168, 0)), + BIG_CHOMPY_BIRD_HUNTING("Big Chompy Bird Hunting", new WorldPoint(2629, 2981, 0)), + BIOHAZARD("Biohazard", new WorldPoint(2591, 3335, 0)), + BONE_VOYAGE("Bone Voyage", new WorldPoint(3259, 3450, 0)), + CABIN_FEVER("Cabin Fever", new WorldPoint(3674, 3496, 0)), + CLIENT_OF_KOUREND("Client of Kourend", new WorldPoint(1823, 3690, 0)), + CLOCK_TOWER("Clock Tower", new WorldPoint(2568, 3249, 0)), + COLD_WAR("Cold War", new WorldPoint(2593, 3265, 0)), + CONTACT("Contact!", new WorldPoint(3280, 2770, 0)), + CREATURE_OF_FENKENSTRAIN("Creature of Fenkenstrain", new WorldPoint(3487, 3485, 0)), + DARKNESS_OF_HALLOWVALE("Darkness of Hallowvale", new WorldPoint(3494, 9628, 0)), + DEATH_PLATEAU_TROLL_STRONGHOLD("Death Plateau & Troll Stronghold", new WorldPoint(2895, 3528, 0)), + DEATH_TO_THE_DORGESHUUN("Death to the Dorgeshuun", new WorldPoint(3316, 9613, 0)), + THE_DEPTHS_OF_DESPAIR("The Depths of Despair", new WorldPoint(1846, 3556, 0)), + DESERT_TREASURE("Desert Treasure", new WorldPoint(3177, 3043, 0)), + DEVIOUS_MINDS("Devious Minds", new WorldPoint(3405, 3492, 0)), + THE_DIG_SITE("The Dig Site", new WorldPoint(3363, 3337, 0)), + DRAGON_SLAYER_II("Dragon Slayer II", new WorldPoint(2456, 2868, 0)), + DREAM_MENTOR("Dream Mentor", new WorldPoint(2144, 10346, 0)), + DRUIDIC_RITUAL("Druidic Ritual", new WorldPoint(2916, 3484, 0)), + DWARF_CANNON("Dwarf Cannon", new WorldPoint(2566, 3461, 0)), + EADGARS_RUSE("Eadgar's Ruse", new WorldPoint(2896, 3426, 0)), + EAGLES_PEAK("Eagles' Peak", new WorldPoint(2605, 3264, 0)), + ELEMENTAL_WORKSHOP("Elemental Workshop I & II", new WorldPoint(2714, 3482, 0)), + ENAKHRAS_LAMENT("Enakhra's Lament", new WorldPoint(3190, 2926, 0)), + ENLIGHTENED_JOURNEY("Enlightened Journey", new WorldPoint(2809, 3356, 0)), + THE_EYES_OF_GLOUPHRIE("The Eyes of Glouphrie", new WorldPoint(2400, 3419, 0)), FAIRYTALE("Fairytale I & II", new WorldPoint(3077, 3258, 0)), - FAMILY_CREST(Quest.FAMILY_CREST, new WorldPoint(3278, 3404, 0)), - THE_FEUD(Quest.THE_FEUD, new WorldPoint(3301, 3211, 0)), - FIGHT_ARENA(Quest.FIGHT_ARENA, new WorldPoint(2565, 3199, 0)), - FISHING_CONTEST_1(Quest.FISHING_CONTEST, new WorldPoint(2875, 3483, 0)), - FISHING_CONTEST_2(Quest.FISHING_CONTEST, new WorldPoint(2820, 3487, 0)), - FORGETTABLE_TALE(Quest.FORGETTABLE_TALE, new WorldPoint(2826, 10215, 0)), - THE_FORSAKEN_TOWER(Quest.THE_FORSAKEN_TOWER, new WorldPoint(1484, 3747, 0)), - THE_FREMENNIK_ISLES(Quest.THE_FREMENNIK_ISLES, new WorldPoint(2645, 3711, 0)), - THE_FREMENNIK_TRIALS(Quest.THE_FREMENNIK_TRIALS, new WorldPoint(2657, 3669, 0)), - GARDEN_OF_TRANQUILLITY(Quest.GARDEN_OF_TRANQUILLITY, new WorldPoint(3227, 3477, 0)), - GERTRUDES_CAT_RATCATCHERS(Quest.GERTRUDES_CAT, new WorldPoint(3150, 3411, 0)), - GHOSTS_AHOY(Quest.GHOSTS_AHOY, new WorldPoint(3677, 3510, 0)), - THE_GIANT_DWARF(Quest.THE_GIANT_DWARF, new WorldPoint(2841, 10129, 0)), - THE_GOLEM(Quest.THE_GOLEM, new WorldPoint(3487, 3089, 0)), + FAMILY_CREST("Family Crest", new WorldPoint(3278, 3404, 0)), + THE_FEUD("The Feud", new WorldPoint(3301, 3211, 0)), + FIGHT_ARENA("Fight Arena", new WorldPoint(2565, 3199, 0)), + FISHING_CONTEST_1("Fishing Contest", new WorldPoint(2875, 3483, 0)), + FISHING_CONTEST_2("Fishing Contest", new WorldPoint(2820, 3487, 0)), + FORGETTABLE_TALE("Forgettable Tale...", new WorldPoint(2826, 10215, 0)), + THE_FORSAKEN_TOWER("The Forsaken Tower", new WorldPoint(1484, 3747, 0)), + THE_FREMENNIK_ISLES("The Fremennik Isles", new WorldPoint(2645, 3711, 0)), + THE_FREMENNIK_TRIALS("The Fremennik Trials", new WorldPoint(2657, 3669, 0)), + GARDEN_OF_TRANQUILLITY("Garden of Tranquillity", new WorldPoint(3227, 3477, 0)), + GERTRUDES_CAT_RATCATCHERS("Gertrude's Cat & Ratcatchers", new WorldPoint(3150, 3411, 0)), + GHOSTS_AHOY("Ghosts Ahoy", new WorldPoint(3677, 3510, 0)), + THE_GIANT_DWARF("The Giant Dwarf", new WorldPoint(2841, 10129, 0)), + THE_GOLEM("The Golem", new WorldPoint(3487, 3089, 0)), THE_GRAND_TREE_MONKEY_MADNESS("The Grand Tree & Monkey Madness I & II", new WorldPoint(2466, 3497, 0)), - THE_GREAT_BRAIN_ROBBERY(Quest.THE_GREAT_BRAIN_ROBBERY, new WorldPoint(3681, 2963, 0)), - GRIM_TALES(Quest.GRIM_TALES, new WorldPoint(2890, 3454, 0)), - THE_HAND_IN_THE_SAND(Quest.THE_HAND_IN_THE_SAND, new WorldPoint(2552, 3101, 0)), - HAUNTED_MINE(Quest.HAUNTED_MINE, new WorldPoint(3443, 3258, 0)), - HAZEEL_CULT(Quest.HAZEEL_CULT, new WorldPoint(2565, 3271, 0)), - HEROES_QUEST(Quest.HEROES_QUEST, new WorldPoint(2903, 3511, 0)), + THE_GREAT_BRAIN_ROBBERY("The Great Brain Robbery", new WorldPoint(3681, 2963, 0)), + GRIM_TALES("Grim Tales", new WorldPoint(2890, 3454, 0)), + THE_HAND_IN_THE_SAND("The Hand in the Sand", new WorldPoint(2552, 3101, 0)), + HAUNTED_MINE("Haunted Mine", new WorldPoint(3443, 3258, 0)), + HAZEEL_CULT("Hazeel Cult", new WorldPoint(2565, 3271, 0)), + HEROES_QUEST("Heroes' Quest", new WorldPoint(2903, 3511, 0)), HOLY_GRAIL("Holy Grail & Merlin's Crystal", new WorldPoint(2763, 3515, 0)), - HORROR_FROM_THE_DEEP(Quest.HORROR_FROM_THE_DEEP, new WorldPoint(2507, 3635, 0)), - ICTHLARINS_LITTLE_HELPER(Quest.ICTHLARINS_LITTLE_HELPER, new WorldPoint(3314, 2849, 0)), - IN_SEARCH_OF_THE_MYREQUE(Quest.IN_SEARCH_OF_THE_MYREQUE, new WorldPoint(3502, 3477, 0)), - JUNGLE_POTION(Quest.JUNGLE_POTION, new WorldPoint(2809, 3086, 0)), - KINGS_RANSOM(Quest.KINGS_RANSOM, new WorldPoint(2741, 3554, 0)), - LEGENDS_QUEST(Quest.LEGENDS_QUEST, new WorldPoint(2725, 3367, 0)), - LOST_CITY(Quest.LOST_CITY, new WorldPoint(3149, 3205, 0)), - THE_LOST_TRIBE(Quest.THE_LOST_TRIBE, new WorldPoint(3211, 3224, 0)), - LUNAR_DIPLOMACY(Quest.LUNAR_DIPLOMACY, new WorldPoint(2619, 3689, 0)), - MAKING_FRIENDS_WITH_MY_ARM(Quest.MAKING_FRIENDS_WITH_MY_ARM, new WorldPoint(2904, 10092, 0)), - MAKING_HISTORY(Quest.MAKING_HISTORY, new WorldPoint(2435, 3346, 0)), - MONKS_FRIEND(Quest.MONKS_FRIEND, new WorldPoint(2605, 3209, 0)), - MOUNTAIN_DAUGHTER(Quest.MOUNTAIN_DAUGHTER, new WorldPoint(2810, 3672, 0)), - MOURNINGS_ENDS_PART_I(Quest.MOURNINGS_ENDS_PART_I, new WorldPoint(2289, 3149, 0)), - MOURNINGS_ENDS_PART_II(Quest.MONKEY_MADNESS_II, new WorldPoint(2352, 3172, 0)), - MURDER_MYSTERY(Quest.MURDER_MYSTERY, new WorldPoint(2740, 3562, 0)), - MY_ARMS_BIG_ADVENTURE(Quest.MY_ARMS_BIG_ADVENTURE, new WorldPoint(2908, 10088, 0)), - NATURE_SPIRIT(Quest.NATURE_SPIRIT, new WorldPoint(3440, 9894, 0)), - OBSERVATORY_QUEST(Quest.OBSERVATORY_QUEST, new WorldPoint(2438, 3185, 0)), - OLAFS_QUEST(Quest.OLAFS_QUEST, new WorldPoint(2723, 3729, 0)), - ONE_SMALL_FAVOUR(Quest.ONE_SMALL_FAVOUR, new WorldPoint(2834, 2985, 0)), - PLAGUE_CITY(Quest.PLAGUE_CITY, new WorldPoint(2567, 3334, 0)), - PRIEST_IN_PERIL(Quest.PRIEST_IN_PERIL, new WorldPoint(3219, 3473, 0)), - THE_QUEEN_OF_THIEVES(Quest.THE_QUEEN_OF_THIEVES, new WorldPoint(1795, 3782, 0)), + HORROR_FROM_THE_DEEP("Horror from the Deep", new WorldPoint(2507, 3635, 0)), + ICTHLARINS_LITTLE_HELPER("Icthlarin's Little Helper", new WorldPoint(3314, 2849, 0)), + IN_SEARCH_OF_THE_MYREQUE("In Search of the Myreque", new WorldPoint(3502, 3477, 0)), + JUNGLE_POTION("Jungle Potion", new WorldPoint(2809, 3086, 0)), + KINGS_RANSOM("King's Ransom", new WorldPoint(2741, 3554, 0)), + LEGENDS_QUEST("Legends' Quest", new WorldPoint(2725, 3367, 0)), + LOST_CITY("Lost City", new WorldPoint(3149, 3205, 0)), + THE_LOST_TRIBE("The Lost Tribe", new WorldPoint(3211, 3224, 0)), + LUNAR_DIPLOMACY("Lunar Diplomacy", new WorldPoint(2619, 3689, 0)), + MAKING_FRIENDS_WITH_MY_ARM("Making Friends with My Arm", new WorldPoint(2904, 10092, 0)), + MAKING_HISTORY("Making History", new WorldPoint(2435, 3346, 0)), + MONKS_FRIEND("Monk's Friend", new WorldPoint(2605, 3209, 0)), + MOUNTAIN_DAUGHTER("Mountain Daughter", new WorldPoint(2810, 3672, 0)), + MOURNINGS_ENDS_PART_I("Mourning's Ends Part I", new WorldPoint(2289, 3149, 0)), + MOURNINGS_ENDS_PART_II("Mourning's Ends Part II", new WorldPoint(2352, 3172, 0)), + MURDER_MYSTERY("Murder Mystery", new WorldPoint(2740, 3562, 0)), + MY_ARMS_BIG_ADVENTURE("My Arm's Big Adventure", new WorldPoint(2908, 10088, 0)), + NATURE_SPIRIT("Nature Spirit", new WorldPoint(3440, 9894, 0)), + OBSERVATORY_QUEST("Observatory Quest", new WorldPoint(2438, 3185, 0)), + OLAFS_QUEST("Olaf's Quest", new WorldPoint(2723, 3729, 0)), + ONE_SMALL_FAVOUR("One Small Favour", new WorldPoint(2834, 2985, 0)), + PLAGUE_CITY("Plague City", new WorldPoint(2567, 3334, 0)), + PRIEST_IN_PERIL("Priest in Peril", new WorldPoint(3219, 3473, 0)), + THE_QUEEN_OF_THIEVES("The Queen of Thieves", new WorldPoint(1795, 3782, 0)), RAG_AND_BONE_MAN("Rag and Bone Man I & II", new WorldPoint(3359, 3504, 0)), RECRUITMENT_DRIVE_BLACK_KNIGHTS_FORTRESS("Recruitment Drive & Black Knights' Fortress", new WorldPoint(2959, 3336, 0)), - ROVING_ELVES(Quest.ROVING_ELVES, new WorldPoint(2289, 3146, 0)), - RUM_DEAL(Quest.RUM_DEAL, new WorldPoint(3679, 3535, 0)), - SCORPION_CATCHER(Quest.SCORPION_CATCHER, new WorldPoint(2701, 3399, 0)), - SEA_SLUG(Quest.SEA_SLUG, new WorldPoint(2715, 3302, 0)), - SHADES_OF_MORTTON(Quest.SHADES_OF_MORTTON, new WorldPoint(3463, 3308, 0)), - SHADOW_OF_THE_STORM(Quest.SHADES_OF_MORTTON, new WorldPoint(3270, 3159, 0)), - SHEEP_HERDER(Quest.SHEEP_HERDER, new WorldPoint(2616, 3299, 0)), - SHILO_VILLAGE(Quest.SHILO_VILLAGE, new WorldPoint(2882, 2951, 0)), - A_SOULS_BANE(Quest.A_SOULS_BANE, new WorldPoint(3307, 3454, 0)), - SPIRITS_OF_THE_ELID(Quest.SPIRITS_OF_THE_ELID, new WorldPoint(3441, 2911, 0)), - SWAN_SONG(Quest.SWAN_SONG, new WorldPoint(2345, 3652, 0)), - TAI_BWO_WANNAI_TRIO(Quest.TAI_BWO_WANNAI_TRIO, new WorldPoint(2779, 3087, 0)), - A_TAIL_OF_TWO_CATS(Quest.A_TAIL_OF_TWO_CATS, new WorldPoint(2917, 3557, 0)), - TALE_OF_THE_RIGHTEOUS(Quest.TALE_OF_THE_RIGHTEOUS, new WorldPoint(1511, 3631, 0)), - A_TASTE_OF_HOPE(Quest.A_TASTE_OF_HOPE, new WorldPoint(3668, 3216, 0)), - TEARS_OF_GUTHIX(Quest.TEARS_OF_GUTHIX, new WorldPoint(3251, 9517, 0)), - TEMPLE_OF_IKOV(Quest.TEMPLE_OF_IKOV, new WorldPoint(2574, 3320, 0)), + ROVING_ELVES("Roving Elves", new WorldPoint(2289, 3146, 0)), + RUM_DEAL("Rum Deal", new WorldPoint(3679, 3535, 0)), + SCORPION_CATCHER("Scorpion Catcher", new WorldPoint(2701, 3399, 0)), + SEA_SLUG("Sea Slug", new WorldPoint(2715, 3302, 0)), + SHADES_OF_MORTTON("Shades of Mort'ton", new WorldPoint(3463, 3308, 0)), + SHADOW_OF_THE_STORM("Shadow of the Storm", new WorldPoint(3270, 3159, 0)), + SHEEP_HERDER("Sheep Herder", new WorldPoint(2616, 3299, 0)), + SHILO_VILLAGE("Shilo Village", new WorldPoint(2882, 2951, 0)), + A_SOULS_BANE("A Soul's Bane", new WorldPoint(3307, 3454, 0)), + SPIRITS_OF_THE_ELID("Spirits of the Elid", new WorldPoint(3441, 2911, 0)), + SWAN_SONG("Swan Song", new WorldPoint(2345, 3652, 0)), + TAI_BWO_WANNAI_TRIO("Tai Bwo Wannai Trio", new WorldPoint(2779, 3087, 0)), + A_TAIL_OF_TWO_CATS("A Tail of Two Cats", new WorldPoint(2917, 3557, 0)), + TALE_OF_THE_RIGHTEOUS("Tale of the Righteous", new WorldPoint(1511, 3631, 0)), + A_TASTE_OF_HOPE("A Taste of Hope", new WorldPoint(3668, 3216, 0)), + TEARS_OF_GUTHIX("Tears of Guthix", new WorldPoint(3251, 9517, 0)), + TEMPLE_OF_IKOV("Temple of Ikov", new WorldPoint(2574, 3320, 0)), THRONE_OF_MISCELLANIA_ROYAL_TROUBLE("Throne of Miscellania & Royal Trouble", new WorldPoint(2497, 3859, 0)), - THE_TOURIST_TRAP(Quest.THE_TOURIST_TRAP, new WorldPoint(3302, 3113, 0)), - TOWER_OF_LIFE(Quest.TOWER_OF_LIFE, new WorldPoint(2640, 3218, 0)), - TREE_GNOME_VILLAGE(Quest.TREE_GNOME_VILLAGE, new WorldPoint(2541, 3169, 0)), - TRIBAL_TOTEM(Quest.TRIBAL_TOTEM, new WorldPoint(2790, 3182, 0)), - TROLL_ROMANCE(Quest.TROLL_ROMANCE, new WorldPoint(2890, 10097, 0)), + THE_TOURIST_TRAP("The Tourist Trap", new WorldPoint(3302, 3113, 0)), + TOWER_OF_LIFE("Tower of Life", new WorldPoint(2640, 3218, 0)), + TREE_GNOME_VILLAGE("Tree Gnome Village", new WorldPoint(2541, 3169, 0)), + TRIBAL_TOTEM("Tribal Totem", new WorldPoint(2790, 3182, 0)), + TROLL_ROMANCE("Troll Romance", new WorldPoint(2890, 10097, 0)), UNDERGROUND_PASS_REGICIDE("Underground Pass & Regicide", new WorldPoint(2575, 3293, 0)), WANTED_SLUG_MENACE("Wanted! & The Slug Menace", new WorldPoint(2996, 3373, 0)), - WATCHTOWER(Quest.WATCHTOWER, new WorldPoint(2545, 3112, 0)), - WATERFALL_QUEST(Quest.WATERFALL_QUEST, new WorldPoint(2521, 3498, 0)), - WHAT_LIES_BELOW(Quest.WHAT_LIES_BELOW, new WorldPoint(3265, 3333, 0)), - WITCHS_HOUSE(Quest.WITCHS_HOUSE, new WorldPoint(2927, 3456, 0)), - ZOGRE_FLESH_EATERS(Quest.ZOGRE_FLESH_EATERS, new WorldPoint(2442, 3051, 0)); + WATCHTOWER("Watchtower", new WorldPoint(2545, 3112, 0)), + WATERFALL_QUEST("Waterfall Quest", new WorldPoint(2521, 3498, 0)), + WHAT_LIES_BELOW("What Lies Below", new WorldPoint(3265, 3333, 0)), + WITCHS_HOUSE("Witch's House", new WorldPoint(2927, 3456, 0)), + ZOGRE_FLESH_EATERS("Zogre Flesh Eaters", new WorldPoint(2442, 3051, 0)); @Getter private final String tooltip; @@ -169,20 +168,9 @@ enum QuestStartLocation @Getter private final WorldPoint location; - @Getter - private final Quest quest; - QuestStartLocation(String description, WorldPoint location) { - this.tooltip = description; + this.tooltip = "Quest Start - " + description; this.location = location; - this.quest = null; - } - - QuestStartLocation(Quest quest, WorldPoint location) - { - this.tooltip = quest.getName(); - this.location = location; - this.quest = quest; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartPoint.java index fe53b045f8..14f1842f62 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartPoint.java @@ -30,10 +30,10 @@ import java.awt.image.BufferedImage; class QuestStartPoint extends WorldMapPoint { - QuestStartPoint(QuestStartLocation data, BufferedImage icon, String toolTip) + QuestStartPoint(QuestStartLocation data, BufferedImage icon) { super(data.getLocation(), icon); - setTooltip("Quest start" + toolTip); + setTooltip(data.getTooltip()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPoint.java index 836ce6f388..57fce253e9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPoint.java @@ -1,5 +1,7 @@ /* - * Copyright (c) 2019, Kyle Sergio , , Bryce Altomare + * Copyright (c) 2019, Kyle Sergio + * Copyright (c) 2019, Bryce Altomare + * Copyright (c) 2019, Kyle Stead * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,13 +30,11 @@ package net.runelite.client.plugins.worldmap; import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; import java.awt.image.BufferedImage; -public class TransportationPoint extends WorldMapPoint +class TransportationPoint extends WorldMapPoint { - TransportationPoint(TransportationPointLocation data, BufferedImage icon) - { - super(data.getLocation(), icon); - - setTooltip(data.getTooltip()); - } - -} \ No newline at end of file + TransportationPoint(TransportationPointLocation data, BufferedImage icon) + { + super(data.getLocation(), icon); + setTooltip(data.getTooltip()); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPointLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPointLocation.java index 7d2dd76e0a..54bd7adfdc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPointLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPointLocation.java @@ -1,5 +1,7 @@ /* - * Copyright (c) 2019, Kyle Sergio , Bryce Altomare + * Copyright (c) 2019, Kyle Sergio + * Copyright (c) 2019, Bryce Altomare + * Copyright (c) 2019, Kyle Stead * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,177 +27,167 @@ */ package net.runelite.client.plugins.worldmap; +import lombok.AllArgsConstructor; import lombok.Getter; import net.runelite.api.coords.WorldPoint; -import net.runelite.http.api.worlds.World; -enum TransportationPointLocation { +@Getter +@AllArgsConstructor +enum TransportationPointLocation +{ + //Ships + ARDOUGNE_TO_BRIMHAVEN("Ship to Brimhaven", new WorldPoint(2675, 3275, 0)), + ARDOUGNE_TO_FISHINGPLAT("Ship to Fishing Platform", new WorldPoint(2722, 3304, 0)), + BRIMHAVEN_TO_ARDOUGNE("Ship to Ardougne", new WorldPoint(2772, 3234, 0)), + CATHERBY_TO_KEEP_LE_FAYE("Ship to Keep Le Faye", new WorldPoint(2804, 3421, 0)), + CORSAIR_TO_RIMMINGTON("Ship to Rimmington", new WorldPoint(2577, 2839, 0)), + DRAGONTOOTH_TO_PHASMATYS("Ship to Port Phasmatys", new WorldPoint(3791, 3561, 0)), + DIGSITE_TO_FOSSIL("Ship to Fossil Island", new WorldPoint(3361, 3448, 0)), + ENTRANA_TO_PORTSARIM("Ship to Port Sarim", new WorldPoint(2833, 3334, 0)), + FISHINGPLAT_TO_ARDOUGNE("Ship to Ardougne", new WorldPoint(2779, 3271, 0)), + HARMLESS_TO_PORT_PHASMATYS("Ship to Port Phasmatys", new WorldPoint(3682, 2951, 0)), + ICEBERG_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2657, 3988, 0)), + ISLAND_TO_APE_ATOLL("Ship to Ape Atoll", new WorldPoint(2891, 2726, 0)), + JATIZSO_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2420, 3780, 0)), + KARAMJA_TO_PORT_SARIM("Ship to Port Sarim", new WorldPoint(2955, 3144, 0)), + KARAMJA_TO_PORT_KHAZARD("Ship to Port Khazard", new WorldPoint(2763, 2957, 0)), + LANDSEND_TO_PORTSARIM_PORTPISCARILIUS("Ship to Port Sarim/Port Piscarilius", new WorldPoint(1503, 3398, 0)), + LUNAR_ISLE_TO_PIRATES_COVE("Ship to Pirates' Cove", new WorldPoint(2137, 3899, 0)), + MISCELLANIA_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2579, 3846, 0)), + NEITIZNOT_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2310, 3779, 0)), + PESTCONTROL_TO_PORTSARIM("Ship to Port Sarim", new WorldPoint(2659, 2675, 0)), + PIRATES_COVE_TO_LUNAR_ISLE("Ship to Lunar Isle", new WorldPoint(2223, 3796, 0)), + PIRATES_COVE_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2212, 3794, 0)), + PORT_PHASMATYS_TO_DRAGONTOOTH("Ship to Dragontooth Island", new WorldPoint(3703, 3487, 0)), + PORT_PHASMATYS_TO_HARMLESS("Ship to Mos Le'Harmless", new WorldPoint(3709, 3497, 0)), + PORT_PISCARILIUS_TO_PORTSARIM_LANDSEND("Ship to Port Sarim/Land's End", new WorldPoint(1823, 3692, 0)), + PORTSARIM_TO_GREAT_KOUREND("Ship to Great Kourend", new WorldPoint(3054, 3244, 0)), + PORTSARIM_TO_ENTRANA("Ship to Entrana", new WorldPoint(3046, 3233, 0)), + PORTSARIM_TO_KARAMJA("Ship to Karamja", new WorldPoint(3029, 3218, 0)), + PORTSARIM_TO_CRANDOR("Ship to Crandor", new WorldPoint(3045, 3205, 0)), + PORTSARIM_TO_PEST_CONTROL("Ship to Pest Control", new WorldPoint(3039, 3201, 0)), + RELLEKKA_TO_JATIZSO_NEITIZNOT("Ship to Jatizso/Neitiznot", new WorldPoint(2639, 3710, 0)), + RELLEKKA_TO_MISCELLANIA("Ship to Miscellania", new WorldPoint(2627, 3692, 0)), + RELLEKKA_TO_WATERBIRTH("Ship to Waterbirth", new WorldPoint(2621, 3683, 0)), + RELLEKKA_TO_WEISS_ICEBERG("Ship to Weiss/Iceberg", new WorldPoint(2707, 3735, 0)), + RELLEKKA_TO_UNGAEL("Ship to Ungael", new WorldPoint(2638, 3698, 0)), + RIMMINGTON_TO_CORSAIR_COVE("Ship to Corsair Cove", new WorldPoint(2909, 3227, 0 )), + WATERBIRTH_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2549, 3758, 0)), + WEISS_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2847, 3967, 0)), + UNGAEL_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2276, 4034, 0)), - //Ships - ARDOUGNE_TO_BRIMHAVEN("Ship to - Brimhaven", new WorldPoint(2675,3275,0)), - ARDOUGNE_TO_FISHINGPLAT("Ship to - Fishing Platform", new WorldPoint(2722,3304,0)), - BRIMHAVEN_TO_ARDOUGNE("Ship to - Ardougne", new WorldPoint(2772,3234,0)), - CATHERBY_TO_KEEP_LE_FAYE("Ship to - Keep Le Faye", new WorldPoint(2804,3421,0)), - CORSAIR_TO_RIMMINGTON("Ship to - Rimmington", new WorldPoint(2577,2839,0)), - DRAGONTOOTH_TO_PHASMATYS("Ship to - Port Phasmatys", new WorldPoint(3791,3561,0)), - DIGSITE_TO_FOSSIL("Ship to - Fossil island", new WorldPoint(3361,3448,0)), - ENTRANA_TO_PORTSARIM("Ship to - Port Sarim", new WorldPoint(2833,3334,0)), - FISHINGPLAT_TO_ARDOUGNE("Ship to - Ardougne", new WorldPoint(2779,3271,0)), - HARMLESS_TO_PORT_PHASMATYS("Ship to - Port Phasmatys", new WorldPoint(3682,2951,0)), - ICEBERG_TO_RELLEKKA("Ship to - Rellekka", new WorldPoint(2657,3988,0)), - ISLAND_TO_APETOLL("Ship to - Ape Toll", new WorldPoint(2891,2726,0)), - JATIZZO_TO_RELLEKKA("Ship to - Rellekka", new WorldPoint(2420,3780,0)), - KARAMJA_TO_PORT_SARIM("Ship to - Port Sarim", new WorldPoint(2955,3144,0)), - KARAMJA_TO_KHAZARD_PORT("Ship to - Khazard Port", new WorldPoint(2763,2957,0)), - KHAZARD_TO_SHILO("Ship to - Shilo", new WorldPoint(2673,3143,0)), - LANDSEND_TO_PORTSARIM_PORTPISCARILLUS("Ship to Port Sarim/Port Piscarillus", new WorldPoint(1503,3398,0)), - LUNAR_ISLE_TO_PIRATES_COVE("Ship to - Pirates Cove", new WorldPoint(2137,3899,0)), - MISCELLANIA_TO_RELLEKKA("Ship to - Rellekka", new WorldPoint(2579,3846,0)), - NEITZNOT_TO_RELLEKKA("Ship to - Rellekka", new WorldPoint(2310,3779,0)), - PESTCONTROL_TO_PORTSARIM("Ship to - Port Sarim", new WorldPoint(2659,2675,0)), - PIRATES_COVE_TO_LUNAR_ISLE("Ship to - Lunar isle", new WorldPoint(2223,3796,0)), - PIRATES_COVER_TO_RELLEKKA("Ship to - Rellekka", new WorldPoint(2212,3794,0)), - PORT_PHASMATYS_TO_DRAGONTOOTH("Ship to - Dragontooth island", new WorldPoint(3703,3487,0)), - PORT_PHASMATYS_TO_HARMLESS("Ship to - Mos le Harmless", new WorldPoint(3709,3497,0)), - PORT_PISCARILIUS_TO_PORTSARIM_lANDSEND("Ship to - Port Sarim/Lands end", new WorldPoint(1823,3692,0)), - PORTSARIM_TO_GREAT_KOUREND("Ship to - Great Kourend", new WorldPoint(3054,3244,0)), - PORTSARIM_TO_ENTRANA("Ship to - Entrana", new WorldPoint(3046,3233,0)), - PORTSARIM_TO_KARAMJA("Ship to - Karamja", new WorldPoint(3029,3218,0)), - PORTSARIM_TO_CRANDOR("Ship to - Crandor", new WorldPoint(3045,3205,0)), - PORTSARIM_TO_PEST_CONTROL("Ship to - Pest Control", new WorldPoint(3039,3201,0)), - RELLEKKA_TO_JATIZZO_NEITIZNOT("Ship to - Jatizzo/Neitiznot", new WorldPoint(2639,3710,0)), - RELLEKKA_TO_MISCELLANIA("Ship to - Miscellania", new WorldPoint(2627,3692,0)), - RELLEKKA_TO_WATERBIRTH("Ship to - Waterbirth", new WorldPoint(2621,3683,0)), - RELLEKKA_TO_WEISS_ICEBERG("Ship to - Weiss/Iceberg", new WorldPoint(2707,3735,0)), - RELLEKKA_TO_UNGAEL("Ship to - Ungael", new WorldPoint(2638,3698,0)), - RIMMINGTON_TO_CORSAIR_COVE("Ship to - Corsair Cove", new WorldPoint(2909,3227,0 )), - WATERBIRTH_TO_RELLEKKA("Ship to - Rellekka", new WorldPoint(2549,3758,0)), - WEISS_TO_RELLEKKA("Ship to - Rellekka", new WorldPoint(2847,3967,0)), - UNGAEL_TO_RELLEKKA("Ship to - Rellekka", new WorldPoint(2276,4034,0)), + //Row Boats + ROW_BOAT_BATTLEFRONT("Rowboat to Molch/Molch Island/Shayzien", new WorldPoint(1383, 3663, 0)), + ROW_BOAT_BRAIN_DEATH("Rowboat to Port Phasmatys", new WorldPoint(2161, 5117, 0)), + ROW_BOAT_BURGH_DE_ROTT("Rowboat to Meiyerditch", new WorldPoint(3522, 3168, 0)), + ROW_BOAT_CRABCLAW("Rowboat to Hosidius", new WorldPoint(1780, 3417, 0)), + ROW_BOAT_DIVING_ISLAND("Rowboat to Barge/Camp/North of Island", new WorldPoint(3764, 3901, 0)), + ROW_BOAT_FISHING_GUILD("Rowboat to Hemenster", new WorldPoint(2598, 3426, 0)), + ROW_BOAT_GNOME_STRONGHOLD("Rowboat to Fishing Colony", new WorldPoint(2368, 3487, 0)), + ROW_BOAT_FISHING_COLONY("Rowboat to Gnome Stronghold", new WorldPoint(2356, 3641, 0)), + ROW_BOAT_HEMENSTER("Rowboat to Fishing Guild", new WorldPoint(2613, 3439, 0)), + ROW_BOAT_HOSIDIUS("Rowboat to Crabclaw Isle", new WorldPoint(1779, 3457, 0)), + ROW_BOAT_LITHKREN("Rowboat to Mushroom Forest", new WorldPoint(3582, 3973, 0)), + ROW_BOAT_LUMBRIDGE("Rowboat to Misthalin Mystery", new WorldPoint(3238, 3141, 0)), + ROW_BOAT_MOLCH("Rowboat to Molch Island/Shayzien/Battlefront", new WorldPoint(1343, 3646, 0)), + ROW_BOAT_MOLCH_ISLAND("Rowboat to Molch/Shayzien/Battlefront", new WorldPoint(1368, 3641, 0)), + ROW_BOAT_MORT("Rowboat to Mort Myre", new WorldPoint(3518, 3284, 0)), + ROW_BOAT_MORT_SWAMP("Rowboat to Mort'ton", new WorldPoint(3498, 3380, 0)), + ROW_BOAT_MUSEUM_CAMP("Rowboat to Barge/Digsite/North of Island", new WorldPoint(3723, 3807, 0)), + ROW_BOAT_MUSHROOM_FOREST_WEST("Rowboat to Lithkren", new WorldPoint(3659, 3849, 0)), + ROW_BOAT_MUSHROOM_FOREST_NE("Rowboat to Barge/Camp/Sea", new WorldPoint(3733, 3894, 0)), + ROW_BOAT_PORT_PHASMATYS_NORTH("Rowboat to Slepe", new WorldPoint(3670, 3545, 0)), + ROW_BOAT_PORT_PHASMATYS_EAST("Rowboat to Braindeath Island", new WorldPoint(3680, 3538, 0)), + ROW_BOAT_SHAYZIEN("Rowboat to Molch/Molch Island/Battlefront", new WorldPoint(1405, 3612, 0)), + ROW_BOAT_SLEPE("Rowboat to Port Phasmatys", new WorldPoint(3661, 3279, 0)), + OGRE_BOAT_FELDIP("Ogre Boat to Karamja", new WorldPoint(2653, 2964, 0)), + OGRE_BOAT_KARAMJA("Ogre Boat to Feldip", new WorldPoint(2757, 3085, 0)), - //Row Boats - ROW_BOAT_BATTLEFRONT("Rowboat", new WorldPoint(1383,3663,0)), - ROW_BOAT_BRAIN_DEATH("Rowboat", new WorldPoint(2161,5117,0)), - ROW_BOAT_BURGH_DE_ROTT("Rowboat", new WorldPoint(3522,3168,0)), - ROW_BOAT_CRABCLAW("Rowboat", new WorldPoint(1780,3417,0)), - ROW_BOAT_DIVING_ISLAND("Rowboat", new WorldPoint(3764,3901,0)), - ROW_BOAT_FISHING_GUILD("Rowboat", new WorldPoint(2598,3426,0)), - ROW_BOAT_GNOME_STRONGHOLD("Rowboat", new WorldPoint(2368,3487,0)), - ROW_BOAT_FISHING_COLONY("Rowboat", new WorldPoint(2356,3641,0)), - ROW_BOAT_HEMENSTER("Rowboat", new WorldPoint(2613,3439,0)), - ROW_BOAT_HOSIDIUS("Rowboat", new WorldPoint(1779,3457,0)), - ROW_BOAT_LITHKREN("Rowboat", new WorldPoint(3582,3973,0)), - ROW_BOAT_LUMBRIDGE("Rowboat", new WorldPoint(3238,3141,0)), - ROW_BOAT_MOLCH("Rowboat", new WorldPoint(1343,3646,0)), - ROW_BOAT_MOLCH_ISLAND("Rowboat", new WorldPoint(1368,3641,0)), - ROW_BOAT_MORT("Rowboat", new WorldPoint(3518,3284,0)), - ROW_BOAT_MORT_SWAMP("Rowboat", new WorldPoint(3498,3380,0)), - ROW_BOAT_MUSEUM_CAMP("Rowboat", new WorldPoint(3723,3807,0)), - ROW_BOAT_MUSHROOM_FOREST_WEST("Rowboat", new WorldPoint(3659,3849,0)), - ROW_BOAT_MUSHROOM_FOREST_NE("Rowboat", new WorldPoint(3733,3894,0)), - ROW_BOAT_PORT_PHASMATYS_NORTH("Rowboat", new WorldPoint(3670,3545,0)), - ROW_BOAT_PORT_PHASMATYS_EAST("Rowboat", new WorldPoint(3680,3538,0)), - ROW_BOAT_SHAYZIEN("Rowboat", new WorldPoint(1405,3612,0)), - ROW_BOAT_SLEPE("Rowboat", new WorldPoint(3661,3279,0)), - OGRE_BOAT_FELDIP("Ogre Boat", new WorldPoint(2653,2964,0)), - OGRE_BOAT_KARAMJA("Ogre Boat", new WorldPoint(2757,3085,0)), + //Charter ships + CHARTER_BRIMHAVEN("Charter Ship", new WorldPoint(2760, 3238, 0)), + CHARTER_CATHERBY("Charter Ship", new WorldPoint(2791, 3415, 0)), + CHARTER_CORSAIR_("Charter Ship", new WorldPoint(2589, 2851, 0)), + CHARTER_KARAMJA_NORTH("Charter Ship", new WorldPoint(2954, 3159, 0)), + CHARTER_KARAMJA_EAST("Charter Ship", new WorldPoint(2999, 3032, 0)), + CHARTER_KHAZARD("Charter Ship", new WorldPoint(2673, 3143, 0)), + CHARTER_MOSLE_HARMLESS("Charter Ship", new WorldPoint(3669, 2931, 0)), + CHARTER_PORT_PHASMATYS("Charter Ship", new WorldPoint(3702, 3503, 0)), + CHARTER_PORTSARIM("Charter Ship", new WorldPoint(3037, 3191, 0)), + CHARTER_TYRAS("Charter Ship", new WorldPoint(2141, 3123, 0)), - //Charter ships - CHARTER_BRIMHAVEN("Charter Ship", new WorldPoint(2760,3238,0)), - CHARTER_CATHERBY("Charter ship", new WorldPoint(2791,3415,0)), - CHARTER_CORSAIR_("Charter Ship", new WorldPoint(2589,2851,0)), - CHARTER_KARAMJA_NORTH("Charter Ship", new WorldPoint(2954,3159,0)), - CHARTER_KARAMJA_EAST("Charter Ship", new WorldPoint(2999,3032,0)), - CHARTER_MOSLE_HARMLESS("Charter Ship", new WorldPoint(3669,2931,0)), - CHARTER_PORT_PHASMATYS("Charter Ship", new WorldPoint(3702,3503,0)), - CHARTER_PORTSARIM("Charter ship", new WorldPoint(3037,3191,0)), - CHARTER_TYRAS("Charter Ship", new WorldPoint(2141,3123,0)), + //Minecarts/Carts + MINE_CART_ARCEUUS("Minecart", new WorldPoint(1673, 3832, 0)), + MINE_CART_GRANDEXCHANGE("Minecart to Keldagrim", new WorldPoint(3139, 3504, 0)), + MINE_CART_HOSIDIUS("Minecart", new WorldPoint(1656, 3542, 0)), + MINE_CART_KELDAGRIM("Minecart", new WorldPoint(2908, 10170, 0)), + MINE_CART_LOVAKENGJ("Minecart", new WorldPoint(1524, 3721, 0)), + MINE_CART_PORT_PISCARILIUS("Minecart", new WorldPoint(1760, 3708, 0)), + MINE_CART_QUIDAMORTEM("Minecart", new WorldPoint(1253, 3550, 0)), + MINE_CART_SHAYZIEN("Minecart", new WorldPoint(1586, 3622, 0)), + MINE_CART_TAVERLEY_UNDERGROUND("Minecart", new WorldPoint(2874, 9870, 0)), + CART_TO_BRIMHAVEN("Cart to Brimhaven", new WorldPoint(2833, 2958, 0)), + CART_TO_SHILO("Cart to Shilo", new WorldPoint(2780, 3214, 0)), - //Minecarts/Carts - MINE_CART_ARCEUUS("Mine cart", new WorldPoint(1673,3832,0)), - MINE_CART_GRANDEXCHANGE("Minecart to - Keldagrim", new WorldPoint(3139,3504,0)), - MINE_CART_HOSIDIUS("Minecart", new WorldPoint(1656,3542,0)), - MINE_CART_KELDAGRIM("Minecart", new WorldPoint(2908,10170,0)), - MINE_CART_LOVAKENGJ("Minecart", new WorldPoint(1524,3721,0)), - MINE_CART_PORT_PISCARILIUS("Minecart", new WorldPoint(1760,3708,0)), - MINE_CART_QUIDAMORTEM("Minecart", new WorldPoint(1253,3550,0)), - MINE_CART_SHAYZIEN("Minecart", new WorldPoint(1586,3622,0)), - MINE_CART_TAVERLEY_UNDERGROUND("Minecart", new WorldPoint(2874,9870,0)), - CART_TO_BRIMHAVEN("Cart to - Brimhaven", new WorldPoint(2833,2958,0)), - CART_TO_SHILO("Cart to - Shilo", new WorldPoint(2780,3214,0)), + //Canoes + CANOE_BARBVILLAGE("Canoe", new WorldPoint(3111, 3409, 0)), + CANOE_CHAMPIONSGUILD("Canoe", new WorldPoint(3202, 3344, 0)), + CANOE_EDGEVILLE("Canoe", new WorldPoint(3130, 3509, 0)), + CANOE_LUMBRIDGE("Canoe", new WorldPoint(3241, 3238, 0)), - //Canoes - CANOE_BARBVILLAGE("Canoe", new WorldPoint(3111,3409,0)), - CANOE_CHAMPIONSGUILD("Canoe", new WorldPoint(3202,3344,0)), - CANOE_EDGEVILLE("Canoe", new WorldPoint(3130,3509,0)), - CANOE_LUMBRIDGE("Canoe ", new WorldPoint(3241,3238,0)), + //Gnome Gliders + GNOME_GLIDER_KHARID("Gnome Glider", new WorldPoint(3278, 3213, 0)), + GNOME_GLIDER_APE_ATOLL("Gnome Glider", new WorldPoint(2712, 2804, 0)), + GNOME_GLIDER_KARAMJA("Gnome Glider", new WorldPoint(2971, 2974, 0)), + GNOME_GLIDER_FELDIP("Gnome Glider", new WorldPoint(2540, 2969, 0)), + GNOME_GLIDER_GNOMESTRONGHOLD("Gnome Glider", new WorldPoint(2460, 3502, 0)), + GNOME_GLIDER_WHITEWOLF("Gnome Glider", new WorldPoint(2845, 3501, 0)), - //Gnome Gliders - GNOME_GLIDER_KHARID("Gnome Glider", new WorldPoint(3278,3213,0)), - GNOME_GLIDER_APETOLL("Gnome Glider", new WorldPoint(2712,2804,0)), - GNOME_GLIDER_KARAMJA("Gnome Glider", new WorldPoint(2971,2974,0)), - GNOME_GLIDER_FELDIP("Gnome Glider", new WorldPoint(2540,2969,0)), - GNOME_GLIDER_GNOMESTRONGHOLD("Gnome Glider", new WorldPoint(2460,3502,0)), - GNOME_GLIDER_WHITEWOLF("Gnome Glider", new WorldPoint(2845,3501,0)), + //Balloons + BALLOON_VARROCK("Hot Air Balloon", new WorldPoint(3298, 3480, 0)), + BALLOON_YANILLE("Hot Air Balloon", new WorldPoint(2458, 3108, 0)), + BALLOON_GNOMESTRONGHOLD("Hot Air Balloon", new WorldPoint(2478, 3459, 0)), + BALLOON_TAVERLEY("Hot Air Balloon", new WorldPoint(2936, 3422, 0)), + BALLOON_FALADOR("Hot Air Balloon", new WorldPoint(2921, 3301, 0)), - //Balloons - BALLOON_VARROCK("Hot air Balloon", new WorldPoint(3298,3480,0)), - BALLOON_YANILLE("Hot air Balloon", new WorldPoint(2458,3108,0)), - BALLOON_GNOMESTRONGHOLD("Hot air Balloon", new WorldPoint(2478,3459,0)), - BALLOON_TAVERLEY("Hot air Balloon", new WorldPoint(2936,3422,0)), - BALLOON_FALADOR("Hot air Balloon", new WorldPoint(2921,3301,0)), + //Spirit Tree + SPIRITTREE_ARDOUGNE("Spirit Tree", new WorldPoint(2554, 3259, 0)), + SPIRITTREE_CORSAIR("Spirit Tree", new WorldPoint(2485, 2850, 0)), + SPIRITTREE_GNOMESTRONGHOLD("Spirit Tree", new WorldPoint(2459, 3446, 0)), + SPIRITTREE_GNOMEVILLAGE("Spirit Tree", new WorldPoint(2538, 3166, 0)), + SPIRITTREE_GRANDEXCHANGE("Spirit Tree", new WorldPoint(3184, 3510, 0)), - //Spirit Tree - SPIRITTREE_ARDOUGNE("Spirit Tree", new WorldPoint(2554,3259,0)), - SPIRITTREE_CORSAIR("Spirit Tree", new WorldPoint(2485,2850,0)), - SPIRITTREE_GNOMESTRONGHOLD("Spirit Tree", new WorldPoint(2459,3446,0)), - SPIRITTREE_GNOMEVILLAGE("Spirit Tree", new WorldPoint(2538,3166,0)), - SPIRITTREE_GRANDEXCHANGE("Spirit Tree", new WorldPoint(3184,3510,0)), + //Carpets + CARPET_KHARID("Carpet to Bedabin/Pollnivneach/Uzer", new WorldPoint(3311, 3107, 0)), + CARPET_BEDABIN("Carpet to Shantay Pass", new WorldPoint(3183, 3042, 0)), + CARPET_POLLNIVNEACH_NORTH("Carpet to Shantay Pass", new WorldPoint(3351, 3001, 0)), + CARPET_POLLNIVNEACH_SOUTH("Carpet to Nardah/Sophanem/Menaphos", new WorldPoint(3345, 2943, 0)), + CARPET_NARDAH("Carpet to Pollnivneach", new WorldPoint(3399, 2916, 0)), + CARPET_SOPHANEM("Carpet to Pollnivneach", new WorldPoint(3288, 2814, 0)), + CARPET_MENAPHOS("Carpet to Pollnivneach", new WorldPoint(3244, 2812, 0)), + CARPET_UZER("Carpet to Shantay Pass", new WorldPoint(3468, 3111, 0)), + //Teleports + TELEPORT_ARCHIVE_FROM_ARCEUUS("Teleport to Library Archive", new WorldPoint(1623, 3808, 0)), + TELEPORT_HARMLESS_FROM_HARMONY("Teleport to Mos Le'Harmless", new WorldPoint(3784, 2828, 0)), + TELEPORT_RUNE_ARDOUGNE("Teleport to Rune Essence", new WorldPoint(2681, 3325, 0)), + TELEPORT_RUNE_YANILLE("Teleport to Rune Essence", new WorldPoint(2592, 3089, 0)), + TELEPORT_SORCERESS_GARDEN("Teleport to Sorceress's Garden", new WorldPoint(3320, 3141, 0)), - //Carpets - CARPET_KHARID("Carpet", new WorldPoint(3311,3107,0)), - CARPET_BEDABIN("Carpet",new WorldPoint(3183,3042,0)), - CARPET_POLLNIVNEACH_NORTH("Carpet", new WorldPoint(3351,3001,0)), - CARPET_POLLNIVNEACH_SOUTH("Carpet", new WorldPoint(3345,2943,0)), - CARPET_NARDAH("Carpet", new WorldPoint(3399,2916,0)), - CARPET_SOPHANEM("Carpet", new WorldPoint(3288,2814,0)), - CARPET_MENAPHOS("Carpet", new WorldPoint(3244,2812,0)), - CARPET_UZER("Carpet", new WorldPoint(3468,3111,0)), + //Other + ALTER_KOUREND_UNDERGROUND("Altar to Skotizo", new WorldPoint(1662, 10047, 0)), + FAIRY_RING_ZANARIS_TO_KHARID("Fairy Ring to Al Kharid", new WorldPoint(2483, 4471, 0)), + FAIRY_RING_ZANARIS_TO_SHACK("Fairy Ring to Shack", new WorldPoint(2451, 4471, 0)), + MOUNTAIN_GUIDE_QUIDAMORTEM("Mountain Guide", new WorldPoint(1275, 3559, 0)), + MOUNTAIN_GUIDE_WALL("Mountain Guide", new WorldPoint(1400, 3538, 0)), + MUSHTREE_MUSHROOM_FOREST("Mushtree", new WorldPoint(3674, 3871, 0)), + MUSHTREE_TAR_SWAMP("Mushtree", new WorldPoint(3676, 3755, 0)), + MUSHTREE_VERDANT_VALLEY("Mushtree", new WorldPoint(3757, 3756, 0)), + MYTHS_GUILD_PORTAL("Portal to Guilds", new WorldPoint(2456, 2856, 0)), + TRAIN_KELDAGRIM("Railway Station", new WorldPoint(2941, 10179, 0)), + WILDERNESS_LEVER_ARDOUGNE("Wilderness Lever", new WorldPoint(2559, 3309, 0)), + WILDERNESS_LEVER_EDGEVILLE("Wilderness Lever", new WorldPoint(3088, 3474, 0)), + WILDERNESS_LEVER_WILDERNESS("Wilderness Lever", new WorldPoint(3154, 3924, 0)); - //Teleports - TELEPORT_ARCHIVE_FROM_ARCEUUS("Teleport to - Library archive", new WorldPoint(1623,3808,0)), - TELEPORT_HARMELSS_FROM_HARMONY("Teleport to - Mos le Harmless", new WorldPoint(3784,2828,0)), - TELEPORT_RUNE_FROM_ARDOUGNE("Teleport to - Rune Eccense", new WorldPoint(2681,3325,0)), - TELEPORT_RUNE_FROM_YANILLE("Teleport to - Rune Eccense", new WorldPoint(2592,3089,0)), - TELEPORT_SORCERESS_GARDEN("Teleport to - Sorceress`s garden", new WorldPoint(3320,3141,0)), - - //Other - ALTER_KOUREND_UNDERGROUND("Altar", new WorldPoint(1662,10047,0)), - FAIRY_RING_ZANRIS_TO_KHARID("Fairy Ring to - Al Kharid", new WorldPoint(2483,4471,0)), - FAIRY_RING_ZANRIS_TO_SHACK("Fairy Ring to - Shack", new WorldPoint(2451,4471,0)), - MOUNTAIN_GUIDE_QUIDAMORTEM("Mountain Guide", new WorldPoint(1275,3559,0)), - MOUNTAIN_GUIDE_WALL("Mountain Guide", new WorldPoint(1400,3538,0)), - MUSHTREE_MUSHROOM_FOREST("Mushtree", new WorldPoint(3674,3871,0)), - MUSHTREE_TAR_SWAMP("Mushtree", new WorldPoint(3676,3755,0)), - MUSHTREE_VERDANT_VALLEY("Mushtree", new WorldPoint(3757,3756,0)), - MYTHS_GUILD_PORTAL("Portal", new WorldPoint(2456,2856,0)), - TRAINSTATION_KELDAGRIM("Trainstation", new WorldPoint(2941,10179,0)), - WILDERNESS_LEVER_ARDOUGNE("Wilderness Lever", new WorldPoint(2559,3309,0)), - WILDERNESS_LEVER_EDGEVILLE("Wilderness Lever", new WorldPoint(3088,3474,0)), - WILDERNESS_LEVER_WILDERNESS("Wilderness Lever", new WorldPoint(3154,3924,0)); - - - @Getter - private final String tooltip; - - @Getter - private final WorldPoint location; - - TransportationPointLocation(String description, WorldPoint location) - { - this.tooltip = description; - this.location = location; - } - -} \ No newline at end of file + private final String tooltip; + private final WorldPoint location; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WayPointWorldMapListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WayPointWorldMapListener.java deleted file mode 100644 index 5540a2a0fb..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WayPointWorldMapListener.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2019, Yani - * 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.worldmap; - -import net.runelite.api.*; -import net.runelite.api.Point; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.input.MouseAdapter; - -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.swing.*; -import java.awt.*; -import java.awt.event.MouseEvent; - -@Singleton -public class WayPointWorldMapListener extends MouseAdapter -{ - - private final Client client; - - private final WorldMapConfig config; - private final WorldMapPlugin plugin; - - @Inject - private WayPointWorldMapListener(Client client, WorldMapPlugin plugin, WorldMapConfig config) - { - this.client = client; - this.plugin = plugin; - this.config = config; - } - - @Override - public MouseEvent mouseClicked(MouseEvent e) - { - if (!SwingUtilities.isLeftMouseButton(e)) - { - return e; - } - - if (!config.isWaypointEnabled()) - { - return e; - } - - if (e.getClickCount() % 2 != 0) - { - return e; - } - - Widget mapWidget = client.getWidget(WidgetInfo.WORLD_MAP_VIEW); - - if (mapWidget == null) - { - return e; - } - - Rectangle worldMapRect = mapWidget.getBounds(); - Point mousePos = client.getMouseCanvasPosition(); - - if (!worldMapRect.contains(mousePos.getX(), mousePos.getY())) - { - return e; - } - - if (plugin.hasWayPoint()) - { - plugin.removeWayPoint(); - return e; - } - - RenderOverview ro = client.getRenderOverview(); - Float pixelsPerTile = ro.getWorldMapZoom(); - - // Get mouse location in world map window - int xMouseInBounds = mousePos.getX() - (int) worldMapRect.getX(); - int yMouseInBounds = mousePos.getY() - (int) worldMapRect.getY(); - - // Get center pixel because that's where we calculate the offset from - int xCenterPixel = (int) (worldMapRect.getWidth() / 2); - int yCenterPixel = (int) (worldMapRect.getHeight() / 2); - - // Get offset in amount of pixels and tiles - int xOffset = xMouseInBounds - xCenterPixel; - int yOffset = yCenterPixel - yMouseInBounds; - int xTileOffset = (int) (xOffset / pixelsPerTile); - int yTileOffset = (int) (yOffset / pixelsPerTile); - - // Get actual tile position - int xPos = ro.getWorldMapPosition().getX() + xTileOffset; - int yPos = ro.getWorldMapPosition().getY() + yTileOffset; - - plugin.setWayPoint(new WorldPoint(xPos, yPos, 0)); - - return e; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WayPointWorldMapPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WayPointWorldMapPoint.java deleted file mode 100644 index 058665a256..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WayPointWorldMapPoint.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2019, Yani - * 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.worldmap; - -import java.awt.image.BufferedImage; - -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; -import net.runelite.client.util.ImageUtil; - -class WayPointWorldMapPoint extends WorldMapPoint -{ - - WayPointWorldMapPoint(final WorldPoint worldPoint) - { - super(worldPoint, null); - - BufferedImage markerImage = ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, "waypoint_marker.png"); - - this.setSnapToEdge(true); - this.setJumpOnClick(true); - - this.setImage(markerImage); - - setTooltip("Waypoint"); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapConfig.java index 036c69d6a6..ca62df484d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapConfig.java @@ -1,16 +1,16 @@ /* * Copyright (c) 2018, Morgan Lewis - * Copyright (c) 2019, Yani * 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. + * 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 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 @@ -33,10 +33,10 @@ import net.runelite.client.config.ConfigItem; public interface WorldMapConfig extends Config { @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_FAIRY_RING_TOOLTIPS, - name = "Show fairy ring codes in tooltip", - description = "Display the code for fairy rings in the icon tooltip", - position = 1 + keyName = WorldMapPlugin.CONFIG_KEY_FAIRY_RING_TOOLTIPS, + name = "Show fairy ring codes in tooltip", + description = "Display the code for fairy rings in the icon tooltip", + position = 1 ) default boolean fairyRingTooltips() { @@ -44,10 +44,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_FAIRY_RING_ICON, - name = "Show fairy ring travel icon", - description = "Override the travel icon for fairy rings", - position = 2 + keyName = WorldMapPlugin.CONFIG_KEY_FAIRY_RING_ICON, + name = "Show fairy ring travel icon", + description = "Override the travel icon for fairy rings", + position = 2 ) default boolean fairyRingIcon() { @@ -55,10 +55,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_AGILITY_SHORTCUT_TOOLTIPS, - name = "Show agility level requirement", - description = "Display the required Agility level in the icon tooltip", - position = 3 + keyName = WorldMapPlugin.CONFIG_KEY_AGILITY_SHORTCUT_TOOLTIPS, + name = "Show agility level requirement", + description = "Display the required Agility level in the icon tooltip", + position = 3 ) default boolean agilityShortcutTooltips() { @@ -66,10 +66,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_AGILITY_SHORTCUT_LEVEL_ICON, - name = "Indicate inaccessible shortcuts", - description = "Indicate shortcuts you do not have the level to use on the icon", - position = 4 + keyName = WorldMapPlugin.CONFIG_KEY_AGILITY_SHORTCUT_LEVEL_ICON, + name = "Indicate inaccessible shortcuts", + description = "Indicate shortcuts you do not have the level to use on the icon", + position = 4 ) default boolean agilityShortcutLevelIcon() { @@ -77,10 +77,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_NORMAL_TELEPORT_ICON, - name = "Show Standard Spellbook destinations", - description = "Show icons at the destinations for teleports in the Standard Spellbook", - position = 5 + keyName = WorldMapPlugin.CONFIG_KEY_NORMAL_TELEPORT_ICON, + name = "Show Standard Spellbook destinations", + description = "Show icons at the destinations for teleports in the Standard Spellbook", + position = 5 ) default boolean normalTeleportIcon() { @@ -88,10 +88,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_MINIGAME_TOOLTIP, - name = "Show minigame name in tooltip", - description = "Display the name of the minigame in the icon tooltip", - position = 6 + keyName = WorldMapPlugin.CONFIG_KEY_MINIGAME_TOOLTIP, + name = "Show minigame name in tooltip", + description = "Display the name of the minigame in the icon tooltip", + position = 6 ) default boolean minigameTooltip() { @@ -99,10 +99,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_ANCIENT_TELEPORT_ICON, - name = "Show Ancient Magicks destinations", - description = "Show icons at the destinations for teleports in the Ancient Spellbook", - position = 7 + keyName = WorldMapPlugin.CONFIG_KEY_ANCIENT_TELEPORT_ICON, + name = "Show Ancient Magicks destinations", + description = "Show icons at the destinations for teleports in the Ancient Spellbook", + position = 7 ) default boolean ancientTeleportIcon() { @@ -110,10 +110,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_LUNAR_TELEPORT_ICON, - name = "Show Lunar Spellbook destinations", - description = "Show icons at the destinations for teleports in the Lunar Spellbook", - position = 8 + keyName = WorldMapPlugin.CONFIG_KEY_LUNAR_TELEPORT_ICON, + name = "Show Lunar Spellbook destinations", + description = "Show icons at the destinations for teleports in the Lunar Spellbook", + position = 8 ) default boolean lunarTeleportIcon() { @@ -121,10 +121,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_ARCEUUS_TELEPORT_ICON, - name = "Show Arceuus Spellbook destinations", - description = "Show icons at the destinations for teleports in the Arceuus Spellbook", - position = 9 + keyName = WorldMapPlugin.CONFIG_KEY_ARCEUUS_TELEPORT_ICON, + name = "Show Arceuus Spellbook destinations", + description = "Show icons at the destinations for teleports in the Arceuus Spellbook", + position = 9 ) default boolean arceuusTeleportIcon() { @@ -132,10 +132,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_JEWELLERY_TELEPORT_ICON, - name = "Show jewellery teleport locations", - description = "Show icons at the destinations for teleports from jewellery", - position = 10 + keyName = WorldMapPlugin.CONFIG_KEY_JEWELLERY_TELEPORT_ICON, + name = "Show jewellery teleport locations", + description = "Show icons at the destinations for teleports from jewellery", + position = 10 ) default boolean jewelleryTeleportIcon() { @@ -143,10 +143,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_SCROLL_TELEPORT_ICON, - name = "Show teleport scroll locations", - description = "Show icons at the destinations for teleports from scrolls", - position = 11 + keyName = WorldMapPlugin.CONFIG_KEY_SCROLL_TELEPORT_ICON, + name = "Show teleport scroll locations", + description = "Show icons at the destinations for teleports from scrolls", + position = 11 ) default boolean scrollTeleportIcon() { @@ -154,10 +154,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_MISC_TELEPORT_ICON, - name = "Show misc teleport locations", - description = "Show icons at the destinations for miscellaneous teleport items", - position = 12 + keyName = WorldMapPlugin.CONFIG_KEY_MISC_TELEPORT_ICON, + name = "Show misc teleport locations", + description = "Show icons at the destinations for miscellaneous teleport items", + position = 12 ) default boolean miscellaneousTeleportIcon() { @@ -165,10 +165,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_QUEST_START_TOOLTIPS, - name = "Show quest names", - description = "Indicates the names of quests and highlights incomplete ones", - position = 13 + keyName = WorldMapPlugin.CONFIG_KEY_QUEST_START_TOOLTIPS, + name = "Show quest names", + description = "Indicates the names of quests and highlights incomplete ones", + position = 13 ) default boolean questStartTooltips() { @@ -176,21 +176,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_QUEST_PROGRESS_ICON, - name = "Show quest progress", - description = "Indicates your quest progress", - position = 14 - ) - default boolean questProgressIcon() - { - return true; - } - - @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_FARMING_PATCH_TOOLTIPS, - name = "Show farming patch type", - description = "Display the type of farming patches in the icon tooltip", - position = 15 + keyName = WorldMapPlugin.CONFIG_KEY_FARMING_PATCH_TOOLTIPS, + name = "Show farming patch type", + description = "Display the type of farming patches in the icon tooltip", + position = 14 ) default boolean farmingPatchTooltips() { @@ -198,10 +187,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_RARE_TREE_TOOLTIPS, - name = "Show rare tree type", - description = "Display the type of rare tree in the icon tooltip", - position = 16 + keyName = WorldMapPlugin.CONFIG_KEY_RARE_TREE_TOOLTIPS, + name = "Show rare tree type", + description = "Display the type of rare tree in the icon tooltip", + position = 15 ) default boolean rareTreeTooltips() { @@ -209,10 +198,10 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_RARE_TREE_LEVEL_ICON, - name = "Indicate unavailable trees", - description = "Indicate rare trees you do not have the level to cut on the icon", - position = 17 + keyName = WorldMapPlugin.CONFIG_KEY_RARE_TREE_LEVEL_ICON, + name = "Indicate unavailable trees", + description = "Indicate rare trees you do not have the level to cut on the icon", + position = 16 ) default boolean rareTreeLevelIcon() { @@ -220,20 +209,12 @@ public interface WorldMapConfig extends Config } @ConfigItem( - keyName = WorldMapPlugin.CONFIG_KEY_TRANSPORATION_TELEPORT_TOOLTIPS, - name = "Show Transporation Tooltips", - description = "Indicates type of Transporation", - position = 17 + keyName = WorldMapPlugin.CONFIG_KEY_TRANSPORATION_TELEPORT_TOOLTIPS, + name = "Show transporation tooltips", + description = "Indicates types and destinations of Transporation", + position = 17 ) - default boolean TransportationTeleportTooltips() { return true; } - - @ConfigItem( - keyName = "isWaypointEnabled", - name = "Enable waypoint", - description = "Allows you to set a waypoint by double clicking on the worldmap", - position = 17 - ) - default boolean isWaypointEnabled() + default boolean transportationTeleportTooltips() { return true; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java index 63da32b6b1..5fd38d5ff2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java @@ -1,16 +1,16 @@ /* * Copyright (c) 2018, Morgan Lewis - * Copyright (c) 2019, Yani * 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. + * 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 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 @@ -25,42 +25,27 @@ */ package net.runelite.client.plugins.worldmap; -import com.google.common.base.Strings; -import com.google.gson.Gson; import com.google.inject.Inject; import com.google.inject.Provides; - import java.awt.image.BufferedImage; import java.util.Arrays; - - -import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.Experience; -import net.runelite.api.GameState; import net.runelite.api.Skill; -import net.runelite.api.events.*; -import net.runelite.api.widgets.WidgetID; -import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ExperienceChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.client.chat.ChatMessageBuilder; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.AgilityShortcut; -import net.runelite.client.input.MouseManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager; import net.runelite.client.util.ImageUtil; @PluginDescriptor( - name = "World Map", - description = "Enhance the world map to display additional information", - tags = {"agility", "fairy", "farming", "rings", "teleports"} + name = "World Map", + description = "Enhance the world map to display additional information", + tags = {"agility", "fairy", "farming", "rings", "teleports"} ) public class WorldMapPlugin extends Plugin { @@ -68,9 +53,6 @@ public class WorldMapPlugin extends Plugin private static final BufferedImage FAIRY_TRAVEL_ICON; private static final BufferedImage NOPE_ICON; - private static final BufferedImage STARTED_ICON; - private static final BufferedImage FINISHED_ICON; - static final String CONFIG_KEY = "worldmap"; static final String CONFIG_KEY_FAIRY_RING_TOOLTIPS = "fairyRingTooltips"; static final String CONFIG_KEY_FAIRY_RING_ICON = "fairyRingIcon"; @@ -84,17 +66,12 @@ public class WorldMapPlugin extends Plugin static final String CONFIG_KEY_SCROLL_TELEPORT_ICON = "scrollIcon"; static final String CONFIG_KEY_MISC_TELEPORT_ICON = "miscellaneousTeleportIcon"; static final String CONFIG_KEY_QUEST_START_TOOLTIPS = "questStartTooltips"; - static final String CONFIG_KEY_QUEST_PROGRESS_ICON = "questProgressIcon"; static final String CONFIG_KEY_MINIGAME_TOOLTIP = "minigameTooltip"; static final String CONFIG_KEY_FARMING_PATCH_TOOLTIPS = "farmingpatchTooltips"; static final String CONFIG_KEY_RARE_TREE_TOOLTIPS = "rareTreeTooltips"; static final String CONFIG_KEY_RARE_TREE_LEVEL_ICON = "rareTreeIcon"; static final String CONFIG_KEY_TRANSPORATION_TELEPORT_TOOLTIPS = "transportationTooltips"; - static final String WAYPOINT_SET_MESSAGE = "You have set a waypoint."; - static final String WAYPOINT_UNSET_MESSAGE = "You have cleared your waypoint."; - static final String WAYPOINT_ACTIVE_MESSAGE = "You have an active waypoint."; - static { //A size of 17 gives us a buffer when triggering tooltips @@ -109,43 +86,20 @@ public class WorldMapPlugin extends Plugin NOPE_ICON = new BufferedImage(iconBufferSize, iconBufferSize, BufferedImage.TYPE_INT_ARGB); final BufferedImage nopeImage = ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, "nope_icon.png"); NOPE_ICON.getGraphics().drawImage(nopeImage, 1, 1, null); - - STARTED_ICON = new BufferedImage(iconBufferSize, iconBufferSize, BufferedImage.TYPE_INT_ARGB); - final BufferedImage startedIcon = ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, "quest_started_icon.png"); - STARTED_ICON.getGraphics().drawImage(startedIcon, 1, 1, null); - FINISHED_ICON = new BufferedImage(iconBufferSize, iconBufferSize, BufferedImage.TYPE_INT_ARGB); - final BufferedImage finishedIcon = ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, "quest_complete_icon.png"); - FINISHED_ICON.getGraphics().drawImage(finishedIcon, 1, 1, null); } @Inject private Client client; - @Inject - private ConfigManager configManager; - @Inject private WorldMapConfig config; @Inject private WorldMapPointManager worldMapPointManager; - @Inject - private MouseManager mouseManager; - - @Inject - private WayPointWorldMapListener wayPointWorldMapListener; - - @Inject - private ChatMessageManager chatMessageManager; - private int agilityLevel = 0; private int woodcuttingLevel = 0; - private WorldPoint wayPoint; - - private static final Gson gson = new Gson(); - @Provides WorldMapConfig provideConfig(ConfigManager configManager) { @@ -158,23 +112,6 @@ public class WorldMapPlugin extends Plugin agilityLevel = client.getRealSkillLevel(Skill.AGILITY); woodcuttingLevel = client.getRealSkillLevel(Skill.WOODCUTTING); updateShownIcons(); - - mouseManager.registerMouseListener(wayPointWorldMapListener); - wayPoint = loadWayPoint(); - - if (wayPoint != null) - { - updateWayPoint(); - } - } - - @Subscribe - private void onWidgetLoaded(WidgetLoaded l) - { - if (l.getGroupId() == WidgetID.WORLD_MAP_GROUP_ID) - { - updateQuestStartPointIcons(); - } } @Override @@ -188,25 +125,8 @@ public class WorldMapPlugin extends Plugin worldMapPointManager.removeIf(MinigamePoint.class::isInstance); worldMapPointManager.removeIf(FarmingPatchPoint.class::isInstance); worldMapPointManager.removeIf(RareTreePoint.class::isInstance); - worldMapPointManager.removeIf(WayPointWorldMapPoint.class::isInstance); - agilityLevel = 0; woodcuttingLevel = 0; - - if (wayPoint != null) - { - client.clearHintArrow(); - } - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - { - sendChatMessage(WAYPOINT_ACTIVE_MESSAGE); - updateWayPoint(); - } } @Subscribe @@ -218,8 +138,6 @@ public class WorldMapPlugin extends Plugin } updateShownIcons(); - updateQuestStartPointIcons(); - updateWayPoint(); } @Subscribe @@ -249,14 +167,15 @@ public class WorldMapPlugin extends Plugin private void updateAgilityIcons() { worldMapPointManager.removeIf(AgilityShortcutPoint.class::isInstance); + if (config.agilityShortcutLevelIcon() || config.agilityShortcutTooltips()) { Arrays.stream(AgilityShortcut.values()) - .filter(value -> value.getWorldMapLocation() != null) - .map(value -> new AgilityShortcutPoint(value, - agilityLevel > 0 && config.agilityShortcutLevelIcon() && value.getLevel() > agilityLevel ? NOPE_ICON : BLANK_ICON, - config.agilityShortcutTooltips())) - .forEach(worldMapPointManager::add); + .filter(value -> value.getWorldMapLocation() != null) + .map(value -> new AgilityShortcutPoint(value, + agilityLevel > 0 && config.agilityShortcutLevelIcon() && value.getLevel() > agilityLevel ? NOPE_ICON : BLANK_ICON, + config.agilityShortcutTooltips())) + .forEach(worldMapPointManager::add); } } @@ -267,59 +186,13 @@ public class WorldMapPlugin extends Plugin if (config.rareTreeLevelIcon() || config.rareTreeTooltips()) { Arrays.stream(RareTreeLocation.values()).forEach(rareTree -> - Arrays.stream(rareTree.getLocations()) - .map(point -> new RareTreePoint(point, - rareTree.getTooltip(), - woodcuttingLevel > 0 && config.rareTreeLevelIcon() && - rareTree.getLevelReq() > woodcuttingLevel ? NOPE_ICON : BLANK_ICON, - config.rareTreeTooltips())) - .forEach(worldMapPointManager::add)); - } - } - - private void updateQuestStartPointIcons() - { - worldMapPointManager.removeIf(QuestStartPoint.class::isInstance); - - if (config.questStartTooltips() || config.questProgressIcon()) - { - Arrays.stream(QuestStartLocation.values()) - .map(value -> - { - BufferedImage icon; - String tooltip = ""; - - if (config.questStartTooltips()) - { - tooltip += " - " + value.getTooltip(); - } - - if (config.questProgressIcon() && value.getQuest() != null) - { - switch (value.getQuest().getState(client)) - { - case FINISHED: - icon = FINISHED_ICON; - tooltip += " - Finished"; - break; - case IN_PROGRESS: - icon = STARTED_ICON; - tooltip += " - Started"; - break; - default: - icon = BLANK_ICON; - break; - } - } - else - { - icon = BLANK_ICON; - } - - return new QuestStartPoint(value, icon, tooltip); - - }) - .forEach(worldMapPointManager::add); + Arrays.stream(rareTree.getLocations()) + .map(point -> new RareTreePoint(point, + rareTree.getTooltip(), + woodcuttingLevel > 0 && config.rareTreeLevelIcon() && + rareTree.getLevelReq() > woodcuttingLevel ? NOPE_ICON : BLANK_ICON, + config.rareTreeTooltips())) + .forEach(worldMapPointManager::add)); } } @@ -332,141 +205,70 @@ public class WorldMapPlugin extends Plugin if (config.fairyRingIcon() || config.fairyRingTooltips()) { Arrays.stream(FairyRingLocation.values()) - .map(value -> new FairyRingPoint(value, - config.fairyRingIcon() ? FAIRY_TRAVEL_ICON : BLANK_ICON, - config.fairyRingTooltips())) - .forEach(worldMapPointManager::add); + .map(value -> new FairyRingPoint(value, + config.fairyRingIcon() ? FAIRY_TRAVEL_ICON : BLANK_ICON, + config.fairyRingTooltips())) + .forEach(worldMapPointManager::add); } worldMapPointManager.removeIf(MinigamePoint.class::isInstance); if (config.minigameTooltip()) { Arrays.stream(MinigameLocation.values()) - .map(value -> new MinigamePoint(value, BLANK_ICON)) - .forEach(worldMapPointManager::add); + .map(value -> new MinigamePoint(value, BLANK_ICON)) + .forEach(worldMapPointManager::add); + } + + worldMapPointManager.removeIf(QuestStartPoint.class::isInstance); + if (config.questStartTooltips()) + { + Arrays.stream(QuestStartLocation.values()) + .map(value -> new QuestStartPoint(value, BLANK_ICON)) + .forEach(worldMapPointManager::add); } worldMapPointManager.removeIf(TransportationPoint.class::isInstance); - if (config.TransportationTeleportTooltips()) + if (config.transportationTeleportTooltips()) { Arrays.stream(TransportationPointLocation.values()) .map(value -> new TransportationPoint(value, BLANK_ICON)) .forEach((worldMapPointManager::add)); - } - worldMapPointManager.removeIf(FarmingPatchPoint.class::isInstance); if (config.farmingPatchTooltips()) { Arrays.stream(FarmingPatchLocation.values()).forEach(location -> - Arrays.stream(location.getLocations()) - .map(point -> new FarmingPatchPoint(point, location.getTooltip(), BLANK_ICON)) - .forEach(worldMapPointManager::add) + Arrays.stream(location.getLocations()) + .map(point -> new FarmingPatchPoint(point, location.getTooltip(), BLANK_ICON)) + .forEach(worldMapPointManager::add) ); } worldMapPointManager.removeIf(TeleportPoint.class::isInstance); Arrays.stream(TeleportLocationData.values()) - .filter(data -> + .filter(data -> + { + switch (data.getType()) { - switch (data.getType()) - { - case NORMAL_MAGIC: - return config.normalTeleportIcon(); - case ANCIENT_MAGICKS: - return config.ancientTeleportIcon(); - case LUNAR_MAGIC: - return config.lunarTeleportIcon(); - case ARCEUUS_MAGIC: - return config.arceuusTeleportIcon(); - case JEWELLERY: - return config.jewelleryTeleportIcon(); - case SCROLL: - return config.scrollTeleportIcon(); - case OTHER: - return config.miscellaneousTeleportIcon(); - default: - return false; - } - }).map(TeleportPoint::new) - .forEach(worldMapPointManager::add); - } - - private WorldPoint loadWayPoint() - { - String json = configManager.getConfiguration(WorldMapPlugin.CONFIG_KEY, "waypoint_data"); - - if (Strings.isNullOrEmpty(json)) - { - return null; - } - - return gson.fromJson(json, WorldPoint.class); - } - - private void saveWayPoint() - { - if (wayPoint == null) - { - configManager.unsetConfiguration(WorldMapPlugin.CONFIG_KEY, "waypoint_data"); - return; - } - - String json = gson.toJson(wayPoint); - configManager.setConfiguration(WorldMapPlugin.CONFIG_KEY, "waypoint_data", json); - } - - public void setWayPoint(WorldPoint point) - { - wayPoint = point; - saveWayPoint(); - updateWayPoint(); - sendChatMessage(WAYPOINT_SET_MESSAGE); - } - - public void removeWayPoint() - { - wayPoint = null; - saveWayPoint(); - updateWayPoint(); - sendChatMessage(WAYPOINT_UNSET_MESSAGE); - } - - public boolean hasWayPoint() - { - return (wayPoint != null); - } - - private void updateWayPoint() - { - client.clearHintArrow(); - worldMapPointManager.removeIf(WayPointWorldMapPoint.class::isInstance); - - if (!config.isWaypointEnabled()) - { - return; - } - - if (wayPoint == null) - { - return; - } - - client.setHintArrow(wayPoint); - worldMapPointManager.add(new WayPointWorldMapPoint(wayPoint)); - } - - private void sendChatMessage(String chatMessage) - { - final String message = new ChatMessageBuilder() - .append(chatMessage) - .build(); - - chatMessageManager.queue( - QueuedMessage.builder() - .type(ChatMessageType.CONSOLE) - .runeLiteFormattedMessage(message) - .build()); + case NORMAL_MAGIC: + return config.normalTeleportIcon(); + case ANCIENT_MAGICKS: + return config.ancientTeleportIcon(); + case LUNAR_MAGIC: + return config.lunarTeleportIcon(); + case ARCEUUS_MAGIC: + return config.arceuusTeleportIcon(); + case JEWELLERY: + return config.jewelleryTeleportIcon(); + case SCROLL: + return config.scrollTeleportIcon(); + case OTHER: + return config.miscellaneousTeleportIcon(); + default: + return false; + } + }).map(TeleportPoint::new) + .forEach(worldMapPointManager::add); } } 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/zoneIndicators/MapLocations.java deleted file mode 100644 index 81e8e0f527..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java +++ /dev/null @@ -1,3479 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import java.awt.Polygon; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.geom.Area; -import java.util.ArrayList; -import java.util.List; -import net.runelite.api.Constants; - -public class MapLocations -{ - private static final List[] MULTICOMBAT = new List[Constants.MAX_Z]; - private static final List[] NOT_MULTICOMBAT = new List[Constants.MAX_Z]; - private static final List[] ROUGH_WILDERNESS = new List[Constants.MAX_Z]; - private static final List[] DEADMAN_SAFE_ZONES = new List[Constants.MAX_Z]; - private static final List[] PVP_WORLD_SAFE_ZONES = new List[Constants.MAX_Z]; - - private static Area getArea(List shapes) - { - Area area = new Area(); - for (Shape shape : shapes) - { - area.add(new Area(shape)); - } - return area; - } - - private static Area getArea(List shapes, Rectangle view) - { - Area area = new Area(); - for (Shape shape : shapes) - { - if (shape.intersects(view)) - { - area.add(new Area(shape)); - } - } - return area; - } - - public static Area getMulticombat(int plane) - { - Area area = getArea(MULTICOMBAT[plane]); - area.subtract(getArea(NOT_MULTICOMBAT[plane])); - return area; - } - - public static Area getMulticombat(Rectangle view, int plane) - { - Area area = getArea(MULTICOMBAT[plane], view); - area.subtract(getArea(NOT_MULTICOMBAT[plane], view)); - return area; - } - - public static Area getRoughWilderness(int plane) - { - return getArea(ROUGH_WILDERNESS[plane]); - } - - public static Area getRoughWilderness(Rectangle view, int plane) - { - return getArea(ROUGH_WILDERNESS[plane], view); - } - - public static Area getDeadmanSafeZones(int plane) - { - return getArea(DEADMAN_SAFE_ZONES[plane]); - } - - public static Area getDeadmanSafeZones(Rectangle view, int plane) - { - return getArea(DEADMAN_SAFE_ZONES[plane], view); - } - - public static Area getPvpSafeZones(int plane) - { - return getArea(PVP_WORLD_SAFE_ZONES[plane]); - } - - public static Area getPvpSafeZones(Rectangle view, int plane) - { - return getArea(PVP_WORLD_SAFE_ZONES[plane], view); - } - - static - { - for (int i = 0; i < MULTICOMBAT.length; i++) - { - MULTICOMBAT[i] = new ArrayList<>(); - } - for (int i = 0; i < NOT_MULTICOMBAT.length; i++) - { - NOT_MULTICOMBAT[i] = new ArrayList<>(); - } - for (int i = 0; i < ROUGH_WILDERNESS.length; i++) - { - ROUGH_WILDERNESS[i] = new ArrayList<>(); - } - for (int i = 0; i < DEADMAN_SAFE_ZONES.length; i++) - { - DEADMAN_SAFE_ZONES[i] = new ArrayList<>(); - } - for (int i = 0; i < PVP_WORLD_SAFE_ZONES.length; i++) - { - PVP_WORLD_SAFE_ZONES[i] = new ArrayList<>(); - } - - defineMulticombatAreas(); - defineDeadmanSafeZones(); - definePvpSafeZones(); - defineWilderness(); - } - - private static void defineMulticombatAreas() - { - // Main Wilderness - addPolygonOnPlane(MULTICOMBAT, 0, - 3200, 3968, - 3392, 3968, - 3392, 3840, - 3328, 3840, - 3328, 3520, - 3136, 3520, - 3136, 3648, - 3192, 3648, - 3192, 3752, - 3152, 3752, - 3152, 3840, - 3136, 3840, - 3136, 3872, - 3112, 3872, - 3112, 3880, - 3072, 3880, - 3072, 3896, - 3048, 3896, - 3048, 3872, - 3056, 3872, - 3056, 3864, - 3048, 3864, - 3048, 3856, - 3008, 3856, - 3008, 3904, - 3200, 3904); - - // South of wildy agility training arena - addPolygonOnPlane(MULTICOMBAT, 0, - 2984, 3928, - 3008, 3928, - 3008, 3912, - 2984, 3912); - - // Wildy zamorak temple - addPolygonOnPlane(MULTICOMBAT, 0, - 2944, 3832, - 2960, 3832, - 2960, 3816, - 2944, 3816); - - // Wildy bandit camp - addPolygonOnPlane(MULTICOMBAT, 0, - 3008, 3712, - 3072, 3712, - 3072, 3600, - 3008, 3600); - - // Chaos temple north of Falador - addPolygonOnPlane(MULTICOMBAT, 0, - 2928, 3520, - 2944, 3520, - 2944, 3512, - 2928, 3512); - - // Burthorpe - addPolygonOnPlane(MULTICOMBAT, 0, - 2880, 3544, - 2904, 3544, - 2904, 3520, - 2880, 3520); - - // White Wolf Mountain - addPolygonOnPlane(MULTICOMBAT, 0, - 2880, 3520, - 2816, 3520, - 2816, 3456, - 2880, 3456); - - // Death Plateu - addPolygonOnPlane(MULTICOMBAT, 0, - 2848, 3608, - 2880, 3608, - 2880, 3600, - 2848, 3600); - - // Trollheim/Godwars - addPolygonOnPlane(MULTICOMBAT, 0, - 2880, 3776, - 2912, 3776, - 2912, 3696, - 2920, 3696, - 2920, 3688, - 2896, 3688, - 2896, 3696, - 2880, 3696, - 2880, 3728, - 2888, 3728, - 2888, 3744, - 2880, 3744); - - // Northen Rellekka - addPolygonOnPlane(MULTICOMBAT, 0, - 2656, 3736, - 2704, 3736, - 2704, 3728, - 2712, 3728, - 2712, 3736, - 2736, 3736, - 2736, 3712, - 2656, 3712); - - // Northen Fremennik Isles - addPolygonOnPlane(MULTICOMBAT, 0, - 2304, 3904, - 2432, 3904, - 2432, 3840, - 2368, 3840, - 2368, 3816, - 2352, 3816, - 2352, 3824, - 2304, 3824); - - // Pirates Cove - addPolygonOnPlane(MULTICOMBAT, 0, - 2176, 3840, - 2240, 3840, - 2240, 3776, - 2176, 3776); - - // Lunar Isle - addPolygonOnPlane(MULTICOMBAT, 0, - 2048, 3968, - 2176, 3968, - 2176, 3840, - 2048, 3840); - - // Piscatoris Fishing Colony - addPolygonOnPlane(MULTICOMBAT, 0, - 2304, 3712, - 2368, 3712, - 2368, 3648, - 2304, 3648); - - // Ranging Guild - addPolygonOnPlane(MULTICOMBAT, 0, - 2656, 3448, - 2680, 3448, - 2680, 3440, - 2688, 3440, - 2688, 3416, - 2680, 3416, - 2680, 3408, - 2656, 3408, - 2656, 3416, - 2648, 3416, - 2648, 3440, - 2656, 3440); - - // Necromancer house, southeast of Ardy - addPolygonOnPlane(MULTICOMBAT, 0, - 2656, 3256, - 2680, 3256, - 2680, 3216, - 2664, 3216, - 2664, 3232, - 2656, 3232); - - // Battlefield noth of Tree Gnome Village - addPolygonOnPlane(MULTICOMBAT, 0, - 2504, 3248, - 2544, 3248, - 2544, 3232, - 2552, 3232, - 2552, 3208, - 2504, 3208); - - // Castle Wars - addPolygonOnPlane(MULTICOMBAT, 0, - 2368, 3136, - 2432, 3136, - 2432, 3072, - 2368, 3072); - - // Jiggig - addPolygonOnPlane(MULTICOMBAT, 0, - 2456, 3056, - 2496, 3056, - 2496, 3032, - 2456, 3032); - - // East feldip hills, near rantz - addPolygonOnPlane(MULTICOMBAT, 0, - 2648, 2976, - 2656, 2976, - 2656, 2952, - 2648, 2952); - - // Ape Atoll - addPolygonOnPlane(MULTICOMBAT, 0, - 2688, 2816, - 2816, 2816, - 2816, 2688, - 2688, 2688); - - // Pest Control - addPolygonOnPlane(MULTICOMBAT, 0, - 2624, 2624, - 2688, 2624, - 2688, 2560, - 2624, 2560); - - // Desert Bandit Camp - addPolygonOnPlane(MULTICOMBAT, 0, - 3152, 3000, - 3192, 3000, - 3192, 2960, - 3152, 2960); - - // Al Kharid - addPolygonOnPlane(MULTICOMBAT, 0, - 3264, 3200, - 3328, 3200, - 3328, 3136, - 3264, 3136); - - // Wizards Tower - addPolygonOnPlane(MULTICOMBAT, 0, - 3094, 3176, - 3126, 3176, - 3126, 3144, - 3094, 3144); - - // Draynor Village - addPolygonOnPlane(MULTICOMBAT, 0, - 3112, 3264, - 3136, 3264, - 3136, 3232, - 3104, 3232, - 3104, 3256, - 3112, 3256); - - // Falador - addPolygonOnPlane(MULTICOMBAT, 0, - 2944, 3456, - 3008, 3456, - 3008, 3328, - 3016, 3328, - 3016, 3304, - 2944, 3304); - - // Southwest fally castle isn't multicombat downstairs - addPolygonOnPlane(NOT_MULTICOMBAT, 0, - 2968, 3336, - 2968, 3328, - 2960, 3328, - 2960, 3336); - - // Barbarian Village - addPolygonOnPlane(MULTICOMBAT, 0, - 3072, 3456, - 3136, 3456, - 3136, 3392, - 3048, 3392, - 3048, 3408, - 3056, 3408, - 3056, 3440, - 3064, 3440, - 3064, 3448, - 3072, 3448); - - // Ammoniate crabs at northwest fossil island - addPolygonOnPlane(MULTICOMBAT, 0, - 3648, 3885, - 3663, 3885, - 3663, 3882, - 3664, 3882, - 3664, 3872, - 3663, 3872, - 3663, 3868, - 3648, 3868); - - // Ammoniate crabs at north fossil island - addPolygonOnPlane(MULTICOMBAT, 0, - 3680, 3904, - 3744, 3904, - 3744, 3856, - 3756, 3856, - 3756, 3852, - 3755, 3852, - 3755, 3851, - 3754, 3851, - 3754, 3850, - 3751, 3850, - 3751, 3849, - 3750, 3849, - 3750, 3848, - 3749, 3848, - 3749, 3847, - 3748, 3847, - 3748, 3846, - 3747, 3846, - 3747, 3845, - 3746, 3845, - 3746, 3844, - 3742, 3844, - 3742, 3845, - 3740, 3845, - 3740, 3844, - 3732, 3844, - 3732, 3843, - 3730, 3843, - 3730, 3842, - 3724, 3842, - 3724, 3843, - 3717, 3843, - 3717, 3842, - 3712, 3842, - 3712, 3846, - 3710, 3846, - 3710, 3847, - 3709, 3847, - 3709, 3848, - 3708, 3848, - 3708, 3859, - 3709, 3859, - 3709, 3860, - 3710, 3860, - 3710, 3861, - 3712, 3861, - 3712, 3866, - 3713, 3866, - 3713, 3870, - 3714, 3870, - 3714, 3873, - 3713, 3873, - 3713, 3876, - 3712, 3876, - 3712, 3881, - 3710, 3881, - 3710, 3888, - 3712, 3888, - 3712, 3890, - 3714, 3890, - 3714, 3891, - 3716, 3891, - 3716, 3892, - 3717, 3892, - 3717, 3893, - 3716, 3893, - 3716, 3894, - 3714, 3894, - 3714, 3895, - 3713, 3895, - 3713, 3896, - 3712, 3896, - 3712, 3897, - 3705, 3897, - 3705, 3898, - 3704, 3898, - 3704, 3899, - 3692, 3899, - 3692, 3898, - 3688, 3898, - 3688, 3897, - 3686, 3897, - 3686, 3896, - 3680, 3896); - - // Zeah, southwest of Wintertodt, snowy area with ice giants and wolves - addPolygonOnPlane(MULTICOMBAT, 0, - 1540, 3898, - 1543, 3898, - 1543, 3901, - 1546, 3901, - 1546, 3903, - 1547, 3903, - 1547, 3904, - 1550, 3904, - 1550, 3903, - 1553, 3903, - 1553, 3904, - 1559, 3904, - 1559, 3902, - 1564, 3902, - 1564, 3903, - 1565, 3903, - 1565, 3904, - 1568, 3904, - 1568, 3903, - 1569, 3903, - 1569, 3902, - 1570, 3902, - 1570, 3901, - 1573, 3901, - 1573, 3898, - 1577, 3898, - 1577, 3899, - 1578, 3899, - 1578, 3902, - 1579, 3902, - 1579, 3903, - 1584, 3903, - 1584, 3902, - 1586, 3902, - 1586, 3901, - 1590, 3901, - 1590, 3891, - 1588, 3891, - 1588, 3887, - 1572, 3887, - 1572, 3872, - 1567, 3872, - 1567, 3868, - 1563, 3868, - 1563, 3867, - 1558, 3867, - 1558, 3868, - 1557, 3868, - 1557, 3870, - 1549, 3870, - 1549, 3874, - 1545, 3874, - 1545, 3876, - 1543, 3876, - 1543, 3877, - 1542, 3877, - 1542, 3879, - 1541, 3879, - 1541, 3882, - 1539, 3882, - 1539, 3887, - 1540, 3887, - 1540, 3888, - 1539, 3888, - 1539, 3894, - 1540, 3894); - - // Zeah arceuus area - addPolygonOnPlane(MULTICOMBAT, 0, - 1664, 3776, - 1664, 3785, - 1667, 3785, - 1667, 3805, - 1671, 3805, - 1671, 3811, - 1675, 3811, - 1675, 3819, - 1690, 3819, - 1690, 3814, - 1695, 3814, - 1695, 3806, - 1719, 3806, - 1719, 3787, - 1725, 3787, - 1725, 3778, - 1711, 3778, - 1711, 3776); - - // Arceuus teletab-making house - addPolygonOnPlane(MULTICOMBAT, 0, - 1667, 3772, - 1679, 3772, - 1679, 3775, - 1691, 3775, - 1691, 3761, - 1679, 3761, - 1679, 3764, - 1667, 3764); - // Next house east - addPolygonOnPlane(MULTICOMBAT, 0, - 1696, 3775, - 1708, 3775, - 1708, 3763, - 1696, 3763); - // Next house east - addPolygonOnPlane(MULTICOMBAT, 0, - 1713, 3775, - 1727, 3775, - 1727, 3763, - 1724, 3763, - 1724, 3752, - 1716, 3752, - 1716, 3763, - 1713, 3763); - // Arceuus rune shop house - addPolygonOnPlane(MULTICOMBAT, 0, - 1716, 3750, - 1728, 3750, - 1728, 3736, - 1716, 3736); - // Arceuus general store house - addPolygonOnPlane(MULTICOMBAT, 0, - 1717, 3732, - 1725, 3732, - 1725, 3715, - 1715, 3715, - 1715, 3725, - 1717, 3725); - // Arceuus pub - addPolygonOnPlane(MULTICOMBAT, 0, - 1683, 3732, - 1691, 3732, - 1691, 3725, - 1697, 3725, - 1697, 3730, - 1703, 3730, - 1703, 3712, - 1683, 3712); - // Arceuus staff store - addPolygonOnPlane(MULTICOMBAT, 0, - 1664, 3732, - 1676, 3732, - 1676, 3720, - 1664, 3720); - // Next house to the west - addPolygonOnPlane(MULTICOMBAT, 0, - 1647, 3738, - 1655, 3738, - 1655, 3726, - 1658, 3726, - 1658, 3714, - 1644, 3714, - 1644, 3726, - 1647, 3726); - // Next house to the north - addPolygonOnPlane(MULTICOMBAT, 0, - 1647, 3762, - 1657, 3762, - 1657, 3752, - 1655, 3752, - 1655, 3745, - 1647, 3745); - - // Arceuus house magic trees - addPolygonOnPlane(MULTICOMBAT, 0, - 1682, 3755, - 1692, 3755, - 1692, 3745, - 1690, 3745, - 1690, 3738, - 1682, 3738); - // West of that ^ - addPolygonOnPlane(MULTICOMBAT, 0, - 1667, 3756, - 1675, 3756, - 1675, 3740, - 1665, 3740, - 1665, 3746, - 1667, 3746); - - // This one goes through western piscarilius, northen hosidius - // and southwestern arceuus - addPolygonOnPlane(MULTICOMBAT, 0, - 1728, 3808, - 1792, 3808, - 1792, 3764, - 1856, 3764, - 1856, 3712, - 1792, 3712, - 1792, 3648, - 1664, 3648, - 1664, 3706, - 1665, 3706, - 1665, 3705, - 1668, 3705, - 1668, 3706, - 1671, 3706, - 1671, 3705, - 1675, 3705, - 1675, 3704, - 1683, 3704, - 1683, 3701, - 1684, 3701, - 1684, 3700, - 1686, 3700, - 1686, 3702, - 1687, 3702, - 1687, 3700, - 1688, 3700, - 1688, 3701, - 1690, 3701, - 1690, 3703, - 1689, 3703, - 1689, 3704, - 1690, 3704, - 1690, 3705, - 1704, 3705, - 1704, 3707, - 1706, 3707, - 1706, 3712, - 1711, 3712, - 1711, 3711, - 1710, 3711, - 1710, 3710, - 1712, 3710, - 1712, 3707, - 1728, 3707); - - // Kourend castle - addPolygonOnPlane(MULTICOMBAT, 0, - 1614, 3691, - 1619, 3691, - 1619, 3690, - 1620, 3690, - 1620, 3689, - 1653, 3689, - 1653, 3690, - 1654, 3690, - 1654, 3691, - 1657, 3691, - 1657, 3690, - 1658, 3690, - 1658, 3689, - 1659, 3689, - 1659, 3686, - 1658, 3686, - 1658, 3685, - 1657, 3685, - 1657, 3662, - 1658, 3662, - 1658, 3661, - 1659, 3661, - 1659, 3658, - 1658, 3658, - 1658, 3657, - 1657, 3657, - 1657, 3656, - 1654, 3656, - 1654, 3657, - 1653, 3657, - 1653, 3658, - 1620, 3658, - 1620, 3657, - 1619, 3657, - 1619, 3656, - 1614, 3656, - 1614, 3657, - 1613, 3657, - 1613, 3661, - 1612, 3661, - 1612, 3662, - 1611, 3662, - 1611, 3663, - 1600, 3663, - 1600, 3662, - 1599, 3662, - 1599, 3661, - 1594, 3661, - 1594, 3662, - 1593, 3662, - 1593, 3685, - 1594, 3685, - 1594, 3686, - 1599, 3686, - 1599, 3685, - 1600, 3685, - 1600, 3684, - 1611, 3684, - 1611, 3685, - 1612, 3685, - 1612, 3686, - 1613, 3686, - 1613, 3690, - 1614, 3690); - - // Western hosidius area, including woodcutting guild and western sand crabs - addPolygonOnPlane(MULTICOMBAT, 0, - 1650, 3648, - 1664, 3648, - 1664, 3520, - 1689, 3520, - 1689, 3496, - 1707, 3496, - 1707, 3485, - 1708, 3485, - 1708, 3484, - 1710, 3484, - 1710, 3483, - 1713, 3483, - 1713, 3482, - 1720, 3482, - 1720, 3481, - 1721, 3481, - 1721, 3480, - 1722, 3480, - 1722, 3479, - 1723, 3479, - 1723, 3478, - 1724, 3478, - 1724, 3477, - 1726, 3477, - 1726, 3476, - 1728, 3476, - 1728, 3472, - 1708, 3472, - 1708, 3456, - 1600, 3456, - 1600, 3584, - 1608, 3584, - 1608, 3616, - 1650, 3616); - - // Hosidius sand crabs - addPolygonOnPlane(MULTICOMBAT, 0, - 1740, 3478, - 1741, 3478, - 1741, 3479, - 1745, 3479, - 1745, 3480, - 1751, 3480, - 1751, 3479, - 1752, 3479, - 1752, 3478, - 1753, 3478, - 1753, 3477, - 1755, 3477, - 1755, 3476, - 1757, 3476, - 1757, 3475, - 1758, 3475, - 1758, 3474, - 1759, 3474, - 1759, 3473, - 1779, 3473, - 1779, 3474, - 1781, 3474, - 1781, 3475, - 1786, 3475, - 1786, 3476, - 1800, 3476, - 1800, 3475, - 1805, 3475, - 1805, 3474, - 1807, 3474, - 1807, 3473, - 1808, 3473, - 1808, 3472, - 1810, 3472, - 1810, 3471, - 1833, 3471, - 1833, 3470, - 1834, 3470, - 1834, 3469, - 1852, 3469, - 1852, 3449, - 1792, 3449, - 1792, 3424, - 1800, 3424, - 1800, 3449, - 1800, 3400, - 1728, 3400, - 1728, 3462, - 1729, 3462, - 1729, 3466, - 1730, 3466, - 1730, 3469, - 1731, 3469, - 1731, 3470, - 1732, 3470, - 1732, 3471, - 1733, 3471, - 1733, 3473, - 1734, 3473, - 1734, 3474, - 1736, 3474, - 1736, 3475, - 1737, 3475, - 1737, 3476, - 1738, 3476, - 1738, 3477, - 1740, 3477); - - // Apparently there is a 1x1 single zone on the sand crab island - addPolygonOnPlane(NOT_MULTICOMBAT, 0, - 1777, 3416, - 1777, 3417, - 1778, 3417, - 1778, 3416); - - // Eastern hosidius area - addPolygonOnPlane(MULTICOMBAT, 0, - 1834, 3584, - 1888, 3584, - 1888, 3528, - 1856, 3528, - 1856, 3520, - 1834, 3520, - 1834, 3522, - 1833, 3522, - 1833, 3535, - 1834, 3535, - 1834, 3538, - 1835, 3538, - 1835, 3539, - 1836, 3539, - 1836, 3540, - 1837, 3540, - 1837, 3541, - 1838, 3541, - 1838, 3542, - 1840, 3542, - 1840, 3543, - 1841, 3543, - 1841, 3545, - 1842, 3545, - 1842, 3546, - 1844, 3546, - 1844, 3547, - 1845, 3547, - 1845, 3548, - 1851, 3548, - 1851, 3551, - 1853, 3551, - 1853, 3563, - 1851, 3563, - 1851, 3566, - 1847, 3566, - 1847, 3567, - 1845, 3567, - 1845, 3568, - 1844, 3568, - 1844, 3569, - 1843, 3569, - 1843, 3571, - 1842, 3571, - 1842, 3573, - 1841, 3573, - 1841, 3574, - 1840, 3574, - 1840, 3575, - 1839, 3575, - 1839, 3576, - 1838, 3576, - 1838, 3577, - 1837, 3577, - 1837, 3578, - 1836, 3578, - 1836, 3579, - 1835, 3579, - 1835, 3581, - 1834, 3581); - - // Eastern hosidius area also has a 1x1 multi area - addPolygonOnPlane(MULTICOMBAT, 0, - 1849, 3563, - 1849, 3564, - 1850, 3564, - 1850, 3563); - - // Hosidius cows/chickens/pigs - addPolygonOnPlane(MULTICOMBAT, 0, - 1792, 3513, - 1802, 3513, - 1802, 3520, - 1810, 3520, - 1810, 3513, - 1816, 3513, - 1816, 3512, - 1836, 3512, - 1836, 3494, - 1796, 3494, - 1796, 3495, - 1792, 3495); - - // Hosidius southeast of tithe farm - addPolygonOnPlane(MULTICOMBAT, 0, - 1777, 3597, - 1794, 3597, - 1794, 3561, - 1777, 3561, - 1777, 3591, - 1779, 3591, - 1779, 3592, - 1777, 3592); - - // West of shayzien house - addPolygonOnPlane(MULTICOMBAT, 0, - 1408, 3584, - 1408, 3582, - 1486, 3582, - 1486, 3568, - 1528, 3568, - 1528, 3520, - 1408, 3520, - 1408, 3464, - 1380, 3464, - 1380, 3486, - 1377, 3486, - 1377, 3488, - 1373, 3488, - 1373, 3492, - 1364, 3492, - 1364, 3512, - 1358, 3512, - 1358, 3520, - 1356, 3520, - 1356, 3532, - 1358, 3532, - 1358, 3540, - 1359, 3540, - 1359, 3542, - 1360, 3542, - 1360, 3557, - 1356, 3557, - 1356, 3560, - 1351, 3560, - 1351, 3570, - 1354, 3570, - 1354, 3581, - 1346, 3581, - 1346, 3584); - - // South of chambers of xeric - addPolygonOnPlane(MULTICOMBAT, 0, - 1261, 3489, - 1259, 3489, - 1259, 3488, - 1255, 3488, - 1255, 3487, - 1243, 3487, - 1243, 3490, - 1234, 3490, - 1234, 3480, - 1192, 3480, - 1192, 3568, - 1209, 3568, - 1209, 3548, - 1215, 3548, - 1215, 3544, - 1217, 3544, - 1217, 3536, - 1235, 3536, - 1235, 3532, - 1249, 3532, - 1249, 3525, - 1248, 3525, - 1248, 3517, - 1254, 3517, - 1254, 3513, - 1274, 3513, - 1274, 3510, - 1296, 3510, - 1296, 3511, - 1300, 3511, - 1300, 3501, - 1287, 3501, - 1287, 3490, - 1280, 3490, - 1280, 3489, - 1264, 3489, - 1264, 3490, - 1261, 3490); - - // Lizardman shamans - addPolygonOnPlane(MULTICOMBAT, 0, - 1416, 3728, - 1456, 3728, - 1456, 3688, - 1416, 3688); - - // Other lizardman area at shayzien (west side) - addPolygonOnPlane(MULTICOMBAT, 0, - 1472, 3712, - 1510, 3712, - 1510, 3702, - 1509, 3702, - 1509, 3701, - 1506, 3701, - 1506, 3696, - 1500, 3696, - 1500, 3680, - 1472, 3680); - - // Other lizardman area at shayzien (east side) - addPolygonOnPlane(MULTICOMBAT, 0, - 1538, 3704, - 1560, 3704, - 1560, 3672, - 1538, 3672); - - // Lovakengj house - addPolygonOnPlane(MULTICOMBAT, 0, - 1600, 3712, - 1472, 3712, - 1472, 3840, - 1547, 3840, - 1547, 3816, - 1556, 3816, - 1556, 3809, - 1562, 3809, - 1562, 3800, - 1568, 3800, - 1568, 3793, - 1571, 3793, - 1571, 3816, - 1571, 3776, - 1600, 3776); - - // Shayzien house - addPolygonOnPlane(MULTICOMBAT, 0, - 1475, 3587, - 1475, 3641, - 1534, 3641, - 1534, 3587); - - // Shayzien house bank is non-multi - addPolygonOnPlane(NOT_MULTICOMBAT, 0, - 1495, 3622, - 1515, 3622, - 1515, 3612, - 1495, 3612); - - // Shayzien house general store - addPolygonOnPlane(MULTICOMBAT, 0, - 1539, 3640, - 1551, 3640, - 1551, 3621, - 1539, 3621); - - // Kourend woodland barbarian area - addPolygonOnPlane(MULTICOMBAT, 0, - 1572, 3442, - 1591, 3442, - 1591, 3424, - 1572, 3424); - - // Catacombs - addPolygonTo(MULTICOMBAT, - 1600, 9984, - 1600, 10067, - 1628, 10067, - 1628, 10070, - 1639, 10070, - 1639, 10112, - 1730, 10112, - 1730, 9984); - - // Zeah dungeon with sand crabs - addPolygonTo(MULTICOMBAT, - 1632, 9792, - 1632, 9856, - 1728, 9856, - 1728, 9792); - - // Waterbirth island near the doors where people use rune throwing axes - addPolygonTo(MULTICOMBAT, - 2536, 10136, - 2536, 10152, - 2552, 10152, - 2552, 10136); - - // Waterbirth island dungeon, on the path to dks - addPolygonTo(MULTICOMBAT, - 1792, 4352, - 1792, 4416, - 1984, 4416, - 1984, 4352); - - // Dagannoths in lighthouse - addPolygonTo(MULTICOMBAT, - 2496, 10048, - 2560, 10048, - 2560, 9984, - 2496, 9984); - - // Dagannoth kings (DKs) including slayer only dks - addPolygonTo(MULTICOMBAT, - 2944, 4352, - 2944, 4480, - 2880, 4480, - 2880, 4352); - - // White wolf mountain dungeon at ice queen - addPolygonTo(MULTICOMBAT, - 2856, 9928, - 2856, 9968, - 2880, 9968, - 2880, 9928); - - // Kharazi jungle dungeon (in dragon slayer 2 quest) - addPolygonTo(MULTICOMBAT, - 2816, 9296, - 2880, 9296, - 2880, 9216, - 2816, 9216); - - // Tzhaar, fight pits and inferno area - addPolygonTo(MULTICOMBAT, - 2368, 5184, - 2560, 5184, - 2560, 5056, - 2368, 5056); - - // Smoke devils - addPolygonTo(MULTICOMBAT, - 2432, 9408, - 2344, 9408, - 2344, 9472, - 2432, 9472); - - // Kraken - addPolygonTo(MULTICOMBAT, - 2270, 10045, - 2291, 10045, - 2291, 10022, - 2270, 10022); - - // Giant mole - addPolygonTo(MULTICOMBAT, - 1728, 5240, - 1792, 5240, - 1792, 5120, - 1728, 5120); - - // Godwars dungeon - addPolygonTo(MULTICOMBAT, - 2816, 5376, - 2944, 5376, - 2944, 5248, - 2816, 5248); - - // Desert treasure shadow diamond area - addPolygonTo(MULTICOMBAT, - 2752, 5064, - 2728, 5064, - 2728, 5088, - 2720, 5088, - 2720, 5096, - 2712, 5096, - 2712, 5112, - 2736, 5112, - 2736, 5120, - 2752, 5120); - - // Kalphite slayer area - addPolygonTo(MULTICOMBAT, - 3264, 9544, - 3344, 9544, - 3344, 9472, - 3264, 9472); - - // Normal kalphite area including kalphite queen - addPolygonTo(MULTICOMBAT, - 3456, 9536, - 3520, 9536, - 3520, 9472, - 3456, 9472); - - // Tarns lair - addPolygonTo(MULTICOMBAT, - 3136, 4664, - 3200, 4664, - 3200, 4544, - 3136, 4544); - - // Haunted mine boss area - addPolygonTo(MULTICOMBAT, - 2752, 4416, - 2752, 4480, - 2816, 4480, - 2816, 4416); - - // Entrance to dorgesh kaan - addPolygonTo(MULTICOMBAT, - 3328, 9600, - 3312, 9600, - 3312, 9640, - 3304, 9640, - 3304, 9664, - 3328, 9664); - - // Hammerspikes hangout in dwarven mines - addPolygonTo(MULTICOMBAT, - 2960, 9824, - 2976, 9824, - 2976, 9800, - 2960, 9800); - - // Fremennik isles dungeon - addPolygonTo(MULTICOMBAT, - 2432, 10304, - 2432, 10240, - 2368, 10240, - 2368, 10304); - - // Varrock sewers - addPolygonTo(MULTICOMBAT, - 3152, 9920, - 3288, 9920, - 3288, 9856, - 3152, 9856); - - // Stronghold of security 1st floor - addPolygonTo(MULTICOMBAT, - 1856, 5248, - 1920, 5248, - 1920, 5184, - 1856, 5184); - - // Corp cave - addPolygonTo(MULTICOMBAT, - 2960, 4400, - 3000, 4400, - 3000, 4368, - 2960, 4368); - - // ZMI altar area - addPolygonTo(MULTICOMBAT, - 3008, 5632, - 3072, 5632, - 3072, 5568, - 3008, 5568); - - // Dragon slayer 2 zeah underground puzzle - addPolygonTo(MULTICOMBAT, - 1472, 9984, - 1536, 9984, - 1536, 9920, - 1472, 9920); - - // Wildy revenant caves - addPolygonTo(MULTICOMBAT, - 3136, 10062, - 3136, 10240, - 3236, 10240, - 3236, 10229, - 3264, 10229, - 3264, 10048, - 3208, 10048, - 3208, 10062); - - // King black dragon (Kbd) - addPolygonTo(MULTICOMBAT, - 2240, 4672, - 2240, 4736, - 2304, 4736, - 2304, 4672); - - // Scorpia - addPolygonTo(MULTICOMBAT, - 3248, 10352, - 3248, 10328, - 3216, 10328, - 3216, 10352); - - // Inside mage bank - addPolygonTo(MULTICOMBAT, - 2496, 4672, - 2496, 4736, - 2560, 4736, - 2560, 4672); - - // Wildy godwars dungeon - addPolygonTo(MULTICOMBAT, - 3072, 10112, - 3008, 10112, - 3008, 10176, - 3048, 10176, - 3048, 10152, - 3056, 10152, - 3056, 10144, - 3064, 10144, - 3064, 10136, - 3072, 10136); - - // Enchanted valley - addPolygonTo(MULTICOMBAT, - 3008, 4480, - 3008, 4544, - 3072, 4544, - 3072, 4480); - - // Zulrah - addPolygonTo(MULTICOMBAT, - 2256, 3080, - 2280, 3080, - 2280, 3064, - 2256, 3064); - - // Abyssal sire and abyss - addPolygonTo(MULTICOMBAT, - 3008, 4736, - 2944, 4736, - 2944, 4864, - 3136, 4864, - 3136, 4736, - 3072, 4736, - 3072, 4800, - 3008, 4800); - } - - private static void defineDeadmanSafeZones() - { - // Varrock - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3182, 3382, - 3182, 3399, - 3174, 3399, - 3174, 3448, - 3198, 3448, - 3198, 3449, - 3197, 3449, - 3197, 3450, - 3196, 3450, - 3196, 3451, - 3195, 3451, - 3195, 3452, - 3194, 3452, - 3194, 3453, - 3193, 3453, - 3193, 3454, - 3192, 3454, - 3192, 3455, - 3191, 3455, - 3191, 3456, - 3190, 3456, - 3190, 3457, - 3185, 3457, - 3185, 3463, - 3186, 3463, - 3186, 3464, - 3187, 3464, - 3187, 3467, - 3167, 3467, - 3167, 3468, - 3163, 3468, - 3163, 3467, - 3142, 3467, - 3142, 3468, - 3141, 3468, - 3141, 3469, - 3140, 3469, - 3140, 3470, - 3139, 3470, - 3139, 3471, - 3138, 3471, - 3138, 3484, - 3139, 3484, - 3139, 3485, - 3140, 3485, - 3140, 3486, - 3141, 3486, - 3141, 3491, - 3140, 3491, - 3140, 3492, - 3139, 3492, - 3139, 3493, - 3138, 3493, - 3138, 3515, - 3139, 3515, - 3139, 3516, - 3140, 3516, - 3140, 3517, - 3141, 3517, - 3141, 3518, - 3160, 3518, - 3160, 3517, - 3161, 3517, - 3161, 3516, - 3162, 3516, - 3162, 3515, - 3167, 3515, - 3167, 3516, - 3168, 3516, - 3168, 3517, - 3169, 3517, - 3169, 3518, - 3191, 3518, - 3191, 3517, - 3192, 3517, - 3192, 3516, - 3193, 3516, - 3193, 3515, - 3194, 3515, - 3194, 3514, - 3195, 3514, - 3195, 3513, - 3196, 3513, - 3196, 3512, - 3197, 3512, - 3197, 3511, - 3198, 3511, - 3198, 3510, - 3199, 3510, - 3199, 3509, - 3200, 3509, - 3200, 3508, - 3230, 3508, - 3230, 3507, - 3231, 3507, - 3231, 3506, - 3232, 3506, - 3232, 3505, - 3233, 3505, - 3233, 3504, - 3234, 3504, - 3234, 3503, - 3235, 3503, - 3235, 3502, - 3252, 3502, - 3252, 3496, - 3253, 3496, - 3253, 3495, - 3254, 3495, - 3254, 3494, - 3255, 3494, - 3255, 3493, - 3263, 3493, - 3263, 3472, - 3264, 3472, - 3264, 3471, - 3265, 3471, - 3265, 3470, - 3266, 3470, - 3266, 3469, - 3267, 3469, - 3267, 3468, - 3268, 3468, - 3268, 3467, - 3269, 3467, - 3269, 3466, - 3270, 3466, - 3270, 3465, - 3271, 3465, - 3271, 3437, - 3274, 3437, - 3274, 3424, - 3277, 3424, - 3277, 3420, - 3274, 3420, - 3274, 3411, - 3275, 3411, - 3275, 3410, - 3276, 3410, - 3276, 3409, - 3277, 3409, - 3277, 3408, - 3288, 3408, - 3288, 3391, - 3289, 3391, - 3289, 3385, - 3290, 3385, - 3290, 3378, - 3289, 3378, - 3289, 3377, - 3288, 3377, - 3288, 3376, - 3265, 3376, - 3265, 3380, - 3253, 3380, - 3253, 3382, - 3245, 3382, - 3245, 3380, - 3242, 3380, - 3242, 3382, - 3239, 3382, - 3239, 3381, - 3209, 3381, - 3209, 3382, - 3282, 3382); - - // Lumbridge - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3201, 3257, - 3213, 3257, - 3213, 3264, - 3233, 3264, - 3233, 3257, - 3235, 3257, - 3235, 3241, - 3237, 3241, - 3237, 3237, - 3239, 3237, - 3239, 3231, - 3243, 3231, - 3243, 3220, - 3253, 3220, - 3253, 3217, - 3256, 3217, - 3256, 3212, - 3259, 3212, - 3259, 3190, - 3247, 3190, - 3247, 3191, - 3238, 3191, - 3238, 3195, - 3230, 3195, - 3230, 3201, - 3228, 3201, - 3228, 3202, - 3227, 3202, - 3227, 3205, - 3228, 3205, - 3228, 3207, - 3225, 3207, - 3225, 3206, - 3224, 3206, - 3224, 3205, - 3223, 3205, - 3223, 3204, - 3222, 3204, - 3222, 3203, - 3215, 3203, - 3215, 3202, - 3214, 3202, - 3214, 3201, - 3203, 3201, - 3203, 3202, - 3202, 3202, - 3202, 3203, - 3201, 3203, - 3201, 3217, - 3199, 3217, - 3199, 3220, - 3201, 3220); - - // Falador - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2986, 3395, - 2986, 3394, - 2987, 3394, - 2987, 3393, - 2996, 3393, - 2996, 3394, - 3002, 3394, - 3002, 3395, - 3009, 3395, - 3009, 3394, - 3010, 3394, - 3010, 3393, - 3011, 3393, - 3011, 3392, - 3021, 3392, - 3021, 3391, - 3022, 3391, - 3022, 3390, - 3041, 3390, - 3041, 3389, - 3047, 3389, - 3047, 3390, - 3062, 3390, - 3062, 3389, - 3063, 3389, - 3063, 3388, - 3064, 3388, - 3064, 3387, - 3065, 3387, - 3065, 3386, - 3066, 3386, - 3066, 3368, - 3065, 3368, - 3065, 3367, - 3064, 3367, - 3064, 3366, - 3063, 3366, - 3063, 3365, - 3062, 3365, - 3062, 3364, - 3061, 3364, - 3061, 3363, - 3060, 3363, - 3060, 3331, - 3061, 3331, - 3061, 3328, - 3058, 3328, - 3058, 3329, - 3025, 3329, - 3025, 3328, - 3024, 3328, - 3024, 3327, - 3016, 3327, - 3016, 3326, - 3015, 3326, - 3015, 3325, - 3014, 3325, - 3014, 3324, - 3013, 3324, - 3013, 3323, - 3008, 3323, - 3008, 3324, - 3006, 3324, - 3006, 3323, - 3002, 3323, - 3002, 3322, - 3001, 3322, - 3001, 3321, - 3000, 3321, - 3000, 3320, - 2999, 3320, - 2999, 3319, - 2998, 3319, - 2998, 3318, - 2997, 3318, - 2997, 3317, - 2996, 3317, - 2996, 3316, - 2992, 3316, - 2992, 3315, - 2991, 3315, - 2991, 3314, - 2990, 3314, - 2990, 3313, - 2989, 3313, - 2989, 3312, - 2988, 3312, - 2988, 3311, - 2987, 3311, - 2987, 3310, - 2986, 3310, - 2986, 3309, - 2966, 3309, - 2966, 3310, - 2956, 3310, - 2956, 3311, - 2941, 3311, - 2941, 3312, - 2940, 3312, - 2940, 3320, - 2936, 3320, - 2936, 3354, - 2937, 3354, - 2937, 3357, - 2936, 3357, - 2936, 3389, - 2937, 3389, - 2937, 3390, - 2938, 3390, - 2938, 3391, - 2939, 3391, - 2939, 3392, - 2940, 3392, - 2940, 3393, - 2943, 3393, - 2943, 3394, - 2944, 3394, - 2944, 3395, - 2950, 3395, - 2950, 3394, - 2956, 3394, - 2956, 3395); - - // Port phasmatys - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3650, 3456, - 3650, 3472, - 3651, 3472, - 3651, 3473, - 3652, 3473, - 3652, 3474, - 3653, 3474, - 3653, 3507, - 3654, 3507, - 3654, 3508, - 3668, 3508, - 3668, 3509, - 3669, 3509, - 3669, 3510, - 3670, 3510, - 3670, 3511, - 3671, 3511, - 3671, 3512, - 3672, 3512, - 3672, 3513, - 3673, 3513, - 3673, 3514, - 3674, 3514, - 3674, 3515, - 3675, 3515, - 3675, 3516, - 3676, 3516, - 3676, 3517, - 3687, 3517, - 3687, 3494, - 3690, 3494, - 3690, 3493, - 3696, 3493, - 3696, 3482, - 3699, 3482, - 3699, 3481, - 3712, 3481, - 3712, 3456); - - // Sophanem - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3274, 2752, - 3274, 2784, - 3277, 2784, - 3277, 2786, - 3274, 2786, - 3274, 2789, - 3272, 2789, - 3272, 2810, - 3322, 2810, - 3322, 2752); - - // Ardy - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2560, 3256, - 2560, 3264, - 2559, 3264, - 2559, 3328, - 2560, 3328, - 2560, 3339, - 2561, 3339, - 2561, 3340, - 2562, 3340, - 2562, 3341, - 2563, 3341, - 2563, 3342, - 2616, 3342, - 2616, 3341, - 2617, 3341, - 2617, 3340, - 2669, 3340, - 2669, 3339, - 2670, 3339, - 2670, 3338, - 2671, 3338, - 2671, 3337, - 2672, 3337, - 2672, 3336, - 2673, 3336, - 2673, 3335, - 2674, 3335, - 2674, 3334, - 2683, 3334, - 2683, 3333, - 2684, 3333, - 2684, 3332, - 2685, 3332, - 2685, 3331, - 2686, 3331, - 2686, 3330, - 2687, 3330, - 2687, 3329, - 2688, 3329, - 2688, 3264, - 2638, 3264, - 2638, 3263, - 2625, 3263, - 2625, 3264, - 2611, 3264, - 2611, 3257, - 2602, 3257, - 2602, 3264, - 2587, 3264, - 2587, 3263, - 2586, 3263, - 2586, 3262, - 2584, 3262, - 2584, 3261, - 2583, 3261, - 2583, 3260, - 2582, 3260, - 2582, 3259, - 2581, 3259, - 2581, 3258, - 2572, 3258, - 2572, 3260, - 2571, 3260, - 2571, 3261, - 2566, 3261, - 2566, 3260, - 2565, 3260, - 2565, 3259, - 2564, 3259, - 2564, 3256); - - // Yanille - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2613, 3103, - 2614, 3103, - 2614, 3102, - 2615, 3102, - 2615, 3101, - 2616, 3101, - 2616, 3100, - 2617, 3100, - 2617, 3099, - 2618, 3099, - 2618, 3098, - 2619, 3098, - 2619, 3097, - 2620, 3097, - 2620, 3075, - 2590, 3075, - 2590, 3074, - 2589, 3074, - 2589, 3073, - 2584, 3073, - 2584, 3074, - 2583, 3074, - 2583, 3075, - 2543, 3075, - 2543, 3076, - 2542, 3076, - 2542, 3077, - 2539, 3077, - 2539, 3107, - 2542, 3107, - 2542, 3108, - 2543, 3108, - 2543, 3109, - 2608, 3109, - 2608, 3108, - 2609, 3108, - 2609, 3107, - 2610, 3107, - 2610, 3106, - 2611, 3106, - 2611, 3105, - 2612, 3105, - 2612, 3104, - 2613, 3104); - - // Gnome stronghold - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2495, 3439, - 2494, 3439, - 2494, 3432, - 2495, 3432, - 2495, 3431, - 2496, 3431, - 2496, 3430, - 2497, 3430, - 2497, 3429, - 2498, 3429, - 2498, 3417, - 2497, 3417, - 2497, 3416, - 2496, 3416, - 2496, 3412, - 2495, 3412, - 2495, 3408, - 2494, 3408, - 2494, 3404, - 2495, 3404, - 2495, 3403, - 2496, 3403, - 2496, 3402, - 2497, 3402, - 2497, 3401, - 2498, 3401, - 2498, 3400, - 2499, 3400, - 2499, 3399, - 2500, 3399, - 2500, 3398, - 2501, 3398, - 2501, 3397, - 2502, 3397, - 2502, 3396, - 2506, 3396, - 2506, 3391, - 2502, 3391, - 2502, 3390, - 2492, 3390, - 2492, 3391, - 2489, 3391, - 2489, 3390, - 2488, 3390, - 2488, 3389, - 2485, 3389, - 2485, 3390, - 2482, 3390, - 2482, 3389, - 2476, 3389, - 2476, 3390, - 2471, 3390, - 2471, 3391, - 2468, 3391, - 2468, 3390, - 2467, 3390, - 2467, 3389, - 2466, 3389, - 2466, 3385, - 2465, 3385, - 2465, 3384, - 2458, 3384, - 2458, 3385, - 2457, 3385, - 2457, 3389, - 2456, 3389, - 2456, 3390, - 2455, 3390, - 2455, 3391, - 2450, 3391, - 2450, 3390, - 2446, 3390, - 2446, 3391, - 2443, 3391, - 2443, 3390, - 2442, 3390, - 2442, 3389, - 2440, 3389, - 2440, 3388, - 2434, 3388, - 2434, 3389, - 2433, 3389, - 2433, 3390, - 2432, 3390, - 2432, 3391, - 2428, 3391, - 2428, 3392, - 2427, 3392, - 2427, 3393, - 2420, 3393, - 2420, 3394, - 2419, 3394, - 2419, 3395, - 2418, 3395, - 2418, 3396, - 2417, 3396, - 2417, 3397, - 2416, 3397, - 2416, 3399, - 2415, 3399, - 2415, 3400, - 2414, 3400, - 2414, 3408, - 2413, 3408, - 2413, 3409, - 2412, 3409, - 2412, 3410, - 2411, 3410, - 2411, 3411, - 2410, 3411, - 2410, 3412, - 2387, 3412, - 2387, 3407, - 2383, 3407, - 2383, 3408, - 2380, 3408, - 2380, 3409, - 2379, 3409, - 2379, 3410, - 2377, 3410, - 2377, 3411, - 2376, 3411, - 2376, 3413, - 2375, 3413, - 2375, 3417, - 2374, 3417, - 2374, 3418, - 2373, 3418, - 2373, 3419, - 2372, 3419, - 2372, 3420, - 2371, 3420, - 2371, 3421, - 2370, 3421, - 2370, 3422, - 2369, 3422, - 2369, 3433, - 2370, 3433, - 2370, 3434, - 2371, 3434, - 2371, 3444, - 2372, 3444, - 2372, 3445, - 2373, 3445, - 2373, 3446, - 2374, 3446, - 2374, 3447, - 2375, 3447, - 2375, 3459, - 2376, 3459, - 2376, 3460, - 2377, 3460, - 2377, 3461, - 2378, 3461, - 2378, 3462, - 2379, 3462, - 2379, 3463, - 2380, 3463, - 2380, 3464, - 2381, 3464, - 2381, 3476, - 2379, 3476, - 2379, 3477, - 2378, 3477, - 2378, 3478, - 2377, 3478, - 2377, 3485, - 2376, 3485, - 2376, 3486, - 2375, 3486, - 2375, 3499, - 2376, 3499, - 2376, 3500, - 2377, 3500, - 2377, 3507, - 2378, 3507, - 2378, 3508, - 2379, 3508, - 2379, 3509, - 2380, 3509, - 2380, 3521, - 2382, 3521, - 2382, 3522, - 2384, 3522, - 2384, 3523, - 2393, 3523, - 2393, 3524, - 2399, 3524, - 2399, 3525, - 2404, 3525, - 2404, 3524, - 2405, 3524, - 2405, 3523, - 2407, 3523, - 2407, 3522, - 2415, 3522, - 2415, 3521, - 2425, 3521, - 2425, 3522, - 2427, 3522, - 2427, 3523, - 2430, 3523, - 2430, 3522, - 2431, 3522, - 2431, 3521, - 2432, 3521, - 2432, 3520, - 2448, 3520, - 2448, 3517, - 2454, 3517, - 2454, 3516, - 2455, 3516, - 2455, 3515, - 2456, 3515, - 2456, 3514, - 2457, 3514, - 2457, 3513, - 2460, 3513, - 2460, 3512, - 2461, 3512, - 2461, 3511, - 2465, 3511, - 2465, 3510, - 2468, 3510, - 2468, 3511, - 2472, 3511, - 2472, 3512, - 2473, 3512, - 2473, 3513, - 2475, 3513, - 2475, 3514, - 2476, 3514, - 2476, 3515, - 2477, 3515, - 2477, 3516, - 2478, 3516, - 2478, 3517, - 2483, 3517, - 2483, 3516, - 2487, 3516, - 2487, 3515, - 2488, 3515, - 2488, 3512, - 2487, 3512, - 2487, 3509, - 2488, 3509, - 2488, 3508, - 2489, 3508, - 2489, 3507, - 2491, 3507, - 2491, 3506, - 2492, 3506, - 2492, 3505, - 2493, 3505, - 2493, 3499, - 2492, 3499, - 2492, 3498, - 2491, 3498, - 2491, 3497, - 2490, 3497, - 2490, 3495, - 2491, 3495, - 2491, 3494, - 2492, 3494, - 2492, 3493, - 2493, 3493, - 2493, 3485, - 2490, 3485, - 2490, 3484, - 2489, 3484, - 2489, 3483, - 2488, 3483, - 2488, 3482, - 2487, 3482, - 2487, 3481, - 2486, 3481, - 2486, 3474, - 2488, 3474, - 2488, 3471, - 2489, 3471, - 2489, 3470, - 2490, 3470, - 2490, 3460, - 2491, 3460, - 2491, 3456, - 2496, 3456, - 2496, 3440, - 2495, 3440); - - // Rellekka - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2620, 3682, - 2624, 3682, - 2624, 3683, - 2625, 3683, - 2625, 3687, - 2629, 3687, - 2629, 3686, - 2630, 3686, - 2630, 3685, - 2632, 3685, - 2632, 3686, - 2636, 3686, - 2636, 3692, - 2645, 3692, - 2645, 3695, - 2647, 3695, - 2647, 3696, - 2649, 3696, - 2649, 3702, - 2650, 3702, - 2650, 3703, - 2651, 3703, - 2651, 3704, - 2652, 3704, - 2652, 3711, - 2653, 3711, - 2653, 3712, - 2691, 3712, - 2691, 3709, - 2692, 3709, - 2692, 3707, - 2693, 3707, - 2693, 3703, - 2692, 3703, - 2692, 3701, - 2691, 3701, - 2691, 3699, - 2690, 3699, - 2690, 3695, - 2691, 3695, - 2691, 3693, - 2692, 3693, - 2692, 3691, - 2693, 3691, - 2693, 3685, - 2692, 3685, - 2692, 3683, - 2691, 3683, - 2691, 3681, - 2690, 3681, - 2690, 3680, - 2689, 3680, - 2689, 3672, - 2690, 3672, - 2690, 3671, - 2691, 3671, - 2691, 3666, - 2690, 3666, - 2690, 3664, - 2689, 3664, - 2689, 3660, - 2690, 3660, - 2690, 3658, - 2691, 3658, - 2691, 3656, - 2692, 3656, - 2692, 3654, - 2693, 3654, - 2693, 3651, - 2692, 3651, - 2692, 3649, - 2690, 3649, - 2690, 3648, - 2688, 3648, - 2688, 3647, - 2686, 3647, - 2686, 3646, - 2673, 3646, - 2673, 3645, - 2636, 3645, - 2636, 3647, - 2627, 3647, - 2627, 3648, - 2625, 3648, - 2625, 3649, - 2624, 3649, - 2624, 3650, - 2622, 3650, - 2622, 3651, - 2620, 3651, - 2620, 3652, - 2618, 3652, - 2618, 3653, - 2616, 3653, - 2616, 3654, - 2609, 3654, - 2609, 3655, - 2607, 3655, - 2607, 3656, - 2603, 3656, - 2603, 3657, - 2602, 3657, - 2602, 3658, - 2601, 3658, - 2601, 3663, - 2602, 3663, - 2602, 3664, - 2603, 3664, - 2603, 3665, - 2604, 3665, - 2604, 3666, - 2605, 3666, - 2605, 3667, - 2606, 3667, - 2606, 3671, - 2609, 3671, - 2609, 3672, - 2610, 3672, - 2610, 3673, - 2611, 3673, - 2611, 3675, - 2612, 3675, - 2612, 3676, - 2614, 3676, - 2614, 3677, - 2616, 3677, - 2616, 3679, - 2618, 3679, - 2618, 3681, - 2620, 3681); - - // Jatizo - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2407, 3797, - 2407, 3793, - 2399, 3793, - 2399, 3792, - 2391, 3792, - 2391, 3791, - 2386, 3791, - 2386, 3796, - 2388, 3796, - 2388, 3802, - 2386, 3802, - 2386, 3807, - 2388, 3807, - 2388, 3809, - 2402, 3809, - 2402, 3819, - 2406, 3819, - 2406, 3824, - 2408, 3824, - 2408, 3826, - 2413, 3826, - 2413, 3824, - 2419, 3824, - 2419, 3826, - 2424, 3826, - 2424, 3821, - 2423, 3821, - 2423, 3798, - 2422, 3798, - 2422, 3797); - - // Neitiznot - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2329, 3812, - 2333, 3812, - 2333, 3813, - 2334, 3813, - 2334, 3814, - 2335, 3814, - 2335, 3815, - 2338, 3815, - 2338, 3816, - 2339, 3816, - 2339, 3817, - 2368, 3817, - 2368, 3776, - 2352, 3776, - 2352, 3796, - 2344, 3796, - 2344, 3795, - 2331, 3795, - 2331, 3797, - 2330, 3797, - 2330, 3798, - 2329, 3798); - - // Pest control - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2624, 2688, - 2688, 2688, - 2688, 2624, - 2624, 2624); - - // Tutorial island - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3052, 3135, - 3156, 3135, - 3156, 3057, - 3052, 3057); - - // Camelot bank - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2724, 3487, - 2724, 3490, - 2721, 3490, - 2721, 3494, - 2719, 3494, - 2719, 3497, - 2721, 3497, - 2721, 3498, - 2731, 3498, - 2731, 3490, - 2728, 3490, - 2728, 3487); - - // Catherby bank - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2806, 3438, - 2806, 3446, - 2813, 3446, - 2813, 3438); - - // Kourend castle - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 1627, 3658, - 1620, 3658, - 1620, 3657, - 1619, 3657, - 1619, 3656, - 1614, 3656, - 1614, 3657, - 1613, 3657, - 1613, 3661, - 1612, 3661, - 1612, 3662, - 1611, 3662, - 1611, 3663, - 1600, 3663, - 1600, 3662, - 1599, 3662, - 1599, 3661, - 1594, 3661, - 1594, 3662, - 1593, 3662, - 1593, 3685, - 1594, 3685, - 1594, 3686, - 1599, 3686, - 1599, 3685, - 1600, 3685, - 1600, 3684, - 1611, 3684, - 1611, 3685, - 1612, 3685, - 1612, 3686, - 1613, 3686, - 1613, 3690, - 1614, 3690, - 1614, 3691, - 1619, 3691, - 1619, 3690, - 1620, 3690, - 1620, 3689, - 1630, 3689, - 1630, 3686, - 1620, 3686, - 1620, 3685, - 1619, 3685, - 1619, 3683, - 1620, 3683, - 1620, 3682, - 1621, 3682, - 1621, 3681, - 1622, 3681, - 1622, 3680, - 1623, 3680, - 1623, 3679, - 1624, 3679, - 1624, 3668, - 1623, 3668, - 1623, 3667, - 1622, 3667, - 1622, 3666, - 1621, 3666, - 1621, 3665, - 1620, 3665, - 1620, 3664, - 1619, 3664, - 1619, 3662, - 1620, 3662, - 1620, 3661, - 1627, 3661); - } - - private static void definePvpSafeZones() - { - // Grand exchange - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3159, 3473, - 3159, 3474, - 3157, 3474, - 3157, 3475, - 3155, 3475, - 3155, 3476, - 3153, 3476, - 3153, 3477, - 3152, 3477, - 3152, 3478, - 3151, 3478, - 3151, 3480, - 3150, 3480, - 3150, 3482, - 3149, 3482, - 3149, 3484, - 3148, 3484, - 3148, 3496, - 3149, 3496, - 3149, 3498, - 3150, 3498, - 3150, 3500, - 3151, 3500, - 3151, 3502, - 3152, 3502, - 3152, 3503, - 3153, 3503, - 3153, 3504, - 3155, 3504, - 3155, 3505, - 3157, 3505, - 3157, 3506, - 3159, 3506, - 3159, 3507, - 3171, 3507, - 3171, 3506, - 3173, 3506, - 3173, 3505, - 3175, 3505, - 3175, 3504, - 3177, 3504, - 3177, 3503, - 3178, 3503, - 3178, 3502, - 3179, 3502, - 3179, 3500, - 3180, 3500, - 3180, 3498, - 3181, 3498, - 3181, 3496, - 3182, 3496, - 3182, 3484, - 3181, 3484, - 3181, 3482, - 3180, 3482, - 3180, 3480, - 3179, 3480, - 3179, 3478, - 3178, 3478, - 3178, 3477, - 3177, 3477, - 3177, 3476, - 3175, 3476, - 3175, 3475, - 3173, 3475, - 3173, 3474, - 3171, 3474, - 3171, 3473); - - // Edgeville - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3091, 3488, - 3091, 3493, - 3090, 3493, - 3090, 3498, - 3091, 3498, - 3091, 3500, - 3099, 3500, - 3099, 3488); - - // Fally west bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2943, 3368, - 2943, 3374, - 2948, 3374, - 2948, 3370, - 2950, 3370, - 2950, 3366, - 2949, 3366, - 2949, 3359, - 2945, 3359, - 2945, 3362, - 2946, 3362, - 2946, 3366, - 2945, 3366, - 2945, 3368); - - // Fally east bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3009, 3353, - 3009, 3359, - 3019, 3359, - 3019, 3357, - 3022, 3357, - 3022, 3353); - - // Fally castle - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2964, 3354, - 2966, 3354, - 2966, 3352, - 2967, 3352, - 2967, 3349, - 2976, 3349, - 2976, 3348, - 2977, 3348, - 2977, 3347, - 2981, 3347, - 2981, 3343, - 2982, 3343, - 2982, 3339, - 2981, 3339, - 2981, 3337, - 2967, 3337, - 2967, 3330, - 2963, 3330, - 2963, 3331, - 2962, 3331, - 2962, 3332, - 2961, 3332, - 2961, 3334, - 2964, 3334, - 2964, 3335, - 2965, 3335, - 2965, 3343, - 2964, 3343, - 2964, 3344, - 2961, 3344, - 2961, 3350, - 2963, 3350, - 2963, 3352, - 2964, 3352); - - // Varrock east bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3250, 3425, - 3258, 3425, - 3258, 3416, - 3250, 3416); - - // Varrock west bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3180, 3433, - 3180, 3448, - 3191, 3448, - 3191, 3433); - - // Port phasmatys - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3686, 3472, - 3700, 3472, - 3700, 3461, - 3686, 3461); - - // Yanille bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2609, 3088, - 2609, 3098, - 2617, 3098, - 2617, 3088); - - // Ardy east bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2649, 3280, - 2649, 3288, - 2659, 3288, - 2659, 3280); - - // Ardy west bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2612, 3330, - 2612, 3336, - 2615, 3336, - 2615, 3335, - 2619, 3335, - 2619, 3336, - 2622, 3336, - 2622, 3330); - - // Fishing guild bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2593, 3413, - 2588, 3413, - 2588, 3418, - 2583, 3418, - 2583, 3423, - 2590, 3423, - 2590, 3420, - 2593, 3420); - - // Gnome stronghold bank near slayer cave (2nd floor) - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, - 2444, 3431, - 2444, 3435, - 2448, 3435, - 2448, 3431, - 2447, 3431, - 2447, 3428, - 2449, 3428, - 2449, 3422, - 2447, 3422, - 2447, 3419, - 2448, 3419, - 2448, 3415, - 2444, 3415, - 2444, 3419, - 2445, 3419, - 2445, 3422, - 2443, 3422, - 2443, 3428, - 2445, 3428, - 2445, 3431); - - // Gnome stronghold bank in grand tree - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, - 2456, 3488, - 2452, 3488, - 2452, 3486, - 2450, 3486, - 2450, 3483, - 2451, 3483, - 2451, 3478, - 2448, 3478, - 2448, 3483, - 2449, 3483, - 2449, 3486, - 2447, 3486, - 2447, 3488, - 2443, 3488, - 2443, 3487, - 2438, 3487, - 2438, 3490, - 2443, 3490, - 2443, 3489, - 2447, 3489, - 2447, 3491, - 2449, 3491, - 2449, 3494, - 2448, 3494, - 2448, 3496, - 2451, 3496, - 2451, 3494, - 2450, 3494, - 2450, 3491, - 2452, 3491, - 2452, 3489, - 2456, 3489); - - // Al kharid bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3265, 3161, - 3265, 3174, - 3273, 3174, - 3273, 3161); - - // Shantay pass bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3308, 3119, - 3308, 3125, - 3310, 3125, - 3310, 3119); - - // Nardah bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3431, 2891, - 3431, 2889, - 3427, 2889, - 3427, 2887, - 3424, 2887, - 3424, 2895, - 3431, 2895, - 3431, 2893, - 3432, 2893, - 3432, 2891); - - // Sophanem bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2807, 5158, - 2792, 5158, - 2792, 5175, - 2807, 5175); - - // Canifis bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3509, 3474, - 3509, 3478, - 3508, 3478, - 3508, 3483, - 3509, 3483, - 3509, 3484, - 3517, 3484, - 3517, 3477, - 3516, 3477, - 3516, 3476, - 3513, 3476, - 3513, 3474); - - // Lumbridge castle outside - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3216, 3209, - 3216, 3210, - 3217, 3210, - 3217, 3228, - 3216, 3228, - 3216, 3229, - 3227, 3229, - 3227, 3221, - 3230, 3221, - 3230, 3217, - 3227, 3217, - 3227, 3209); - - // Lumbridge bank upstairs - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 2, - 3211, 3223, - 3211, 3215, - 3207, 3215, - 3207, 3223); - - // Draynor bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3098, 3240, - 3088, 3240, - 3088, 3247, - 3098, 3247); - - // Pest control bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2665, 2656, - 2670, 2656, - 2670, 2651, - 2665, 2651); - - // Shilo village bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2843, 2957, - 2846, 2957, - 2846, 2956, - 2849, 2956, - 2849, 2957, - 2850, 2957, - 2850, 2958, - 2855, 2958, - 2855, 2957, - 2856, 2957, - 2856, 2956, - 2858, 2956, - 2858, 2957, - 2862, 2957, - 2862, 2952, - 2858, 2952, - 2858, 2953, - 2856, 2953, - 2856, 2952, - 2855, 2952, - 2855, 2951, - 2850, 2951, - 2850, 2952, - 2849, 2952, - 2849, 2953, - 2847, 2953, - 2847, 2952, - 2843, 2952); - - // Legends guild bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 2, - 2731, 3374, - 2731, 3383, - 2734, 3383, - 2734, 3374); - - // Legends guild middle floor - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, - 2724, 3374, - 2724, 3383, - 2734, 3383, - 2734, 3382, - 2736, 3382, - 2736, 3375, - 2734, 3375, - 2734, 3374); - - // Warriors guild bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2843, 3537, - 2843, 3540, - 2841, 3540, - 2841, 3546, - 2849, 3546, - 2849, 3537, - 2847, 3537, - 2847, 3536, - 2846, 3536, - 2846, 3537); - - // Camelot bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2724, 3487, - 2724, 3490, - 2721, 3490, - 2721, 3494, - 2719, 3494, - 2719, 3497, - 2721, 3497, - 2721, 3498, - 2731, 3498, - 2731, 3490, - 2728, 3490, - 2728, 3487); - - // Camelot respawn point - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2761, 3483, - 2761, 3476, - 2755, 3476, - 2755, 3483); - - // Catherby bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2806, 3438, - 2806, 3446, - 2813, 3446, - 2813, 3438); - - // Barbarian outpost bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2536, 3572, - 2536, 3575, - 2538, 3575, - 2538, 3572); - - // Piscatoris bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2327, 3686, - 2327, 3694, - 2333, 3694, - 2333, 3686); - - // Lletya bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2350, 3161, - 2350, 3165, - 2351, 3165, - 2351, 3167, - 2357, 3167, - 2357, 3165, - 2356, 3165, - 2356, 3164, - 2355, 3164, - 2355, 3161); - - // Castle wars bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2446, 3087, - 2445, 3087, - 2445, 3085, - 2447, 3085, - 2447, 3081, - 2443, 3081, - 2443, 3082, - 2439, 3082, - 2439, 3081, - 2435, 3081, - 2435, 3099, - 2439, 3099, - 2439, 3098, - 2443, 3098, - 2443, 3099, - 2447, 3099, - 2447, 3095, - 2445, 3095, - 2445, 3093, - 2446, 3093); - - // Duel arena bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3380, 3267, - 3380, 3273, - 3381, 3273, - 3381, 3274, - 3385, 3274, - 3385, 3267); - - // Clan wars bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3375, 3165, - 3361, 3165, - 3361, 3173, - 3375, 3173); - - // Lumbridge cellar bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 3218, 9622, - 3218, 9624, - 3220, 9624, - 3220, 9622); - - // Dorgesh kaan bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2709, 5348, - 2707, 5348, - 2707, 5345, - 2701, 5345, - 2701, 5347, - 2697, 5347, - 2697, 5353, - 2701, 5353, - 2701, 5355, - 2707, 5355, - 2707, 5350, - 2709, 5350); - - // Keldagrim bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2842, 10204, - 2834, 10204, - 2834, 10216, - 2842, 10216); - - // Tzhaar bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2438, 5176, - 2438, 5180, - 2441, 5180, - 2441, 5182, - 2449, 5182, - 2449, 5181, - 2450, 5181, - 2450, 5180, - 2452, 5180, - 2452, 5175, - 2441, 5175, - 2441, 5176); - - // Inferno bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2542, 5135, - 2542, 5139, - 2539, 5139, - 2539, 5140, - 2538, 5140, - 2538, 5141, - 2537, 5141, - 2537, 5144, - 2541, 5144, - 2541, 5145, - 2543, 5145, - 2543, 5144, - 2544, 5144, - 2544, 5142, - 2545, 5142, - 2545, 5135); - - // Port khazard bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2661, 3160, - 2661, 3163, - 2666, 3163, - 2666, 3160); - - // Corsair cove bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2569, 2863, - 2569, 2868, - 2572, 2868, - 2572, 2863); - - // Burgh de rott bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3495, 3210, - 3495, 3214, - 3501, 3214, - 3501, 3210); - - // Edgeville respawn point - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3092, 3468, - 3092, 3474, - 3098, 3474, - 3098, 3468); - - // Mage bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2529, 4711, - 2529, 4724, - 2548, 4724, - 2548, 4711); - - // Lunar bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2097, 3917, - 2097, 3922, - 2105, 3922, - 2105, 3917); - - // Jatizo bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2414, 3801, - 2414, 3804, - 2420, 3804, - 2420, 3801); - - // Neitiznot bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2334, 3805, - 2334, 3809, - 2340, 3809, - 2340, 3805); - - // Hosidius bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1671, 3558, - 1671, 3577, - 1682, 3577, - 1682, 3558); - - // Woodcutting guild bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1589, 3475, - 1589, 3481, - 1594, 3481, - 1594, 3475); - - // Lands end bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1508, 3415, - 1508, 3424, - 1514, 3424, - 1514, 3415); - - // Chambers of xeric bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1252, 3570, - 1252, 3574, - 1257, 3574, - 1257, 3570); - - // Arceuus bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1621, 3736, - 1621, 3754, - 1627, 3754, - 1627, 3751, - 1633, 3751, - 1633, 3754, - 1639, 3754, - 1639, 3736); - - // Piscarilius bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1794, 3784, - 1794, 3794, - 1812, 3794, - 1812, 3784); - - // Lovakengj bank southeast - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1518, 3735, - 1518, 3744, - 1535, 3744, - 1535, 3735); - - // Lovakenj bank west - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1433, 3820, - 1433, 3837, - 1442, 3837, - 1442, 3820); - - // Lovakenj sulphur mine bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1452, 3855, - 1452, 3860, - 1455, 3860, - 1455, 3855); - - // Blast mine bank southeast - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1500, 3856, - 1500, 3858, - 1503, 3858, - 1503, 3856); - - // Wintertodt bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1638, 3942, - 1638, 3947, - 1642, 3947, - 1642, 3942); - - // Shayzien bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1495, 3612, - 1495, 3622, - 1515, 3622, - 1515, 3612); - - // Hosidius grape farm bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1804, 3571, - 1804, 3572, - 1808, 3572, - 1808, 3571); - - // Hosidius cooking bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1652, 3605, - 1652, 3615, - 1661, 3615, - 1661, 3605); - - // Ecteria bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2618, 3893, - 2618, 3897, - 2622, 3897, - 2622, 3893); - - // Mining guild expanded area - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 3018, 9733, - 3021, 9733, - 3021, 9729, - 3022, 9729, - 3022, 9728, - 3023, 9728, - 3023, 9727, - 3025, 9727, - 3025, 9726, - 3026, 9726, - 3026, 9725, - 3030, 9725, - 3030, 9726, - 3032, 9726, - 3032, 9727, - 3035, 9727, - 3035, 9726, - 3038, 9726, - 3038, 9727, - 3041, 9727, - 3041, 9728, - 3042, 9728, - 3042, 9730, - 3045, 9730, - 3045, 9727, - 3047, 9727, - 3047, 9726, - 3048, 9726, - 3048, 9724, - 3052, 9724, - 3052, 9725, - 3053, 9725, - 3053, 9726, - 3055, 9726, - 3055, 9725, - 3056, 9725, - 3056, 9723, - 3057, 9723, - 3057, 9720, - 3056, 9720, - 3056, 9719, - 3054, 9719, - 3054, 9718, - 3052, 9718, - 3052, 9717, - 3050, 9717, - 3050, 9718, - 3045, 9718, - 3045, 9716, - 3044, 9716, - 3044, 9715, - 3041, 9715, - 3041, 9714, - 3039, 9714, - 3039, 9713, - 3037, 9713, - 3037, 9714, - 3036, 9714, - 3036, 9715, - 3034, 9715, - 3034, 9716, - 3029, 9716, - 3029, 9715, - 3028, 9715, - 3028, 9714, - 3026, 9714, - 3026, 9709, - 3027, 9709, - 3027, 9708, - 3028, 9708, - 3028, 9705, - 3029, 9705, - 3029, 9701, - 3028, 9701, - 3028, 9700, - 3027, 9700, - 3027, 9699, - 3023, 9699, - 3023, 9700, - 3019, 9700, - 3019, 9701, - 3018, 9701, - 3018, 9705, - 3019, 9705, - 3019, 9707, - 3020, 9707, - 3020, 9708, - 3021, 9708, - 3021, 9709, - 3022, 9709, - 3022, 9713, - 3021, 9713, - 3021, 9714, - 3019, 9714, - 3019, 9715, - 3018, 9715, - 3018, 9717, - 3015, 9717, - 3015, 9716, - 3013, 9716, - 3013, 9717, - 3012, 9717, - 3012, 9720, - 3013, 9720, - 3013, 9721, - 3015, 9721, - 3015, 9723, - 3016, 9723, - 3016, 9727, - 3017, 9727, - 3017, 9730, - 3018, 9730); - - // Motherlode mine bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 3760, 5671, - 3760, 5668, - 3761, 5668, - 3761, 5665, - 3760, 5665, - 3760, 5663, - 3758, 5663, - 3758, 5671); - - // Mos le harmles bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3679, 2980, - 3679, 2985, - 3681, 2985, - 3681, 2984, - 3682, 2984, - 3682, 2985, - 3684, 2985, - 3684, 2980, - 3682, 2980, - 3682, 2981, - 3681, 2981, - 3681, 2980); - - // Zanaris bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2388, 4454, - 2380, 4454, - 2380, 4463, - 2388, 4463); - - // Wodcuting guild bank underground - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 1550, 9872, - 1550, 9874, - 1553, 9874, - 1553, 9872); - } - - private static void defineWilderness() - { - // Above ground - addPolygonTo(ROUGH_WILDERNESS, - 2944, 3523, - 3392, 3523, - 3392, 3971, - 2944, 3971); - - // Underground - addPolygonTo(ROUGH_WILDERNESS, - 2944, 9918, - 2944, 10360, - 3264, 10360, - 3264, 9918); - } - - private static void addPolygonTo(List[] shapes, int... coords) - { - Polygon poly = new Polygon(); - for (int i = 0; i < coords.length; i += 2) - { - poly.addPoint(coords[i], coords[i + 1]); - } - for (int i = 0; i < shapes.length; i++) - { - shapes[i].add(poly); - } - } - - private static void addPolygonOnPlane(List[] shapes, int plane, int... coords) - { - Polygon poly = new Polygon(); - for (int i = 0; i < coords.length; i += 2) - { - poly.addPoint(coords[i], coords[i + 1]); - } - shapes[plane].add(poly); - } - - private static void addPolygonOnPlanes(List[] shapes, int minPlane, int maxPlane, int... coords) - { - Polygon poly = new Polygon(); - for (int i = 0; i < coords.length; i += 2) - { - poly.addPoint(coords[i], coords[i + 1]); - } - for (int i = minPlane; i <= maxPlane; i++) - { - shapes[i].add(poly); - } - } -} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsConfig.java deleted file mode 100644 index 370533dac7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -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 -{ - @ConfigItem( - keyName = "multicombatZoneVisibility", - name = "Multicombat zones", - description = "Determine where multicombat zones should be shown", - position = 1 - ) - default ZoneVisibility multicombatZoneVisibility() - { - return ZoneVisibility.SHOW_IN_PVP; - } - - @ConfigItem( - keyName = "pvpSafeZones", - name = "PvP safe zones", - description = "Show safe zones in PvP worlds", - position = 2 - ) - default boolean showPvpSafeZones() - { - return true; - } - - @ConfigItem( - keyName = "deadmanSafeZones", - name = "Deadman safe zones", - description = "Show safe zones in Deadman worlds", - position = 3 - ) - default boolean showDeadmanSafeZones() - { - return true; - } - - @ConfigItem( - keyName = "collisionDetection", - name = "Collision detection", - description = "Only show lines where they can be walked through", - position = 4 - ) - default boolean collisionDetection() - { - return false; - } - - @ConfigItem( - keyName = "showMinimapLines", - name = "Show on minimap", - description = "Show multicombat and safe zones on the minimap", - position = 5 - ) - default boolean showMinimapLines() - { - return true; - } - - @ConfigItem( - keyName = "multicombatColor", - name = "Multicombat zone color", - description = "Choose color to use for marking multicombat zones", - position = 6 - ) - default Color multicombatColor() - { - return Color.MAGENTA; - } - - @ConfigItem( - keyName = "safeZoneColor", - name = "Safe zone color", - description = "Choose color to use for marking safe zones in PvP/Deadman", - position = 7 - ) - default Color safeZoneColor() - { - return Color.GREEN; - } -} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsMinimapOverlay.java deleted file mode 100644 index 699b0f0ddf..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.geom.GeneralPath; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.geometry.Geometry; -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; - -public class ZoneIndicatorsMinimapOverlay extends Overlay -{ - private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; - - @Inject - private Client client; - - @Inject - private ZoneIndicatorsPlugin plugin; - - @Inject - private ZoneIndicatorsConfig config; - - @Inject - public ZoneIndicatorsMinimapOverlay() - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ALWAYS_ON_TOP); - setPriority(OverlayPriority.LOW); - } - - private Color getTransparentColorVersion(Color c) - { - return new Color(c.getRed(), c.getGreen(), c.getBlue(), 192); - } - - private void renderPath(Graphics2D graphics, GeneralPath path, Color color) - { - LocalPoint playerLp = client.getLocalPlayer().getLocalLocation(); - Rectangle viewArea = new Rectangle( - playerLp.getX() - MAX_LOCAL_DRAW_LENGTH, - playerLp.getY() - MAX_LOCAL_DRAW_LENGTH, - MAX_LOCAL_DRAW_LENGTH * 2, - MAX_LOCAL_DRAW_LENGTH * 2); - - graphics.setColor(color); - - path = Geometry.clipPath(path, viewArea); - path = Geometry.filterPath(path, (p1, p2) -> - Perspective.localToMinimap(client, new LocalPoint((int)p1[0], (int)p1[1])) != null && - Perspective.localToMinimap(client, new LocalPoint((int)p2[0], (int)p2[1])) != null); - path = Geometry.transformPath(path, coords -> - { - Point point = Perspective.localToMinimap(client, new LocalPoint((int)coords[0], (int)coords[1])); - coords[0] = point.getX(); - coords[1] = point.getY(); - }); - - graphics.draw(path); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!config.showMinimapLines()) - { - return null; - } - - GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()]; - GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()]; - - if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null) - { - renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor())); - } - if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null) - { - renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor())); - } - - return null; - } -} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsOverlay.java deleted file mode 100644 index 0f52222e8b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.geom.GeneralPath; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.geometry.Geometry; -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; - -public class ZoneIndicatorsOverlay extends Overlay -{ - private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; - - @Inject - private Client client; - - @Inject - private ZoneIndicatorsPlugin plugin; - - @Inject - private ZoneIndicatorsConfig config; - - @Inject - public ZoneIndicatorsOverlay() - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - setPriority(OverlayPriority.LOW); - } - - private Color getTransparentColorVersion(Color c) - { - return new Color(c.getRed(), c.getGreen(), c.getBlue(), 92); - } - - private void renderPath(Graphics2D graphics, GeneralPath path, Color color) - { - LocalPoint playerLp = client.getLocalPlayer().getLocalLocation(); - Rectangle viewArea = new Rectangle( - playerLp.getX() - MAX_LOCAL_DRAW_LENGTH, - playerLp.getY() - MAX_LOCAL_DRAW_LENGTH, - MAX_LOCAL_DRAW_LENGTH * 2, - MAX_LOCAL_DRAW_LENGTH * 2); - - graphics.setColor(color); - graphics.setStroke(new BasicStroke(2)); - - path = Geometry.clipPath(path, viewArea); - path = Geometry.filterPath(path, (p1, p2) -> - Perspective.localToCanvas(client, new LocalPoint((int)p1[0], (int)p1[1]), client.getPlane()) != null && - Perspective.localToCanvas(client, new LocalPoint((int)p2[0], (int)p2[1]), client.getPlane()) != null); - path = Geometry.transformPath(path, coords -> - { - Point point = Perspective.localToCanvas(client, new LocalPoint((int)coords[0], (int)coords[1]), client.getPlane()); - coords[0] = point.getX(); - coords[1] = point.getY(); - }); - - graphics.draw(path); - } - - @Override - public Dimension render(Graphics2D graphics) - { - GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()]; - GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()]; - - if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null) - { - renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor())); - } - if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null) - { - renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor())); - } - - return null; - } -} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsPlugin.java deleted file mode 100644 index 5f3397e900..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import java.awt.Rectangle; -import java.awt.geom.GeneralPath; -import java.util.Arrays; -import javax.inject.Inject; -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.Constants; -import net.runelite.api.GameState; -import net.runelite.api.ObjectComposition; -import net.runelite.api.Perspective; -import net.runelite.api.Tile; -import net.runelite.api.WallObject; -import net.runelite.api.WorldType; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldArea; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.geometry.Geometry; -import net.runelite.client.callback.ClientThread; -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; - -@PluginDescriptor( - name = "!MultiLines", - description = "Show borders of multicombat and PvP safezones", - tags = {"multicombat", "lines", "pvp", "deadman", "safezones", "bogla"}, - enabledByDefault = false -) -public class ZoneIndicatorsPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private ClientThread clientThread; - - @Inject - private ZoneIndicatorsConfig config; - - @Inject - private ZoneIndicatorsOverlay overlay; - - @Inject - private ZoneIndicatorsMinimapOverlay minimapOverlay; - - @Inject - private OverlayManager overlayManager; - - @Getter - private GeneralPath[] multicombatPathToDisplay; - - @Getter - private GeneralPath[] pvpPathToDisplay; - - @Getter - private boolean inPvp; - - @Getter - private boolean inDeadman; - - private int currentPlane; - - @Provides - ZoneIndicatorsConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(ZoneIndicatorsConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - overlayManager.add(minimapOverlay); - - multicombatPathToDisplay = new GeneralPath[Constants.MAX_Z]; - pvpPathToDisplay = new GeneralPath[Constants.MAX_Z]; - - clientThread.invokeLater(() -> - { - if (client.getGameState() == GameState.LOGGED_IN) - { - findLinesInScene(); - } - }); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - overlayManager.remove(minimapOverlay); - - multicombatPathToDisplay = null; - pvpPathToDisplay = null; - } - - private void transformWorldToLocal(float[] coords) - { - LocalPoint lp = LocalPoint.fromWorld(client, (int)coords[0], (int)coords[1]); - coords[0] = lp.getX() - Perspective.LOCAL_TILE_SIZE / 2; - coords[1] = lp.getY() - Perspective.LOCAL_TILE_SIZE / 2; - } - - private boolean isOpenableAt(WorldPoint wp) - { - int sceneX = wp.getX() - client.getBaseX(); - int sceneY = wp.getY() - client.getBaseY(); - - Tile tile = client.getScene().getTiles()[wp.getPlane()][sceneX][sceneY]; - if (tile == null) - { - return false; - } - - WallObject wallObject = tile.getWallObject(); - if (wallObject == null) - { - return false; - } - - ObjectComposition objectComposition = client.getObjectDefinition(wallObject.getId()); - if (objectComposition == null) - { - return false; - } - - String[] actions = objectComposition.getActions(); - if (actions == null) - { - return false; - } - - return Arrays.stream(actions).anyMatch(x -> x != null && x.toLowerCase().equals("open")); - } - - private boolean collisionFilter(float[] p1, float[] p2) - { - int x1 = (int)p1[0]; - int y1 = (int)p1[1]; - int x2 = (int)p2[0]; - int y2 = (int)p2[1]; - - if (x1 > x2) - { - int temp = x1; - x1 = x2; - x2 = temp; - } - if (y1 > y2) - { - int temp = y1; - y1 = y2; - y2 = temp; - } - int dx = x2 - x1; - int dy = y2 - y1; - WorldArea wa1 = new WorldArea(new WorldPoint( - x1, y1, currentPlane), 1, 1); - WorldArea wa2 = new WorldArea(new WorldPoint( - x1 - dy, y1 - dx, currentPlane), 1, 1); - - if (isOpenableAt(wa1.toWorldPoint()) || isOpenableAt(wa2.toWorldPoint())) - { - // When there's something with the open option (e.g. a door) on the tile, - // we assume it can be opened and walked through afterwards. Without this - // check, the line for that tile wouldn't render with collision detection - // because the collision check isn't done if collision data changes. - return true; - } - - boolean b1 = wa1.canTravelInDirection(client, -dy, -dx); - boolean b2 = wa2.canTravelInDirection(client, dy, dx); - return b1 && b2; - } - - private void findLinesInScene() - { - inDeadman = client.getWorldType().stream().anyMatch(x -> - x == WorldType.DEADMAN || x == WorldType.SEASONAL_DEADMAN); - inPvp = client.getWorldType().stream().anyMatch(x -> - x == WorldType.PVP || x == WorldType.PVP_HIGH_RISK); - - Rectangle sceneRect = new Rectangle( - client.getBaseX() + 1, client.getBaseY() + 1, - Constants.SCENE_SIZE - 2, Constants.SCENE_SIZE - 2); - - // Generate lines for multicombat zones - if (config.multicombatZoneVisibility() == ZoneVisibility.HIDE) - { - for (int i = 0; i < multicombatPathToDisplay.length; i++) - { - multicombatPathToDisplay[i] = null; - } - } - else - { - for (int i = 0; i < multicombatPathToDisplay.length; i++) - { - currentPlane = i; - - GeneralPath lines = new GeneralPath(MapLocations.getMulticombat(sceneRect, i)); - lines = Geometry.clipPath(lines, sceneRect); - if (config.multicombatZoneVisibility() == ZoneVisibility.SHOW_IN_PVP && - !isInDeadman() && !isInPvp()) - { - lines = Geometry.clipPath(lines, MapLocations.getRoughWilderness(i)); - } - lines = Geometry.splitIntoSegments(lines, 1); - if (config.collisionDetection()) - { - lines = Geometry.filterPath(lines, this::collisionFilter); - } - lines = Geometry.transformPath(lines, this::transformWorldToLocal); - multicombatPathToDisplay[i] = lines; - } - } - - // Generate safezone lines for deadman/pvp worlds - for (int i = 0; i < pvpPathToDisplay.length; i++) - { - currentPlane = i; - - GeneralPath safeZonePath = null; - if (config.showDeadmanSafeZones() && isInDeadman()) - { - safeZonePath = new GeneralPath(MapLocations.getDeadmanSafeZones(sceneRect, i)); - } - else if (config.showPvpSafeZones() && isInPvp()) - { - safeZonePath = new GeneralPath(MapLocations.getPvpSafeZones(sceneRect, i)); - } - if (safeZonePath != null) - { - safeZonePath = Geometry.clipPath(safeZonePath, sceneRect); - safeZonePath = Geometry.splitIntoSegments(safeZonePath, 1); - if (config.collisionDetection()) - { - safeZonePath = Geometry.filterPath(safeZonePath, this::collisionFilter); - } - safeZonePath = Geometry.transformPath(safeZonePath, this::transformWorldToLocal); - } - pvpPathToDisplay[i] = safeZonePath; - } - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (event.getKey().equals("collisionDetection") || - event.getKey().equals("multicombatZoneVisibility") || - event.getKey().equals("deadmanSafeZones") || - event.getKey().equals("pvpSafeZones")) - { - findLinesInScene(); - } - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - { - findLinesInScene(); - } - } -} 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/zoneIndicators/ZoneVisibility.java deleted file mode 100644 index 9a457d9e50..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public enum ZoneVisibility -{ - HIDE("Hide"), - SHOW_IN_PVP("Show in PvP"), - SHOW_EVERYWHERE("Show everywhere"); - - private final String visibility; - - @Override - public String toString() - { - return visibility; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java deleted file mode 100644 index 6f63951785..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI - * No rights reserved. Use, redistribute, and modify at your own discretion, - * and in accordance with Yagex and RuneLite guidelines. - * However, aforementioned monkey would prefer if you don't sell this plugin for profit. - * Good luck on your raids! - */ - -package net.runelite.client.plugins.ztob; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("Theatre") - -public interface TheatreConfig extends Config -{ - @ConfigItem( - position = 0, - keyName = "MaidenBlood", - name = "Maiden blood attack", - description = "" - ) - default boolean MaidenBlood(){ return false; } - - @ConfigItem( - position = 1, - keyName = "MaidenSpawns", - name = "Maiden blood spawns", - description = "" - ) - default boolean MaidenSpawns(){ return false; } - - @ConfigItem( - position = 2, - keyName = "BloatIndicator", - name = "Bloat indicator", - description = "" - ) - default boolean BloatIndicator(){ return false; } - - @ConfigItem( - position = 3, - keyName = "BloatHands", - name = "Bloat Falling Hands", - description = "" - ) - default boolean BloatHands(){ return false; } - - @ConfigItem( - position = 4, - keyName = "NyloPillars", - name = "Nylocas pillar health", - description = "" - ) - default boolean NyloPillars(){ return false; } - - @ConfigItem( - position = 5, - keyName = "NyloBlasts", - name = "Nylocas explosions", - description = "" - ) - default boolean NyloBlasts(){ return false; } - - @ConfigItem( - position = 6, - keyName = "SotetsegMaze1", - name = "Sotetseg maze", - description = "" - ) - default boolean SotetsegMaze1(){ return false; } - - @ConfigItem( - position = 7, - keyName = "SotetsegMaze2", - name = "Sotetseg maze (solo mode)", - description = "" - ) - default boolean SotetsegMaze2(){ return false; } - - @ConfigItem( - position = 8, - keyName = "SotetsegTick", - name = "Sotetseg tick eat", - description = "" - ) - default boolean SotetsegTick(){ return false; } - - @ConfigItem( - position = 9, - keyName = "XarpusExhumed", - name = "Xarpus exhumed", - description = "" - ) - default boolean XarpusExhumed(){ return false; } - - @ConfigItem( - position = 10, - keyName = "XarpusTick", - name = "Xarpus tick", - description = "" - ) - default boolean XarpusTick(){ return false; } - - @ConfigItem( - position = 11, - keyName = "VerzikCupcakes", - name = "Verzik cupcakes", - description = " " - ) - default boolean VerzikCupcakes(){ return false; } - - @ConfigItem( - position = 12, - keyName = "VerzikTick", - name = "Verzik p3 tick", - description = "" - ) - default boolean VerzikTick(){ return false; } - - @ConfigItem( - position = 13, - keyName = "VerzikMelee", - name = "Verzik p3 melee range", - description = "" - ) - default boolean VerzikMelee(){ return false; } - - @ConfigItem( - position = 14, - keyName = "VerzikYellow", - name = "Verzik yellow timing", - description = "" - ) - default boolean VerzikYellow(){ return false; } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java deleted file mode 100644 index 07f8e2f7b4..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI - * No rights reserved. Use, redistribute, and modify at your own discretion, - * and in accordance with Yagex and RuneLite guidelines. - * However, aforementioned monkey would prefer if you don't sell this plugin for profit. - * Good luck on your raids! - */ - -package net.runelite.client.plugins.ztob; - -import java.awt.*; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldArea; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.OverlayUtil; - -public class TheatreOverlay extends Overlay { - private final Client client; - - - private final TheatrePlugin plugin; - private final TheatreConfig config; - - @Inject - private TheatreOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) { - this.client = client; - this.plugin = plugin; - this.config = config; - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGH); - setLayer(OverlayLayer.ABOVE_SCENE); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (plugin.isRunMaiden()) - { - if (config.MaidenBlood()) - { - for (WorldPoint point : plugin.getMaiden_BloodSpatters()) - { - drawTile(graphics, point, new Color(0,150,200), 2, 150, 10); - } - } - - if (config.MaidenSpawns()) - { - for (WorldPoint point : plugin.getMaiden_SpawnLocations()) - { - drawTile(graphics, point, new Color(0,150,200), 2, 180, 20); - } - for (WorldPoint point : plugin.getMaiden_SpawnLocations2()) - { - drawTile(graphics, point, new Color(0,150,200), 1,120, 10); - } - } - } - - if (plugin.isRunBloat()) - { - - if (config.BloatHands()) - { - for (WorldPoint p : plugin.getBloat_Hands()) - { - drawTile(graphics, p, Color.BLACK,3,255,0); - } - } - if(config.BloatIndicator()) { - NPC bloat = plugin.getBloat_NPC(); - int state = plugin.getBloat_State(); - if (bloat == null) { - return null; - } - switch (state) { - case 2: - renderNpcOverlay(graphics, bloat, Color.GREEN, 3, 150, 0); - break; - case 3: - renderNpcOverlay(graphics, bloat, Color.YELLOW, 3, 150, 0); - break; - default: - renderNpcOverlay(graphics, bloat, new Color(223, 109, 255), 3, 150, 0); - break; - } - } - } - - if (plugin.isRunNylocas()) - { - if (config.NyloPillars()) - { - Map pillars = plugin.getNylocas_Pillars(); - for (NPC npc : pillars.keySet()) { - final int health = pillars.get(npc); - final String healthStr = String.valueOf(health) + "%"; - WorldPoint p = npc.getWorldLocation(); - LocalPoint lp = LocalPoint.fromWorld(client, p.getX() + 1, p.getY() + 1); - final double rMod = 130.0 * health / 100.0; - final double gMod = 255.0 * health / 100.0; - final double bMod = 125.0 * health / 100.0; - final Color c = new Color((int) (255 - rMod), (int) (0 + gMod), (int) (0 + bMod)); - Point canvasPoint = Perspective.localToCanvas(client, lp, client.getPlane(), - 65); - renderTextLocation(graphics, healthStr, 13, Font.BOLD, c, canvasPoint); - } - } - - if (config.NyloBlasts()) - { - final Map npcMap = plugin.getNylocas_Map(); - for (NPC npc : npcMap.keySet()) - { - int ticksLeft = npcMap.get(npc); - if (ticksLeft > -1) { - if (ticksLeft <= 6) { - Color color = new Color(255, 255,0 ,180); - int outlineWidth = 2; - int outlineAlpha = 150; - renderNpcOverlay(graphics, npc, color, outlineWidth, outlineAlpha, 0); - } - } - } - } - } - - if (plugin.isRunSotetseg()) - { - if (config.SotetsegMaze1()) - { - int i = 1; - for (GroundObject z : plugin.getRedTiles().keySet()) - { - Polygon poly = z.getCanvasTilePoly(); - if (poly != null) - { - graphics.setColor(Color.WHITE); - graphics.setStroke(new BasicStroke(2)); - graphics.draw(poly); - } - Point textLocation = z.getCanvasTextLocation(graphics, String.valueOf(i), 0); - if (textLocation != null) - { - OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(i), Color.WHITE); - } - - i++; - } - } - - if (config.SotetsegMaze2()) - { - for (WorldPoint p : plugin.getRedTilesOverworld()) - { - drawTile(graphics, p, Color.WHITE, 2, 255, 10); - } - } - if (config.SotetsegTick()) { - NPC boss = plugin.getSotetseg_NPC(); - int eattick = plugin.getTickTillEat(); - if (eattick > -1) - { - final String eatTicksStr = String.valueOf(eattick); - Point canvasPoint = boss.getCanvasTextLocation(graphics, eatTicksStr, 130); - renderTextLocation(graphics, eatTicksStr, 12, Font.BOLD, Color.WHITE, canvasPoint); - - } - } - } - - - - if (plugin.isRunXarpus()) - { - NPC boss = plugin.getXarpus_NPC(); - - if (boss.getId() == NpcID.XARPUS_8340 && !plugin.isXarpus_Stare() && config.XarpusTick()) - { - int tick = plugin.getXarpus_TicksUntilShoot(); - if (tick < 1) - { - tick = tick % 4 + 4; - } - final String ticksLeftStr = String.valueOf(tick); - Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 130); - renderTextLocation(graphics, ticksLeftStr, 12, Font.BOLD, Color.WHITE, canvasPoint); - } - if (boss.getId() == NpcID.XARPUS_8339 && config.XarpusExhumed()) - { - for (GroundObject o : plugin.getXarpus_Exhumeds().keySet()) - { - Polygon poly = o.getCanvasTilePoly(); - if (poly != null) - { - graphics.setColor(new Color(0, 255, 0, 130)); - graphics.setStroke(new BasicStroke(1)); - graphics.draw(poly); - } - } - } - } - - if (plugin.isRunVerzik()) - { - if (config.VerzikCupcakes()) - { - for (WorldPoint p : plugin.getVerzik_RangeProjectiles().values()) - { - drawTile(graphics, p, Color.RED, 2, 180, 50); - } - } - - if (config.VerzikYellow()) - { - for (WorldPoint p : plugin.getVerzik_YellowTiles()) - { - drawTile(graphics, p, Color.YELLOW,3,255,0); - - Projectile yellowBall = plugin.getVerzik_YellowBall(); - if (yellowBall != null) - { - final int ticksToImpact = yellowBall.getRemainingCycles()/30; - final String countdownStr = String.valueOf(ticksToImpact); - Point canvasPoint = Perspective.getCanvasTextLocation(client, graphics, LocalPoint.fromWorld(client, p), countdownStr, 0); - renderTextLocation(graphics, countdownStr, 12, Font.BOLD, Color.WHITE, canvasPoint); - } - } - } - if (plugin.getVerzik_NPC_P3() != null) { - final NPC boss = plugin.getVerzik_NPC_P3(); - if (boss.getId() == NpcID.VERZIK_VITUR_8374) - { - if (config.VerzikTick()) - { - final int ticksLeft = plugin.getP3_TicksUntilAttack(); - if (ticksLeft > 0 && ticksLeft < 8) - { - final String ticksLeftStr = String.valueOf(ticksLeft); - Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); - renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); - } - } - - if (config.VerzikMelee() && boss.getAnimation() != 8127) - { - List meleeRange = getHitSquares(boss.getWorldLocation(), 7, 1, false); - - for (WorldPoint p : meleeRange) - { - drawTile(graphics, p, Color.WHITE, 1,155, 10); - } - } - } - } - } - return null; - } - - private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) { - WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); - if (point.distanceTo(playerLocation) >= 32) { - return; - } - LocalPoint lp = LocalPoint.fromWorld(client, point); - if (lp == null) { - return; - } - - Polygon poly = Perspective.getCanvasTilePoly(client, lp); - if (poly == null) { - return; - } - //OverlayUtil.renderPolygon(graphics, poly, color); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); - graphics.setStroke(new BasicStroke(strokeWidth)); - graphics.draw(poly); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); - graphics.fill(poly); - } - - private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha) - { - int size = 1; - NPCComposition composition = actor.getTransformedComposition(); - if (composition != null) - { - size = composition.getSize(); - } - LocalPoint lp = actor.getLocalLocation(); - Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size); - - if (tilePoly != null) - { - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); - graphics.setStroke(new BasicStroke(outlineWidth)); - graphics.draw(tilePoly); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); - graphics.fill(tilePoly); - } - } - - private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) - { - graphics.setFont(new Font("Arial", fontStyle, fontSize)); - if (canvasPoint != null) - { - final Point canvasCenterPoint = new Point( - canvasPoint.getX(), - canvasPoint.getY()); - final Point canvasCenterPoint_shadow = new Point( - canvasPoint.getX() + 1, - canvasPoint.getY() + 1) ; - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); - } - } - - private List getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder) - { - List little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList(); - List big = new WorldArea(npcLoc.getX()-thickness, npcLoc.getY()-thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList(); - if (!includeUnder) - { - for (Iterator it = big.iterator(); it.hasNext();) - { - WorldPoint p = it.next(); - if (little.contains(p)) - { - it.remove(); - } - } - } - return big; - } -} 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 deleted file mode 100644 index 8fa2ee2481..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java +++ /dev/null @@ -1,766 +0,0 @@ -/* - * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI - * No rights reserved. Use, redistribute, and modify at your own discretion, - * and in accordance with Yagex and RuneLite guidelines. - * However, aforementioned monkey would prefer if you don't sell this plugin for profit. - * Good luck on your raids! - */ - -package net.runelite.client.plugins.ztob; - -import java.util.*; -import java.util.Iterator; -import javax.inject.Inject; - -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import lombok.AccessLevel; -import lombok.Getter; -import net.runelite.api.*; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.*; -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; - -@PluginDescriptor( - name = "!Theatre of Blood", - description = "All-in-one plugin for Theatre of Blood", - tags = {"ToB"}, - enabledByDefault = false -) - -public class TheatrePlugin extends Plugin { - private static final int GRAPHICSOBJECT_ID_MAIDEN = 1579; - private static final int NPCID_NYLOCAS_PILLAR = 8358; - private static final int GROUNDOBJECT_ID_BLACKMAZE = 33034; - private static final int GROUNDOBJECT_ID_REDMAZE = 33035; - private static final int GROUNDOBJECT_ID_EXHUMED = 32743; - private static final int ANIMATION_ID_XARPUS = 8059; - private static final int GRAPHICSOBJECT_ID_YELLOW = 1595; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND1 = 1570; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND2 = 1571; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND3 = 1572; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND4 = 1573; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND5 = 1576; - private static final int PROJECTILE_ID_P2RANGE = 1583; - private static final int PROJECTILE_ID_YELLOW = 1596; - private static final int ANIMATION_ID_P3_WEB = 8127; - private static final int ANIMATION_ID_P3_YELLOW = 8126; - private static final int ANIMATION_ID_P3_MELEE = 8123; - private static final int ANIMATION_ID_P3_MAGE = 8124; - private static final int ANIMATION_ID_P3_RANGE = 8125; - private static final int VERZIK_ID_P3 = NpcID.VERZIK_VITUR_8374; - private static final int NPC_ID_TORNADO = 8386; - private static final int PROJECTILE_ID_P3_GREEN = 1598; - private static final String sotmsg = "A large ball of energy is shot your way..."; - private static final String sotmsg1 = "A large ball of energy is shot your way..."; - - @Inject - private ChatMessageManager chatMessageManager; - - @Getter(AccessLevel.PACKAGE) - private boolean runMaiden; - - @Getter(AccessLevel.PACKAGE) - private List Maiden_BloodSpatters = new ArrayList<>(); - - private List Maiden_Spawns = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private List Maiden_SpawnLocations = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private List Maiden_SpawnLocations2 = new ArrayList<>(); - - - @Getter(AccessLevel.PACKAGE) - private boolean runBloat; - - @Getter(AccessLevel.PACKAGE) - private int TickTillEat = 20; - - @Getter(AccessLevel.PACKAGE) - private NPC Bloat_NPC; - - private int Bloat_downCount; - - @Getter(AccessLevel.PACKAGE) - private Integer Bloat_State; - - - @Getter(AccessLevel.PACKAGE) - private boolean runNylocas; - - @Getter(AccessLevel.PACKAGE) - private Map Nylocas_Pillars = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private Map Nylocas_Map = new HashMap<>(); - - - @Getter(AccessLevel.PACKAGE) - private boolean runSotetseg; - - @Getter(AccessLevel.PACKAGE) - private final Map RedTiles = new LinkedHashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private List RedTilesOverworld = new ArrayList<>(); - - private List BlackTilesOverworld = new ArrayList<>(); - - private List BlackTilesUnderworld= new ArrayList<>(); - - private List RedTilesUnderworld= new ArrayList<>(); - - private List GridPath = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private boolean runXarpus; - - private int Xarpus_previousAnimation; - - @Getter(AccessLevel.PACKAGE) - private boolean Xarpus_Stare; - - @Getter(AccessLevel.PACKAGE) - private final Map Xarpus_Exhumeds = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private int Xarpus_TicksUntilShoot = 9; - - @Getter(AccessLevel.PACKAGE) - private NPC Xarpus_NPC; - - @Getter(AccessLevel.PACKAGE) - private NPC Sotetseg_NPC; - - @Getter(AccessLevel.PACKAGE) - private boolean runVerzik; - - @Getter(AccessLevel.PACKAGE) - private final Map Verzik_RangeProjectiles = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private int P3_TicksUntilAttack = -1; - - @Getter(AccessLevel.PACKAGE) - private Projectile Verzik_YellowBall; - - @Getter(AccessLevel.PACKAGE) - private List Verzik_YellowTiles = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private List Bloat_Hands = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private NPC Verzik_NPC; - - @Getter(AccessLevel.PACKAGE) - private NPC Verzik_NPC_P3; - - @Getter(AccessLevel.PACKAGE) - private NPC Verzik_NPC_P2; - - private int P3_attacksLeft; - - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private TheatreOverlay overlay; - - @Inject - private TheatreConfig config; - - @Provides - TheatreConfig getConfig(ConfigManager configManager) { - return configManager.getConfig(TheatreConfig.class); - } - - @Override - protected void startUp() { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() { - overlayManager.remove(overlay); - } - - @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) - { - NPC npc = npcSpawned.getNpc(); - switch (npc.getId()) - { - case NpcID.THE_MAIDEN_OF_SUGADINTI: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8361: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8362: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8363: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8364: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8365: - runMaiden = true; - break; - case NpcID.BLOOD_SPAWN: - Maiden_Spawns.add(npc); - break; - case NpcID.PESTILENT_BLOAT: - runBloat = true; - Bloat_NPC = npc; - break; - case NPCID_NYLOCAS_PILLAR: - runNylocas = true; - if (!Nylocas_Pillars.keySet().contains(npc)) - { - Nylocas_Pillars.put(npc, 100); - } - break; - case 8342: case 8343: case 8344: case 8345: case 8346: case 8347: - case 8348: case 8349: case 8350: case 8351: case 8352: case 8353: - if (runNylocas) - { - Nylocas_Map.put(npc, 52); - } - break; - case NpcID.SOTETSEG: - case NpcID.SOTETSEG_8388: - runSotetseg = true; - Sotetseg_NPC = npc; - RedTiles.clear(); - break; - case NpcID.XARPUS: - case NpcID.XARPUS_8339: - case NpcID.XARPUS_8340: - case NpcID.XARPUS_8341: - runXarpus = true; - Xarpus_NPC = npc; - Xarpus_Stare = false; - Xarpus_TicksUntilShoot = 9; - Xarpus_previousAnimation = -1; - break; - case NpcID.VERZIK_VITUR_8369: - case NpcID.VERZIK_VITUR_8370: - case NpcID.VERZIK_VITUR_8371: - case NpcID.VERZIK_VITUR_8373: - case NpcID.VERZIK_VITUR_8375: - Verzik_NPC = npc; - runVerzik = true; - break; - - case NpcID.VERZIK_VITUR_8372:/*p2 spider*/ - Verzik_NPC_P2 = npc; - runVerzik = true; - break; - - case NpcID.VERZIK_VITUR_8374:/*p3 spider*/ - P3_TicksUntilAttack = 0; - P3_attacksLeft = 9; - Verzik_NPC_P3 = npc; - runVerzik = true; - break; - } - } - - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) { - NPC npc = npcDespawned.getNpc(); - switch (npc.getId()) { - case NpcID.THE_MAIDEN_OF_SUGADINTI: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8361: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8362: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8363: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8364: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8365: - runMaiden = false; - Maiden_Spawns.clear(); - break; - case NpcID.BLOOD_SPAWN: - Maiden_Spawns.remove(npc); - break; - case NpcID.PESTILENT_BLOAT: - runBloat = false; - Bloat_NPC = null; - break; - case NPCID_NYLOCAS_PILLAR: - if (Nylocas_Pillars.keySet().contains(npc)) - { - Nylocas_Pillars.remove(npc); - } - break; - case 8342: case 8343: case 8344: case 8345: case 8346: case 8347: - case 8348: case 8349: case 8350: case 8351: case 8352: case 8353: - if (Nylocas_Map.keySet().contains(npc)) - { - Nylocas_Map.remove(npc); - } - break; - case NpcID.SOTETSEG: - case NpcID.SOTETSEG_8388: - RedTiles.clear(); - if (client.getPlane() != 3) - { - runSotetseg = false; - } - Sotetseg_NPC = null; - break; - case NpcID.XARPUS: - case NpcID.XARPUS_8339: - case NpcID.XARPUS_8340: - case NpcID.XARPUS_8341: - runXarpus = false; - Xarpus_NPC = null; - Xarpus_Stare = false; - Xarpus_TicksUntilShoot = 9; - Xarpus_previousAnimation = -1; - Xarpus_Exhumeds.clear(); - break; - case NpcID.VERZIK_VITUR_8369: - case NpcID.VERZIK_VITUR_8370: - case NpcID.VERZIK_VITUR_8371:/*p2*/ - - case NpcID.VERZIK_VITUR_8373: - - case NpcID.VERZIK_VITUR_8375: - Verzik_NPC = null; - break; - case NpcID.VERZIK_VITUR_8372: - Verzik_NPC_P2 = null; - break; - case NpcID.VERZIK_VITUR_8374:/*p3 spider*/ - Verzik_NPC_P3 = null; - break; - - } - - } - - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) - { - if (runSotetseg) - { - GroundObject o = event.getGroundObject(); - if (o.getId() == GROUNDOBJECT_ID_BLACKMAZE) - { - Tile t = event.getTile(); - WorldPoint p = t.getWorldLocation(); - if (t.getPlane() == 0) - { - if (!BlackTilesOverworld.contains(p)) - BlackTilesOverworld.add(p); - } - else - { - if (!BlackTilesUnderworld.contains(p)) - BlackTilesUnderworld.add(p); - } - } - - if (o.getId() == GROUNDOBJECT_ID_REDMAZE) - { - Tile t = event.getTile(); - WorldPoint p = t.getWorldLocation(); - if (p.getPlane() == 0) - { - if (!RedTiles.containsValue(t)) - { - RedTiles.put(o,t); - } - } - else - { - if (!RedTilesUnderworld.contains(p)) - RedTilesUnderworld.add(p); - } - } - } - - if (runXarpus) - { - GroundObject o = event.getGroundObject(); - if (o.getId() == GROUNDOBJECT_ID_EXHUMED) - { - Xarpus_Exhumeds.put(o, 18); - } - } - } - - @Subscribe - public void onProjectileMoved(ProjectileMoved event) - { - if (runVerzik) - { - Projectile projectile = event.getProjectile(); - if (projectile.getId() == PROJECTILE_ID_P2RANGE) - { - WorldPoint p = WorldPoint.fromLocal(client,event.getPosition()); - Verzik_RangeProjectiles.put(projectile, p); - } - } - } - - @Subscribe - public void onChatMessage(ChatMessage chatMessage) - { - MessageNode messageNode = chatMessage.getMessageNode(); - - if (messageNode.getValue().toLowerCase().contains(sotmsg.toLowerCase())) - { - TickTillEat = 20; - /*20 ticks*/ - - } - - - } - - @Subscribe - public void onGameTick(GameTick event) - { - if (runMaiden) - { - Maiden_BloodSpatters.clear(); - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_MAIDEN) - { - Maiden_BloodSpatters.add(WorldPoint.fromLocal(client, o.getLocation())); - } - } - - Maiden_SpawnLocations2.clear(); - Maiden_SpawnLocations2.addAll(Maiden_SpawnLocations); - Maiden_SpawnLocations.clear(); - for (NPC spawn : Maiden_Spawns) - { - Maiden_SpawnLocations.add(spawn.getWorldLocation()); - } - } - - if (runBloat) - { - - Bloat_downCount++; - - Bloat_Hands.clear(); - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND1 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND2 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND3 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND4|| o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND5) - { - Bloat_Hands.add(WorldPoint.fromLocal(client, o.getLocation())); - } - } - - - if (Bloat_NPC.getAnimation() == -1) //1 = up; 2 = down; 3 = warn; - { - Bloat_downCount = 0; - if (Bloat_NPC.getHealth() == 0) - { - Bloat_State = 2; - } - else - Bloat_State = 1; - } - else - { - if (25 it = Nylocas_Map.keySet().iterator(); it.hasNext();) - { - NPC npc = it.next(); - int ticksLeft = Nylocas_Map.get(npc); - - if (ticksLeft < 0) - { - it.remove(); - continue; - } - Nylocas_Map.replace(npc, ticksLeft - 1); - } - - for (NPC pillar : Nylocas_Pillars.keySet()) - { - int healthPercent = pillar.getHealthRatio(); - if (healthPercent > -1) - { - Nylocas_Pillars.replace(pillar, healthPercent); - } - } - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == 8358) - { - runNylocas = true; - break; - } - runNylocas = false; - } - } - - if (runSotetseg) - { - TickTillEat--; - boolean sotetsegFighting = false; - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == NpcID.SOTETSEG_8388) - { - BlackTilesUnderworld.clear(); - BlackTilesOverworld.clear(); - RedTilesOverworld.clear(); - RedTilesUnderworld.clear(); - GridPath.clear(); - sotetsegFighting = true; - RedTiles.clear(); - break; - } - } - - if (!sotetsegFighting) - { - if (!BlackTilesUnderworld.isEmpty() && !RedTilesUnderworld.isEmpty() && GridPath.isEmpty()) - { - int minX = 99999; - int minY = 99999; - for (WorldPoint p : BlackTilesUnderworld) - { - int x = p.getX(); - int y = p.getY(); - if (x < minX) - { - minX = x; - } - if (y < minY) - { - minY = y; - } - } - - - - boolean messageSent = false; - for (WorldPoint p : RedTilesUnderworld) - { - WorldPoint pN = new WorldPoint(p.getX(), p.getY() + 1, p.getPlane()); - WorldPoint pS = new WorldPoint(p.getX(), p.getY() - 1, p.getPlane()); - WorldPoint pE = new WorldPoint(p.getX() + 1, p.getY(), p.getPlane()); - WorldPoint pW = new WorldPoint(p.getX() - 1, p.getY(), p.getPlane()); - - if ( !( (RedTilesUnderworld.contains(pN) && RedTilesUnderworld.contains(pS)) || - (RedTilesUnderworld.contains(pE) && RedTilesUnderworld.contains(pW)) ) ) - { - GridPath.add(new Point(p.getX() - minX, p.getY() - minY)); - if (!messageSent) - { - //client.addChatMessage(ChatMessageType.SERVER, "", "Maze path acquired.", null); - messageSent = true; - } - } - - } - } - - if (!BlackTilesOverworld.isEmpty() && !GridPath.isEmpty() && RedTilesOverworld.isEmpty()) - { - int minX = 99999; - int minY = 99999; - for (WorldPoint p : BlackTilesOverworld) - { - int x = p.getX(); - int y = p.getY(); - if (x < minX) - { - minX = x; - } - if (y < minY) - { - minY = y; - } - } - for (Point p : GridPath) - { - RedTilesOverworld.add(new WorldPoint(minX + p.getX(), minY + p.getY(), 0)); - } - } - } - } - - if (runXarpus) - { - for (Iterator it = Xarpus_Exhumeds.keySet().iterator(); it.hasNext();) - { - GroundObject key = it.next(); - Xarpus_Exhumeds.replace(key, Xarpus_Exhumeds.get(key) - 1); - if (Xarpus_Exhumeds.get(key) < 0) - { - it.remove(); - } - } - if (Xarpus_NPC.getOverheadText() != null ) - { - Xarpus_Stare = true; - } - if (Xarpus_Stare) - { - //dont hit xarpus if it looking at u - } - else if (Xarpus_NPC.getId() == NpcID.XARPUS_8340) - { - Xarpus_TicksUntilShoot--; - if (Xarpus_NPC.getAnimation() == ANIMATION_ID_XARPUS && Xarpus_previousAnimation != ANIMATION_ID_XARPUS) - { - Xarpus_TicksUntilShoot = 3; - } - Xarpus_previousAnimation = Xarpus_NPC.getAnimation(); - } - - } - - if (runVerzik) - { - if (!Verzik_RangeProjectiles.isEmpty()) - { - for (Iterator it = Verzik_RangeProjectiles.keySet().iterator(); it.hasNext();) - { - Projectile projectile = it.next(); - if (projectile.getRemainingCycles() < 1) - { - it.remove(); - } - } - } - - Verzik_YellowBall = null; - Verzik_YellowTiles.clear(); - - for (Projectile projectile : client.getProjectiles()) - { - if (projectile.getId() == PROJECTILE_ID_YELLOW) - { - Verzik_YellowBall = projectile; - break; - } - } - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_YELLOW) - { - Verzik_YellowTiles.add(WorldPoint.fromLocal(client, o.getLocation())); - } - } - - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == 8379) - { - runVerzik = true; - break; - } - runVerzik = false; - } - - - if (Verzik_NPC_P3 != null) { - boolean tornadosActive = false; - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == NPC_ID_TORNADO) - { - tornadosActive = true; - break; - } - } - - boolean isGreenBall = false; - for (Projectile projectile : client.getProjectiles()) - { - if (projectile.getId() == PROJECTILE_ID_P3_GREEN) { - isGreenBall = projectile.getRemainingCycles() > 210; - break; - } - } - P3_TicksUntilAttack--; - - switch (Verzik_NPC_P3.getAnimation()) { - case ANIMATION_ID_P3_MAGE: - if (P3_TicksUntilAttack < 2) { - P3_attacksLeft--; - if (tornadosActive) { - P3_TicksUntilAttack = 5; - } else { - P3_TicksUntilAttack = 7; - } - if (P3_attacksLeft < 1) { - P3_TicksUntilAttack = 24; - } - } - break; - case ANIMATION_ID_P3_RANGE: - if (P3_TicksUntilAttack < 2) { - P3_attacksLeft--; - if (tornadosActive) { - P3_TicksUntilAttack = 5; - } else { - P3_TicksUntilAttack = 7; - } - if (P3_attacksLeft < 1) { - P3_TicksUntilAttack = 30; - } - if (isGreenBall) { - P3_TicksUntilAttack = 12; - } - } - break; - case ANIMATION_ID_P3_MELEE: - if (P3_TicksUntilAttack < 2) { - P3_attacksLeft--; - if (tornadosActive) { - P3_TicksUntilAttack = 5; - } else { - P3_TicksUntilAttack = 7; - } - if (P3_attacksLeft < 1) { - P3_TicksUntilAttack = 24; - } - } - break; - case ANIMATION_ID_P3_WEB: - P3_attacksLeft = 4; - P3_TicksUntilAttack = 11; // - break; - case ANIMATION_ID_P3_YELLOW: - P3_attacksLeft = 14; - P3_TicksUntilAttack = 11; - break; - } - } - - } - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahConfig.java deleted file mode 100644 index 5e18ef4fc3..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahConfig.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.runelite.client.plugins.zulrah; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("zulrah") -public interface ZulrahConfig extends Config { - @ConfigItem( - position = 0, - keyName = "zulrahenable", - name = "Enable Zulrah Helper", - description = "Configures whether or not to enable Zulrah Helper." - ) - default boolean EnableZulrah() { return true; } - - @ConfigItem( - position = 1, - keyName = "zulrahprayenable", - name = "Show Prayer Helper", - description = "Configures whether or not to show when to pray at Zulrah." - ) - default boolean EnableZulrahPrayerHelper() { return true; } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahOverlay.java deleted file mode 100644 index ed2dd23991..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahOverlay.java +++ /dev/null @@ -1,72 +0,0 @@ -package net.runelite.client.plugins.zulrah; - -import java.awt.*; -import javax.inject.Inject; - -import net.runelite.api.*; -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.components.PanelComponent; -import net.runelite.client.ui.overlay.components.TitleComponent; - -public class ZulrahOverlay extends Overlay { - private final ZulrahConfig config; - private final ZulrahPlugin plugin; - private final PanelComponent panelComponent = new PanelComponent(); - - - @Inject - private Client client; - - @Inject - private ZulrahOverlay(ZulrahConfig config, ZulrahPlugin plugin) { - this.config = config; - this.plugin = plugin; - setLayer(OverlayLayer.ABOVE_SCENE); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.MED); - panelComponent.setPreferredSize(new Dimension(150, 0)); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (!config.EnableZulrahPrayerHelper()) { - return null; - } - NPC Zulrah = plugin.Zulrah; - if (Zulrah != null) { - if (plugin.prayerconserve && plugin.nextprayerendticks == 0) { - Player player = client.getLocalPlayer(); - HeadIcon icon = player.getOverheadIcon(); - if (icon != null) { - final String text = "Disable Overhead Prayer"; - final int textWidth = graphics.getFontMetrics().stringWidth(text); - final int textHeight = graphics.getFontMetrics().getAscent() - graphics.getFontMetrics().getDescent(); - final int width = (int) client.getRealDimensions().getWidth(); - java.awt.Point jpoint = new java.awt.Point((width / 2) - textWidth, textHeight + 75); - panelComponent.getChildren().clear(); - panelComponent.getChildren().add(TitleComponent.builder().text(text).color(Color.RED).build()); - panelComponent.setPreferredLocation(jpoint); - panelComponent.render(graphics); - } - } else if (plugin.nextprayerendticks != 0) { - Player player = client.getLocalPlayer(); - HeadIcon icon = player.getOverheadIcon(); - if (icon == null) { - final String text = "Protect from MAGIC: " + (plugin.nextprayerendticks - plugin.ticks); - final int textWidth = graphics.getFontMetrics().stringWidth(text); - final int textHeight = graphics.getFontMetrics().getAscent() - graphics.getFontMetrics().getDescent(); - final int width = (int) client.getRealDimensions().getWidth(); - java.awt.Point jpoint = new java.awt.Point((width / 2) - textWidth, textHeight + 75); - panelComponent.getChildren().clear(); - panelComponent.getChildren().add(TitleComponent.builder().text(text).color(Color.GREEN).build()); - panelComponent.setPreferredLocation(jpoint); - panelComponent.render(graphics); - } - } - } - return null; - } -} 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 deleted file mode 100644 index 10c9f89e74..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java +++ /dev/null @@ -1,640 +0,0 @@ -package net.runelite.client.plugins.zulrah; - -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import javax.inject.Inject; -import java.awt.*; -import java.awt.image.*; -import java.util.*; -import java.util.List; - -import net.runelite.api.*; - -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.ImageUtil; - -@PluginDescriptor( - name = "!Zulrah", - description = "Zulrah Helper", - tags = {"Zulrah", "Helper"} -) -public class ZulrahPlugin extends Plugin -{ - @Inject - private OverlayManager overlayManager; - - @Inject - private ZulrahConfig config; - - @Inject - private ZulrahOverlay ZulrahOverlay; - - @Inject - private ZulrahTileOverlay ZulrahTileOverlay; - - @Inject - private Client client; - - @Inject - private SpriteManager spriteManager; - - @Provides - ZulrahConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(ZulrahConfig.class); - } - - private static final int[] PROTECTION_ICONS = { - SpriteID.PRAYER_PROTECT_FROM_MISSILES, - SpriteID.PRAYER_PROTECT_FROM_MELEE, - SpriteID.PRAYER_PROTECT_FROM_MAGIC - }; - - private static final Dimension PROTECTION_ICON_DIMENSION = new Dimension(33, 33); - private static final Color PROTECTION_ICON_OUTLINE_COLOR = new Color(33, 33, 33); - public final BufferedImage[] ProtectionIcons = new BufferedImage[PROTECTION_ICONS.length]; - int zulrahstart = 0; - NPC Zulrah; - - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) - { - if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { - loadProtectionIcons(); - } - } - - @Override - protected void startUp() throws Exception { - overlayManager.add(ZulrahOverlay); - overlayManager.add(ZulrahTileOverlay); - } - - @Override - protected void shutDown() throws Exception { - overlayManager.remove(ZulrahOverlay); - overlayManager.remove(ZulrahTileOverlay); - } - - LocalPoint ZulrahPosCenter = new LocalPoint(6720, 7616); - LocalPoint ZulrahPosWest = new LocalPoint(8000, 7360); - LocalPoint ZulrahPosEast = new LocalPoint(5440, 7360); - LocalPoint ZulrahPosNorth = new LocalPoint(6720, 6208); - - LocalPoint SWCornerTile = new LocalPoint(7488, 7872); - LocalPoint SWCornerTileMelee = new LocalPoint(7232, 8000); - LocalPoint WPillar = new LocalPoint(7232, 7232); - LocalPoint WPillarN = new LocalPoint(7232, 7104); - LocalPoint EPillar = new LocalPoint(6208, 7232); - LocalPoint EPillarN = new LocalPoint(6208, 7104); - LocalPoint SECornerTile = new LocalPoint(6208, 8000); - LocalPoint SECornerTileMelee = new LocalPoint(5952, 7744); - LocalPoint Middle = new LocalPoint(6720, 6848); - - int ticks; - int phaseticks; - int not; - int lastphase; - int phase; - int nextprayerendticks; - boolean phase1 = true; - boolean phase2 = true; - boolean phase3 = true; - boolean phase4 = true; - boolean restart = false; - boolean prayerconserve = false; - Color nztcolor; - LocalPoint nextzulrahtile; - LocalPoint nexttile; - LocalPoint currenttile; - LocalPoint lastloc; - LocalPoint MeleeTile; - List phases = new ArrayList<>(); - List locations = new ArrayList<>(); - - ArrayList Phase1types = new ArrayList<>(Arrays.asList(2042, 2043, 2044, 2042, 2044, 2043, 2042, 2044, 2042, 2043)); - ArrayList Phase1pos = new ArrayList<>(Arrays.asList(ZulrahPosCenter, ZulrahPosCenter, ZulrahPosCenter, ZulrahPosEast, ZulrahPosNorth, ZulrahPosCenter, ZulrahPosWest, ZulrahPosNorth, ZulrahPosEast, ZulrahPosCenter)); - ArrayList Phase1tiles = new ArrayList<>(Arrays.asList(SWCornerTile, SWCornerTile, SWCornerTile, EPillar, EPillarN, EPillar, Middle, EPillar, EPillar, SWCornerTile)); - ArrayList Phase1ticks = new ArrayList<>(Arrays.asList(28, 20, 18, 28, 39, 22, 20, 36, 48, 20)); - - ArrayList Phase2types = new ArrayList<>(Arrays.asList(2042, 2043, 2044, 2042, 2043, 2044, 2042, 2044, 2042, 2043)); - ArrayList Phase2pos = new ArrayList<>(Arrays.asList(ZulrahPosCenter, ZulrahPosCenter, ZulrahPosCenter, ZulrahPosNorth, ZulrahPosCenter, ZulrahPosEast, ZulrahPosNorth, ZulrahPosNorth, ZulrahPosEast, ZulrahPosCenter)); - ArrayList Phase2tiles = new ArrayList<>(Arrays.asList(SWCornerTile, SWCornerTile, SWCornerTile, EPillar, EPillar, EPillar, WPillar, WPillarN, EPillar, SWCornerTile)); - ArrayList Phase2ticks = new ArrayList<>(Arrays.asList(28, 20, 17, 39, 22, 20, 28, 36, 48, 21)); - - ArrayList Phase3types = new ArrayList<>(Arrays.asList(2042, 2042, 2043, 2044, 2042, 2044, 2042, 2042, 2044, 2042, 2044)); - ArrayList Phase3pos = new ArrayList<>(Arrays.asList(ZulrahPosCenter, ZulrahPosWest, ZulrahPosCenter, ZulrahPosEast, ZulrahPosNorth, ZulrahPosWest, ZulrahPosCenter, ZulrahPosEast, ZulrahPosCenter, ZulrahPosWest, ZulrahPosCenter)); - ArrayList Phase3tiles = new ArrayList<>(Arrays.asList(SWCornerTile, SWCornerTile, SECornerTile, EPillar, WPillar, WPillar, EPillar, EPillar, WPillar, WPillar, SWCornerTile)); - ArrayList Phase3ticks = new ArrayList<>(Arrays.asList(28, 30, 40, 20, 20, 20, 25, 20, 36, 35, 18)); - - ArrayList Phase4types = new ArrayList<>(Arrays.asList(2042, 2044, 2042, 2044, 2043, 2042, 2042, 2044, 2042, 2044, 2042, 2044)); - ArrayList Phase4pos = new ArrayList<>(Arrays.asList(ZulrahPosCenter, ZulrahPosWest, ZulrahPosNorth, ZulrahPosEast, ZulrahPosCenter, ZulrahPosWest, ZulrahPosNorth, ZulrahPosEast, ZulrahPosCenter, ZulrahPosCenter, ZulrahPosWest, ZulrahPosCenter)); - ArrayList Phase4tiles = new ArrayList<>(Arrays.asList(SWCornerTile, SWCornerTile, EPillar, EPillar, WPillar, WPillar, WPillar, EPillar, WPillar, WPillar, WPillar, SWCornerTile)); - ArrayList Phase4ticks = new ArrayList<>(Arrays.asList(28, 36, 24, 30, 28, 17, 34, 33, 20, 27, 29, 18)); - - @Subscribe - public void onGameTick(GameTick event) { - if (!config.EnableZulrah()) { - return; - } - - boolean foundzulrah = false; - for (NPC monster : client.getNpcs()) - { - if (monster == null || monster.getName() == null) - { - continue; - } - if (monster.getName().equalsIgnoreCase("zulrah")) { - foundzulrah = true; - Zulrah = monster; - break; - } - } - if (!foundzulrah) { - Zulrah = null; - } - - if (Zulrah != null) { - if (zulrahstart == 0) { - currenttile = SWCornerTile; - lastloc = Zulrah.getLocalLocation(); - lastphase = Zulrah.getId(); - zulrahstart = client.getTickCount(); - phases.add(lastphase); - locations.add(lastloc); - phaseticks = 28; - } else { - if (!Zulrah.getLocalLocation().equals(lastloc) || Zulrah.getId() != lastphase) { - if (restart) { - phases.clear(); - locations.clear(); - zulrahstart = client.getTickCount(); - lastphase = 0; - lastloc = null; - phase = 0; - phase1 = true; - phase2 = true; - phase3 = true; - phase4 = true; - nextzulrahtile = null; - nztcolor = null; - nexttile = null; - currenttile = SWCornerTile; - restart = false; - ticks = 0; - prayerconserve = false; - phaseticks = 34; - not = 0; - nextprayerendticks = 0; - } - lastloc = Zulrah.getLocalLocation(); - lastphase = Zulrah.getId(); - ticks = 0; - phases.add(lastphase); - locations.add(lastloc); - if (phase == 0) { - for (int i = 0; i < phases.size(); i++) { - if (phase1) { - if (!phases.get(i).equals(Phase1types.get(i)) || !locations.get(i).equals(Phase1pos.get(i))) { - phase1 = false; - not++; - } - } - if (phase2) { - if (!phases.get(i).equals(Phase2types.get(i)) || !locations.get(i).equals(Phase2pos.get(i))) { - phase2 = false; - not++; - } - } - if (phase3) { - if (!phases.get(i).equals(Phase3types.get(i)) || !locations.get(i).equals(Phase3pos.get(i))) { - phase3 = false; - not++; - } - } - if (phase4) { - if (!phases.get(i).equals(Phase4types.get(i)) || !locations.get(i).equals(Phase4pos.get(i))) { - phase4 = false; - not++; - } - } - } - - if (not == 2) { - if (lastphase == 2043) { - nztcolor = Color.BLUE; - nextzulrahtile = ZulrahPosCenter; - currenttile = SWCornerTile; - nexttile = SWCornerTile; - phaseticks = Phase2ticks.get(phases.size() - 1); - prayerconserve = true; - } else if (lastphase == 2044) { - nztcolor = Color.GREEN; - nextzulrahtile = ZulrahPosNorth; - currenttile = SWCornerTile; - nexttile = EPillar; - phaseticks = Phase2ticks.get(phases.size() - 1); - prayerconserve = false; - } - } else if (not == 3) { - if (phase1) { - nztcolor = zulrahtype(Phase1types.get(phases.size())); - nextzulrahtile = Phase1pos.get(phases.size()); - currenttile = Phase1tiles.get(phases.size() - 1); - nexttile = Phase1tiles.get(phases.size()); - phaseticks = Phase1ticks.get(phases.size() - 1); - prayerconserve = true; - phase = 1; - } else if (phase2) { - nztcolor = zulrahtype(Phase2types.get(phases.size())); - nextzulrahtile = Phase2pos.get(phases.size()); - currenttile = Phase2tiles.get(phases.size() - 1); - nexttile = Phase2tiles.get(phases.size()); - phaseticks = Phase2ticks.get(phases.size() - 1); - prayerconserve = false; - phase = 2; - } else if (phase3) { - nztcolor = zulrahtype(Phase3types.get(phases.size())); - nextzulrahtile = Phase3pos.get(phases.size()); - currenttile = Phase3tiles.get(phases.size() - 1); - nexttile = Phase3tiles.get(phases.size()); - phaseticks = Phase3ticks.get(phases.size() - 1); - prayerconserve = false; - phase = 3; - } else if (phase4) { - nztcolor = zulrahtype(Phase4types.get(phases.size())); - nextzulrahtile = Phase4pos.get(phases.size()); - currenttile = Phase4tiles.get(phases.size() - 1); - nexttile = Phase4tiles.get(phases.size()); - phaseticks = Phase4ticks.get(phases.size() - 1); - prayerconserve = true; - phase = 4; - } else { - System.out.println("ERROR: COULD NOT IDENTIFY ZULRAH PHASE!"); - } - not = 0; - } - } else { - if (phase == 1) { - if (Phase1types.size() == phases.size()) { - nztcolor = null; - nextzulrahtile = null; - nexttile = null; - restart = true; - } else { - nextzulrahtile = Phase1pos.get(phases.size()); - nexttile = Phase1tiles.get(phases.size()); - if (phases.size() == 8) { - nztcolor = Color.YELLOW; - } else { - nztcolor = zulrahtype(Phase1types.get(phases.size())); - } - } - currenttile = Phase1tiles.get(phases.size() - 1); - phaseticks = Phase1ticks.get(phases.size() - 1); - } else if (phase == 2) { - if (Phase2types.size() == phases.size()) { - nztcolor = null; - nextzulrahtile = null; - nexttile = null; - restart = true; - } else { - nextzulrahtile = Phase2pos.get(phases.size()); - nexttile = Phase2tiles.get(phases.size()); - if (phases.size() == 8) { - nztcolor = Color.YELLOW; - } else { - nztcolor = zulrahtype(Phase2types.get(phases.size())); - } - } - currenttile = Phase2tiles.get(phases.size() - 1); - phaseticks = Phase2ticks.get(phases.size() - 1); - } else if (phase == 3) { - if (Phase3types.size() == phases.size()) { - nztcolor = null; - nextzulrahtile = null; - nexttile = null; - restart = true; - } else { - nextzulrahtile = Phase3pos.get(phases.size()); - nexttile = Phase3tiles.get(phases.size()); - if (phases.size() == 9) { - nztcolor = Color.YELLOW; - } else { - nztcolor = zulrahtype(Phase3types.get(phases.size())); - } - } - currenttile = Phase3tiles.get(phases.size() - 1); - phaseticks = Phase3ticks.get(phases.size() - 1); - } else if (phase == 4) { - if (Phase4types.size() == phases.size()) { - nztcolor = null; - nextzulrahtile = null; - nexttile = null; - restart = true; - } else { - nextzulrahtile = Phase4pos.get(phases.size()); - nexttile = Phase4tiles.get(phases.size()); - if (phases.size() == 10) { - nztcolor = Color.YELLOW; - } else { - nztcolor = zulrahtype(Phase4types.get(phases.size())); - } - } - currenttile = Phase4tiles.get(phases.size() - 1); - phaseticks = Phase4ticks.get(phases.size() - 1); - } else { - System.out.println("ERROR: COULD NOT IDENTIFY ZULRAH PHASE!"); - } - } - } else { - ticks++; - if (phases.size() == 1 && phaseticks == 34) { - if (ticks >= 18) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } - if (not == 2) { - if (lastphase == 2043) { - if (ticks >= 12 && ticks <= 13) { - MeleeTile = SWCornerTileMelee; - } else { - MeleeTile = null; - } - } - } else if (phase == 1) { - if (phases.size() == 5) { - if (ticks >= 19) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 8) { - if (ticks >= 19) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 9) { - if (ticks >= 34) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 10) { - if (ticks >= 12 && ticks <= 13) { - MeleeTile = SWCornerTileMelee; - } else { - MeleeTile = null; - } - } else if (phases.size() == 4 || phases.size() == 6 || phases.size() == 10) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phase == 2) { - if (phases.size() == 4) { - if (ticks >= 20) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 8) { - if (ticks >= 18) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 9) { - if (ticks >= 34) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 5 || phases.size() == 7 || phases.size() == 10) { - if (phases.size() == 10) { - if (ticks >= 12 && ticks <= 13) { - MeleeTile = SWCornerTileMelee; - } else { - MeleeTile = null; - } - } - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phase == 3) { - if (phases.size() == 2) { - if (ticks >= 20) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 3) { - prayerconserve = true; - if (ticks >= 24 && ticks <= 25) { - MeleeTile = SECornerTileMelee; - } else if (ticks >= 32 && ticks <= 33) { - MeleeTile = SECornerTile; - } else { - MeleeTile = null; - } - } else if (phases.size() == 7 || phases.size() == 11) { - prayerconserve = true; - } else if (phases.size() == 9) { - if (ticks >= 16) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else { - prayerconserve = false; - } - } else if (phase == 4) { - if (phases.size() == 2) { - if (ticks >= 10 && ticks <= 16) { - nextprayerendticks = 16; - } else { - nextprayerendticks = 0; - } - - if (ticks >= 16) { - prayerconserve = false; - } else { - prayerconserve = true; - } - } else if (phases.size() == 3) { - if (ticks >= 16) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 4) { - if (ticks >= 10 && ticks <= 16) { - nextprayerendticks = 16; - } else { - nextprayerendticks = 0; - } - - if (ticks <= 16) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 5 || phases.size() == 7 || phases.size() == 12) { - prayerconserve = true; - } else if (phases.size() == 8) { - if (ticks >= 18) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else if (phases.size() == 10) { - if (ticks >= 14) { - prayerconserve = true; - } else { - prayerconserve = false; - } - } else { - prayerconserve = false; - } - } - } - } - } else { - if (zulrahstart > 0) { - phases.clear(); - locations.clear(); - zulrahstart = 0; - lastphase= 0; - lastloc = null; - phase = 0; - phase1 = true; - phase2 = true; - phase3 = true; - phase4 = true; - nextzulrahtile = null; - nztcolor = null; - nexttile = null; - currenttile = null; - restart = false; - ticks = 0; - prayerconserve = false; - not = 0; - nextprayerendticks = 0; - } - } - } - - public Color zulrahtype(int type) { - switch(type) { - case 2042: - return Color.GREEN; - case 2043: - return Color.RED; - case 2044: - return Color.BLUE; - } - return null; - } - - private void loadProtectionIcons() { - final IndexedSprite[] protectionIcons = {}; - final IndexedSprite[] newProtectionIcons = Arrays.copyOf(protectionIcons, PROTECTION_ICONS.length); - int curPosition = 0; - - for (int i = 0; i < PROTECTION_ICONS.length; i++, curPosition++) - { - final int resource = PROTECTION_ICONS[i]; - ProtectionIcons[i] = rgbaToIndexedBufferedImage(ProtectionIconFromSprite(spriteManager.getSprite(resource, 0))); - newProtectionIcons[curPosition] = createIndexedSprite(client, ProtectionIcons[i]); - } - } - - private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) { - final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel(); - - final int width = bufferedImage.getWidth(); - final int height = bufferedImage.getHeight(); - final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); - final int[] palette = new int[indexedCM.getMapSize()]; - indexedCM.getRGBs(palette); - - final IndexedSprite newIndexedSprite = client.createIndexedSprite(); - newIndexedSprite.setPixels(pixels); - newIndexedSprite.setPalette(palette); - newIndexedSprite.setWidth(width); - newIndexedSprite.setHeight(height); - newIndexedSprite.setOriginalWidth(width); - newIndexedSprite.setOriginalHeight(height); - newIndexedSprite.setOffsetX(0); - newIndexedSprite.setOffsetY(0); - return newIndexedSprite; - } - - private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) { - final BufferedImage indexedImage = new BufferedImage( - sourceBufferedImage.getWidth(), - sourceBufferedImage.getHeight(), - BufferedImage.TYPE_BYTE_INDEXED); - - final ColorModel cm = indexedImage.getColorModel(); - final IndexColorModel icm = (IndexColorModel) cm; - - final int size = icm.getMapSize(); - final byte[] reds = new byte[size]; - final byte[] greens = new byte[size]; - final byte[] blues = new byte[size]; - icm.getReds(reds); - icm.getGreens(greens); - icm.getBlues(blues); - - final WritableRaster raster = indexedImage.getRaster(); - final int pixel = raster.getSample(0, 0, 0); - final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); - final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); - resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); - return resultIndexedImage; - } - - private static BufferedImage ProtectionIconFromSprite(final BufferedImage freezeSprite) { - final BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, PROTECTION_ICON_DIMENSION.width, PROTECTION_ICON_DIMENSION.height); - return ImageUtil.outlineImage(freezeCanvas, PROTECTION_ICON_OUTLINE_COLOR); - } - - BufferedImage getProtectionIcon() { - int type = 0; - if (phase1) { - type = Phase1types.get(phases.size()); - } else if (phase2) { - type = Phase2types.get(phases.size()); - } else if (phase3) { - type = Phase3types.get(phases.size()); - } else if (phase4) { - type = Phase4types.get(phases.size()); - } else { - System.out.println("ERROR: COULD NOT IDENTIFY ZULRAH PHASE!"); - } - - if (type > 0) { - switch (type) { - case 2042: - return ProtectionIcons[0]; - case 2043: - return ProtectionIcons[1]; - case 2044: - return ProtectionIcons[2]; - } - } - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahTileOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahTileOverlay.java deleted file mode 100644 index 28d14f026b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahTileOverlay.java +++ /dev/null @@ -1,120 +0,0 @@ -package net.runelite.client.plugins.zulrah; - -import java.awt.*; -import java.awt.image.BufferedImage; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.Point; -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 ZulrahTileOverlay extends Overlay -{ - private final ZulrahConfig config; - private final ZulrahPlugin plugin; - - @Inject - private Client client; - - @Inject - private ZulrahTileOverlay(ZulrahConfig config, ZulrahPlugin plugin) - { - this.config = config; - this.plugin = plugin; - setLayer(OverlayLayer.ABOVE_SCENE); - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) - { - - NPC Zulrah = plugin.Zulrah; - if (Zulrah != null) { - OverlayUtil.renderTextLocation(graphics, Zulrah.getCanvasTextLocation(graphics, Integer.toString(plugin.phaseticks - plugin.ticks), Zulrah.getLogicalHeight() + 40), Integer.toString(plugin.phaseticks - plugin.ticks), Color.WHITE); - Player player = client.getLocalPlayer(); - if (plugin.currenttile != null) { - if (plugin.currenttile.equals(plugin.nexttile)) { - final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.currenttile); - if (poly != null) { - Point textLocationtile = Perspective.getCanvasTextLocation(client, graphics, plugin.currenttile, "Current & Next", 50); - OverlayUtil.renderTextLocation(graphics, textLocationtile, "Current & Next", Color.WHITE); - OverlayUtil.renderPolygon(graphics, poly, Color.WHITE); - } - } else { - if (!player.getLocalLocation().equals(plugin.currenttile)) { - final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.currenttile); - if (poly != null) { - Point textLocationtile = Perspective.getCanvasTextLocation(client, graphics, plugin.currenttile, "Current", 50); - OverlayUtil.renderTextLocation(graphics, textLocationtile, "Current", Color.WHITE); - OverlayUtil.renderPolygon(graphics, poly, Color.GREEN); - } - } - if (plugin.nexttile != null) { - final Polygon poly2 = Perspective.getCanvasTilePoly(client, plugin.nexttile); - if (poly2 != null) { - Point textLocationtile = Perspective.getCanvasTextLocation(client, graphics, plugin.nexttile, "Next", 50); - OverlayUtil.renderTextLocation(graphics, textLocationtile, "Next", Color.WHITE); - OverlayUtil.renderPolygon(graphics, poly2, Color.RED); - } - } - } - } - if (plugin.nextzulrahtile != null) { - String style = ""; - if (plugin.nztcolor.equals(Color.RED)) { - style = "MELEE"; - } else if (plugin.nztcolor.equals(Color.BLUE)) { - style = "MAGE"; - } else if (plugin.nztcolor.equals(Color.GREEN)) { - style = "RANGE"; - } else if (plugin.nztcolor.equals(Color.YELLOW)) { - style = "JAD"; - } - - final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.nextzulrahtile); - Point textLocation = Perspective.getCanvasTextLocation(client, graphics, plugin.nextzulrahtile, style, 200); - if (poly != null) - { - BufferedImage clanchatImage = null; - if (style.equals("JAD")) { - if (plugin.phase4 && plugin.phases.size() == 10) { - clanchatImage = plugin.ProtectionIcons[2]; - } else if (plugin.phase3 && plugin.phases.size() == 9) { - clanchatImage = plugin.ProtectionIcons[2]; - } else { - clanchatImage = plugin.ProtectionIcons[0]; - } - } else { - clanchatImage = plugin.getProtectionIcon(); - } - - if (clanchatImage != null) { - Point imageLocation = new Point(textLocation.getX(), textLocation.getY() + 15); - OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); - } - - graphics.setFont(FontManager.getRunescapeBoldFont()); - OverlayUtil.renderTextLocation(graphics, textLocation, style, Color.WHITE); - OverlayUtil.renderPolygon(graphics, poly, plugin.nztcolor); - } - } - if (plugin.MeleeTile != null) { - final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.MeleeTile); - if (poly != null) { - Point textLocationtile = Perspective.getCanvasTextLocation(client, graphics, plugin.MeleeTile, "MOVE HERE NOW!", 50); - graphics.setFont(FontManager.getRunescapeBoldFont()); - OverlayUtil.renderTextLocation(graphics, textLocationtile, "MOVE HERE NOW!", Color.WHITE); - OverlayUtil.renderPolygon(graphics, poly, Color.BLACK); - } - } - } - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/util/Clipboard.java b/runelite-client/src/main/java/net/runelite/client/util/Clipboard.java deleted file mode 100644 index 3474f85543..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/util/Clipboard.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.runelite.client.util; - -import java.awt.Toolkit; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.io.IOException; - -public class Clipboard { - public static String retrieve() - { - Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); - - if (contents == null || ! contents.isDataFlavorSupported(DataFlavor.stringFlavor)) - { - return null; - } - - try - { - return (String) contents.getTransferData(DataFlavor.stringFlavor); - } - catch (UnsupportedFlavorException | IOException ex) - { - return null; - } - } - - public static void store(String contents) - { - final StringSelection selection = new StringSelection(contents); - - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, null); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/util/MiscUtils.java b/runelite-client/src/main/java/net/runelite/client/util/MiscUtils.java deleted file mode 100644 index 039c3cfa2b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/util/MiscUtils.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.runelite.client.util; - -import net.runelite.api.Client; -import net.runelite.api.Player; -import net.runelite.api.WorldType; -import net.runelite.api.coords.WorldPoint; - -import java.awt.*; - -public class MiscUtils -{ - private static int[] abovePointsX = { 2944, 3392, 3392, 2944 }; - private static int[] abovePointsY = { 3523, 3523, 3971, 3971 }; - private static int[] belowPointsX = { 2944, 2944, 3264, 3264 }; - private static int[] belowPointsY = { 9918, 10360, 10360, 9918 }; - - private static Polygon abovePoly = new Polygon(abovePointsX, abovePointsY, abovePointsX.length); - private static Polygon belowPoly = new Polygon(belowPointsX, belowPointsY, belowPointsX.length); - - //test replacement so private for now - private static boolean inWildy(WorldPoint point) - { - if (point == null) - return false; - - return abovePoly.contains(point.getX(), point.getY()) || belowPoly.contains(point.getX(), point.getY()); - } - - public static int getWildernessLevelFrom(Client client, WorldPoint point) - { - if (client == null) - return 0; - - if (point == null) - return 0; - - int x = point.getX(); - - if (point.getPlane() == 0 && (x < 2940 || x > 3391)) - return 0; - - int y = point.getY(); - //v underground //v above ground - int wildernessLevel = clamp(y > 6400 ? ((y - 9920) / 8) + 1 : ((y - 3520) / 8) + 1, 0, 56); - - if (point.getPlane() > 0) - if (y < 9920) - wildernessLevel = 0; - - if (client.getWorldType().stream().anyMatch(worldType -> worldType == WorldType.PVP || worldType == WorldType.PVP_HIGH_RISK)) - { - wildernessLevel += 15; - } - - return Math.max(0, wildernessLevel); - } - - public static int clamp(int val, int min, int max) - { - return Math.max(min, Math.min(max, val)); - } - - public static float clamp(float val, float min, float max) - { - return Math.max(min, Math.min(max, val)); - } - - public static boolean inWilderness(Client client) - { - Player localPlayer = client.getLocalPlayer(); - - if (localPlayer == null) - return false; - - return inWildy(localPlayer.getWorldLocation()); - - //return getWildernessLevelFrom(client, localPlayer.getWorldLocation()) > 0; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/util/QueryRunner.java b/runelite-client/src/main/java/net/runelite/client/util/QueryRunner.java deleted file mode 100644 index 0f34fc5448..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/util/QueryRunner.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017, Tomas Slusny - * 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.util; - -import javax.inject.Inject; -import javax.inject.Singleton; -import net.runelite.api.Client; -import net.runelite.api.Query; - -@Singleton -public class QueryRunner -{ - @Inject - private Client client; - - @SuppressWarnings("unchecked") - public T[] runQuery(Query query) - { - return (T[]) query.result(client); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/util/ScreenCapture.java b/runelite-client/src/main/java/net/runelite/client/util/ScreenCapture.java deleted file mode 100644 index 7f84f6f1ac..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/util/ScreenCapture.java +++ /dev/null @@ -1,206 +0,0 @@ -package net.runelite.client.util; - -import java.awt.Toolkit; -import java.awt.TrayIcon; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.EnumSet; -import java.util.concurrent.ScheduledExecutorService; -import javax.imageio.ImageIO; -import javax.inject.Inject; -import javax.inject.Singleton; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.WorldType; -import net.runelite.client.Notifier; -import static net.runelite.client.RuneLite.SCREENSHOT_DIR; -import net.runelite.client.plugins.screenshot.imgur.ImageUploadRequest; -import net.runelite.client.plugins.screenshot.imgur.ImageUploadResponse; -import net.runelite.http.api.RuneLiteAPI; -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; - -@Slf4j -@Singleton -public class ScreenCapture -{ - private static final String IMGUR_CLIENT_ID = "30d71e5f6860809"; - private static final HttpUrl IMGUR_IMAGE_UPLOAD_URL = HttpUrl.parse("https://api.imgur.com/3/image"); - private static final MediaType JSON = MediaType.parse("application/json"); - private static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); - - @Inject - private ScheduledExecutorService executor; - - @Inject - private Client client; - - @Inject - private Notifier notifier; - - /** - * Saves a screenshot of the client window to the screenshot folder as a PNG, - * sends a notification to the system tray, and uploads it to an image-hosting service. - * - * @param screenshot BufferedImage to capture. - * @param notify Send a notification to the system tray when the image is captured. - * @param subDirectory Subdirectory of the default screenshot directory to save the image in. - */ - public void takeScreenshot(BufferedImage screenshot, boolean notify, String subDirectory) - { - takeScreenshot(screenshot, null, notify, true, subDirectory); - } - - /** - * Saves a screenshot of the client window to the screenshot folder as a PNG, - * and optionally uploads it to an image-hosting service. - * - * @param screenshot BufferedImage to capture. - * @param name Filename to use, without file extension. - * @param notify Send a notification to the system tray when the image is captured. - * @param upload Upload the image to a hosting service. - */ - public void takeScreenshot(BufferedImage screenshot, String name, boolean notify, boolean upload) - { - takeScreenshot(screenshot, name, notify, upload, null); - } - - /** - * Saves a screenshot of the client window to the screenshot folder as a PNG, - * and optionally uploads it to an image-hosting service. - * - * @param screenshot BufferedImage to capture. - * @param name Filename to use, without file extension. - * @param subDirectory Subdirectory of the default screenshot directory to save the image in. - * @param notify Send a notification to the system tray when the image is captured. - * @param upload Upload the image to a hosting service. - */ - public void takeScreenshot(BufferedImage screenshot, String name, boolean notify, boolean upload, String subDirectory) - { - if (client.getGameState() == GameState.LOGIN_SCREEN) - { - // Prevent the screenshot from being captured - log.info("Login screenshot prevented"); - return; - } - - if (name == null) - name = format(new Date()); - - String fileName = name; - File imageDirectory; - if (client.getLocalPlayer() != null && client.getLocalPlayer().getName() != null) - { - final EnumSet worldTypes = client.getWorldType(); - final boolean dmm = worldTypes.contains(WorldType.DEADMAN); - final boolean sdmm = worldTypes.contains(WorldType.SEASONAL_DEADMAN); - final boolean dmmt = worldTypes.contains(WorldType.DEADMAN_TOURNAMENT); - final boolean isDmmWorld = dmm || sdmm || dmmt; - - String playerDir = client.getLocalPlayer().getName(); - if (isDmmWorld) - playerDir += "-Deadman"; - imageDirectory = new File(SCREENSHOT_DIR, playerDir); - } - else - { - imageDirectory = SCREENSHOT_DIR; - } - if (subDirectory != null) - imageDirectory = new File(imageDirectory, subDirectory); - - imageDirectory.mkdirs(); - File writeDirectory = imageDirectory; - - executor.execute(() -> - { - try - { - File screenshotFile = new File(writeDirectory, fileName + ".png"); - - ImageIO.write(screenshot, "PNG", screenshotFile); - - if (upload) - uploadScreenshot(screenshotFile, notify); - else if (notify) - notifier.notify("A screenshot was saved to " + screenshotFile, TrayIcon.MessageType.INFO); - } - catch (IOException ex) - { - log.warn("error writing screenshot", ex); - } - }); - } - - /** - * Uploads a screenshot to the Imgur image-hosting service, - * and copies the image link to the clipboard. - * - * @param screenshotFile Image file to upload. - * @throws IOException Thrown if the file cannot be read. - */ - private void uploadScreenshot(File screenshotFile, boolean notify) throws IOException - { - String json = RuneLiteAPI.GSON.toJson(new ImageUploadRequest(screenshotFile)); - - Request request = new Request.Builder() - .url(IMGUR_IMAGE_UPLOAD_URL) - .addHeader("Authorization", "Client-ID " + IMGUR_CLIENT_ID) - .post(RequestBody.create(JSON, json)) - .build(); - - executor.execute(() -> - RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback() - { - @Override - public void onFailure(Call call, IOException ex) - { - log.warn("error uploading screenshot", ex); - } - - @Override - public void onResponse(Call call, Response response) throws IOException - { - try (InputStream in = response.body().byteStream()) - { - ImageUploadResponse imageUploadResponse = RuneLiteAPI.GSON - .fromJson(new InputStreamReader(in), ImageUploadResponse.class); - - if (imageUploadResponse.isSuccess()) - { - String link = imageUploadResponse.getData().getLink(); - - StringSelection selection = new StringSelection(link); - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.setContents(selection, selection); - if (notify) - notifier.notify("A screenshot was uploaded and inserted into your clipboard!", TrayIcon.MessageType.INFO); - } - } - } - }) - ); - } - - private static String format(Date date) - { - synchronized (TIME_FORMAT) - { - return TIME_FORMAT.format(date); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/util/WildernessLocation.java b/runelite-client/src/main/java/net/runelite/client/util/WildernessLocation.java deleted file mode 100644 index 19e62c64a4..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/util/WildernessLocation.java +++ /dev/null @@ -1,98 +0,0 @@ - -package net.runelite.client.util; - -import net.runelite.api.coords.WorldArea; - -public enum WildernessLocation { - REV_CAVE_OTHER("Rev Cave", new Location(3128, 10232, 3225, 10059), 0), - REV_BLACK_DRAGS("Rev Black Drags", new Location(3223, 10216, 3254, 10190), 0), - REV_DARK_BEAST("Rev Dark Beast", new Location(3243, 10154, 3264, 10136), 0), - REV_MAIN_CHAMBER("Main Rev Chamber", new Location(3227, 10187, 3261, 10157), 0), - REV_ENTRANCE_INSIDE("Inside Rev Ent.", new Location(3238, 10236, 3243, 10231), 0), - ICE_ROCK("Ice Rock", new Location(2957, 3942, 2984, 3929), 0), - WILDY_AGILITY_COURSE("Wildy Agility Course", new Location(2988, 3967, 3008, 3906), 0), - FIRE_GIANT_ENTRANCE("Fire Giant Entrance", new Location(3042, 3929, 3051, 3920), 0), - PIRATE_HUT("Pirate Hut", new Location(3037, 3959, 3045, 3948), 0), - MAGE_BANK("Mage Bank", new Location(3082, 3960, 3103, 3952), 0), - MAGE_ARENA("Mage Arena", new Location(3088, 3949, 3123, 3919), 0), - LEVER("Lever", new Location(3149, 3933, 3162, 3917), 0), - WEB("Web", new Location(3153, 3961, 3163, 3948), 0), - RESOURCE_ARENA("Resource Arena", new Location(3174, 3946, 3195, 3923), 0), - AXE_HUT("Axe Hut", new Location(3187, 3962, 3194, 3957), 0), - SCORPIA("Scorpia", new Location(3216, 3949, 3248, 3935), 0), - ROGUE_CASTLE("Rogue Castle", new Location(3275, 3947, 3299, 3920), 0), - FIFTY_PORTS("50 ports", new Location(3301, 3923, 3315, 3909), 0), - VOLCANO("Volcano", new Location(3345, 3957, 3390, 3916), 0), - NEW_GATE("New Gate", new Location(3345, 3957, 3390, 3916), 0), - GLORY_HOLE("Glory Hole", new Location(3352, 3897, 3386, 3869), 0), - GLORY_HILL("Glory Hill", new Location(3331, 3890, 3348, 3866), 0), - GDZ("Gdz", new Location(3279, 3895, 3296, 3875), 0), - GAP("Gap", new Location(3238, 3855, 3258, 3841), 0), - OLD_GATE("Old Gate", new Location(3211, 3906, 3238, 3882), 0), - LAVA_DRAGS("Lava Drags", new Location(3175, 3857, 3221, 3805), 0), - SPIDER_HILL("Spider Hill", new Location(3156, 3896, 3182, 3871), 0), - RUNE_ROCKS("Rune Rocks", new Location(3055, 3890, 3072, 3876), 0), - ICE_GATE("Ice Gate", new Location(2945, 3913, 2978, 3878), 0), - VENENATIS("Venenatis", new Location(3298, 3759, 3353, 3722), 0), - SINGLE_STRIP("Single Strip", new Location(3333, 3842, 3348, 3774), 0), - CALLISTO("Callisto", new Location(3266, 3863, 3315, 3827), 0), - DWARVES("Dwarves", new Location(3230, 3805, 3264, 3779), 0), - VETTION("Vet'tion", new Location(3183, 3796, 3227, 3765), 0), - EAST_DRAGONS("East Drags", new Location(3326, 3704, 3365, 3671), 0), - HILL_GIANTS("Hill Giants", new Location(3282, 3687, 3300, 3674), 0), - ENTS("Ents", new Location(3300, 3627, 3320, 3584), 0), - CHAOS_TEMPLE("Chaos Temple", new Location(3220, 3632, 3255, 3593), 0), - NINETEEN_OBELISK("19s", new Location(3220, 3672, 3234, 3660), 0), - CORP_CAVE("Corp Cave", new Location(3201, 3684, 3219, 3672), 0), - THIRTEEN_OBELISK("13s", new Location(3145, 3628, 3168, 3609), 0), - SOUTH_REV_ENTRANCE("Lvl 18 Rev Ent", new Location(3071, 3660, 3092, 3645), 0), - GRAVES("Graves", new Location(3128, 3686, 3181, 3658), 0), - GRAVEYARD_DRAGS("Graveyard Drags", new Location(3129, 3717, 3172, 3691), 0), - CHINS("Chins", new Location(3128, 3792, 3160, 3754), 0), - REV_ENTRANCE("Rev Entrance", new Location(3118, 3837, 3142, 3818), 0), - HOB_OBELISK("35 Obelisk", new Location(3097, 3804, 3115, 3785), 0), - HOBGOBLINS("Hobgoblins", new Location(3073, 3775, 3104, 3745), 0), - GWD("God Wars Dungeon", new Location(3010, 3745, 3027, 3727), 0), - LAVA_MAZE_TELE("Lava Maze Tele", new Location(3019, 3842, 3044, 3812), 0), - KBD_CAGE("KBD CAGE", new Location(3007, 3855, 3021, 3839), 0), - GHORROCK("44s", new Location(2973, 3870, 2987, 3859), 0), - CHAOS_FANATIC("Chaos Fanatic", new Location(2971, 3854, 2992, 3834), 0), - HIGH_ALTAR("High Altar", new Location(2945, 3826, 2970, 3813), 0), - CEMETERY("Cemetery", new Location(2956, 3767, 2996, 3736), 0), - CRAZY_ARCHAEOLOGIST("Crazy Archaeologist", new Location(2952, 3709, 2985, 3678), 0), - DARK_WARRIOR_FORTRESS("Dark Warriors", new Location(3014, 3648, 3046, 3616), 0), - WEST_DRAGONS("West Drags", new Location(2960, 3627, 2992, 3598), 0), - BANDIT_CAMP("Bandit Camp", new Location(3017, 3712, 3059, 3681), 0); - - private final String name1; - private final WorldArea worldArea; - - private WildernessLocation(String name, Location location, int plane) { - name1 = name; - worldArea = new WorldArea(location.x, location.y, location.width, location.height, plane); - } - - public String getName() { - return name1; - } - - public WorldArea getWorldArea() { - return worldArea; - } - - public static class Location { - public int x; - public int y; - public int width; - public int height; - - Location(int x, int y, int x1, int y1) { - x = x; - y = y1; - width = x1 - x; - height = y - y1; - } - } - -} - diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/equipmentinspector/normal.png b/runelite-client/src/main/resources/net/runelite/client/plugins/equipmentinspector/normal.png deleted file mode 100644 index 613f95e46d5235a49ec0843faaa35384e9b0896b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 624 zcmV-$0+0QPP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0tHD#K~z{r?Uuhw z!$1_rUmcyLn~P8fmrQ~BGyq5#M;t!sDe|AI9PCT z5L;*0n(yTB<#Ji>Y`9Ti3&7jKIc7LRzA=EB!@v>HuhtrJNg@rXeB>M9M-je0Kgy>A zylh?sDMIn)l}ej(`+H8v(E%7b5cc-@C3nN&w2Fwp-R+IopcXQj3?*h0Vy~0lOgpUz zIPDlH0yrEs;AVPiQm$;Ucia462~d@01* diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/inventorysetups/add_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/inventorysetups/add_icon.png deleted file mode 100644 index 343c3dce0cd5c460af2627b8a4acb39f68cc86fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa&H|6fVg?3oVGw3ym^DWND5&k} z;uxYaF*)G?V@#UG-}0FczsOIw5!T~$N>Is2IU-(UvQbc7qSu|vgo)vBE7!_33zDV) PwJ~_Q`njxgN@xNAsURJG diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/inventorysetups/inventorysetups_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/inventorysetups/inventorysetups_icon.png deleted file mode 100644 index 70e415beec14c745d3b5254ea6c50366ef9235a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 765 zcmV004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv00000008+zyMF)x010qNS#tmY3labT3lag+-G2N400Lo2L_t(Y$Gw(2Xj4%b zfWK2S_#AxHQG{+C9IP!(OSGd)baM~_f*?rApsib-G8WQ7N+dN<36!iwy5vF;LToSw zADBQ%LoV4gwe65Wv~nD7ZpM^1n z8GwXbOT|dNe8qZZ(->wHQLa$p?0%g){tK*UHjQ%OGf^HN8Rpih3IN~F43f>I_48qL zEQEZ&_!xk(=@=lj?R~BT=iP4DzAnX+WTlI)+I|3pY^=`GSe@mtb)Cn`r?K*BK**_y zQ3*mWgoaoM4SCkAe44dXti!(5uV_t2{o*xpg%ZK5`vAQDw9EC;F#wXwD+DI}p7Un1 z8-yO*2f!{@n|5z(ALAp#4F34iOtTN97@LlH+B9@!O zXpL@WF3ja~SGaWk1a`T45RG1o8{TzC7o&*autDCwa|^E*ktWE2B;rxFcmL4XuCcRM zXK^W|4bw=SGm!1A?ndVh^f7=O2~7G)F0atot^rUiZgmWBKQX$!f#%$Fi}0T#s(t(l zxD6l$NZ~evyLW7<`wt>yBEHb$hos-$5kUPN9qq5E!-!o!q-( vm#ckYUGm;dQS}*U+BAUQz-f>tTQ&Xy=bj!>0e93H00000NkvXXu0mjfhjCHs diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/inventorysetups/remove_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/inventorysetups/remove_icon.png deleted file mode 100644 index 3f4915d0419444a5b2307d16643b4a5e36cf62f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 299 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa&H|6fVg?3oVGw3ym^DWND0tV? z#W6%<;@pddUPl51*dFM==Q$)Mz3qk*cfNp9({zDtQ70Daq-+${ey`AW=b+m()o2d6 zgNM?>l0SJo)P8=}oaevD?oBqwW%Fk5`)~5OEVZ&NJxBOmVRKpdv~I~Q4&B-|DmeuQ zSa-?vMTy(8=LB8;?jBNc-0DM7!?eb07lTb}>vfERuN!XdTF#g4uk{=e4e6hER(3JY@|k;E?cvG% uC&Da&s~4rW9&b@wcGc44kZIh;zidH`nZ;AQ*G>R>l)=;0&t;ucLK6UgICIPZ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/profiles/delete_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/profiles/delete_icon.png deleted file mode 100644 index 18b67f23f3454d38f3758f3f42009f5a1fe03214..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mI14-?iy0WWg+Z8+Vb&Z8pkR}y zi(`n!#I+Y4xegf!uwHm1$rYQjwENzFCcRY^?Kw^_ZCjo@DfSu)EZIE!{CxZW=Xnk{ zrk0t8y?F6#(rwm@ApvTF-fT_0nwNcq%o6RzRhF1Xlr8;}zU|uD*fra3CC*fD`Z4$G zm*&4YE8bjNd$v^en6=-9QlIbhwx5yfWuHIW^8Xs~u!i*|FD#yH0lJ34)78&qol`;+ E08pz??f?J) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/profiles/profiles_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/profiles/profiles_icon.png deleted file mode 100644 index a733eaf4a19343c3416d4b12cea60d735d9f7170..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77 zcmZ?wbhEHb6k!l#n8*ME|NsBLFxLl2D*j|)WME)s&;f~pt}h6ALapu&{r|SU75EW^!jfk!|ZJKm+=KZ8z$+r?+#-Fs_ci2g7`l z4X5}=bIDynLUy(^#TFbFvPx>4GlX%KRkf6;sA^i>!AgRt@Pf?C0w>9OTF}!H+j%AP z3G^-NniYMzxVMuIS-E7*_nSJ;w_2@KOHMg%l@~Ql;{}PABo58sym{LPZO-;KMM1i8 ziqJD$tLa;g%?5En*_rcm$z+hI_v);x(d;F%y$(A>k#B=0FQx>3n3HMre42A^J-js2 z;9(s$pzV9ePaNvktU12p)tnJ2d-BM{XirL|UhbjS+h`0;?fH9-BLp3!Lp{Bj`6lG2 zq36uG2HbNTEoIZN)%#YZzd1`H1Vmdi5OqO_1&L;2 zF-neURpy7skmPub*i1YI>K_yMU|CV(b7OH#L$5e)1NeEX0jiL1+SM%IAB@fHRh3?F z>W+&p3+Cl4KWsSW6;_%)X?s4f4LDiMqk)uVnR-R7ND5R%&Xi?^(}eUmSFR{!4yxk- zmZ zRG5}~iDJP95= z5wr(H6qbzkFRSO-akB=ub9o4&_%Zj zV?xI<+N#)XS=fWoD7xuG_nUn0hI61jd#Bi){L)|1os5dbqDe3yWRv0|^TAY#3j;zn zDK0V}Or^LmAY_x`BJ;siiVFimHYqMLA55jVFd$@;;v)0GREi4&LN+NbG9OH(xG*4O zlj0)t!BmP1141?_E;1iXrMNI4WRv0|^TAY#3j;znDK0V}Or^LmAY_x`BJ;siiVFim zHYqMLA55jVFd$@;;v)0GREi4&LN+NbG9OH(xG*4Olj0)t!BmP1141?_E;1iXrMNI4 zWRv0|^TAY#3j;znDK0V}Or^LmAY_x`BJ;siiVFimHi@_r{YN;Vjh@?Vp$9aNZ9itB zhdWtgV!FgI3tJfGT`cp*{LT+9 zzj)&2!mZbTc>L${n?HZ|xm7psP8|7r>(qT;pZ@5=zO6r9SpDgDAKv)YF*h>%UR}As Uefie+!Go%kd-fMU-hE{8Uz>eky#N3J diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/panel_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/panel_icon.png deleted file mode 100644 index 833bbc37c49fad091460fec4ec434189daecdd83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1095 zcmV-N1i1T&P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1KdeOK~zXfwN*=t zTtyWA>T&z_V|pf|%qogOLBSs(S-5xQFrY31#)TRO4UW@FqFa%WRTlA$Om+$`TqQ_A zVL%boKj1<`rgfa@$4uY8&nmyFZhI2CZ}&#O=2Exop8D!Lr_MQr{{vz?mg2^TEgQ!N zNU{|D$YA@@7Yo-cH2C@U`!-NLq!#%7P7j@49p_&DVD36O9?N0-FvZ^xri-HBgQM|> zax5e*Lo0!*Y8BT%`ef$% zQqniK-?G9c&?;sKGAI=w8l*@Qs?UL#LH_jf&t|SK^+hZCEUSFhAoN32b{d6w07f(r zCj#*>9a~PLoKz}=I)LD*Ybl}llI01KBtcqa7!ISc7SQcO|sifQ1*a@Kl>>z}IVyxHKH|8>z zlD1kcn`KOV5;+v6@T2=5@Brtb{Pd|Z2u>CoV|+NIl9M=>VJ2y-#l)9XW`{hO0j(k! z8Ioqh_ zR2Ad#Cr%?u`>dV>gJa;Yb{}c1k)#q?W-u6LxUuui6vx!Wk3U_uCcjJ93)c6LWocOR z3Gz%Ki3?x*X>O6G8S=b=3$J`RpY-;(E&Irsl#}~hl(K&oNKDR@5?+~WBxz#Uu~K@X z5XCjVKa7p_tM~CtVtVt|8#WC0(E0NY>bi-Q+9@nAHSyr`GES{jvC^!dxiorKS87w&zt7ObA*!`U z@!a#*CtP0X&0FtStuj9`BIH4EzXBDe65F4tLW(M@sX`0MlC_MnVMZ`-b&BJoyLkQ8 zrza`qNh_g*X6{K*L2g(*?%rU`Mg*?@71eUil0@p!ccrPA+iGVU^N6O4H=x z2JfMeE>oSKX60~i*GFC6f{$e-xlP@MDo_Y&0c~AQTka9#%9R(rT2K1a*)3trGMjH5 zMh5<;>Z5u*pgu@*67+Qch){Pogn+KVlx^Y zTr+WTcl{+!Bzm0++Is=Ew!WH3xmT0N?(Vx*h+}R*PuzuP9evI&#R6apOn9EXeuSfb zhF%xA@Y>f?98(kb;)mU9HqW{|;hb5(bfWoQyF+yuUOInm?%Mwtz(1Z6y6xxefcpRd N002ovPDHLkV1oIE2VnpJ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/plus_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/plus_icon.png deleted file mode 100644 index 9634216e10404080082e5c9bd5143163c461840d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!pogc6V~B-+vIOgt=Klc~H990&04ej3~ChmDm}2}#i<#Y(m-;pXy?VYF0Y38l*%eJ zfk-5xFnT0i0trtb5|$nTLDYAkFijXtlYmB|3IDlNcL5v%umn~^K&t^T4g|r0RQG|E z004ri(=G-6t3Y6NMz{t-QwymcsKx?d5Cj5-LY7jir_ZR*0VocJH?-UV*Ks?fu{xBn zDK5PLVYIWNiAe96Hn#F($7^co>XDW$H(6u4)@aOmL*Zr8mnhq+p`On&~|RE6+n zOh*i5dMf?4V$@SEI#=&m-dfmYb74zTz@5Gg*%21KK3$nu82y%Ji#Hdw(X&y(Kow-f z7qf8PPo6uqU+dhUldHR()q^hvk7EdA~TFV6rv3AOx_XjtbyQr6Lh9LwdsDUl=g+c&2b zN3&|CKUChl)Vy99*ZBqy+w(rY6?xBN!wV;$iZjqjXROT|i`Ud|4G8HRW|c({c@S>9jt`2B3k$3^H6K1v=K>k*yx3gDOMc~?wv83q%yE*DSXDW; zDPe-Z0f9h%u5GbevM8pIUE!~pqfJ+9>#rgWH&jSTtn>9VlYFzIrI%UyY@rnvl5mW? zFp?(tW-+oj*Lm&_PU%tfOBD#9#v)mkrA4@H#6Pp@>W0M&+Du5Jj5*8*) zqDYE|pSI6DDhhgqa%^660+dwjZapCJu*xfaK}kll7dK90l0-+Scty?`syO7f(zO3u zJujR2-5q!ZePmVYyO1i0`HWfYs2{d0qINjFbA^GTcI>?lvny0rFofUL-gq!2f`ewe?aaPizx9Z@ zz}G+Qj^o}dbLKST=Q-;?xp&wFhzw%KgeyNVV^*ku0g>rqMgw7wM!V=&kupz1?7Bd* S5Y4VzOkG=eR!iMf)!^?)JNLc- diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/quest_complete_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/quest_complete_icon.png deleted file mode 100644 index 31acc0fdb45c8466a3ef96a293d4881074520b34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^{2!lvI6;>1s;*b z3=DjSK$uZf!>a)(C{f}XQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QJXPV+30Wx`~r;B5V zg@5nFvz$zZA}zs<8WkcUM<(BBD7W6geg4r!sWk`Kg1TEPHng5N;Wy*E@P`kAlji2% z%iDG(iuq~OEcLT9&x+XC^UM2(CAsL!#IG(`#_C*H9&d8u_wk|#fhU)%FDtC#xi&rW ze929J*9ojs6n~jFq^I~LGNyE?OcgwH0i8Re_ANcX{A@|hL_VM=7(8A5T-G@y GGywpSEOf^J diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/quest_started_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/quest_started_icon.png deleted file mode 100644 index 0c567b0664b54ecdcabc9b842ccf9096477d4bbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^{2!lvI6;>1s;*b z3=Dh+L6~vJ#O${~L5ULAh?3y^w370~qEv>0#LT=By}Z;C1rt3(J<}BT2$0EZJzX3_ zEc|;f?iOuw5MjA+eZpOd$+IR&RB>n=xsu?$fvwosdIDF3j3x8??Q+eW4dvwt?UTA(PbpK_OTFuv>M)~Dsjt5F7aIG*bvVLbQ{cSbV#s-NC z?-|Y|toxxW5$HkV^AJMsB@He#Q*uU8a u*D}TR@hv>4bHb~`#Dyo#VukSYE}bQFg(v!N{wWA_ID@CFpUXO@geCx}9C9iE diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/waypoint_marker.png b/runelite-client/src/main/resources/net/runelite/client/plugins/worldmap/waypoint_marker.png deleted file mode 100644 index 8e229a7bf7629f4b9f60cc1db3cef39debb4e36b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 958 zcmV;v13~e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00SmTL_t(o!_`@Z#2&7m@n`Z9=_%ZGiKRX(1TQA#9@{7PoW7 z%9U4Ue= za@jYDc5BT=-eep=rw$Oq79bg@C=B5Bb6c}Afl(NgzK$13HGmt+@vQb|f{)w9SId+M zwy}uVQl3}n!Z>P5|H6mnBQJ(q0$~8Nej(@hTR@elOsxQQ*rK23PkLaoAC`PB3InQ8 z1Mu{y*n8Ll0A{WnB$ELE!ppRq0B84lU@BkqxpEveQ5c96ORL=km<|BCjRHUv2KmE* zbsKbFyXo$a*Ea=tfw@kdnXFA25lqI}1Ipg7HNdb304oaQ@l9m3+WL4-Zxx&AYA1WA}4$5aGU9knKCW7lCMiWhP)c*2>_JV!npmY5*0C9q8P_ zmW+KJrOT9l-mR(wL_X&0fZeS`J(X)=bVbOI--KK~6Y_@;a`8f+=!y^_)v&#`-!5LL zoXck_x3srv;Xi+(5w(6OB9Jnm4ieYM=9$2>v}VP=hjWTae21F?{8vp6F?iV zDr+NfwybYUHQR$jS)6wiHejx~kjt~xa4U1TfZKq%q#C(l_#bH`)1?YcI>|OkCtBus zlc?w{a5>6Uj;~j};sC-c8d&ZWDH;D=# z%T&NzBign28!H5V%We8OQ#FxWc|CK;oV+tFO<0-&zW&%vCoB^oF!%aNTV-W`WdJ7E z$z{qIS Date: Fri, 19 Apr 2019 19:44:16 -0400 Subject: [PATCH 07/75] Gazivodag master (#10) * Transform objects now use an interface * Plugins can now accept colors (not my code) * mixins: renderWidgetLayer: skip hidden widgets * World Map: Identify Both Shield of Arrav Quest Start Points (#8442) Closes #8437 * widgetitem: associate Widget with WidgetItem * widgetitem overlay: allow configuring which interfaces to overlay Update overlays to behave consistent with how they behaved before removal of query api, with the exception of adding the rune pouch overlay to the bank. * Update .gitignore * Revert "Adding external plugin support (#4)" This reverts commit bfe1482 * Update QuestStartLocation.java * Revert "Plugins update (#7)" This reverts commit 216f7d9 * Adding external plugin support (#4) * Adding archetype * Update RuneLiteConfig.java * Update Plugin.java * Update PluginManager.java * Adding pluginwatcher & classloader * Update RuneLite.java * Update pom.xml * Update settings.xml * Update pom.xml * Update pom.xml * Removing old example plugin * Fixing the fix of the fix for plugin archetype. (cherry picked from commit bfe14827051d084c4b4e250906b5c28e6b7d321f) * Plugins can now accept colors (not my code) (cherry picked from commit 8e094f738686140104202c6c5aac8b5eb7e47a38) * Update MenuEntrySwapperConfig.java --- .gitignore | 6 +- .../net/runelite/api/widgets/WidgetItem.java | 48 +- .../client/plugins/config/ConfigPanel.java | 54 +- .../client/plugins/config/PluginListItem.java | 26 +- .../inventorytags/InventoryTagsOverlay.java | 2 + .../itemcharges/ItemChargeOverlay.java | 2 + .../MenuEntrySwapperConfig.java | 569 +++++++++--------- .../plugins/runepouch/RunepouchOverlay.java | 2 + .../client/plugins/slayer/SlayerOverlay.java | 2 + .../plugins/worldmap/QuestStartLocation.java | 5 +- .../client/ui/overlay/WidgetItemOverlay.java | 58 +- .../net/runelite/mixins/RSClientMixin.java | 4 +- .../net/runelite/mixins/RSWidgetMixin.java | 2 +- 13 files changed, 415 insertions(+), 365 deletions(-) diff --git a/.gitignore b/.gitignore index a4f1ba7d02..177b1d7858 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,8 @@ project.properties .idea/ .project .settings/ -.classpath \ No newline at end of file +.classpath +runelite-client/src/main/resources/META-INF/MANIFEST.MF +git +classes/artifacts/client_jar/run.bat +classes/artifacts/client_jar/client.jar diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetItem.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetItem.java index 51f63ad40f..c39e961f81 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetItem.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetItem.java @@ -26,6 +26,7 @@ package net.runelite.api.widgets; import java.awt.Rectangle; import lombok.AllArgsConstructor; +import lombok.Getter; import lombok.ToString; import net.runelite.api.Point; @@ -34,55 +35,34 @@ import net.runelite.api.Point; */ @AllArgsConstructor @ToString +@Getter public class WidgetItem { - private final int id; - private final int quantity; - private final int index; - private final Rectangle canvasBounds; - /** - * Gets the ID of the item represented. + * The ID of the item represented. * - * @return the items ID * @see net.runelite.api.ItemID */ - public int getId() - { - return id; - } - + private final int id; /** - * Gets the quantity of the represented item. - * - * @return the items quantity + * The quantity of the represented item. */ - public int getQuantity() - { - return quantity; - } - + private final int quantity; /** - * Gets the index position of this WidgetItem inside its parents + * The index position of this WidgetItem inside its parents * WidgetItem array. * - * @return the index in the parent widget * @see Widget#getWidgetItems() */ - public int getIndex() - { - return index; - } - + private final int index; /** - * Gets the area where the widget is drawn on the canvas. - * - * @return the occupied area of the widget + * The area where the widget is drawn on the canvas. */ - public Rectangle getCanvasBounds() - { - return canvasBounds; - } + private final Rectangle canvasBounds; + /** + * The widget which contains this item. + */ + private final Widget widget; /** * Gets the upper-left coordinate of where the widget is being drawn 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 b71d5e8b0e..6f5712f4a8 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 @@ -130,7 +130,7 @@ public class ConfigPanel extends PluginPanel } ConfigPanel(PluginManager pluginManager, ConfigManager configManager, ScheduledExecutorService executorService, - RuneLiteConfig runeLiteConfig, ChatColorConfig chatColorConfig) + RuneLiteConfig runeLiteConfig, ChatColorConfig chatColorConfig) { super(false); this.pluginManager = pluginManager; @@ -195,28 +195,28 @@ public class ConfigPanel extends PluginPanel // populate pluginList with all non-hidden plugins pluginManager.getPlugins().stream() - .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden()) - .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); + .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden()) + .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); - listItem.setPinned(pinnedPlugins.contains(listItem.getName())); - pluginList.add(listItem); - }); + final PluginListItem listItem = new PluginListItem(this, plugin, descriptor, config, configDescriptor); + listItem.setPinned(pinnedPlugins.contains(listItem.getName())); + pluginList.add(listItem); + }); // add special entries for core client configurations final PluginListItem runeLite = new PluginListItem(this, runeLiteConfig, - configManager.getConfigDescriptor(runeLiteConfig), - RUNELITE_PLUGIN, "RuneLite client settings", "client"); + 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, - configManager.getConfigDescriptor(chatColorConfig), - CHAT_COLOR_PLUGIN, "Recolor chat text", "colour", "messages"); + configManager.getConfigDescriptor(chatColorConfig), + CHAT_COLOR_PLUGIN, "Recolor chat text", "colour", "messages"); chatColor.setPinned(pinnedPlugins.contains(CHAT_COLOR_PLUGIN)); pluginList.add(chatColor); @@ -421,7 +421,7 @@ public class ConfigPanel extends PluginPanel public void mouseClicked(MouseEvent e) { RuneliteColorPicker colorPicker = new RuneliteColorPicker(SwingUtilities.windowForComponent(ConfigPanel.this), - colorPickerBtn.getBackground(), cid.getItem().name(), cid.getAlpha() == null); + colorPickerBtn.getBackground(), cid.getItem().name(), cid.getAlpha() == null); colorPicker.setLocation(getLocationOnScreen()); colorPicker.setOnColorChange(c -> { @@ -467,7 +467,7 @@ public class ConfigPanel extends PluginPanel heightSpinnerTextField.setColumns(4); ChangeListener listener = e -> - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); widthSpinner.addChangeListener(listener); heightSpinner.addChangeListener(listener); @@ -512,8 +512,8 @@ public class ConfigPanel extends PluginPanel if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class) { Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), - (Class) cid.getType()); + cid.getItem().keyName(), + (Class) cid.getType()); HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class); @@ -536,8 +536,8 @@ public class ConfigPanel extends PluginPanel resetButton.addActionListener((e) -> { final int result = JOptionPane.showOptionDialog(resetButton, "Are you sure you want to reset this plugin's configuration?", - "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, - null, new String[]{"Yes", "No"}, "No"); + "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, new String[]{"Yes", "No"}, "No"); if (result == JOptionPane.YES_OPTION) { @@ -564,8 +564,8 @@ public class ConfigPanel extends PluginPanel if (!Strings.isNullOrEmpty(configItem.warning())) { final int result = JOptionPane.showOptionDialog(component, configItem.warning(), - "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, - null, new String[]{"Yes", "No"}, "No"); + "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, new String[]{"Yes", "No"}, "No"); if (result != JOptionPane.YES_OPTION) { @@ -659,9 +659,9 @@ public class ConfigPanel extends PluginPanel void savePinnedPlugins() { final String value = pluginList.stream() - .filter(PluginListItem::isPinned) - .map(PluginListItem::getName) - .collect(Collectors.joining(",")); + .filter(PluginListItem::isPinned) + .map(PluginListItem::getName) + .collect(Collectors.joining(",")); configManager.setConfiguration(RUNELITE_GROUP_NAME, PINNED_PLUGINS_CONFIG_KEY, value); } @@ -704,4 +704,4 @@ public class ConfigPanel extends PluginPanel } } -} \ No newline at end of file +} 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 64b97a6ab8..c6a23544c7 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 @@ -99,17 +99,17 @@ class PluginListItem extends JPanel ON_STAR = new ImageIcon(onStar); CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(configIcon, -100)); BufferedImage offSwitcherImage = ImageUtil.flipImage( - ImageUtil.grayscaleOffset( - ImageUtil.grayscaleImage(onSwitcher), - 0.61f - ), - true, - false + ImageUtil.grayscaleOffset( + ImageUtil.grayscaleImage(onSwitcher), + 0.61f + ), + true, + false ); OFF_SWITCHER = new ImageIcon(offSwitcherImage); BufferedImage offStar = ImageUtil.grayscaleOffset( - ImageUtil.grayscaleImage(onStar), - 0.77f + ImageUtil.grayscaleImage(onStar), + 0.77f ); OFF_STAR = new ImageIcon(offStar); } @@ -121,23 +121,23 @@ class PluginListItem extends JPanel * if there is no configuration associated with the plugin. */ PluginListItem(ConfigPanel configPanel, Plugin plugin, PluginDescriptor descriptor, - @Nullable Config config, @Nullable ConfigDescriptor configDescriptor) + @Nullable Config config, @Nullable ConfigDescriptor configDescriptor) { this(configPanel, plugin, config, configDescriptor, - descriptor.name(), descriptor.description(), descriptor.tags()); + descriptor.name(), descriptor.description(), descriptor.tags()); } /** * Creates a new {@code PluginListItem} for a core configuration. */ PluginListItem(ConfigPanel configPanel, Config config, ConfigDescriptor configDescriptor, - String name, String description, String... tags) + String name, String description, String... tags) { this(configPanel, null, config, configDescriptor, name, description, tags); } private PluginListItem(ConfigPanel configPanel, @Nullable Plugin plugin, @Nullable Config config, - @Nullable ConfigDescriptor configDescriptor, String name, String description, String... tags) + @Nullable ConfigDescriptor configDescriptor, String name, String description, String... tags) { this.configPanel = configPanel; this.plugin = plugin; @@ -260,7 +260,7 @@ class PluginListItem extends JPanel for (String term : searchTerms) { if (keywords.stream().noneMatch((t) -> t.contains(term) || - DISTANCE.apply(t, term) > 0.9)) + DISTANCE.apply(t, term) > 0.9)) { return false; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java index 99798156ad..14fe723a71 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java @@ -43,6 +43,8 @@ public class InventoryTagsOverlay extends WidgetItemOverlay { this.itemManager = itemManager; this.plugin = plugin; + showOnEquipment(); + showOnInventory(); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java index a37570aa22..5082ab2ccd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java @@ -51,6 +51,8 @@ class ItemChargeOverlay extends WidgetItemOverlay { this.itemChargePlugin = itemChargePlugin; this.config = config; + showOnInventory(); + showOnEquipment(); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index 23ab63df16..36185d8aed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -1,284 +1,285 @@ -/* - * Copyright (c) 2018, Adam - * 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.menuentryswapper; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("menuentryswapper") -public interface MenuEntrySwapperConfig extends Config -{ - @ConfigItem( - position = -2, - keyName = "shiftClickCustomization", - name = "Customizable shift-click", - description = "Allows customization of shift-clicks on items" - ) - default boolean shiftClickCustomization() - { - return true; - } - - @ConfigItem( - keyName = "swapAdmire", - name = "Admire", - description = "Swap Admire with Teleport, Spellbook and Perks (max cape) for mounted skill capes." - ) - default boolean swapAdmire() - { - return true; - } - - @ConfigItem( - keyName = "swapAssignment", - name = "Assignment", - description = "Swap Talk-to with Assignment for Slayer Masters. This will take priority over swapping Trade." - ) - default boolean swapAssignment() - { - return true; - } - - @ConfigItem( - keyName = "swapBanker", - name = "Bank", - description = "Swap Talk-to with Bank on Bank NPC
Example: Banker" - ) - default boolean swapBank() - { - return true; - } - - @ConfigItem( - keyName = "swapBirdhouseEmpty", - name = "Birdhouse", - description = "Swap Interact with Empty for birdhouses on Fossil Island" - ) - default boolean swapBirdhouseEmpty() - { - return true; - } - - @ConfigItem( - keyName = "swapBones", - name = "Bury", - description = "Swap Bury with Use on Bones" - ) - default boolean swapBones() - { - return false; - } - - @ConfigItem( - keyName = "swapContract", - name = "Contract", - description = "Swap Talk-to with Contract on Guildmaster Jane" - ) - default boolean swapContract() - { - return true; - } - - @ConfigItem( - keyName = "swapChase", - name = "Chase", - description = "Allows to left click your cat to chase" - ) - default boolean swapChase() - { - return true; - } - - @ConfigItem( - keyName = "claimSlime", - name = "Claim Slime", - description = "Swap Talk-to with Claim Slime from Morytania diaries" - ) - default boolean claimSlime() - { - return true; - } - - @ConfigItem( - keyName = "swapDarkMage", - name = "Repairs", - description = "Swap Talk-to with Repairs for Dark Mage" - ) - default boolean swapDarkMage() - { - return true; - } - - @ConfigItem( - keyName = "swapDecant", - name = "Decant", - description = "Swap Talk-to with Decant for Bob Barter and Murky Matt at the Grand Exchange." - ) - default boolean swapDecant() - { - return false; - } - - @ConfigItem( - keyName = "swapExchange", - name = "Exchange", - description = "Swap Talk-to with Exchange on NPC
Example: Grand Exchange Clerk, Tool Leprechaun, Void Knight" - ) - default boolean swapExchange() - { - return true; - } - - @ConfigItem( - keyName = "swapFairyRing", - name = "Fairy ring", - description = "Swap Zanaris with Last-destination or Configure on Fairy rings" - ) - default FairyRingMode swapFairyRing() - { - return FairyRingMode.LAST_DESTINATION; - } - - @ConfigItem( - keyName = "swapHarpoon", - name = "Harpoon", - description = "Swap Cage, Big Net with Harpoon on Fishing spot" - ) - default boolean swapHarpoon() - { - return false; - } - - @ConfigItem( - keyName = "swapHomePortal", - name = "Home", - description = "Swap Enter with Home or Build or Friend's house on Portal" - ) - default HouseMode swapHomePortal() - { - return HouseMode.HOME; - } - - @ConfigItem( - keyName = "swapPickpocket", - name = "Pickpocket on H.A.M.", - description = "Swap Talk-to with Pickpocket on H.A.M members" - ) - default boolean swapPickpocket() - { - return true; - } - - @ConfigItem( - keyName = "swapPay", - name = "Pay", - description = "Swap Talk-to with Pay on NPC
Example: Elstan, Heskel, Fayeth" - ) - default boolean swapPay() - { - return true; - } - - @ConfigItem( - keyName = "swapPrivate", - name = "Private", - description = "Swap Shared with Private on the Chambers of Xeric storage units." - ) - default boolean swapPrivate() - { - return false; - } - - @ConfigItem( - keyName = "swapPick", - name = "Pick", - description = "Swap Pick with Pick-lots of the Gourd tree in the Chambers of Xeric" - ) - default boolean swapPick() - { - return false; - } - - @ConfigItem( - keyName = "swapQuick", - name = "Quick Pass/Open/Start/Travel", - description = "Swap Pass with Quick-Pass, Open with Quick-Open, Ring with Quick-Start and Talk-to with Quick-Travel" - ) - default boolean swapQuick() - { - return true; - } - - @ConfigItem( - keyName = "swapBoxTrap", - name = "Reset", - description = "Swap Check with Reset on box trap" - ) - default boolean swapBoxTrap() - { - return true; - } - - @ConfigItem( - keyName = "swapTeleportItem", - name = "Teleport item", - description = "Swap Wear, Wield with Rub, Teleport on teleport item
Example: Amulet of glory, Explorer's ring, Chronicle" - ) - default boolean swapTeleportItem() - { - return false; - } - - @ConfigItem( - keyName = "swapAbyssTeleport", - name = "Teleport to Abyss", - description = "Swap Talk-to with Teleport for the Mage of Zamorak" - ) - default boolean swapAbyssTeleport() - { - return true; - } - - @ConfigItem( - keyName = "swapTrade", - name = "Trade", - description = "Swap Talk-to with Trade on NPC
Example: Shop keeper, Shop assistant" - ) - default boolean swapTrade() - { - return true; - } - - @ConfigItem( - keyName = "swapTravel", - name = "Travel", - description = "Swap Talk-to with Travel, Take-boat, Pay-fare, Charter on NPC
Example: Squire, Monk of Entrana, Customs officer, Trader Crewmember" - ) - default boolean swapTravel() - { - return true; - } -} + +/* + * Copyright (c) 2018, Adam + * 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.menuentryswapper; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("menuentryswapper") +public interface MenuEntrySwapperConfig extends Config +{ + @ConfigItem( + position = -2, + keyName = "shiftClickCustomization", + name = "Customizable shift-click", + description = "Allows customization of shift-clicks on items" + ) + default boolean shiftClickCustomization() + { + return true; + } + + @ConfigItem( + keyName = "swapAdmire", + name = "Admire", + description = "Swap Admire with Teleport, Spellbook and Perks (max cape) for mounted skill capes." + ) + default boolean swapAdmire() + { + return true; + } + + @ConfigItem( + keyName = "swapAssignment", + name = "Assignment", + description = "Swap Talk-to with Assignment for Slayer Masters. This will take priority over swapping Trade." + ) + default boolean swapAssignment() + { + return true; + } + + @ConfigItem( + keyName = "swapBanker", + name = "Bank", + description = "Swap Talk-to with Bank on Bank NPC
Example: Banker" + ) + default boolean swapBank() + { + return true; + } + + @ConfigItem( + keyName = "swapBirdhouseEmpty", + name = "Birdhouse", + description = "Swap Interact with Empty for birdhouses on Fossil Island" + ) + default boolean swapBirdhouseEmpty() + { + return true; + } + + @ConfigItem( + keyName = "swapBones", + name = "Bury", + description = "Swap Bury with Use on Bones" + ) + default boolean swapBones() + { + return false; + } + + @ConfigItem( + keyName = "swapContract", + name = "Contract", + description = "Swap Talk-to with Contract on Guildmaster Jane" + ) + default boolean swapContract() + { + return true; + } + + @ConfigItem( + keyName = "swapChase", + name = "Chase", + description = "Allows to left click your cat to chase" + ) + default boolean swapChase() + { + return true; + } + + @ConfigItem( + keyName = "claimSlime", + name = "Claim Slime", + description = "Swap Talk-to with Claim Slime from Morytania diaries" + ) + default boolean claimSlime() + { + return true; + } + + @ConfigItem( + keyName = "swapDarkMage", + name = "Repairs", + description = "Swap Talk-to with Repairs for Dark Mage" + ) + default boolean swapDarkMage() + { + return true; + } + + @ConfigItem( + keyName = "swapDecant", + name = "Decant", + description = "Swap Talk-to with Decant for Bob Barter and Murky Matt at the Grand Exchange." + ) + default boolean swapDecant() + { + return false; + } + + @ConfigItem( + keyName = "swapExchange", + name = "Exchange", + description = "Swap Talk-to with Exchange on NPC
Example: Grand Exchange Clerk, Tool Leprechaun, Void Knight" + ) + default boolean swapExchange() + { + return true; + } + + @ConfigItem( + keyName = "swapFairyRing", + name = "Fairy ring", + description = "Swap Zanaris with Last-destination or Configure on Fairy rings" + ) + default FairyRingMode swapFairyRing() + { + return FairyRingMode.LAST_DESTINATION; + } + + @ConfigItem( + keyName = "swapHarpoon", + name = "Harpoon", + description = "Swap Cage, Big Net with Harpoon on Fishing spot" + ) + default boolean swapHarpoon() + { + return false; + } + + @ConfigItem( + keyName = "swapHomePortal", + name = "Home", + description = "Swap Enter with Home or Build or Friend's house on Portal" + ) + default HouseMode swapHomePortal() + { + return HouseMode.HOME; + } + + @ConfigItem( + keyName = "swapPickpocket", + name = "Pickpocket on H.A.M.", + description = "Swap Talk-to with Pickpocket on H.A.M members" + ) + default boolean swapPickpocket() + { + return true; + } + + @ConfigItem( + keyName = "swapPay", + name = "Pay", + description = "Swap Talk-to with Pay on NPC
Example: Elstan, Heskel, Fayeth" + ) + default boolean swapPay() + { + return true; + } + + @ConfigItem( + keyName = "swapPrivate", + name = "Private", + description = "Swap Shared with Private on the Chambers of Xeric storage units." + ) + default boolean swapPrivate() + { + return false; + } + + @ConfigItem( + keyName = "swapPick", + name = "Pick", + description = "Swap Pick with Pick-lots of the Gourd tree in the Chambers of Xeric" + ) + default boolean swapPick() + { + return false; + } + + @ConfigItem( + keyName = "swapQuick", + name = "Quick Pass/Open/Start/Travel", + description = "Swap Pass with Quick-Pass, Open with Quick-Open, Ring with Quick-Start and Talk-to with Quick-Travel" + ) + default boolean swapQuick() + { + return true; + } + + @ConfigItem( + keyName = "swapBoxTrap", + name = "Reset", + description = "Swap Check with Reset on box trap" + ) + default boolean swapBoxTrap() + { + return true; + } + + @ConfigItem( + keyName = "swapTeleportItem", + name = "Teleport item", + description = "Swap Wear, Wield with Rub, Teleport on teleport item
Example: Amulet of glory, Explorer's ring, Chronicle" + ) + default boolean swapTeleportItem() + { + return false; + } + + @ConfigItem( + keyName = "swapAbyssTeleport", + name = "Teleport to Abyss", + description = "Swap Talk-to with Teleport for the Mage of Zamorak" + ) + default boolean swapAbyssTeleport() + { + return true; + } + + @ConfigItem( + keyName = "swapTrade", + name = "Trade", + description = "Swap Talk-to with Trade on NPC
Example: Shop keeper, Shop assistant" + ) + default boolean swapTrade() + { + return true; + } + + @ConfigItem( + keyName = "swapTravel", + name = "Travel", + description = "Swap Talk-to with Travel, Take-boat, Pay-fare, Charter on NPC
Example: Squire, Monk of Entrana, Customs officer, Trader Crewmember" + ) + default boolean swapTravel() + { + return true; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java index 17486efe0d..a7e2fd86d7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java @@ -69,6 +69,8 @@ public class RunepouchOverlay extends WidgetItemOverlay this.tooltipManager = tooltipManager; this.client = client; this.config = config; + showOnInventory(); + showOnBank(); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java index e8c49b20a0..97a191d608 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java @@ -87,6 +87,8 @@ class SlayerOverlay extends WidgetItemOverlay { this.plugin = plugin; this.config = config; + showOnInventory(); + showOnEquipment(); } @Override 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 c1d9e9fb88..afd2bba6a4 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,7 +46,10 @@ 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("Shield of Arrav", new WorldPoint(3208, 3495, 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/ui/overlay/WidgetItemOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java index 0eaae6e50b..9cf6f39217 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java @@ -26,15 +26,33 @@ package net.runelite.client.ui.overlay; import java.awt.Dimension; import java.awt.Graphics2D; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import lombok.AccessLevel; import lombok.Setter; +import net.runelite.api.widgets.Widget; +import static net.runelite.api.widgets.WidgetID.BANK_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.BANK_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.DEPOSIT_BOX_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.EQUIPMENT_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.EQUIPMENT_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.GUIDE_PRICES_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.SHOP_INVENTORY_GROUP_ID; +import static net.runelite.api.widgets.WidgetInfo.TO_GROUP; import net.runelite.api.widgets.WidgetItem; public abstract class WidgetItemOverlay extends Overlay { @Setter(AccessLevel.PACKAGE) private OverlayManager overlayManager; + /** + * Interfaces to draw overlay over. + */ + private final Set interfaceGroups = new HashSet<>(); protected WidgetItemOverlay() { @@ -49,13 +67,49 @@ public abstract class WidgetItemOverlay extends Overlay public Dimension render(Graphics2D graphics) { final List itemWidgets = overlayManager.getItemWidgets(); - for (WidgetItem widget : itemWidgets) + for (WidgetItem widgetItem : itemWidgets) { - renderItemOverlay(graphics, widget.getId(), widget); + Widget widget = widgetItem.getWidget(); + int interfaceGroup = TO_GROUP(widget.getId()); + + // Don't draw if this widget isn't one of the allowed + if (!interfaceGroups.contains(interfaceGroup)) + { + continue; + } + + renderItemOverlay(graphics, widgetItem.getId(), widgetItem); } return null; } + protected void showOnInventory() + { + showOnInterfaces( + DEPOSIT_BOX_GROUP_ID, + BANK_INVENTORY_GROUP_ID, + SHOP_INVENTORY_GROUP_ID, + GRAND_EXCHANGE_INVENTORY_GROUP_ID, + GUIDE_PRICES_INVENTORY_GROUP_ID, + EQUIPMENT_INVENTORY_GROUP_ID, + INVENTORY_GROUP_ID); + } + + protected void showOnBank() + { + showOnInterfaces(BANK_GROUP_ID); + } + + protected void showOnEquipment() + { + showOnInterfaces(EQUIPMENT_GROUP_ID); + } + + protected void showOnInterfaces(int... ids) + { + Arrays.stream(ids).forEach(interfaceGroups::add); + } + // Don't allow setting position, priority, or layer @Override diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 56b9190ead..7c934a265d 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1335,7 +1335,7 @@ public abstract class RSClientMixin implements RSClient for (Widget rlWidget : widgets) { RSWidget widget = (RSWidget) rlWidget; - if (widget == null || widget.getRSParentId() != parentId) + if (widget == null || widget.getRSParentId() != parentId || widget.isSelfHidden()) { continue; } @@ -1355,7 +1355,7 @@ public abstract class RSClientMixin implements RSClient { if (renderX >= minX && renderX <= maxX && renderY >= minY && renderY <= maxY) { - WidgetItem widgetItem = new WidgetItem(widget.getItemId(), widget.getItemQuantity(), -1, widget.getBounds()); + WidgetItem widgetItem = new WidgetItem(widget.getItemId(), widget.getItemQuantity(), -1, widget.getBounds(), widget); callbacks.drawItem(widget.getItemId(), widgetItem); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java index 4130ce5930..1b4bda7fc6 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java @@ -300,7 +300,7 @@ public abstract class RSWidgetMixin implements RSWidget int itemY = widgetCanvasLocation.getY() + ((ITEM_SLOT_SIZE + yPitch) * row); Rectangle bounds = new Rectangle(itemX - 1, itemY - 1, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE); - return new WidgetItem(itemId - 1, itemQuantity, index, bounds); + return new WidgetItem(itemId - 1, itemQuantity, index, bounds, this); } @Inject From e1b099ab1ce444e4012719bbde2c2531594be160 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 02:00:55 +0100 Subject: [PATCH 08/75] added org.jetbrains.annotations (#11) added org.jetbrains.annotations --- runelite-client/pom.xml | 833 ++++++++++++++++++++-------------------- 1 file changed, 419 insertions(+), 414 deletions(-) diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 386dd29a60..fda33e1eb1 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -1,414 +1,419 @@ - - - - 4.0.0 - - - net.runelite - runelite-parent - 1.5.21-SNAPSHOT - - - client - RuneLite Client - - - 4.1.0 - 2.3.2 - - true - - - - - org.slf4j - slf4j-api - - - ch.qos.logback - logback-classic - - - net.sf.jopt-simple - jopt-simple - 5.0.1 - - - com.google.guava - guava - - - com.google.inject - guice - ${guice.version} - no_aop - - - com.google.code.gson - gson - - - net.runelite.pushingpixels - substance - 8.0.02 - - - net.runelite.pushingpixels - trident - 1.5.00 - runtime - - - org.projectlombok - lombok - provided - - - org.apache.commons - commons-text - 1.2 - - - org.jogamp.jogl - jogl-all - ${jogl.version} - - - org.jogamp.jogl - jogl-all - ${jogl.version} - natives-windows-amd64 - runtime - - - org.jogamp.jogl - jogl-all - ${jogl.version} - natives-windows-i586 - runtime - - - org.jogamp.jogl - jogl-all - ${jogl.version} - natives-linux-amd64 - runtime - - - org.jogamp.jogl - jogl-all - ${jogl.version} - natives-linux-i586 - runtime - - - org.jogamp.gluegen - gluegen-rt - ${jogl.version} - - - org.jogamp.gluegen - gluegen-rt - ${jogl.version} - natives-windows-amd64 - runtime - - - org.jogamp.gluegen - gluegen-rt - ${jogl.version} - natives-windows-i586 - runtime - - - org.jogamp.gluegen - gluegen-rt - ${jogl.version} - natives-linux-amd64 - runtime - - - org.jogamp.gluegen - gluegen-rt - ${jogl.version} - natives-linux-i586 - runtime - - - io.sigpipe - jbsdiff - 1.0 - - - org.tukaani - xz - - - - - - net.java.dev.jna - jna - 4.5.1 - - - net.java.dev.jna - jna-platform - 4.5.1 - - - - net.runelite - runelite-api - ${project.version} - - - net.runelite.rs - runescape-api - ${project.version} - runtime - - - net.runelite - client-patch - ${project.version} - runtime - - - net.runelite - http-api - ${project.version} - - - net.runelite - discord - 1.1 - - - net.runelite - orange-extensions - 1.0 - provided - - - - junit - junit - 4.12 - test - - - org.hamcrest - hamcrest-library - 1.3 - test - - - org.mockito - mockito-all - 1.10.19 - test - - - com.google.inject.extensions - guice-testlib - ${guice.version} - test - - - com.google.inject.extensions - guice-grapher - ${guice.version} - test - - - org.javassist - javassist - 3.24.1-GA - - - org.xeustechnologies - jcl-core - 2.8 - - - - - - - src/main/resources - - logback.xml - - true - - - src/main/resources - - logback.xml - - false - - - - - org.apache.maven.plugins - maven-resources-plugin - 3.0.2 - - - ttf - png - gif - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.0.0 - - - package - - shade - - - true - - true - shaded - - - - - - net.runelite:* - - ** - - - - net.runelite.rs:runescape-api - - ** - - - - net.runelite.pushingpixels:* - - ** - - - - com.google.guava:* - - ** - - - - ch.qos.logback:* - - ** - - - - org.jogamp.jogl:* - - ** - - - - org.jogamp.gluegen:* - - ** - - - - - - net.runelite.client.RuneLite - - - - - - - - - io.github.zlika - reproducible-build-maven-plugin - - - org.apache.maven.plugins - maven-jarsigner-plugin - 1.4 - - - sign - - sign - - - - - ${jarsigner.skip} - ${jarsigner.keystore} - ${jarsigner.alias} - ${jarsigner.storepass} - ${jarsigner.keypass} - - - - net.runelite - script-assembler-plugin - ${project.version} - - - assemble - - assemble - - - src/main/scripts - ${project.build.outputDirectory}/runelite - - - - build-index - - build-index - - - ${project.build.outputDirectory}/runelite - ${project.build.outputDirectory}/runelite/index - - - - - - - + + + + 4.0.0 + + + net.runelite + runelite-parent + 1.5.21-SNAPSHOT + + + client + RuneLite Client + + + 4.1.0 + 2.3.2 + + true + + + + + org.slf4j + slf4j-api + + + ch.qos.logback + logback-classic + + + net.sf.jopt-simple + jopt-simple + 5.0.1 + + + com.google.guava + guava + + + com.google.inject + guice + ${guice.version} + no_aop + + + com.google.code.gson + gson + + + net.runelite.pushingpixels + substance + 8.0.02 + + + net.runelite.pushingpixels + trident + 1.5.00 + runtime + + + org.projectlombok + lombok + provided + + + org.apache.commons + commons-text + 1.2 + + + org.jogamp.jogl + jogl-all + ${jogl.version} + + + org.jogamp.jogl + jogl-all + ${jogl.version} + natives-windows-amd64 + runtime + + + org.jogamp.jogl + jogl-all + ${jogl.version} + natives-windows-i586 + runtime + + + org.jogamp.jogl + jogl-all + ${jogl.version} + natives-linux-amd64 + runtime + + + org.jogamp.jogl + jogl-all + ${jogl.version} + natives-linux-i586 + runtime + + + org.jogamp.gluegen + gluegen-rt + ${jogl.version} + + + org.jogamp.gluegen + gluegen-rt + ${jogl.version} + natives-windows-amd64 + runtime + + + org.jogamp.gluegen + gluegen-rt + ${jogl.version} + natives-windows-i586 + runtime + + + org.jogamp.gluegen + gluegen-rt + ${jogl.version} + natives-linux-amd64 + runtime + + + org.jogamp.gluegen + gluegen-rt + ${jogl.version} + natives-linux-i586 + runtime + + + io.sigpipe + jbsdiff + 1.0 + + + org.tukaani + xz + + + + + + net.java.dev.jna + jna + 4.5.1 + + + net.java.dev.jna + jna-platform + 4.5.1 + + + + net.runelite + runelite-api + ${project.version} + + + net.runelite.rs + runescape-api + ${project.version} + runtime + + + net.runelite + client-patch + ${project.version} + runtime + + + net.runelite + http-api + ${project.version} + + + net.runelite + discord + 1.1 + + + net.runelite + orange-extensions + 1.0 + provided + + + + junit + junit + 4.12 + test + + + org.hamcrest + hamcrest-library + 1.3 + test + + + org.mockito + mockito-all + 1.10.19 + test + + + com.google.inject.extensions + guice-testlib + ${guice.version} + test + + + com.google.inject.extensions + guice-grapher + ${guice.version} + test + + + org.javassist + javassist + 3.24.1-GA + + + org.xeustechnologies + jcl-core + 2.8 + + + org.jetbrains + annotations + 17.0.0 + + + + + + + src/main/resources + + logback.xml + + true + + + src/main/resources + + logback.xml + + false + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + + + ttf + png + gif + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.0.0 + + + package + + shade + + + true + + true + shaded + + + + + + net.runelite:* + + ** + + + + net.runelite.rs:runescape-api + + ** + + + + net.runelite.pushingpixels:* + + ** + + + + com.google.guava:* + + ** + + + + ch.qos.logback:* + + ** + + + + org.jogamp.jogl:* + + ** + + + + org.jogamp.gluegen:* + + ** + + + + + + net.runelite.client.RuneLite + + + + + + + + + io.github.zlika + reproducible-build-maven-plugin + + + org.apache.maven.plugins + maven-jarsigner-plugin + 1.4 + + + sign + + sign + + + + + ${jarsigner.skip} + ${jarsigner.keystore} + ${jarsigner.alias} + ${jarsigner.storepass} + ${jarsigner.keypass} + + + + net.runelite + script-assembler-plugin + ${project.version} + + + assemble + + assemble + + + src/main/scripts + ${project.build.outputDirectory}/runelite + + + + build-index + + build-index + + + ${project.build.outputDirectory}/runelite + ${project.build.outputDirectory}/runelite/index + + + + + + + From 1a0c2eb03ba22422d36316bcabefa4bbbff75f00 Mon Sep 17 00:00:00 2001 From: zeruth Date: Fri, 19 Apr 2019 22:59:29 -0400 Subject: [PATCH 09/75] Plugins Bringup Adds all? non broken widget plugins: AoeWarnings BATools ClanmanMode Equipment Inspector Fight Cave Wave Helper Fight Cave Jad Helper Freeze Timers Grotesque Guardians Hide Prayers Hydra Lizardmen Shaman Menu Modifier Music Modifier Next Hit Notifier PK Vision Plank make helper Pray against player Profiles Pyramid Plunder Screen markers Shayzien Infirmary Shift Walker Slayermusiq Spellbook fixer Supplies tracker Temple Trek Time Tracking Theatre of Blood damage counter Vetion Vorkath Wilderness Locations Zone Indicators ZTOB Zulrah --- .../src/main/java/net/runelite/api/Actor.java | 7 + .../java/net/runelite/api/AnimationID.java | 21 +- .../main/java/net/runelite/api/VarPlayer.java | 3 +- .../main/java/net/runelite/api/Varbits.java | 11 +- .../runelite/api/events/CannonballFired.java | 32 + .../java/net/runelite/api/kit/KitType.java | 5 +- .../net/runelite/api/widgets/WidgetID.java | 145 +- .../net/runelite/api/widgets/WidgetInfo.java | 62 +- .../plugins/aoewarnings/AoeProjectile.java | 58 + .../aoewarnings/AoeProjectileInfo.java | 128 + .../plugins/aoewarnings/AoeWarningConfig.java | 213 + .../aoewarnings/AoeWarningOverlay.java | 166 + .../plugins/aoewarnings/AoeWarningPlugin.java | 307 ++ .../plugins/aoewarnings/BombOverlay.java | 178 + .../plugins/aoewarnings/CrystalBomb.java | 64 + .../client/plugins/batools/BAToolsConfig.java | 124 + .../plugins/batools/BAToolsOverlay.java | 126 + .../client/plugins/batools/BAToolsPlugin.java | 643 +++ .../client/plugins/batools/Calls.java | 84 + .../client/plugins/batools/CycleCounter.java | 14 + .../client/plugins/batools/Healer.java | 84 + .../client/plugins/batools/HealerCode.java | 34 + .../clanmanmode/ClanManModeConfig.java | 168 + .../ClanManModeMinimapOverlay.java | 52 + .../clanmanmode/ClanManModeOverlay.java | 63 + .../clanmanmode/ClanManModePlugin.java | 137 + .../clanmanmode/ClanManModeService.java | 157 + .../clanmanmode/ClanManModeTileOverlay.java | 48 + .../EquipmentInspectorConfig.java | 65 + .../EquipmentInspectorPanel.java | 98 + .../EquipmentInspectorPlugin.java | 240 ++ .../plugins/equipmentinspector/ItemPanel.java | 52 + .../plugins/equipmentinspector/normal.png | Bin 0 -> 624 bytes .../FightCaveJadHelperOverlay.java | 63 + .../FightCaveJadHelperPlugin.java | 89 + .../plugins/fightcavejadhelper/JadAttack.java | 29 + .../FightCaveWaveHelperConfig.java | 43 + .../FightCaveWaveHelperPlugin.java | 173 + .../fightcavewavehelper/WaveDisplayMode.java | 43 + .../fightcavewavehelper/WaveMonster.java | 47 + .../fightcavewavehelper/WaveOverlay.java | 125 + .../client/plugins/freezetimers/Barrage.java | 43 + .../freezetimers/FreezeTimersConfig.java | 51 + .../freezetimers/FreezeTimersOverlay.java | 157 + .../freezetimers/FreezeTimersPlugin.java | 402 ++ .../freezetimers/FreezeTimersService.java | 81 + .../freezetimers/FreezeTimersTileOverlay.java | 46 + .../freezetimers/PlayerSpellEffect.java | 35 + .../client/plugins/freezetimers/Spell.java | 34 + .../GrotesqueGuardiansOverlay.java | 100 + .../GrotesqueGuardiansPlugin.java | 56 + .../hideprayers/HidePrayersConfig.java | 35 + .../hideprayers/HidePrayersPlugin.java | 169 + .../plugins/hideprayers/PrayerTabState.java | 8 + .../client/plugins/hydra/HydraConfig.java | 41 + .../plugins/hydra/HydraIndicatorOverlay.java | 52 + .../client/plugins/hydra/HydraOverlay.java | 76 + .../client/plugins/hydra/HydraPlugin.java | 145 + .../plugins/hydra/HydraPrayOverlay.java | 100 + .../kittennotifier/KittenNotifierConfig.java | 27 + .../kittennotifier/KittenNotifierPlugin.java | 84 + .../LizardmenShamanConfig.java | 32 + .../LizardmenShamanPlugin.java | 91 + .../lizardmenshaman/LizardmenShamanSpawn.java | 18 + .../lizardmenshaman/ShamanSpawnOverlay.java | 90 + .../menumodifier/MenuModifierConfig.java | 24 + .../MenuModifierInputListener.java | 39 + .../menumodifier/MenuModifierPlugin.java | 168 + .../musicmodifier/MidiFileAdjuster.java | 165 + .../musicmodifier/MusicCustomizerPlugin.java | 355 ++ .../musicmodifier/RealTimeMIDIPlayer.java | 229 ++ .../NextHitNotifierConfig.java | 11 + .../NextHitNotifierOverlay.java | 59 + .../NextHitNotifierPlugin.java | 116 + .../plugins/pkvision/PKVisionConfig.java | 55 + .../pkvision/PKVisionMinimapOverlay.java | 43 + .../plugins/pkvision/PKVisionOverlay.java | 55 + .../plugins/pkvision/PKVisionPlugin.java | 135 + .../plugins/pkvision/PKVisionService.java | 63 + .../plugins/pkvision/PKVisionTileOverlay.java | 44 + .../plankmakehelper/PlankMakeOverlay.java | 88 + .../plankmakehelper/PlankMakePlugin.java | 49 + .../prayagainstplayer/PlayerContainer.java | 56 + .../PrayAgainstPlayerConfig.java | 183 + .../PrayAgainstPlayerOverlay.java | 158 + .../PrayAgainstPlayerOverlayPrayerTab.java | 101 + .../PrayAgainstPlayerPlugin.java | 327 ++ .../plugins/prayagainstplayer/WeaponType.java | 125 + .../client/plugins/profiles/ProfilePanel.java | 123 + .../plugins/profiles/ProfilesConfig.java | 36 + .../plugins/profiles/ProfilesPanel.java | 248 ++ .../plugins/profiles/ProfilesPlugin.java | 128 + .../plugins/pyramidplunder/Obstacles.java | 40 + .../pyramidplunder/PyramidPlunderConfig.java | 66 + .../pyramidplunder/PyramidPlunderOverlay.java | 131 + .../pyramidplunder/PyramidPlunderPlugin.java | 271 ++ .../pyramidplunder/PyramidPlunderTimer.java | 39 + .../screenmarkers/ui/ScreenMarkerPanel.java | 2 +- .../ShayzienInfirmaryOverlay.java | 100 + .../ShayzienInfirmaryPlugin.java | 121 + .../shiftwalker/ShiftWalkerConfig.java | 66 + .../shiftwalker/ShiftWalkerGroups.java | 32 + .../shiftwalker/ShiftWalkerInputListener.java | 61 + .../shiftwalker/ShiftWalkerPlugin.java | 208 + .../plugins/slayermusiq/QuestGuideLinks.java | 207 + .../slayermusiq/SlayermusiqPlugin.java | 152 + .../spellbookfixer/SpellbookFixerConfig.java | 110 + .../spellbookfixer/SpellbookFixerPlugin.java | 170 + .../plugins/suppliestracker/ActionType.java | 36 + .../suppliestracker/BlowpipeDartType.java | 46 + .../plugins/suppliestracker/ItemType.java | 77 + .../plugins/suppliestracker/MenuAction.java | 60 + .../plugins/suppliestracker/SuppliesBox.java | 341 ++ .../SuppliesTrackerConfig.java | 43 + .../suppliestracker/SuppliesTrackerItem.java | 42 + .../suppliestracker/SuppliesTrackerPanel.java | 217 + .../SuppliesTrackerPlugin.java | 781 ++++ .../templetrek/TempleTrekBogOverlay.java | 68 + .../plugins/templetrek/TempleTrekConfig.java | 55 + .../plugins/templetrek/TempleTrekOverlay.java | 78 + .../plugins/templetrek/TempleTrekPlugin.java | 136 + .../tickcounter/TickCounterConfig.java | 71 + .../tickcounter/TickCounterOverlay.java | 69 + .../tickcounter/TickCounterPlugin.java | 193 + .../timetracking/OverviewItemPanel.java | 2 +- .../timetracking/TimeTrackingPlugin.java | 2 +- .../tobdamagecount/DamageCounterPlugin.java | 356 ++ .../client/plugins/vetion/VetionConfig.java | 44 + .../client/plugins/vetion/VetionOverlay.java | 93 + .../client/plugins/vetion/VetionPlugin.java | 95 + .../client/plugins/vorkath/TileHighlight.java | 8 + .../client/plugins/vorkath/VorkathConfig.java | 51 + .../vorkath/VorkathIndicatorOverlay.java | 53 + .../plugins/vorkath/VorkathOverlay.java | 84 + .../client/plugins/vorkath/VorkathPlugin.java | 157 + .../WildernessLocationsOverlay.java | 38 + .../WildernessLocationsPlugin.java | 127 + .../plugins/zoneIndicators/MapLocations.java | 3479 +++++++++++++++++ .../zoneIndicators/ZoneIndicatorsConfig.java | 111 + .../ZoneIndicatorsMinimapOverlay.java | 116 + .../zoneIndicators/ZoneIndicatorsOverlay.java | 113 + .../zoneIndicators/ZoneIndicatorsPlugin.java | 297 ++ .../zoneIndicators/ZoneVisibility.java | 43 + .../client/plugins/ztob/TheatreConfig.java | 138 + .../client/plugins/ztob/TheatreOverlay.java | 347 ++ .../client/plugins/ztob/TheatrePlugin.java | 766 ++++ .../client/plugins/zulrah/ZulrahConfig.java | 24 + .../client/plugins/zulrah/ZulrahOverlay.java | 72 + .../client/plugins/zulrah/ZulrahPlugin.java | 640 +++ .../plugins/zulrah/ZulrahTileOverlay.java | 120 + .../net/runelite/client/util/MiscUtils.java | 79 + .../client/util/WildernessLocation.java | 98 + .../client/plugins/profiles/delete_icon.png | Bin 0 -> 208 bytes .../client/plugins/profiles/profiles_icon.png | Bin 0 -> 77 bytes 154 files changed, 20987 insertions(+), 12 deletions(-) create mode 100644 runelite-api/src/main/java/net/runelite/api/events/CannonballFired.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectile.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/Calls.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/CycleCounter.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/Healer.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/batools/HealerCode.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeMinimapOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeService.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeTileOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/normal.png create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/JadAttack.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveDisplayMode.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveMonster.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraIndicatorOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPrayOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanSpawn.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/ShamanSpawnOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierInputListener.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MidiFileAdjuster.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MusicCustomizerPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/RealTimeMIDIPlayer.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionMinimapOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionService.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionTileOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/Obstacles.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderTimer.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerGroups.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerInputListener.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ActionType.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/BlowpipeDartType.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ItemType.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/MenuAction.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesBox.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerItem.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/TileHighlight.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathIndicatorOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahTileOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/util/MiscUtils.java create mode 100644 runelite-client/src/main/java/net/runelite/client/util/WildernessLocation.java create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/profiles/delete_icon.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/profiles/profiles_icon.png diff --git a/runelite-api/src/main/java/net/runelite/api/Actor.java b/runelite-api/src/main/java/net/runelite/api/Actor.java index 6357a91ebc..53166fba5b 100644 --- a/runelite-api/src/main/java/net/runelite/api/Actor.java +++ b/runelite-api/src/main/java/net/runelite/api/Actor.java @@ -38,6 +38,7 @@ import net.runelite.api.coords.WorldPoint; */ public interface Actor extends Renderable { + /** * Gets the combat level of the actor. * @@ -246,4 +247,10 @@ public interface Actor extends Renderable * @param overheadText the overhead text */ void setOverheadText(String overheadText); + + /** + * Used by the "Tick Counter Plugin + */ + int getActionFrame(); + int getActionFrameCycle(); } diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java index e3fa08fd88..b488d21512 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -154,10 +154,26 @@ public final class AnimationID public static final int PISCARILIUS_CRANE_REPAIR = 7199; public static final int HOME_MAKE_TABLET = 4067; + //block animations for players and perhaps npcs as well? + public static final int BLOCK_DEFENDER = 4177; + public static final int BLOCK_NO_SHIELD = 420; + public static final int BLOCK_SHIELD = 1156; + public static final int BLOCK_SWORD = 388; + public static final int BLOCK_UNARMED = 424; + // NPC animations public static final int TZTOK_JAD_MAGIC_ATTACK = 2656; public static final int TZTOK_JAD_RANGE_ATTACK = 2652; public static final int HELLHOUND_DEFENCE = 6566; + public static final int VORKATH_WAKE_UP = 7950; + public static final int VORKATH_DEATH = 7949; + public static final int VORKATH_SLASH_ATTACK = 7951; + public static final int VORKATH_ATTACK = 7952; + public static final int VORKATH_FIRE_BOMB_ATTACK = 7960; + public static final int VORKATH_ACID_ATTACK = 7957; + public static final int BLACKJACK_KO = 838; + public static final int VETION_EARTHQUAKE = 5507; + public static final int ZULRAH_DEATH = 5804; // Farming public static final int FARMING_HARVEST_FRUIT_TREE = 2280; @@ -194,4 +210,7 @@ public final class AnimationID // POH Animations public static final int INCENSE_BURNER = 3687; -} + public static final int LOW_LEVEL_MAGIC_ATTACK = 1162; + public static final int HIGH_LEVEL_MAGIC_ATTACK = 1167; + public static final int BLOWPIPE_ATTACK = 5061; +} \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/VarPlayer.java b/runelite-api/src/main/java/net/runelite/api/VarPlayer.java index 62489df3f0..36ff1a18f2 100644 --- a/runelite-api/src/main/java/net/runelite/api/VarPlayer.java +++ b/runelite-api/src/main/java/net/runelite/api/VarPlayer.java @@ -52,7 +52,8 @@ public enum VarPlayer IN_RAID_PARTY(1427), NMZ_REWARD_POINTS(1060), - + + ATTACKING_PLAYER(1075), /** * -1 : Poison immune * Normal poison damage is ceil( this / 5.0f ) 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 88ce84f272..3c46a0b71e 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -480,7 +480,16 @@ public enum Varbits /** * The active tab within the quest interface */ - QUEST_TAB(8168); + QUEST_TAB(8168), + + /** + * Temple Trekking + */ + TREK_POINTS(1955), + TREK_STARTED(1956), + TREK_EVENT(1958), + TREK_STATUS(6719); + /** * The raw varbit ID. diff --git a/runelite-api/src/main/java/net/runelite/api/events/CannonballFired.java b/runelite-api/src/main/java/net/runelite/api/events/CannonballFired.java new file mode 100644 index 0000000000..077a88096d --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/CannonballFired.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019, Davis Cook + * 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; + +/** + * an event posted when a cannonball is fired + */ +public class CannonballFired +{ +} diff --git a/runelite-api/src/main/java/net/runelite/api/kit/KitType.java b/runelite-api/src/main/java/net/runelite/api/kit/KitType.java index fdbf92ebfd..a808f2e899 100644 --- a/runelite-api/src/main/java/net/runelite/api/kit/KitType.java +++ b/runelite-api/src/main/java/net/runelite/api/kit/KitType.java @@ -36,6 +36,7 @@ import net.runelite.api.PlayerComposition; */ public enum KitType { + HELMET(0), CAPE(1), AMULET(2), WEAPON(3), @@ -45,7 +46,9 @@ public enum KitType HEAD(8), HANDS(9), BOOTS(10), - JAW(11); + JAW(11), + RING(12), + AMMUNITION(13); /** * Raw equipment index. 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 d84bae473e..8577438af2 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 @@ -129,6 +129,7 @@ public class WidgetID public static final int SKILLS_GROUP_ID = 320; public static final int QUESTTAB_GROUP_ID = 629; public static final int MUSIC_GROUP_ID = 239; + public static final int MUSICTAB_GROUP_ID = 239; public static final int BARROWS_PUZZLE_GROUP_ID = 25; static class WorldMap @@ -701,16 +702,152 @@ public class WidgetID static class StandardSpellBook { static final int LUMBRIDGE_HOME_TELEPORT = 4; +static final int WIND_STRIKE = 5; + static final int CONFUSE = 6; + static final int ENCHANT_CROSSBOW_BOLT = 7; + static final int WATER_STRIKE = 8; + static final int LVL_1_ENCHANT = 9; + static final int EARTH_STRIKE = 10; + static final int WEAKEN = 11; + static final int FIRE_STRIKE = 12; + static final int BONES_TO_BANANAS = 13; + static final int WIND_BOLT = 14; + static final int CURSE = 15; + static final int BIND = 16; + static final int LOW_LEVEL_ALCHEMY = 17; + static final int WATER_BOLT = 18; + static final int VARROCK_TELEPORT = 19; + static final int LVL_2_ENCHANT = 20; + static final int EARTH_BOLT = 21; + static final int LUMBRIDGE_TELEPORT = 22; + static final int TELEKINETIC_GRAB = 23; + static final int FIRE_BOLT = 24; + static final int FALADOR_TELEPORT = 25; + static final int CRUMBLE_UNDEAD = 26; + static final int TELEPORT_TO_HOUSE = 27; + static final int WIND_BLAST = 28; + static final int SUPERHEAT_ITEM = 29; + static final int CAMELOT_TELEPORT = 30; + static final int WATER_BLAST = 31; + static final int LVL_3_ENCHANT = 32; + static final int IBAN_BLAST = 33; + static final int SNARE = 34; + static final int MAGIC_DART = 35; + static final int ARDOUGNE_TELEPORT = 36; + static final int EARTH_BLAST = 37; + static final int HIGH_LEVEL_ALCHEMY = 38; + static final int CHARGE_WATER_ORB = 39; + static final int LVL_4_ENCHANT = 40; + static final int WATCHTOWER_TELEPORT = 41; + static final int FIRE_BLAST = 42; + static final int CHARGE_EARTH_ORB = 43; + static final int BONES_TO_PEACHES = 44; + static final int SARADOMIN_STRIKE = 45; + static final int CLAWS_OF_GUTHIX = 46; + static final int FLAMES_OF_ZAMORAK = 47; + static final int TROLLHEIM_TELEPORT = 48; + static final int WIND_WAVE = 49; + static final int HARGE_FIRE_ORB = 50; + static final int TELEPORT_TO_APE_ATOLL = 51; + static final int WATER_WAVE = 52; + static final int CHARGE_AIR_ORB = 53; + static final int VULNERABILITY = 54; + static final int LVL_5_ENCHANT = 55; + static final int TELEPORT_TO_KOUREND = 56; + static final int EARTH_WAVE = 57; + static final int ENFEEBLE = 58; + static final int TELEOTHER_LUMBRIDGE = 59; + static final int FIRE_WAVE = 60; + static final int ENTANGLE = 61; + static final int STUN = 62; + static final int CHARGE = 63; + static final int WIND_SURGE = 64; + static final int TELEOTHER_FALADOR = 65; + static final int WATER_SURGE = 66; + static final int TELE_BLOCK = 67; + static final int BOUNTY_TARGET_TELEPORT = 68; + static final int LVL_6_ENCHANT = 69; + static final int TELEOTHER_CAMELOT = 70; + static final int EARTH_SURGE = 71; + static final int LVL_7_ENCHANT = 72; + static final int FIRE_SURGE = 73; } - static class AncientSpellBook - { + static class AncientSpellBook { + static final int BOUNTY_TARGET_TELEPORT = 68; + static final int ICE_RUSH = 74; + static final int ICE_BLITZ = 75; + static final int ICE_BURST = 76; + static final int ICE_BARRAGE = 77; + static final int BLOOD_RUSH = 78; + static final int BLOOD_BLITZ = 79; + static final int BLOOD_BURST = 80; + static final int BLOOD_BARRAGE = 81; + static final int SMOKE_RUSH = 82; + static final int SMOKE_BLITZ = 83; + static final int SMOKE_BURST = 84; + static final int SMOKE_BARRAGE = 85; + static final int SHADOW_RUSH = 86; + static final int SHADOW_BLITZ = 87; + static final int SHADOW_BURST = 88; + static final int SHADOW_BARRAGE = 89; + static final int PADDEWWA_TELEPORT = 90; + static final int SENNTISTEN_TELEPORT = 91; + static final int KHARYRLL_TELEPORT = 92; + static final int LASSAR_TELEPORT = 93; + static final int DAREEYAK_TELEPORT = 94; + static final int CARRALLANGER_TELEPORT = 95; + static final int ANNAKARL_TELEPORT = 96; + static final int GHORROCK_TELEPORT = 97; static final int EDGEVILLE_HOME_TELEPORT = 98; } - static class LunarSpellBook - { + static class LunarSpellBook { + static final int BOUNTY_TARGET_TELEPORT = 68; static final int LUNAR_HOME_TELEPORT = 99; + static final int BAKE_PIE = 100; + static final int CURE_PLANT = 101; + static final int MONSTER_EXAMINE = 102; + static final int NPC_CONTACT = 103; + static final int CURE_OTHER = 104; + static final int HUMIDIFY = 105; + static final int MOONCLAN_TELEPORT = 106; + static final int TELE_GROUP_MOONCLAN = 107; + static final int CURE_ME = 108; + static final int HUNTER_KIT = 109; + static final int WATERBIRTH_TELEPORT = 110; + static final int TELE_GROUP_WATERBIRTH = 111; + static final int CURE_GROUP = 112; + static final int STAT_SPY = 113; + static final int BARBARIAN_TELEPORT = 114; + static final int TELE_GROUP_BARBARIAN = 115; + static final int SUPERGLASS_MAKE = 116; + static final int TAN_LEATHER = 117; + static final int KHAZARD_TELEPORT = 118; + static final int TELE_GROUP_KHAZARD = 119; + static final int DREAM = 120; + static final int STRING_JEWELLERY = 121; + static final int STAT_RESTORE_POT_SHARE = 122; + static final int MAGIC_IMBUE = 123; + static final int FERTILE_SOIL = 124; + static final int BOOST_POTION_SHARE = 125; + static final int FISHING_GUILD_TELEPORT = 126; + static final int TELE_GROUP_FISHING_GUILD = 127; + static final int PLANK_MAKE = 128; + static final int CATHERBY_TELEPORT = 129; + static final int TELE_GROUP_CATHERBY = 130; + static final int RECHARGE_DRAGONSTONE = 131; + static final int ICE_PLATEAU_TELEPORT = 132; + static final int TELE_GROUP_ICE_PLATEAU = 133; + static final int ENERGY_TRANSFER = 134; + static final int HEAL_OTHER = 135; + static final int VENGEANCE_OTHER = 136; + static final int VENGEANCE = 137; + static final int HEAL_GROUP = 138; + static final int SPELLBOOK_SWAP = 139; + static final int GEOMANCY = 140; + static final int SPIN_FLAX = 141; + static final int OURANIA_TELEPORT = 142; } static class ArceuusSpellBook 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 5f12519d5d..65e82471d7 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 @@ -450,10 +450,56 @@ public enum WidgetInfo MINIGAME_TELEPORT_BUTTON(WidgetID.MINIGAME_TAB_ID, WidgetID.Minigames.TELEPORT_BUTTON), +/* STANDARD SPELL BOOK WIDGETS*/ SPELL_LUMBRIDGE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.LUMBRIDGE_HOME_TELEPORT), - SPELL_EDGEVILLE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.EDGEVILLE_HOME_TELEPORT), + SPELL_BIND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.BIND), + SPELL_SNARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.SNARE), + SPELL_ENTANGLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.ENTANGLE), + SPELL_TELE_BLOCK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.TELE_BLOCK), + SPELL_FIRE_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.FIRE_SURGE), + SPELL_BOUNTY_TARGET_TELEPORT2(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.BOUNTY_TARGET_TELEPORT), + /* END OF STANDARD SPELL BOOK WIDGETS*/ + + /* LUNAR SPELL BOOK WIDGETS*/ SPELL_LUNAR_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.LUNAR_HOME_TELEPORT), + SPELL_VENGEANCE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.VENGEANCE_OTHER), + SPELL_VENGEANCE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.VENGEANCE), + SPELL_BOUNTY_TARGET_TELEPORT3(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.BOUNTY_TARGET_TELEPORT), + /* LUNA SPELL BOOK WIDGETS*/ + + /* ARCEUUS SPELL BOOK WIDGETS*/ SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.ArceuusSpellBook.ARCEUUS_HOME_TELEPORT), + /* END OF ARCEUUS SPELL BOOK WIDGETS*/ + + /* ANCIENT SPELL BOOK WIDGETS*/ + SPELL_ICE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_RUSH), + SPELL_ICE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BLITZ), + SPELL_ICE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BURST), + SPELL_ICE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BARRAGE), + SPELL_BLOOD_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_RUSH), + SPELL_BLOOD_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BLITZ), + SPELL_BLOOD_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BURST), + SPELL_BLOOD_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BARRAGE), + SPELL_SMOKE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_RUSH), + SPELL_SMOKE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BLITZ), + SPELL_SMOKE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BURST), + SPELL_SMOKE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BARRAGE), + SPELL_SHADOW_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_RUSH), + SPELL_SHADOW_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BLITZ), + SPELL_SHADOW_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BURST), + SPELL_SHADOW_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BARRAGE), + SPELL_PADDEWWA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.PADDEWWA_TELEPORT), + SPELL_SENNTISTEN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SENNTISTEN_TELEPORT), + SPELL_KHARYRLL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.KHARYRLL_TELEPORT), + SPELL_LASSAR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.LASSAR_TELEPORT), + SPELL_DAREEYAK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.DAREEYAK_TELEPORT), + SPELL_CARRALLANGER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.CARRALLANGER_TELEPORT), + SPELL_ANNAKARL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ANNAKARL_TELEPORT), + SPELL_GHORROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.GHORROCK_TELEPORT), + SPELL_EDGEVILLE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.EDGEVILLE_HOME_TELEPORT), + SPELL_BOUNTY_TARGET_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BOUNTY_TARGET_TELEPORT), + + /* 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), @@ -477,6 +523,20 @@ public enum WidgetInfo QUESTLIST_FREE_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.FREE_CONTAINER), QUESTLIST_MEMBERS_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.MEMBERS_CONTAINER), QUESTLIST_MINIQUEST_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.MINIQUEST_CONTAINER), + + MUSICTAB_INTERFACE(WidgetID.MUSICTAB_GROUP_ID, 1), + MUSICTAB_SONG_BOX(WidgetID.MUSICTAB_GROUP_ID, 2), + MUSICTAB_ALL_SONGS(WidgetID.MUSICTAB_GROUP_ID, 3), + MUSICTAB_SCROLLBAR(WidgetID.MUSICTAB_GROUP_ID, 4), + MUSICTAB_PLAYING(WidgetID.MUSICTAB_GROUP_ID, 5), + MUSICTAB_CURRENT_SONG_NAME(WidgetID.MUSICTAB_GROUP_ID, 6), + MUSICTAB_AUTO_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 7), + MUSICTAB_AUTO_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 8), + MUSICTAB_MANUAL_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 9), + MUSICTAB_MANUAL_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 10), + MUSICTAB_LOOP_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 11), + MUSICTAB_LOOP_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 12), + MUSICTAB_UNLOCKED_SONGS(WidgetID.MUSICTAB_GROUP_ID, 13), QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectile.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectile.java new file mode 100644 index 0000000000..8bd41f2610 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectile.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, Adam + * 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.aoewarnings; + +import net.runelite.api.coords.LocalPoint; + +import java.time.Instant; + +public class AoeProjectile +{ + private final Instant startTime; + private final LocalPoint targetPoint; + private final AoeProjectileInfo aoeProjectileInfo; + + public AoeProjectile(Instant startTime, LocalPoint targetPoint, AoeProjectileInfo aoeProjectileInfo) + { + this.startTime = startTime; + this.targetPoint = targetPoint; + this.aoeProjectileInfo = aoeProjectileInfo; + } + + public Instant getStartTime() + { + return startTime; + } + + public LocalPoint getTargetPoint() + { + return targetPoint; + } + + public AoeProjectileInfo getAoeProjectileInfo() + { + return aoeProjectileInfo; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java new file mode 100644 index 0000000000..4d4f59a650 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java @@ -0,0 +1,128 @@ +package net.runelite.client.plugins.aoewarnings; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import net.runelite.api.ProjectileID; + +public enum AoeProjectileInfo +{ + LIZARDMAN_SHAMAN_AOE(ProjectileID.LIZARDMAN_SHAMAN_AOE, 3000, 3), + CRAZY_ARCHAEOLOGIST_AOE(ProjectileID.CRAZY_ARCHAEOLOGIST_AOE, 3000, 3), + ICE_DEMON_RANGED_AOE(ProjectileID.ICE_DEMON_RANGED_AOE, 3000, 3), + /** + * When you don't have pray range on ice demon does an ice barrage + */ + ICE_DEMON_ICE_BARRAGE_AOE(ProjectileID.ICE_DEMON_ICE_BARRAGE_AOE, 3000, 3), + /** + * The AOE when vasa first starts + */ + VASA_AWAKEN_AOE(ProjectileID.VASA_AWAKEN_AOE, 4500, 3), + VASA_RANGED_AOE(ProjectileID.VASA_RANGED_AOE, 3000, 3), + TEKTON_METEOR_AOE(ProjectileID.TEKTON_METEOR_AOE, 4000, 3), + + /** + * The AOEs of Vorkath + */ + VORKATH_BOMB(ProjectileID.VORKATH_BOMB_AOE, 2400, 3), + VORKATH_POISON_POOL(ProjectileID.VORKATH_POISON_POOL_AOE, 1800, 1), + VORKATH_SPAWN(ProjectileID.VORKATH_SPAWN_AOE, 3000, 1), //extra tick because hard to see otherwise + VORKATH_TICK_FIRE(ProjectileID.VORKATH_TICK_FIRE_AOE, 600, 1), + + /** + * the AOEs of Galvek + */ + GALVEK_MINE(ProjectileID.GALVEK_MINE, 3600, 3), + GALVEK_BOMB(ProjectileID.GALVEK_BOMB, 2400, 3), + + DAWN_FREEZE(ProjectileID.DAWN_FREEZE, 3000, 3), + DUSK_CEILING(ProjectileID.DUSK_CEILING, 3000, 3), + + /** + * the AOE of Vet'ion + */ + VETION_LIGHTNING(ProjectileID.VETION_LIGHTNING, 3000, 1), + + /** + * the AOE of Chaos Fanatic + */ + CHAOS_FANATIC(ProjectileID.CHAOS_FANATIC_AOE, 3000, 1), + + /** + * the AOE of the Corporeal Beast + */ + + CORPOREAL_BEAST(ProjectileID.CORPOREAL_BEAST_AOE, 3000, 1), + CORPOREAL_BEAST_DARK_CORE(ProjectileID.CORPOREAL_BEAST_DARK_CORE_AOE, 3000, 3), + + /** + * the AOEs of The Great Olm + * missing ids and length, please help + */ + OLM_FALLING_CRYSTAL(1357, 3000, 3), + OLM_BURNING(1349, 2400, 1), + OLM_FALLING_CRYSTAL_TRAIL(1352, 2400, 1), + OLM_ACID_TRAIL(1354, 2400, 1), + OLM_FIRE_LINE(1347, 2400, 1), + + /** + * the AOE of the Wintertodt snow that falls + */ + WINTERTODT_SNOW_FALL(1310, 4000, 3); + + + /** + * The id of the projectile to trigger this AoE warning + */ + private final int id; + + /** + * How long the indicator should last for this AoE warning This might + * need to be a bit longer than the projectile actually takes to land as + * there is a fade effect on the warning + */ + private final Duration lifeTime; + + /** + * The size of the splash radius of the AoE warning Ex. Lizardman shaman + * AoE is a 3x3, so aoeSize = 3 + */ + private final int aoeSize; + + private static final Map map = new HashMap<>(); + + static + { + for (AoeProjectileInfo aoe : values()) + { + map.put(aoe.id, aoe); + } + } + + AoeProjectileInfo(int id, int lifeTimeMillis, int aoeSize) + { + this.id = id; + this.lifeTime = Duration.ofMillis(lifeTimeMillis); + this.aoeSize = aoeSize; + } + + public Duration getLifeTime() + { + return lifeTime; + } + + public int getId() + { + return id; + } + + public int getAoeSize() + { + return aoeSize; + } + + public static AoeProjectileInfo getById(int id) + { + return map.get(id); + } +} 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 new file mode 100644 index 0000000000..af1b361ec0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningConfig.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2018, Adam + * 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.aoewarnings; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("aoe") +public interface AoeWarningConfig extends Config +{ + @ConfigItem( + keyName = "enabled", + name = "AoE Warnings Enabled", + description = "Configures whether or not AoE Projectile Warnings plugin is displayed" + ) + default boolean enabled() + { + return true; + } + + @ConfigItem( + keyName = "lizardmanaoe", + name = "Lizardman Shamans", + description = "Configures whether or not AoE Projectile Warnings for Lizardman Shamans is displayed" + ) + default boolean isShamansEnabled() + { + return true; + } + + @ConfigItem( + keyName = "archaeologistaoe", + name = "Crazy Archaeologist", + description = "Configures whether or not AoE Projectile Warnings for Archaeologist is displayed" + ) + default boolean isArchaeologistEnabled() + { + return true; + } + + @ConfigItem( + keyName = "icedemon", + name = "Ice Demon", + description = "Configures whether or not AoE Projectile Warnings for Ice Demon is displayed" + ) + default boolean isIceDemonEnabled() + { + return true; + } + + @ConfigItem( + keyName = "vasa", + name = "Vasa", + description = "Configures whether or not AoE Projectile Warnings for Vasa is displayed" + ) + default boolean isVasaEnabled() + { + return true; + } + + @ConfigItem( + keyName = "tekton", + name = "Tekton", + description = "Configures whether or not AoE Projectile Warnings for Tekton is displayed" + ) + default boolean isTektonEnabled() + { + return true; + } + + @ConfigItem( + keyName = "vorkath", + name = "Vorkath", + description = "Configures whether or not AoE Projectile Warnings for Vorkath are displayed" + ) + default boolean isVorkathEnabled() + { + return true; + } + + @ConfigItem( + keyName = "galvek", + name = "Galvek", + description = "Configures whether or not AoE Projectile Warnings for Galvek are displayed" + ) + default boolean isGalvekEnabled() + { + return true; + } + + @ConfigItem( + keyName = "gargboss", + name = "Gargoyle Boss", + description = "Configs whether or not AoE Projectile Warnings for Dawn/Dusk are displayed" + ) + default boolean isGargBossEnabled() + { + return true; + } + + @ConfigItem( + keyName = "vetion", + name = "Vet'ion", + description = "Configures whether or not AoE Projectile Warnings for Vet'ion are displayed" + ) + default boolean isVetionEnabled() + { + return true; + } + + @ConfigItem( + keyName = "chaosfanatic", + name = "Chaos Fanatic", + description = "Configures whether or not AoE Projectile Warnings for Chaos Fanatic are displayed" + ) + default boolean isChaosFanaticEnabled() + { + return true; + } + + @ConfigItem( + keyName = "olm", + name = "Great Olm", + description = "Configures whether or not AoE Projectile Warnings for The Great Olm are displayed" + ) + default boolean isOlmEnabled() + { + return true; + } + + @ConfigItem( + keyName = "bombDisplay", + name = "Display crystal phase bomb tracker", + description = "Display a timer and colour-coded AoE for Olm's crystal-phase bombs." + ) + default boolean bombDisplay() + { + return true; + } + + @ConfigItem( + keyName = "corp", + name = "Corporeal Beast", + description = "Configures whether or not AoE Projectile Warnings for the Corporeal Beast are displayed" + ) + default boolean isCorpEnabled() + { + return true; + } + + @ConfigItem( + keyName = "wintertodt", + name = "Wintertodt Snow Fall", + description = "Configures whether or not AOE Projectile Warnings for the Wintertodt snow fall are displayed" + ) + default boolean isWintertodtEnabled() + { + return true; + } + + @ConfigItem( + keyName = "outline", + name = "Display Outline", + description = "Configures whether or not AoE Projectile Warnings have an outline" + ) + default boolean isOutlineEnabled() + { + return true; + } + + @ConfigItem( + keyName = "lightning", + name = "Show Lightning Trails", + description = "Show Lightning Trails" + ) + default boolean LightningTrail() + { + return true; + } + + @ConfigItem( + keyName = "fade", + name = "Fade Warnings", + description = "Configures whether or not AoE Projectile Warnings fade over time" + ) + default boolean isFadeEnabled() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java new file mode 100644 index 0000000000..7e6dd2409a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningOverlay.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2017, Adam + * 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.aoewarnings; + +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Projectile; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import java.awt.*; +import java.time.Instant; +import java.util.Iterator; +import java.util.Map; + +public class AoeWarningOverlay extends Overlay +{ + private static final int FILL_START_ALPHA = 25; + private static final int OUTLINE_START_ALPHA = 255; + + private final Client client; + private final AoeWarningPlugin plugin; + private final AoeWarningConfig config; + + @Inject + public AoeWarningOverlay(@Nullable Client client, AoeWarningPlugin plugin, AoeWarningConfig config) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.UNDER_WIDGETS); + this.client = client; + this.plugin = plugin; + this.config = config; + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!config.enabled()) + { + return null; + } + for (WorldPoint point : plugin.getLightningTrail()) + { + drawTile(graphics, point, new Color(0,150,200), 2, 150, 50); + } + for (WorldPoint point : plugin.getAcidTrail()) + { + drawTile(graphics, point, new Color(69, 241, 44), 2, 150, 50); + } + for (WorldPoint point : plugin.getCrystalSpike()) + { + drawTile(graphics, point, new Color(255, 0, 84), 2, 150, 50); + } + + Instant now = Instant.now(); + Map projectiles = plugin.getProjectiles(); + for (Iterator it = projectiles.values().iterator(); it.hasNext();) + { + AoeProjectile aoeProjectile = it.next(); + + if (now.isAfter(aoeProjectile.getStartTime().plus(aoeProjectile.getAoeProjectileInfo().getLifeTime()))) + { + it.remove(); + continue; + } + + Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, aoeProjectile.getTargetPoint(), aoeProjectile.getAoeProjectileInfo().getAoeSize()); + if (tilePoly == null) + { + continue; + } + + // how far through the projectiles lifetime between 0-1. + double progress = (System.currentTimeMillis() - aoeProjectile.getStartTime().toEpochMilli()) / (double) aoeProjectile.getAoeProjectileInfo().getLifeTime().toMillis(); + + int fillAlpha, outlineAlpha; + if (config.isFadeEnabled()) + { + fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA);//alpha drop off over lifetime + outlineAlpha = (int) ((1 - progress) * OUTLINE_START_ALPHA); + } + else + { + fillAlpha = FILL_START_ALPHA; + outlineAlpha = OUTLINE_START_ALPHA; + } + + if (fillAlpha < 0) + { + fillAlpha = 0; + } + if (outlineAlpha < 0) + { + outlineAlpha = 0; + } + + if (fillAlpha > 255) + { + fillAlpha = 255; + } + if (outlineAlpha > 255) + { + outlineAlpha = 255;//Make sure we don't pass in an invalid alpha + } + + if (config.isOutlineEnabled()) + { + graphics.setColor(new Color(0, 150, 200, outlineAlpha)); + graphics.drawPolygon(tilePoly); + } + + graphics.setColor(new Color(0, 150, 200, fillAlpha)); + graphics.fillPolygon(tilePoly); + } + return null; + } + + private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) { + WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); + if (point.distanceTo(playerLocation) >= 32) { + return; + } + LocalPoint lp = LocalPoint.fromWorld(client, point); + if (lp == null) { + return; + } + + Polygon poly = Perspective.getCanvasTilePoly(client, lp); + if (poly == null) { + return; + } + //OverlayUtil.renderPolygon(graphics, poly, color); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); + graphics.setStroke(new BasicStroke(strokeWidth)); + graphics.draw(poly); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); + graphics.fill(poly); + } +} 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 new file mode 100644 index 0000000000..c3219d53b7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2018, Adam + * 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.aoewarnings; + +import com.google.inject.Provides; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.GameObject; +import net.runelite.api.GameState; +import net.runelite.api.GraphicID; +import net.runelite.api.GraphicsObject; +import net.runelite.api.ObjectID; +import net.runelite.api.Projectile; +import net.runelite.api.Client; +import net.runelite.api.Tile; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.GameObjectDespawned; +import net.runelite.api.events.GameObjectSpawned; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.GraphicsObjectCreated; +import net.runelite.api.events.ProjectileMoved; +import net.runelite.client.Notifier; +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.ui.overlay.OverlayManager; + +import javax.inject.Inject; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +@PluginDescriptor( + name = "!AoE Warnings", + description = "Shows the final destination for AoE Attack projectiles", + tags = {"bosses", "combat", "pve", "overlay"} +) + +@Slf4j +public class AoeWarningPlugin extends Plugin +{ + + @Inject + private OverlayManager overlayManager; + + @Inject + private AoeWarningOverlay coreOverlay; + + @Inject + public AoeWarningConfig config; + + @Inject + private BombOverlay bombOverlay; + + @Inject + private Client client; + + @Inject + private Notifier notifier; + + @Getter + private final Map bombs = new HashMap<>(); + @Getter(AccessLevel.PACKAGE) + private List LightningTrail = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) + private List AcidTrail = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) + private List CrystalSpike = new ArrayList<>(); + + + @Provides + AoeWarningConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(AoeWarningConfig.class); + } + + + private final Map projectiles = new HashMap<>(); + + public Map getProjectiles() + { + return projectiles; + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(coreOverlay); + overlayManager.add(bombOverlay); + LightningTrail.clear(); + AcidTrail.clear(); + CrystalSpike.clear(); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(coreOverlay); + overlayManager.remove(bombOverlay); + } + + @Subscribe + public void onProjectileMoved(ProjectileMoved event) + { + Projectile projectile = event.getProjectile(); + + int projectileId = projectile.getId(); + AoeProjectileInfo aoeProjectileInfo = AoeProjectileInfo.getById(projectileId); + if (aoeProjectileInfo != null && isConfigEnabledForProjectileId(projectileId)) + { + LocalPoint targetPoint = event.getPosition(); + AoeProjectile aoeProjectile = new AoeProjectile(Instant.now(), targetPoint, aoeProjectileInfo); + projectiles.put(projectile, aoeProjectile); + } + } + + @Subscribe + public void onGameObjectSpawned(GameObjectSpawned event) + { + final GameObject gameObject = event.getGameObject(); + final WorldPoint bombLocation = gameObject.getWorldLocation(); + + switch (gameObject.getId()) + { + case ObjectID.CRYSTAL_BOMB: + bombs.put(bombLocation, new CrystalBomb(gameObject, client.getTickCount())); + break; + case ObjectID.ACID_POOL: + AcidTrail.add(bombLocation); + break; + case ObjectID.SMALL_CRYSTALS: + //todo + CrystalSpike.add(bombLocation); + break; + } + } + + @Subscribe + public void onGameObjectDespawned(GameObjectDespawned event) + { + GameObject gameObject = event.getGameObject(); + WorldPoint bombLocation = gameObject.getWorldLocation(); + switch (gameObject.getId()) + { + case ObjectID.CRYSTAL_BOMB: + //might as well check the ObjectID to save some time. + purgeBombs(bombs); + break; + case ObjectID.ACID_POOL: + AcidTrail.remove(bombLocation); + break; + case ObjectID.SMALL_CRYSTALS: + //todo + CrystalSpike.remove(bombLocation); + break; + } + } + + @Subscribe + public void onGameStateChanged(GameStateChanged delta) + { + if (client.getGameState() == GameState.LOGGED_IN) + { + purgeBombs(bombs); + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (config.LightningTrail()) + { + LightningTrail.clear(); + for (GraphicsObject o : client.getGraphicsObjects()) + { + if (o.getId() == 1356) + { + LightningTrail.add(WorldPoint.fromLocal(client, o.getLocation())); + } + } + } + + Iterator> it = bombs.entrySet().iterator(); + + while (it.hasNext()) + { + Map.Entry entry = it.next(); + CrystalBomb bomb = entry.getValue(); + bomb.bombClockUpdate(); + //bombClockUpdate smooths the shown timer; not using this results in 1.2 --> .6 vs. 1.2 --> 1.1, etc. + } + } + + private void purgeBombs(Map bombs) + { + Iterator> it = bombs.entrySet().iterator(); + Tile[][][] tiles = client.getScene().getTiles(); + + while (it.hasNext()) + { + Map.Entry entry = it.next(); + WorldPoint world = entry.getKey(); + LocalPoint local = LocalPoint.fromWorld(client, world); + Tile tile = tiles[world.getPlane()][local.getSceneX()][local.getSceneY()]; + GameObject[] objects = tile.getGameObjects(); + boolean containsObjects = false; + + for (GameObject object : objects) + { + if (object != null) + { + containsObjects = true; + } + } + + if (!containsObjects) + { + it.remove(); + } + + } + } + + private boolean isConfigEnabledForProjectileId(int projectileId) + { + AoeProjectileInfo projectileInfo = AoeProjectileInfo.getById(projectileId); + if (projectileInfo == null) + { + return false; + } + + switch (projectileInfo) + { + case LIZARDMAN_SHAMAN_AOE: + return config.isShamansEnabled(); + case CRAZY_ARCHAEOLOGIST_AOE: + return config.isArchaeologistEnabled(); + case ICE_DEMON_RANGED_AOE: + case ICE_DEMON_ICE_BARRAGE_AOE: + return config.isIceDemonEnabled(); + case VASA_AWAKEN_AOE: + case VASA_RANGED_AOE: + return config.isVasaEnabled(); + case TEKTON_METEOR_AOE: + return config.isTektonEnabled(); + case VORKATH_BOMB: + case VORKATH_POISON_POOL: + case VORKATH_SPAWN: + case VORKATH_TICK_FIRE: + return config.isVorkathEnabled(); + case VETION_LIGHTNING: + return config.isVetionEnabled(); + case CHAOS_FANATIC: + return config.isChaosFanaticEnabled(); + case GALVEK_BOMB: + case GALVEK_MINE: + return config.isGalvekEnabled(); + case DAWN_FREEZE: + case DUSK_CEILING: + return config.isGargBossEnabled(); + case OLM_FALLING_CRYSTAL: + case OLM_BURNING: + case OLM_FALLING_CRYSTAL_TRAIL: + case OLM_ACID_TRAIL: + case OLM_FIRE_LINE: + return config.isOlmEnabled(); + case CORPOREAL_BEAST: + case CORPOREAL_BEAST_DARK_CORE: + return config.isCorpEnabled(); + case WINTERTODT_SNOW_FALL: + return config.isWintertodtEnabled(); + } + + return false; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java new file mode 100644 index 0000000000..0ee6162a76 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/BombOverlay.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2018, PallasDieKatze (Pallas Cat) + * 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.aoewarnings; + +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.aoewarnings.CrystalBomb; +import net.runelite.client.ui.overlay.*; +import javax.inject.Inject; +import java.awt.Graphics2D; +import java.awt.Dimension; +import java.awt.Color; +import java.awt.Polygon; +import java.awt.BasicStroke; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.time.Instant; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; + +@Slf4j +public class BombOverlay extends Overlay +{ + + private static final String SAFE = "#00cc00"; + //safe + private static final String CAUTION = "#ffff00"; + //1 tile in range (minor damage) + private static final String WARNING = "#ff9933"; + //2 tiles in range (moderate damage) + private static final String DANGER = "#ff6600"; + //3 tiles in range/adjacent to bomb (major damage) + private static final String LETHAL = "#cc0000"; + //On the bomb, using it as a makeshift space launch vehicle. (massive damage) + + private static final int BOMB_AOE = 7; + private static final int BOMB_DETONATE_TIME = 8; + //This is in ticks. It should be 10, but it varies from 8 to 11. + private static final double ESTIMATED_TICK_LENGTH = .6; + //Thank you Woox & co. for this assumption. .6 seconds/tick. + + + //Utilized from the npc highlight code for formatting text being displayed on the client canvas. + private static final NumberFormat TIME_LEFT_FORMATTER = + DecimalFormat.getInstance(Locale.US); + + static + { + ((DecimalFormat) TIME_LEFT_FORMATTER).applyPattern("#0.0"); + } + + private final Client client; + private final AoeWarningConfig config; + private final AoeWarningPlugin plugin; + + @Inject + public BombOverlay(Client client, AoeWarningPlugin plugin, AoeWarningConfig config) + { + this.client = client; + this.plugin = plugin; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + setPriority(OverlayPriority.MED); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (config.bombDisplay()) + { + drawBombs(graphics); + } + return null; + } + + private void drawBombs(Graphics2D graphics) + //I can condense drawDangerZone into this. Ambivalent though. + { + Iterator> it = plugin.getBombs().entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = it.next(); + CrystalBomb bomb = entry.getValue(); + drawDangerZone(graphics, bomb); + } + } + + private void drawDangerZone(Graphics2D graphics, CrystalBomb bomb) + { + final Player localPlayer = client.getLocalPlayer(); + LocalPoint localLoc = LocalPoint.fromWorld(client, bomb.getWorldLocation()); + double distance_x = Math.abs(bomb.getWorldLocation().getX() - localPlayer.getWorldLocation().getX()); + double distance_y = Math.abs(bomb.getWorldLocation().getY() - localPlayer.getWorldLocation().getY()); + Color color_code = Color.decode(SAFE); + //defaults to this unless conditionals met below. + + if (distance_x < 1 && distance_y < 1) + { + color_code = Color.decode(LETHAL); + } + else if (distance_x < 2 && distance_y < 2) + { + color_code = Color.decode(DANGER); + } + else if (distance_x < 3 && distance_y < 3) + { + color_code = Color.decode(WARNING); + } + else if (distance_x < 4 && distance_y < 4) + { + color_code = Color.decode(CAUTION); + } + LocalPoint CenterPoint = new LocalPoint(localLoc.getX() + 0, localLoc.getY() + 0); + Polygon poly = Perspective.getCanvasTileAreaPoly(client, CenterPoint, BOMB_AOE); + + if (poly != null) + { + //manually generating the polygon so as to assign a custom alpha value. Request adtl' arg for alpha maybe? + graphics.setColor(color_code); + graphics.setStroke(new BasicStroke(1)); + graphics.drawPolygon(poly); + graphics.setColor(new Color(0, 0, 0, 10)); + graphics.fillPolygon(poly); + } + + Instant now = Instant.now(); + double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() - + bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) - + (now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0; + //divided by 1000.00 because of milliseconds :) + + timeLeft = Math.max(0.0, timeLeft); + String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft); + int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString); + int textHeight = graphics.getFontMetrics().getAscent(); + Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(), + localLoc.getY(), bomb.getWorldLocation().getPlane()); + + if (canvasPoint != null) + { + Point canvasCenterPoint = new Point( + canvasPoint.getX() - textWidth / 2, + canvasPoint.getY() + textHeight / 2); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code); + } + + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java new file mode 100644 index 0000000000..d138aed20c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/CrystalBomb.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018, PallasDieKatze (Pallas Cat) + * 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.aoewarnings; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.GameObject; +import net.runelite.api.coords.WorldPoint; +import java.time.Instant; + +@Slf4j +public class CrystalBomb +{ + @Getter + private Instant plantedOn; + + @Getter + private Instant lastClockUpdate; + + @Getter + private int objectId; + + @Getter + private int tickStarted; + // + + @Getter + private WorldPoint worldLocation; + + public CrystalBomb(GameObject gameObject, int startTick) + { + this.plantedOn = Instant.now(); + this.objectId = gameObject.getId(); + this.worldLocation = gameObject.getWorldLocation(); + this.tickStarted = startTick; + } + + public void bombClockUpdate() + { + lastClockUpdate = Instant.now(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsConfig.java new file mode 100644 index 0000000000..64cf45dc8f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsConfig.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2018, Cameron + * Copyright (c) 2018, Jacob M + * 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.batools; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("BATools") +public interface BAToolsConfig extends Config +{ + @ConfigItem( + keyName = "defTimer", + name = "Defender Tick Timer", + description = "Shows the current cycle tick of runners." + ) + default boolean defTimer() + { + return false; + } + + @ConfigItem( + keyName = "calls", + name = "Remove Incorrect Calls", + description = "Remove incorrect calls." + ) + default boolean calls() + { + return false; + } + + @ConfigItem( + keyName = "swapLadder", + name = "Swap ladder option", + description = "Swap Climb-down with Quick-start in the wave lobbies" + ) + default boolean swapLadder() + { + return true; + } + + @ConfigItem( + keyName = "healerCodes", + name = "Healer Codes", + description = "Overlay to show healer codes" + ) + default boolean healerCodes() + { + return false; + } + + @ConfigItem( + keyName = "healerMenuOption", + name = "Healer menu options", + description = "asd" + ) + default boolean healerMenuOption() + { + return false; + } + + @ConfigItem( + keyName = "antiDrag", + name = "Anti Drag", + description = "asd" + ) + default boolean antiDrag() + { + return false; + } + + @ConfigItem( + keyName = "antiDragDelay", + name = "Anti Drag Delay", + description = "asd" + ) + default int antiDragDelay() + { + return 5; + } + + @ConfigItem( + keyName = "eggBoi", + name = "Collector helper", + description = "asd" + ) + default boolean eggBoi() + { + return false; + } + + @ConfigItem( + keyName = "osHelp", + name = "Shift OS", + description = "asd" + ) + default boolean osHelp() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsOverlay.java new file mode 100644 index 0000000000..43a7bf4e7f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsOverlay.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2018, Woox + * 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.batools; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import net.runelite.api.NPCComposition; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.Overlay; +import java.time.Duration; +import java.time.Instant; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import lombok.extern.slf4j.Slf4j; +@Slf4j + +public class BAToolsOverlay extends Overlay +{ + private static final Color RED = new Color(221, 44, 0); + private static final Color GREEN = new Color(0, 200, 83); + private static final Color ORANGE = new Color(255, 109, 0); + private static final Color YELLOW = new Color(255, 214, 0); + private static final Color CYAN = new Color(0, 184, 212); + private static final Color BLUE = new Color(41, 98, 255); + private static final Color DEEP_PURPLE = new Color(98, 0, 234); + private static final Color PURPLE = new Color(170, 0, 255); + private static final Color GRAY = new Color(158, 158, 158); + + private final BAToolsConfig config; + private Client client; + private BAToolsPlugin plugin; + + @Inject + public BAToolsOverlay(Client client, BAToolsPlugin plugin, BAToolsConfig config) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + this.config = config; + this.client = client; + this.plugin = plugin; + } + + + @Override + public Dimension render(Graphics2D graphics) + { + if(!config.healerCodes()) + { + return null; + } + + for (Healer healer : plugin.getHealers().values()) + { + NPCComposition composition = healer.getNpc().getComposition(); + Color color = composition.getCombatLevel() > 1 ? YELLOW : ORANGE; + if (composition.getConfigs() != null) + { + NPCComposition transformedComposition = composition.transform(); + if (transformedComposition == null) + { + color = GRAY; + } + else + { + composition = transformedComposition; + } + } + int timeLeft = healer.getLastFoodTime() - (int)Duration.between(plugin.getWave_start(), Instant.now()).getSeconds(); + timeLeft = timeLeft < 1 ? 0 : timeLeft; + + if(healer.getFoodRemaining() > 1) + { + color = GREEN; + } + else if(healer.getFoodRemaining() == 1) + { + if(timeLeft > 0) + { + color = RED; + } + else + { + color = GREEN; + } + } + else + { + continue; + } + + String text = String.format("%d %d", + healer.getFoodRemaining(), + timeLeft); + + + + OverlayUtil.renderActorOverlay(graphics, healer.getNpc(), text, color); + } + return null; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..7b9e195848 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/batools/BAToolsPlugin.java @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2018, Cameron + * Copyright (c) 2018, Jacob M + * 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.batools; + +import net.runelite.client.eventbus.EventBus; +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Actor; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import static net.runelite.api.Constants.CHUNK_SIZE; +import net.runelite.api.ItemID; +import net.runelite.api.MenuEntry; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; +import net.runelite.api.Varbits; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.HitsplatApplied; +import net.runelite.api.events.InteractingChanged; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.MenuOptionClicked; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.NpcSpawned; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.input.KeyListener; +import net.runelite.client.input.KeyManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.util.Text; + +@Slf4j +@PluginDescriptor( + name = "BA Tools", + description = "Custom tools for Barbarian Assault", + tags = {"minigame", "overlay", "timer"} +) +public class BAToolsPlugin extends Plugin implements KeyListener +{ + int inGameBit = 0; + int tickNum; + int pastCall = 0; + private int currentWave = 1; + private static final int BA_WAVE_NUM_INDEX = 2; + private final List entries = new ArrayList<>(); + private HashMap foodPressed = new HashMap<>(); + private CycleCounter counter; + private Actor lastInteracted; + + private boolean shiftDown; + + @Inject + private Client client; + + @Inject + private ConfigManager configManager; + + @Inject + private ChatMessageManager chatMessageManager; + + @Inject + private OverlayManager overlayManager; + + @Inject + private BAToolsConfig config; + + @Inject + private ItemManager itemManager; + + @Inject + private InfoBoxManager infoBoxManager; + + @Inject + private BAToolsOverlay overlay; + + @Getter + private Map healers; + + @Getter + private Instant wave_start; + + @Inject + private KeyManager keyManager; + + + @Provides + BAToolsConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(BAToolsConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + healers = new HashMap<>(); + wave_start = Instant.now(); + lastInteracted = null; + foodPressed.clear(); + client.setInventoryDragDelay(config.antiDragDelay()); + keyManager.registerKeyListener(this); + } + + @Override + protected void shutDown() throws Exception + { + removeCounter(); + healers.clear(); + inGameBit = 0; + lastInteracted = null; + overlayManager.remove(overlay); + client.setInventoryDragDelay(5); + keyManager.unregisterKeyListener(this); + shiftDown = false; + } + + @Subscribe + public void onWidgetLoaded(WidgetLoaded event) + { + switch (event.getGroupId()) + { + case WidgetID.BA_REWARD_GROUP_ID: + { + Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT); + + if (rewardWidget != null && rewardWidget.getText().contains("
5")) + { + tickNum = 0; + } + } + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (config.antiDrag()) + { + client.setInventoryDragDelay(config.antiDragDelay()); + } + + Widget callWidget = getWidget(); + + if (callWidget != null) + { + if (callWidget.getTextColor() != pastCall && callWidget.getTextColor() == 16316664) + { + tickNum = 0; + } + pastCall = callWidget.getTextColor(); + } + if (inGameBit == 1) + { + if (tickNum > 9) + { + tickNum = 0; + } + if (counter == null) + { + addCounter(); + } + //counter.setText(String.valueOf(tickNum)); + counter.setCount(tickNum); + if (config.defTimer()) + { + log.info("" + tickNum++); + } + } + } + + private Widget getWidget() + { + if (client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT) != null) + { + return client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT); + } + else if (client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT) != null) + { + return client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT); + } + else if (client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT) != null) + { + return client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT); + } + else if (client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) != null) + { + return client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT); + } + return null; + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + int inGame = client.getVar(Varbits.IN_GAME_BA); + + if (inGameBit != inGame) + { + if (inGameBit == 1) + { + pastCall = 0; + removeCounter(); + foodPressed.clear(); + } + else + { + addCounter(); + } + } + + inGameBit = inGame; + } + + @Subscribe + public void onChatMessage(ChatMessage event) + { + if (event.getType() == ChatMessageType.CONSOLE + && event.getMessage().startsWith("---- Wave:")) + { + String[] message = event.getMessage().split(" "); + currentWave = Integer.parseInt(message[BA_WAVE_NUM_INDEX]); + wave_start = Instant.now(); + healers.clear(); + } + } + + @Subscribe + public void onNpcSpawned(NpcSpawned event) + { + NPC npc = event.getNpc(); + + if (isNpcHealer(npc.getId())) + { + if (checkNewSpawn(npc) || Duration.between(wave_start, Instant.now()).getSeconds() < 16) + { + int spawnNumber = healers.size(); + healers.put(npc, new Healer(npc, spawnNumber, currentWave)); + log.info("spawn number: " + spawnNumber + " on wave " + currentWave); + } + } + } + + @Subscribe + public void onHitsplatApplied(HitsplatApplied hitsplatApplied) + { + Actor actor = hitsplatApplied.getActor(); + + if (healers.isEmpty() && !(actor instanceof NPC) && lastInteracted == null) + { + return; + } + + for (Healer healer : healers.values()) + { + if (healer.getNpc() == actor && actor == lastInteracted) + { + healer.setFoodRemaining(healer.getFoodRemaining() - 1); + } + } + } + + @Subscribe + public void onNpcDespawned(NpcDespawned event) + { + if (healers.remove(event.getNpc()) != null && healers.isEmpty()) + { + healers.clear(); + } + } + + @Subscribe + public void onInteractingChanged(InteractingChanged event) + { + Actor opponent = event.getTarget(); + + if (opponent != null && opponent instanceof NPC && isNpcHealer(((NPC) opponent).getId()) && event.getSource() != client.getLocalPlayer()) + { + lastInteracted = opponent; + } + } + + public static boolean isNpcHealer(int npcId) + { + return npcId == NpcID.PENANCE_HEALER || + npcId == NpcID.PENANCE_HEALER_5766 || + npcId == NpcID.PENANCE_HEALER_5767 || + npcId == NpcID.PENANCE_HEALER_5768 || + npcId == NpcID.PENANCE_HEALER_5769 || + npcId == NpcID.PENANCE_HEALER_5770 || + npcId == NpcID.PENANCE_HEALER_5771 || + npcId == NpcID.PENANCE_HEALER_5772 || + npcId == NpcID.PENANCE_HEALER_5773 || + npcId == NpcID.PENANCE_HEALER_5774; + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + if (config.calls() && getWidget() != null && event.getTarget().endsWith("horn") && !event.getTarget().contains("Unicorn")) + { + MenuEntry[] menuEntries = client.getMenuEntries(); + Widget callWidget = getWidget(); + String call = Calls.getOption(callWidget.getText()); + MenuEntry correctCall = null; + + entries.clear(); + for (MenuEntry entry : menuEntries) + { + String option = entry.getOption(); + if (option.equals(call)) + { + correctCall = entry; + } + else if (!option.startsWith("Tell-")) + { + entries.add(entry); + } + } + + if (correctCall != null) //&& callWidget.getTextColor()==16316664) + { + entries.add(correctCall); + client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()])); + } + } + else if (config.calls() && event.getTarget().endsWith("horn")) + { + entries.clear(); + client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()])); + } + + String option = Text.removeTags(event.getOption()).toLowerCase(); + String target = Text.removeTags(event.getTarget()).toLowerCase(); + + if (config.swapLadder() && option.equals("climb-down") && target.equals("ladder")) + { + swap("quick-start", option, target, true); + } + + if (inGameBit == 1 && config.healerMenuOption() && event.getTarget().contains("Penance Healer")) + { + + MenuEntry[] menuEntries = client.getMenuEntries(); + MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; + String targett = lastEntry.getTarget(); + + if (foodPressed.containsKey(lastEntry.getIdentifier())) + { + lastEntry.setTarget(lastEntry.getTarget().split("\\(")[0] + "(" + Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() + ")"); + if (Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() > 20) + { + lastEntry.setTarget(lastEntry.getTarget().replace("", "")); + } + } + else + { + lastEntry.setTarget(targett.replace("", "")); + + } + + client.setMenuEntries(menuEntries); + } + + if (client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT) != null && inGameBit == 1 && config.eggBoi() && event.getTarget().endsWith("egg") && shiftDown) + { + String[] currentCall = client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT).getText().split(" "); + log.info("1 " + currentCall[0]); + MenuEntry[] menuEntries = client.getMenuEntries(); + MenuEntry correctEgg = null; + entries.clear(); + + for (MenuEntry entry : menuEntries) + { + if (entry.getTarget().contains(currentCall[0]) && entry.getOption().equals("Take")) + { + correctEgg = entry; + } + } + if (correctEgg != null) + { + entries.add(correctEgg); + client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()])); + } + } + + if (client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT) != null && inGameBit == 1 && config.osHelp() && event.getTarget().equals("Healer item machine") && shiftDown) + { + String[] currentCall = client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT).getText().split(" "); + + if (!currentCall[0].contains("Pois.")) + { + return; + } + + MenuEntry[] menuEntries = client.getMenuEntries(); + MenuEntry correctEgg = null; + entries.clear(); + + for (MenuEntry entry : menuEntries) + { + if (entry.getOption().equals("Take-" + currentCall[1])) + { + correctEgg = entry; + } + } + if (correctEgg != null) + { + entries.add(correctEgg); + client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()])); + } + } + } + + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked event) + { + if (!config.healerMenuOption() || !event.getMenuTarget().contains("Penance Healer") || client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) == null) + { + return; + } + + String currentCall = client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT).getText(); + String target = event.getMenuTarget(); + + if ((currentCall.equals("Pois. Worms") && (target.contains("Poisoned worms") && target.contains("->") && target.contains("Penance Healer"))) + || (currentCall.equals("Pois. Meat") && (target.contains("Poisoned meat") && target.contains("->") && target.contains("Penance Healer"))) + || (currentCall.equals("Pois. Tofu") && (target.contains("Poisoned tofu") && target.contains("->") && target.contains("Penance Healer")))) + { + foodPressed.put(event.getId(), Instant.now()); + } + + if (target.contains("->") && target.contains("Penance Healer")) + { + foodPressed.put(event.getId(), Instant.now()); + } + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (config.antiDrag()) + { + client.setInventoryDragDelay(config.antiDragDelay()); + } + } + + + private void addCounter() + { + if (!config.defTimer() || counter != null) + { + return; + } + + int itemSpriteId = ItemID.FIGHTER_TORSO; + + BufferedImage taskImg = itemManager.getImage(itemSpriteId); + counter = new CycleCounter(taskImg, this, tickNum); + + infoBoxManager.addInfoBox(counter); + } + + private void removeCounter() + { + if (counter == null) + { + return; + } + + infoBoxManager.removeInfoBox(counter); + counter = null; + } + + private void swap(String optionA, String optionB, String target, boolean strict) + { + MenuEntry[] entries = client.getMenuEntries(); + + int idxA = searchIndex(entries, optionA, target, strict); + int idxB = searchIndex(entries, optionB, target, strict); + + if (idxA >= 0 && idxB >= 0) + { + MenuEntry entry = entries[idxA]; + entries[idxA] = entries[idxB]; + entries[idxB] = entry; + + client.setMenuEntries(entries); + } + } + + private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict) + { + for (int i = entries.length - 1; i >= 0; i--) + { + MenuEntry entry = entries[i]; + String entryOption = Text.removeTags(entry.getOption()).toLowerCase(); + String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase(); + + if (strict) + { + if (entryOption.equals(option) && entryTarget.equals(target)) + { + return i; + } + } + else + { + if (entryOption.contains(option.toLowerCase()) && entryTarget.equals(target)) + { + return i; + } + } + } + + return -1; + } + + private static WorldPoint rotate(WorldPoint point, int rotation) + { + int chunkX = point.getX() & ~(CHUNK_SIZE - 1); + int chunkY = point.getY() & ~(CHUNK_SIZE - 1); + int x = point.getX() & (CHUNK_SIZE - 1); + int y = point.getY() & (CHUNK_SIZE - 1); + switch (rotation) + { + case 1: + return new WorldPoint(chunkX + y, chunkY + (CHUNK_SIZE - 1 - x), point.getPlane()); + case 2: + return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - x), chunkY + (CHUNK_SIZE - 1 - y), point.getPlane()); + case 3: + return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - y), chunkY + x, point.getPlane()); + } + return point; + } + + private boolean checkNewSpawn(NPC npc) + { + int regionId = 7509; + int regionX = 42; + int regionY = 46; + int z = 0; + + // world point of the tile marker + WorldPoint worldPoint = new WorldPoint( + ((regionId >>> 8) << 6) + regionX, + ((regionId & 0xff) << 6) + regionY, + z + ); + + int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks(); + for (int x = 0; x < instanceTemplateChunks[z].length; ++x) + { + for (int y = 0; y < instanceTemplateChunks[z][x].length; ++y) + { + int chunkData = instanceTemplateChunks[z][x][y]; + int rotation = chunkData >> 1 & 0x3; + int templateChunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE; + int templateChunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE; + if (worldPoint.getX() >= templateChunkX && worldPoint.getX() < templateChunkX + CHUNK_SIZE + && worldPoint.getY() >= templateChunkY && worldPoint.getY() < templateChunkY + CHUNK_SIZE) + { + WorldPoint p = new WorldPoint(client.getBaseX() + x * CHUNK_SIZE + (worldPoint.getX() & (CHUNK_SIZE - 1)), + client.getBaseY() + y * CHUNK_SIZE + (worldPoint.getY() & (CHUNK_SIZE - 1)), + worldPoint.getPlane()); + p = rotate(p, rotation); + if (p.distanceTo(npc.getWorldLocation()) < 5) + { + return true; + } + } + } + } + return false; + } + + @Override + public void keyTyped(KeyEvent e) + { + } + + @Override + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_SHIFT) + { + shiftDown = true; + } + } + + @Override + public void keyReleased(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_SHIFT) + { + shiftDown = false; + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/Calls.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/Calls.java new file mode 100644 index 0000000000..0c273f5be5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/batools/Calls.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018, Cameron + * 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.batools; + +import java.util.HashMap; +import java.util.Map; + +public enum Calls +{ + //Attacker Calls + RED_EGG("Red egg", "Tell-red"), + GREEN_EGG("Green egg", "Tell-green"), + BLUE_EGG("Blue egg", "Tell-blue"), + //Collector Calls + CONTROLLED("Controlled/Bullet/Wind", "Tell-controlled"), + ACCURATE("Accurate/Field/Water", "Tell-accurate"), + AGGRESSIVE("Aggressive/Blunt/Earth", "Tell-aggressive"), + DEFENSIVE("Defensive/Barbed/Fire", "Tell-defensive"), + //Healer Calls + TOFU("Tofu", "Tell-tofu"), + CRACKERS("Crackers", "Tell-crackers"), + WORMS("Worms", "Tell-worms"), + //Defender Calls + POIS_WORMS("Pois. Worms", "Tell-worms"), + POIS_TOFU("Pois. Tofu", "Tell-tofu"), + POIS_MEAT("Pois. Meat", "Tell-meat"); + + private final String call; + private final String option; + + private static final Map CALL_MENU = new HashMap<>(); + + static + { + for (Calls s : values()) + { + CALL_MENU.put(s.getCall(), s.getOption()); + } + } + + Calls(String call, String option) + { + this.call = call; + this.option = option; + } + + public String getCall() + { + return call; + } + + public String getOption() + { + return option; + } + + public static String getOption(String call) + { + return CALL_MENU.get(call); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/CycleCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/CycleCounter.java new file mode 100644 index 0000000000..e8f6e3e639 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/batools/CycleCounter.java @@ -0,0 +1,14 @@ +package net.runelite.client.plugins.batools; + +import net.runelite.client.plugins.Plugin; +import net.runelite.client.ui.overlay.infobox.Counter; + +import java.awt.image.BufferedImage; + +public class CycleCounter extends Counter +{ + public CycleCounter(BufferedImage img, Plugin plugin, int tick) + { + super(img, plugin, tick); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/Healer.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/Healer.java new file mode 100644 index 0000000000..9fb07e90e8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/batools/Healer.java @@ -0,0 +1,84 @@ +package net.runelite.client.plugins.batools; + + +import lombok.Getter; +import lombok.Setter; + +import net.runelite.api.NPC; +import net.runelite.api.Actor; + + +public class Healer +{ + + @Getter + private NPC npc; + + @Getter + @Setter + private int wave; + + @Getter + @Setter + private int spawnNumber; + + @Getter + @Setter + private int foodRemaining; + + @Getter + @Setter + private int lastFoodTime; + + @Getter + @Setter + private int firstCallFood; + + @Getter + @Setter + private int secondCallFood; + + + + public Healer(NPC npc, int spawnNumber, int wave) + { + this.npc = npc; + this.wave = wave; + this.spawnNumber = spawnNumber; + this.firstCallFood = getCode(wave).getFirstCallFood()[spawnNumber]; + this.secondCallFood = getCode(wave).getSecondCallFood()[spawnNumber]; + this.foodRemaining = firstCallFood + secondCallFood; + this.lastFoodTime = getCode(wave).getSpacing()[spawnNumber]; + } + + private HealerCode getCode(int wave) + { + switch(wave) + { + case 1: + return HealerCode.WAVEONE; + case 2: + return HealerCode.WAVETWO; + case 3: + return HealerCode.WAVETHREE; + case 4: + return HealerCode.WAVEFOUR; + case 5: + return HealerCode.WAVEFIVE; + case 6: + return HealerCode.WAVESIX; + case 7: + return HealerCode.WAVESEVEN; + case 8: + return HealerCode.WAVEEIGHT; + case 9: + return HealerCode.WAVENINE; + case 10: + return HealerCode.WAVETEN; + default: return null; + } + } + + + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/batools/HealerCode.java b/runelite-client/src/main/java/net/runelite/client/plugins/batools/HealerCode.java new file mode 100644 index 0000000000..ee7f492585 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/batools/HealerCode.java @@ -0,0 +1,34 @@ +package net.runelite.client.plugins.batools; + +import lombok.Getter; + + +enum HealerCode +{ + + WAVEONE(new int[] {1,1}, new int[] {0,0}, new int[] {0,0}), + WAVETWO(new int[] {1,1,2}, new int[] {0,0,0}, new int[] {0,0,21}), + WAVETHREE(new int[] {1,6,2}, new int[] {0,0,0}, new int[] {0,0,0}), + WAVEFOUR(new int[] {2,5,2,0}, new int[] {0,0,7,10}, new int[] {0,0,0,0}), + WAVEFIVE(new int[] {2,5,2,3,0}, new int[] {0,0,0,0,7}, new int[] {0,0,21,30,0}), + WAVESIX(new int[] {3,5,3,1,0,0}, new int[] {0,0,0,2,9,10}, new int[] {18,0,0,0,0,0}), + WAVESEVEN(new int[] {5,2,1,1,0,0,0}, new int[] {0,0,0,0,6,8,10}, new int[] {27,33,0,0,51,0,0}), + WAVEEIGHT(new int[] {2,8,1,1,0,0,0}, new int[] {1,0,1,1,3,1,10}, new int[] {36,0,33,39,45,48,0}), + WAVENINE(new int[] {2,8,1,1,0,0,0,0}, new int[] {1,1,1,1,1,1,1,10}, new int[] {0,21,0,0,0,0,0,0,0}), + WAVETEN(new int[] {5,2,1,1,0,0,0}, new int[] {0,1,1,1,3,3,10}, new int[] {27,33,0,0,51,0,0}); + + + @Getter + private final int[] firstCallFood; + @Getter + private final int[] secondCallFood; + @Getter + private final int[] spacing; + + HealerCode(int[] firstCallFood, int[] secondCallFood, int[] spacing) + { + this.firstCallFood = firstCallFood; + this.secondCallFood = secondCallFood; + this.spacing = spacing; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeConfig.java new file mode 100644 index 0000000000..3f2d8da467 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeConfig.java @@ -0,0 +1,168 @@ +package net.runelite.client.plugins.clanmanmode; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("clanmanmode") +public interface ClanManModeConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "highlightattackable", + name = "Highlight attackable targets", + description = "Highlights targets attackable by all clan members" + ) + default boolean highlightAttackable() + { + return false; + } + + @ConfigItem( + position = 1, + keyName = "attackablecolor", + name = "Attackable target c olor", + description = "Color of targets all clan members can target" + ) + default Color getAttackableColor() + { + return new Color(0, 184, 212); + } + + @ConfigItem( + position = 2, + keyName = "highlightattacked", + name = "Highlight clan targets", + description = "Highlights people being attacked by your clan" + ) + default boolean highlightAttacked() + { + return false; + } + + @ConfigItem( + position = 3, + keyName = "attackedcolor", + name = "Clan target color", + description = "Color of players being attacked by clan" + ) + default Color getClanAttackableColor() + { + return new Color(0, 184, 212); + } + + @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 = "drawOverheadPlayerNames", + name = "Draw names above players", + description = "Configures whether or not player names should be drawn above players" + ) + default boolean drawOverheadPlayerNames() + { + return true; + } + + @ConfigItem( + position = 6, + keyName = "drawMinimapNames", + name = "Draw names on minimap", + description = "Configures whether or not minimap names for players with rendered names should be drawn" + ) + default boolean drawMinimapNames() + { + return false; + } + + @ConfigItem( + position = 7, + keyName = "showtargets", + name = "Highlight My Attackers", + description = "Shows players interacting with you" + ) + default boolean showAttackers() + { + return false; + } + + @ConfigItem( + position = 8, + keyName = "attackcolor", + name = "Attacker Color", + description = "Color of attackers" + ) + default Color getAttackerColor() + { + return new Color(255, 0, 0); + } + + @ConfigItem( + position = 9, + keyName = "showbold", + name = "Bold names of clan targets", + description = "Turns names of clan targets bold" + ) + default boolean ShowBold() { return false; } + + @ConfigItem( + position = 10, + keyName = "hideafter", + name = "Hide attackable targets after login", + description = "Automatically disables attackable player highlighting after login" + ) + default boolean hideAttackable() { return false; } + + @ConfigItem( + position = 11, + keyName = "hidetime", + name = "Ticks to hide", + description = "How many ticks after you are logged in that attackbles are hidden (1 tick = 0.6 seconds)" + ) + default int hideTime() { return 5; } + + @ConfigItem( + position = 12, + keyName = "mycblvl", + name = "Calc targets on my own combat level", + description = "Calculates potential targets based off your own combat lvl instead of clans" + ) + default boolean CalcSelfCB() { return false; } + + @ConfigItem( + position = 13, + keyName = "hideatkopt", + name = "Hide attack option for clan members", + description = "Disables attack option for clan members" + ) + default boolean hideAtkOpt() { return false; } + + @ConfigItem( + position = 14, + keyName = "showclanmembers", + name = "Persistent Clan Members", + description = "Will highlight clan members even when not in clan chat" + ) + default boolean PersistentClan() { return false; } + + @ConfigItem( + position = 15, + keyName = "clancolor", + name = "Clan Member Color", + description = "Color of clan members" + ) + default Color getClanMemberColor() + { + return new Color(255, 0, 0); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeMinimapOverlay.java new file mode 100644 index 0000000000..be94ee06f3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeMinimapOverlay.java @@ -0,0 +1,52 @@ +package net.runelite.client.plugins.clanmanmode; + +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 ClanManModeMinimapOverlay extends Overlay +{ + private final ClanManModeService ClanManModeService; + private final ClanManModeConfig config; + + @Inject + private ClanManModeMinimapOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService) + { + this.config = config; + this.ClanManModeService = ClanManModeService; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + ClanManModeService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); + return null; + } + + private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) + { + final String name = actor.getName().replace('\u00A0', ' '); + + if (config.drawMinimapNames()) + { + final net.runelite.api.Point minimapLocation = actor.getMinimapLocation(); + + if (minimapLocation != null) + { + OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeOverlay.java new file mode 100644 index 0000000000..ff058f675c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeOverlay.java @@ -0,0 +1,63 @@ +package net.runelite.client.plugins.clanmanmode; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import javax.inject.Inject; +import javax.inject.Singleton; +import net.runelite.api.ClanMemberRank; +import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.client.game.ClanManager; +import net.runelite.client.ui.FontManager; +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 ClanManModeOverlay extends Overlay +{ + private final ClanManModeService ClanManModeService; + private final ClanManModeConfig config; + private final ClanManager clanManager; + + @Inject + private ClanManModeOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService, + ClanManager clanManager) + { + this.config = config; + this.ClanManModeService = ClanManModeService; + this.clanManager = clanManager; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.MED); + } + + @Override + public Dimension render(Graphics2D graphics) + { + ClanManModeService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); + return null; + } + + private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) + { + if (!config.drawOverheadPlayerNames()) + { + return; + } + + String name = actor.getName().replace('\u00A0', ' '); + int offset = actor.getLogicalHeight() + 40; + Point textLocation = actor.getCanvasTextLocation(graphics, name, offset); + + if (textLocation != null) + { + if (config.getClanAttackableColor().equals(color) && config.ShowBold()) { + graphics.setFont(FontManager.getRunescapeBoldFont()); + } + OverlayUtil.renderTextLocation(graphics, textLocation, name, color); + } + } +} 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 new file mode 100644 index 0000000000..d71d054674 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java @@ -0,0 +1,137 @@ +package net.runelite.client.plugins.clanmanmode; + +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.inject.Inject; +import net.runelite.api.*; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.ClanManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.Text; +import org.apache.commons.lang3.ArrayUtils; + +@PluginDescriptor( + name = "!Clan Man Mode", + description = "Assists in clan PVP scenarios", + tags = {"highlight", "minimap", "overlay", "players"} +) +public class ClanManModePlugin extends Plugin +{ + @Inject + private OverlayManager overlayManager; + + @Inject + private ClanManModeConfig config; + + @Inject + private ClanManModeOverlay ClanManModeOverlay; + + @Inject + private ClanManModeTileOverlay ClanManModeTileOverlay; + + @Inject + private ClanManModeMinimapOverlay ClanManModeMinimapOverlay; + + @Inject + private Client client; + + @Inject + private ClanManager clanManager; + + @Provides + ClanManModeConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(ClanManModeConfig.class); + } + + int wildernessLevel; + int clanmin; + int clanmax; + int inwildy; + int ticks; + Map clan = new HashMap<>(); + + @Override + protected void startUp() throws Exception { + overlayManager.add(ClanManModeOverlay); + overlayManager.add(ClanManModeTileOverlay); + overlayManager.add(ClanManModeMinimapOverlay); + } + + @Override + protected void shutDown() throws Exception { + overlayManager.remove(ClanManModeOverlay); + overlayManager.remove(ClanManModeTileOverlay); + overlayManager.remove(ClanManModeMinimapOverlay); + clan.clear(); + ticks = 0; + wildernessLevel = 0; + clanmin = 0; + clanmax = 0; + inwildy = 0; + } + + @Subscribe + public void onGameStateChanged(GameStateChanged gameStateChanged) { + if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN || gameStateChanged.getGameState() == GameState.HOPPING) { + ticks = 0; + } + } + + @Subscribe + public void onGameTick(GameTick event) { + ticks++; + final Player localPlayer = client.getLocalPlayer(); + if (!clan.containsKey(localPlayer.getName())) { + clan.put(localPlayer.getName(), localPlayer.getCombatLevel()); + } + WorldPoint a = localPlayer.getWorldLocation(); + int underLevel = ((a.getY() - 9920) / 8) + 1; + int upperLevel = ((a.getY() - 3520) / 8) + 1; + wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel; + inwildy = client.getVar(Varbits.IN_WILDERNESS); + if (clan.size() > 0) { + clanmin = Collections.min(clan.values()); + clanmax = Collections.max(clan.values()); + } + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) { + if (!config.hideAtkOpt()) { + return; + } + if (client.getGameState() != GameState.LOGGED_IN) { + return; + } + + final String option = Text.removeTags(event.getOption()).toLowerCase(); + + if (option.equals("attack")) { + final Pattern ppattern = Pattern.compile("(.+?) interactors = new HashMap<>(); + + public void forEachPlayer(final BiConsumer consumer) + { + int minatk = plugin.clanmax - plugin.wildernessLevel; + int maxatk = plugin.clanmin + plugin.wildernessLevel; + final Player localPlayer = client.getLocalPlayer(); + final String localName = localPlayer.getName(); + int selfmin = localPlayer.getCombatLevel() - plugin.wildernessLevel; + int selfmax = localPlayer.getCombatLevel() + plugin.wildernessLevel; + for (Player player : client.getPlayers()) + { + if (player == null || player.getName() == null) { + continue; + } + + if (player == localPlayer) { + continue; + } + + boolean isClanMember = player.isClanMember(); + Actor interacting = player.getInteracting(); + Player interactor = null; + if (interacting != null && !(interacting instanceof NPC)) { + interactor = ((Player) interacting); + } + + if (config.showAttackers()) { + if (interactor != null) { + if (interactor.getName().equals(localName)) { + consumer.accept(player, config.getAttackerColor()); + } + } + } + + if (plugin.inwildy == 1) { + if (isClanMember) { + if (!plugin.clan.containsKey(player.getName())) { + plugin.clan.put(player.getName(), player.getCombatLevel()); + } + if (config.highlightAttacked()) { + if (interactor != null) { + if (!interactors.containsKey(interactor.getName())) { + WorldPoint a = interactor.getWorldLocation(); + int underLevel = ((a.getY() - 9920) / 8) + 1; + int upperLevel = ((a.getY() - 3520) / 8) + 1; + int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel; + int wildydiff = plugin.wildernessLevel - wildernessLevel; + if (wildydiff < 0) { + wildydiff = 0; + } + if (config.CalcSelfCB()) { + if (interacting.getCombatLevel() <= selfmax && interacting.getCombatLevel() - wildydiff >= selfmin && !interactor.isClanMember()) { + interactors.put(interactor.getName(), player.getName()); + consumer.accept(interactor, config.getClanAttackableColor()); + } + } else { + if (interacting.getCombatLevel() <= maxatk && interacting.getCombatLevel() - wildydiff >= minatk && !interactor.isClanMember()) { + interactors.put(interactor.getName(), player.getName()); + consumer.accept(interactor, config.getClanAttackableColor()); + } + } + } + } + } + } else { + if (config.PersistentClan()) { + if (plugin.clan.containsKey(player.getName())) { + consumer.accept(player, config.getClanMemberColor()); + } + } + if (config.highlightAttacked()) { + if (interactors.containsKey(player.getName())) { + String attackername = interactors.get(player.getName()); + Boolean found = false; + for (Player attacker : client.getPlayers()) { + if (attacker == null || attacker.getName() == null) { + continue; + } + if (attacker.getName().equals(attackername)) { + found = true; + Actor ainteract = attacker.getInteracting(); + if (ainteract != null) { + if (ainteract.getName().equals(player.getName())) { + consumer.accept(player, config.getClanAttackableColor()); + } else { + interactors.remove(player.getName()); + } + } else { + interactors.remove(player.getName()); + } + break; + } + } + if (!found) { + interactors.remove(player.getName()); + } + continue; + } + } + if (config.highlightAttackable()) { + if ((config.hideAttackable() && plugin.ticks >= config.hideTime()) || plugin.clan.containsKey(player.getName())) { + continue; + } + WorldPoint a = player.getWorldLocation(); + int underLevel = ((a.getY() - 9920) / 8) + 1; + int upperLevel = ((a.getY() - 3520) / 8) + 1; + int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel; + int wildydiff = plugin.wildernessLevel - wildernessLevel; + if (wildydiff < 0) { + wildydiff = 0; + } + if (config.CalcSelfCB()) { + if (player.getCombatLevel() <= selfmax && player.getCombatLevel() - wildydiff >= selfmin) { + consumer.accept(player, config.getAttackableColor()); + } + } else { + if (player.getCombatLevel() <= maxatk && player.getCombatLevel() - wildydiff >= minatk) { + consumer.accept(player, config.getAttackableColor()); + } + } + } + } + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeTileOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeTileOverlay.java new file mode 100644 index 0000000000..5aea2e108f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModeTileOverlay.java @@ -0,0 +1,48 @@ +package net.runelite.client.plugins.clanmanmode; + +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 ClanManModeTileOverlay extends Overlay +{ + private final ClanManModeService ClanManModeService; + private final ClanManModeConfig config; + + @Inject + private ClanManModeTileOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService) + { + this.config = config; + this.ClanManModeService = ClanManModeService; + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.MED); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!config.drawTiles()) + { + return null; + } + + ClanManModeService.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/equipmentinspector/EquipmentInspectorConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java new file mode 100644 index 0000000000..98392d4539 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017, Aria + * 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.equipmentinspector; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.plugins.grounditems.config.ItemHighlightMode; +import net.runelite.client.plugins.grounditems.config.MenuHighlightMode; +import net.runelite.client.plugins.grounditems.config.PriceDisplayMode; + +@ConfigGroup("grounditems") +public interface EquipmentInspectorConfig extends Config +{ + @ConfigItem( + keyName = "ShowValue", + name = "Show the total value of the items", + description = "shows the total value of the items", + position = 1 + ) + default boolean ShowValue() + { + return true; + } + @ConfigItem( + keyName = "protecteditems", + name = "# of protected items", + description = "Limit 4", + position = 2 + ) + default int protecteditems() + { return 1; } + @ConfigItem( + keyName = "ExactValue", + name = "Show exact value", + description = "shows the excact gp value", + position = 3 + ) + default boolean ExactValue() + { return false; } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java new file mode 100644 index 0000000000..e630c28b4f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java @@ -0,0 +1,98 @@ +package net.runelite.client.plugins.equipmentinspector; + +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.ItemComposition; +import net.runelite.api.kit.KitType; +import net.runelite.client.game.AsyncBufferedImage; +import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.PluginPanel; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.swing.*; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Singleton +public class EquipmentInspectorPanel extends PluginPanel +{ + private final static String NO_PLAYER_SELECTED = "No player selected"; + + private GridBagConstraints c; + private JPanel equipmentPanels; + private JPanel header; + private JLabel nameLabel; + + @Inject + private ItemManager itemManager; + + public EquipmentInspectorPanel() + { + GroupLayout layout = new GroupLayout(this); + setLayout(layout); + setBorder(new EmptyBorder(10, 10, 10, 10)); + setBackground(ColorScheme.DARK_GRAY_COLOR); + + equipmentPanels = new JPanel(new GridBagLayout()); + c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.gridx = 0; + c.gridy = 0; + + header = new JPanel(); + header.setLayout(new BorderLayout()); + header.setBorder(new CompoundBorder( + BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(58, 58, 58)), + BorderFactory.createEmptyBorder(0, 0, 10, 0))); + + nameLabel = new JLabel(NO_PLAYER_SELECTED); + nameLabel.setForeground(Color.WHITE); + + header.add(nameLabel, BorderLayout.CENTER); + + layout.setHorizontalGroup(layout.createParallelGroup() + .addComponent(equipmentPanels) + .addComponent(header) + ); + layout.setVerticalGroup(layout.createSequentialGroup() + .addComponent(header) + .addGap(10) + .addComponent(equipmentPanels) + ); + + update(new HashMap<>(), ""); + } + + public void update(Map playerEquipment, String playerName) + { + if (playerName.isEmpty() || playerName == null) + { + nameLabel.setText(NO_PLAYER_SELECTED); + } + else + { + nameLabel.setText("Player: " + playerName); + } + + SwingUtilities.invokeLater(() -> + { + equipmentPanels.removeAll(); + playerEquipment.forEach((kitType, itemComposition) -> + { + AsyncBufferedImage itemImage = itemManager.getImage(itemComposition.getId()); + equipmentPanels.add(new ItemPanel(itemComposition, kitType, itemImage), c); + c.gridy++; + + }); + header.revalidate(); + header.repaint(); + } + ); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..8af1567609 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java @@ -0,0 +1,240 @@ +package net.runelite.client.plugins.equipmentinspector; + + +import com.google.inject.Provides; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; +import net.runelite.api.events.PlayerMenuOptionClicked; +import net.runelite.api.kit.KitType; +import net.runelite.client.chat.ChatColorType; +import net.runelite.client.chat.ChatMessageBuilder; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; +import net.runelite.client.menus.MenuManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.ClientToolbar; +import net.runelite.client.ui.NavigationButton; +import net.runelite.client.util.Text; +import net.runelite.http.api.item.ItemPrice; + +import javax.annotation.Nullable; +import javax.imageio.ImageIO; +import javax.inject.Inject; +import javax.swing.*; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import java.text.NumberFormat; +import java.util.*; +import java.util.concurrent.ScheduledExecutorService; + +@PluginDescriptor( + name = "!Equipment Inspector", + enabledByDefault = false +) + +@Slf4j + +public class EquipmentInspectorPlugin extends Plugin { + + private static final String INSPECT_EQUIPMENT = "Gear"; + private static final String KICK_OPTION = "Kick"; + + @Inject + @Nullable + private Client client; + + @Inject + private ItemManager itemManager; + + @Inject + private EquipmentInspectorConfig config; + + @Inject + private ChatMessageManager chatMessageManager; + @Inject + private MenuManager menuManager; + + @Inject + private ScheduledExecutorService executor; + + @Inject + private ClientToolbar pluginToolbar; + + @Provides + EquipmentInspectorConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(EquipmentInspectorConfig.class); + } + + private NavigationButton navButton; + private EquipmentInspectorPanel equipmentInspectorPanel; + private int TotalPrice = 0; + private int Prot1 = 0; + private int Prot2 = 0; + private int Prot3 = 0; + private int Prot4 = 0; + + + @Override + protected void startUp() throws Exception + { + + equipmentInspectorPanel = injector.getInstance(EquipmentInspectorPanel.class); + if(client != null) { + menuManager.addPlayerMenuItem(INSPECT_EQUIPMENT); + } + + BufferedImage icon; + synchronized (ImageIO.class) + { + icon = ImageIO.read(getClass().getResourceAsStream("normal.png")); + } + + navButton = NavigationButton.builder() + .tooltip("Equipment Inspector") + .icon(icon) + .priority(5) + .panel(equipmentInspectorPanel) + .build(); + + + pluginToolbar.addNavigation(navButton); + + } + + @Override + protected void shutDown() throws Exception + { + + menuManager.removePlayerMenuItem(INSPECT_EQUIPMENT); + } + + @Subscribe + public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + { + if (event.getMenuOption().equals(INSPECT_EQUIPMENT)) + { + + + executor.execute(() -> + { + try + { + SwingUtilities.invokeAndWait(() -> + { + if (!navButton.isSelected()) + { + navButton.getOnSelect().run(); + } + }); + } + catch (InterruptedException | InvocationTargetException e) + { + + throw new RuntimeException(e); + + } + String playerName = Text.removeTags(event.getMenuTarget()); + // The player menu uses a non-breaking space in the player name, we need to replace this to compare + // against the playerName in the player cache. + String finalPlayerName = playerName.replace('\u00A0', ' '); + System.out.println(finalPlayerName); + List players = client.getPlayers(); + Optional targetPlayer = players.stream() + .filter(Objects::nonNull) + .filter(p -> p.getName().equals(finalPlayerName)).findFirst(); + + if (targetPlayer.isPresent()) + { + TotalPrice = 0; + Prot1 = 0; + Prot2 = 0; + Prot3 = 0; + Prot4 = 0; + Player p = targetPlayer.get(); + Map playerEquipment = new HashMap<>(); + + for (KitType kitType : KitType.values()) + { + int itemId = p.getPlayerComposition().getEquipmentId(kitType); + if (itemId != -1) + { + ItemComposition itemComposition = client.getItemDefinition(itemId); + playerEquipment.put(kitType, itemComposition); + int ItemPrice = itemManager.getItemPrice(itemId); + TotalPrice += ItemPrice; + if (ItemPrice > Prot1 ) { + Prot4 = Prot3; + Prot3 = Prot2; + Prot2 = Prot1; + + Prot1 = ItemPrice; + } else if (ItemPrice > Prot2){ + Prot4 = Prot3; + Prot3 = Prot2; + Prot2 = ItemPrice; + } else if (ItemPrice > Prot3){ + Prot4 = Prot3; + Prot3 = ItemPrice; + } else if (ItemPrice > Prot4){ + Prot4 = ItemPrice; + } + } + } + int IgnoredItems = config.protecteditems(); + if (IgnoredItems != 0 && IgnoredItems != 1 && IgnoredItems != 2 && IgnoredItems != 3) { + IgnoredItems = 4; + + } + if (config.ShowValue()) { + switch (IgnoredItems) { + case 1: + TotalPrice = TotalPrice - Prot1; + break; + case 2: + TotalPrice = TotalPrice - Prot1; + TotalPrice = TotalPrice - Prot2; + + break; + case 3: + TotalPrice = TotalPrice - Prot1; + TotalPrice = TotalPrice - Prot2; + TotalPrice = TotalPrice - Prot3; + break; + case 4: + TotalPrice = TotalPrice - Prot1; + TotalPrice = TotalPrice - Prot2; + TotalPrice = TotalPrice - Prot3; + TotalPrice = TotalPrice - Prot4; + break; + } + String StringPrice = ""; + if (!config.ExactValue()) { + TotalPrice = TotalPrice / 1000; + StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); + StringPrice = StringPrice + 'K'; + } + if (config.ExactValue()) { + StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); + } + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.FRIENDSCHATNOTIFICATION) + .runeLiteFormattedMessage(new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append("Risked Value: ") + .append(ChatColorType.NORMAL) + .append(StringPrice) + .build()) + .build()); + } + equipmentInspectorPanel.update(playerEquipment, playerName); + + } + }); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java new file mode 100644 index 0000000000..873bf058b6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java @@ -0,0 +1,52 @@ +package net.runelite.client.plugins.equipmentinspector; + +import net.runelite.api.ItemComposition; +import net.runelite.api.kit.KitType; +import net.runelite.client.game.AsyncBufferedImage; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.FontManager; +import org.apache.commons.lang3.StringUtils; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; + +class ItemPanel extends JPanel +{ + + ItemPanel(ItemComposition item, KitType kitType, AsyncBufferedImage icon) + { + setBorder(new EmptyBorder(3, 3, 3, 3)); + setBackground(ColorScheme.DARK_GRAY_COLOR); + + GroupLayout layout = new GroupLayout(this); + this.setLayout(layout); + + JLabel name = new JLabel(item.getName()); + + JLabel location = new JLabel(StringUtils.capitalize(kitType.toString().toLowerCase())); + location.setFont(FontManager.getRunescapeSmallFont()); + + JLabel imageLabel = new JLabel(); + icon.addTo(imageLabel); + + layout.setVerticalGroup(layout.createParallelGroup() + .addComponent(imageLabel) + .addGroup(layout.createSequentialGroup() + .addComponent(name) + .addComponent(location) + ) + ); + + layout.setHorizontalGroup(layout.createSequentialGroup() + .addComponent(imageLabel) + .addGap(8) + .addGroup(layout.createParallelGroup() + .addComponent(name) + .addComponent(location) + ) + ); + + // AWT's Z order is weird. This put image at the back of the stack + setComponentZOrder(imageLabel, getComponentCount() - 1); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/normal.png b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..613f95e46d5235a49ec0843faaa35384e9b0896b GIT binary patch literal 624 zcmV-$0+0QPP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0tHD#K~z{r?Uuhw z!$1_rUmcyLn~P8fmrQ~BGyq5#M;t!sDe|AI9PCT z5L;*0n(yTB<#Ji>Y`9Ti3&7jKIc7LRzA=EB!@v>HuhtrJNg@rXeB>M9M-je0Kgy>A zylh?sDMIn)l}ej(`+H8v(E%7b5cc-@C3nN&w2Fwp-R+IopcXQj3?*h0Vy~0lOgpUz zIPDlH0yrEs;AVPiQm$;Ucia462~d@01* literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperOverlay.java new file mode 100644 index 0000000000..3698b395c1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperOverlay.java @@ -0,0 +1,63 @@ +package net.runelite.client.plugins.fightcavejadhelper; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.SpriteID; +import net.runelite.client.game.SpriteManager; +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.components.ComponentConstants; +import net.runelite.client.ui.overlay.components.ImageComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +public class FightCaveJadHelperOverlay extends Overlay +{ + private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150); + + private final Client client; + private final FightCaveJadHelperPlugin plugin; + private final SpriteManager spriteManager; + private final PanelComponent imagePanelComponent = new PanelComponent(); + + @Inject + private FightCaveJadHelperOverlay(Client client, FightCaveJadHelperPlugin plugin, SpriteManager spriteManager) + { + setPosition(OverlayPosition.BOTTOM_RIGHT); + setPriority(OverlayPriority.HIGH); + this.client = client; + this.plugin = plugin; + this.spriteManager = spriteManager; + } + + @Override + public Dimension render(Graphics2D graphics) + { + final JadAttack attack = plugin.getAttack(); + + if (attack == null) + { + return null; + } + + final BufferedImage prayerImage = getPrayerImage(attack); + + imagePanelComponent.getChildren().clear(); + imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); + imagePanelComponent.setBackgroundColor(client.isPrayerActive(attack.getPrayer()) + ? ComponentConstants.STANDARD_BACKGROUND_COLOR + : NOT_ACTIVATED_BACKGROUND_COLOR); + + return imagePanelComponent.render(graphics); + } + + private BufferedImage getPrayerImage(JadAttack attack) + { + final int prayerSpriteID = attack == JadAttack.MAGIC ? SpriteID.PRAYER_PROTECT_FROM_MAGIC : SpriteID.PRAYER_PROTECT_FROM_MISSILES; + return spriteManager.getSprite(prayerSpriteID, 0); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..4eeb311101 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/FightCaveJadHelperPlugin.java @@ -0,0 +1,89 @@ +package net.runelite.client.plugins.fightcavejadhelper; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; +import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.NpcSpawned; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "!Fight Cave - Jad", + description = "Show what to pray against Jad", + tags = {"bosses", "combat", "minigame", "overlay", "prayer", "pve", "pvm"}, + enabledByDefault = false +) +public class FightCaveJadHelperPlugin extends Plugin +{ + @Inject + private OverlayManager overlayManager; + + @Inject + private FightCaveJadHelperOverlay overlay; + + @Getter(AccessLevel.PACKAGE) + @Nullable + private JadAttack attack; + + private NPC jad; + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + jad = null; + attack = null; + } + + @Subscribe + public void onNpcSpawned(final NpcSpawned event) + { + final int id = event.getNpc().getId(); + + if (id == NpcID.TZTOKJAD || id == NpcID.TZTOKJAD_6506) + { + jad = event.getNpc(); + } + } + + @Subscribe + public void onNpcDespawned(final NpcDespawned event) + { + if (jad == event.getNpc()) + { + jad = null; + attack = null; + } + } + + @Subscribe + public void onAnimationChanged(final AnimationChanged event) + { + if (event.getActor() != jad) + { + return; + } + + if (jad.getAnimation() == JadAttack.MAGIC.getAnimation()) + { + attack = JadAttack.MAGIC; + } + else if (jad.getAnimation() == JadAttack.RANGE.getAnimation()) + { + attack = JadAttack.RANGE; + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/JadAttack.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/JadAttack.java new file mode 100644 index 0000000000..9d9ec47a4b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavejadhelper/JadAttack.java @@ -0,0 +1,29 @@ +package net.runelite.client.plugins.fightcavejadhelper; + +import net.runelite.api.AnimationID; +import net.runelite.api.Prayer; + +public enum JadAttack +{ + MAGIC(AnimationID.TZTOK_JAD_MAGIC_ATTACK, Prayer.PROTECT_FROM_MAGIC), + RANGE(AnimationID.TZTOK_JAD_RANGE_ATTACK, Prayer.PROTECT_FROM_MISSILES); + + private final int animation; + private final Prayer prayer; + + JadAttack(int animation, Prayer prayer) + { + this.animation = animation; + this.prayer = prayer; + } + + public int getAnimation() + { + return animation; + } + + public Prayer getPrayer() + { + return prayer; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperConfig.java new file mode 100644 index 0000000000..989c4965e8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperConfig.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018, Jordan Atwood + * 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.fightcavewavehelper; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("Fight Cave - Wave Helper") +public interface FightCaveWaveHelperConfig extends Config +{ + @ConfigItem( + keyName = "waveDisplay", + name = "Wave display", + description = "Shows monsters that will spawn on the selected wave(s)." + ) + default WaveDisplayMode waveDisplay() + { + return WaveDisplayMode.BOTH; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..d06451a9d0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/FightCaveWaveHelperPlugin.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2018, Jordan Atwood + * 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.fightcavewavehelper; + +import com.google.inject.Provides; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.inject.Inject; +import lombok.Getter; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameStateChanged; +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.ui.overlay.OverlayManager; +import org.apache.commons.lang3.ArrayUtils; + +@PluginDescriptor( + 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"}, + enabledByDefault = false +) +public class FightCaveWaveHelperPlugin extends Plugin +{ + private static final Pattern WAVE_PATTERN = Pattern.compile(".*Wave: (\\d+).*"); + private static final int FIGHT_CAVE_REGION = 9551; + private static final int MAX_MONSTERS_OF_TYPE_PER_WAVE = 2; + + static final int MAX_WAVE = 63; + + @Getter + static final List> WAVES = new ArrayList<>(); + + @Getter + private int currentWave = -1; + + @Inject + private Client client; + + @Inject + private OverlayManager overlayManager; + + @Inject + private WaveOverlay waveOverlay; + + static + { + final WaveMonster[] waveMonsters = WaveMonster.values(); + + // Add wave 1, future waves are derived from its contents + final EnumMap waveOne = new EnumMap<>(WaveMonster.class); + waveOne.put(waveMonsters[0], 1); + WAVES.add(waveOne); + + for (int wave = 1; wave < MAX_WAVE; wave++) + { + final EnumMap prevWave = WAVES.get(wave - 1).clone(); + int maxMonsterOrdinal = -1; + + for (int i = 0; i < waveMonsters.length; i++) + { + final int ordinalMonsterQuantity = prevWave.getOrDefault(waveMonsters[i], 0); + + if (ordinalMonsterQuantity == MAX_MONSTERS_OF_TYPE_PER_WAVE) + { + maxMonsterOrdinal = i; + break; + } + } + + if (maxMonsterOrdinal >= 0) + { + prevWave.remove(waveMonsters[maxMonsterOrdinal]); + } + + final int addedMonsterOrdinal = maxMonsterOrdinal >= 0 ? maxMonsterOrdinal + 1 : 0; + final WaveMonster addedMonster = waveMonsters[addedMonsterOrdinal]; + final int addedMonsterQuantity = prevWave.getOrDefault(addedMonster, 0); + + prevWave.put(addedMonster, addedMonsterQuantity + 1); + + WAVES.add(prevWave); + } + } + + @Provides + FightCaveWaveHelperConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(FightCaveWaveHelperConfig.class); + } + + @Override + public void startUp() + { + overlayManager.add(waveOverlay); + } + + @Override + public void shutDown() + { + overlayManager.remove(waveOverlay); + currentWave = -1; + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() != GameState.LOGGED_IN) + { + return; + } + + if (!inFightCave()) + { + currentWave = -1; + } + } + + @Subscribe + public void onChatMessage(ChatMessage event) + { + final Matcher waveMatcher = WAVE_PATTERN.matcher(event.getMessage()); + + if (event.getType() != ChatMessageType.GAMEMESSAGE + || !inFightCave() + || !waveMatcher.matches()) + { + return; + } + + currentWave = Integer.parseInt(waveMatcher.group(1)); + } + + boolean inFightCave() + { + return ArrayUtils.contains(client.getMapRegions(), FIGHT_CAVE_REGION); + } + + static String formatMonsterQuantity(final WaveMonster monster, final int quantity) + { + return String.format("%dx %s", quantity, monster); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveDisplayMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveDisplayMode.java new file mode 100644 index 0000000000..79a9d8174e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveDisplayMode.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018, Jordan Atwood + * 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.fightcavewavehelper; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum WaveDisplayMode +{ + CURRENT("Current wave"), + NEXT("Next wave"), + BOTH("Both"); + + 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/fightcavewavehelper/WaveMonster.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveMonster.java new file mode 100644 index 0000000000..df2fa9b7af --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveMonster.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Jordan Atwood + * 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.fightcavewavehelper; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +enum WaveMonster +{ + TZ_KIH("Tz-Kih", 22), + TZ_KEK("Tz-Kek", 45), + TOK_XIL("Tok-Xil", 90), + YT_MEJKOT("Yt-MejKot", 180), + KET_ZEK("Ket-Zek", 360), + TZKOK_JAD("TzTok-Jad", 702); + + private final String name; + private final int level; + + @Override + public String toString() + { + return String.format("%s - Level %s", name, level); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveOverlay.java new file mode 100644 index 0000000000..b5e6878b02 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcavewavehelper/WaveOverlay.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2018, Jordan Atwood + * 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.fightcavewavehelper; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import net.runelite.client.ui.ColorScheme; +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; + +class WaveOverlay extends Overlay +{ + private static final Color HEADER_COLOR = ColorScheme.BRAND_ORANGE; + + private final FightCaveWaveHelperConfig config; + private final FightCaveWaveHelperPlugin plugin; + + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + private WaveOverlay(FightCaveWaveHelperConfig config, FightCaveWaveHelperPlugin plugin) + { + setPosition(OverlayPosition.TOP_RIGHT); + this.config = config; + this.plugin = plugin; + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!plugin.inFightCave() + || plugin.getCurrentWave() < 0) + { + return null; + } + + panelComponent.getChildren().clear(); + + final int currentWave = plugin.getCurrentWave(); + final int waveIndex = currentWave - 1; + + if (config.waveDisplay() == WaveDisplayMode.CURRENT + || config.waveDisplay() == WaveDisplayMode.BOTH) + { + final Map waveContents = FightCaveWaveHelperPlugin.getWAVES().get(waveIndex); + + addWaveInfo("Wave " + plugin.getCurrentWave(), waveContents); + } + + if ((config.waveDisplay() == WaveDisplayMode.NEXT + || config.waveDisplay() == WaveDisplayMode.BOTH) + && currentWave != FightCaveWaveHelperPlugin.MAX_WAVE) + { + final Map waveContents = FightCaveWaveHelperPlugin.getWAVES().get(waveIndex + 1); + + addWaveInfo("Next wave", waveContents); + } + + return panelComponent.render(graphics); + } + + private void addWaveInfo(final String headerText, final Map waveContents) + { + panelComponent.getChildren().add(TitleComponent.builder() + .text(headerText) + .color(HEADER_COLOR) + .build()); + + for (LineComponent line : buildWaveLines(waveContents)) + { + panelComponent.getChildren().add(line); + } + } + + private static Collection buildWaveLines(final Map wave) + { + final List> monsters = new ArrayList<>(wave.entrySet()); + monsters.sort(Map.Entry.comparingByKey()); + final List outputLines = new ArrayList<>(); + + for (Map.Entry monsterEntry : monsters) + { + final WaveMonster monster = monsterEntry.getKey(); + final int quantity = monsterEntry.getValue(); + final LineComponent line = LineComponent.builder() + .left(FightCaveWaveHelperPlugin.formatMonsterQuantity(monster, quantity)) + .build(); + + outputLines.add(line); + } + + return outputLines; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java new file mode 100644 index 0000000000..6b80dd4ce3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java @@ -0,0 +1,43 @@ +package net.runelite.client.plugins.freezetimers; + +import net.runelite.api.Actor; +import net.runelite.client.plugins.freezetimers.Spell; +import net.runelite.client.util.Text; + +public class Barrage +extends Spell { + public static final long DURATION = 20000L; + private long remainingTime; + private boolean isFinished; + + public Barrage(Actor affectedTarget, Actor caster) { + super(affectedTarget, caster); + } + + public long getRemainingTime() { + long elapsedTime = System.currentTimeMillis() - this.startTime; + if (Barrage.getDURATION() > elapsedTime) { + return Barrage.getDURATION() - elapsedTime; + } + this.isFinished = true; + return 0L; + } + + public boolean equals(Object o) { + if (o instanceof Barrage) { + Barrage barrage = (Barrage)o; + return Text.standardize(this.getAffectedTarget().getName()).equals(Text.standardize(((Barrage)o).getAffectedTarget().getName())) && this.getStartTime() == ((Barrage)o).getStartTime(); + } + return false; + } + + public static long getDURATION() { + return 20000L; + } + + @Override + public boolean isFinished() { + return this.isFinished; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java new file mode 100644 index 0000000000..512905759d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java @@ -0,0 +1,51 @@ +package net.runelite.client.plugins.freezetimers; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup(value="freezetimers") +public interface FreezeTimersConfig +extends Config { + @ConfigItem(position=0, keyName="freezeenable", name="Enable PvP freeze timers", description="Configures whether or not to show freeze timers.") + default public boolean EnableFreezeTimers() { + return false; + } + + @ConfigItem(position=1, keyName="tilehighlight", name="Frozen opponent tile highlighting", description="Configures whether or not to highlight tiles frozen opponents are standing on.") + default public boolean drawTiles() { + return false; + } + + @ConfigItem(position=2, keyName="timercolor", name="Freeze Timer Color", description="Color of freeze timer") + default public Color FreezeTimerColor() { + return new Color(0, 184, 212); + } + + @ConfigItem(position=3, keyName="spellIcon", name="Show spell icon", description="Shows the spell icon for the freeze spell affecting the target") + default public boolean spellIcon() { + return true; + } + + @ConfigItem(position=4, keyName="refreezeTimer", name="Refreeze Timer", description="Show a timer that counts up until the target can be refrozen") + default public boolean refreezeTimer() { + return true; + } + + @ConfigItem(position=5, keyName="refreezeTimerColor", name="Refreeze color", description="The color for the timer that counts until the target can be refrozen") + default public Color RefreezeTimerColor() { + return Color.red; + } + + @ConfigItem(position = 6, keyName = "tbtimer", name = "Tele Block Timer", description = "Enables tele block timer") + default boolean TBTimer() { + return true; + } + + @ConfigItem(position = 7, keyName = "timerpos", name = "Freeze Timer Position", description = "Position of freeze timer") + default int FreezeTimerPos() { + return 80; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java new file mode 100644 index 0000000000..1d7dbd162e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java @@ -0,0 +1,157 @@ +package net.runelite.client.plugins.freezetimers; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.image.BufferedImage; +import java.util.function.BiConsumer; +import javax.inject.Inject; +import javax.inject.Singleton; +import net.runelite.api.Client; +import net.runelite.api.HeadIcon; +import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; +import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin; +import net.runelite.client.plugins.freezetimers.FreezeTimersService; +import net.runelite.client.ui.FontManager; +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 FreezeTimersOverlay +extends Overlay { + private final FreezeTimersService FreezeTimersService; + private final FreezeTimersConfig config; + private final FreezeTimersPlugin plugin; + private final SpriteManager spriteManager; + private final Client client; + + @Inject + private FreezeTimersOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2, FreezeTimersPlugin plugin, Client client, SpriteManager spriteManager) { + this.config = config; + this.FreezeTimersService = FreezeTimersService2; + this.plugin = plugin; + this.client = client; + this.spriteManager = spriteManager; + this.setPosition(OverlayPosition.DYNAMIC); + this.setPriority(OverlayPriority.MED); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (!this.config.EnableFreezeTimers()) { + return null; + } + this.FreezeTimersService.forEachPlayer((player, color) -> this.renderPlayerOverlay(graphics, (Player)player, (Color)color)); + return null; + } + + private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) { + BufferedImage clanchatImage; + int timer = 0; + String name = actor.getName(); + int freezetype = this.plugin.freezetype(name); + boolean frozenoverlay = false; + int offset = 5; + long dtime = this.plugin.opponentfreezetime(name); + long tbed = plugin.istbed(name); + Point textLocation = null; + HeadIcon headIcon = actor.getOverheadIcon(); + int freezetime = 0; + if (freezetype == 1 || freezetype == 4) { + freezetime = 5000; + } else if (freezetype == 2 || freezetype == 5) { + freezetime = 10000; + } else if (freezetype == 3 || freezetype == 6) { + freezetime = 15000; + } else if (freezetype == 7) { + freezetime = 20000; + } else if (freezetype == 8) { + freezetime = 2500; + } else if (freezetype == 9) { + freezetime = 5000; + } else if (freezetype == 10) { + freezetime = 7500; + } + long currenttime = System.currentTimeMillis(); + long timediff = currenttime - dtime; + timer = (freezetime - (int)timediff) / 1000; + if (timediff < (long)freezetime) { + textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos()); + textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); + } else if (timediff < (long)(freezetime + 3000)) { + timer = Math.abs(timer); + ++timer; + if (this.config.refreezeTimer()) { + textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos()); + textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); + graphics.setFont(FontManager.getRunescapeBoldFont()); + if (headIcon != null) { + textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); + } + frozenoverlay = true; + OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), this.config.RefreezeTimerColor()); + return; + } + } else { + this.plugin.deleteopponent(name); + } + if (textLocation != null && (clanchatImage = this.plugin.GetFreezeIcon(freezetype - 1)) != null) { + int width = clanchatImage.getWidth(); + int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent(); + Point imageLocation = new Point(textLocation.getX(), textLocation.getY() - (config.FreezeTimerPos() / 2)); + graphics.setFont(FontManager.getRunescapeFont()); + graphics.setStroke(new BasicStroke(3.0f)); + if (this.config.spellIcon()) { + frozenoverlay = true; + graphics.drawOval(imageLocation.getX(), imageLocation.getY(), clanchatImage.getWidth(), clanchatImage.getHeight()); + OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); + OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), color); + } else { + graphics.setColor(Color.cyan); + graphics.drawOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight()); + graphics.setColor(Color.blue); + graphics.fillOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight()); + OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), Color.WHITE); + } + } + + if (config.TBTimer()) { + if (tbed > 0) { + int type = plugin.tbtype(name); + int tbexpiry; + if (type > 0) { + if (type == 1) { + tbexpiry = 300000; + } else if (type == 2) { + tbexpiry = 150000; + } else { + return; + } + long tbtime = currenttime - tbed; + int tbtimer = (tbexpiry - (int) tbtime) / 1000; + if (tbtime < tbexpiry) { + textLocation = actor.getCanvasTextLocation(graphics, Integer.toString(tbtimer), actor.getLogicalHeight() + config.FreezeTimerPos()); + if (frozenoverlay) { + textLocation = new Point(textLocation.getX() + 40, textLocation.getY() - config.FreezeTimerPos()); + } else { + textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); + } + } else { + plugin.deletetb(name); + } + } + + } + } + } +} + 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 new file mode 100644 index 0000000000..878270bfd4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java @@ -0,0 +1,402 @@ +package net.runelite.client.plugins.freezetimers; + + + + + +import com.google.inject.Provides; +import java.awt.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.image.*; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.ImageObserver; +import java.awt.image.IndexColorModel; +import java.awt.image.WritableRaster; +import java.util.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.inject.Inject; +import net.runelite.api.*; +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.api.events.*; +import net.runelite.api.GameState; +import net.runelite.api.HeadIcon; +import net.runelite.api.IndexedSprite; +import net.runelite.api.Player; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.ExperienceChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.MenuOptionClicked; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.freezetimers.Barrage; +import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; +import net.runelite.client.plugins.freezetimers.FreezeTimersOverlay; +import net.runelite.client.plugins.freezetimers.FreezeTimersTileOverlay; +import net.runelite.client.plugins.freezetimers.Spell; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.ImageUtil; +import org.slf4j.Logger; + +@PluginDescriptor( + name = "!Freeze Timers", + description = "PVP Freeze Timers", + tags = {"PvP", "Freeze", "Timers"} +) + +public class FreezeTimersPlugin +extends Plugin { + @Inject + private OverlayManager overlayManager; + @Inject + private FreezeTimersConfig config; + @Inject + private FreezeTimersOverlay FreezeTimersOverlay; + @Inject + private FreezeTimersTileOverlay FreezeTimersTileOverlay; + @Inject + private Client client; + @Inject + private SpriteManager spriteManager; + + private static final int[] FREEZE_ICONS = { + SpriteID.SPELL_BIND, + SpriteID.SPELL_SNARE, + SpriteID.SPELL_ENTANGLE, + SpriteID.SPELL_ICE_RUSH, + SpriteID.SPELL_ICE_BURST, + SpriteID.SPELL_ICE_BLITZ, + SpriteID.SPELL_ICE_BARRAGE, + SpriteID.SPELL_BIND, + SpriteID.SPELL_SNARE, + SpriteID.SPELL_ENTANGLE, + SpriteID.SPELL_TELE_BLOCK + }; + private static final Dimension FREEZE_ICON_DIMENSION = new Dimension(25, 25); + private static final Color FREEZE_ICON_OUTLINE_COLOR = new Color(33, 33, 33); + private final BufferedImage[] FreezeIcons = new BufferedImage[FREEZE_ICONS.length]; + private final int SPLASH_ID = 85; + Map tbedthings = new HashMap<>(); + Map tbtypes = new HashMap<>(); + Map testMap = new HashMap(); + Map frozenthings = new HashMap(); + Map frozenthingpoints = new HashMap(); + Map freezetype = new HashMap(); + Map magexp = new HashMap(); + int lastxp; + int ticks; + int currticks; + String currtarget; + String spell; + + @Provides + FreezeTimersConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(FreezeTimersConfig.class); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged gameStateChanged) { + if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { + this.loadFreezeIcons(); + } + } + + @Override + protected void startUp() throws Exception { + this.overlayManager.add(this.FreezeTimersOverlay); + this.overlayManager.add(this.FreezeTimersTileOverlay); + } + + @Override + protected void shutDown() throws Exception { + this.overlayManager.remove(this.FreezeTimersOverlay); + this.overlayManager.remove(this.FreezeTimersTileOverlay); + this.frozenthings.clear(); + this.frozenthingpoints.clear(); + this.tbedthings.clear(); + this.tbtypes.clear(); + } + + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked event) { + if (event.getMenuTarget().contains("->")) { + Pattern spattern = Pattern.compile(">(.+?)"); + Pattern ppattern = Pattern.compile("> (.+?) 0 && this.currtarget != null) { + if (this.frozenthings.containsKey(this.currtarget)) { + this.currtarget = null; + return; + } + WorldPoint targetPosition = null; + for (Player player : this.client.getPlayers()) { + String playerName; + if (player == null || !(playerName = player.getName()).equals(this.currtarget)) continue; + if (player.getOverheadIcon() != null && player.getOverheadIcon().equals((Object)HeadIcon.MAGIC)) { + praymage = true; + } + targetPosition = player.getWorldLocation(); + break; + } + if (targetPosition != null) { + if (this.spell.equals("Bind") && xp > 30) { + this.frozenthings.put(this.currtarget, System.currentTimeMillis()); + this.frozenthingpoints.put(this.currtarget, targetPosition); + if (praymage) { + this.freezetype.put(this.currtarget, 8); + } else { + this.freezetype.put(this.currtarget, 1); + } + } else if (this.spell.equals("Snare") && xp > 60) { + this.frozenthings.put(this.currtarget, System.currentTimeMillis()); + this.frozenthingpoints.put(this.currtarget, targetPosition); + if (praymage) { + this.freezetype.put(this.currtarget, 9); + } else { + this.freezetype.put(this.currtarget, 2); + } + } else if (this.spell.equals("Entangle") && xp >= 89) { + this.frozenthings.put(this.currtarget, System.currentTimeMillis()); + this.frozenthingpoints.put(this.currtarget, targetPosition); + if (praymage) { + this.freezetype.put(this.currtarget, 10); + } else { + this.freezetype.put(this.currtarget, 3); + } + } else if (this.spell.equals("Ice Rush") && xp > 34) { + this.frozenthings.put(this.currtarget, System.currentTimeMillis()); + this.frozenthingpoints.put(this.currtarget, targetPosition); + this.freezetype.put(this.currtarget, 4); + } else if (this.spell.equals("Ice Burst") && xp > 40) { + this.frozenthings.put(this.currtarget, System.currentTimeMillis()); + this.frozenthingpoints.put(this.currtarget, targetPosition); + this.freezetype.put(this.currtarget, 5); + } else if (this.spell.equals("Ice Blitz") && xp > 46) { + this.frozenthings.put(this.currtarget, System.currentTimeMillis()); + this.frozenthingpoints.put(this.currtarget, targetPosition); + this.freezetype.put(this.currtarget, 6); + } else if (this.spell.equals("Ice Barrage") && xp > 52) { + Barrage barrage = new Barrage(this.client.getLocalPlayer().getInteracting(), this.client.getLocalPlayer()); + this.testMap.put(this.currtarget, barrage); + this.frozenthings.put(this.currtarget, System.currentTimeMillis()); + this.frozenthingpoints.put(this.currtarget, targetPosition); + this.freezetype.put(this.currtarget, 7); + } else if (spell.equals("Tele Block") && xp == 95) { + if (config.TBTimer()) { + if (praymage) { + this.tbtypes.put(this.currtarget, 2); + } else { + this.tbtypes.put(this.currtarget, 1); + } + this.tbedthings.put(this.currtarget, System.currentTimeMillis()); + } + } + } + } + if (this.currtarget != null && this.ticks > this.currticks + 1) { + Player local = this.client.getLocalPlayer(); + Actor interacting = local.getInteracting(); + if (interacting != null) { + if (!interacting.getName().equals(this.currtarget)) { + this.currtarget = null; + } + } else { + this.currtarget = null; + } + } + ++this.ticks; + } + + public long opponentfreezetime(String name) { + if (this.frozenthings.containsKey(name)) { + return this.frozenthings.get(name); + } + return 0L; + } + + public WorldPoint playerpos(String name) { + if (this.frozenthingpoints.containsKey(name)) { + return this.frozenthingpoints.get(name); + } + return null; + } + + public void updatePosition(String name, WorldPoint point) { + if (this.frozenthingpoints.containsKey(name)) { + this.frozenthingpoints.remove(name); + this.frozenthingpoints.put(name, point); + } + } + + public int freezetype(String name) { + if (this.freezetype.containsKey(name)) { + return this.freezetype.get(name); + } + return 0; + } + public long istbed(String name) { + if (this.tbedthings.containsKey(name)) { + return this.tbedthings.get(name); + } + return 0; + } + public int tbtype(String name) { + if (this.tbtypes.containsKey(name)) { + return this.tbtypes.get(name); + } + return 0; + } + public void deleteopponent(String name) { + if (this.frozenthings.containsKey(name)) { + this.frozenthings.remove(name); + } + if (this.frozenthingpoints.containsKey(name)) { + this.frozenthingpoints.remove(name); + } + if (this.freezetype.containsKey(name)) { + this.freezetype.remove(name); + } + } + public void deletetb(String name) { + if (this.tbedthings.containsKey(name)) { + this.tbedthings.remove(name); + } + if (this.tbtypes.containsKey(name)) { + this.tbtypes.remove(name); + } + } + private void loadFreezeIcons() { + IndexedSprite[] freezeIcons = new IndexedSprite[]{}; + IndexedSprite[] newfreezeIcons = Arrays.copyOf(freezeIcons, FREEZE_ICONS.length); + int curPosition = 0; + int i = 0; + while (i < FREEZE_ICONS.length) { + int resource = FREEZE_ICONS[i]; + this.FreezeIcons[i] = FreezeTimersPlugin.rgbaToIndexedBufferedImage(FreezeTimersPlugin.FreezeIconFromSprite(this.spriteManager.getSprite(resource, 0))); + newfreezeIcons[curPosition] = FreezeTimersPlugin.createIndexedSprite(this.client, this.FreezeIcons[i]); + ++i; + ++curPosition; + } + } + + private static IndexedSprite createIndexedSprite(Client client, BufferedImage bufferedImage) { + IndexColorModel indexedCM = (IndexColorModel)bufferedImage.getColorModel(); + int width = bufferedImage.getWidth(); + int height = bufferedImage.getHeight(); + byte[] pixels = ((DataBufferByte)bufferedImage.getRaster().getDataBuffer()).getData(); + int[] palette = new int[indexedCM.getMapSize()]; + indexedCM.getRGBs(palette); + IndexedSprite newIndexedSprite = client.createIndexedSprite(); + newIndexedSprite.setPixels(pixels); + newIndexedSprite.setPalette(palette); + newIndexedSprite.setWidth(width); + newIndexedSprite.setHeight(height); + newIndexedSprite.setOriginalWidth(width); + newIndexedSprite.setOriginalHeight(height); + newIndexedSprite.setOffsetX(0); + newIndexedSprite.setOffsetY(0); + return newIndexedSprite; + } + + private static BufferedImage rgbaToIndexedBufferedImage(BufferedImage sourceBufferedImage) { + BufferedImage indexedImage = new BufferedImage(sourceBufferedImage.getWidth(), sourceBufferedImage.getHeight(), 13); + ColorModel cm = indexedImage.getColorModel(); + IndexColorModel icm = (IndexColorModel)cm; + int size = icm.getMapSize(); + byte[] reds = new byte[size]; + byte[] greens = new byte[size]; + byte[] blues = new byte[size]; + icm.getReds(reds); + icm.getGreens(greens); + icm.getBlues(blues); + WritableRaster raster = indexedImage.getRaster(); + int pixel = raster.getSample(0, 0, 0); + IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); + BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); + resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); + return resultIndexedImage; + } + + private static BufferedImage FreezeIconFromSprite(BufferedImage freezeSprite) { + BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.width, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.height); + return ImageUtil.outlineImage(freezeCanvas, FREEZE_ICON_OUTLINE_COLOR); + } + + BufferedImage GetFreezeIcon(int id) { + return this.FreezeIcons[id]; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java new file mode 100644 index 0000000000..257aae69b8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java @@ -0,0 +1,81 @@ +package net.runelite.client.plugins.freezetimers; + +import java.awt.Color; +import java.util.List; +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.api.coords.WorldPoint; +import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; +import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin; + +@Singleton +public class FreezeTimersService { + private final Client client; + private final FreezeTimersConfig config; + private final FreezeTimersPlugin plugin; + + @Inject + private FreezeTimersService(Client client, FreezeTimersConfig config, FreezeTimersPlugin plugin) { + this.config = config; + this.plugin = plugin; + this.client = client; + } + + public void forEachPlayer(BiConsumer consumer) { + for (Player player : this.client.getPlayers()) { + if (player == null || player.getName() == null) continue; + String name = player.getName(); + int freezetype = this.plugin.freezetype(name); + long tbed = plugin.istbed(name); + long dtime = this.plugin.opponentfreezetime(name); + int freezetime = 0; + if (freezetype == 1 || freezetype == 4) { + freezetime = 5000; + } else if (freezetype == 2 || freezetype == 5) { + freezetime = 10000; + } else if (freezetype == 3 || freezetype == 6) { + freezetime = 15000; + } else if (freezetype == 7) { + freezetime = 20000; + } else if (freezetype == 8) { + freezetime = 2500; + } else if (freezetype == 9) { + freezetime = 5000; + } else if (freezetype == 10) { + freezetime = 7500; + } + if (dtime <= 0L) continue; + long currenttime = System.currentTimeMillis(); + long timediff = currenttime - dtime; + if (timediff < (long)freezetime) { + WorldPoint lastWorldPoint; + WorldPoint currentWorldPoint = player.getWorldLocation(); + if (currentWorldPoint.equals(lastWorldPoint = this.plugin.playerpos(name))) { + consumer.accept(player, this.config.FreezeTimerColor()); + continue; + } + if (timediff < 605L) { + this.plugin.updatePosition(name, currentWorldPoint); + consumer.accept(player, this.config.FreezeTimerColor()); + continue; + } + this.plugin.deleteopponent(name); + continue; + } + if (timediff < (long)(freezetime + 3000)) { + consumer.accept(player, Color.YELLOW); + continue; + } else { + this.plugin.deleteopponent(name); + } + if (tbed > 0) { + consumer.accept(player, config.FreezeTimerColor()); + return; + } + } + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java new file mode 100644 index 0000000000..a945470c85 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java @@ -0,0 +1,46 @@ +package net.runelite.client.plugins.freezetimers; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.util.function.BiConsumer; +import javax.inject.Inject; +import net.runelite.api.Player; +import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; +import net.runelite.client.plugins.freezetimers.FreezeTimersService; +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 FreezeTimersTileOverlay +extends Overlay { + private final FreezeTimersService FreezeTimersService; + private final FreezeTimersConfig config; + + @Inject + private FreezeTimersTileOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2) { + this.config = config; + this.FreezeTimersService = FreezeTimersService2; + this.setLayer(OverlayLayer.ABOVE_SCENE); + this.setPosition(OverlayPosition.DYNAMIC); + this.setPriority(OverlayPriority.MED); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (!this.config.drawTiles()) { + return null; + } + this.FreezeTimersService.forEachPlayer((player, color) -> { + 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/freezetimers/PlayerSpellEffect.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java new file mode 100644 index 0000000000..8bc136fbb5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java @@ -0,0 +1,35 @@ +package net.runelite.client.plugins.freezetimers; + +public enum PlayerSpellEffect { + BARRAGE("Ice Barrage", 20000, false), + BLITZ("Ice Blitz", 15000, false); + + private final String SPELL_NAME; + private long startTime; + private int duration; + private boolean halvable; + + private PlayerSpellEffect(String name, int duration, boolean halvable) { + this.SPELL_NAME = name; + this.duration = duration; + this.halvable = halvable; + this.startTime = System.currentTimeMillis(); + } + + public String getSPELL_NAME() { + return this.SPELL_NAME; + } + + public long getStartTime() { + return this.startTime; + } + + public int getDuration() { + return this.duration; + } + + public boolean isHalvable() { + return this.halvable; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java new file mode 100644 index 0000000000..d9033a7c0d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java @@ -0,0 +1,34 @@ +package net.runelite.client.plugins.freezetimers; + +import net.runelite.api.Actor; + +public abstract class Spell { + private final Actor affectedTarget; + private final Actor caster; + public final long startTime; + private long remainingTime; + private boolean isFinished; + + protected Spell(Actor affectedTarget, Actor caster) { + this.affectedTarget = affectedTarget; + this.caster = caster; + this.startTime = System.currentTimeMillis(); + } + + public Actor getAffectedTarget() { + return this.affectedTarget; + } + + public Actor getCaster() { + return this.caster; + } + + public long getStartTime() { + return this.startTime; + } + + public boolean isFinished() { + return this.isFinished; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansOverlay.java new file mode 100644 index 0000000000..8f90c59363 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansOverlay.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2018, Damen + * 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.grotesqueguardians; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.GraphicsObject; +import net.runelite.api.Perspective; +import net.runelite.api.coords.LocalPoint; +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; + +class GrotesqueGuardiansOverlay extends Overlay +{ + private static final int GROTESQUE_GUARDIANS_REGION_ID = 6727; + private final Client client; + private static final int GROTESQUE_GUARDIANS_LIGHTNING_START = 1416; + private static final int GROTESQUE_GUARDIANS_LIGHTNING_END = 1431; + private static final int GROTESQUE_GUARDIANS_FALLING_ROCKS = 1436; + private static final int GROTESQUE_GUARDIANS_STONE_ORB = 160; + + @Inject + private GrotesqueGuardiansOverlay(Client client) + { + this.client = client; + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + setPriority(OverlayPriority.LOW); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!client.isInInstancedRegion() || client.getMapRegions()[0] != GROTESQUE_GUARDIANS_REGION_ID) + { + return null; + } + + // TODO: Awaiting GraphicsObjectDespawn event to be tracked to make this more efficient. + for (GraphicsObject graphicsObject : client.getGraphicsObjects()) + { + Color color = null; + + if (graphicsObject.getId() >= GROTESQUE_GUARDIANS_LIGHTNING_START && graphicsObject.getId() <= GROTESQUE_GUARDIANS_LIGHTNING_END) + { + color = Color.ORANGE; + } + else if (graphicsObject.getId() == GROTESQUE_GUARDIANS_STONE_ORB) + { + color = Color.GRAY; + } + else if (graphicsObject.getId() == GROTESQUE_GUARDIANS_FALLING_ROCKS) + { + color = Color.YELLOW; + } + else + { + continue; + } + + LocalPoint lp = graphicsObject.getLocation(); + Polygon poly = Perspective.getCanvasTilePoly(client, lp); + + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, color); + } + } + return null; + } +} 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 new file mode 100644 index 0000000000..d6df9dc49f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, Damen + * 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.grotesqueguardians; + +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 = "!Grotesque Guardians", + description = "Display tile indicators for the Grotesque Guardian special attacks", + tags = {"grotesque", "guardians", "gargoyle", "garg"} +) +public class GrotesqueGuardiansPlugin extends Plugin +{ + @Inject + private OverlayManager overlayManager; + + @Inject + private GrotesqueGuardiansOverlay overlay; + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java new file mode 100644 index 0000000000..8a92bed779 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersConfig.java @@ -0,0 +1,35 @@ +package net.runelite.client.plugins.hideprayers; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("hideprayers") +public interface HidePrayersConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "pk prayers", + name = "Hides none pk prayers", + description = "Hides widget icons." + ) + default boolean showPrayers() { return false; } + + @ConfigItem( + position = 1, + keyName = "eagle/mystic", + name = "Shows eagle and mystic prayers", + description = "Hides widget icons." + ) + default boolean showEagleMystic() { return false; } + + @ConfigItem( + position = 1, + keyName = "ultstr", + name = "Shows ultimate strength", + description = "Hides widget icons." + ) + default boolean showUltStrength() { return false; } + +} + 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 new file mode 100644 index 0000000000..df473a5d0d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java @@ -0,0 +1,169 @@ +package net.runelite.client.plugins.hideprayers; + +import com.google.common.collect.ImmutableList; +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import net.runelite.api.*; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +import javax.inject.Inject; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@PluginDescriptor( + name = "!Hide Prayers", + description = "Hides specific Prayers in the Prayer tab." +) +public class HidePrayersPlugin extends Plugin { + private static final int PRAYER_COUNT = Prayer.values().length; + + private static final List PRAYER_WIDGET_INFO_LIST = ImmutableList.of(WidgetInfo.PRAYER_THICK_SKIN, + WidgetInfo.PRAYER_BURST_OF_STRENGTH, WidgetInfo.PRAYER_CLARITY_OF_THOUGHT, WidgetInfo.PRAYER_SHARP_EYE, + WidgetInfo.PRAYER_MYSTIC_WILL, WidgetInfo.PRAYER_ROCK_SKIN, WidgetInfo.PRAYER_SUPERHUMAN_STRENGTH, + WidgetInfo.PRAYER_IMPROVED_REFLEXES, WidgetInfo.PRAYER_RAPID_RESTORE, WidgetInfo.PRAYER_RAPID_HEAL, + WidgetInfo.PRAYER_PROTECT_ITEM, WidgetInfo.PRAYER_HAWK_EYE, WidgetInfo.PRAYER_MYSTIC_LORE, + WidgetInfo.PRAYER_STEEL_SKIN, WidgetInfo.PRAYER_ULTIMATE_STRENGTH, WidgetInfo.PRAYER_INCREDIBLE_REFLEXES, + WidgetInfo.PRAYER_PROTECT_FROM_MAGIC, WidgetInfo.PRAYER_PROTECT_FROM_MISSILES, + WidgetInfo.PRAYER_PROTECT_FROM_MELEE, WidgetInfo.PRAYER_EAGLE_EYE, WidgetInfo.PRAYER_MYSTIC_MIGHT, + WidgetInfo.PRAYER_RETRIBUTION, WidgetInfo.PRAYER_REDEMPTION, WidgetInfo.PRAYER_SMITE, + WidgetInfo.PRAYER_PRESERVE, WidgetInfo.PRAYER_CHIVALRY, WidgetInfo.PRAYER_PIETY, WidgetInfo.PRAYER_RIGOUR, + WidgetInfo.PRAYER_AUGURY); + + @Inject + private Client client; + + @Inject + private HidePrayersConfig config; + + @Provides + HidePrayersConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(HidePrayersConfig.class); + } + + @Override + protected void startUp() throws Exception { + hidePrayers(); + } + + @Override + protected void shutDown() throws Exception { + restorePrayers(); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) { + if (event.getGameState() == GameState.LOGGED_IN) { + hidePrayers(); + } + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) { + if (event.getGroup().equals("hideprayers")) { + hidePrayers(); + } + } + + @Subscribe + public void onWidgetLoaded(WidgetLoaded event) { + if (event.getGroupId() == WidgetID.PRAYER_GROUP_ID || event.getGroupId() == WidgetID.QUICK_PRAYERS_GROUP_ID) { + hidePrayers(); + } + } + + private PrayerTabState getPrayerTabState() { + HashTable componentTable = client.getComponentTable(); + for (WidgetNode widgetNode : componentTable.getNodes()) { + if (widgetNode.getId() == WidgetID.PRAYER_GROUP_ID) { + return PrayerTabState.PRAYERS; + } else if (widgetNode.getId() == WidgetID.QUICK_PRAYERS_GROUP_ID) { + return PrayerTabState.QUICK_PRAYERS; + } + } + return PrayerTabState.NONE; + } + + private void restorePrayers() { + if (client.getGameState() != GameState.LOGGED_IN) + return; + + PrayerTabState prayerTabState = getPrayerTabState(); + + if (prayerTabState == PrayerTabState.PRAYERS) { + List prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget) + .filter(Objects::nonNull).collect(Collectors.toList()); + + if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size()) + return; + + for (int index = 0; index < PRAYER_COUNT; index++) + prayerWidgets.get(Prayer.values()[index].ordinal()).setHidden(false); + } + } + + private void hidePrayers() { + if (client.getGameState() != GameState.LOGGED_IN) + return; + + PrayerTabState prayerTabState = getPrayerTabState(); + + if (prayerTabState == PrayerTabState.PRAYERS) { + List prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget) + .filter(Objects::nonNull).collect(Collectors.toList()); + + if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size()) + return; + + for (int index = 0; index < PRAYER_COUNT; index++) { + Prayer prayer = Prayer.values()[index]; + Widget prayerWidget = prayerWidgets.get(prayer.ordinal()); + + if (!config.showPrayers() && !config.showEagleMystic()) + prayerWidget.setHidden(false); + + if (config.showPrayers()) { + prayerWidget.setHidden(true); + prayerWidgets.get(Prayer.values()[10].ordinal()).setHidden(false);// protect item + prayerWidgets.get(Prayer.values()[16].ordinal()).setHidden(false);// mage + prayerWidgets.get(Prayer.values()[17].ordinal()).setHidden(false);// range + prayerWidgets.get(Prayer.values()[18].ordinal()).setHidden(false);// melee + prayerWidgets.get(Prayer.values()[23].ordinal()).setHidden(false);// smite + if (config.showEagleMystic()) { + prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour + prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury + } else { + prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(false);// rigour + prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(false);// augury + } + if (config.showUltStrength()) { + prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety + } else { + prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(false);// piety + } + } + if (config.showEagleMystic()) { + prayerWidget.setHidden(true); + prayerWidgets.get(Prayer.values()[19].ordinal()).setHidden(false);// eagle + prayerWidgets.get(Prayer.values()[20].ordinal()).setHidden(false);// mystic + prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour + prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury + } + if (config.showUltStrength()) { + prayerWidget.setHidden(true); + prayerWidgets.get(Prayer.values()[14].ordinal()).setHidden(false);// Ult Strength + prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety + } + + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java new file mode 100644 index 0000000000..699300f8a9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/PrayerTabState.java @@ -0,0 +1,8 @@ +package net.runelite.client.plugins.hideprayers; + +public enum PrayerTabState +{ + NONE, + PRAYERS, + QUICK_PRAYERS +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraConfig.java new file mode 100644 index 0000000000..8c3d8467b8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraConfig.java @@ -0,0 +1,41 @@ +package net.runelite.client.plugins.hydra; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("hydra") +public interface HydraConfig extends Config { + @ConfigItem( + position = 0, + keyName = "hydraenable", + name = "Enable Hydra (194 cb) Helper", + description = "Configures whether or not to enable Hydra Helper. (For use on regular hydra's only, will not work with Alchemical Hydra)." + ) + default boolean EnableHydra() { return true; } + + @ConfigItem( + position = 1, + keyName = "textindicators", + name = "Text Indicator", + description = "Configures if text indicator is shown above hydra's or not." + ) + default boolean TextIndicator() { return true; } + + @ConfigItem( + position = 2, + keyName = "countersize", + name = "Bold indicator", + description = "Configures if text indicator is bold or not." + ) + default boolean BoldText() { return false; } + + @ConfigItem( + position = 3, + keyName = "prayerhelper", + name = "Prayer Helper", + description = "Configures if prayer helper is shown or not." + ) + default boolean PrayerHelper() { return true; } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraIndicatorOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraIndicatorOverlay.java new file mode 100644 index 0000000000..6c38c81b3f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraIndicatorOverlay.java @@ -0,0 +1,52 @@ +package net.runelite.client.plugins.hydra; + +import java.awt.*; +import java.awt.image.BufferedImage; +import javax.inject.Inject; + +import net.runelite.api.*; +import net.runelite.api.Point; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.ui.overlay.*; +import net.runelite.client.ui.overlay.components.ComponentConstants; +import net.runelite.client.ui.overlay.components.ImageComponent; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; + +public class HydraIndicatorOverlay extends Overlay { + private final HydraConfig config; + private final HydraPlugin plugin; + + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + private HydraIndicatorOverlay(HydraConfig config, HydraPlugin plugin) { + this.config = config; + this.plugin = plugin; + setPosition(OverlayPosition.BOTTOM_RIGHT); + setPriority(OverlayPriority.MED); + panelComponent.setPreferredSize(new Dimension(14, 0)); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (!config.PrayerHelper()) { + return null; + } + + if (plugin.Hydra != null) { + if (plugin.hydras.containsKey(plugin.Hydra.getIndex())) { + int val = plugin.hydras.get(plugin.Hydra.getIndex()); + if (val != 0) { + panelComponent.getChildren().clear(); + panelComponent.getChildren().add(LineComponent.builder().right(Integer.toString(val)).build()); + return panelComponent.render(graphics); + } + } + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraOverlay.java new file mode 100644 index 0000000000..b499227ec2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraOverlay.java @@ -0,0 +1,76 @@ +package net.runelite.client.plugins.hydra; + +import java.awt.*; +import javax.inject.Inject; + +import net.runelite.api.*; +import net.runelite.api.Point; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.overlay.*; +import net.runelite.client.ui.overlay.components.PanelComponent; + +public class HydraOverlay extends Overlay { + private final HydraConfig config; + private final HydraPlugin plugin; + private final PanelComponent panelComponent = new PanelComponent(); + + + @Inject + private Client client; + + @Inject + private HydraOverlay(HydraConfig config, HydraPlugin plugin) { + this.config = config; + this.plugin = plugin; + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.MED); + panelComponent.setPreferredSize(new Dimension(150, 0)); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (!config.TextIndicator()) { + return null; + } + + for (NPC hydra : client.getNpcs()) { + if (hydra == null || hydra.getName() == null) { + continue; + } + if (hydra.getName().equalsIgnoreCase("Hydra")) { + if (plugin.hydras.containsKey(hydra.getIndex())) { + int val = plugin.hydras.get(hydra.getIndex()); + if (val != 0) { + if (config.BoldText()) { + graphics.setFont(FontManager.getRunescapeBoldFont()); + } + if (plugin.hydraattacks.containsKey(hydra.getIndex())) { + int attack = plugin.hydraattacks.get(hydra.getIndex()); + if (attack == 8261) { + if (val == 3) { + OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "MAGE", hydra.getLogicalHeight() + 100), "MAGE", Color.BLUE); + } else { + OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "RANGE", hydra.getLogicalHeight() + 100), "RANGE", Color.GREEN); + } + } else if (attack == 8262) { + if (val == 3) { + OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "RANGE", hydra.getLogicalHeight() + 100), "RANGE", Color.GREEN); + } else { + OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "MAGE", hydra.getLogicalHeight() + 100), "MAGE", Color.BLUE); + } + } + } + Point runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam = hydra.getCanvasTextLocation(graphics, Integer.toString(val), hydra.getLogicalHeight() + 40); + if (runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam != null) { + OverlayUtil.renderTextLocation(graphics, runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam, Integer.toString(val), Color.WHITE); + } + } + } + } + + } + graphics.setFont(FontManager.getRunescapeFont()); + return null; + } +} 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 new file mode 100644 index 0000000000..ba8c0317a7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPlugin.java @@ -0,0 +1,145 @@ +package net.runelite.client.plugins.hydra; + +import net.runelite.api.events.*; +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import javax.inject.Inject; +import net.runelite.api.*; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +import java.util.HashMap; +import java.util.Map; + +@PluginDescriptor( + name = "Hydra", + description = "Hydra Helper", + tags = {"Hydra", "Helper"} +) +public class HydraPlugin extends Plugin +{ + @Inject + private OverlayManager overlayManager; + + @Inject + private HydraConfig config; + + @Inject + private HydraOverlay HydraOverlay; + + @Inject + private HydraPrayOverlay HydraPrayOverlay; + + @Inject + private HydraIndicatorOverlay HydraIndicatorOverlay; + + @Inject + private Client client; + + @Inject + private SpriteManager spriteManager; + + @Provides + HydraConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(HydraConfig.class); + } + + Map hydras = new HashMap<>(); + Map hydraattacks = new HashMap<>(); + NPC Hydra; + + @Override + protected void startUp() throws Exception { + overlayManager.add(HydraOverlay); + overlayManager.add(HydraPrayOverlay); + overlayManager.add(HydraIndicatorOverlay); + } + + @Override + protected void shutDown() throws Exception { + overlayManager.remove(HydraOverlay); + overlayManager.remove(HydraPrayOverlay); + overlayManager.remove(HydraIndicatorOverlay); + hydras.clear(); + hydraattacks.clear(); + } + + @Subscribe + public void onNpcSpawned(NpcSpawned event) { + if (!config.EnableHydra()) { + return; + } + NPC hydra = event.getNpc(); + if (hydra.getCombatLevel() != 0 && hydra.getName() != null) { + if (hydra.getName().equalsIgnoreCase("Hydra")) { + if (!hydras.containsKey(hydra.getIndex())) { + hydras.put(hydra.getIndex(), 3); + } + } + } + } + + @Subscribe + public void onNpcDespawned(NpcDespawned event) { + if (!config.EnableHydra()) { + return; + } + NPC hydra = event.getNpc(); + if (hydra.getCombatLevel() != 0 && hydra.getName() != null) { + if (hydra.getName().equalsIgnoreCase("Hydra")) { + if (hydras.containsKey(hydra.getIndex())) { + hydras.remove(hydra.getIndex()); + } + if (hydraattacks.containsKey(hydra.getIndex())) { + hydraattacks.remove(hydra.getIndex()); + } + } + } + } + + @Subscribe + public void onAnimationChanged(AnimationChanged event) { + Actor monster = event.getActor(); + Actor local = client.getLocalPlayer(); + if (monster instanceof NPC) { + NPC hydra = (NPC) monster; + if (hydra.getCombatLevel() != 0 && hydra.getName() != null) { + if (hydra.getName().equalsIgnoreCase("Hydra")) { + if (hydras.containsKey(hydra.getIndex())) { + if (hydra.getAnimation() == 8261 || hydra.getAnimation() == 8262) { + if (hydra.getInteracting().equals(local)) { + Hydra = hydra; + } + if (hydraattacks.containsKey(hydra.getIndex())) { + int lastattack = hydraattacks.get(hydra.getIndex()); + hydraattacks.replace(hydra.getIndex(), hydra.getAnimation()); + + if (lastattack != hydra.getAnimation()) { + hydras.replace(hydra.getIndex(), 2); + } else { + int currval = hydras.get(hydra.getIndex()); + if (currval == 1) { + hydras.replace(hydra.getIndex(), 3); + } else { + hydras.replace(hydra.getIndex(), currval - 1); + } + } + } else { + hydraattacks.put(hydra.getIndex(), hydra.getAnimation()); + int currval = hydras.get(hydra.getIndex()); + if (currval == 1) { + hydras.replace(hydra.getIndex(), 3); + } else { + hydras.replace(hydra.getIndex(), currval - 1); + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPrayOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPrayOverlay.java new file mode 100644 index 0000000000..47a7657667 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/HydraPrayOverlay.java @@ -0,0 +1,100 @@ +package net.runelite.client.plugins.hydra; + +import java.awt.*; +import java.awt.image.BufferedImage; +import javax.inject.Inject; + +import net.runelite.api.*; +import net.runelite.api.Point; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.ui.overlay.*; +import net.runelite.client.ui.overlay.components.ComponentConstants; +import net.runelite.client.ui.overlay.components.ImageComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +public class HydraPrayOverlay extends Overlay { + private final HydraConfig config; + private final HydraPlugin plugin; + + private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150); + + private final SpriteManager spriteManager; + private final PanelComponent imagePanelComponent = new PanelComponent(); + + + @Inject + private Client client; + + @Inject + private HydraPrayOverlay(HydraConfig config, HydraPlugin plugin, SpriteManager spriteManager) { + this.config = config; + this.plugin = plugin; + setPosition(OverlayPosition.BOTTOM_RIGHT); + setPriority(OverlayPriority.HIGH); + this.spriteManager = spriteManager; + } + + @Override + public Dimension render(Graphics2D graphics) { + if (!config.PrayerHelper()) { + return null; + } + + if (plugin.Hydra != null) { + if (plugin.hydras.containsKey(plugin.Hydra.getIndex())) { + int val = plugin.hydras.get(plugin.Hydra.getIndex()); + if (val != 0) { + if (plugin.hydraattacks.containsKey(plugin.Hydra.getIndex())) { + int attack = plugin.hydraattacks.get(plugin.Hydra.getIndex()); + if (attack == 8261) { + if (val == 3) { + final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0); + + imagePanelComponent.getChildren().clear(); + imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); + imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC) + ? ComponentConstants.STANDARD_BACKGROUND_COLOR + : NOT_ACTIVATED_BACKGROUND_COLOR); + + return imagePanelComponent.render(graphics); + } else { + final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0); + + imagePanelComponent.getChildren().clear(); + imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); + imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES) + ? ComponentConstants.STANDARD_BACKGROUND_COLOR + : NOT_ACTIVATED_BACKGROUND_COLOR); + + return imagePanelComponent.render(graphics); + } + } else if (attack == 8262) { + if (val == 3) { + final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0); + + imagePanelComponent.getChildren().clear(); + imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); + imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES) + ? ComponentConstants.STANDARD_BACKGROUND_COLOR + : NOT_ACTIVATED_BACKGROUND_COLOR); + + return imagePanelComponent.render(graphics); + } else { + final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0); + + imagePanelComponent.getChildren().clear(); + imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); + imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC) + ? ComponentConstants.STANDARD_BACKGROUND_COLOR + : NOT_ACTIVATED_BACKGROUND_COLOR); + + return imagePanelComponent.render(graphics); + } + } + } + } + } + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java new file mode 100644 index 0000000000..e9d28f6b26 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java @@ -0,0 +1,27 @@ +package net.runelite.client.plugins.kittennotifier; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("kittennotifier") +public interface KittenNotifierConfig extends Config{ + @ConfigItem( + keyName = "absolutelyNeeded", + name = "Notify only on Absolute Need", + description = "Only notify when kitten absolutely needs food or attention." + ) + default boolean absolutelyNeeded() { return false; } + @ConfigItem( + keyName = "catOwned", + name = "", + description = "", + hidden = true + ) + default boolean catOwned() { return false; } + @ConfigItem( + keyName = "catOwned", + name = "", + description = "" + ) + void catOwned(Boolean bool); +} 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 new file mode 100644 index 0000000000..921dcd4a46 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java @@ -0,0 +1,84 @@ +package net.runelite.client.plugins.kittennotifier; +import com.google.inject.Provides; +import net.runelite.api.ChatMessageType; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.NpcActionChanged; +import net.runelite.api.events.NpcSpawned; +import net.runelite.client.Notifier; +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.api.NPC; +import net.runelite.api.Client; +import javax.inject.Inject; + +@PluginDescriptor( + name = "!Kitten Notifier", + description = "Sends a notification when your kitten needs food, attention, or is grown.", + tags = {"kitten, notifications"} +) +public class KittenNotifierPlugin extends Plugin{ + @Inject + private Notifier notifier; + @Inject + private KittenNotifierConfig config; + @Inject + private Client client; + @Provides + KittenNotifierConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(KittenNotifierConfig.class); + } + @Subscribe + public void onChatMessage(ChatMessage event) { + if (event.getType() == ChatMessageType.ENGINE && !config.catOwned()) { + if (!config.absolutelyNeeded()) { + if (event.getMessage().contentEquals("Your kitten is hungry.")) { + notifier.notify("Your kitten is hungry."); + } + if (event.getMessage().contentEquals("Your kitten wants attention.")) { + notifier.notify("Your kitten wants attention."); + } + } + if (event.getMessage().contentEquals("Your kitten is very hungry.")) { + notifier.notify("Your kitten is very hungry."); + } + if (event.getMessage().contentEquals("Your kitten really wants attention.")) { + notifier.notify("Your kitten really wants attention."); + } + } + } + @Subscribe + public void onNpcActionChanged(NpcActionChanged event) { + if (!config.catOwned()) { + for (NPC npc : client.getNpcs()) { + if (npc.getInteracting() != null) { + if (npc.getName().contentEquals("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); + notifier.notify("Your kitten has grown into a cat."); + } + } + } + } + } + } + @Subscribe + public void onNpcSpawned(NpcSpawned event) { + NPC cat = event.getNpc(); + if (cat.getName() != null) { + if (cat.getName().equalsIgnoreCase("Kitten")) { + if (cat.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) { + config.catOwned(false); + } + } + else if (cat.getName().contentEquals("Cat")) { + if (cat.getInteracting().getName().equalsIgnoreCase(client.getLocalPlayer().getName())) { + config.catOwned(true); + } + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanConfig.java new file mode 100644 index 0000000000..33e61c0d46 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanConfig.java @@ -0,0 +1,32 @@ +package net.runelite.client.plugins.lizardmenshaman; + +import net.runelite.client.config.Config; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("shaman") +public interface LizardmenShamanConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "showTimer", + name = "Show timer", + description = "Display timer till for lizardman shaman spawns." + ) + default boolean showTimer() + { + return true; + } + + @ConfigItem( + position = 2, + keyName = "notifyOnSpawn", + name = "Notify on spawn", + description = "Notify user when lizardman summons spawns." + ) + default boolean notifyOnSpawn() + { + return 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 new file mode 100644 index 0000000000..e6b3923fea --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java @@ -0,0 +1,91 @@ +package net.runelite.client.plugins.lizardmenshaman; + +import com.google.common.eventbus.Subscribe; +import com.google.inject.Provides; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.events.AnimationChanged; +import net.runelite.client.Notifier; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import java.util.HashMap; +import java.util.Map; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "!Lizard Shamans", + description = "Configures timer for lizardmen shaman spawns.", + enabledByDefault = false, + tags = {"shaman", "lizard", "lizardmen"} +) +@Slf4j +public class LizardmenShamanPlugin extends Plugin +{ + private static final String SHAMAN = "Lizardman shaman"; + private static final String MESSAGE = "A Lizardman shaman has summoned his spawn!"; + + @Getter(AccessLevel.PACKAGE) + private final Map spawns = new HashMap<>(); + + @Inject + private OverlayManager overlayManager; + + @Inject + private ShamanSpawnOverlay overlay; + + @Inject + private LizardmenShamanConfig config; + + @Inject + private Notifier notifier; + + @Inject + private Client client; + + @Provides + LizardmenShamanConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(LizardmenShamanConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + spawns.clear(); + } + + @Subscribe + public void onAnimationChanged(AnimationChanged event) + { + Actor actor = event.getActor(); + if (actor == null || actor.getName() == null) + { + return; + } + else if (actor.getName().equals(SHAMAN) && actor.getAnimation() == 7157) + { + if (config.showTimer()) + { + spawns.put(event.getActor().getLocalLocation(), new LizardmenShamanSpawn(8.4, null)); + } + + if (config.notifyOnSpawn()) + { + notifier.notify(MESSAGE); + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanSpawn.java b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanSpawn.java new file mode 100644 index 0000000000..d4297ed624 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanSpawn.java @@ -0,0 +1,18 @@ +package net.runelite.client.plugins.lizardmenshaman; + +import java.time.Instant; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@RequiredArgsConstructor +@AllArgsConstructor +class LizardmenShamanSpawn +{ + private final Instant start = Instant.now(); + private double countdownTimer; + private Instant end; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/ShamanSpawnOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/ShamanSpawnOverlay.java new file mode 100644 index 0000000000..4d363e72c4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/ShamanSpawnOverlay.java @@ -0,0 +1,90 @@ +package net.runelite.client.plugins.lizardmenshaman; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.time.Duration; +import java.time.Instant; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ProgressPieComponent; + +class ShamanSpawnOverlay extends Overlay +{ + private final Client client; + private final LizardmenShamanPlugin plugin; + + @Inject + private ShamanSpawnOverlay(Client client, LizardmenShamanPlugin plugin) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + this.client = client; + this.plugin = plugin; + } + @Override + public Dimension render(Graphics2D graphics) + { + plugin.getSpawns().forEach((localPoint, spawn) -> + { + final Instant now = Instant.now(); + final long startCountdown = Duration.between(spawn.getStart(), now).getSeconds(); + final double certainSec = spawn.getCountdownTimer() - startCountdown; + + if (certainSec <= 0) + { + if (spawn.getEnd() == null) + { + spawn.setEnd(Instant.now()); + } + } + + final ProgressPieComponent pieComponent = new ProgressPieComponent(); + final Point loc = Perspective.localToCanvas(client, localPoint, client.getPlane()); + + if (loc == null || certainSec < 0) + { + return; + } + + pieComponent.setPosition(loc); + pieComponent.setProgress(certainSec / spawn.getCountdownTimer()); + if (certainSec > 4.8) + { + pieComponent.setFill(Color.GREEN); + pieComponent.setBorderColor(Color.GREEN); + pieComponent.render(graphics); + } + else if (certainSec > 3.6) + { + pieComponent.setFill(Color.YELLOW); + pieComponent.setBorderColor(Color.YELLOW); + pieComponent.render(graphics); + } + else if (certainSec > 2.4) + { + pieComponent.setFill(Color.ORANGE); + pieComponent.setBorderColor(Color.ORANGE); + pieComponent.render(graphics); + } + else if (certainSec > 1.2) + { + pieComponent.setFill(new Color(255, 140, 0)); + pieComponent.setBorderColor(new Color(255, 140, 0)); + pieComponent.render(graphics); + } + else + { + pieComponent.setFill(Color.RED); + pieComponent.setBorderColor(Color.RED); + pieComponent.render(graphics); + } + }); + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierConfig.java new file mode 100644 index 0000000000..53f49012c2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierConfig.java @@ -0,0 +1,24 @@ +package net.runelite.client.plugins.menumodifier; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("menumodifier") +public interface MenuModifierConfig extends Config +{ + @ConfigItem(position = 0, keyName = "hideCancel", name = "Hide Cancel", description = "Hides the 'cancel' option from the right click menu") + default boolean hideCancel() { return true; } + + @ConfigItem(position = 1, keyName = "hideExamine", name = "Hide Examine", description = "Hides the 'examine' option from the right click menu") + default boolean hideExamine() { return true; } + + @ConfigItem(position = 2, keyName = "hideTradeWith", name = "Hide Trade With", description = "Hides the 'trade with' option from the right click menu") + default boolean hideTradeWith() { return true; } + + @ConfigItem(position = 3, keyName = "hideReport", name = "Hide Report", description = "Hides the 'report' option from the right click menu") + default boolean hideReport() { return true; } + + @ConfigItem(position = 4, keyName = "hideLookup", name = "Hide Lookup", description = "Hides the 'lookup' option from the right click menu") + default boolean hideLookup() { return true; } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierInputListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierInputListener.java new file mode 100644 index 0000000000..cbb15161f8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierInputListener.java @@ -0,0 +1,39 @@ +package net.runelite.client.plugins.menumodifier; + +import net.runelite.client.input.KeyListener; +import net.runelite.client.input.MouseAdapter; + +import javax.inject.Inject; +import java.awt.event.KeyEvent; + +public class MenuModifierInputListener extends MouseAdapter implements KeyListener +{ + private static final int HOTKEY = KeyEvent.VK_CONTROL; + + @Override + public void keyTyped(KeyEvent e) + { + + } + + @Inject + private MenuModifierPlugin plugin; + + @Override + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() == HOTKEY) + { + plugin.setHotKeyPressed(true); + } + } + + @Override + public void keyReleased(KeyEvent e) + { + if (e.getKeyCode() == HOTKEY) + { + plugin.setHotKeyPressed(false); + } + } +} 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 new file mode 100644 index 0000000000..dc5b9e7a27 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menumodifier/MenuModifierPlugin.java @@ -0,0 +1,168 @@ +package net.runelite.client.plugins.menumodifier; + +import net.runelite.api.events.MenuOpened; +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.Client; +import net.runelite.api.MenuEntry; +import net.runelite.api.Player; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.input.KeyManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.MiscUtils; +import net.runelite.client.util.Text; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +@PluginDescriptor( + name = "!Menu Modifier", + description = "Changes right click menu for players", + tags = { "menu", "modifier", "right", "click", "pk", "bogla" }, + enabledByDefault = false +) +public class MenuModifierPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private MenuModifierConfig config; + + @Inject + private MenuModifierInputListener inputListener; + + @Inject + private KeyManager keyManager; + + @Provides + MenuModifierConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(MenuModifierConfig.class); + } + + @Override + protected void startUp() throws Exception + { + keyManager.registerKeyListener(inputListener); + } + + @Override + protected void shutDown() throws Exception + { + keyManager.unregisterKeyListener(inputListener); + } + + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private boolean hotKeyPressed; + + @Subscribe + public void onMenuOpened(MenuOpened event) + { + Player localPlayer = client.getLocalPlayer(); + + if (localPlayer == null) + return; + + if (!(MiscUtils.getWildernessLevelFrom(client, localPlayer.getWorldLocation()) >= 0)) + return; + + if (hotKeyPressed) + return; + + List menu_entries = new ArrayList(); + + for (MenuEntry entry : event.getMenuEntries()) + { + String option = Text.removeTags(entry.getOption()).toLowerCase(); + + if (option.contains("trade with") && config.hideTradeWith()) + continue; + + if (option.contains("lookup") && config.hideLookup()) + continue; + + if (option.contains("report") && config.hideReport()) + continue; + + if (option.contains("examine") && config.hideExamine()) + continue; + + int identifier = entry.getIdentifier(); + + Player[] players = client.getCachedPlayers(); + Player player = null; + + if (identifier >= 0 && identifier < players.length) + player = players[identifier]; + + if (player == null) + { + menu_entries.add(entry); + continue; + } + + if ((option.contains("attack") || option.contains("cast")) && (player.isFriend() || player.isClanMember())) + continue; + + menu_entries.add(entry); + } + + MenuEntry[] updated_menu_entries = new MenuEntry[menu_entries.size()]; + updated_menu_entries = menu_entries.toArray(updated_menu_entries); + + client.setMenuEntries(updated_menu_entries); + } + + /*@Subscribe + public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) + { + if (true) + return; + + if (!inWilderness) + return; + + if (hotKeyPressed) + return; + + String option = Text.removeTags(menuEntryAdded.getOption()).toLowerCase(); + + if ((option.contains("trade with") && config.hideTradeWith()) + || (option.contains("lookup") && config.hideLookup()) + || (option.contains("report") && config.hideReport()) + || (option.contains("examine") && config.hideExamine()) + || (option.contains("cancel") && config.hideCancel())) + { + int identifier = menuEntryAdded.getIdentifier(); + + Player[] players = client.getCachedPlayers(); + Player player = null; + + if (identifier >= 0 && identifier < players.length) + player = players[identifier]; + + if (player == null) + return; + + //allow trading with friends/clanmates + if (option.contains("trade with") && (player.isFriend() || player.isClanMember())) + return; + + MenuEntry[] menuEntries = client.getMenuEntries(); + + if (menuEntries.length > 0) + client.setMenuEntries(Arrays.copyOf(menuEntries, menuEntries.length - 1)); + } + }*/ +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MidiFileAdjuster.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MidiFileAdjuster.java new file mode 100644 index 0000000000..ee67b0a694 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MidiFileAdjuster.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2019, Rodolfo Ruiz-Velasco + * 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.musicmodifier; + +import javax.sound.midi.*; +import java.io.IOException; + +public class MidiFileAdjuster { + + private int bankLSBValue; + private int chPosition = -1; + + private boolean customBank = false; + + public Sequence reorderTracks(Sequence sequence) throws InvalidMidiDataException, IOException { + for (Track track : sequence.getTracks()) { + for (int i = 0; i < track.size(); i++) { + MidiEvent midiEvent = track.get(i); + MidiMessage midiMessage = midiEvent.getMessage(); + + if (midiMessage instanceof ShortMessage) { + ShortMessage sm = (ShortMessage) midiMessage; + + if (sm.getChannel() < 16) { + getBankLSB(sm); + + if (i == 0 & bankLSBValue != 1) { + chPosition++; + if (chPosition == 9) { + chPosition = 10; + } + } + + if (!customBank) { + + if (sm.getChannel() == 9) { + bankLSBValue = 1; + } + + if (sm.getChannel() != 9) { + bankLSBValue = 0; + } + } + } + + if (bankLSBValue == 1) { + + int drumChannel = 9; + if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) { + sm.setMessage(ShortMessage.PROGRAM_CHANGE, drumChannel, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) { + sm.setMessage(ShortMessage.CONTROL_CHANGE, drumChannel, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.NOTE_OFF) { + sm.setMessage(ShortMessage.NOTE_OFF, drumChannel, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.NOTE_ON) { + sm.setMessage(ShortMessage.NOTE_ON, drumChannel, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) { + sm.setMessage(ShortMessage.PROGRAM_CHANGE, drumChannel, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) { + sm.setMessage(ShortMessage.CONTROL_CHANGE, drumChannel, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.PITCH_BEND) { + sm.setMessage(ShortMessage.PITCH_BEND, drumChannel, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.CHANNEL_PRESSURE) { + sm.setMessage(ShortMessage.CHANNEL_PRESSURE, drumChannel, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.POLY_PRESSURE) { + sm.setMessage(ShortMessage.POLY_PRESSURE, drumChannel, sm.getData1(), sm.getData2()); + } + } else { + + if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) { + sm.setMessage(ShortMessage.PROGRAM_CHANGE, chPosition, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) { + sm.setMessage(ShortMessage.CONTROL_CHANGE, chPosition, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.NOTE_OFF) { + sm.setMessage(ShortMessage.NOTE_OFF, chPosition, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.NOTE_ON) { + sm.setMessage(ShortMessage.NOTE_ON, chPosition, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) { + sm.setMessage(ShortMessage.PROGRAM_CHANGE, chPosition, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) { + sm.setMessage(ShortMessage.CONTROL_CHANGE, chPosition, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.PITCH_BEND) { + sm.setMessage(ShortMessage.PITCH_BEND, chPosition, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.CHANNEL_PRESSURE) { + sm.setMessage(ShortMessage.CHANNEL_PRESSURE, chPosition, sm.getData1(), sm.getData2()); + } + + if (sm.getCommand() == ShortMessage.POLY_PRESSURE) { + sm.setMessage(ShortMessage.POLY_PRESSURE, chPosition, sm.getData1(), sm.getData2()); + } + } + } + } + } + return sequence; + } + + private void getBankLSB(ShortMessage sm) throws InvalidMidiDataException + { + if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) + { + if (sm.getData1() == 32) + { + bankLSBValue = sm.getData2(); + customBank = true; + } + if (sm.getData1() == 0) + { + sm.setMessage(sm.getCommand(), sm.getChannel(), sm.getData1(), bankLSBValue); + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MusicCustomizerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MusicCustomizerPlugin.java new file mode 100644 index 0000000000..a1202750bb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/MusicCustomizerPlugin.java @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2019, Rodolfo Ruiz-Velasco + * 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.musicmodifier; + +import net.runelite.api.*; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.*; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.chatbox.ChatboxPanelManager; +import net.runelite.client.game.chatbox.ChatboxTextInput; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +import javax.inject.Inject; +import java.io.File; + +@PluginDescriptor( + name = "Music Track Customizer", + description = "Customize what track plays and how it sounds, with local files", + tags = {"music", "sound"}, + enabledByDefault = false +) + +public class MusicCustomizerPlugin extends Plugin +{ + + @Inject + private Client client; + + @Inject + private ChatboxPanelManager chatboxPanelManager; + + @Inject + private ClientThread clientThread; + + private RealTimeMIDIPlayer realTimeMIDIPlayer = new RealTimeMIDIPlayer(); + + private String songName = "Scape Main"; + + private ChatboxTextInput songInput; + + private Widget playlistModeButton; + + private Widget playlistBox; + + private Widget hidePlaylistButton; + + private Widget addPlaylistSongButton; + + private Widget playlistText; + + private Widget playlistSong; + + private String defaultUnlockedSongs; + + private boolean isLooping = true; + + private boolean playlistMode = false; + + private int newSongY = 34; + + private int playlistCount = 0; + + @Override + public void startUp() + { + playSong(songName); + } + + @Override + public void shutDown() + { + if (realTimeMIDIPlayer != null) + { + realTimeMIDIPlayer.stopSong(); + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + try + { + if (!playlistMode) + { + String newSong = client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME).getText(); + + if (!newSong.equals(songName)) + { + songName = newSong; + playSongFromList(songName); + } + } + } catch (NullPointerException ignored) + { + + } + + } + + private void playSong(String song) + { + File midiMusicFile = new File(System.getProperty("user.home") + "/RuneLiteAudio/MIDI Files/" + + "Music/" + song + ".mid/"); + if (realTimeMIDIPlayer.midi == null) + { + realTimeMIDIPlayer.midi = midiMusicFile; + realTimeMIDIPlayer.run(); + } + + else + { + if (realTimeMIDIPlayer.isPlaying()) + { + realTimeMIDIPlayer.stopSong(); + } + realTimeMIDIPlayer.midi = midiMusicFile; + realTimeMIDIPlayer.run(); + } + } + + @Subscribe + private void onWidgetLoaded(WidgetLoaded widgetLoaded) + { + if (widgetLoaded.getGroupId() == WidgetID.MUSICTAB_GROUP_ID) + { + Widget musicPlayerSongs = client.getWidget(WidgetInfo.MUSICTAB_ALL_SONGS); + if (musicPlayerSongs != null) + { + playlistModeButton = musicPlayerSongs.createChild(-1, WidgetType.GRAPHIC); + playlistModeButton.setSpriteId(SpriteID.RS2_TAB_MUSIC); + playlistModeButton.setOriginalWidth(32); + playlistModeButton.setOriginalHeight(32); + playlistModeButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_RIGHT); + playlistModeButton.setOriginalX(0); + playlistModeButton.setOriginalY(0); + playlistModeButton.setHasListener(true); + playlistModeButton.setAction(1, "Open"); + playlistModeButton.setOnOpListener((JavaScriptCallback) e -> openPlaylist()); + playlistModeButton.setName("Playlist"); + playlistModeButton.setHidden(true); //Playlist is not enabled for this release (Unfinished). + playlistModeButton.revalidate(); + } + } + } + + private void openPlaylist() + { + playlistMode = true; + + Widget currentPlayingSong = client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME); + Widget allInGameSongs = client.getWidget(WidgetInfo.MUSICTAB_ALL_SONGS); + Widget musicScrollbar = client.getWidget(WidgetInfo.MUSICTAB_SCROLLBAR); + allInGameSongs.setHidden(true); + musicScrollbar.setHidden(true); + + defaultUnlockedSongs = client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).getText(); + + client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).setText(playlistCount + " / 10"); + + playlistBox = client.getWidget(WidgetInfo.MUSICTAB_INTERFACE); + + playlistText = playlistBox.createChild(-1, WidgetType.TEXT); + playlistText.setText("Music Playlist"); + playlistText.setFontId(497); + playlistText.setXPositionMode(WidgetPositionMode.ABSOLUTE_TOP); + playlistText.setOriginalX(40); + playlistText.setOriginalY(14); + playlistText.setOriginalHeight(1); + playlistText.setOriginalWidth(1); + playlistText.setTextColor(currentPlayingSong.getTextColor()); + playlistText.revalidate(); + + hidePlaylistButton = playlistBox.createChild(-1, WidgetType.GRAPHIC); + hidePlaylistButton.setSpriteId(SpriteID.RS2_TAB_MUSIC); + hidePlaylistButton.setOriginalWidth(32); + hidePlaylistButton.setOriginalHeight(32); + hidePlaylistButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_RIGHT); + hidePlaylistButton.setOriginalX(0); + hidePlaylistButton.setOriginalY(6); + hidePlaylistButton.setHasListener(true); + hidePlaylistButton.setAction(1, "Close"); + hidePlaylistButton.setOnOpListener((JavaScriptCallback) e -> closePlaylist()); + hidePlaylistButton.setName("Playlist"); + hidePlaylistButton.revalidate(); + + addPlaylistSongButton = playlistBox.createChild(-1, WidgetType.GRAPHIC); + addPlaylistSongButton.setSpriteId(SpriteID.BANK_ADD_TAB_ICON); + addPlaylistSongButton.setOriginalWidth(36); + addPlaylistSongButton.setOriginalHeight(32); + addPlaylistSongButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_LEFT); + addPlaylistSongButton.setOriginalX(0); + addPlaylistSongButton.setOriginalY(6); + addPlaylistSongButton.setHasListener(true); + addPlaylistSongButton.setAction(1, "Add to"); + addPlaylistSongButton.setOnOpListener((JavaScriptCallback) e -> addSongFromInput()); + addPlaylistSongButton.setName("Playlist"); + addPlaylistSongButton.revalidate(); + + if (playlistSong != null) + { + playlistSong.setHidden(false); + } + } + + private void closePlaylist() + { + playlistMode = false; + + Widget allInGameSongs = client.getWidget(WidgetInfo.MUSICTAB_ALL_SONGS); + Widget musicScrollbar = client.getWidget(WidgetInfo.MUSICTAB_SCROLLBAR); + allInGameSongs.setHidden(false); + musicScrollbar.setHidden(false); + + client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).setText(defaultUnlockedSongs); + playlistText.setHidden(true); + addPlaylistSongButton.setHidden(true); + hidePlaylistButton.setHidden(true); + + if (playlistSong != null) + { + playlistSong.setHidden(true); + } + } + + private void addSongFromInput() + { + addPlaylistSongButton.setAction(1, "Close search"); + addPlaylistSongButton.setOnOpListener((JavaScriptCallback) e -> closeInput()); + songInput = chatboxPanelManager.openTextInput("Please type a valid song name") + .onChanged(s -> clientThread.invokeLater(() -> updateSongs(s))) + .onClose(() -> + { + clientThread.invokeLater(() -> updateSongs(songInput.getValue())); + addPlaylistSongButton.setOnOpListener((JavaScriptCallback) e -> addSongFromInput()); + addPlaylistSongButton.setAction(1, "Add to"); + }) + .build(); + } + + private void updateSongs() + { + String song = ""; + if (chatboxIsOpen()) + { + song = songInput.getValue(); + } + updateSongs(song); + } + + private void updateSongs(String song) + { + if (playlistBox == null) + { + return; + } + + if (new File(System.getProperty("user.home") + "/RuneLiteAudio/MIDI Files/" + + "Music/" + song + ".mid/").exists()) + { + playListSongPlayer(song); + } + } + + private void playListSongPlayer(String song) + { + if (!song.equals(songName) && !chatboxIsOpen() && playlistCount < 10) + { + Widget playlistWidget = client.getWidget(WidgetInfo.MUSICTAB_INTERFACE); + playlistSong = playlistWidget.createChild(-1, WidgetType.TEXT); + playlistSong.setText(song); + playlistSong.setFontId(495); + playlistSong.setOriginalX(12); + playlistSong.setOriginalY(newSongY); + playlistSong.setOriginalWidth(120); + playlistSong.setOriginalHeight(16); + playlistSong.setTextColor(client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME).getTextColor()); + playlistSong.setHasListener(true); + playlistSong.setAction(1, "Play"); + playlistSong.setOnOpListener((JavaScriptCallback) e -> playSongFromList(song)); + playlistSong.setName(song); + playlistSong.revalidate(); + + newSongY = newSongY + 15; + + songName = song; + + playlistCount++; + client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).setText(playlistCount + " / 10"); + + if (playlistCount == 10) + { + addPlaylistSongButton.setHidden(true); + } + } + } + + private boolean chatboxIsOpen() + { + return songInput != null && chatboxPanelManager.getCurrentInput() == songInput; + } + + private void closeInput() + { + updateSongs(); + chatboxPanelManager.close(); + } + + private void playSongFromList(String song) + { + client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME).setName(song); + File midiMusicFile = new File(System.getProperty("user.home") + "/RuneLiteAudio/MIDI Files/" + + "Music/" + song + ".mid/"); + + if (realTimeMIDIPlayer.midi == null) + { + realTimeMIDIPlayer.midi = midiMusicFile; + realTimeMIDIPlayer.run(); + } + + else + { + if (realTimeMIDIPlayer.isPlaying()) + { + realTimeMIDIPlayer.stopSong(); + } + realTimeMIDIPlayer.midi = midiMusicFile; + realTimeMIDIPlayer.run(); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/RealTimeMIDIPlayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/RealTimeMIDIPlayer.java new file mode 100644 index 0000000000..858c7465fd --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/musicmodifier/RealTimeMIDIPlayer.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2019, Rodolfo Ruiz-Velasco + * 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.musicmodifier; + +import com.sun.media.sound.AudioSynthesizer; + +import javax.sound.midi.*; +import javax.sound.sampled.*; +import java.io.*; +import java.util.HashMap; +import java.util.Map; + +public class RealTimeMIDIPlayer implements Runnable +{ + private AudioFormat format; + + private Sequence midiSequence; + + private Soundbank soundbank; + + private SourceDataLine sdl; + + private MusicCustomizerPlugin customMusicPlugin; + + private MidiFileAdjuster adjuster; + + private Clip clip; + + public boolean looping = true; + + public File soundFont = new File(System.getProperty("user.home") + "/RuneLiteAudio/SoundFonts/" + + "RuneScape 2.sf2/"); + + public File midi; + + @Override + public void run() { + + try { + + adjuster = new MidiFileAdjuster(); //Unfinished class + + midiSequence = MidiSystem.getSequence(midi); + soundbank = MidiSystem.getSoundbank(soundFont); + init(); + } + catch (IOException | InvalidMidiDataException e) + { + e.printStackTrace(); + } + } + + public void stopSong() + { + if (sdl.isRunning()) + { + sdl.stop(); + } + } + + public static AudioSynthesizer findAudioSynthesizer() throws MidiUnavailableException + { + Synthesizer synth = MidiSystem.getSynthesizer(); + if (synth instanceof AudioSynthesizer) + return (AudioSynthesizer) synth; + + double gain = 0.8D; + + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + MidiChannel[] channels = synth.getChannels(); + + for (int i = 0; i < channels.length; i++) + { + channels[i].controlChange(7, ((int) (channels[i].getController(7) * gain))); + } + + for (int i = 0; i < infos.length; i++) + { + MidiDevice device = MidiSystem.getMidiDevice(infos[i]); + + if (device instanceof AudioSynthesizer) + return (AudioSynthesizer) device; + } + return null; + } + + public boolean isPlaying() + { + return sdl.isActive(); + } + + public static double send(Sequence sequence, Receiver receiver) { + float divtype = sequence.getDivisionType(); + assert (sequence.getDivisionType() == Sequence.PPQ); + Track[] tracks = sequence.getTracks(); + int[] trackspos = new int[tracks.length]; + int mpq = 500000; + int seqres = sequence.getResolution(); + long lasttick = 0; + long curtime = 0; + while (true) { + MidiEvent selevent = null; + int seltrack = -1; + for (int i = 0; i < tracks.length; i++) { + int trackpos = trackspos[i]; + Track track = tracks[i]; + if (trackpos < track.size()) { + MidiEvent event = track.get(trackpos); + if (selevent == null + || event.getTick() < selevent.getTick()) { + selevent = event; + seltrack = i; + } + } + } + if (seltrack == -1) + break; + trackspos[seltrack]++; + long tick = selevent.getTick(); + if (divtype == Sequence.PPQ) + curtime += ((tick - lasttick) * mpq) / seqres; + else + curtime = (long) ((tick * 1000000.0 * divtype) / seqres); + lasttick = tick; + MidiMessage msg = selevent.getMessage(); + if (msg instanceof MetaMessage) { + if (divtype == Sequence.PPQ) + if (((MetaMessage) msg).getType() == 0x51) { + byte[] data = ((MetaMessage) msg).getData(); + mpq = ((data[0] & 0xff) << 16) + | ((data[1] & 0xff) << 8) | (data[2] & 0xff); + } + } else { + if (receiver != null) + receiver.send(msg, curtime); + } + } + return curtime / 1000000.0; + } + + public void init() { + new Thread(new Runnable() { + @Override + public void run() { + + AudioSynthesizer synth = null; + try { + synth = findAudioSynthesizer(); + format = new AudioFormat(44100, 16, 2, true, false); + + Map info = new HashMap(); + info.put("resamplerType", "sinc"); + info.put("maxPolyphony", "8192"); + AudioInputStream ais = synth.openStream(format, info); + synth.unloadAllInstruments(synth.getDefaultSoundbank()); + synth.loadAllInstruments(soundbank); + double total = send(midiSequence, synth.getReceiver()); + long length = (long) (ais.getFormat().getFrameRate() * (total + 4)); + AudioInputStream stream = new AudioInputStream(ais, format, length); + sdl = AudioSystem.getSourceDataLine(format); + sdl.open(format); + sdl.start(); + writeAudio(sdl, stream); + } catch (LineUnavailableException | MidiUnavailableException e) { + e.printStackTrace(); + } + } + }).start(); + } + + public void writeAudio(SourceDataLine sdl, AudioInputStream stream) + { + new Thread(new Runnable() { + @Override + public void run() { + + byte[] sampledAudio = new byte[1024]; + + int numBytesRead = 0; + + while (numBytesRead != -1) { + try + { + numBytesRead = stream.read(sampledAudio, 0, sampledAudio.length); + + if (numBytesRead >= 0) { + sdl.write(sampledAudio, 0, numBytesRead); + } + } + + catch (IOException e) + { + e.printStackTrace(); + } + + finally { + + if (!isPlaying() && looping) + { + this.run(); + } + } + } + } + }).start(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java new file mode 100644 index 0000000000..8bce5b84b7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java @@ -0,0 +1,11 @@ +package net.runelite.client.plugins.nexthitnotifier; + + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; + +@ConfigGroup("nexthitnotifier") +public interface NextHitNotifierConfig extends Config +{ + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java new file mode 100644 index 0000000000..fe47f37307 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java @@ -0,0 +1,59 @@ +package net.runelite.client.plugins.nexthitnotifier; + +import net.runelite.api.Client; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; +import net.runelite.client.util.MiscUtils; + +import javax.inject.Inject; +import java.awt.*; + +public class NextHitNotifierOverlay extends Overlay +{ + private final Client client; + private final NextHitNotifierPlugin plugin; + private final NextHitNotifierConfig config; + + private final PanelComponent panelComponent = new PanelComponent(); + private final Dimension panelSize = new Dimension(48, 0); + + @Inject + private NextHitNotifierOverlay(Client client, NextHitNotifierPlugin plugin, NextHitNotifierConfig config) + { + setPosition(OverlayPosition.BOTTOM_LEFT); + //setPosition(OverlayPosition.DYNAMIC); + //setPosition(OverlayPosition.DETACHED); + + this.client = client; + this.plugin = plugin; + this.config = config; + } + + @Override + public Dimension render(Graphics2D graphics) + { + panelComponent.getChildren().clear(); + panelComponent.setPreferredSize(panelSize); + + String lastHitText = Integer.toString(plugin.lastHit); + int lastHit = plugin.lastHit; + + if (plugin.showTime < 0) + { + lastHitText = "0"; + lastHit = 0; + } + + int g = (int)MiscUtils.clamp((float)Math.floor(lastHit / 30.f) * 255.f, 0.f, 255.f); + int r = 255 - g; + + Color textColor = Color.getHSBColor(Color.RGBtoHSB(r, g, 0, null)[0], 1.f, 1.f); + + panelComponent.getChildren().add(TitleComponent.builder().text("Next hit:").color(Color.YELLOW).build()); + panelComponent.getChildren().add(TitleComponent.builder().text(lastHitText).color(textColor).build()); + + return panelComponent.render(graphics); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..ccece4d4a4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java @@ -0,0 +1,116 @@ +package net.runelite.client.plugins.nexthitnotifier; + +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.Skill; +import net.runelite.api.events.ExperienceChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +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 javax.inject.Inject; + +@PluginDescriptor( + name = "!Next Hit Notifier", + description = "Shows estimated next hit based on xp drop.", + tags = { "experience", "damage", "overlay", "pking", "bogla" }, + enabledByDefault = false +) +public class NextHitNotifierPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private OverlayManager overlayManager; + + @Inject + private NextHitNotifierOverlay overlay; + + private int lastHpXp = 0; + int lastHit = 0; + int showTime = 0; + + @Provides + NextHitNotifierConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(NextHitNotifierConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOGGED_IN) + { + lastHpXp = client.getSkillExperience(Skill.HITPOINTS); + lastHit = 0; + showTime = 0; + } + else + { + lastHpXp = 0; + lastHit = 0; + showTime = 0; + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (showTime > 0) + showTime--; + else + lastHit = 0; + } + + @Subscribe + public void onExperienceChanged(ExperienceChanged event) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + lastHpXp = 0; + lastHit = 0; + showTime = 0; + return; + } + + final Skill skill = event.getSkill(); + + if (skill != Skill.HITPOINTS) + return; + + final int currentXp = client.getSkillExperience(skill); + + int gainedXp = currentXp - lastHpXp; + + //filter out big xp drops (such as login) + if (gainedXp > 1000) + { + lastHpXp = client.getSkillExperience(skill); + return; + } + + lastHit = (int)Math.rint(gainedXp / 1.33f); + lastHpXp = currentXp; + showTime = 3; + } + + +} 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 new file mode 100644 index 0000000000..74a733a7eb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionConfig.java @@ -0,0 +1,55 @@ +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 new file mode 100644 index 0000000000..fc844eb734 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionMinimapOverlay.java @@ -0,0 +1,43 @@ +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 new file mode 100644 index 0000000000..b36b91da7b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionOverlay.java @@ -0,0 +1,55 @@ +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 new file mode 100644 index 0000000000..6fc74fb2c2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionPlugin.java @@ -0,0 +1,135 @@ +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 new file mode 100644 index 0000000000..770cbd6505 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionService.java @@ -0,0 +1,63 @@ +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 new file mode 100644 index 0000000000..aba6c3fad6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionTileOverlay.java @@ -0,0 +1,44 @@ +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/plankmakehelper/PlankMakeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java new file mode 100644 index 0000000000..8295f294b1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java @@ -0,0 +1,88 @@ +package net.runelite.client.plugins.plankmakehelper; + +import net.runelite.api.*; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetItem; +import net.runelite.client.ui.overlay.*; + +import javax.inject.Inject; +import java.awt.*; + +public class PlankMakeOverlay extends Overlay { + + private final PlankMakePlugin plugin; + private final Client client; + + @Inject + public PlankMakeOverlay(final PlankMakePlugin plugin, final Client client) { + super(plugin); + this.plugin = plugin; + this.client = client; + + setPosition(OverlayPosition.DETACHED); + setLayer(OverlayLayer.ALWAYS_ON_TOP); + setPriority(OverlayPriority.MED); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (hasPlankableItems()) { + renderInventory(graphics); + renderPlankMakeSpell(graphics); + } + return null; + } + + private void renderInventory(Graphics2D graphics) { + Widget inventory = client.getWidget(WidgetInfo.INVENTORY); + + int firstItemSeenIndex = -1; + + if (inventory != null) { + for (WidgetItem item : inventory.getWidgetItems()) { + if (PlankMakePlugin.isLogAndPlankable(item.getId())) { + if (firstItemSeenIndex == -1) { + firstItemSeenIndex = item.getIndex(); + } + if (!inventory.isHidden()) { + if (item.getIndex() != firstItemSeenIndex) { + OverlayUtil.renderPolygon(graphics, RectangleToPolygon(item.getCanvasBounds()), Color.BLUE); + } + } + } + } + if (firstItemSeenIndex != -1) { + OverlayUtil.renderPolygon(graphics, RectangleToPolygon(inventory.getWidgetItem(firstItemSeenIndex).getCanvasBounds()), Color.CYAN); + } + } + } + + private void renderPlankMakeSpell(Graphics2D graphics) { + Widget plankMakeSpell = client.getWidget(218,128); + if (plankMakeSpell != null && (plankMakeSpell.getCanvasLocation().getX() != 29 & plankMakeSpell.getCanvasLocation().getY() != 32)) { + OverlayUtil.renderPolygon(graphics, RectangleToPolygon(plankMakeSpell.getBounds()), Color.CYAN); + } + } + + private boolean hasPlankableItems() { + ItemContainer invo = client.getItemContainer(InventoryID.INVENTORY); + if (invo != null) { + if (invo.getItems().length > 0) { + for (Item item : invo.getItems()) { + if (PlankMakePlugin.isLogAndPlankable(item.getId())) { + return true; + } + } + } + } + return false; + } + + static Polygon RectangleToPolygon(Rectangle rect) { + int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x}; + int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height}; + return new Polygon(xpoints, ypoints, 4); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java new file mode 100644 index 0000000000..4c5a72001e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java @@ -0,0 +1,49 @@ +package net.runelite.client.plugins.plankmakehelper; + +import net.runelite.api.Client; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +import javax.inject.Inject; + +@PluginDescriptor( + name = "Plank Make Helper", + description = "Highlights planks and plank make spell", + tags = {"overlay", "plankmaking", "lunar", "money", "moneymaking", "gp"} +) + +public class PlankMakePlugin extends Plugin { + + @Inject + private OverlayManager overlayManager; + + @Inject + private Client client; + + @Inject + private PlankMakeOverlay overlay; + + @Override + protected void startUp() { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() { + overlayManager.remove(overlay); + } + + static boolean isLogAndPlankable(int itemID) { + switch (itemID) { + case 6332: //mahogany + case 1521: //oak + case 6333: //teak + case 1511: //plain + return true; + default: + return false; + } + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java new file mode 100644 index 0000000000..6c1370ef76 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019, gazivodag + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.runelite.client.plugins.prayagainstplayer; + +import net.runelite.api.Player; + +/** + * Contains a player object + * When they attacked me + * And (in milliseconds) when to expire the overlay around them + */ +public class PlayerContainer { + + private Player player; + private long whenTheyAttackedMe; + private int millisToExpireHighlight; + + public PlayerContainer(Player player, long whenTheyAttackedMe, int millisToExpireHighlight) { + this.player = player; + this.whenTheyAttackedMe = whenTheyAttackedMe; + this.millisToExpireHighlight = millisToExpireHighlight; + } + + + //getters + public Player getPlayer() { + return player; + } + public long getWhenTheyAttackedMe() { + return whenTheyAttackedMe; + } + public int getMillisToExpireHighlight() { return millisToExpireHighlight; }; + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java new file mode 100644 index 0000000000..ce453fd3d9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2019, gazivodag + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.runelite.client.plugins.prayagainstplayer; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +import java.awt.*; + +@ConfigGroup("prayagainstplayer") +public interface PrayAgainstPlayerConfig extends Config { + @ConfigItem( + position = 0, + keyName = "attackerPlayerColor", + name = "Attacker color", + description = "This is the color that will be used to highlight attackers." + ) + default Color attackerPlayerColor() { return new Color(0xFF0006); } + + @ConfigItem( + position = 1, + keyName = "potentialPlayerColor", + name = "Potential Attacker color", + description = "This is the color that will be used to highlight potential attackers." + ) + default Color potentialPlayerColor() { return new Color(0xFFFF00); } + + //// + @ConfigItem( + position = 2, + keyName = "attackerTargetTimeout", + name = "Attacker Timeout", + description = "Seconds until attacker is no longer highlighted." + ) + default int attackerTargetTimeout() { return 10; } + + @ConfigItem( + position = 3, + keyName = "potentialTargetTimeout", + name = "Potential Attacker Timeout", + description = "Seconds until potential attacker is no longer highlighted." + ) + default int potentialTargetTimeout() { return 10; } + + @ConfigItem( + position = 4, + keyName = "newSpawnTimeout", + name = "New Player Timeout", + description = "Seconds until logged in/spawned player is no longer highlighted." + ) + default int newSpawnTimeout() { return 5; } + //// + + //// + @ConfigItem( + position = 5, + keyName = "ignoreFriends", + name = "Ignore Friends", + description = "This lets you decide whether you want friends to be highlighted by this plugin." + ) + default boolean ignoreFriends() { return true; } + + @ConfigItem( + position = 6, + keyName = "ignoreClanMates", + name = "Ignore Clan Mates", + description = "This lets you decide whether you want clan mates to be highlighted by this plugin." + ) + default boolean ignoreClanMates() { return true; } + //// + + @ConfigItem( + position = 7, + keyName = "markNewPlayer", + name = "Mark new player as potential attacker", + description = "Marks someone that logged in or teleported as a potential attacker for your safety\nDO NOT RUN THIS IN WORLD 1-2 GRAND EXCHANGE!" + ) + default boolean markNewPlayer() { return false; } + + @ConfigItem( + position = 8, + keyName = "drawTargetPrayAgainst", + name = "Draw what to pray on attacker", + description = "Tells you what to pray from what weapon the attacker is holding" + ) + default boolean drawTargetPrayAgainst() { return true; } + + @ConfigItem( + position = 9, + keyName = "drawPotentialTargetPrayAgainst", + name = "Draw what to pray on potential attacker", + description = "Tells you what to pray from what weapon the potential attacker is holding" + ) + default boolean drawPotentialTargetPrayAgainst() { return true; } + + @ConfigItem( + position = 10, + keyName = "drawTargetPrayAgainstPrayerTab", + name = "Draw what to pray from prayer tab", + description = "Tells you what to pray from what weapon the attacker is holding from the prayer tab" + ) + default boolean drawTargetPrayAgainstPrayerTab() { return false; } + + @ConfigItem( + position = 11, + keyName = "drawTargetsName", + name = "Draw name on attacker", + description = "Configures whether or not the attacker\'s name should be shown" + ) + default boolean drawTargetsName() { return true; } + + @ConfigItem( + position = 12, + keyName = "drawPotentialTargetsName", + name = "Draw name on potential attacker", + description = "Configures whether or not the potential attacker\'s name should be shown" + ) + default boolean drawPotentialTargetsName() { return true; } + + @ConfigItem( + position = 13, + keyName = "drawTargetHighlight", + name = "Draw highlight around attacker", + description = "Configures whether or not the attacker should be highlighted" + ) + default boolean drawTargetHighlight() { return true; } + + @ConfigItem( + position = 14, + keyName = "drawPotentialTargetHighlight", + name = "Draw highlight around potential attacker", + description = "Configures whether or not the potential attacker should be highlighted" + ) + default boolean drawPotentialTargetHighlight() { return true; } + + @ConfigItem( + position = 15, + keyName = "drawTargetTile", + name = "Draw tile under attacker", + description = "Configures whether or not the attacker\'s tile be highlighted" + ) + default boolean drawTargetTile() { return false; } + + @ConfigItem( + position = 16, + keyName = "drawPotentialTargetTile", + name = "Draw tile under potential attacker", + description = "Configures whether or not the potential attacker\'s tile be highlighted" + ) + default boolean drawPotentialTargetTile() { return false; } + + @ConfigItem( + position = 17, + keyName = "drawUnknownWeapons", + name = "Draw unknown weapons", + description = "Configures whether or not the unknown weapons should be shown when a player equips one" + ) + default boolean drawUnknownWeapons() { return false; } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java new file mode 100644 index 0000000000..e54efd8127 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2019, gazivodag + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.runelite.client.plugins.prayagainstplayer; + +import net.runelite.api.Client; +import net.runelite.api.ItemComposition; +import net.runelite.api.Player; +import net.runelite.api.kit.KitType; +import net.runelite.client.ui.overlay.*; +import net.runelite.client.util.Text; +import net.runelite.api.Point; + +import javax.inject.Inject; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.ConcurrentModificationException; + +class PrayAgainstPlayerOverlay extends Overlay { + + private final PrayAgainstPlayerPlugin plugin; + private final PrayAgainstPlayerConfig config; + private final Client client; + + @Inject + private PrayAgainstPlayerOverlay(PrayAgainstPlayerPlugin plugin, PrayAgainstPlayerConfig config, Client client) { + super(plugin); + this.plugin = plugin; + this.config = config; + this.client = client; + + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + } + + + @Override + public Dimension render(Graphics2D graphics) { + renderPotentialPlayers(graphics); + renderAttackingPlayers(graphics); + return null; + } + + private void renderPotentialPlayers(Graphics2D graphics) { + if (plugin.getPotentialPlayersAttackingMe() == null || !plugin.getPotentialPlayersAttackingMe().isEmpty()) { + try { + for (PlayerContainer container : plugin.getPotentialPlayersAttackingMe()) { + if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) { + plugin.removePlayerFromPotentialContainer(container); + } + if (config.drawPotentialTargetsName()) renderNameAboveHead(graphics, container.getPlayer(), config.potentialPlayerColor()); + if (config.drawPotentialTargetHighlight()) renderHighlightedPlayer(graphics, container.getPlayer(), config.potentialPlayerColor()); + if (config.drawPotentialTargetTile()) renderTileUnderPlayer(graphics, container.getPlayer(), config.potentialPlayerColor()); + if (config.drawPotentialTargetPrayAgainst()) renderPrayAgainstOnPlayer(graphics, container.getPlayer(), config.potentialPlayerColor()); + } + } catch (ConcurrentModificationException e) { + } + } + } + + private void renderAttackingPlayers(Graphics2D graphics) { + if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) { + try { + for (PlayerContainer container : plugin.getPlayersAttackingMe()) { + if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) { + plugin.removePlayerFromAttackerContainer(container); + } + + if (config.drawTargetsName()) renderNameAboveHead(graphics, container.getPlayer(), config.attackerPlayerColor()); + if (config.drawTargetHighlight()) renderHighlightedPlayer(graphics, container.getPlayer(), config.attackerPlayerColor()); + if (config.drawTargetTile()) renderTileUnderPlayer(graphics, container.getPlayer(), config.attackerPlayerColor()); + if (config.drawTargetPrayAgainst()) renderPrayAgainstOnPlayer(graphics, container.getPlayer(), config.attackerPlayerColor()); + } + } catch (ConcurrentModificationException e) { + } + } + } + + private void renderNameAboveHead(Graphics2D graphics, Player player, Color color) { + final String name = Text.sanitize(player.getName()); + final int offset = player.getLogicalHeight() + 40; + Point textLocation = player.getCanvasTextLocation(graphics, name, offset); + if (textLocation != null) { + OverlayUtil.renderTextLocation(graphics, textLocation, name, color); + } + } + + private void renderHighlightedPlayer(Graphics2D graphics, Player player, Color color) { + try { + OverlayUtil.renderPolygon(graphics, player.getConvexHull(), color); + } catch (NullPointerException e) { + } + } + + private void renderTileUnderPlayer(Graphics2D graphics, Player player, Color color) { + Polygon poly = player.getCanvasTilePoly(); + OverlayUtil.renderPolygon(graphics, poly, color); + } + + private void renderPrayAgainstOnPlayer(Graphics2D graphics, Player player, Color color) { + final int offset = (player.getLogicalHeight() / 2) + 75; + BufferedImage icon; + + switch (WeaponType.checkWeaponOnPlayer(client, player)) { + case WEAPON_MELEE: + icon = plugin.getProtectionIcon(WeaponType.WEAPON_MELEE); + break; + case WEAPON_MAGIC: + icon = plugin.getProtectionIcon(WeaponType.WEAPON_MAGIC); + break; + case WEAPON_RANGED: + icon = plugin.getProtectionIcon(WeaponType.WEAPON_RANGED); + break; + default: + icon = null; + break; + } + try { + if (icon != null) { + Point point = player.getCanvasImageLocation(icon, offset); + OverlayUtil.renderImageLocation(graphics, point, icon); + } else { + if (config.drawUnknownWeapons()) { + int itemId = player.getPlayerComposition().getEquipmentId(KitType.WEAPON); + ItemComposition itemComposition = client.getItemDefinition(itemId); + + final String str = itemComposition.getName().toUpperCase(); + Point point = player.getCanvasTextLocation(graphics, str, offset); + OverlayUtil.renderTextLocation(graphics, point, str, color); + } + } + } catch (Exception e) { + } + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java new file mode 100644 index 0000000000..4e505675f6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2019, gazivodag + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.runelite.client.plugins.prayagainstplayer; + +import net.runelite.api.Client; +import net.runelite.api.Player; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.ui.overlay.*; + +import javax.inject.Inject; +import java.awt.*; +import java.util.ConcurrentModificationException; + +class PrayAgainstPlayerOverlayPrayerTab extends Overlay { + + private final PrayAgainstPlayerPlugin plugin; + private final PrayAgainstPlayerConfig config; + private final Client client; + + @Inject + private PrayAgainstPlayerOverlayPrayerTab (PrayAgainstPlayerPlugin plugin, PrayAgainstPlayerConfig config, Client client) { + super(plugin); + this.plugin = plugin; + this.config = config; + this.client = client; + + setPosition(OverlayPosition.DETACHED); + setLayer(OverlayLayer.ALWAYS_ON_TOP); + setPriority(OverlayPriority.MED); + } + + + @Override + public Dimension render(Graphics2D graphics) { + if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) { + try { + for (PlayerContainer container : plugin.getPlayersAttackingMe()) { + if (plugin.getPlayersAttackingMe() != null && plugin.getPlayersAttackingMe().size() > 0) { + //no reason to show you what prayers to pray in your prayer tab if multiple people are attacking you + if ((plugin.getPlayersAttackingMe().size() == 1) && (config.drawTargetPrayAgainstPrayerTab())) { + renderPrayerToClick(graphics, container.getPlayer()); + } + } + } + } catch (ConcurrentModificationException e) { + } + } + return null; + } + + private void renderPrayerToClick(Graphics2D graphics, Player player) { + Widget PROTECT_FROM_MAGIC = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MAGIC); + Widget PROTECT_FROM_RANGED = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MISSILES); + Widget PROTECT_FROM_MELEE = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MELEE); + Color color = Color.RED; + if (PROTECT_FROM_MELEE.isHidden()) return; + switch (WeaponType.checkWeaponOnPlayer(client, player)) { + case WEAPON_MAGIC: + OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MAGIC.getBounds()), color); + break; + case WEAPON_MELEE: + OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MELEE.getBounds()), color); + break; + case WEAPON_RANGED: + OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_RANGED.getBounds()), color); + break; + default: + break; + } + } + + private static Polygon rectangleToPolygon(Rectangle rect) { + int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x}; + int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height}; + return new Polygon(xpoints, ypoints, 4); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java new file mode 100644 index 0000000000..5664621b60 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2019, gazivodag + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.runelite.client.plugins.prayagainstplayer; + +import com.google.inject.Provides; +import net.runelite.api.*; +import net.runelite.api.events.*; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.ImageUtil; + +import javax.inject.Inject; +import java.awt.*; +import java.awt.image.*; +import java.util.ArrayList; +import java.util.Arrays; + +@PluginDescriptor( + name = "!Pray Against Player", + description = "Use plugin in PvP situations for best results!!", + tags = {"highlight", "pvp", "overlay", "players"} +) + +/** + * I am fully aware that there is plenty of overhead and is a MESS! + * If you'd like to contribute please do! + */ +public class PrayAgainstPlayerPlugin extends Plugin { + + private static final int[] PROTECTION_ICONS = { + SpriteID.PRAYER_PROTECT_FROM_MISSILES, + SpriteID.PRAYER_PROTECT_FROM_MELEE, + SpriteID.PRAYER_PROTECT_FROM_MAGIC + }; + private static final Dimension PROTECTION_ICON_DIMENSION = new Dimension(33, 33); + private static final Color PROTECTION_ICON_OUTLINE_COLOR = new Color(33, 33, 33); + public final BufferedImage[] ProtectionIcons = new BufferedImage[PROTECTION_ICONS.length]; + + private ArrayList potentialPlayersAttackingMe; + private ArrayList playersAttackingMe; + + @Inject + private Client client; + + @Inject + private SpriteManager spriteManager; + + @Inject + private OverlayManager overlayManager; + + @Inject + private PrayAgainstPlayerOverlay overlay; + + @Inject + private PrayAgainstPlayerOverlayPrayerTab overlayPrayerTab; + + @Inject + private PrayAgainstPlayerConfig config; + + @Provides + PrayAgainstPlayerConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(PrayAgainstPlayerConfig.class); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged gameStateChanged) { + if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { + loadProtectionIcons(); + } + } + + @Override + protected void startUp() { + potentialPlayersAttackingMe = new ArrayList<>(); + playersAttackingMe = new ArrayList<>(); + overlayManager.add(overlay); + overlayManager.add(overlayPrayerTab); + } + + @Override + protected void shutDown() throws Exception { + overlayManager.remove(overlay); + overlayManager.remove(overlayPrayerTab); + } + + @Subscribe + protected void onAnimationChanged(AnimationChanged animationChanged) { + if ((animationChanged.getActor() instanceof Player) && (animationChanged.getActor().getInteracting() instanceof Player) && (animationChanged.getActor().getInteracting() == client.getLocalPlayer())) { + Player sourcePlayer = (Player) animationChanged.getActor(); + + //is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list + if (client.isFriended(sourcePlayer.getName(), true) && config.ignoreFriends()) return; + if (client.isClanMember(sourcePlayer.getName()) && config.ignoreClanMates()) return; + + if ((sourcePlayer.getAnimation() != -1) && (!isBlockAnimation(sourcePlayer.getAnimation()))) { + //if attacker attacks again, reset his timer so overlay doesn't go away + if (findPlayerInAttackerList(sourcePlayer) != null) { + resetPlayerFromAttackerContainerTimer(findPlayerInAttackerList(sourcePlayer)); + } + //if he attacks and he was in the potential attackers list, remove him + if (!potentialPlayersAttackingMe.isEmpty() && potentialPlayersAttackingMe.contains(findPlayerInPotentialList(sourcePlayer))) { + removePlayerFromPotentialContainer(findPlayerInPotentialList(sourcePlayer)); + } + //if he's not in the attackers list, add him + if (findPlayerInAttackerList(sourcePlayer) == null) { + PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (config.attackerTargetTimeout() * 1000)); + playersAttackingMe.add(container); + } + } + } + } + + @Subscribe + protected void onInteractingChanged(InteractingChanged interactingChanged) { + //if someone interacts with you, add them to the potential attackers list + if ((interactingChanged.getSource() instanceof Player) && (interactingChanged.getTarget() instanceof Player)) { + Player sourcePlayer = (Player) interactingChanged.getSource(); + Player targetPlayer = (Player) interactingChanged.getTarget(); + if ((targetPlayer == client.getLocalPlayer()) && (findPlayerInPotentialList(sourcePlayer) == null)) { //we're being interacted with + + //is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list + if (client.isFriended(sourcePlayer.getName(), true) && config.ignoreFriends()) return; + if (client.isClanMember(sourcePlayer.getName()) && config.ignoreClanMates()) return; + + PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (config.potentialTargetTimeout() * 1000)); + potentialPlayersAttackingMe.add(container); + } + } + } + + @Subscribe + protected void onPlayerDespawned(PlayerDespawned playerDespawned) { + PlayerContainer container = findPlayerInAttackerList(playerDespawned.getPlayer()); + PlayerContainer container2 = findPlayerInPotentialList(playerDespawned.getPlayer()); + if (container != null) { + playersAttackingMe.remove(container); + } + if (container2 != null) { + potentialPlayersAttackingMe.remove(container2); + } + } + + @Subscribe + protected void onPlayerSpawned(PlayerSpawned playerSpawned) { + if (config.markNewPlayer()) { + Player p = playerSpawned.getPlayer(); + + if (client.isFriended(p.getName(), true) && config.ignoreFriends()) return; + if (client.isClanMember(p.getName()) && config.ignoreClanMates()) return; + + PlayerContainer container = findPlayerInPotentialList(p); + if (container == null) { + container = new PlayerContainer(p, System.currentTimeMillis(), (config.newSpawnTimeout() * 1000)); + potentialPlayersAttackingMe.add(container); + } + } + } + + PlayerContainer findPlayerInAttackerList(Player player) { + if (playersAttackingMe.isEmpty()) { + return null; + } + for (int i = 0 ; i < playersAttackingMe.size() ; i++) { + PlayerContainer container = playersAttackingMe.get(i); + if (container.getPlayer() == player) { + return container; + } + } + return null; + } + + PlayerContainer findPlayerInPotentialList(Player player) { + if (potentialPlayersAttackingMe.isEmpty()) { + return null; + } + for (int i = 0 ; i < potentialPlayersAttackingMe.size() ; i++) { + PlayerContainer container = potentialPlayersAttackingMe.get(i); + if (container.getPlayer() == player) { + return container; + } + } + return null; + } + + /** + * Resets player timer in case he attacks again, so his highlight doesn't go away so easily + * @param container + */ + public void resetPlayerFromAttackerContainerTimer(PlayerContainer container) { + removePlayerFromAttackerContainer(container); + PlayerContainer newContainer = new PlayerContainer(container.getPlayer(), System.currentTimeMillis(), (config.attackerTargetTimeout() * 1000)); + playersAttackingMe.add(newContainer); + } + + + public void removePlayerFromPotentialContainer(PlayerContainer container) { + if ((potentialPlayersAttackingMe != null) && (!potentialPlayersAttackingMe.isEmpty()) && (potentialPlayersAttackingMe.contains(container))) { + potentialPlayersAttackingMe.remove(container); + } + } + + public void removePlayerFromAttackerContainer(PlayerContainer container) { + if ((playersAttackingMe != null) && (!playersAttackingMe.isEmpty()) && (playersAttackingMe.contains(container))) { + playersAttackingMe.remove(container); + } + } + + private boolean isBlockAnimation(int anim) { + switch (anim) { + case AnimationID.BLOCK_DEFENDER: + case AnimationID.BLOCK_NO_SHIELD: + case AnimationID.BLOCK_SHIELD: + case AnimationID.BLOCK_SWORD: + case AnimationID.BLOCK_UNARMED: + return true; + default: + return false; + } + } + + public ArrayList getPotentialPlayersAttackingMe() { return potentialPlayersAttackingMe; } + public ArrayList getPlayersAttackingMe() { return playersAttackingMe; } + + //All of the methods below are from the Zulrah plugin!!! Credits to it's respective owner + private void loadProtectionIcons() { + final IndexedSprite[] protectionIcons = {}; + final IndexedSprite[] newProtectionIcons = Arrays.copyOf(protectionIcons, PROTECTION_ICONS.length); + int curPosition = 0; + + for (int i = 0; i < PROTECTION_ICONS.length; i++, curPosition++) + { + final int resource = PROTECTION_ICONS[i]; + ProtectionIcons[i] = rgbaToIndexedBufferedImage(ProtectionIconFromSprite(spriteManager.getSprite(resource, 0))); + newProtectionIcons[curPosition] = createIndexedSprite(client, ProtectionIcons[i]); + } + } + + private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) { + final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel(); + + final int width = bufferedImage.getWidth(); + final int height = bufferedImage.getHeight(); + final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); + final int[] palette = new int[indexedCM.getMapSize()]; + indexedCM.getRGBs(palette); + + final IndexedSprite newIndexedSprite = client.createIndexedSprite(); + newIndexedSprite.setPixels(pixels); + newIndexedSprite.setPalette(palette); + newIndexedSprite.setWidth(width); + newIndexedSprite.setHeight(height); + newIndexedSprite.setOriginalWidth(width); + newIndexedSprite.setOriginalHeight(height); + newIndexedSprite.setOffsetX(0); + newIndexedSprite.setOffsetY(0); + return newIndexedSprite; + } + + private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) { + final BufferedImage indexedImage = new BufferedImage( + sourceBufferedImage.getWidth(), + sourceBufferedImage.getHeight(), + BufferedImage.TYPE_BYTE_INDEXED); + + final ColorModel cm = indexedImage.getColorModel(); + final IndexColorModel icm = (IndexColorModel) cm; + + final int size = icm.getMapSize(); + final byte[] reds = new byte[size]; + final byte[] greens = new byte[size]; + final byte[] blues = new byte[size]; + icm.getReds(reds); + icm.getGreens(greens); + icm.getBlues(blues); + + final WritableRaster raster = indexedImage.getRaster(); + final int pixel = raster.getSample(0, 0, 0); + final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); + final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); + resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); + return resultIndexedImage; + } + + private static BufferedImage ProtectionIconFromSprite(final BufferedImage freezeSprite) { + final BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, PROTECTION_ICON_DIMENSION.width, PROTECTION_ICON_DIMENSION.height); + return ImageUtil.outlineImage(freezeCanvas, PROTECTION_ICON_OUTLINE_COLOR); + } + + BufferedImage getProtectionIcon(WeaponType weaponType) { + switch (weaponType) { + case WEAPON_RANGED: + return ProtectionIcons[0]; + case WEAPON_MELEE: + return ProtectionIcons[1]; + case WEAPON_MAGIC: + return ProtectionIcons[2]; + } + return null; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java new file mode 100644 index 0000000000..1dc00c8311 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019, gazivodag + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.runelite.client.plugins.prayagainstplayer; + +import net.runelite.api.Client; +import net.runelite.api.ItemComposition; +import net.runelite.api.Player; +import net.runelite.api.kit.KitType; + +enum WeaponType { + + WEAPON_MELEE, + WEAPON_RANGED, + WEAPON_MAGIC, + WEAPON_UNKNOWN; + + /** + * im fully aware this could of been done better!!! + * @param client + * @param attacker + * @return + */ + public static WeaponType checkWeaponOnPlayer (Client client, Player attacker) { + int itemId = attacker.getPlayerComposition().getEquipmentId(KitType.WEAPON); + ItemComposition itemComposition = client.getItemDefinition(itemId); + String weaponNameGivenLowerCase = itemComposition.getName().toLowerCase(); + + if (itemId == -1) return WEAPON_MELEE; + if (weaponNameGivenLowerCase == null || weaponNameGivenLowerCase.toLowerCase().contains("null")) return WEAPON_MELEE; + + for (String meleeWeaponName : meleeWeaponNames) { + if (weaponNameGivenLowerCase.contains(meleeWeaponName) && !weaponNameGivenLowerCase.contains("thrownaxe")) { + return WEAPON_MELEE; + } + } + + for (String rangedWeaponName : rangedWeaponNames) { + if (weaponNameGivenLowerCase.contains(rangedWeaponName)) { + return WEAPON_RANGED; + } + } + + for (String magicWeaponName : magicWeaponNames) { + if (weaponNameGivenLowerCase.contains(magicWeaponName)) { + return WEAPON_MAGIC; + } + } + + return WEAPON_UNKNOWN; + + } + + private static String[] meleeWeaponNames = { + "sword", + "scimitar", + "dagger", + "spear", + "mace", + "axe", + "whip", + "tentacle", + "-ket-", + "-xil-", + "warhammer", + "halberd", + "claws", + "hasta", + "scythe", + "maul", + "anchor", + "sabre", + "excalibur", + "machete", + "dragon hunter lance", + "event rpg", + "silverlight", + "darklight", + "arclight", + "flail", + "granite hammer", + "rapier", + "bulwark" + }; + + private static String[] rangedWeaponNames = { + "bow", + "blowpipe", + "xil-ul", + "knife", + "dart", + "thrownaxe", + "chinchompa", + "ballista" + }; + + private static String[] magicWeaponNames = { + "staff", + "trident", + "wand", + "dawnbringer" + }; + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java new file mode 100644 index 0000000000..cf27d2b78d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java @@ -0,0 +1,123 @@ +/* + * Decompiled with CFR 0.139. + */ +package net.runelite.client.plugins.profiles; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.util.ImageUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class ProfilePanel +extends JPanel { + private static final Logger log = LoggerFactory.getLogger(ProfilePanel.class); + private static final ImageIcon DELETE_ICON; + private static final ImageIcon DELETE_HOVER_ICON; + private final String loginText; + private String password = null; + + ProfilePanel(final Client client, final String data, final ProfilesConfig config) { + String[] parts = data.split(":"); + this.loginText = parts[1]; + if (parts.length == 3) { + this.password = parts[2]; + } + final ProfilePanel panel = this; + this.setLayout(new BorderLayout()); + this.setBackground(ColorScheme.DARKER_GRAY_COLOR); + JPanel labelWrapper = new JPanel(new BorderLayout()); + labelWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR); + labelWrapper.setBorder(new CompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR), BorderFactory.createLineBorder(ColorScheme.DARKER_GRAY_COLOR))); + JPanel panelActions = new JPanel(new BorderLayout(3, 0)); + panelActions.setBorder(new EmptyBorder(0, 0, 0, 8)); + panelActions.setBackground(ColorScheme.DARKER_GRAY_COLOR); + final JLabel delete = new JLabel(); + delete.setIcon(DELETE_ICON); + delete.setToolTipText("Delete account profile"); + delete.addMouseListener(new MouseAdapter(){ + + @Override + public void mousePressed(MouseEvent e) { + panel.getParent().remove(panel); + ProfilesPanel.removeProfile(data); + } + + @Override + public void mouseEntered(MouseEvent e) { + delete.setIcon(DELETE_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent e) { + delete.setIcon(DELETE_ICON); + } + }); + panelActions.add((Component)delete, "East"); + JLabel label = new JLabel(); + label.setText(parts[0]); + label.setBorder(null); + label.setBackground(ColorScheme.DARKER_GRAY_COLOR); + label.setPreferredSize(new Dimension(0, 24)); + label.setForeground(Color.WHITE); + label.setBorder(new EmptyBorder(0, 8, 0, 0)); + labelWrapper.add((Component)label, "Center"); + labelWrapper.add((Component)panelActions, "East"); + label.addMouseListener(new MouseAdapter(){ + + @Override + public void mousePressed(MouseEvent e) { + if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) { + client.setUsername(ProfilePanel.this.loginText); + if (config.rememberPassword() && ProfilePanel.this.password != null) { + client.setPassword(ProfilePanel.this.password); + } + } + } + }); + JPanel bottomContainer = new JPanel(new BorderLayout()); + bottomContainer.setBorder(new EmptyBorder(8, 0, 8, 0)); + bottomContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR); + bottomContainer.addMouseListener(new MouseAdapter(){ + + @Override + public void mousePressed(MouseEvent e) { + if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) { + client.setUsername(ProfilePanel.this.loginText); + } + } + }); + JLabel login = new JLabel(); + login.setText(config.isStreamerMode() ? "Hidden email" : this.loginText); + login.setBorder(null); + login.setPreferredSize(new Dimension(0, 24)); + login.setForeground(Color.WHITE); + login.setBorder(new EmptyBorder(0, 8, 0, 0)); + bottomContainer.add((Component)login, "Center"); + this.add((Component)labelWrapper, "North"); + this.add((Component)bottomContainer, "Center"); + } + + static { + BufferedImage deleteImg = ImageUtil.getResourceStreamFromClass(ProfilesPlugin.class, "net/runelite/client/plugins/profiles/delete_icon.png"); + DELETE_ICON = new ImageIcon(deleteImg); + DELETE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(deleteImg, -100)); + } + +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java new file mode 100644 index 0000000000..2d6b171919 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java @@ -0,0 +1,36 @@ +/* + * Decompiled with CFR 0.139. + */ +package net.runelite.client.plugins.profiles; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup(value="profiles") +public interface ProfilesConfig +extends Config { + @ConfigItem(keyName="profilesData", name="", description="", hidden=true) + default public String profilesData() { + return ""; + } + + @ConfigItem(keyName="profilesData", name="", description="") + public void profilesData(String var1); + + @ConfigItem(keyName="rememberPassword", name="Remember Password", description="Remembers passwords for accounts") + default public boolean rememberPassword() { + return true; + } + + @ConfigItem(keyName="streamerMode", name="Hide email addresses", description="Hides your account emails") + default public boolean isStreamerMode() { + return false; + } + + @ConfigItem(keyName="switchPanel", name="Auto-open Panel", description="Automatically switch to the account switcher panel on the login screen") + default public boolean switchPanel() { + return true; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java new file mode 100644 index 0000000000..f3f6da6b67 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java @@ -0,0 +1,248 @@ +/* + * Decompiled with CFR 0.139. + */ +package net.runelite.client.plugins.profiles; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.Arrays; +import java.util.function.Consumer; +import javax.inject.Inject; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import net.runelite.api.Client; +import net.runelite.client.plugins.profiles.ProfilePanel; +import net.runelite.client.plugins.profiles.ProfilesConfig; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.PluginPanel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class ProfilesPanel +extends PluginPanel { + private static final Logger log = LoggerFactory.getLogger(ProfilesPanel.class); + private static final String ACCOUNT_USERNAME = "Account Username"; + private static final String ACCOUNT_LABEL = "Account Label"; + private static final String PASSWORD_LABEL = "Account Password"; + private static final Dimension PREFERRED_SIZE = new Dimension(205, 30); + private static final Dimension MINIMUM_SIZE = new Dimension(0, 30); + private final Client client; + private static ProfilesConfig profilesConfig; + private final JTextField txtAccountLabel = new JTextField("Account Label"); + private final JPasswordField txtAccountLogin = new JPasswordField("Account Username"); + private final JPasswordField txtPasswordLogin = new JPasswordField("Account Password"); + private final JPanel profilesPanel = new JPanel(); + private GridBagConstraints c; + + @Inject + public ProfilesPanel(Client client, final ProfilesConfig config) { + this.client = client; + profilesConfig = config; + this.setBorder(new EmptyBorder(18, 10, 0, 10)); + this.setBackground(ColorScheme.DARK_GRAY_COLOR); + this.setLayout(new GridBagLayout()); + this.c = new GridBagConstraints(); + this.c.fill = 2; + this.c.gridx = 0; + this.c.gridy = 0; + this.c.weightx = 1.0; + this.c.weighty = 0.0; + this.c.insets = new Insets(0, 0, 4, 0); + this.txtAccountLabel.setPreferredSize(PREFERRED_SIZE); + this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + this.txtAccountLabel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + this.txtAccountLabel.setMinimumSize(MINIMUM_SIZE); + this.txtAccountLabel.addFocusListener(new FocusListener(){ + + @Override + public void focusGained(FocusEvent e) { + if (ProfilesPanel.this.txtAccountLabel.getText().equals(ProfilesPanel.ACCOUNT_LABEL)) { + ProfilesPanel.this.txtAccountLabel.setText(""); + ProfilesPanel.this.txtAccountLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + } + } + + @Override + public void focusLost(FocusEvent e) { + if (ProfilesPanel.this.txtAccountLabel.getText().isEmpty()) { + ProfilesPanel.this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + ProfilesPanel.this.txtAccountLabel.setText(ProfilesPanel.ACCOUNT_LABEL); + } + } + }); + this.add((Component)this.txtAccountLabel, this.c); + ++this.c.gridy; + this.txtAccountLogin.setEchoChar('\u0000'); + this.txtAccountLogin.setPreferredSize(PREFERRED_SIZE); + this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + this.txtAccountLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR); + this.txtAccountLogin.setMinimumSize(MINIMUM_SIZE); + this.txtAccountLogin.addFocusListener(new FocusListener(){ + + @Override + public void focusGained(FocusEvent e) { + if (ProfilesPanel.ACCOUNT_USERNAME.equals(String.valueOf(ProfilesPanel.this.txtAccountLogin.getPassword()))) { + ProfilesPanel.this.txtAccountLogin.setText(""); + if (config.isStreamerMode()) { + ProfilesPanel.this.txtAccountLogin.setEchoChar('*'); + } + ProfilesPanel.this.txtAccountLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + } + } + + @Override + public void focusLost(FocusEvent e) { + if (ProfilesPanel.this.txtAccountLogin.getPassword().length == 0) { + ProfilesPanel.this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + ProfilesPanel.this.txtAccountLogin.setText(ProfilesPanel.ACCOUNT_USERNAME); + ProfilesPanel.this.txtAccountLogin.setEchoChar('\u0000'); + } + } + }); + this.add((Component)this.txtAccountLogin, this.c); + ++this.c.gridy; + this.txtPasswordLogin.setEchoChar('\u0000'); + this.txtPasswordLogin.setPreferredSize(PREFERRED_SIZE); + this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + this.txtPasswordLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR); + this.txtPasswordLogin.setToolTipText("Account password"); + this.txtPasswordLogin.setMinimumSize(MINIMUM_SIZE); + this.txtPasswordLogin.addFocusListener(new FocusListener(){ + + @Override + public void focusGained(FocusEvent e) { + if (ProfilesPanel.PASSWORD_LABEL.equals(String.valueOf(ProfilesPanel.this.txtPasswordLogin.getPassword()))) { + ProfilesPanel.this.txtPasswordLogin.setText(""); + ProfilesPanel.this.txtPasswordLogin.setEchoChar('*'); + ProfilesPanel.this.txtPasswordLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + } + } + + @Override + public void focusLost(FocusEvent e) { + if (ProfilesPanel.this.txtPasswordLogin.getPassword().length == 0) { + ProfilesPanel.this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + ProfilesPanel.this.txtPasswordLogin.setText(ProfilesPanel.PASSWORD_LABEL); + ProfilesPanel.this.txtPasswordLogin.setEchoChar('\u0000'); + } + } + }); + if (config.rememberPassword()) { + this.add((Component)this.txtPasswordLogin, this.c); + ++this.c.gridy; + } + this.c.insets = new Insets(0, 0, 15, 0); + final JButton btnAddAccount = new JButton("Add Account"); + btnAddAccount.setPreferredSize(PREFERRED_SIZE); + btnAddAccount.setBackground(ColorScheme.DARKER_GRAY_COLOR); + btnAddAccount.setMinimumSize(MINIMUM_SIZE); + btnAddAccount.addActionListener(e -> { + String labelText = String.valueOf(this.txtAccountLabel.getText()); + String loginText = String.valueOf(this.txtAccountLogin.getPassword()); + String passwordText = String.valueOf(this.txtPasswordLogin.getPassword()); + if (labelText.equals(ACCOUNT_LABEL) || loginText.equals(ACCOUNT_USERNAME)) { + return; + } + String data = config.rememberPassword() && this.txtPasswordLogin.getPassword() != null ? labelText + ":" + loginText + ":" + passwordText : labelText + ":" + loginText; + log.info(data); + this.addAccount(data); + ProfilesPanel.addProfile(data); + this.txtAccountLabel.setText(ACCOUNT_LABEL); + this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + this.txtAccountLogin.setText(ACCOUNT_USERNAME); + this.txtAccountLogin.setEchoChar('\u0000'); + this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + this.txtPasswordLogin.setText(PASSWORD_LABEL); + this.txtPasswordLogin.setEchoChar('\u0000'); + this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + }); + this.txtAccountLogin.addKeyListener(new KeyAdapter(){ + + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == 10) { + btnAddAccount.doClick(); + btnAddAccount.requestFocus(); + } + } + }); + this.txtAccountLogin.addMouseListener(new MouseListener(){ + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + } + + @Override + public void mouseReleased(MouseEvent e) { + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + }); + this.add((Component)btnAddAccount, this.c); + ++this.c.gridy; + this.profilesPanel.setLayout(new GridBagLayout()); + this.add((Component)this.profilesPanel, this.c); + this.c.gridy = 0; + this.c.insets = new Insets(0, 0, 5, 0); + this.addAccounts(config.profilesData()); + } + + void redrawProfiles() { + this.profilesPanel.removeAll(); + this.c.gridy = 0; + this.addAccounts(profilesConfig.profilesData()); + } + + private void addAccount(String data) { + ProfilePanel profile = new ProfilePanel(this.client, data, profilesConfig); + ++this.c.gridy; + this.profilesPanel.add((Component)profile, this.c); + this.revalidate(); + this.repaint(); + } + + void addAccounts(String data) { + if (!(data = data.trim()).contains(":")) { + return; + } + Arrays.stream(data.split("\\n")).forEach(this::addAccount); + } + + static void addProfile(String data) { + profilesConfig.profilesData(profilesConfig.profilesData() + data + "\n"); + } + + static void removeProfile(String data) { + profilesConfig.profilesData(profilesConfig.profilesData().replaceAll(data + "\\n", "")); + } + +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java new file mode 100644 index 0000000000..4128adba44 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java @@ -0,0 +1,128 @@ +/* + * Decompiled with CFR 0.139. + */ +package net.runelite.client.plugins.profiles; + +import com.google.inject.Provides; +import java.awt.image.BufferedImage; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.util.logging.Logger; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.events.ConfigChanged; +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.ui.ClientToolbar; +import net.runelite.client.ui.NavigationButton; +import net.runelite.client.util.ImageUtil; + +@PluginDescriptor(name="Account Switcher", description="Allow for a allows you to easily switch between multiple OSRS Accounts", tags={"profile", "account", "login", "log in"}) +public class ProfilesPlugin +extends Plugin { + @Inject + private ClientToolbar clientToolbar; + @Inject + private Client client; + @Inject + private ProfilesConfig config; + private ProfilesPanel panel; + private NavigationButton navButton; + String text = "Hello World"; + private static String key = "Bar12345Bar12345"; + private static Key aesKey = new SecretKeySpec(key.getBytes(), "AES"); + + @Provides + ProfilesConfig getConfig(ConfigManager configManager) { + return configManager.getConfig(ProfilesConfig.class); + } + + @Override + protected void startUp() throws Exception { + this.panel = this.injector.getInstance(ProfilesPanel.class); + BufferedImage icon = ImageUtil.getResourceStreamFromClass(this.getClass(), "/net/runelite/client/plugins/profiles/profiles_icon.png"); + this.navButton = NavigationButton.builder().tooltip("Profiles").icon(icon).priority(8).panel(this.panel).build(); + this.clientToolbar.addNavigation(this.navButton); + } + + @Override + protected void shutDown() { + this.clientToolbar.removeNavigation(this.navButton); + } + + @Subscribe + private void onConfigChanged(ConfigChanged event) throws Exception { + if (event.getGroup().equals("profiles") && event.getKey().equals("rememberPassword")) { + this.panel = this.injector.getInstance(ProfilesPanel.class); + this.shutDown(); + this.startUp(); + } + } + + public static String decryptText(String text) { + byte[] bb = new byte[text.length()]; + for (int i = 0; i < text.length(); ++i) { + bb[i] = (byte)text.charAt(i); + } + Cipher cipher = null; + try { + cipher = Cipher.getInstance("AES"); + } + catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + e.printStackTrace(); + } + try { + cipher.init(2, aesKey); + } + catch (InvalidKeyException e) { + e.printStackTrace(); + } + try { + Logger.getLogger("EncryptionLogger").info("Decrypted " + text + " to " + new String(cipher.doFinal(bb))); + return new String(cipher.doFinal(bb)); + } + catch (BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + return ""; + } + } + + public static String encryptText(String text) { + try { + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(1, aesKey); + byte[] encrypted = cipher.doFinal(text.getBytes()); + StringBuilder sb = new StringBuilder(); + for (byte b : encrypted) { + sb.append((char)b); + } + Logger.getLogger("EncryptionLogger").info("Encrypted " + text + " to " + sb.toString()); + return sb.toString(); + } + catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + catch (NoSuchPaddingException e) { + e.printStackTrace(); + } + catch (BadPaddingException e) { + e.printStackTrace(); + } + catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } + catch (InvalidKeyException e) { + e.printStackTrace(); + } + return ""; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/Obstacles.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/Obstacles.java new file mode 100644 index 0000000000..fff21802f0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/Obstacles.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, Steffen Hauge + * 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.pyramidplunder; + +import com.google.common.collect.ImmutableSet; +import java.util.Set; +import static net.runelite.api.ObjectID.SPEARTRAP_21280; + +public class Obstacles +{ + static final Set WALL_OBSTACLE_IDS = ImmutableSet.of( + 26618, 26619, 26620, 26621 + ); + + static final Set TRAP_OBSTACLE_IDS = ImmutableSet.of( + SPEARTRAP_21280 + ); +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderConfig.java new file mode 100644 index 0000000000..4b3038762c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderConfig.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018, Steffen Hauge + * 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.pyramidplunder; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("pyramidplunder") +public interface PyramidPlunderConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "highlightDoors", + name = "Highlights doors", + description = "Highlights the four doors in each room" + ) + default boolean highlightDoors() + { + return true; + } + + @ConfigItem( + position = 2, + keyName = "highlightSpearTrap", + name = "Highlights spear traps", + description = "Highlights the spear traps in each room" + ) + default boolean highlightSpearTrap() + { + return false; + } + + @ConfigItem( + position = 3, + keyName = "showTimer", + name = "Display numerical timer", + description = "Displays a numerical timer instead of the default timer" + ) + default boolean showTimer() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderOverlay.java new file mode 100644 index 0000000000..fd61a03229 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderOverlay.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2018, Steffen Hauge + * 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.pyramidplunder; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.geom.Area; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.ObjectComposition; +import static net.runelite.api.ObjectID.SPEARTRAP_21280; +import static net.runelite.api.ObjectID.TOMB_DOOR_20948; +import static net.runelite.api.ObjectID.TOMB_DOOR_20949; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; + +public class PyramidPlunderOverlay extends Overlay +{ + private static final int MAX_DISTANCE = 2400; + private static final Color COLOR_DOOR = Color.GREEN; + private static final Color COLOR_SPEAR_TRAP = Color.ORANGE; + + private final Client client; + private final PyramidPlunderPlugin plugin; + private final PyramidPlunderConfig config; + + @Inject + private PyramidPlunderOverlay(Client client, PyramidPlunderPlugin plugin, PyramidPlunderConfig config) + { + this.client = client; + this.plugin = plugin; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + @Override + public Dimension render(Graphics2D graphics) + { + if (!plugin.isInGame()) + { + return null; + } + + LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation(); + Point mousePosition = client.getMouseCanvasPosition(); + + plugin.getObstacles().forEach((object, tile) -> + { + if (Obstacles.WALL_OBSTACLE_IDS.contains(object.getId()) && !config.highlightDoors() || + Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !config.highlightSpearTrap()) + { + return; + } + + if (tile.getPlane() == client.getPlane() && + object.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE) + { + int objectID = object.getId(); + if (Obstacles.WALL_OBSTACLE_IDS.contains(object.getId())) + { + //Impostor + ObjectComposition comp = client.getObjectDefinition(objectID); + ObjectComposition impostor = comp.getImpostor(); + + if (impostor == null) + { + return; + } + objectID = impostor.getId(); + } + + Area objectClickbox = object.getClickbox(); + if (objectClickbox != null) + { + Color configColor = Color.GREEN; + switch (objectID) + { + case SPEARTRAP_21280: + configColor = COLOR_SPEAR_TRAP; + break; + case TOMB_DOOR_20948: + case TOMB_DOOR_20949: + configColor = COLOR_DOOR; + break; + } + + if (objectClickbox.contains(mousePosition.getX(), mousePosition.getY())) + { + graphics.setColor(configColor.darker()); + } + else + { + graphics.setColor(configColor); + } + + graphics.draw(objectClickbox); + graphics.setColor(new Color(configColor.getRed(), configColor.getGreen(), configColor.getBlue(), 50)); + graphics.fill(objectClickbox); + } + } + }); + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java new file mode 100644 index 0000000000..64a009f2cb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2018, Steffen Hauge + * 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.pyramidplunder; + +import com.google.common.eventbus.Subscribe; +import com.google.inject.Provides; +import java.time.temporal.ChronoUnit; +import java.util.HashMap; +import java.util.Map; +import javax.inject.Inject; +import lombok.Getter; +import net.runelite.api.Client; +import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE; +import net.runelite.api.Player; +import net.runelite.api.Tile; +import net.runelite.api.TileObject; +import net.runelite.api.Varbits; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameObjectChanged; +import net.runelite.api.events.GameObjectDespawned; +import net.runelite.api.events.GameObjectSpawned; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.events.WallObjectChanged; +import net.runelite.api.events.WallObjectDespawned; +import net.runelite.api.events.WallObjectSpawned; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; + +@PluginDescriptor( + name = "PyramidPlunder", + description = "Highlights doors and spear traps in pyramid plunder and adds a numerical timer", + tags = {"pyramidplunder", "pyramid", "plunder", "overlay", "skilling", "thieving"}, + enabledByDefault = false +) + +public class PyramidPlunderPlugin extends Plugin +{ + private static final int PYRAMIND_PLUNDER_REGION_ID = 7749; + private static final int PYRAMIND_PLUNDER_TIMER_MAX = 500; + private static final double GAMETICK_SECOND = 0.6; + + @Getter + private final Map obstacles = new HashMap<>(); + + @Inject + private Client client; + + @Inject + private PyramidPlunderConfig config; + + @Inject + private InfoBoxManager infoBoxManager; + + @Inject + private ItemManager itemManager; + + @Inject + private OverlayManager overlayManager; + + @Inject + private PyramidPlunderOverlay pyramidPlunderOverlay; + + @Getter + private boolean isInGame; + + private int pyramidTimer = 0; + + @Provides + PyramidPlunderConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(PyramidPlunderConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(pyramidPlunderOverlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(pyramidPlunderOverlay); + obstacles.clear(); + reset(); + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (!config.showTimer()) + { + removeTimer(); + } + + if (config.showTimer() && isInGame) + { + int remainingTime = PYRAMIND_PLUNDER_TIMER_MAX - pyramidTimer; + + if (remainingTime >= 2) + { + double timeInSeconds = remainingTime * GAMETICK_SECOND; + showTimer((int)timeInSeconds, ChronoUnit.SECONDS); + } + } + } + + private void removeTimer() + { + infoBoxManager.removeIf(infoBox -> infoBox instanceof PyramidPlunderTimer); + } + + private void showTimer() + { + showTimer(5, ChronoUnit.MINUTES); + } + + private void showTimer(int period, ChronoUnit chronoUnit) + { + removeTimer(); + infoBoxManager.addInfoBox(new PyramidPlunderTimer(this, itemManager.getImage(PHARAOHS_SCEPTRE), period, chronoUnit)); + } + + @Subscribe + public void onGameStateChange(GameStateChanged event) + { + switch (event.getGameState()) + { + case HOPPING: + case LOGIN_SCREEN: + reset(); + break; + case LOADING: + obstacles.clear(); + case LOGGED_IN: + if (!isInRegion()) + { + reset(); + } + break; + } + } + + private boolean isInRegion() + { + Player local = client.getLocalPlayer(); + if (local == null) + { + return false; + } + + WorldPoint location = local.getWorldLocation(); + if (location.getRegionID() != PYRAMIND_PLUNDER_REGION_ID) + { + return false; + } + + return true; + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + int lastValue = pyramidTimer; + pyramidTimer = client.getVar(Varbits.PYRAMID_PLUNDER_TIMER); + + if (lastValue == pyramidTimer) + { + return; + } + + if (pyramidTimer == 0) + { + reset(); + } + if (pyramidTimer == 1) + { + isInGame = true; + if (config.showTimer()) + { + showTimer(); + } + } + } + + private void reset() + { + isInGame = false; + removeTimer(); + } + + @Subscribe + public void onGameObjectSpawned(GameObjectSpawned event) + { + onTileObject(event.getTile(), null, event.getGameObject()); + } + + @Subscribe + public void onGameObjectChanged(GameObjectChanged event) + { + onTileObject(event.getTile(), event.getPrevious(), event.getGameObject()); + } + + @Subscribe + public void onGameObjectDeSpawned(GameObjectDespawned event) + { + onTileObject(event.getTile(), event.getGameObject(), null); + } + + @Subscribe + public void onWallObjectSpawned(WallObjectSpawned event) + { + onTileObject(event.getTile(), null, event.getWallObject()); + } + + @Subscribe + public void onWallObjectChanged(WallObjectChanged event) + { + onTileObject(event.getTile(), event.getPrevious(), event.getWallObject()); + } + + @Subscribe + public void onWallObjectDeSpawned(WallObjectDespawned event) + { + onTileObject(event.getTile(), event.getWallObject(), null); + } + + private void onTileObject(Tile tile, TileObject oldObject, TileObject newObject) + { + obstacles.remove(oldObject); + + if (newObject == null) + { + return; + } + + if (Obstacles.WALL_OBSTACLE_IDS.contains(newObject.getId()) || + Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId())) + { + obstacles.put(newObject, tile); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderTimer.java new file mode 100644 index 0000000000..a9f73cf8c3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderTimer.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, Steffen Hauge + * 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.pyramidplunder; + +import java.awt.image.BufferedImage; +import java.time.temporal.ChronoUnit; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.ui.overlay.infobox.Timer; + +public class PyramidPlunderTimer extends Timer +{ + PyramidPlunderTimer(Plugin plugin, BufferedImage image, int period, ChronoUnit chronoUnit) + { + super(period, chronoUnit, image, plugin); + setTooltip("Time left until minigame ends"); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java index d225410209..a0c1214a0d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java @@ -139,7 +139,7 @@ class ScreenMarkerPanel extends JPanel INVISIBLE_ICON = new ImageIcon(invisibleImg); INVISIBLE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(invisibleImg, -100)); - final BufferedImage deleteImg = ImageUtil.getResourceStreamFromClass(ScreenMarkerPlugin.class, "delete_icon.png"); + final BufferedImage deleteImg = ImageUtil.getResourceStreamFromClass(ScreenMarkerPlugin.class, "net/runelite/client/plugins/profiles/delete_icon.png"); DELETE_ICON = new ImageIcon(deleteImg); DELETE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(deleteImg, -100)); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryOverlay.java new file mode 100644 index 0000000000..726702f8eb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryOverlay.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019, Yani + * 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.shayzieninfirmary; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.image.BufferedImage; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.ItemID; +import net.runelite.api.NPC; +import net.runelite.api.Point; +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.OverlayUtil; + +public class ShayzienInfirmaryOverlay extends Overlay +{ + private final ShayzienInfirmaryPlugin plugin; + private final Client client; + + private BufferedImage medPackImage; + + @Inject + public ShayzienInfirmaryOverlay(ShayzienInfirmaryPlugin plugin, Client client, ItemManager itemManager) + { + setPosition(OverlayPosition.DYNAMIC); + this.plugin = plugin; + this.client = client; + + medPackImage = itemManager.getImage(ItemID.SHAYZIEN_MEDPACK); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!plugin.isAtInfirmary()) + { + return null; + } + + for (NPC npc : plugin.getUnhealedSoldiers()) + { + + Polygon tilePoly = npc.getCanvasTilePoly(); + + if (tilePoly == null) + { + continue; + } + + OverlayUtil.renderPolygon(graphics, npc.getCanvasTilePoly(), Color.ORANGE); + + Point imageLocation = npc.getCanvasImageLocation(medPackImage, 25); + + if (imageLocation == null) + { + continue; + } + + Composite originalComposite = graphics.getComposite(); + Composite translucentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f); + + graphics.setComposite(translucentComposite); + + OverlayUtil.renderImageLocation(graphics, imageLocation, medPackImage); + + graphics.setComposite(originalComposite); + } + + return null; + } +} 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 new file mode 100644 index 0000000000..f4ff6078f1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2019, Yani + * 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.shayzieninfirmary; + +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.events.GameTick; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +@Slf4j +@PluginDescriptor( + name = "Shayzien Infirmary", + description = "Shows the status of wounded soldiers", + tags = {"shayzien", "infirmary", "soldiers"} +) +public class ShayzienInfirmaryPlugin extends Plugin +{ + @Getter(AccessLevel.PACKAGE) + private List unhealedSoldiers = new ArrayList(); + + @Inject + private OverlayManager overlayManager; + + @Inject + private Client client; + + @Inject + private ShayzienInfirmaryOverlay overlay; + + @Override + protected void startUp() throws Exception + { + loadPlugin(); + } + + @Override + protected void shutDown() throws Exception + { + unloadPlugin(); + } + + private void loadPlugin() + { + overlayManager.add(overlay); + } + + private void unloadPlugin() + { + overlayManager.remove(overlay); + } + + @Subscribe + public void onGameTick(GameTick event) + { + if(!isAtInfirmary()) + { + return; + } + + unhealedSoldiers.clear(); + + for (NPC npc : client.getNpcs()) + { + if (isUnhealedSoldierId(npc.getId())) + { + unhealedSoldiers.add(npc); + } + } + } + + public boolean isSoldierId(int npcId) + { + return (npcId >= 6826 && npcId <= 6857); + } + + public boolean isUnhealedSoldierId(int npcId) + { + return (isSoldierId(npcId) && npcId % 2 == 0); + } + + public boolean isHealedSoldierId(int npcId) + { + return (isSoldierId(npcId) && npcId % 2 == 1); + } + + public boolean isAtInfirmary() + { + return client.getLocalPlayer().getWorldLocation().getRegionID() == 6200; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerConfig.java new file mode 100644 index 0000000000..dfd21986ba --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerConfig.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018, Plinko60 + * 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.shiftwalker; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("shiftwalkhere") +public interface ShiftWalkerConfig extends Config +{ + + @ConfigItem( + keyName = "shiftWalkEverything", + name = "Walk Under Everything", + description = "Enable this option when you do not want to interact with anything while Shift is pressed. " + + "If Walk Here is an option it will be the action taken." + ) + default boolean shiftWalkEverything() + { + return true; + } + + @ConfigItem( + keyName = "shiftWalkBoxTraps", + name = "Walk Under Box Traps", + description = "Press \"Shift\" to be able to walk under instead of picking up a Box Trap." + ) + default boolean shiftWalkBoxTraps() + { + return true; + } + + @ConfigItem( + keyName = "shiftWalkAttackOption", + name = "Walk Under Attack Options", + description = "Press \"Shift\" to be able to walk instead of attacking. Make sure Left Click Attack is on." + ) + default boolean shiftWalkAttackOption() + { + return true; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerGroups.java b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerGroups.java new file mode 100644 index 0000000000..aff9c0efdb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerGroups.java @@ -0,0 +1,32 @@ +package net.runelite.client.plugins.shiftwalker; + +import java.util.HashSet; + +public final class ShiftWalkerGroups +{ + //Specific Targets to limit the walking to + private static final String BOX_TRAP = "BOX TRAP"; + private static final String BOX_TRAP_SHAKING = "SHAKING BOX"; + + //Specific menu options to replace + private static final String BOX_TRAP_DISMANTLE = "DISMANTLE"; + private static final String BOX_TRAP_CHECK = "CHECK"; + + private static final String ATTACK_OPTIONS_ATTACK = "ATTACK"; + + public static final HashSet BOX_TRAP_TARGETS = new HashSet<>(); + public static final HashSet BOX_TRAP_KEYWORDS = new HashSet<>(); + public static final HashSet ATTACK_OPTIONS_KEYWORDS = new HashSet<>(); + + static + { + BOX_TRAP_TARGETS.add(BOX_TRAP); + BOX_TRAP_TARGETS.add(BOX_TRAP_SHAKING); + + BOX_TRAP_KEYWORDS.add(BOX_TRAP_DISMANTLE); + BOX_TRAP_KEYWORDS.add(BOX_TRAP_CHECK); + + ATTACK_OPTIONS_KEYWORDS.add(ATTACK_OPTIONS_ATTACK); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerInputListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerInputListener.java new file mode 100644 index 0000000000..677f30357d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerInputListener.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018, Plinko60 + * 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.shiftwalker; + +import net.runelite.client.input.KeyListener; + +import javax.inject.Inject; +import java.awt.event.KeyEvent; + +public class ShiftWalkerInputListener implements KeyListener +{ + + @Inject + private ShiftWalkerPlugin plugin; + + @Override + public void keyTyped(KeyEvent event) + { + + } + + @Override + public void keyPressed(KeyEvent event) + { + if (event.getKeyCode() == KeyEvent.VK_SHIFT) + { + plugin.setHotKeyPressed(true); + } + } + + @Override + public void keyReleased(KeyEvent event) + { + if (event.getKeyCode() == KeyEvent.VK_SHIFT) + { + plugin.setHotKeyPressed(false); + } + } +} 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 new file mode 100644 index 0000000000..aef2adb45e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2018, Plinko60 + * 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.shiftwalker; + +import com.google.inject.Provides; +import lombok.Setter; +import net.runelite.api.*; +import net.runelite.api.events.*; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.input.KeyManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.Text; + +import javax.inject.Inject; + +/** + * Shift Walker Plugin. Credit to MenuEntrySwapperPlugin for code some code structure used here. + */ +@PluginDescriptor( + name = "!Shift To Walk Here", + 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 +) +public class ShiftWalkerPlugin extends Plugin +{ + + private static final String WALK_HERE = "WALK HERE"; + private static final String CANCEL = "CANCEL"; + + @Inject + private Client client; + + @Inject + private ShiftWalkerConfig config; + + @Inject + private ShiftWalkerInputListener inputListener; + + @Inject + private ConfigManager configManager; + + @Inject + private KeyManager keyManager; + + @Setter + private boolean hotKeyPressed = false; + + @Provides + ShiftWalkerConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(ShiftWalkerConfig.class); + } + + @Override + public void startUp() + { + keyManager.registerKeyListener(inputListener); + } + + @Override + public void shutDown() + { + keyManager.unregisterKeyListener(inputListener); + } + + @Subscribe + public void onFocusChanged(FocusChanged event) + { + if (!event.isFocused()) + { + hotKeyPressed = false; + } + } + + /** + * Event when a new menu entry was added. + * @param event {@link MenuEntryAdded}. + */ + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + if (client.getGameState() != GameState.LOGGED_IN || !hotKeyPressed) + { + return; + } + + final String pOptionToReplace = Text.removeTags(event.getOption()).toUpperCase(); + + //If the option is already to walk there, or cancel we don't need to swap it with anything + if (pOptionToReplace.equals(CANCEL) || pOptionToReplace.equals(WALK_HERE)) + { + return; + } + + String target = Text.removeTags(event.getTarget().toUpperCase()); + + if (config.shiftWalkEverything()) + { + //swap(pOptionToReplace); //Swap everything with walk here + stripEntries(); + } + else if (config.shiftWalkBoxTraps() && ShiftWalkerGroups.BOX_TRAP_TARGETS.contains(target) + && ShiftWalkerGroups.BOX_TRAP_KEYWORDS.contains(pOptionToReplace)) + { + //swap(pOptionToReplace); //Swap only on box traps + stripEntries(); + } + else if (config.shiftWalkAttackOption() && ShiftWalkerGroups.ATTACK_OPTIONS_KEYWORDS.contains(pOptionToReplace)) + { + //swap(pOptionToReplace); //Swap on everything that has an attack keyword as the first option + stripEntries(); + } + } + + /** + * Strip everything except "Walk here" + * Other way was unconventional because if there was multiple targets in the menu entry it wouldn't swap correctly + */ + private void stripEntries() { + MenuEntry walkkHereEntry = null; + + for (MenuEntry entry : client.getMenuEntries()) { + switch (entry.getOption()) { + case "Walk here": + walkkHereEntry = entry; + break; + } + } + if (walkkHereEntry != null) { + MenuEntry[] newEntries = new MenuEntry[1]; + newEntries[0] = walkkHereEntry; + client.setMenuEntries(newEntries); + } + } + + /** + * Swaps menu entries if the entries could be found. This places Walk Here where the top level menu option was. + * @param pOptionToReplace The String containing the Menu Option that needs to be replaced. IE: "Attack", "Chop Down". + */ + private void swap(String pOptionToReplace) + { + MenuEntry[] entries = client.getMenuEntries(); + + Integer walkHereEntry = searchIndex(entries, WALK_HERE); + Integer entryToReplace = searchIndex(entries, pOptionToReplace); + + if (walkHereEntry != null + && entryToReplace != null) + { + MenuEntry walkHereMenuEntry = entries[walkHereEntry]; + entries[walkHereEntry] = entries[entryToReplace]; + entries[entryToReplace] = walkHereMenuEntry; + + client.setMenuEntries(entries); + } + } + + /** + * Finds the index of the menu that contains the verbiage we are looking for. + * @param pMenuEntries The list of {@link MenuEntry}s. + * @param pMenuEntryToSearchFor The Option in the menu to search for. + * @return The index location or null if it was not found. + */ + private Integer searchIndex(MenuEntry[] pMenuEntries, String pMenuEntryToSearchFor) + { + Integer indexLocation = 0; + + for (MenuEntry menuEntry : pMenuEntries) + { + String entryOption = Text.removeTags(menuEntry.getOption()).toUpperCase(); + + if (entryOption.equals(pMenuEntryToSearchFor)) + { + return indexLocation; + } + + indexLocation++; + } + + return null; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java new file mode 100644 index 0000000000..078491bb4d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java @@ -0,0 +1,207 @@ +package net.runelite.client.plugins.slayermusiq; + +import net.runelite.client.util.LinkBrowser; +import net.runelite.api.ChatMessageType; +import net.runelite.api.events.ChatMessage; +import net.runelite.client.chat.ChatColorType; +import net.runelite.client.chat.ChatMessageBuilder; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; + +public class QuestGuideLinks { + private static final Link[] QUEST_GUIDE_LINKS = { + // Free Quests + new Link("Cook's Assistant", "https://www.youtube.com/watch?v=ehmtDRelj3c"), + new Link("Romeo & Juliet", "https://www.youtube.com/watch?v=rH_biWSNWVY"), + new Link("Demon Slayer", "https://www.youtube.com/watch?v=hgACrzJSiQk"), + new Link("Shield of Arrav", "https://www.youtube.com/watch?v=a_imLDKUdzg"), + new Link("Sheep Shearer", "https://www.youtube.com/watch?v=XFG3aNwK68s"), + new Link("The Restless Ghost", "https://www.youtube.com/watch?v=UkWNcsG_pXM"), + new Link("Ernest the Chicken", "https://www.youtube.com/watch?v=cq8NIVhSqh4"), + new Link("Vampire Slayer", "https://www.youtube.com/watch?v=FcEuxsDJWCU"), + new Link("Imp Catcher", "https://www.youtube.com/watch?v=LHgnl0FbOzk"), + new Link("Prince Ali Rescue", "https://www.youtube.com/watch?v=hrSPl1GfFaw"), + new Link("Doric's Quest", "https://www.youtube.com/watch?v=5TYyxHU27a4"), + new Link("Black Knights' Fortress", "https://www.youtube.com/watch?v=aekoZi3f9cU"), + new Link("Witch's Potion", "https://www.youtube.com/watch?v=XV4i5sPUvXo"), + new Link("The Knight's Sword", "https://www.youtube.com/watch?v=UkBWaI0rOqE"), + new Link("Goblin Diplomacy", "https://www.youtube.com/watch?v=P9BKOb_dLoY"), + new Link("Pirate's Treasure", "https://www.youtube.com/watch?v=zcD87PQW8Qk"), + new Link("Dragon Slayer", "https://www.youtube.com/watch?v=bMtCjlFOaBI"), + new Link("Rune Mysteries", "https://www.youtube.com/watch?v=l8ZhaN8uoS0"), + new Link("Misthalin Mystery", "https://www.youtube.com/watch?v=QlFqVAobAlQ"), + new Link("The Corsair Curse", "https://www.youtube.com/watch?v=wi7mUAHExz4"), + new Link("X Marks the Spot", "https://www.youtube.com/watch?v=GhRgvEG5jxQ"), + // Members Quests + new Link("Druidic Ritual", "https://www.youtube.com/watch?v=QIfU6HSmH4w"), + new Link("Lost City", "https://www.youtube.com/watch?v=T-kQNUSjFZI"), + new Link("Witch's House", "https://www.youtube.com/watch?v=TLsg7Wa-LUA"), + new Link("Merlin's Crystal", "https://www.youtube.com/watch?v=ESX-qriNtCE"), + new Link("Heroes' Quest", "https://www.youtube.com/watch?v=hK2N0WLKviE"), + new Link("Scorpion Catcher", "https://www.youtube.com/watch?v=xpqdec7_ZWg"), + new Link("Family Crest", "https://www.youtube.com/watch?v=0mk_Cgjr738"), + new Link("Monk's Friend", "https://www.youtube.com/watch?v=avi4y4G3Hcw"), + new Link("Temple of Ikov", "https://www.youtube.com/watch?v=5K7jDgr_4Z4"), + new Link("Clock Tower", "https://www.youtube.com/watch?v=GUCkkQFzyDw"), + new Link("Holy Grail", "https://www.youtube.com/watch?v=cgXoV1QlYco"), + new Link("Tree Gnome Village", "https://www.youtube.com/watch?v=T6Su__yuyRI"), + new Link("Fight Arena", "https://www.youtube.com/watch?v=4Nqjep2E5pw"), + new Link("Hazeel Cult", "https://www.youtube.com/watch?v=2_fhFJW6cNY"), + new Link("Sheep Herder", "https://www.youtube.com/watch?v=akC9FeYCG1Q"), + new Link("Plague City", "https://www.youtube.com/watch?v=Hf2wQQZL5CU"), + new Link("Waterfall Quest", "https://www.youtube.com/watch?v=xWBSnGkQTi4"), + new Link("Jungle Potion", "https://www.youtube.com/watch?v=xqLKsFz08As"), + new Link("The Grand Tree", "https://www.youtube.com/watch?v=N5e_Jus_E-Y"), + new Link("Underground Pass", "https://www.youtube.com/watch?v=5klGJg1wY8k"), + new Link("Observatory Quest", "https://www.youtube.com/watch?v=yxa9B6svv44"), + new Link("Watchtower", "https://www.youtube.com/watch?v=Vb10GoYP7FE"), + new Link("Dwarf Cannon", "https://www.youtube.com/watch?v=pROFg5jcCR0"), + new Link("Murder Mystery", "https://www.youtube.com/watch?v=P1IDGCA2f9o"), + new Link("The Dig Site", "https://www.youtube.com/watch?v=TOdcWV4MzuU"), + new Link("Gertrude's Cat", "https://www.youtube.com/watch?v=g7S09wA8EAY"), + new Link("Legends' Quest", "https://www.youtube.com/watch?v=Lid8enDEF_U"), + new Link("Death Plateau", "https://www.youtube.com/watch?v=SIQFmTvnb6w"), + new Link("Big Chompy Bird Hunting", "https://www.youtube.com/watch?v=s2fytMOHJXI"), + new Link("Elemental Workshop I", "https://www.youtube.com/watch?v=tbZD2RDqvfQ"), + new Link("Nature Spirit", "https://www.youtube.com/watch?v=Enf8vUWb5o0"), + new Link("Priest in Peril", "https://www.youtube.com/watch?v=fyYri6wUQIU"), + new Link("Regicide", "https://www.youtube.com/watch?v=KkWM-ok3C4Y"), + new Link("Tai Bwo Wannai Trio", "https://www.youtube.com/watch?v=Mdair5mvZL0"), + new Link("Troll Stronghold", "https://www.youtube.com/watch?v=zqmUs-f3AKA"), + new Link("Horror from the Deep", "https://www.youtube.com/watch?v=9htK8kb6DR8"), + new Link("Throne of Miscellania", "https://www.youtube.com/watch?v=fzGMnv2skBE"), + new Link("Monkey Madness I", "https://www.youtube.com/watch?v=VnoRfeBnPFA"), + new Link("Haunted Mine", "https://www.youtube.com/watch?v=cIc6loJHm9Q"), + new Link("Troll Romance", "https://www.youtube.com/watch?v=j2zifZVu7Gc"), + new Link("In Search of the Myreque", "https://www.youtube.com/watch?v=5nmYFHdAXAQ"), + new Link("Creature of Fenkenstrain", "https://www.youtube.com/watch?v=swqUVIs7B7M"), + new Link("Roving Elves", "https://www.youtube.com/watch?v=J3qf9DnT9cA"), + new Link("One Small Favour", "https://www.youtube.com/watch?v=ix_0-W3e9ps"), + new Link("Mountain Daughter", "https://www.youtube.com/watch?v=HETx_LX7aiY"), + new Link("Between a Rock...", "https://www.youtube.com/watch?v=cB11I45EGgA"), + new Link("The Golem", "https://www.youtube.com/watch?v=qpEHpiO6lLw"), + new Link("Desert Treasure", "https://www.youtube.com/watch?v=BuIqulIsICo"), + new Link("Icthlarin's Little Helper", "https://www.youtube.com/watch?v=wpNKm8_vUOM"), + new Link("Tears of Guthix", "https://www.youtube.com/watch?v=EMonDNI0uPk"), + new Link("The Lost Tribe", "https://www.youtube.com/watch?v=spZErjRnCdc"), + new Link("The Giant Dwarf", "https://www.youtube.com/watch?v=Z7PsGpOYgxY"), + new Link("Recruitment Drive", "https://www.youtube.com/watch?v=sOuzMpA_xtw"), + new Link("Mourning's Ends Part I", "https://www.youtube.com/watch?v=vuzAdk-h3c0"), + new Link("Garden of Tranquillity", "https://www.youtube.com/watch?v=7hbCzYnLCsQ"), + new Link("A Tail of Two Cats", "https://www.youtube.com/watch?v=SgN9Yw_YqHk"), + new Link("Wanted!", "https://www.youtube.com/watch?v=ZHZAKDCfXGs"), + new Link("Mourning's Ends Part II", "https://www.youtube.com/watch?v=FK5sLogGbU8"), + new Link("Rum Deal", "https://www.youtube.com/watch?v=I14CIu5x2S8"), + new Link("Shadow of the Storm", "https://www.youtube.com/watch?v=5ZvWd3XCQjI"), + new Link("Ratcatchers", "https://www.youtube.com/watch?v=s7G22fEuhTc"), + new Link("Spirits of the Elid", "https://www.youtube.com/watch?v=A1zAX55hZC0"), + new Link("Devious Minds", "https://www.youtube.com/watch?v=_UtlFmrWt1w"), + new Link("Enakhra's Lament", "https://www.youtube.com/watch?v=Y3kEIPYVaVE"), + new Link("Cabin Fever", "https://www.youtube.com/watch?v=k5DtxNXhOaw"), + new Link("Fairytale I - Growing Pains", "https://www.youtube.com/watch?v=cfGI9qFOmsg"), + new Link("Recipe for Disaster", "https://www.youtube.com/watch?v=hrAyyInJaTA"), + new Link("In Aid of the Myreque", "https://www.youtube.com/watch?v=O2Ru2NmuTaA"), + new Link("A Soul's Bane", "https://www.youtube.com/watch?v=dp8dp79qp6I"), + new Link("Rag and Bone Man", "https://www.youtube.com/watch?v=3owXSeN56W8"), + new Link("Swan Song", "https://www.youtube.com/watch?v=IpmERThXv2g"), + new Link("Royal Trouble", "https://www.youtube.com/watch?v=bVWUlKzNXEg"), + new Link("Death to the Dorgeshuun", "https://www.youtube.com/watch?v=2XJHuLhig98"), + new Link("Fairytale II - Cure a Queen", "https://www.youtube.com/watch?v=P6KkRk4_e3U"), + new Link("Lunar Diplomacy", "https://www.youtube.com/watch?v=vmeSKb7IBgQ"), + new Link("The Eyes of Glouphrie", "https://www.youtube.com/watch?v=0YCPwmZcxKA"), + new Link("Darkness of Hallowvale", "https://www.youtube.com/watch?v=QziKl99qdtU"), + new Link("Elemental Workshop II", "https://www.youtube.com/watch?v=Bb4E7ecIgv0"), + new Link("My Arm's Big Adventure", "https://www.youtube.com/watch?v=xa1KWOewgYA"), + new Link("Enlightened Journey", "https://www.youtube.com/watch?v=XAPthC8d7k0"), + new Link("Eagles' Peak", "https://www.youtube.com/watch?v=KDxIrrwXp7U"), + new Link("Animal Magnetism", "https://www.youtube.com/watch?v=kUyjXA7TaFU"), + new Link("Contact!", "https://www.youtube.com/watch?v=czn-yWABBWs"), + new Link("Cold War", "https://www.youtube.com/watch?v=0m1KpP-qKWI"), + new Link("The Fremennik Isles", "https://www.youtube.com/watch?v=EvxhiOWmraY"), + new Link("The Great Brain Robbery", "https://www.youtube.com/watch?v=ImHFASuNUN8"), + new Link("What Lies Below", "https://www.youtube.com/watch?v=f_9nVMGTtuo"), + new Link("Olaf's Quest", "https://www.youtube.com/watch?v=mXV5bM1NFMM"), + new Link("Dream Mentor", "https://www.youtube.com/watch?v=XDLUu0Kf0sE"), + new Link("Grim Tales", "https://www.youtube.com/watch?v=dFB0Q6v8Apw"), + new Link("King's Ransom", "https://www.youtube.com/watch?v=UJz9ZfF3uCY"), + new Link("Shilo Village", "https://www.youtube.com/watch?v=bDvBi8FT-QI"), + new Link("Biohazard", "https://www.youtube.com/watch?v=n9k87LwOGMk"), + new Link("Tower of Life", "https://www.youtube.com/watch?v=KReMcWpeY3k"), + new Link("Rag and Bone Man II", "https://www.youtube.com/watch?v=KGdHiDDUX_U"), + new Link("Zogre Flesh Eaters", "https://www.youtube.com/watch?v=vzm4949kXP4"), + new Link("Monkey Madness II", "https://www.youtube.com/watch?v=ykE5LbjABaI"), + new Link("Client of Kourend", "https://www.youtube.com/watch?v=Y-KIHF-cL9w"), + new Link("The Queen of Thieves", "https://www.youtube.com/watch?v=W94zFZVrHkQ"), + new Link("Bone Voyage", "https://www.youtube.com/watch?v=-VTR4p8kPmI"), + new Link("Dragon Slayer II", "https://www.youtube.com/watch?v=4BMb3Zwzk_U"), + new Link("The Depths of Despair", "https://www.youtube.com/watch?v=CaVUk2eAsKs"), + new Link("A Taste of Hope", "https://www.youtube.com/watch?v=VjdgEIizdSc"), + new Link("Tale of the Righteous", "https://www.youtube.com/watch?v=99yiv0tPl58"), + new Link("Making Friends with My Arm", "https://www.youtube.com/watch?v=DltzzhIsM_Q"), + new Link("The Ascent of Arceuus", "https://www.youtube.com/watch?v=4VQnfrv6S18"), + new Link("The Forsaken Tower", "https://www.youtube.com/watch?v=con0sXl5NBY"), + new Link("Fishing Contest", "https://www.youtube.com/watch?v=XYSv37A_l5w"), + new Link("Tribal Totem", "https://www.youtube.com/watch?v=XkUEIjr886M"), + new Link("Sea Slug", "https://www.youtube.com/watch?v=oOZVfa5SkVQ"), + new Link("The Tourist Trap", "https://www.youtube.com/watch?v=0bmSCCepMvo"), + new Link("Eadgar's Ruse", "https://www.youtube.com/watch?v=aVQ3DjTElXg"), + new Link("Shades of Mort'ton", "https://www.youtube.com/watch?v=eF05R8OMxgg"), + new Link("The Fremennik Trials", "https://www.youtube.com/watch?v=YUIvEgcvl5c"), + new Link("Ghosts Ahoy", "https://www.youtube.com/watch?v=aNBkLOywDfM"), + new Link("The Feud", "https://www.youtube.com/watch?v=nlBSc9IUklA"), + new Link("Forgettable Tale...", "https://www.youtube.com/watch?v=3HvFd6AxNU0"), + new Link("Making History", "https://www.youtube.com/watch?v=bOTGi2zAuhs"), + new Link("The Hand in the Sand", "https://www.youtube.com/watch?v=gdNLcZ-l1Lw"), + new Link("The Slug Menace", "https://www.youtube.com/watch?v=BRQbdr3JEZ8"), + new Link("Another Slice of H.A.M.", "https://www.youtube.com/watch?v=Yq3db7827Lk") + }; + + private static class Link { + + private String questName; + private String url; + + public Link(String questName, String url) { + this.questName = questName; + this.url = url; + } + + public String getQuestName() { + return questName; + } + + public void openURL() { + LinkBrowser.browse(this.url); + } + + } + + private static boolean openGuide(String questName) { + for (Link link : QUEST_GUIDE_LINKS) { + if (link.getQuestName().equals(questName)) { + link.openURL(); + return true; + } + } + return false; + } + + private static void logQuestNotFoundError(String questName, ChatMessageManager chatMessageManager) { + String chatMessage = new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append("Could not find Slayermusiq1 guide for " + questName) + .build(); + + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .runeLiteFormattedMessage(chatMessage) + .build()); + } + + public static void tryOpenGuide(String questName, ChatMessageManager chatMessageManager) { + boolean success = openGuide(questName); + if (!success) { + logQuestNotFoundError(questName, chatMessageManager); + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java new file mode 100644 index 0000000000..7e07a0564d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2018, Jeremy Berchtold + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Based off RuneLite's Wiki Plugin +/* + * Copyright (c) 2018 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.slayermusiq; + +import com.google.inject.Provides; +import com.google.common.primitives.Ints; +import java.awt.Dimension; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import javax.swing.SwingUtilities; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.MenuOptionClicked; +import net.runelite.client.util.Text; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +@PluginDescriptor( + name = "!Slayermusiq1 Guides", + description = "Adds a right-click option to go to Slayermusiq1's guides from the quest tab", + tags = {"quest", "guide", "slayermusiq"} +) +@Slf4j +public class SlayermusiqPlugin extends Plugin +{ + + private static final int[] QUESTLIST_WIDGET_IDS = new int[] + { + WidgetInfo.QUESTLIST_FREE_CONTAINER.getId(), + WidgetInfo.QUESTLIST_MEMBERS_CONTAINER.getId(), + WidgetInfo.QUESTLIST_MINIQUEST_CONTAINER.getId(), + }; + + private static final String MENUOP_SLAYERMUSIQ = "Slayermusiq"; + + @Inject + private Client client; + + @Inject + private ChatMessageManager chatMessageManager; + + @Override + protected void startUp() throws Exception + { + // + } + + @Override + protected void shutDown() throws Exception + { + // + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + int widgetID = event.getActionParam1(); + if (Ints.contains(QUESTLIST_WIDGET_IDS, widgetID) && "Read Journal:".equals(event.getOption())) { + MenuEntry[] menuEntries = client.getMenuEntries(); + + MenuEntry newMenuEntry = createSlayermusiqOptionMenuEntry(event); + menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); + menuEntries[menuEntries.length - 1] = newMenuEntry; + + client.setMenuEntries(menuEntries); + } + } + + @Subscribe + private void onMenuOptionClicked(MenuOptionClicked ev) { + if (ev.getMenuAction() == MenuAction.RUNELITE && ev.getMenuOption().equals(MENUOP_SLAYERMUSIQ)) { + ev.consume(); + String quest = Text.removeTags(ev.getMenuTarget()); + QuestGuideLinks.tryOpenGuide(quest, chatMessageManager); + } + } + + private MenuEntry createSlayermusiqOptionMenuEntry(MenuEntryAdded event) { + int widgetIndex = event.getActionParam0(); + int widgetID = event.getActionParam1(); + + MenuEntry menuEntry = new MenuEntry(); + menuEntry.setTarget(event.getTarget()); + menuEntry.setOption(MENUOP_SLAYERMUSIQ); + menuEntry.setParam0(widgetIndex); + menuEntry.setParam1(widgetID); + menuEntry.setType(MenuAction.RUNELITE.getId()); + + return menuEntry; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java new file mode 100644 index 0000000000..bb16cd3709 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java @@ -0,0 +1,110 @@ +package net.runelite.client.plugins.spellbookfixer; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("spellbookfixer") +public interface SpellbookFixerConfig extends Config +{ + @ConfigItem(position = 0, keyName = "shouldHideOthers", name = "Hide Others", description = "Toggle on to hide spells not useful for pking that cannot be filtered otherwise.") + default boolean shouldHideOthers() + { + return false; + } + + //ice blitz + @ConfigItem(position = 1, keyName = "shouldModifyIceBlitz", name = "Ice Blitz", description = "Toggle on to enable Ice Blitz modifications.") + default boolean shouldModifyIceBlitz() { return false; } + @ConfigItem(position = 2, keyName = "getBlitzPositionX", name = "Ice Blitz Pos X", description = "Modifies the X-axis position of Ice Blitz.") + default int getBlitzPositionX() + { + return 0; + } + @ConfigItem(position = 3, keyName = "getBlitzPositionY", name = "Ice Blitz Pos Y", description = "Modifies the Y-axis position of Ice Blitz.") + default int getBlitzPositionY() + { + return 118; + } + @ConfigItem(position = 4, keyName = "getBlitzSize", name = "Ice Blitz Size", description = "Modifies the width of Ice Blitz.") + default int getBlitzSize() + { + return 80; + } + + //ice barrage + @ConfigItem(position = 5, keyName = "shouldModifyIceBarrage", name = "Ice Barrage", description = "Toggle on to enable Ice Barrage modifications.") + default boolean shouldModifyIceBarrage() { return false; } + @ConfigItem(position = 6, keyName = "getBarragePositionX", name = "Ice Barrage Pos X", description = "Modifies the X-axis position of Ice Barrage.") + default int getBarragePositionX() + { + return 0; + } + @ConfigItem(position = 7, keyName = "getBarragePositionY", name = "Ice Barrage Pos X", description = "Modifies the X-axis position of Ice Barrage.") + default int getBarragePositionY() + { + return 0; + } + @ConfigItem(position = 8, keyName = "getBarrageSize", name = "Ice Barrage Size", description = "Modifies the width position of Ice Barrage.") + default int getBarrageSize() + { + return 80; + } + + //vengeance + @ConfigItem(position = 9, keyName = "shouldModifyVengeance", name = "Vengeance", description = "Toggle on to enable Vengeance modifications.") + default boolean shouldModifyVengeance() { return false; } + @ConfigItem(position = 10, keyName = "getVengeancePositionX", name = "Vengeance Pos X", description = "Modifies the X-axis position of Vengeance.") + default int getVengeancePositionX() + { + return 0; + } + @ConfigItem(position = 11, keyName = "getVengeancePositionY", name = "Vengeance Pos X", description = "Modifies the X-axis position of Vengeance.") + default int getVengeancePositionY() + { + return 0; + } + @ConfigItem(position = 12, keyName = "getVengeanceSize", name = "Vengeance Size", description = "Modifies the width position of Vengeance.") + default int getVengeanceSize() + { + return 80; + } + + //teleblock + @ConfigItem(position = 13, keyName = "shouldModifyTeleBlock", name = "TeleBlock", description = "Toggle on to enable TeleBlock modifications.") + default boolean shouldModifyTeleBlock() { return false; } + @ConfigItem(position = 14, keyName = "getTeleBlockPositionX", name = "TeleBlock Pos X", description = "Modifies the X-axis position of TeleBlock.") + default int getTeleBlockPositionX() + { + return 0; + } + @ConfigItem(position = 15, keyName = "getTeleBlockPositionY", name = "TeleBlock Pos X", description = "Modifies the X-axis position of TeleBlock.") + default int getTeleBlockPositionY() + { + return 0; + } + @ConfigItem(position = 16, keyName = "getTeleBlockSize", name = "TeleBlock Size", description = "Modifies the width position of TeleBlock.") + default int getTeleBlockSize() + { + return 80; + } + + //entangle + @ConfigItem(position = 17, keyName = "shouldModifyEntangle", name = "Entangle", description = "Toggle on to enable Entangle modifications.") + default boolean shouldModifyEntangle() { return false; } + @ConfigItem(position = 18, keyName = "getEntanglePositionX", name = "Entangle Pos X", description = "Modifies the X-axis position of Entangle.") + default int getEntanglePositionX() + { + return 0; + } + @ConfigItem(position = 19, keyName = "getEntanglePositionY", name = "Entangle Pos X", description = "Modifies the X-axis position of Entangle.") + default int getEntanglePositionY() + { + return 118; + } + @ConfigItem(position = 20, keyName = "getEntangleSize", name = "Entangle Size", description = "Modifies the width position of Entangle.") + default int getEntangleSize() + { + return 80; + } +} 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 new file mode 100644 index 0000000000..7d71cef371 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java @@ -0,0 +1,170 @@ +package net.runelite.client.plugins.spellbookfixer; + +import com.google.inject.Provides; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +import javax.inject.Inject; + + +@PluginDescriptor( + name = "Spellbook Fixer", + description = "Resize and filter spellbook for PKing", + tags = {"resize", "spellbook", "magic", "spell", "pk", "book", "filter", "bogla"} +) +@Slf4j +public class SpellbookFixerPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + SpellbookFixerConfig config; + + @Provides + SpellbookFixerConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(SpellbookFixerConfig.class); } + + @Override + protected void startUp() throws Exception + { + adjustSpellbook(); + } + + @Override + protected void shutDown() throws Exception + { + resetSpellbook(); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOGGED_IN) + adjustSpellbook(); + } + + @Subscribe + public void onWidgetLoaded(WidgetLoaded event) + { + if (event.getGroupId() == WidgetID.SPELLBOOK_GROUP_ID) + adjustSpellbook(); + } + + @Subscribe + public void onGameTick(GameTick event) + { + adjustSpellbook(); + } + + private void adjustSpellbook() + { + if (client.getGameState() != GameState.LOGGED_IN) + return; + + try + { + if (config.shouldModifyIceBarrage()) + modifySpell(WidgetInfo.SPELL_ICE_BARRAGE, config.getBarragePositionX(), config.getBarragePositionY(), config.getBarrageSize()); + + if (config.shouldModifyIceBlitz()) + modifySpell(WidgetInfo.SPELL_ICE_BLITZ, config.getBlitzPositionX(), config.getBlitzPositionY(), config.getBlitzSize()); + + if (config.shouldModifyVengeance()) + modifySpell(WidgetInfo.SPELL_VENGEANCE, config.getVengeancePositionX(), config.getVengeancePositionY(), config.getVengeanceSize()); + + if (config.shouldModifyTeleBlock()) + modifySpell(WidgetInfo.SPELL_TELE_BLOCK, config.getTeleBlockPositionX(), config.getTeleBlockPositionY(), config.getTeleBlockSize()); + + if (config.shouldModifyEntangle()) + modifySpell(WidgetInfo.SPELL_ENTANGLE, config.getEntanglePositionX(), config.getEntanglePositionY(), config.getEntangleSize()); + + setSpellHidden(WidgetInfo.SPELL_BLOOD_BLITZ, config.shouldHideOthers()); + setSpellHidden(WidgetInfo.SPELL_VENGEANCE_OTHER, config.shouldHideOthers()); + setSpellHidden(WidgetInfo.SPELL_BIND, config.shouldHideOthers()); + setSpellHidden(WidgetInfo.SPELL_SNARE, config.shouldHideOthers()); + } + catch (Exception e) + { + //swallow + } + + + } + + private void resetSpellbook() + { + if (client.getGameState() != GameState.LOGGED_IN) + return; + + try + { + if (config.shouldModifyIceBarrage()) + modifySpell(WidgetInfo.SPELL_ICE_BARRAGE, config.getBarragePositionX(), config.getBarragePositionY(), 24); + + if (config.shouldModifyIceBlitz()) + modifySpell(WidgetInfo.SPELL_ICE_BLITZ, config.getBlitzPositionX(), config.getBlitzPositionY(), 24); + + if (config.shouldModifyVengeance()) + modifySpell(WidgetInfo.SPELL_VENGEANCE, config.getVengeancePositionX(), config.getVengeancePositionY(), 24); + + if (config.shouldModifyTeleBlock()) + modifySpell(WidgetInfo.SPELL_TELE_BLOCK, config.getTeleBlockPositionX(), config.getTeleBlockPositionY(), 24); + + if (config.shouldModifyEntangle()) + modifySpell(WidgetInfo.SPELL_ENTANGLE, config.getEntanglePositionX(), config.getEntanglePositionY(), 24); + + setSpellHidden(WidgetInfo.SPELL_BLOOD_BLITZ, false); + setSpellHidden(WidgetInfo.SPELL_VENGEANCE_OTHER, false); + setSpellHidden(WidgetInfo.SPELL_BIND, false); + setSpellHidden(WidgetInfo.SPELL_SNARE, false); + } + catch (Exception e) + { + //swallow + } + } + + private void modifySpell(WidgetInfo widgetInfo, int posX, int posY, int size) + { + Widget widget = client.getWidget(widgetInfo); + + if (widget == null) + return; + + try + { + widget.setOriginalX(posX); + widget.setOriginalY(posY); + widget.setOriginalWidth(size); + widget.setOriginalHeight(size); + widget.revalidate(); + } + catch (Exception e) + { + //swallow + } + + } + + private void setSpellHidden(WidgetInfo widgetInfo, boolean hidden) + { + Widget widget = client.getWidget(widgetInfo); + + if (widget == null) + return; + + widget.setHidden(hidden); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ActionType.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ActionType.java new file mode 100644 index 0000000000..b801e8b2a8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ActionType.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018, Davis Cook + * Copyright (c) 2018, Daddy Dozer + * 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.suppliestracker; + +/** + * Type of action performed in a menu + */ +public enum ActionType +{ + + CONSUMABLE, TELEPORT, CAST; + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/BlowpipeDartType.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/BlowpipeDartType.java new file mode 100644 index 0000000000..09182d6cde --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/BlowpipeDartType.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018, Davis Cook + * 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.suppliestracker; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import static net.runelite.api.ItemID.*; + +/** + * Type of darts that can be put into the blowpipe + */ +@AllArgsConstructor +public enum BlowpipeDartType +{ + BRONZE(BRONZE_DART), IRON(IRON_DART), + STEEL(STEEL_DART), MITHRIL(MITHRIL_DART), + ADAMANT(ADAMANT_DART), RUNE(RUNE_DART), + DRAGON(DRAGON_DART); + + @Getter + private int dartID; + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ItemType.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ItemType.java new file mode 100644 index 0000000000..8479937589 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/ItemType.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018, Davis Cook + * Copyright (c) 2018, Daddy Dozer + * 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.suppliestracker; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * The potential types that supplies can be along with a categorization function + * that assigns the supplies to these categories + */ +@AllArgsConstructor +public enum ItemType +{ + FOOD("Food"), + POTION("Potions"), + RUNE("Runes"), + AMMO("Ammo"), + TELEPORT("Teleports"); + + @Getter + private String label; + + /** + * Takes an item and determines what ItemType it should categorize into + * @param item the item to determine category for + * @return our best guess for what category this item goes into + * note that if the guess is wrong (per say) it won't break anything because it will be + * consistently wrong but it could have an item that is clearly not food in the food section + */ + public static ItemType categorize(SuppliesTrackerItem item) + { + if (item.getName().contains("(4)")) + { + return ItemType.POTION; + } + if (item.getName().toLowerCase().contains("bolt") || item.getName().toLowerCase().contains("dart") + || item.getName().toLowerCase().contains("arrow") || item.getName().toLowerCase().contains("javelin") + || item.getName().toLowerCase().contains("knive") || item.getName().toLowerCase().contains("throwing") + || item.getName().toLowerCase().contains("zulrah's scale") || item.getName().toLowerCase().contains("cannonball")) + { + return ItemType.AMMO; + } + if (item.getName().contains("rune")) + { + return ItemType.RUNE; + } + if (item.getName().toLowerCase().contains("teleport")) + { + return ItemType.TELEPORT; + } + return ItemType.FOOD; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/MenuAction.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/MenuAction.java new file mode 100644 index 0000000000..42a942e74b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/MenuAction.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, Davis Cook + * 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.suppliestracker; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.runelite.api.Item; + +/** + * Data class that tracks all info related to a menu click action + */ +@AllArgsConstructor +public class MenuAction +{ + + @Getter + private ActionType type; + @Getter + private Item[] oldInventory; + + public static class ItemAction extends MenuAction + { + + @Getter + private int itemID; + @Getter + private int slot; + + public ItemAction(ActionType type, Item[] oldInventory, int itemID, int slot) + { + super(type, oldInventory); + this.itemID = itemID; + this.slot = slot; + } + + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesBox.java new file mode 100644 index 0000000000..76dc060a9f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesBox.java @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2018, Davis Cook + * Copyright (c) 2018, Daddy Dozer + * 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.suppliestracker; + +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.client.game.AsyncBufferedImage; +import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.FontManager; +import net.runelite.client.util.StackFormatter; +import net.runelite.client.util.Text; +import net.runelite.http.api.item.ItemPrice; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +import static net.runelite.api.ItemID.*; +import static net.runelite.api.ItemID.HALF_A_MEAT_PIE; + +public class SuppliesBox extends JPanel +{ + private static final int ITEMS_PER_ROW = 5; + + private final JPanel itemContainer = new JPanel(); + private final JLabel priceLabel = new JLabel(); + private final JLabel subTitleLabel = new JLabel(); + private final ItemManager itemManager; + @Getter(AccessLevel.PACKAGE) + private final String id; + private final SuppliesTrackerPlugin plugin; + private final SuppliesTrackerPanel panel; + + @Getter + private final List trackedItems = new ArrayList<>(); + + private long totalPrice; + + @Getter + private final ItemType type; + + SuppliesBox(final ItemManager itemManager, final String id, + final SuppliesTrackerPlugin plugin, final SuppliesTrackerPanel panel, + final ItemType type) + { + this.id = id; + this.itemManager = itemManager; + this.plugin = plugin; + this.panel = panel; + this.type = type; + + setLayout(new BorderLayout(0, 1)); + setBorder(new EmptyBorder(5, 0, 0, 0)); + + final JPanel logTitle = new JPanel(new BorderLayout(5, 0)); + logTitle.setBorder(new EmptyBorder(7, 7, 7, 7)); + logTitle.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); + + final JLabel titleLabel = new JLabel(Text.removeTags(id)); + titleLabel.setFont(FontManager.getRunescapeSmallFont()); + titleLabel.setForeground(Color.WHITE); + + logTitle.add(titleLabel, BorderLayout.WEST); + + subTitleLabel.setFont(FontManager.getRunescapeSmallFont()); + subTitleLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + logTitle.add(subTitleLabel, BorderLayout.CENTER); + + priceLabel.setFont(FontManager.getRunescapeSmallFont()); + priceLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + logTitle.add(priceLabel, BorderLayout.EAST); + + add(logTitle, BorderLayout.NORTH); + add(itemContainer, BorderLayout.CENTER); + + // Create popup menu + final JPopupMenu popupMenu = new JPopupMenu(); + popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5)); + setComponentPopupMenu(popupMenu); + + // Create reset menu + final JMenuItem reset = new JMenuItem("Reset Category"); + reset.addActionListener(e -> + { + for (SuppliesTrackerItem item : trackedItems) + { + plugin.clearItem(item.getId()); + } + clearAll(); + rebuild(); + panel.updateOverall(); + }); + + popupMenu.add(reset); + + setVisible(false); + } + + void update(SuppliesTrackerItem item) + { + trackedItems.removeIf(r -> r.getId() == item.getId()); + trackedItems.add(item); + setVisible(trackedItems.size() > 0); + } + + void remove(SuppliesTrackerItem item) + { + trackedItems.removeIf(r -> r.getId() == item.getId()); + plugin.clearItem(item.getId()); + setVisible(trackedItems.size() > 0); + } + + void clearAll() + { + trackedItems.clear(); + setVisible(false); + } + + public long getTotalSupplies() + { + long totalSupplies = 0; + for (SuppliesTrackerItem item : trackedItems) + { + totalSupplies += item.getQuantity(); + } + return totalSupplies; + } + + public long getTotalPrice() + { + return totalPrice; + } + + void rebuild() + { + buildItems(); + + priceLabel.setText(StackFormatter.quantityToStackSize(totalPrice) + " gp"); + priceLabel.setToolTipText(StackFormatter.formatNumber(totalPrice) + " gp"); + + final long supplies = getTotalSupplies(); + if (supplies > 0) + { + subTitleLabel.setText("x " + supplies); + } + else + { + subTitleLabel.setText(""); + } + + validate(); + repaint(); + } + + private void buildItems() + { + final List items = new ArrayList<>(trackedItems); + totalPrice = 0; + + for (SuppliesTrackerItem item : items) + { + totalPrice += item.getPrice(); + } + + items.sort((i1, i2) -> Long.compare(i2.getPrice(), i1.getPrice())); + + // calculates how many rows need to be displayed to fit all item + final int rowSize = ((items.size() % ITEMS_PER_ROW == 0) ? 0 : 1) + items.size() / ITEMS_PER_ROW; + + itemContainer.removeAll(); + itemContainer.setLayout(new GridLayout(rowSize, ITEMS_PER_ROW, 1, 1)); + + for (int i = 0; i < rowSize * ITEMS_PER_ROW; i++) + { + final JPanel slotContainer = new JPanel(); + slotContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR); + + if (i < items.size()) + { + final SuppliesTrackerItem item = items.get(i); + final JLabel imageLabel = new JLabel(); + imageLabel.setToolTipText(buildToolTip(item)); + imageLabel.setVerticalAlignment(SwingConstants.CENTER); + imageLabel.setHorizontalAlignment(SwingConstants.CENTER); + + AsyncBufferedImage itemImage = itemManager.getImage(getModifiedItemId(item.getName(), item.getId()), item.getQuantity(), item.getQuantity() > 1); + itemImage.addTo(imageLabel); + slotContainer.add(imageLabel); + + // create popup menu + final JPopupMenu popupMenu = new JPopupMenu(); + popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5)); + slotContainer.setComponentPopupMenu(popupMenu); + + final JMenuItem reset = new JMenuItem("Reset"); + reset.addActionListener(e -> + { + remove(item); + rebuild(); + panel.updateOverall(); + }); + + popupMenu.add(reset); + } + itemContainer.add(slotContainer); + } + itemContainer.repaint(); + } + + private int getModifiedItemId(String name, int itemId) + { + if (SuppliesTrackerPlugin.isPotion(name)) + { + return getSingleDose(name); + } + if (SuppliesTrackerPlugin.isCake(name, itemId)) + { + return getSlice(itemId); + } + if (SuppliesTrackerPlugin.isPizzaPie(name)) + { + return getHalf(itemId); + } + + return itemId; + } + + //Switches full cake ids to get the image for slice + private int getSlice(int itemId) + { + switch (itemId) + { + case CAKE: + itemId = SLICE_OF_CAKE; + break; + case CHOCOLATE_CAKE: + itemId = CHOCOLATE_SLICE; + break; + } + return itemId; + } + + //Switches full pizza and pie ids to get the image for half + private int getHalf(int itemId) + { + switch (itemId) + { + case ANCHOVY_PIZZA: + itemId = _12_ANCHOVY_PIZZA; + break; + case MEAT_PIZZA: + itemId = _12_MEAT_PIZZA; + break; + case PINEAPPLE_PIZZA: + itemId = _12_PINEAPPLE_PIZZA; + break; + case PLAIN_PIZZA: + itemId = _12_PLAIN_PIZZA; + break; + case REDBERRY_PIE: + itemId = HALF_A_REDBERRY_PIE; + break; + case GARDEN_PIE: + itemId = HALF_A_GARDEN_PIE; + break; + case SUMMER_PIE: + itemId = HALF_A_SUMMER_PIE; + break; + case FISH_PIE: + itemId = HALF_A_FISH_PIE; + break; + case BOTANICAL_PIE: + itemId = HALF_A_BOTANICAL_PIE; + break; + case MUSHROOM_PIE: + itemId = HALF_A_MUSHROOM_PIE; + break; + case ADMIRAL_PIE: + itemId = HALF_AN_ADMIRAL_PIE; + break; + case WILD_PIE: + itemId = HALF_A_WILD_PIE; + break; + case APPLE_PIE: + itemId = HALF_AN_APPLE_PIE; + break; + case MEAT_PIE: + itemId = HALF_A_MEAT_PIE; + break; + + } + return itemId; + } + + private int getSingleDose(String name) + { + String nameModified = name.replace("(4)", "(1)"); + int itemId = 0; + List itemList = itemManager.search(nameModified); + for (ItemPrice item: itemList) + { + itemId = item.getId(); + } + return itemId; + } + + private static String buildToolTip(SuppliesTrackerItem item) + { + final String name = item.getName(); + final int quantity = item.getQuantity(); + final long price = item.getPrice(); + return name + " x " + quantity + " (" + StackFormatter.quantityToStackSize(price) + ") "; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerConfig.java new file mode 100644 index 0000000000..f14160db15 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerConfig.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018, Davis Cook + * 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.suppliestracker; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("suppliestracker") +public interface SuppliesTrackerConfig extends Config +{ + @ConfigItem( + keyName = "blowpipeAmmo", + name = "Ammo used in your blowpipe", + description = "What type of dart are you using in your toxic blowpipe" + ) + default BlowpipeDartType blowpipeAmmo() + { + return BlowpipeDartType.MITHRIL; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerItem.java new file mode 100644 index 0000000000..270d3b08b1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerItem.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018, Daddy Dozer + * 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.suppliestracker; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor + +class SuppliesTrackerItem +{ + @Getter + private int id; + @Getter + private String name; + @Getter + private int quantity; + @Getter + private long price; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java new file mode 100644 index 0000000000..6eea00105f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2018, Psikoi + * Copyright (c) 2018, Tomas Slusny + * Copyright (c) 2018, Daddy Dozer + * 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.suppliestracker; + +import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.PluginPanel; +import net.runelite.client.ui.components.PluginErrorPanel; +import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.StackFormatter; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.border.EmptyBorder; +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; + + +class SuppliesTrackerPanel extends PluginPanel +{ + private static final String HTML_LABEL_TEMPLATE = + "%s%s"; + + // Handle loot logs + private final JPanel logsContainer = new JPanel(); + + private final List boxList = new ArrayList<>(); + + private final PluginErrorPanel errorPanel = new PluginErrorPanel(); + + private final ScheduledExecutorService executor; + + // Handle overall session data + private final JPanel overallPanel = new JPanel(); + private final JLabel overallSuppliesUsedLabel = new JLabel(); + private final JLabel overallCostLabel = new JLabel(); + private final JLabel overallIcon = new JLabel(); + private final ItemManager itemManager; + private final SuppliesTrackerPlugin plugin; + private int overallSuppliesUsed; + private int overallCost; + + SuppliesTrackerPanel(final ItemManager itemManager, ScheduledExecutorService executor, SuppliesTrackerPlugin plugin) + { + this.executor = executor; + this.itemManager = itemManager; + this.plugin = plugin; + setBorder(new EmptyBorder(6, 6, 6, 6)); + setBackground(ColorScheme.DARK_GRAY_COLOR); + setLayout(new BorderLayout()); + + // Create layout panel for wrapping + final JPanel layoutPanel = new JPanel(); + layoutPanel.setLayout(new BoxLayout(layoutPanel, BoxLayout.Y_AXIS)); + add(layoutPanel, BorderLayout.NORTH); + + // Create panel that will contain overall data + overallPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); + overallPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + overallPanel.setLayout(new BorderLayout()); + overallPanel.setVisible(true); + + // Add icon and contents + final JPanel overallInfo = new JPanel(); + overallInfo.setBackground(ColorScheme.DARKER_GRAY_COLOR); + overallInfo.setLayout(new GridLayout(2, 1)); + overallInfo.setBorder(new EmptyBorder(0, 10, 0, 0)); + overallSuppliesUsedLabel.setFont(FontManager.getRunescapeSmallFont()); + overallCostLabel.setFont(FontManager.getRunescapeSmallFont()); + overallInfo.add(overallSuppliesUsedLabel); + overallInfo.add(overallCostLabel); + overallPanel.add(overallIcon, BorderLayout.WEST); + overallPanel.add(overallInfo, BorderLayout.CENTER); + + for (ItemType type : ItemType.values()) + { + SuppliesBox newBox = new SuppliesBox(itemManager, type.getLabel(), plugin, this, type); + logsContainer.add(newBox); + boxList.add(newBox); + } + + // Create reset all menu + final JMenuItem reset = new JMenuItem("Reset All"); + reset.addActionListener(e -> + { + overallSuppliesUsed = 0; + overallCost = 0; + plugin.clearSupplies(); + for (SuppliesBox box : boxList) + { + box.clearAll(); + } + updateOverall(); + logsContainer.repaint(); + }); + + // Create popup menu + final JPopupMenu popupMenu = new JPopupMenu(); + popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5)); + popupMenu.add(reset); + overallPanel.setComponentPopupMenu(popupMenu); + + // Create Supply Rows wrapper + logsContainer.setLayout(new BoxLayout(logsContainer, BoxLayout.Y_AXIS)); + layoutPanel.add(overallPanel); + layoutPanel.add(logsContainer); + + errorPanel.setContent("Supply trackers", "You have not used any supplies yet."); + add(errorPanel); + overallPanel.setVisible(false); + } + + /** + * loads an img to the icon on the header + * @param img the img for the header icon + */ + public void loadHeaderIcon(BufferedImage img) + { + overallIcon.setIcon(new ImageIcon(img)); + } + + /** + * convert key value pair to html formatting needed to display nicely + * @param key key + * @param value value + * @return key: value in html + */ + private static String htmlLabel(String key, long value) + { + final String valueStr = StackFormatter.quantityToStackSize(value); + return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), key, valueStr); + } + + /** + * Add an item to the supply panel by placing it into the correct box + * @param item the item to add + */ + public void addItem(SuppliesTrackerItem item) + { + ItemType category = ItemType.categorize(item); + for (SuppliesBox box : boxList) + { + if (box.getType() == category) + { + box.update(item); + box.rebuild(); + break; + } + } + updateOverall(); + } + + /** + * Updates overall stats to calculate overall used and overall cost from + * the info in each box + */ + public void updateOverall() + { + overallSuppliesUsed = 0; + for (SuppliesBox box : boxList) + { + overallSuppliesUsed += box.getTotalSupplies(); + } + + overallCost = 0; + for (SuppliesBox box : boxList) + { + overallCost += box.getTotalPrice(); + } + + overallSuppliesUsedLabel.setText(htmlLabel("Total Supplies: ", overallSuppliesUsed)); + overallCostLabel.setText(htmlLabel("Total Cost: ", overallCost)); + + if (overallSuppliesUsed <= 0) + { + add(errorPanel); + overallPanel.setVisible(false); + } + else + { + remove(errorPanel); + overallPanel.setVisible(true); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java new file mode 100644 index 0000000000..f7034af63f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java @@ -0,0 +1,781 @@ +/* + * Copyright (c) 2018, Psikoi + * Copyright (c) 2018, Adam + * Copyright (c) 2018, Sir Girion + * Copyright (c) 2018, Davis Cook + * Copyright (c) 2018, Daddy Dozer + * 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.suppliestracker; + + +import com.google.inject.Provides; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; +import net.runelite.api.events.*; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.ClientToolbar; +import net.runelite.client.ui.NavigationButton; +import net.runelite.client.util.ImageUtil; +import net.runelite.http.api.item.ItemPrice; + +import static net.runelite.api.AnimationID.*; +import static net.runelite.api.ItemID.*; +import static net.runelite.client.plugins.suppliestracker.ActionType.CONSUMABLE; +import static net.runelite.client.plugins.suppliestracker.ActionType.TELEPORT; +import static net.runelite.client.plugins.suppliestracker.ActionType.CAST; + +import java.util.*; +import java.util.concurrent.ScheduledExecutorService; +import java.util.regex.Pattern; +import javax.inject.Inject; +import javax.swing.SwingUtilities; +import java.awt.image.BufferedImage; + + +@PluginDescriptor( + name = "Supplies Used Tracker", + description = "Tracks supplies used during the session", + tags = {"cost"}, + enabledByDefault = false +) +@Slf4j +public class SuppliesTrackerPlugin extends Plugin +{ + + private static final String POTION_PATTERN = "[(]\\d[)]"; + + private static final String EAT_PATTERN = "^eat"; + private static final String DRINK_PATTERN = "^drink"; + private static final String TELEPORT_PATTERN = "^teleport"; + private static final String TELETAB_PATTERN = "^break"; + private static final String SPELL_PATTERN = "^cast|^grand\\sexchange|^outside|^seers|^yanille"; + + private static final int EQUIPMENT_MAINHAND_SLOT = EquipmentInventorySlot.WEAPON.getSlotIdx(); + private static final int EQUIPMENT_AMMO_SLOT = EquipmentInventorySlot.AMMO.getSlotIdx(); + private static final int EQUIPMENT_CAPE_SLOT = EquipmentInventorySlot.CAPE.getSlotIdx(); + + private static final double NO_AVAS_PERCENT = 1.0; + private static final double ASSEMBLER_PERCENT = 0.20; + private static final double ACCUMULATOR_PERCENT = 0.28; + private static final double ATTRACTOR_PERCENT = 0.40; + + private static final int BLOWPIPE_TICKS_RAPID_PVM = 2; + private static final int BLOWPIPE_TICKS_RAPID_PVP = 3; + private static final int BLOWPIPE_TICKS_NORMAL_PVM = 3; + private static final int BLOWPIPE_TICKS_NORMAL_PVP = 4; + + private static final double SCALES_PERCENT = 0.66; + + private static final int POTION_DOSES = 4, CAKE_DOSES = 3, PIZZA_PIE_DOSES = 2; + + private static final Random random = new Random(); + + private static final int[] THROWING_IDS = new int[]{BRONZE_DART, IRON_DART, STEEL_DART, BLACK_DART, MITHRIL_DART, ADAMANT_DART, RUNE_DART, DRAGON_DART, BRONZE_KNIFE, IRON_KNIFE, STEEL_KNIFE, BLACK_KNIFE, MITHRIL_KNIFE, ADAMANT_KNIFE, RUNE_KNIFE, BRONZE_THROWNAXE, IRON_THROWNAXE, STEEL_THROWNAXE, MITHRIL_THROWNAXE, ADAMANT_THROWNAXE, RUNE_THROWNAXE, DRAGON_KNIFE, DRAGON_KNIFE_22812, DRAGON_KNIFE_22814, DRAGON_KNIFEP_22808, DRAGON_KNIFEP_22810, DRAGON_KNIFEP , DRAGON_THROWNAXE, CHINCHOMPA_10033, RED_CHINCHOMPA_10034, BLACK_CHINCHOMPA}; + private static final int[] RUNE_IDS = new int[]{AIR_RUNE, WATER_RUNE, EARTH_RUNE, MIND_RUNE, BODY_RUNE, COSMIC_RUNE, CHAOS_RUNE, NATURE_RUNE, LAW_RUNE, DEATH_RUNE, ASTRAL_RUNE, BLOOD_RUNE, SOUL_RUNE, WRATH_RUNE, MIST_RUNE, DUST_RUNE, MUD_RUNE, SMOKE_RUNE, STEAM_RUNE, LAVA_RUNE}; + + //Hold Supply Data + private static HashMap suppliesEntry = new HashMap<>(); + private ItemContainer old; + private Deque actionStack = new ArrayDeque<>(); + private int ammoId = 0; + private int ammoAmount = 0; + private int thrownId = 0; + private int thrownAmount = 0; + private boolean ammoLoaded = false; + private boolean throwingAmmoLoaded = false; + private boolean mainHandThrowing = false; + private int mainHand = 0; + private SuppliesTrackerPanel panel; + private NavigationButton navButton; + private String[] RAIDS_CONSUMABLES = new String[]{"xeric's", "elder", "twisted", "revitalisation", "overload", "prayer enhance", "pysk", "suphi", "leckish", "brawk", "mycil", "roqed", "kyren", "guanic", "prael", "giral", "phluxia", "kryket", "murng", "psykk"}; + + private int attackStyleVarbit = -1; + private int ticks = 0; + private int ticksInAnimation; + + @Inject + private ClientToolbar clientToolbar; + + @Inject + private ItemManager itemManager; + + @Inject + private SpriteManager spriteManager; + + @Inject + private SuppliesTrackerConfig config; + + @Inject + private Client client; + + @Inject + private ScheduledExecutorService executorService; + + @Inject + private ClientThread clientThread; + + + @Override + protected void startUp() throws Exception + { + panel = new SuppliesTrackerPanel(itemManager, executorService, this); + final BufferedImage header = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); + panel.loadHeaderIcon(header); + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); + + navButton = NavigationButton.builder() + .tooltip("Supplies Tracker") + .icon(icon) + .priority(5) + .panel(panel) + .build(); + + clientToolbar.addNavigation(navButton); + } + + @Override + protected void shutDown() + { + clientToolbar.removeNavigation(navButton); + } + + @Provides + SuppliesTrackerConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(SuppliesTrackerConfig.class); + } + + @Subscribe + public void onGameTick(GameTick tick) + { + Player player = client.getLocalPlayer(); + if (player.getAnimation() == BLOWPIPE_ATTACK) + { + ticks++; + } + if (ticks == ticksInAnimation && (player.getAnimation() == BLOWPIPE_ATTACK)) + { + double ava_percent = getAccumulatorPercent(); + double scale_percent = SCALES_PERCENT; + // randomize the usage of supplies since we CANNOT actually get real supplies used + if (random.nextDouble() <= ava_percent) + { + buildEntries(config.blowpipeAmmo().getDartID()); + + } + if (random.nextDouble() <= scale_percent) + { + buildEntries(ZULRAHS_SCALES); + } + ticks = 0; + } + } + + /** + * checks the player's cape slot to determine what percent of their darts are lost + * - where lost means either break or drop to floor + * @return the percent lost + */ + private double getAccumulatorPercent() + { + double percent = NO_AVAS_PERCENT; + ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT); + if (equipment.getItems().length > EQUIPMENT_CAPE_SLOT) + { + int capeID = equipment.getItems()[EQUIPMENT_CAPE_SLOT].getId(); + switch (capeID) + { + case AVAS_ASSEMBLER: + case ASSEMBLER_MAX_CAPE: + percent = ASSEMBLER_PERCENT; + break; + case AVAS_ACCUMULATOR: + case ACCUMULATOR_MAX_CAPE: + // TODO: the ranging cape can be used as an attractor so this could be wrong + case RANGING_CAPE: + percent = ACCUMULATOR_PERCENT; + break; + case AVAS_ATTRACTOR: + percent = ATTRACTOR_PERCENT; + break; + } + } + return percent; + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + if (attackStyleVarbit == -1 || attackStyleVarbit != client.getVar(VarPlayer.ATTACK_STYLE)) + { + attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE); + if (attackStyleVarbit == 0 || attackStyleVarbit == 3) + { + ticksInAnimation = BLOWPIPE_TICKS_NORMAL_PVM; + if (client.getLocalPlayer() != null && + client.getLocalPlayer().getInteracting() instanceof Player) { + ticksInAnimation = BLOWPIPE_TICKS_NORMAL_PVP; + } + } + else if (attackStyleVarbit == 1) + { + ticksInAnimation = BLOWPIPE_TICKS_RAPID_PVM; + if (client.getLocalPlayer() != null && + client.getLocalPlayer().getInteracting() instanceof Player) { + ticksInAnimation = BLOWPIPE_TICKS_RAPID_PVP; + } + } + } + } + + /** + * Checks for changes between the provided inventories in runes specifically to add those runes + * to the supply tracker + * + * we can't in general just check for when inventory slots change but this method is only run + * immediately after the player performs a cast animation or cast menu click/entry + * @param itemContainer the new inventory + * @param oldInv the old inventory + */ + private void checkUsedRunes(ItemContainer itemContainer, Item[] oldInv) + { + for (int i = 0; i < itemContainer.getItems().length; i++) + { + Item newItem = itemContainer.getItems()[i]; + Item oldItem = oldInv[i]; + boolean isRune = false; + for (int j = 0; j < RUNE_IDS.length; j++) + { + if (oldItem.getId() == RUNE_IDS[j]) + { + isRune = true; + } + } + if (isRune && (newItem.getId() != oldItem.getId() || newItem.getQuantity() != oldItem.getQuantity())) + { + int quantity = oldItem.getQuantity(); + if (newItem.getId() == oldItem.getId()) + { + quantity -= newItem.getQuantity(); + } + buildEntries(oldItem.getId(), quantity); + } + } + } + + @Subscribe + public void onCannonballFired(CannonballFired cannonballFired) + { + buildEntries(CANNONBALL); + } + + @Subscribe + public void onAnimationChanged(AnimationChanged animationChanged) + { + if (animationChanged.getActor() == client.getLocalPlayer()) + { + if (animationChanged.getActor().getAnimation() == HIGH_LEVEL_MAGIC_ATTACK) + { + //Trident of the seas + if (mainHand == TRIDENT_OF_THE_SEAS || mainHand == TRIDENT_OF_THE_SEAS_E || mainHand == TRIDENT_OF_THE_SEAS_FULL ) + { + buildEntries(CHAOS_RUNE); + buildEntries(DEATH_RUNE); + buildEntries(FIRE_RUNE, 5); + buildEntries(COINS_995, 10); + } + //Trident of the swamp + else if (mainHand == TRIDENT_OF_THE_SWAMP_E || mainHand == TRIDENT_OF_THE_SWAMP || mainHand == UNCHARGED_TOXIC_TRIDENT_E || mainHand == UNCHARGED_TOXIC_TRIDENT) + { + buildEntries(CHAOS_RUNE); + buildEntries(DEATH_RUNE); + buildEntries(FIRE_RUNE, 5); + buildEntries(ZULRAHS_SCALES); + } + //Sang Staff + else if (mainHand == SANGUINESTI_STAFF || mainHand == SANGUINESTI_STAFF_UNCHARGED) + { + buildEntries(BLOOD_RUNE, 3); + } + else + { + old = client.getItemContainer(InventoryID.INVENTORY); + + if (old.getItems() != null && !actionStack.stream().anyMatch(a -> + a.getType() == CAST)) + { + MenuAction newAction = new MenuAction(CAST, old.getItems()); + actionStack.push(newAction); + } + } + } + else if (animationChanged.getActor().getAnimation() == LOW_LEVEL_MAGIC_ATTACK) + { + old = client.getItemContainer(InventoryID.INVENTORY); + + if (old.getItems() != null && !actionStack.stream().anyMatch(a -> + a.getType() == CAST)) + { + MenuAction newAction = new MenuAction(CAST, old.getItems()); + actionStack.push(newAction); + } + } + } + } + + @Subscribe + public void onItemContainerChanged(ItemContainerChanged itemContainerChanged) + { + ItemContainer itemContainer = itemContainerChanged.getItemContainer(); + + for (MenuAction action : actionStack) + { + System.out.println(action.getType()); + } + + if (itemContainer == client.getItemContainer(InventoryID.INVENTORY) && old != null && !actionStack.isEmpty()) + { + while (!actionStack.isEmpty()) + { + MenuAction frame = actionStack.pop(); + ActionType type = frame.getType(); + MenuAction.ItemAction itemFrame; + Item[] oldInv = frame.getOldInventory(); + switch (type) + { + case CONSUMABLE: + itemFrame = (MenuAction.ItemAction) frame; + int nextItem = itemFrame.getItemID(); + int nextSlot = itemFrame.getSlot(); + if (itemContainer.getItems()[nextSlot].getId() != oldInv[nextSlot].getId()) + { + buildEntries(nextItem); + } + break; + case TELEPORT: + itemFrame = (MenuAction.ItemAction) frame; + int teleid = itemFrame.getItemID(); + int slot = itemFrame.getSlot(); + if (itemContainer.getItems()[slot].getId() != oldInv[slot].getId() || itemContainer.getItems()[slot].getQuantity() != oldInv[slot].getQuantity()) + { + buildEntries(teleid); + } + break; + case CAST: + checkUsedRunes(itemContainer, oldInv); + break; + } + } + } + + if (itemContainer == client.getItemContainer(InventoryID.EQUIPMENT)) + { + //set mainhand for trident tracking + if (itemContainer.getItems().length > EQUIPMENT_MAINHAND_SLOT) + { + mainHand = itemContainer.getItems()[EQUIPMENT_MAINHAND_SLOT].getId(); + net.runelite.api.Item mainHandItem = itemContainer.getItems()[EQUIPMENT_MAINHAND_SLOT]; + for (int throwingIDs: THROWING_IDS) + { + if (mainHand == throwingIDs) + { + mainHandThrowing = true; + break; + } + else + { + mainHandThrowing = false; + } + } + if (mainHandThrowing) + { + if (throwingAmmoLoaded) + { + if (thrownId == mainHandItem.getId()) + { + if (thrownAmount - 1 == mainHandItem.getQuantity()) + { + buildEntries(mainHandItem.getId()); + thrownAmount = mainHandItem.getQuantity(); + } + else + { + thrownAmount = mainHandItem.getQuantity(); + } + } + else + { + thrownId = mainHandItem.getId(); + thrownAmount = mainHandItem.getQuantity(); + } + } + else + { + thrownId = mainHandItem.getId(); + thrownAmount = mainHandItem.getQuantity(); + throwingAmmoLoaded = true; + } + } + } + //Ammo tracking + if (itemContainer.getItems().length > EQUIPMENT_AMMO_SLOT) + { + net.runelite.api.Item ammoSlot = itemContainer.getItems()[EQUIPMENT_AMMO_SLOT]; + if (ammoSlot != null) + { + if (ammoLoaded) + { + if (ammoId == ammoSlot.getId()) + { + if (ammoAmount - 1 == ammoSlot.getQuantity()) + { + buildEntries(ammoSlot.getId()); + ammoAmount = ammoSlot.getQuantity(); + } + else + { + ammoAmount = ammoSlot.getQuantity(); + } + } + else + { + ammoId = ammoSlot.getId(); + ammoAmount = ammoSlot.getQuantity(); + } + } + else + { + ammoId = ammoSlot.getId(); + ammoAmount = ammoSlot.getQuantity(); + ammoLoaded = true; + } + } + } + + } + } + + @Subscribe + public void onMenuOptionClicked(final MenuOptionClicked event) + { + System.out.println(event.getMenuAction().getId()); + System.out.println(event.getActionParam()); + System.out.println(event.getMenuOption()); + System.out.println(event.getMenuTarget()); + + // Uses stacks to push/pop for tick eating + // Create pattern to find eat/drink at beginning + Pattern eatPattern = Pattern.compile(EAT_PATTERN); + Pattern drinkPattern = Pattern.compile(DRINK_PATTERN); + if (eatPattern.matcher(event.getMenuTarget().toLowerCase()).find() || drinkPattern.matcher(event.getMenuTarget().toLowerCase()).find()) + { + if (!actionStack.stream().anyMatch(a -> + { + if (a instanceof MenuAction.ItemAction) + { + MenuAction.ItemAction i = (MenuAction.ItemAction) a; + return i.getItemID() == event.getId(); + } + return false; + })) + { + old = client.getItemContainer(InventoryID.INVENTORY); + int slot = event.getActionParam(); + if (old.getItems() != null) + { + int pushItem = old.getItems()[event.getActionParam()].getId(); + MenuAction newAction = new MenuAction.ItemAction(CONSUMABLE, old.getItems(), pushItem, slot); + actionStack.push(newAction); + } + } + } + + // Create pattern for teleport scrolls and tabs + Pattern teleportPattern = Pattern.compile(TELEPORT_PATTERN); + Pattern teletabPattern = Pattern.compile(TELETAB_PATTERN); + if (teleportPattern.matcher(event.getMenuTarget().toLowerCase()).find() || + teletabPattern.matcher(event.getMenuTarget().toLowerCase()).find()) + { + old = client.getItemContainer(InventoryID.INVENTORY); + + // Makes stack only contains one teleport type to stop from adding multiple of one teleport + if (old.getItems() != null && !actionStack.stream().anyMatch(a -> + a.getType() == TELEPORT)) + { + int teleid = event.getId(); + MenuAction newAction = new MenuAction.ItemAction(TELEPORT, old.getItems(), teleid, event.getActionParam()); + actionStack.push(newAction); + } + } + + // Create pattern for spell cast + Pattern spellPattern = Pattern.compile(SPELL_PATTERN); + // note that here we look at the menuOption not menuTarget b/c the option for all spells is cast + // but the target differs based on each spell name + if (spellPattern.matcher(event.getMenuOption().toLowerCase()).find()) + { + old = client.getItemContainer(InventoryID.INVENTORY); + + if (old.getItems() != null && !actionStack.stream().anyMatch(a -> + a.getType() == CAST)) + { + MenuAction newAction = new MenuAction(CAST, old.getItems()); + actionStack.push(newAction); + } + } + } + + /** + * Checks if item name is potion + * @param name the name of the item + * @return if the item is a potion - i.e. has a (1) (2) (3) or (4) in the name + */ + static boolean isPotion(String name) + { + return name.contains("(4)") || name.contains("(3)") || name.contains("(2)") || name.contains("(1)"); + } + + /** + * Checks if item name is pizza or pie + * @param name the name of the item + * @return if the item is a pizza or a pie - i.e. has pizza or pie in the name + */ + static boolean isPizzaPie(String name) + { + return name.toLowerCase().contains("pizza") || name.toLowerCase().contains(" pie"); + } + + static boolean isCake(String name, int itemId) + { + return name.toLowerCase().contains("cake") || itemId == ItemID.CHOCOLATE_SLICE; + } + + /** + * correct prices for potions, pizzas pies, and cakes + * tracker tracks each dose of a potion/pizza/pie/cake as an entire one + * so must divide price by total amount of doses in each + * this is necessary b/c the most correct/accurate price for these resources is the + * full price not the 1-dose price + * @param name the item name + * @param itemId the item id + * @param price the current calculated price + * @return the price modified by the number of doses + */ + private long scalePriceByDoses(String name, int itemId, long price) + { + if (isPotion(name)) + { + return price / POTION_DOSES; + } + if (isPizzaPie(name)) + { + return price / PIZZA_PIE_DOSES; + } + if (isCake(name, itemId)) + { + return price / CAKE_DOSES; + } + return price; + } + + /** + * Add an item to the supply tracker (with 1 count for that item) + * @param itemId the id of the item + */ + void buildEntries(int itemId) + { + buildEntries(itemId, 1); + } + + /** + * Add an item to the supply tracker + * @param itemId the id of the item + * @param count the amount of the item to add to the tracker + */ + void buildEntries(int itemId, int count) + { + final ItemComposition itemComposition = itemManager.getItemComposition(itemId); + String name = itemComposition.getName(); + long calculatedPrice; + + for (String raidsConsumables: RAIDS_CONSUMABLES) + { + if (name.toLowerCase().contains(raidsConsumables)) return; + } + + // convert potions, pizzas/pies, and cakes to their full equivalents + // e.g. a half pizza becomes full pizza, 3 dose potion becomes 4, etc... + if (isPotion(name)) + { + name = name.replaceAll(POTION_PATTERN, "(4)"); + itemId = getPotionID(name); + } + if (isPizzaPie(name)) + { + itemId = getFullVersionItemID(itemId); + name = itemManager.getItemComposition(itemId).getName(); + } + if (isCake(name, itemId)) + { + itemId = getFullVersionItemID(itemId); + name = itemManager.getItemComposition(itemId).getName(); + } + + int newQuantity; + if (suppliesEntry.containsKey(itemId)) + { + newQuantity = suppliesEntry.get(itemId).getQuantity() + count; + } + else + { + newQuantity = count; + } + + // calculate price for amount of doses used + calculatedPrice = ((long) itemManager.getItemPrice(itemId)) * ((long) newQuantity); + calculatedPrice = scalePriceByDoses(name, itemId, calculatedPrice); + + // write the new quantity and calculated price for this entry + SuppliesTrackerItem newEntry = new SuppliesTrackerItem( + itemId, + name, + newQuantity, + calculatedPrice); + + suppliesEntry.put(itemId, newEntry); + SwingUtilities.invokeLater(() -> + { + panel.addItem(newEntry); + }); + } + + /** + * reset all item stacks + */ + public void clearSupplies() + { + suppliesEntry.clear(); + } + + /** + * reset an individual item stack + * @param itemId the id of the item stack + */ + public void clearItem(int itemId) + { + suppliesEntry.remove(itemId); + } + + /** + * Gets the item id that matches the provided name within the itemManager + * @param name the given name + * @return the item id for this name + */ + private int getPotionID(String name) + { + int itemId = 0; + + List items = itemManager.search(name); + for (ItemPrice item: items) + { + if (item.getName().contains(name)) + { + itemId = item.getId(); + } + } + return itemId; + } + + /** + * Takes the item id of a partial item (e.g. 1 dose potion, 1/2 a pizza, etc...) and returns + * the corresponding full item + * @param itemId the partial item id + * @return the full item id + */ + private int getFullVersionItemID(int itemId) + { + switch (itemId) + { + case _12_ANCHOVY_PIZZA: + itemId = ANCHOVY_PIZZA; + break; + case _12_MEAT_PIZZA: + itemId = MEAT_PIZZA; + break; + case _12_PINEAPPLE_PIZZA: + itemId = PINEAPPLE_PIZZA; + break; + case _12_PLAIN_PIZZA: + itemId = PLAIN_PIZZA; + break; + case HALF_A_REDBERRY_PIE: + itemId = REDBERRY_PIE; + break; + case HALF_A_GARDEN_PIE: + itemId = GARDEN_PIE; + break; + case HALF_A_SUMMER_PIE: + itemId = SUMMER_PIE; + break; + case HALF_A_FISH_PIE: + itemId = FISH_PIE; + break; + case HALF_A_BOTANICAL_PIE: + itemId = BOTANICAL_PIE; + break; + case HALF_A_MUSHROOM_PIE: + itemId = MUSHROOM_PIE; + break; + case HALF_AN_ADMIRAL_PIE: + itemId = ADMIRAL_PIE; + break; + case HALF_A_WILD_PIE: + itemId = WILD_PIE; + break; + case HALF_AN_APPLE_PIE: + itemId = APPLE_PIE; + break; + case HALF_A_MEAT_PIE: + itemId = MEAT_PIE; + break; + // note behavior of case means both below cases return CAKE + case _23_CAKE: + case SLICE_OF_CAKE: + itemId = CAKE; + break; + case _23_CHOCOLATE_CAKE: + case CHOCOLATE_SLICE: + itemId = CHOCOLATE_CAKE; + break; + } + return itemId; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java new file mode 100644 index 0000000000..119a70f245 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018, Frosty Fridge + * 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.templetrek; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import javax.inject.Inject; +import net.runelite.api.GroundObject; +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; + +public class TempleTrekBogOverlay extends Overlay +{ + private final TempleTrekConfig config; + private final TempleTrekPlugin plugin; + + private static final Color GREEN = new Color(0, 200, 83); + + @Inject + private TempleTrekBogOverlay(TempleTrekConfig config, TempleTrekPlugin plugin) + { + super(plugin); + this.config = config; + this.plugin = plugin; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.LOW); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (config.bogMapActive()) + { + for (GroundObject bog : plugin.getBogList()) + { + Polygon bogPoly = bog.getCanvasTilePoly(); + OverlayUtil.renderPolygon(graphics, bogPoly, GREEN); + } + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java new file mode 100644 index 0000000000..090d1a9cab --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018, Frosty Fridge + * 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.templetrek; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("templetrek") +public interface TempleTrekConfig extends Config +{ + @ConfigItem( + keyName = "bogMapActive", + name = "Bog Map", + description = "Marks out a safe route through the bog event", + position = 0 + ) + default boolean bogMapActive() + { + return true; + } + + @ConfigItem( + keyName = "pointTrackerActive", + name = "Point Tracker", + description = "Track your Temple Trek reward points, which determine the size of your reward.", + position = 1 + ) + default boolean pointTrackerActive() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java new file mode 100644 index 0000000000..afbf4c88a5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018, Frosty Fridge + * 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.templetrek; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +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.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +public class TempleTrekOverlay extends Overlay +{ + private final TempleTrekConfig config; + private final TempleTrekPlugin plugin; + + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + private TempleTrekOverlay(TempleTrekConfig config, TempleTrekPlugin plugin) + { + super(plugin); + this.config = config; + this.plugin = plugin; + setPosition(OverlayPosition.TOP_LEFT); + setPriority(OverlayPriority.LOW); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (config.pointTrackerActive() && plugin.isInTrek()) + { + int points = plugin.getRewardPoints(); + double percentage = plugin.getRewardPercentage() * 100; + panelComponent.getChildren().clear(); + panelComponent.getChildren().add(LineComponent.builder() + .left("Trek Points: ") + .right(Integer.toString(points)) + .rightColor(percentage < 25 ? Color.RED : percentage >= 25 && percentage < 50 ? Color.YELLOW : + percentage >= 50 && percentage < 75 ? Color.BLUE : Color.GREEN) + .build()); + panelComponent.getChildren().add(LineComponent.builder() + .left("Reward %: ") + .right(String.format("%.2f", percentage) + "%") + .rightColor(percentage < 25 ? Color.RED : percentage >= 25 && percentage < 50 ? Color.YELLOW : + percentage >= 50 && percentage < 75 ? Color.BLUE : Color.GREEN) + .build()); + return panelComponent.render(graphics); + } + return null; + } +} 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 new file mode 100644 index 0000000000..99fd1d4286 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2018, Frosty Fridge + * 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.templetrek; + +import com.google.inject.Provides; +import java.util.HashSet; +import java.util.Set; +import javax.inject.Inject; +import lombok.Getter; +import net.runelite.api.Client; +import net.runelite.api.GroundObject; +import net.runelite.api.ObjectID; +import net.runelite.api.Varbits; +import net.runelite.api.events.GroundObjectSpawned; +import net.runelite.api.events.VarbitChanged; +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.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "Temple Trekking", + description = "Helpers for the Temple Trek minigame", + tags = {"minigame", "overlay", "temple trek"} +) +public class TempleTrekPlugin extends Plugin +{ + + @Inject + private Client client; + + @Inject + private OverlayManager overlayManager; + + @Inject + private TempleTrekOverlay overlay; + + @Inject + private TempleTrekBogOverlay bogOverlay; + + @Inject + private TempleTrekConfig config; + + @Getter + private final Set bogList = new HashSet(); + + @Getter + private boolean inTrek = false; + + @Provides + TempleTrekConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(TempleTrekConfig.class); + } + + @Override + protected void startUp() + { + overlayManager.add(overlay); + overlayManager.add(bogOverlay); + } + + @Override + protected void shutDown() + { + overlayManager.remove(overlay); + overlayManager.remove(bogOverlay); + bogList.clear(); + } + + @Subscribe + public void onGroundObjectSpawned(GroundObjectSpawned event) + { + GroundObject obj = event.getGroundObject(); + if (obj.getId() == ObjectID.BOG) + { + bogList.add(obj); + } + } + + //onGroundObjectDespawned is having issues handling this, so bogmap removal is here instead. + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + if (!bogList.isEmpty() && client.getVar(Varbits.TREK_EVENT) == 0) + { + bogList.clear(); + } + if (!inTrek && client.getVar(Varbits.TREK_STARTED) == 1) + { + inTrek = true; + } + else if (inTrek) + { + if (client.getVar(Varbits.TREK_STATUS) == 0 && client.getVar(Varbits.TREK_POINTS) == 0) + { + inTrek = false; + } + } + } + + protected int getRewardPoints() + { + return client.getVar(Varbits.TREK_POINTS); + } + + protected double getRewardPercentage() + { + double percentage = 0.000126945 * getRewardPoints() - 0.0357188951; + return Math.max(percentage, 0); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java new file mode 100644 index 0000000000..79e90dc38d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java @@ -0,0 +1,71 @@ +package net.runelite.client.plugins.tickcounter; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +import java.awt.*; + +@ConfigGroup("tickcounter") +public interface TickCounterConfig extends Config { + @ConfigItem( + keyName = "resetInstance", + name = "Reset on new instances", + description = "", + position = 1 + ) + default boolean instance() + { + return true; + } + @ConfigItem( + keyName = "selfColor", + name = "Your color", + description = "", + position = 4 + ) + default Color selfColor() + { + return Color.green; + } + @ConfigItem( + keyName = "totalColor", + name = "Total color", + description = "", + position = 6 + ) + default Color totalColor() + { + return Color.RED; + } + @ConfigItem( + keyName = "otherColor", + name = "Other players color", + description = "", + position = 5 + ) + default Color otherColor() + { + return Color.white; + } + @ConfigItem( + keyName = "bgColor", + name = "Background color", + description = "", + position = 3 + ) + default Color bgColor() + { + return new Color(70, 61, 50, 156); + } + @ConfigItem( + keyName = "titleColor", + name = "Title color", + description = "", + position = 2 + ) + default Color titleColor() + { + return Color.white; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java new file mode 100644 index 0000000000..33e22fe1fa --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java @@ -0,0 +1,69 @@ +package net.runelite.client.plugins.tickcounter; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map.Entry; + +import javax.inject.Inject; + +import net.runelite.api.Client; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +public class TickCounterOverlay extends Overlay { + + private TickCounterPlugin plugin; + private TickCounterConfig config; + private Client client; + private PanelComponent panelComponent = new PanelComponent(); + + @Inject + public TickCounterOverlay(TickCounterPlugin plugin,Client client,TickCounterConfig config) { + super(plugin); + setPosition(OverlayPosition.DYNAMIC); + setPosition(OverlayPosition.DETACHED); + setPosition(OverlayPosition.BOTTOM_RIGHT); + this.plugin = plugin; + this.client = client; + this.config = config; + } + + @Override + public Dimension render(Graphics2D g) { + List elems = panelComponent.getChildren(); + elems.clear(); + panelComponent.setBackgroundColor(config.bgColor()); + elems.add(TitleComponent.builder().text("Combat counter").color(config.titleColor()).build()); + List> list = new ArrayList<>(plugin.activity.entrySet()); + list.sort(new Comparator>() { + @Override + public int compare(Entry o1, Entry o2) { + int value = -Integer.compare(o1.getValue(), o2.getValue()); + if (value == 0) + value = o1.getKey().compareTo(o2.getKey()); + return value; + } + }); + int total = 0; + for (Entry e : list) { + total += e.getValue(); + if(e.getKey().equals(client.getLocalPlayer().getName())){ + elems.add(LineComponent.builder().leftColor(config.selfColor()).rightColor(config.selfColor()).left(e.getKey()).right(e.getValue().toString()).build()); + }else{ + elems.add(LineComponent.builder().left(e.getKey()).right(e.getValue().toString()).leftColor(config.otherColor()).rightColor(config.otherColor()).build()); + + } + } + elems.add(LineComponent.builder().left("Total").leftColor(config.totalColor()).rightColor(config.totalColor()).right(String.valueOf(total)).build()); + return this.panelComponent.render(g); + } + +} 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 new file mode 100644 index 0000000000..fe2130285c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java @@ -0,0 +1,193 @@ +package net.runelite.client.plugins.tickcounter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import com.google.inject.Provides; +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.api.Player; +import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.ClientTick; +import net.runelite.api.events.GameTick; +import net.runelite.api.kit.KitType; +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.ui.overlay.OverlayManager; + +@PluginDescriptor(name = "!Tick Counter", + description = "Counts combat activity for nearby players", + enabledByDefault = false +) +public class TickCounterPlugin extends Plugin { + + @Inject + private OverlayManager overlayManager; + @Inject + private TickCounterConfig config; + @Inject + private Client client; + @Provides + TickCounterConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(TickCounterConfig.class); + } + @Inject + private TickCounterOverlay overlay; + + Map activity = new HashMap<>(); + + private List blowpiping = new ArrayList<>(); + boolean instanced = false; + boolean prevInstance = false; + + @Override + protected void startUp() throws Exception { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception { + overlayManager.remove(overlay); + activity.clear(); + } + + @Subscribe + public void onAnimationChanged(AnimationChanged e) { + if (!(e.getActor() instanceof Player)) + return; + Player p = (Player) e.getActor(); + int weapon = -1; + if (p.getPlayerComposition() != null) + weapon = p.getPlayerComposition().getEquipmentId(KitType.WEAPON); + int delta = 0; + switch (p.getAnimation()) { + case 7617: // rune knife + case 8194: // dragon knife + case 8291: // dragon knife spec + case 5061: // blowpipe + if (weapon == 12926) + { + blowpiping.add(p); + } + else + { + delta = 2; + } + break; + case 2323: // rpg + case 7618: // chin + delta = 3; + break; + case 426: // bow shoot + if (weapon == 20997) // twisted bow + delta = 5; + else // shortbow + delta = 3; + break; + case 376: // dds poke + case 377: // dds slash + case 422: // punch + case 423: // kick + case 386: // lunge + case 390: // generic slash + case 1062: // dds spec + case 1067: // claw stab + case 1074: // msb spec + case 1167: // trident cast + case 1658: // whip + case 2890: // arclight spec + case 3294: // abby dagger slash + case 3297: // abby dagger poke + case 3298: // bludgeon attack + case 3299: // bludgeon spec + case 3300: // abby dagger spec + case 7514: // claw spec + case 7515: // d sword spec + case 8145: // rapier stab + case 8288: // dhl stab + case 8289: // dhl slash + case 8290: // dhl crush + delta = 4; + break; + case 393: // staff bash + if (weapon == 13652) { // claw scratch + delta = 4; + break; + } + case 395: // axe autos + case 400: // pick smash + case 1379: //burst or blitz + case 1979: // barrage spell cast + case 1162: // strike/bolt spells + case 7552: // generic crossbow + case 7855: // surge spells + case 8056: // scythe swing + delta = 5; + break; + case 401: + if (weapon == 13576) // dwh bop + delta = 6; + else // used by pickaxe and axe + delta = 5; + break; + case 1378: + case 7045: + case 7054: + case 7055: // godsword autos + case 7511: // dinh's attack + case 7516: // maul attack + case 7555: // ballista attack + case 7638: // zgs spec + case 7640: // sgs spec + case 7642: // bgs spec + case 7643: // bgs spec + case 7644: // ags spec + delta = 6; + break; + case 428: // chally swipe + case 440: // chally jab + case 1203: // chally spec + delta = 7; + break; + case -1: + blowpiping.remove(p); + break; + } + if (delta > 0) { + String name = p.getName(); + this.activity.put(name, this.activity.getOrDefault(name, 0) + delta); + } + } + + @Subscribe + public void onClientTick(ClientTick e) { + /* + * Hack for blowpipe since the AnimationChanged event doesn't fire when using a + * blowpipe because of its speed. If blowpipe animation restarts, then add 2 + */ + for (Player p : blowpiping) { + Actor rsp = p; + if (rsp.getActionFrame() == 0 && rsp.getActionFrameCycle() == 1) { + String name = p.getName(); + int activity = this.activity.getOrDefault(name, 0).intValue(); + this.activity.put(name, activity + 2); + } + } + } + @Subscribe + public void onGameTick(GameTick tick){ + if(!config.instance())return; + prevInstance = instanced; + instanced = client.isInInstancedRegion(); + if(!prevInstance && instanced){ + activity.clear(); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java index 96cf62c6fc..520dcb0f3b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java @@ -50,7 +50,7 @@ class OverviewItemPanel extends JPanel static { - ARROW_RIGHT_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(TimeTrackingPlugin.class, "/util/arrow_right.png")); + ARROW_RIGHT_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(TimeTrackingPlugin.class, "/net/runelite/client/plugins/timetracking/arrow_right.png")); } OverviewItemPanel(ItemManager itemManager, TimeTrackingPanel pluginPanel, Tab tab, String title) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java index b49e461025..9279883311 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java @@ -111,7 +111,7 @@ public class TimeTrackingPlugin extends Plugin birdHouseTracker.loadFromConfig(); farmingTracker.loadCompletionTimes(); - final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "watch.png"); + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "/net/runelite/client/plugins/timetracking/watch.png"); panel = new TimeTrackingPanel(itemManager, config, farmingTracker, birdHouseTracker, clockManager); 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 new file mode 100644 index 0000000000..d7cda5adff --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2018, Bryan Chau(RSN:Laura Brehm) + * 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.tobdamagecount; + +import javax.inject.Inject; +import java.text.DecimalFormat; + +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; +import net.runelite.api.Skill; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Actor; +import net.runelite.api.Player; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.HitsplatApplied; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.LocalPlayerDeath; +import net.runelite.client.chat.ChatColorType; +import net.runelite.client.chat.ChatMessageBuilder; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.eventbus.Subscribe; + + +@PluginDescriptor( + name = "ToB Damage Counter", + 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"}, + enabledByDefault = false +) + +public class DamageCounterPlugin extends Plugin +{ + private int currentWorld = -1; + private int DamageCount = 0; + private int currenthpxp = -1; // checking the current hp xp so be easier to find + private String BossName = null; //to ID the boss to calculate the damage + private int DamageTaken = 0; + private boolean status = true; //default boolean alive = true, dead = false + //formatting the number for damage taken and dealt with to look beeter + private static final DecimalFormat DAMAGEFORMAT = new DecimalFormat("#,###"); + private static final double XP_RATIO = 1.3333; + private static final double BOSS_MODIFIER = 1.05; + private static final int MAIDENHP = 3500; + private static final int BLOATHP = 2000; + private static final int NYLOHP = 2500; + private static final int SOTHP = 4000; + private static final int XARPUSHP = 5080; + private static final int VERZIKHP = 8500; + private static final boolean ALIVE = true; // + private static final boolean DEAD = false; //if they're dead they cannot "recreate" the message of being alive + //locations at ToB + private static final int MAIDEN_REGION = 12613; + private static final int MAIDEN_REGION_1 = 12869; + private static final int BLOAT_REGION = 13125; + private static final int NYLOCAS_REGION = 13122; + private static final int SOTETSEG_REGION = 13123; + private static final int SOTETSEG_REGION2 = 13379; + private static final int XARPUS_REGION = 12612; + private static final int VERZIK_REGION = 12611; + private static final int[] ToB_Region = {MAIDEN_REGION, MAIDEN_REGION_1, BLOAT_REGION, NYLOCAS_REGION, + SOTETSEG_REGION, SOTETSEG_REGION2, XARPUS_REGION, VERZIK_REGION}; + //setting up the array for a check list + private static int[] NPCARRAY = {NpcID.THE_MAIDEN_OF_SUGADINTI, NpcID.THE_MAIDEN_OF_SUGADINTI_8361, + NpcID.THE_MAIDEN_OF_SUGADINTI_8362, NpcID.THE_MAIDEN_OF_SUGADINTI_8363, NpcID.THE_MAIDEN_OF_SUGADINTI_8364, + NpcID.THE_MAIDEN_OF_SUGADINTI_8365, NpcID.PESTILENT_BLOAT, NpcID.NYLOCAS_VASILIAS, + NpcID.NYLOCAS_VASILIAS_8355, NpcID.NYLOCAS_VASILIAS_8356, NpcID.NYLOCAS_VASILIAS_8357, NpcID.SOTETSEG, + NpcID.SOTETSEG_8388, NpcID.XARPUS, NpcID.XARPUS_8339, NpcID.XARPUS_8340, NpcID.XARPUS_8341, + NpcID.VERZIK_VITUR, NpcID.VERZIK_VITUR_8369, NpcID.VERZIK_VITUR_8370, NpcID.VERZIK_VITUR_8371, + NpcID.VERZIK_VITUR_8372, NpcID.VERZIK_VITUR_8373, NpcID.VERZIK_VITUR_8374, NpcID.VERZIK_VITUR_8375}; + + private int[] HEALTHARRAY = {MAIDENHP, NYLOHP, VERZIKHP}; + + @Inject + private Client client; + @Inject + private ChatMessageManager chatMessangerManager; + //every game tick it will go through methods + @Subscribe + private void onGameTick(GameTick tick) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + ResetCounter(); + return; + } + checkInterAction(); + DamageCounting(); + currenthpxp = client.getSkillExperience(Skill.HITPOINTS); + } + //checks for npcID and put the boss name into a string be easier to ID it + //once the boss is found it will never check it + private void checkInterAction() + { + Player localPlayer = client.getLocalPlayer(); + Actor interacting = localPlayer.getInteracting(); + if (client.getGameState() == GameState.LOGGED_IN) + { + if (BossName == null) + { + if (interacting instanceof NPC) + { + int interactingId = ((NPC) interacting).getId(); + String interactingName = interacting.getName(); + for (int aNPCARRAY : NPCARRAY) + { + if (aNPCARRAY == interactingId) + { + BossName = interactingName; + } + } + } + } + } + } + + @Subscribe + //if you hop it will reset the counter + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOGGED_IN) + { + if (currentWorld == -1) + { + currentWorld = client.getWorld(); + } + else if (currentWorld != client.getWorld()) + { + currentWorld = client.getWorld(); + ResetCounter(); + } + } + } + + //grabbing the xp and calculating the damage + private int XPtoDamage() + { + int NewXp; + double damageOutput = 0; + int XPdrop; + if (currenthpxp != -1) + { + XPdrop = client.getSkillExperience(Skill.HITPOINTS); + NewXp = XPdrop - currenthpxp; + currenthpxp = -1; + damageOutput = NewXp / XP_RATIO; + } + //returns the damage you have done + return (int) Math.floor(damageOutput); + } + + //adding up the damage for the print message checks every tick(aka attack tick) + private void DamageCounting() + { + Player localPlayer = client.getLocalPlayer(); + Actor interacting = localPlayer.getInteracting(); + if (client.getGameState() == GameState.LOGGED_IN) + { + if (interacting instanceof NPC) + { + String interactingName = interacting.getName(); + int NPC = ((NPC) interacting).getId(); + if (interactingName.equals(BossName)) + { + DamageCount += (XPtoDamage() * BOSS_MODIFIER); + + } + } + } + } + + + @Subscribe + //will add the damage that you have taken from the current boss fight + private void onHitsplatApplied(HitsplatApplied Hit) + { + if (Hit.getActor().equals(client.getLocalPlayer())) + { + DamageTaken += Hit.getHitsplat().getAmount(); + } + + } + + //will check for the monster if it died works only on ToB Bosses + /*Verzik has three phases so the program will add up all the damage and prints it into one message + because every time she phases she "dies" so making sure the counter doesn't print out the damage for phase 1, 2, + and 3. + */ + @Subscribe + public void onNpcDespawned(NpcDespawned npc) + { + NPC actor = npc.getNpc(); + double Percent = calculatePercent(WorldPoint.fromLocalInstance(client, + client.getLocalPlayer().getLocalLocation()).getRegionID()); + if (actor.isDead() && actor.getId() == NpcID.VERZIK_VITUR_8375 && status) + { + DamagePrint(actor, Percent); + ResetCounter(); + } + else if (actor.isDead() && actor.getName().equals(BossName) && actor.getId() != NpcID.VERZIK_VITUR_8374 && + actor.getId() != NpcID.VERZIK_VITUR_8372 && actor.getId() != NpcID.VERZIK_VITUR_8370 && + status) + { + DamagePrint(actor, Percent); + ResetCounter(); + } + //will reset the counter after the boss dies and if you died during the fight + else if (actor.isDead() && actor.getName().equals(BossName) && !status) + { + ResetCounter(); + } + } + + private double calculatePercent(int id) + { + double percent = 0; + if (DamageCount != 0) { + if (id == MAIDEN_REGION || id == MAIDEN_REGION_1) + { + percent = (DamageCount / (double) MAIDENHP) * 100; + } + else if (id == BLOAT_REGION) + { + percent = (DamageCount / (double) BLOATHP) * 100; + } + else if (id == NYLOCAS_REGION) + { + percent = (DamageCount / (double) NYLOHP) * 100; + } + else if (id == SOTETSEG_REGION || id == SOTETSEG_REGION2) + { + percent = (DamageCount / (double) SOTHP) * 100; + } + else if (id == XARPUS_REGION) + { + percent = (DamageCount / (double) XARPUSHP) * 100; + } + else if (id == VERZIK_REGION) + { + percent = (DamageCount / (double) VERZIKHP) * 100; + } + } + return percent; + } + + //just reset the counter for the next fight and status + private void ResetCounter() + { + DamageCount = 0; + DamageTaken = 0; + BossName = null; + status = ALIVE; + } + + //print out the damage after the boss have died + //prevent people from spectating to get the damage message, it is impossible for them to get damage + private void DamagePrint(NPC actor, double percent) + { + String MessageDamage; + if (percent >= 50) + { + MessageDamage = "Well done carrying the team!" + + "WOWIE!! You did" + DAMAGEFORMAT.format(DamageCount) + " damage to " + + actor.getName() + "! You did %" + String.format("%.2f", percent) + " of the damage"; + } + else if (percent >= 25) + { + MessageDamage = "Well done carrying some dead weight in your team! " + + "Awesome! You did " + DAMAGEFORMAT.format(DamageCount) + " damage to " + + actor.getName() + "! You did %" + String.format("%.2f", percent) + " of the damage"; + } + else if (percent >= 1) + { + MessageDamage = "Well done everyone is pulling their weight! " + + "You did " + DAMAGEFORMAT.format(DamageCount) + " damage to " + + actor.getName() + "! You did %" + String.format("%.2f", percent) + " of the damage"; + } + else + { + MessageDamage = "Didn't do much" + + "Fucking leech did " + DAMAGEFORMAT.format(DamageCount) + " damage to " + + actor.getName() + "! You did %" + String.format("%.2f", percent) + " of the damage"; + } + + sendChatMessage(MessageDamage); + String MessageTaken = "You have taken " + DAMAGEFORMAT.format(DamageTaken) + " damage from this fight!"; + sendChatMessage(MessageTaken); + } + + @Subscribe + //whenever you have died in tob you will get a death message with damage + // made sure the message works at ToB area or else it will message every where + private void onLocalPlayerDeath(LocalPlayerDeath death) + { + String DeathMessage = "You have died! You did " + DAMAGEFORMAT.format(DamageCount) + " damage to " + + BossName + "!"; + String MessageTaken = "You have taken " + DAMAGEFORMAT.format(DamageTaken) + " damage from this fight!"; + for (int i = 0; i < ToB_Region.length; i++) + { + if (WorldPoint.fromLocalInstance(client, + client.getLocalPlayer().getLocalLocation()).getRegionID() == ToB_Region[i]) + { + sendChatMessage(DeathMessage); + sendChatMessage(MessageTaken); + ResetCounter(); + //status will become "dead" after you died in the fight + status = DEAD; + } + } + } + + //sends a message saying this "You have done XYZ damage to boss name! or the death message + // "Well done! you have done your best, you have done XYZ damage to boss name + private void sendChatMessage(String chatMessage) + { + final String message = new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append(chatMessage) + .build(); + chatMessangerManager.queue( + QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .runeLiteFormattedMessage(message) + .build()); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionConfig.java new file mode 100644 index 0000000000..b97e73b318 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionConfig.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019, Frosty Fridge + * 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.vetion; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("vetion") +public interface VetionConfig extends Config +{ + @ConfigItem( + keyName = "earthquakeTimerActive", + name = "Vet'ion Earthquake Timer", + description = "Configures whether or not a timer is shown to track the cooldown of Vet'ion's earthquake attack", + position = 0 + ) + default boolean eartquakeTimerActive() + { + return true; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionOverlay.java new file mode 100644 index 0000000000..dcc51b0929 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionOverlay.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019, Frosty Fridge + * 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.vetion; + +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ProgressPieComponent; + +import javax.inject.Inject; +import java.awt.*; +import java.time.Duration; +import java.time.Instant; + +public class VetionOverlay extends Overlay{ + + private static final Color RED_ALPHA = new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue(), 100); + private static final Duration MAX_TIME = Duration.ofSeconds(9); + private final VetionPlugin plugin; + private Client client; + + @Inject + private VetionOverlay(Client client, VetionPlugin plugin) + { + this.plugin = plugin; + this.client = client; + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + plugin.getVetions().forEach((actor, timer) -> + { + LocalPoint localPos = actor.getLocalLocation(); + if (localPos != null) + { + Point position = Perspective.localToCanvas(client, localPos, client.getPlane(), + actor.getLogicalHeight() + 96); + if (position != null) + { + position = new Point(position.getX(), position.getY()); + + final ProgressPieComponent progressPie = new ProgressPieComponent(); + progressPie.setDiameter(30); + progressPie.setFill(RED_ALPHA); + progressPie.setBorderColor(Color.RED); + progressPie.setPosition(position); + + final Duration duration = Duration.between(timer, Instant.now()); + progressPie.setProgress(1 - (duration.compareTo(MAX_TIME) < 0 + ? (double) duration.toMillis() / MAX_TIME.toMillis() + : 1)); + + progressPie.render(graphics); + if (1 - duration.compareTo(MAX_TIME) < 0) + { + plugin.getVetions().remove(actor); + } + } + } + }); + + return null; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..9df9a4fa57 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019, Frosty Fridge + * 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.vetion; + +import com.google.inject.Provides; +import lombok.Getter; +import net.runelite.api.*; +import net.runelite.api.events.AnimationChanged; +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.ui.overlay.OverlayManager; + +import javax.inject.Inject; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; + +@PluginDescriptor( + name = "!Vetion", + description = "Tracks Vet'ion's special attacks", + tags = {"bosses", "combat", "pve", "overlay"} +) +public class VetionPlugin extends Plugin { + + @Inject + private Client client; + + @Inject + private VetionConfig config; + + @Inject + private OverlayManager overlayManager; + + @Inject + private VetionOverlay overlay; + + @Getter + private Map vetions; + + @Provides + VetionConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(VetionConfig.class); + } + + @Override + protected void startUp() + { + vetions = new HashMap<>(); + overlayManager.add(overlay); + } + + @Override + protected void shutDown() + { + overlayManager.remove(overlay); + vetions = null; + } + + + @Subscribe + public void onAnimationChanged(AnimationChanged event) + { + if (config.eartquakeTimerActive() && event.getActor().getAnimation() == AnimationID.VETION_EARTHQUAKE) + { + Actor vet = event.getActor(); + vetions.remove(vet, Instant.now()); + vetions.put(vet, Instant.now()); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/TileHighlight.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/TileHighlight.java new file mode 100644 index 0000000000..c6e5623450 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/TileHighlight.java @@ -0,0 +1,8 @@ +package net.runelite.client.plugins.vorkath; + +public enum TileHighlight +{ + None, + Single, + All +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java new file mode 100644 index 0000000000..927b9b1997 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java @@ -0,0 +1,51 @@ +package net.runelite.client.plugins.vorkath; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +import java.awt.*; + +@ConfigGroup("vorkath") +public interface VorkathConfig extends Config { + @ConfigItem( + position = 0, + keyName = "Vorkathenable", + name = "Enable Vorkath Helper", + description = "Configures whether or not to enable Vorkath Helper." + ) + default boolean EnableVorkath() { return true; } + + @ConfigItem( + position = 1, + keyName = "countercolor", + name = "Indicator color", + description = "Configures color of text displaying Vorkath hits left to special attack." + ) + default Color CounterColor() { return Color.YELLOW; } + + @ConfigItem( + position = 2, + keyName = "countersize", + name = "Bold indicator", + description = "Configures if text indicator is bold or not." + ) + default boolean BoldText() { return true; } + + @ConfigItem( + position = 3, + keyName = "enumConfig", + name = "Fireball Tile Highlight", + description = "Select how to apply tile highlighting for Vorkath's fireball attack" + ) + default TileHighlight TileHighlight() { return TileHighlight.All; } + + @ConfigItem( + position = 4, + keyName = "overlayindicators", + name = "Overlay Indicators", + description = "Configures if an overlay box displaying vorkath information should be displayed." + ) + default boolean VorkathBox() { return false; } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathIndicatorOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathIndicatorOverlay.java new file mode 100644 index 0000000000..77403dab97 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathIndicatorOverlay.java @@ -0,0 +1,53 @@ +package net.runelite.client.plugins.vorkath; + +import java.awt.*; +import javax.inject.Inject; + +import net.runelite.api.*; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.overlay.*; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +public class VorkathIndicatorOverlay extends Overlay { + private final VorkathConfig config; + private final VorkathPlugin plugin; + private final PanelComponent panelComponent = new PanelComponent(); + + + @Inject + private Client client; + + @Inject + private VorkathIndicatorOverlay(VorkathConfig config, VorkathPlugin plugin) { + this.config = config; + this.plugin = plugin; + setPosition(OverlayPosition.BOTTOM_RIGHT); + setPriority(OverlayPriority.MED); + panelComponent.setPreferredSize(new Dimension(150, 0)); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (!config.EnableVorkath()) { + return null; + } + + NPC Vorkath = plugin.Vorkath; + if (Vorkath != null) { + if (config.VorkathBox()) { + panelComponent.getChildren().clear(); + if (plugin.venomticks != 0) { + if (plugin.venomticks + 5 <= plugin.ticks) { + panelComponent.getChildren().add(LineComponent.builder().left("Quickfire Barrage:").right(Integer.toString(30 - (plugin.ticks - plugin.venomticks))).rightColor(Color.ORANGE).build()); + } + } + panelComponent.getChildren().add(LineComponent.builder().left("Special Attack:").right(Integer.toString(7 - plugin.hits)).rightColor(config.CounterColor()).build()); + return panelComponent.render(graphics); + } + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java new file mode 100644 index 0000000000..0773141574 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java @@ -0,0 +1,84 @@ +package net.runelite.client.plugins.vorkath; + +import java.awt.*; +import javax.inject.Inject; + +import net.runelite.api.*; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.overlay.*; +import net.runelite.client.ui.overlay.components.PanelComponent; + +public class VorkathOverlay extends Overlay { + private final VorkathConfig config; + private final VorkathPlugin plugin; + private final PanelComponent panelComponent = new PanelComponent(); + + + @Inject + private Client client; + + @Inject + private VorkathOverlay(VorkathConfig config, VorkathPlugin plugin) { + this.config = config; + this.plugin = plugin; + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.MED); + panelComponent.setPreferredSize(new Dimension(150, 0)); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (!config.EnableVorkath()) { + return null; + } + Actor local = client.getLocalPlayer(); + + WorldArea area = local.getWorldArea(); + if (area == null) + { + return null; + } + + NPC Vorkath = plugin.Vorkath; + if (Vorkath != null) { + if (plugin.fireball != null) { + if (config.TileHighlight() == TileHighlight.Single) { + final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.fireball); + if (poly != null) { + OverlayUtil.renderPolygon(graphics, poly, Color.RED); + } + } else if (config.TileHighlight() == TileHighlight.All) { + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + if (dx == 0 && dy == 0) { + continue; + } + LocalPoint lp = new LocalPoint(plugin.fireball.getX() + dx * Perspective.LOCAL_TILE_SIZE + dx * Perspective.LOCAL_TILE_SIZE * (area.getWidth() - 1) / 2, plugin.fireball.getY() + dy * Perspective.LOCAL_TILE_SIZE + dy * Perspective.LOCAL_TILE_SIZE * (area.getHeight() - 1) / 2); + Polygon polyadj = Perspective.getCanvasTilePoly(client, lp); + if (polyadj != null) { + OverlayUtil.renderPolygon(graphics, polyadj, Color.ORANGE); + } + } + } + } + } + + if (config.BoldText()) { + graphics.setFont(FontManager.getRunescapeBoldFont()); + } + + if (plugin.venomticks != 0) { + if (plugin.venomticks + 5 <= plugin.ticks) { + OverlayUtil.renderTextLocation(graphics, Vorkath.getCanvasTextLocation(graphics, Integer.toString(30 - (plugin.ticks - plugin.venomticks)), Vorkath.getLogicalHeight() + 150), Integer.toString(30 - (plugin.ticks - plugin.venomticks)), Color.ORANGE); + } + } + + OverlayUtil.renderTextLocation(graphics, Vorkath.getCanvasTextLocation(graphics, Integer.toString(7 - plugin.hits), Vorkath.getLogicalHeight() + 40), Integer.toString(7 - plugin.hits), config.CounterColor()); + graphics.setFont(FontManager.getRunescapeFont()); + } + return null; + } +} 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 new file mode 100644 index 0000000000..1ba5e4b0e7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java @@ -0,0 +1,157 @@ +package net.runelite.client.plugins.vorkath; + +import net.runelite.api.events.*; +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import javax.inject.Inject; +import net.runelite.api.*; +import net.runelite.api.coords.LocalPoint; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import org.apache.commons.lang3.ArrayUtils; + +@PluginDescriptor( + name = "!Vorkath", + description = "Vorkath Helper", + tags = {"Vorkath", "Helper"} +) +public class VorkathPlugin extends Plugin +{ + @Inject + private OverlayManager overlayManager; + + @Inject + private VorkathConfig config; + + @Inject + private VorkathOverlay VorkathOverlay; + + @Inject + private VorkathIndicatorOverlay VorkathIndicatorOverlay; + + @Inject + private Client client; + + @Inject + private SpriteManager spriteManager; + + @Provides + VorkathConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(VorkathConfig.class); + } + + NPC Vorkath; + int hits; + int ticks; + Boolean ice = false; + LocalPoint fireball; + int fireballticks = 0; + int lastattack; + int venomticks; + + int[] VorkathIDs = {393, 395, 1470, 1471, 1477, 1479}; + + @Override + protected void startUp() throws Exception { + overlayManager.add(VorkathOverlay); + overlayManager.add(VorkathIndicatorOverlay); + } + + @Override + protected void shutDown() throws Exception { + overlayManager.remove(VorkathOverlay); + overlayManager.remove(VorkathIndicatorOverlay); + Vorkath = null; + hits = 0; + fireball = null; + fireballticks = 0; + ice = false; + lastattack = 0; + } + + @Subscribe + public void onGameTick(GameTick event) { + if (!config.EnableVorkath()) { + return; + } + ticks++; + if (ticks - fireballticks > 5) { + fireballticks = 0; + fireball = null; + } + + if (venomticks + 30 <= ticks) { + venomticks = 0; + } + + boolean foundVorkath = false; + for (NPC monster : client.getNpcs()) + { + if (monster == null || monster.getName() == null || monster.getCombatLevel() == 0) + { + continue; + } + if (monster.getName().equalsIgnoreCase("Vorkath")) { + foundVorkath = true; + Vorkath = monster; + break; + } + } + if (!foundVorkath) { + Vorkath = null; + hits = 0; + fireball = null; + fireballticks = 0; + ice = false; + lastattack = 0; + } + } + + @Subscribe + public void onProjectileMoved(ProjectileMoved event) { + if (Vorkath != null) { + Projectile ball = event.getProjectile(); + if (ArrayUtils.contains(VorkathIDs, ball.getId())) { + if (ticks - lastattack > 4) { + if (ball.getId() == 395) { + ice = true; + } + hits++; + lastattack = ticks; + if (hits == 7) { + hits = 0; + } + } + } + } + } + + @Subscribe + public void onAnimationChanged(AnimationChanged event) { + Actor vorki = event.getActor(); + Actor local = client.getLocalPlayer(); + if (vorki instanceof NPC) { + if (vorki.equals(Vorkath)) { + if (vorki.getAnimation() != -1 && vorki.getAnimation() != 7948 && vorki.getAnimation() != 7952) { + if (ice) { + ice = false; + } else { + hits++; + if (hits == 7) { + venomticks = ticks; + hits = 0; + } + if (vorki.getAnimation() == 7960) { + fireball = local.getLocalLocation(); + fireballticks = ticks; + } + } + } + + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java new file mode 100644 index 0000000000..69668fcbd6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsOverlay.java @@ -0,0 +1,38 @@ + +package net.runelite.client.plugins.wildernesslocations; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.client.plugins.wildernesslocations.WildernessLocationsPlugin; +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.components.TextComponent; + +public class WildernessLocationsOverlay +extends Overlay { + private final WildernessLocationsPlugin plugin; + private TextComponent textComponent; + + @Inject + public WildernessLocationsOverlay(Client client, WildernessLocationsPlugin plugin) { + this.plugin = plugin; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPriority(OverlayPriority.HIGH); + setPosition(OverlayPosition.BOTTOM_RIGHT); + textComponent = new TextComponent(); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (plugin.isRenderLocation()) { + textComponent.setText(plugin.getLocationString()); + return textComponent.render(graphics); + } + return null; + } +} + 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 new file mode 100644 index 0000000000..0020f384f4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java @@ -0,0 +1,127 @@ + +package net.runelite.client.plugins.wildernesslocations; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Consumer; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Player; +import net.runelite.api.Varbits; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.GameTick; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.wildernesslocations.WildernessLocationsOverlay; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayManager; +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"}) + +public class WildernessLocationsPlugin extends Plugin { + @Inject + private Client client; + @Inject + OverlayManager overlayManager; + @Inject + private WildernessLocationsOverlay overlay; + private final HashMap wildLocs; + private boolean renderLocation; + private String locationString; + private WorldPoint worldPoint; + private static int UPDATE_INTERVAL = 3; + + public WildernessLocationsPlugin() { + overlay = new WildernessLocationsOverlay(client, this); + wildLocs = WildernessLocationsPlugin.getLocationMap(); + locationString = ""; + worldPoint = null; + } + + @Override + protected void startUp() throws Exception { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception { + overlayManager.add(overlay); + } + + @Subscribe + public void onGameTick(GameTick event) { + if (UPDATE_INTERVAL > 0) { + --UPDATE_INTERVAL; + return; + } + boolean bl = renderLocation = client.getVar(Varbits.IN_WILDERNESS) == 1; + if (renderLocation) { + if (client.getLocalPlayer().getWorldLocation() != worldPoint) { + locationString = location(); + worldPoint = client.getLocalPlayer().getWorldLocation(); + } + } else { + worldPoint = null; + locationString = ""; + } + UPDATE_INTERVAL = 3; + } + + private String location() { + int dist = 10000; + String s = ""; + WorldArea closestArea = null; + for (Map.Entry entry : wildLocs.entrySet()) { + WorldArea worldArea = entry.getKey(); + if (worldArea.toWorldPointList().contains(client.getLocalPlayer().getWorldLocation())) { + s = entry.getValue(); + return s; + } + int distTo = worldArea.distanceTo(client.getLocalPlayer().getWorldLocation()); + if (distTo >= dist) continue; + dist = distTo; + closestArea = worldArea; + } + if (client.getLocalPlayer().getWorldLocation().getY() > ((WorldArea)Objects.requireNonNull(closestArea)).toWorldPoint().getY() + closestArea.getHeight()) { + s = s + "N"; + } + if (client.getLocalPlayer().getWorldLocation().getY() < closestArea.toWorldPoint().getY()) { + s = s + "S"; + } + if (client.getLocalPlayer().getWorldLocation().getX() < closestArea.toWorldPoint().getX()) { + s = s + "W"; + } + if (client.getLocalPlayer().getWorldLocation().getX() > closestArea.toWorldPoint().getX() + closestArea.getWidth()) { + s = s + "E"; + } + s = s + " of "; + if ((s = s + wildLocs.get(closestArea)).startsWith(" of ")) { + s = s.substring(3); + } + return s; + } + + private static HashMap getLocationMap() { + HashMap hashMap = new HashMap(); + Arrays.stream(WildernessLocation.values()).forEach(wildernessLocation -> hashMap.put(wildernessLocation.getWorldArea(), wildernessLocation.getName())); + return hashMap; + } + + public boolean isRenderLocation() { + return renderLocation; + } + + public String getLocationString() { + return locationString; + } +} + 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/zoneIndicators/MapLocations.java new file mode 100644 index 0000000000..81e8e0f527 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java @@ -0,0 +1,3479 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.Area; +import java.util.ArrayList; +import java.util.List; +import net.runelite.api.Constants; + +public class MapLocations +{ + private static final List[] MULTICOMBAT = new List[Constants.MAX_Z]; + private static final List[] NOT_MULTICOMBAT = new List[Constants.MAX_Z]; + private static final List[] ROUGH_WILDERNESS = new List[Constants.MAX_Z]; + private static final List[] DEADMAN_SAFE_ZONES = new List[Constants.MAX_Z]; + private static final List[] PVP_WORLD_SAFE_ZONES = new List[Constants.MAX_Z]; + + private static Area getArea(List shapes) + { + Area area = new Area(); + for (Shape shape : shapes) + { + area.add(new Area(shape)); + } + return area; + } + + private static Area getArea(List shapes, Rectangle view) + { + Area area = new Area(); + for (Shape shape : shapes) + { + if (shape.intersects(view)) + { + area.add(new Area(shape)); + } + } + return area; + } + + public static Area getMulticombat(int plane) + { + Area area = getArea(MULTICOMBAT[plane]); + area.subtract(getArea(NOT_MULTICOMBAT[plane])); + return area; + } + + public static Area getMulticombat(Rectangle view, int plane) + { + Area area = getArea(MULTICOMBAT[plane], view); + area.subtract(getArea(NOT_MULTICOMBAT[plane], view)); + return area; + } + + public static Area getRoughWilderness(int plane) + { + return getArea(ROUGH_WILDERNESS[plane]); + } + + public static Area getRoughWilderness(Rectangle view, int plane) + { + return getArea(ROUGH_WILDERNESS[plane], view); + } + + public static Area getDeadmanSafeZones(int plane) + { + return getArea(DEADMAN_SAFE_ZONES[plane]); + } + + public static Area getDeadmanSafeZones(Rectangle view, int plane) + { + return getArea(DEADMAN_SAFE_ZONES[plane], view); + } + + public static Area getPvpSafeZones(int plane) + { + return getArea(PVP_WORLD_SAFE_ZONES[plane]); + } + + public static Area getPvpSafeZones(Rectangle view, int plane) + { + return getArea(PVP_WORLD_SAFE_ZONES[plane], view); + } + + static + { + for (int i = 0; i < MULTICOMBAT.length; i++) + { + MULTICOMBAT[i] = new ArrayList<>(); + } + for (int i = 0; i < NOT_MULTICOMBAT.length; i++) + { + NOT_MULTICOMBAT[i] = new ArrayList<>(); + } + for (int i = 0; i < ROUGH_WILDERNESS.length; i++) + { + ROUGH_WILDERNESS[i] = new ArrayList<>(); + } + for (int i = 0; i < DEADMAN_SAFE_ZONES.length; i++) + { + DEADMAN_SAFE_ZONES[i] = new ArrayList<>(); + } + for (int i = 0; i < PVP_WORLD_SAFE_ZONES.length; i++) + { + PVP_WORLD_SAFE_ZONES[i] = new ArrayList<>(); + } + + defineMulticombatAreas(); + defineDeadmanSafeZones(); + definePvpSafeZones(); + defineWilderness(); + } + + private static void defineMulticombatAreas() + { + // Main Wilderness + addPolygonOnPlane(MULTICOMBAT, 0, + 3200, 3968, + 3392, 3968, + 3392, 3840, + 3328, 3840, + 3328, 3520, + 3136, 3520, + 3136, 3648, + 3192, 3648, + 3192, 3752, + 3152, 3752, + 3152, 3840, + 3136, 3840, + 3136, 3872, + 3112, 3872, + 3112, 3880, + 3072, 3880, + 3072, 3896, + 3048, 3896, + 3048, 3872, + 3056, 3872, + 3056, 3864, + 3048, 3864, + 3048, 3856, + 3008, 3856, + 3008, 3904, + 3200, 3904); + + // South of wildy agility training arena + addPolygonOnPlane(MULTICOMBAT, 0, + 2984, 3928, + 3008, 3928, + 3008, 3912, + 2984, 3912); + + // Wildy zamorak temple + addPolygonOnPlane(MULTICOMBAT, 0, + 2944, 3832, + 2960, 3832, + 2960, 3816, + 2944, 3816); + + // Wildy bandit camp + addPolygonOnPlane(MULTICOMBAT, 0, + 3008, 3712, + 3072, 3712, + 3072, 3600, + 3008, 3600); + + // Chaos temple north of Falador + addPolygonOnPlane(MULTICOMBAT, 0, + 2928, 3520, + 2944, 3520, + 2944, 3512, + 2928, 3512); + + // Burthorpe + addPolygonOnPlane(MULTICOMBAT, 0, + 2880, 3544, + 2904, 3544, + 2904, 3520, + 2880, 3520); + + // White Wolf Mountain + addPolygonOnPlane(MULTICOMBAT, 0, + 2880, 3520, + 2816, 3520, + 2816, 3456, + 2880, 3456); + + // Death Plateu + addPolygonOnPlane(MULTICOMBAT, 0, + 2848, 3608, + 2880, 3608, + 2880, 3600, + 2848, 3600); + + // Trollheim/Godwars + addPolygonOnPlane(MULTICOMBAT, 0, + 2880, 3776, + 2912, 3776, + 2912, 3696, + 2920, 3696, + 2920, 3688, + 2896, 3688, + 2896, 3696, + 2880, 3696, + 2880, 3728, + 2888, 3728, + 2888, 3744, + 2880, 3744); + + // Northen Rellekka + addPolygonOnPlane(MULTICOMBAT, 0, + 2656, 3736, + 2704, 3736, + 2704, 3728, + 2712, 3728, + 2712, 3736, + 2736, 3736, + 2736, 3712, + 2656, 3712); + + // Northen Fremennik Isles + addPolygonOnPlane(MULTICOMBAT, 0, + 2304, 3904, + 2432, 3904, + 2432, 3840, + 2368, 3840, + 2368, 3816, + 2352, 3816, + 2352, 3824, + 2304, 3824); + + // Pirates Cove + addPolygonOnPlane(MULTICOMBAT, 0, + 2176, 3840, + 2240, 3840, + 2240, 3776, + 2176, 3776); + + // Lunar Isle + addPolygonOnPlane(MULTICOMBAT, 0, + 2048, 3968, + 2176, 3968, + 2176, 3840, + 2048, 3840); + + // Piscatoris Fishing Colony + addPolygonOnPlane(MULTICOMBAT, 0, + 2304, 3712, + 2368, 3712, + 2368, 3648, + 2304, 3648); + + // Ranging Guild + addPolygonOnPlane(MULTICOMBAT, 0, + 2656, 3448, + 2680, 3448, + 2680, 3440, + 2688, 3440, + 2688, 3416, + 2680, 3416, + 2680, 3408, + 2656, 3408, + 2656, 3416, + 2648, 3416, + 2648, 3440, + 2656, 3440); + + // Necromancer house, southeast of Ardy + addPolygonOnPlane(MULTICOMBAT, 0, + 2656, 3256, + 2680, 3256, + 2680, 3216, + 2664, 3216, + 2664, 3232, + 2656, 3232); + + // Battlefield noth of Tree Gnome Village + addPolygonOnPlane(MULTICOMBAT, 0, + 2504, 3248, + 2544, 3248, + 2544, 3232, + 2552, 3232, + 2552, 3208, + 2504, 3208); + + // Castle Wars + addPolygonOnPlane(MULTICOMBAT, 0, + 2368, 3136, + 2432, 3136, + 2432, 3072, + 2368, 3072); + + // Jiggig + addPolygonOnPlane(MULTICOMBAT, 0, + 2456, 3056, + 2496, 3056, + 2496, 3032, + 2456, 3032); + + // East feldip hills, near rantz + addPolygonOnPlane(MULTICOMBAT, 0, + 2648, 2976, + 2656, 2976, + 2656, 2952, + 2648, 2952); + + // Ape Atoll + addPolygonOnPlane(MULTICOMBAT, 0, + 2688, 2816, + 2816, 2816, + 2816, 2688, + 2688, 2688); + + // Pest Control + addPolygonOnPlane(MULTICOMBAT, 0, + 2624, 2624, + 2688, 2624, + 2688, 2560, + 2624, 2560); + + // Desert Bandit Camp + addPolygonOnPlane(MULTICOMBAT, 0, + 3152, 3000, + 3192, 3000, + 3192, 2960, + 3152, 2960); + + // Al Kharid + addPolygonOnPlane(MULTICOMBAT, 0, + 3264, 3200, + 3328, 3200, + 3328, 3136, + 3264, 3136); + + // Wizards Tower + addPolygonOnPlane(MULTICOMBAT, 0, + 3094, 3176, + 3126, 3176, + 3126, 3144, + 3094, 3144); + + // Draynor Village + addPolygonOnPlane(MULTICOMBAT, 0, + 3112, 3264, + 3136, 3264, + 3136, 3232, + 3104, 3232, + 3104, 3256, + 3112, 3256); + + // Falador + addPolygonOnPlane(MULTICOMBAT, 0, + 2944, 3456, + 3008, 3456, + 3008, 3328, + 3016, 3328, + 3016, 3304, + 2944, 3304); + + // Southwest fally castle isn't multicombat downstairs + addPolygonOnPlane(NOT_MULTICOMBAT, 0, + 2968, 3336, + 2968, 3328, + 2960, 3328, + 2960, 3336); + + // Barbarian Village + addPolygonOnPlane(MULTICOMBAT, 0, + 3072, 3456, + 3136, 3456, + 3136, 3392, + 3048, 3392, + 3048, 3408, + 3056, 3408, + 3056, 3440, + 3064, 3440, + 3064, 3448, + 3072, 3448); + + // Ammoniate crabs at northwest fossil island + addPolygonOnPlane(MULTICOMBAT, 0, + 3648, 3885, + 3663, 3885, + 3663, 3882, + 3664, 3882, + 3664, 3872, + 3663, 3872, + 3663, 3868, + 3648, 3868); + + // Ammoniate crabs at north fossil island + addPolygonOnPlane(MULTICOMBAT, 0, + 3680, 3904, + 3744, 3904, + 3744, 3856, + 3756, 3856, + 3756, 3852, + 3755, 3852, + 3755, 3851, + 3754, 3851, + 3754, 3850, + 3751, 3850, + 3751, 3849, + 3750, 3849, + 3750, 3848, + 3749, 3848, + 3749, 3847, + 3748, 3847, + 3748, 3846, + 3747, 3846, + 3747, 3845, + 3746, 3845, + 3746, 3844, + 3742, 3844, + 3742, 3845, + 3740, 3845, + 3740, 3844, + 3732, 3844, + 3732, 3843, + 3730, 3843, + 3730, 3842, + 3724, 3842, + 3724, 3843, + 3717, 3843, + 3717, 3842, + 3712, 3842, + 3712, 3846, + 3710, 3846, + 3710, 3847, + 3709, 3847, + 3709, 3848, + 3708, 3848, + 3708, 3859, + 3709, 3859, + 3709, 3860, + 3710, 3860, + 3710, 3861, + 3712, 3861, + 3712, 3866, + 3713, 3866, + 3713, 3870, + 3714, 3870, + 3714, 3873, + 3713, 3873, + 3713, 3876, + 3712, 3876, + 3712, 3881, + 3710, 3881, + 3710, 3888, + 3712, 3888, + 3712, 3890, + 3714, 3890, + 3714, 3891, + 3716, 3891, + 3716, 3892, + 3717, 3892, + 3717, 3893, + 3716, 3893, + 3716, 3894, + 3714, 3894, + 3714, 3895, + 3713, 3895, + 3713, 3896, + 3712, 3896, + 3712, 3897, + 3705, 3897, + 3705, 3898, + 3704, 3898, + 3704, 3899, + 3692, 3899, + 3692, 3898, + 3688, 3898, + 3688, 3897, + 3686, 3897, + 3686, 3896, + 3680, 3896); + + // Zeah, southwest of Wintertodt, snowy area with ice giants and wolves + addPolygonOnPlane(MULTICOMBAT, 0, + 1540, 3898, + 1543, 3898, + 1543, 3901, + 1546, 3901, + 1546, 3903, + 1547, 3903, + 1547, 3904, + 1550, 3904, + 1550, 3903, + 1553, 3903, + 1553, 3904, + 1559, 3904, + 1559, 3902, + 1564, 3902, + 1564, 3903, + 1565, 3903, + 1565, 3904, + 1568, 3904, + 1568, 3903, + 1569, 3903, + 1569, 3902, + 1570, 3902, + 1570, 3901, + 1573, 3901, + 1573, 3898, + 1577, 3898, + 1577, 3899, + 1578, 3899, + 1578, 3902, + 1579, 3902, + 1579, 3903, + 1584, 3903, + 1584, 3902, + 1586, 3902, + 1586, 3901, + 1590, 3901, + 1590, 3891, + 1588, 3891, + 1588, 3887, + 1572, 3887, + 1572, 3872, + 1567, 3872, + 1567, 3868, + 1563, 3868, + 1563, 3867, + 1558, 3867, + 1558, 3868, + 1557, 3868, + 1557, 3870, + 1549, 3870, + 1549, 3874, + 1545, 3874, + 1545, 3876, + 1543, 3876, + 1543, 3877, + 1542, 3877, + 1542, 3879, + 1541, 3879, + 1541, 3882, + 1539, 3882, + 1539, 3887, + 1540, 3887, + 1540, 3888, + 1539, 3888, + 1539, 3894, + 1540, 3894); + + // Zeah arceuus area + addPolygonOnPlane(MULTICOMBAT, 0, + 1664, 3776, + 1664, 3785, + 1667, 3785, + 1667, 3805, + 1671, 3805, + 1671, 3811, + 1675, 3811, + 1675, 3819, + 1690, 3819, + 1690, 3814, + 1695, 3814, + 1695, 3806, + 1719, 3806, + 1719, 3787, + 1725, 3787, + 1725, 3778, + 1711, 3778, + 1711, 3776); + + // Arceuus teletab-making house + addPolygonOnPlane(MULTICOMBAT, 0, + 1667, 3772, + 1679, 3772, + 1679, 3775, + 1691, 3775, + 1691, 3761, + 1679, 3761, + 1679, 3764, + 1667, 3764); + // Next house east + addPolygonOnPlane(MULTICOMBAT, 0, + 1696, 3775, + 1708, 3775, + 1708, 3763, + 1696, 3763); + // Next house east + addPolygonOnPlane(MULTICOMBAT, 0, + 1713, 3775, + 1727, 3775, + 1727, 3763, + 1724, 3763, + 1724, 3752, + 1716, 3752, + 1716, 3763, + 1713, 3763); + // Arceuus rune shop house + addPolygonOnPlane(MULTICOMBAT, 0, + 1716, 3750, + 1728, 3750, + 1728, 3736, + 1716, 3736); + // Arceuus general store house + addPolygonOnPlane(MULTICOMBAT, 0, + 1717, 3732, + 1725, 3732, + 1725, 3715, + 1715, 3715, + 1715, 3725, + 1717, 3725); + // Arceuus pub + addPolygonOnPlane(MULTICOMBAT, 0, + 1683, 3732, + 1691, 3732, + 1691, 3725, + 1697, 3725, + 1697, 3730, + 1703, 3730, + 1703, 3712, + 1683, 3712); + // Arceuus staff store + addPolygonOnPlane(MULTICOMBAT, 0, + 1664, 3732, + 1676, 3732, + 1676, 3720, + 1664, 3720); + // Next house to the west + addPolygonOnPlane(MULTICOMBAT, 0, + 1647, 3738, + 1655, 3738, + 1655, 3726, + 1658, 3726, + 1658, 3714, + 1644, 3714, + 1644, 3726, + 1647, 3726); + // Next house to the north + addPolygonOnPlane(MULTICOMBAT, 0, + 1647, 3762, + 1657, 3762, + 1657, 3752, + 1655, 3752, + 1655, 3745, + 1647, 3745); + + // Arceuus house magic trees + addPolygonOnPlane(MULTICOMBAT, 0, + 1682, 3755, + 1692, 3755, + 1692, 3745, + 1690, 3745, + 1690, 3738, + 1682, 3738); + // West of that ^ + addPolygonOnPlane(MULTICOMBAT, 0, + 1667, 3756, + 1675, 3756, + 1675, 3740, + 1665, 3740, + 1665, 3746, + 1667, 3746); + + // This one goes through western piscarilius, northen hosidius + // and southwestern arceuus + addPolygonOnPlane(MULTICOMBAT, 0, + 1728, 3808, + 1792, 3808, + 1792, 3764, + 1856, 3764, + 1856, 3712, + 1792, 3712, + 1792, 3648, + 1664, 3648, + 1664, 3706, + 1665, 3706, + 1665, 3705, + 1668, 3705, + 1668, 3706, + 1671, 3706, + 1671, 3705, + 1675, 3705, + 1675, 3704, + 1683, 3704, + 1683, 3701, + 1684, 3701, + 1684, 3700, + 1686, 3700, + 1686, 3702, + 1687, 3702, + 1687, 3700, + 1688, 3700, + 1688, 3701, + 1690, 3701, + 1690, 3703, + 1689, 3703, + 1689, 3704, + 1690, 3704, + 1690, 3705, + 1704, 3705, + 1704, 3707, + 1706, 3707, + 1706, 3712, + 1711, 3712, + 1711, 3711, + 1710, 3711, + 1710, 3710, + 1712, 3710, + 1712, 3707, + 1728, 3707); + + // Kourend castle + addPolygonOnPlane(MULTICOMBAT, 0, + 1614, 3691, + 1619, 3691, + 1619, 3690, + 1620, 3690, + 1620, 3689, + 1653, 3689, + 1653, 3690, + 1654, 3690, + 1654, 3691, + 1657, 3691, + 1657, 3690, + 1658, 3690, + 1658, 3689, + 1659, 3689, + 1659, 3686, + 1658, 3686, + 1658, 3685, + 1657, 3685, + 1657, 3662, + 1658, 3662, + 1658, 3661, + 1659, 3661, + 1659, 3658, + 1658, 3658, + 1658, 3657, + 1657, 3657, + 1657, 3656, + 1654, 3656, + 1654, 3657, + 1653, 3657, + 1653, 3658, + 1620, 3658, + 1620, 3657, + 1619, 3657, + 1619, 3656, + 1614, 3656, + 1614, 3657, + 1613, 3657, + 1613, 3661, + 1612, 3661, + 1612, 3662, + 1611, 3662, + 1611, 3663, + 1600, 3663, + 1600, 3662, + 1599, 3662, + 1599, 3661, + 1594, 3661, + 1594, 3662, + 1593, 3662, + 1593, 3685, + 1594, 3685, + 1594, 3686, + 1599, 3686, + 1599, 3685, + 1600, 3685, + 1600, 3684, + 1611, 3684, + 1611, 3685, + 1612, 3685, + 1612, 3686, + 1613, 3686, + 1613, 3690, + 1614, 3690); + + // Western hosidius area, including woodcutting guild and western sand crabs + addPolygonOnPlane(MULTICOMBAT, 0, + 1650, 3648, + 1664, 3648, + 1664, 3520, + 1689, 3520, + 1689, 3496, + 1707, 3496, + 1707, 3485, + 1708, 3485, + 1708, 3484, + 1710, 3484, + 1710, 3483, + 1713, 3483, + 1713, 3482, + 1720, 3482, + 1720, 3481, + 1721, 3481, + 1721, 3480, + 1722, 3480, + 1722, 3479, + 1723, 3479, + 1723, 3478, + 1724, 3478, + 1724, 3477, + 1726, 3477, + 1726, 3476, + 1728, 3476, + 1728, 3472, + 1708, 3472, + 1708, 3456, + 1600, 3456, + 1600, 3584, + 1608, 3584, + 1608, 3616, + 1650, 3616); + + // Hosidius sand crabs + addPolygonOnPlane(MULTICOMBAT, 0, + 1740, 3478, + 1741, 3478, + 1741, 3479, + 1745, 3479, + 1745, 3480, + 1751, 3480, + 1751, 3479, + 1752, 3479, + 1752, 3478, + 1753, 3478, + 1753, 3477, + 1755, 3477, + 1755, 3476, + 1757, 3476, + 1757, 3475, + 1758, 3475, + 1758, 3474, + 1759, 3474, + 1759, 3473, + 1779, 3473, + 1779, 3474, + 1781, 3474, + 1781, 3475, + 1786, 3475, + 1786, 3476, + 1800, 3476, + 1800, 3475, + 1805, 3475, + 1805, 3474, + 1807, 3474, + 1807, 3473, + 1808, 3473, + 1808, 3472, + 1810, 3472, + 1810, 3471, + 1833, 3471, + 1833, 3470, + 1834, 3470, + 1834, 3469, + 1852, 3469, + 1852, 3449, + 1792, 3449, + 1792, 3424, + 1800, 3424, + 1800, 3449, + 1800, 3400, + 1728, 3400, + 1728, 3462, + 1729, 3462, + 1729, 3466, + 1730, 3466, + 1730, 3469, + 1731, 3469, + 1731, 3470, + 1732, 3470, + 1732, 3471, + 1733, 3471, + 1733, 3473, + 1734, 3473, + 1734, 3474, + 1736, 3474, + 1736, 3475, + 1737, 3475, + 1737, 3476, + 1738, 3476, + 1738, 3477, + 1740, 3477); + + // Apparently there is a 1x1 single zone on the sand crab island + addPolygonOnPlane(NOT_MULTICOMBAT, 0, + 1777, 3416, + 1777, 3417, + 1778, 3417, + 1778, 3416); + + // Eastern hosidius area + addPolygonOnPlane(MULTICOMBAT, 0, + 1834, 3584, + 1888, 3584, + 1888, 3528, + 1856, 3528, + 1856, 3520, + 1834, 3520, + 1834, 3522, + 1833, 3522, + 1833, 3535, + 1834, 3535, + 1834, 3538, + 1835, 3538, + 1835, 3539, + 1836, 3539, + 1836, 3540, + 1837, 3540, + 1837, 3541, + 1838, 3541, + 1838, 3542, + 1840, 3542, + 1840, 3543, + 1841, 3543, + 1841, 3545, + 1842, 3545, + 1842, 3546, + 1844, 3546, + 1844, 3547, + 1845, 3547, + 1845, 3548, + 1851, 3548, + 1851, 3551, + 1853, 3551, + 1853, 3563, + 1851, 3563, + 1851, 3566, + 1847, 3566, + 1847, 3567, + 1845, 3567, + 1845, 3568, + 1844, 3568, + 1844, 3569, + 1843, 3569, + 1843, 3571, + 1842, 3571, + 1842, 3573, + 1841, 3573, + 1841, 3574, + 1840, 3574, + 1840, 3575, + 1839, 3575, + 1839, 3576, + 1838, 3576, + 1838, 3577, + 1837, 3577, + 1837, 3578, + 1836, 3578, + 1836, 3579, + 1835, 3579, + 1835, 3581, + 1834, 3581); + + // Eastern hosidius area also has a 1x1 multi area + addPolygonOnPlane(MULTICOMBAT, 0, + 1849, 3563, + 1849, 3564, + 1850, 3564, + 1850, 3563); + + // Hosidius cows/chickens/pigs + addPolygonOnPlane(MULTICOMBAT, 0, + 1792, 3513, + 1802, 3513, + 1802, 3520, + 1810, 3520, + 1810, 3513, + 1816, 3513, + 1816, 3512, + 1836, 3512, + 1836, 3494, + 1796, 3494, + 1796, 3495, + 1792, 3495); + + // Hosidius southeast of tithe farm + addPolygonOnPlane(MULTICOMBAT, 0, + 1777, 3597, + 1794, 3597, + 1794, 3561, + 1777, 3561, + 1777, 3591, + 1779, 3591, + 1779, 3592, + 1777, 3592); + + // West of shayzien house + addPolygonOnPlane(MULTICOMBAT, 0, + 1408, 3584, + 1408, 3582, + 1486, 3582, + 1486, 3568, + 1528, 3568, + 1528, 3520, + 1408, 3520, + 1408, 3464, + 1380, 3464, + 1380, 3486, + 1377, 3486, + 1377, 3488, + 1373, 3488, + 1373, 3492, + 1364, 3492, + 1364, 3512, + 1358, 3512, + 1358, 3520, + 1356, 3520, + 1356, 3532, + 1358, 3532, + 1358, 3540, + 1359, 3540, + 1359, 3542, + 1360, 3542, + 1360, 3557, + 1356, 3557, + 1356, 3560, + 1351, 3560, + 1351, 3570, + 1354, 3570, + 1354, 3581, + 1346, 3581, + 1346, 3584); + + // South of chambers of xeric + addPolygonOnPlane(MULTICOMBAT, 0, + 1261, 3489, + 1259, 3489, + 1259, 3488, + 1255, 3488, + 1255, 3487, + 1243, 3487, + 1243, 3490, + 1234, 3490, + 1234, 3480, + 1192, 3480, + 1192, 3568, + 1209, 3568, + 1209, 3548, + 1215, 3548, + 1215, 3544, + 1217, 3544, + 1217, 3536, + 1235, 3536, + 1235, 3532, + 1249, 3532, + 1249, 3525, + 1248, 3525, + 1248, 3517, + 1254, 3517, + 1254, 3513, + 1274, 3513, + 1274, 3510, + 1296, 3510, + 1296, 3511, + 1300, 3511, + 1300, 3501, + 1287, 3501, + 1287, 3490, + 1280, 3490, + 1280, 3489, + 1264, 3489, + 1264, 3490, + 1261, 3490); + + // Lizardman shamans + addPolygonOnPlane(MULTICOMBAT, 0, + 1416, 3728, + 1456, 3728, + 1456, 3688, + 1416, 3688); + + // Other lizardman area at shayzien (west side) + addPolygonOnPlane(MULTICOMBAT, 0, + 1472, 3712, + 1510, 3712, + 1510, 3702, + 1509, 3702, + 1509, 3701, + 1506, 3701, + 1506, 3696, + 1500, 3696, + 1500, 3680, + 1472, 3680); + + // Other lizardman area at shayzien (east side) + addPolygonOnPlane(MULTICOMBAT, 0, + 1538, 3704, + 1560, 3704, + 1560, 3672, + 1538, 3672); + + // Lovakengj house + addPolygonOnPlane(MULTICOMBAT, 0, + 1600, 3712, + 1472, 3712, + 1472, 3840, + 1547, 3840, + 1547, 3816, + 1556, 3816, + 1556, 3809, + 1562, 3809, + 1562, 3800, + 1568, 3800, + 1568, 3793, + 1571, 3793, + 1571, 3816, + 1571, 3776, + 1600, 3776); + + // Shayzien house + addPolygonOnPlane(MULTICOMBAT, 0, + 1475, 3587, + 1475, 3641, + 1534, 3641, + 1534, 3587); + + // Shayzien house bank is non-multi + addPolygonOnPlane(NOT_MULTICOMBAT, 0, + 1495, 3622, + 1515, 3622, + 1515, 3612, + 1495, 3612); + + // Shayzien house general store + addPolygonOnPlane(MULTICOMBAT, 0, + 1539, 3640, + 1551, 3640, + 1551, 3621, + 1539, 3621); + + // Kourend woodland barbarian area + addPolygonOnPlane(MULTICOMBAT, 0, + 1572, 3442, + 1591, 3442, + 1591, 3424, + 1572, 3424); + + // Catacombs + addPolygonTo(MULTICOMBAT, + 1600, 9984, + 1600, 10067, + 1628, 10067, + 1628, 10070, + 1639, 10070, + 1639, 10112, + 1730, 10112, + 1730, 9984); + + // Zeah dungeon with sand crabs + addPolygonTo(MULTICOMBAT, + 1632, 9792, + 1632, 9856, + 1728, 9856, + 1728, 9792); + + // Waterbirth island near the doors where people use rune throwing axes + addPolygonTo(MULTICOMBAT, + 2536, 10136, + 2536, 10152, + 2552, 10152, + 2552, 10136); + + // Waterbirth island dungeon, on the path to dks + addPolygonTo(MULTICOMBAT, + 1792, 4352, + 1792, 4416, + 1984, 4416, + 1984, 4352); + + // Dagannoths in lighthouse + addPolygonTo(MULTICOMBAT, + 2496, 10048, + 2560, 10048, + 2560, 9984, + 2496, 9984); + + // Dagannoth kings (DKs) including slayer only dks + addPolygonTo(MULTICOMBAT, + 2944, 4352, + 2944, 4480, + 2880, 4480, + 2880, 4352); + + // White wolf mountain dungeon at ice queen + addPolygonTo(MULTICOMBAT, + 2856, 9928, + 2856, 9968, + 2880, 9968, + 2880, 9928); + + // Kharazi jungle dungeon (in dragon slayer 2 quest) + addPolygonTo(MULTICOMBAT, + 2816, 9296, + 2880, 9296, + 2880, 9216, + 2816, 9216); + + // Tzhaar, fight pits and inferno area + addPolygonTo(MULTICOMBAT, + 2368, 5184, + 2560, 5184, + 2560, 5056, + 2368, 5056); + + // Smoke devils + addPolygonTo(MULTICOMBAT, + 2432, 9408, + 2344, 9408, + 2344, 9472, + 2432, 9472); + + // Kraken + addPolygonTo(MULTICOMBAT, + 2270, 10045, + 2291, 10045, + 2291, 10022, + 2270, 10022); + + // Giant mole + addPolygonTo(MULTICOMBAT, + 1728, 5240, + 1792, 5240, + 1792, 5120, + 1728, 5120); + + // Godwars dungeon + addPolygonTo(MULTICOMBAT, + 2816, 5376, + 2944, 5376, + 2944, 5248, + 2816, 5248); + + // Desert treasure shadow diamond area + addPolygonTo(MULTICOMBAT, + 2752, 5064, + 2728, 5064, + 2728, 5088, + 2720, 5088, + 2720, 5096, + 2712, 5096, + 2712, 5112, + 2736, 5112, + 2736, 5120, + 2752, 5120); + + // Kalphite slayer area + addPolygonTo(MULTICOMBAT, + 3264, 9544, + 3344, 9544, + 3344, 9472, + 3264, 9472); + + // Normal kalphite area including kalphite queen + addPolygonTo(MULTICOMBAT, + 3456, 9536, + 3520, 9536, + 3520, 9472, + 3456, 9472); + + // Tarns lair + addPolygonTo(MULTICOMBAT, + 3136, 4664, + 3200, 4664, + 3200, 4544, + 3136, 4544); + + // Haunted mine boss area + addPolygonTo(MULTICOMBAT, + 2752, 4416, + 2752, 4480, + 2816, 4480, + 2816, 4416); + + // Entrance to dorgesh kaan + addPolygonTo(MULTICOMBAT, + 3328, 9600, + 3312, 9600, + 3312, 9640, + 3304, 9640, + 3304, 9664, + 3328, 9664); + + // Hammerspikes hangout in dwarven mines + addPolygonTo(MULTICOMBAT, + 2960, 9824, + 2976, 9824, + 2976, 9800, + 2960, 9800); + + // Fremennik isles dungeon + addPolygonTo(MULTICOMBAT, + 2432, 10304, + 2432, 10240, + 2368, 10240, + 2368, 10304); + + // Varrock sewers + addPolygonTo(MULTICOMBAT, + 3152, 9920, + 3288, 9920, + 3288, 9856, + 3152, 9856); + + // Stronghold of security 1st floor + addPolygonTo(MULTICOMBAT, + 1856, 5248, + 1920, 5248, + 1920, 5184, + 1856, 5184); + + // Corp cave + addPolygonTo(MULTICOMBAT, + 2960, 4400, + 3000, 4400, + 3000, 4368, + 2960, 4368); + + // ZMI altar area + addPolygonTo(MULTICOMBAT, + 3008, 5632, + 3072, 5632, + 3072, 5568, + 3008, 5568); + + // Dragon slayer 2 zeah underground puzzle + addPolygonTo(MULTICOMBAT, + 1472, 9984, + 1536, 9984, + 1536, 9920, + 1472, 9920); + + // Wildy revenant caves + addPolygonTo(MULTICOMBAT, + 3136, 10062, + 3136, 10240, + 3236, 10240, + 3236, 10229, + 3264, 10229, + 3264, 10048, + 3208, 10048, + 3208, 10062); + + // King black dragon (Kbd) + addPolygonTo(MULTICOMBAT, + 2240, 4672, + 2240, 4736, + 2304, 4736, + 2304, 4672); + + // Scorpia + addPolygonTo(MULTICOMBAT, + 3248, 10352, + 3248, 10328, + 3216, 10328, + 3216, 10352); + + // Inside mage bank + addPolygonTo(MULTICOMBAT, + 2496, 4672, + 2496, 4736, + 2560, 4736, + 2560, 4672); + + // Wildy godwars dungeon + addPolygonTo(MULTICOMBAT, + 3072, 10112, + 3008, 10112, + 3008, 10176, + 3048, 10176, + 3048, 10152, + 3056, 10152, + 3056, 10144, + 3064, 10144, + 3064, 10136, + 3072, 10136); + + // Enchanted valley + addPolygonTo(MULTICOMBAT, + 3008, 4480, + 3008, 4544, + 3072, 4544, + 3072, 4480); + + // Zulrah + addPolygonTo(MULTICOMBAT, + 2256, 3080, + 2280, 3080, + 2280, 3064, + 2256, 3064); + + // Abyssal sire and abyss + addPolygonTo(MULTICOMBAT, + 3008, 4736, + 2944, 4736, + 2944, 4864, + 3136, 4864, + 3136, 4736, + 3072, 4736, + 3072, 4800, + 3008, 4800); + } + + private static void defineDeadmanSafeZones() + { + // Varrock + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3182, 3382, + 3182, 3399, + 3174, 3399, + 3174, 3448, + 3198, 3448, + 3198, 3449, + 3197, 3449, + 3197, 3450, + 3196, 3450, + 3196, 3451, + 3195, 3451, + 3195, 3452, + 3194, 3452, + 3194, 3453, + 3193, 3453, + 3193, 3454, + 3192, 3454, + 3192, 3455, + 3191, 3455, + 3191, 3456, + 3190, 3456, + 3190, 3457, + 3185, 3457, + 3185, 3463, + 3186, 3463, + 3186, 3464, + 3187, 3464, + 3187, 3467, + 3167, 3467, + 3167, 3468, + 3163, 3468, + 3163, 3467, + 3142, 3467, + 3142, 3468, + 3141, 3468, + 3141, 3469, + 3140, 3469, + 3140, 3470, + 3139, 3470, + 3139, 3471, + 3138, 3471, + 3138, 3484, + 3139, 3484, + 3139, 3485, + 3140, 3485, + 3140, 3486, + 3141, 3486, + 3141, 3491, + 3140, 3491, + 3140, 3492, + 3139, 3492, + 3139, 3493, + 3138, 3493, + 3138, 3515, + 3139, 3515, + 3139, 3516, + 3140, 3516, + 3140, 3517, + 3141, 3517, + 3141, 3518, + 3160, 3518, + 3160, 3517, + 3161, 3517, + 3161, 3516, + 3162, 3516, + 3162, 3515, + 3167, 3515, + 3167, 3516, + 3168, 3516, + 3168, 3517, + 3169, 3517, + 3169, 3518, + 3191, 3518, + 3191, 3517, + 3192, 3517, + 3192, 3516, + 3193, 3516, + 3193, 3515, + 3194, 3515, + 3194, 3514, + 3195, 3514, + 3195, 3513, + 3196, 3513, + 3196, 3512, + 3197, 3512, + 3197, 3511, + 3198, 3511, + 3198, 3510, + 3199, 3510, + 3199, 3509, + 3200, 3509, + 3200, 3508, + 3230, 3508, + 3230, 3507, + 3231, 3507, + 3231, 3506, + 3232, 3506, + 3232, 3505, + 3233, 3505, + 3233, 3504, + 3234, 3504, + 3234, 3503, + 3235, 3503, + 3235, 3502, + 3252, 3502, + 3252, 3496, + 3253, 3496, + 3253, 3495, + 3254, 3495, + 3254, 3494, + 3255, 3494, + 3255, 3493, + 3263, 3493, + 3263, 3472, + 3264, 3472, + 3264, 3471, + 3265, 3471, + 3265, 3470, + 3266, 3470, + 3266, 3469, + 3267, 3469, + 3267, 3468, + 3268, 3468, + 3268, 3467, + 3269, 3467, + 3269, 3466, + 3270, 3466, + 3270, 3465, + 3271, 3465, + 3271, 3437, + 3274, 3437, + 3274, 3424, + 3277, 3424, + 3277, 3420, + 3274, 3420, + 3274, 3411, + 3275, 3411, + 3275, 3410, + 3276, 3410, + 3276, 3409, + 3277, 3409, + 3277, 3408, + 3288, 3408, + 3288, 3391, + 3289, 3391, + 3289, 3385, + 3290, 3385, + 3290, 3378, + 3289, 3378, + 3289, 3377, + 3288, 3377, + 3288, 3376, + 3265, 3376, + 3265, 3380, + 3253, 3380, + 3253, 3382, + 3245, 3382, + 3245, 3380, + 3242, 3380, + 3242, 3382, + 3239, 3382, + 3239, 3381, + 3209, 3381, + 3209, 3382, + 3282, 3382); + + // Lumbridge + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3201, 3257, + 3213, 3257, + 3213, 3264, + 3233, 3264, + 3233, 3257, + 3235, 3257, + 3235, 3241, + 3237, 3241, + 3237, 3237, + 3239, 3237, + 3239, 3231, + 3243, 3231, + 3243, 3220, + 3253, 3220, + 3253, 3217, + 3256, 3217, + 3256, 3212, + 3259, 3212, + 3259, 3190, + 3247, 3190, + 3247, 3191, + 3238, 3191, + 3238, 3195, + 3230, 3195, + 3230, 3201, + 3228, 3201, + 3228, 3202, + 3227, 3202, + 3227, 3205, + 3228, 3205, + 3228, 3207, + 3225, 3207, + 3225, 3206, + 3224, 3206, + 3224, 3205, + 3223, 3205, + 3223, 3204, + 3222, 3204, + 3222, 3203, + 3215, 3203, + 3215, 3202, + 3214, 3202, + 3214, 3201, + 3203, 3201, + 3203, 3202, + 3202, 3202, + 3202, 3203, + 3201, 3203, + 3201, 3217, + 3199, 3217, + 3199, 3220, + 3201, 3220); + + // Falador + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2986, 3395, + 2986, 3394, + 2987, 3394, + 2987, 3393, + 2996, 3393, + 2996, 3394, + 3002, 3394, + 3002, 3395, + 3009, 3395, + 3009, 3394, + 3010, 3394, + 3010, 3393, + 3011, 3393, + 3011, 3392, + 3021, 3392, + 3021, 3391, + 3022, 3391, + 3022, 3390, + 3041, 3390, + 3041, 3389, + 3047, 3389, + 3047, 3390, + 3062, 3390, + 3062, 3389, + 3063, 3389, + 3063, 3388, + 3064, 3388, + 3064, 3387, + 3065, 3387, + 3065, 3386, + 3066, 3386, + 3066, 3368, + 3065, 3368, + 3065, 3367, + 3064, 3367, + 3064, 3366, + 3063, 3366, + 3063, 3365, + 3062, 3365, + 3062, 3364, + 3061, 3364, + 3061, 3363, + 3060, 3363, + 3060, 3331, + 3061, 3331, + 3061, 3328, + 3058, 3328, + 3058, 3329, + 3025, 3329, + 3025, 3328, + 3024, 3328, + 3024, 3327, + 3016, 3327, + 3016, 3326, + 3015, 3326, + 3015, 3325, + 3014, 3325, + 3014, 3324, + 3013, 3324, + 3013, 3323, + 3008, 3323, + 3008, 3324, + 3006, 3324, + 3006, 3323, + 3002, 3323, + 3002, 3322, + 3001, 3322, + 3001, 3321, + 3000, 3321, + 3000, 3320, + 2999, 3320, + 2999, 3319, + 2998, 3319, + 2998, 3318, + 2997, 3318, + 2997, 3317, + 2996, 3317, + 2996, 3316, + 2992, 3316, + 2992, 3315, + 2991, 3315, + 2991, 3314, + 2990, 3314, + 2990, 3313, + 2989, 3313, + 2989, 3312, + 2988, 3312, + 2988, 3311, + 2987, 3311, + 2987, 3310, + 2986, 3310, + 2986, 3309, + 2966, 3309, + 2966, 3310, + 2956, 3310, + 2956, 3311, + 2941, 3311, + 2941, 3312, + 2940, 3312, + 2940, 3320, + 2936, 3320, + 2936, 3354, + 2937, 3354, + 2937, 3357, + 2936, 3357, + 2936, 3389, + 2937, 3389, + 2937, 3390, + 2938, 3390, + 2938, 3391, + 2939, 3391, + 2939, 3392, + 2940, 3392, + 2940, 3393, + 2943, 3393, + 2943, 3394, + 2944, 3394, + 2944, 3395, + 2950, 3395, + 2950, 3394, + 2956, 3394, + 2956, 3395); + + // Port phasmatys + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3650, 3456, + 3650, 3472, + 3651, 3472, + 3651, 3473, + 3652, 3473, + 3652, 3474, + 3653, 3474, + 3653, 3507, + 3654, 3507, + 3654, 3508, + 3668, 3508, + 3668, 3509, + 3669, 3509, + 3669, 3510, + 3670, 3510, + 3670, 3511, + 3671, 3511, + 3671, 3512, + 3672, 3512, + 3672, 3513, + 3673, 3513, + 3673, 3514, + 3674, 3514, + 3674, 3515, + 3675, 3515, + 3675, 3516, + 3676, 3516, + 3676, 3517, + 3687, 3517, + 3687, 3494, + 3690, 3494, + 3690, 3493, + 3696, 3493, + 3696, 3482, + 3699, 3482, + 3699, 3481, + 3712, 3481, + 3712, 3456); + + // Sophanem + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3274, 2752, + 3274, 2784, + 3277, 2784, + 3277, 2786, + 3274, 2786, + 3274, 2789, + 3272, 2789, + 3272, 2810, + 3322, 2810, + 3322, 2752); + + // Ardy + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2560, 3256, + 2560, 3264, + 2559, 3264, + 2559, 3328, + 2560, 3328, + 2560, 3339, + 2561, 3339, + 2561, 3340, + 2562, 3340, + 2562, 3341, + 2563, 3341, + 2563, 3342, + 2616, 3342, + 2616, 3341, + 2617, 3341, + 2617, 3340, + 2669, 3340, + 2669, 3339, + 2670, 3339, + 2670, 3338, + 2671, 3338, + 2671, 3337, + 2672, 3337, + 2672, 3336, + 2673, 3336, + 2673, 3335, + 2674, 3335, + 2674, 3334, + 2683, 3334, + 2683, 3333, + 2684, 3333, + 2684, 3332, + 2685, 3332, + 2685, 3331, + 2686, 3331, + 2686, 3330, + 2687, 3330, + 2687, 3329, + 2688, 3329, + 2688, 3264, + 2638, 3264, + 2638, 3263, + 2625, 3263, + 2625, 3264, + 2611, 3264, + 2611, 3257, + 2602, 3257, + 2602, 3264, + 2587, 3264, + 2587, 3263, + 2586, 3263, + 2586, 3262, + 2584, 3262, + 2584, 3261, + 2583, 3261, + 2583, 3260, + 2582, 3260, + 2582, 3259, + 2581, 3259, + 2581, 3258, + 2572, 3258, + 2572, 3260, + 2571, 3260, + 2571, 3261, + 2566, 3261, + 2566, 3260, + 2565, 3260, + 2565, 3259, + 2564, 3259, + 2564, 3256); + + // Yanille + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2613, 3103, + 2614, 3103, + 2614, 3102, + 2615, 3102, + 2615, 3101, + 2616, 3101, + 2616, 3100, + 2617, 3100, + 2617, 3099, + 2618, 3099, + 2618, 3098, + 2619, 3098, + 2619, 3097, + 2620, 3097, + 2620, 3075, + 2590, 3075, + 2590, 3074, + 2589, 3074, + 2589, 3073, + 2584, 3073, + 2584, 3074, + 2583, 3074, + 2583, 3075, + 2543, 3075, + 2543, 3076, + 2542, 3076, + 2542, 3077, + 2539, 3077, + 2539, 3107, + 2542, 3107, + 2542, 3108, + 2543, 3108, + 2543, 3109, + 2608, 3109, + 2608, 3108, + 2609, 3108, + 2609, 3107, + 2610, 3107, + 2610, 3106, + 2611, 3106, + 2611, 3105, + 2612, 3105, + 2612, 3104, + 2613, 3104); + + // Gnome stronghold + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2495, 3439, + 2494, 3439, + 2494, 3432, + 2495, 3432, + 2495, 3431, + 2496, 3431, + 2496, 3430, + 2497, 3430, + 2497, 3429, + 2498, 3429, + 2498, 3417, + 2497, 3417, + 2497, 3416, + 2496, 3416, + 2496, 3412, + 2495, 3412, + 2495, 3408, + 2494, 3408, + 2494, 3404, + 2495, 3404, + 2495, 3403, + 2496, 3403, + 2496, 3402, + 2497, 3402, + 2497, 3401, + 2498, 3401, + 2498, 3400, + 2499, 3400, + 2499, 3399, + 2500, 3399, + 2500, 3398, + 2501, 3398, + 2501, 3397, + 2502, 3397, + 2502, 3396, + 2506, 3396, + 2506, 3391, + 2502, 3391, + 2502, 3390, + 2492, 3390, + 2492, 3391, + 2489, 3391, + 2489, 3390, + 2488, 3390, + 2488, 3389, + 2485, 3389, + 2485, 3390, + 2482, 3390, + 2482, 3389, + 2476, 3389, + 2476, 3390, + 2471, 3390, + 2471, 3391, + 2468, 3391, + 2468, 3390, + 2467, 3390, + 2467, 3389, + 2466, 3389, + 2466, 3385, + 2465, 3385, + 2465, 3384, + 2458, 3384, + 2458, 3385, + 2457, 3385, + 2457, 3389, + 2456, 3389, + 2456, 3390, + 2455, 3390, + 2455, 3391, + 2450, 3391, + 2450, 3390, + 2446, 3390, + 2446, 3391, + 2443, 3391, + 2443, 3390, + 2442, 3390, + 2442, 3389, + 2440, 3389, + 2440, 3388, + 2434, 3388, + 2434, 3389, + 2433, 3389, + 2433, 3390, + 2432, 3390, + 2432, 3391, + 2428, 3391, + 2428, 3392, + 2427, 3392, + 2427, 3393, + 2420, 3393, + 2420, 3394, + 2419, 3394, + 2419, 3395, + 2418, 3395, + 2418, 3396, + 2417, 3396, + 2417, 3397, + 2416, 3397, + 2416, 3399, + 2415, 3399, + 2415, 3400, + 2414, 3400, + 2414, 3408, + 2413, 3408, + 2413, 3409, + 2412, 3409, + 2412, 3410, + 2411, 3410, + 2411, 3411, + 2410, 3411, + 2410, 3412, + 2387, 3412, + 2387, 3407, + 2383, 3407, + 2383, 3408, + 2380, 3408, + 2380, 3409, + 2379, 3409, + 2379, 3410, + 2377, 3410, + 2377, 3411, + 2376, 3411, + 2376, 3413, + 2375, 3413, + 2375, 3417, + 2374, 3417, + 2374, 3418, + 2373, 3418, + 2373, 3419, + 2372, 3419, + 2372, 3420, + 2371, 3420, + 2371, 3421, + 2370, 3421, + 2370, 3422, + 2369, 3422, + 2369, 3433, + 2370, 3433, + 2370, 3434, + 2371, 3434, + 2371, 3444, + 2372, 3444, + 2372, 3445, + 2373, 3445, + 2373, 3446, + 2374, 3446, + 2374, 3447, + 2375, 3447, + 2375, 3459, + 2376, 3459, + 2376, 3460, + 2377, 3460, + 2377, 3461, + 2378, 3461, + 2378, 3462, + 2379, 3462, + 2379, 3463, + 2380, 3463, + 2380, 3464, + 2381, 3464, + 2381, 3476, + 2379, 3476, + 2379, 3477, + 2378, 3477, + 2378, 3478, + 2377, 3478, + 2377, 3485, + 2376, 3485, + 2376, 3486, + 2375, 3486, + 2375, 3499, + 2376, 3499, + 2376, 3500, + 2377, 3500, + 2377, 3507, + 2378, 3507, + 2378, 3508, + 2379, 3508, + 2379, 3509, + 2380, 3509, + 2380, 3521, + 2382, 3521, + 2382, 3522, + 2384, 3522, + 2384, 3523, + 2393, 3523, + 2393, 3524, + 2399, 3524, + 2399, 3525, + 2404, 3525, + 2404, 3524, + 2405, 3524, + 2405, 3523, + 2407, 3523, + 2407, 3522, + 2415, 3522, + 2415, 3521, + 2425, 3521, + 2425, 3522, + 2427, 3522, + 2427, 3523, + 2430, 3523, + 2430, 3522, + 2431, 3522, + 2431, 3521, + 2432, 3521, + 2432, 3520, + 2448, 3520, + 2448, 3517, + 2454, 3517, + 2454, 3516, + 2455, 3516, + 2455, 3515, + 2456, 3515, + 2456, 3514, + 2457, 3514, + 2457, 3513, + 2460, 3513, + 2460, 3512, + 2461, 3512, + 2461, 3511, + 2465, 3511, + 2465, 3510, + 2468, 3510, + 2468, 3511, + 2472, 3511, + 2472, 3512, + 2473, 3512, + 2473, 3513, + 2475, 3513, + 2475, 3514, + 2476, 3514, + 2476, 3515, + 2477, 3515, + 2477, 3516, + 2478, 3516, + 2478, 3517, + 2483, 3517, + 2483, 3516, + 2487, 3516, + 2487, 3515, + 2488, 3515, + 2488, 3512, + 2487, 3512, + 2487, 3509, + 2488, 3509, + 2488, 3508, + 2489, 3508, + 2489, 3507, + 2491, 3507, + 2491, 3506, + 2492, 3506, + 2492, 3505, + 2493, 3505, + 2493, 3499, + 2492, 3499, + 2492, 3498, + 2491, 3498, + 2491, 3497, + 2490, 3497, + 2490, 3495, + 2491, 3495, + 2491, 3494, + 2492, 3494, + 2492, 3493, + 2493, 3493, + 2493, 3485, + 2490, 3485, + 2490, 3484, + 2489, 3484, + 2489, 3483, + 2488, 3483, + 2488, 3482, + 2487, 3482, + 2487, 3481, + 2486, 3481, + 2486, 3474, + 2488, 3474, + 2488, 3471, + 2489, 3471, + 2489, 3470, + 2490, 3470, + 2490, 3460, + 2491, 3460, + 2491, 3456, + 2496, 3456, + 2496, 3440, + 2495, 3440); + + // Rellekka + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2620, 3682, + 2624, 3682, + 2624, 3683, + 2625, 3683, + 2625, 3687, + 2629, 3687, + 2629, 3686, + 2630, 3686, + 2630, 3685, + 2632, 3685, + 2632, 3686, + 2636, 3686, + 2636, 3692, + 2645, 3692, + 2645, 3695, + 2647, 3695, + 2647, 3696, + 2649, 3696, + 2649, 3702, + 2650, 3702, + 2650, 3703, + 2651, 3703, + 2651, 3704, + 2652, 3704, + 2652, 3711, + 2653, 3711, + 2653, 3712, + 2691, 3712, + 2691, 3709, + 2692, 3709, + 2692, 3707, + 2693, 3707, + 2693, 3703, + 2692, 3703, + 2692, 3701, + 2691, 3701, + 2691, 3699, + 2690, 3699, + 2690, 3695, + 2691, 3695, + 2691, 3693, + 2692, 3693, + 2692, 3691, + 2693, 3691, + 2693, 3685, + 2692, 3685, + 2692, 3683, + 2691, 3683, + 2691, 3681, + 2690, 3681, + 2690, 3680, + 2689, 3680, + 2689, 3672, + 2690, 3672, + 2690, 3671, + 2691, 3671, + 2691, 3666, + 2690, 3666, + 2690, 3664, + 2689, 3664, + 2689, 3660, + 2690, 3660, + 2690, 3658, + 2691, 3658, + 2691, 3656, + 2692, 3656, + 2692, 3654, + 2693, 3654, + 2693, 3651, + 2692, 3651, + 2692, 3649, + 2690, 3649, + 2690, 3648, + 2688, 3648, + 2688, 3647, + 2686, 3647, + 2686, 3646, + 2673, 3646, + 2673, 3645, + 2636, 3645, + 2636, 3647, + 2627, 3647, + 2627, 3648, + 2625, 3648, + 2625, 3649, + 2624, 3649, + 2624, 3650, + 2622, 3650, + 2622, 3651, + 2620, 3651, + 2620, 3652, + 2618, 3652, + 2618, 3653, + 2616, 3653, + 2616, 3654, + 2609, 3654, + 2609, 3655, + 2607, 3655, + 2607, 3656, + 2603, 3656, + 2603, 3657, + 2602, 3657, + 2602, 3658, + 2601, 3658, + 2601, 3663, + 2602, 3663, + 2602, 3664, + 2603, 3664, + 2603, 3665, + 2604, 3665, + 2604, 3666, + 2605, 3666, + 2605, 3667, + 2606, 3667, + 2606, 3671, + 2609, 3671, + 2609, 3672, + 2610, 3672, + 2610, 3673, + 2611, 3673, + 2611, 3675, + 2612, 3675, + 2612, 3676, + 2614, 3676, + 2614, 3677, + 2616, 3677, + 2616, 3679, + 2618, 3679, + 2618, 3681, + 2620, 3681); + + // Jatizo + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2407, 3797, + 2407, 3793, + 2399, 3793, + 2399, 3792, + 2391, 3792, + 2391, 3791, + 2386, 3791, + 2386, 3796, + 2388, 3796, + 2388, 3802, + 2386, 3802, + 2386, 3807, + 2388, 3807, + 2388, 3809, + 2402, 3809, + 2402, 3819, + 2406, 3819, + 2406, 3824, + 2408, 3824, + 2408, 3826, + 2413, 3826, + 2413, 3824, + 2419, 3824, + 2419, 3826, + 2424, 3826, + 2424, 3821, + 2423, 3821, + 2423, 3798, + 2422, 3798, + 2422, 3797); + + // Neitiznot + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2329, 3812, + 2333, 3812, + 2333, 3813, + 2334, 3813, + 2334, 3814, + 2335, 3814, + 2335, 3815, + 2338, 3815, + 2338, 3816, + 2339, 3816, + 2339, 3817, + 2368, 3817, + 2368, 3776, + 2352, 3776, + 2352, 3796, + 2344, 3796, + 2344, 3795, + 2331, 3795, + 2331, 3797, + 2330, 3797, + 2330, 3798, + 2329, 3798); + + // Pest control + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2624, 2688, + 2688, 2688, + 2688, 2624, + 2624, 2624); + + // Tutorial island + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3052, 3135, + 3156, 3135, + 3156, 3057, + 3052, 3057); + + // Camelot bank + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2724, 3487, + 2724, 3490, + 2721, 3490, + 2721, 3494, + 2719, 3494, + 2719, 3497, + 2721, 3497, + 2721, 3498, + 2731, 3498, + 2731, 3490, + 2728, 3490, + 2728, 3487); + + // Catherby bank + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2806, 3438, + 2806, 3446, + 2813, 3446, + 2813, 3438); + + // Kourend castle + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 1627, 3658, + 1620, 3658, + 1620, 3657, + 1619, 3657, + 1619, 3656, + 1614, 3656, + 1614, 3657, + 1613, 3657, + 1613, 3661, + 1612, 3661, + 1612, 3662, + 1611, 3662, + 1611, 3663, + 1600, 3663, + 1600, 3662, + 1599, 3662, + 1599, 3661, + 1594, 3661, + 1594, 3662, + 1593, 3662, + 1593, 3685, + 1594, 3685, + 1594, 3686, + 1599, 3686, + 1599, 3685, + 1600, 3685, + 1600, 3684, + 1611, 3684, + 1611, 3685, + 1612, 3685, + 1612, 3686, + 1613, 3686, + 1613, 3690, + 1614, 3690, + 1614, 3691, + 1619, 3691, + 1619, 3690, + 1620, 3690, + 1620, 3689, + 1630, 3689, + 1630, 3686, + 1620, 3686, + 1620, 3685, + 1619, 3685, + 1619, 3683, + 1620, 3683, + 1620, 3682, + 1621, 3682, + 1621, 3681, + 1622, 3681, + 1622, 3680, + 1623, 3680, + 1623, 3679, + 1624, 3679, + 1624, 3668, + 1623, 3668, + 1623, 3667, + 1622, 3667, + 1622, 3666, + 1621, 3666, + 1621, 3665, + 1620, 3665, + 1620, 3664, + 1619, 3664, + 1619, 3662, + 1620, 3662, + 1620, 3661, + 1627, 3661); + } + + private static void definePvpSafeZones() + { + // Grand exchange + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3159, 3473, + 3159, 3474, + 3157, 3474, + 3157, 3475, + 3155, 3475, + 3155, 3476, + 3153, 3476, + 3153, 3477, + 3152, 3477, + 3152, 3478, + 3151, 3478, + 3151, 3480, + 3150, 3480, + 3150, 3482, + 3149, 3482, + 3149, 3484, + 3148, 3484, + 3148, 3496, + 3149, 3496, + 3149, 3498, + 3150, 3498, + 3150, 3500, + 3151, 3500, + 3151, 3502, + 3152, 3502, + 3152, 3503, + 3153, 3503, + 3153, 3504, + 3155, 3504, + 3155, 3505, + 3157, 3505, + 3157, 3506, + 3159, 3506, + 3159, 3507, + 3171, 3507, + 3171, 3506, + 3173, 3506, + 3173, 3505, + 3175, 3505, + 3175, 3504, + 3177, 3504, + 3177, 3503, + 3178, 3503, + 3178, 3502, + 3179, 3502, + 3179, 3500, + 3180, 3500, + 3180, 3498, + 3181, 3498, + 3181, 3496, + 3182, 3496, + 3182, 3484, + 3181, 3484, + 3181, 3482, + 3180, 3482, + 3180, 3480, + 3179, 3480, + 3179, 3478, + 3178, 3478, + 3178, 3477, + 3177, 3477, + 3177, 3476, + 3175, 3476, + 3175, 3475, + 3173, 3475, + 3173, 3474, + 3171, 3474, + 3171, 3473); + + // Edgeville + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3091, 3488, + 3091, 3493, + 3090, 3493, + 3090, 3498, + 3091, 3498, + 3091, 3500, + 3099, 3500, + 3099, 3488); + + // Fally west bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2943, 3368, + 2943, 3374, + 2948, 3374, + 2948, 3370, + 2950, 3370, + 2950, 3366, + 2949, 3366, + 2949, 3359, + 2945, 3359, + 2945, 3362, + 2946, 3362, + 2946, 3366, + 2945, 3366, + 2945, 3368); + + // Fally east bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3009, 3353, + 3009, 3359, + 3019, 3359, + 3019, 3357, + 3022, 3357, + 3022, 3353); + + // Fally castle + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2964, 3354, + 2966, 3354, + 2966, 3352, + 2967, 3352, + 2967, 3349, + 2976, 3349, + 2976, 3348, + 2977, 3348, + 2977, 3347, + 2981, 3347, + 2981, 3343, + 2982, 3343, + 2982, 3339, + 2981, 3339, + 2981, 3337, + 2967, 3337, + 2967, 3330, + 2963, 3330, + 2963, 3331, + 2962, 3331, + 2962, 3332, + 2961, 3332, + 2961, 3334, + 2964, 3334, + 2964, 3335, + 2965, 3335, + 2965, 3343, + 2964, 3343, + 2964, 3344, + 2961, 3344, + 2961, 3350, + 2963, 3350, + 2963, 3352, + 2964, 3352); + + // Varrock east bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3250, 3425, + 3258, 3425, + 3258, 3416, + 3250, 3416); + + // Varrock west bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3180, 3433, + 3180, 3448, + 3191, 3448, + 3191, 3433); + + // Port phasmatys + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3686, 3472, + 3700, 3472, + 3700, 3461, + 3686, 3461); + + // Yanille bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2609, 3088, + 2609, 3098, + 2617, 3098, + 2617, 3088); + + // Ardy east bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2649, 3280, + 2649, 3288, + 2659, 3288, + 2659, 3280); + + // Ardy west bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2612, 3330, + 2612, 3336, + 2615, 3336, + 2615, 3335, + 2619, 3335, + 2619, 3336, + 2622, 3336, + 2622, 3330); + + // Fishing guild bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2593, 3413, + 2588, 3413, + 2588, 3418, + 2583, 3418, + 2583, 3423, + 2590, 3423, + 2590, 3420, + 2593, 3420); + + // Gnome stronghold bank near slayer cave (2nd floor) + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, + 2444, 3431, + 2444, 3435, + 2448, 3435, + 2448, 3431, + 2447, 3431, + 2447, 3428, + 2449, 3428, + 2449, 3422, + 2447, 3422, + 2447, 3419, + 2448, 3419, + 2448, 3415, + 2444, 3415, + 2444, 3419, + 2445, 3419, + 2445, 3422, + 2443, 3422, + 2443, 3428, + 2445, 3428, + 2445, 3431); + + // Gnome stronghold bank in grand tree + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, + 2456, 3488, + 2452, 3488, + 2452, 3486, + 2450, 3486, + 2450, 3483, + 2451, 3483, + 2451, 3478, + 2448, 3478, + 2448, 3483, + 2449, 3483, + 2449, 3486, + 2447, 3486, + 2447, 3488, + 2443, 3488, + 2443, 3487, + 2438, 3487, + 2438, 3490, + 2443, 3490, + 2443, 3489, + 2447, 3489, + 2447, 3491, + 2449, 3491, + 2449, 3494, + 2448, 3494, + 2448, 3496, + 2451, 3496, + 2451, 3494, + 2450, 3494, + 2450, 3491, + 2452, 3491, + 2452, 3489, + 2456, 3489); + + // Al kharid bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3265, 3161, + 3265, 3174, + 3273, 3174, + 3273, 3161); + + // Shantay pass bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3308, 3119, + 3308, 3125, + 3310, 3125, + 3310, 3119); + + // Nardah bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3431, 2891, + 3431, 2889, + 3427, 2889, + 3427, 2887, + 3424, 2887, + 3424, 2895, + 3431, 2895, + 3431, 2893, + 3432, 2893, + 3432, 2891); + + // Sophanem bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2807, 5158, + 2792, 5158, + 2792, 5175, + 2807, 5175); + + // Canifis bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3509, 3474, + 3509, 3478, + 3508, 3478, + 3508, 3483, + 3509, 3483, + 3509, 3484, + 3517, 3484, + 3517, 3477, + 3516, 3477, + 3516, 3476, + 3513, 3476, + 3513, 3474); + + // Lumbridge castle outside + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3216, 3209, + 3216, 3210, + 3217, 3210, + 3217, 3228, + 3216, 3228, + 3216, 3229, + 3227, 3229, + 3227, 3221, + 3230, 3221, + 3230, 3217, + 3227, 3217, + 3227, 3209); + + // Lumbridge bank upstairs + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 2, + 3211, 3223, + 3211, 3215, + 3207, 3215, + 3207, 3223); + + // Draynor bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3098, 3240, + 3088, 3240, + 3088, 3247, + 3098, 3247); + + // Pest control bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2665, 2656, + 2670, 2656, + 2670, 2651, + 2665, 2651); + + // Shilo village bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2843, 2957, + 2846, 2957, + 2846, 2956, + 2849, 2956, + 2849, 2957, + 2850, 2957, + 2850, 2958, + 2855, 2958, + 2855, 2957, + 2856, 2957, + 2856, 2956, + 2858, 2956, + 2858, 2957, + 2862, 2957, + 2862, 2952, + 2858, 2952, + 2858, 2953, + 2856, 2953, + 2856, 2952, + 2855, 2952, + 2855, 2951, + 2850, 2951, + 2850, 2952, + 2849, 2952, + 2849, 2953, + 2847, 2953, + 2847, 2952, + 2843, 2952); + + // Legends guild bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 2, + 2731, 3374, + 2731, 3383, + 2734, 3383, + 2734, 3374); + + // Legends guild middle floor + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, + 2724, 3374, + 2724, 3383, + 2734, 3383, + 2734, 3382, + 2736, 3382, + 2736, 3375, + 2734, 3375, + 2734, 3374); + + // Warriors guild bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2843, 3537, + 2843, 3540, + 2841, 3540, + 2841, 3546, + 2849, 3546, + 2849, 3537, + 2847, 3537, + 2847, 3536, + 2846, 3536, + 2846, 3537); + + // Camelot bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2724, 3487, + 2724, 3490, + 2721, 3490, + 2721, 3494, + 2719, 3494, + 2719, 3497, + 2721, 3497, + 2721, 3498, + 2731, 3498, + 2731, 3490, + 2728, 3490, + 2728, 3487); + + // Camelot respawn point + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2761, 3483, + 2761, 3476, + 2755, 3476, + 2755, 3483); + + // Catherby bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2806, 3438, + 2806, 3446, + 2813, 3446, + 2813, 3438); + + // Barbarian outpost bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2536, 3572, + 2536, 3575, + 2538, 3575, + 2538, 3572); + + // Piscatoris bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2327, 3686, + 2327, 3694, + 2333, 3694, + 2333, 3686); + + // Lletya bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2350, 3161, + 2350, 3165, + 2351, 3165, + 2351, 3167, + 2357, 3167, + 2357, 3165, + 2356, 3165, + 2356, 3164, + 2355, 3164, + 2355, 3161); + + // Castle wars bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2446, 3087, + 2445, 3087, + 2445, 3085, + 2447, 3085, + 2447, 3081, + 2443, 3081, + 2443, 3082, + 2439, 3082, + 2439, 3081, + 2435, 3081, + 2435, 3099, + 2439, 3099, + 2439, 3098, + 2443, 3098, + 2443, 3099, + 2447, 3099, + 2447, 3095, + 2445, 3095, + 2445, 3093, + 2446, 3093); + + // Duel arena bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3380, 3267, + 3380, 3273, + 3381, 3273, + 3381, 3274, + 3385, 3274, + 3385, 3267); + + // Clan wars bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3375, 3165, + 3361, 3165, + 3361, 3173, + 3375, 3173); + + // Lumbridge cellar bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 3218, 9622, + 3218, 9624, + 3220, 9624, + 3220, 9622); + + // Dorgesh kaan bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2709, 5348, + 2707, 5348, + 2707, 5345, + 2701, 5345, + 2701, 5347, + 2697, 5347, + 2697, 5353, + 2701, 5353, + 2701, 5355, + 2707, 5355, + 2707, 5350, + 2709, 5350); + + // Keldagrim bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2842, 10204, + 2834, 10204, + 2834, 10216, + 2842, 10216); + + // Tzhaar bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2438, 5176, + 2438, 5180, + 2441, 5180, + 2441, 5182, + 2449, 5182, + 2449, 5181, + 2450, 5181, + 2450, 5180, + 2452, 5180, + 2452, 5175, + 2441, 5175, + 2441, 5176); + + // Inferno bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2542, 5135, + 2542, 5139, + 2539, 5139, + 2539, 5140, + 2538, 5140, + 2538, 5141, + 2537, 5141, + 2537, 5144, + 2541, 5144, + 2541, 5145, + 2543, 5145, + 2543, 5144, + 2544, 5144, + 2544, 5142, + 2545, 5142, + 2545, 5135); + + // Port khazard bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2661, 3160, + 2661, 3163, + 2666, 3163, + 2666, 3160); + + // Corsair cove bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2569, 2863, + 2569, 2868, + 2572, 2868, + 2572, 2863); + + // Burgh de rott bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3495, 3210, + 3495, 3214, + 3501, 3214, + 3501, 3210); + + // Edgeville respawn point + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3092, 3468, + 3092, 3474, + 3098, 3474, + 3098, 3468); + + // Mage bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2529, 4711, + 2529, 4724, + 2548, 4724, + 2548, 4711); + + // Lunar bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2097, 3917, + 2097, 3922, + 2105, 3922, + 2105, 3917); + + // Jatizo bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2414, 3801, + 2414, 3804, + 2420, 3804, + 2420, 3801); + + // Neitiznot bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2334, 3805, + 2334, 3809, + 2340, 3809, + 2340, 3805); + + // Hosidius bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1671, 3558, + 1671, 3577, + 1682, 3577, + 1682, 3558); + + // Woodcutting guild bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1589, 3475, + 1589, 3481, + 1594, 3481, + 1594, 3475); + + // Lands end bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1508, 3415, + 1508, 3424, + 1514, 3424, + 1514, 3415); + + // Chambers of xeric bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1252, 3570, + 1252, 3574, + 1257, 3574, + 1257, 3570); + + // Arceuus bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1621, 3736, + 1621, 3754, + 1627, 3754, + 1627, 3751, + 1633, 3751, + 1633, 3754, + 1639, 3754, + 1639, 3736); + + // Piscarilius bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1794, 3784, + 1794, 3794, + 1812, 3794, + 1812, 3784); + + // Lovakengj bank southeast + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1518, 3735, + 1518, 3744, + 1535, 3744, + 1535, 3735); + + // Lovakenj bank west + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1433, 3820, + 1433, 3837, + 1442, 3837, + 1442, 3820); + + // Lovakenj sulphur mine bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1452, 3855, + 1452, 3860, + 1455, 3860, + 1455, 3855); + + // Blast mine bank southeast + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1500, 3856, + 1500, 3858, + 1503, 3858, + 1503, 3856); + + // Wintertodt bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1638, 3942, + 1638, 3947, + 1642, 3947, + 1642, 3942); + + // Shayzien bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1495, 3612, + 1495, 3622, + 1515, 3622, + 1515, 3612); + + // Hosidius grape farm bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1804, 3571, + 1804, 3572, + 1808, 3572, + 1808, 3571); + + // Hosidius cooking bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1652, 3605, + 1652, 3615, + 1661, 3615, + 1661, 3605); + + // Ecteria bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2618, 3893, + 2618, 3897, + 2622, 3897, + 2622, 3893); + + // Mining guild expanded area + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 3018, 9733, + 3021, 9733, + 3021, 9729, + 3022, 9729, + 3022, 9728, + 3023, 9728, + 3023, 9727, + 3025, 9727, + 3025, 9726, + 3026, 9726, + 3026, 9725, + 3030, 9725, + 3030, 9726, + 3032, 9726, + 3032, 9727, + 3035, 9727, + 3035, 9726, + 3038, 9726, + 3038, 9727, + 3041, 9727, + 3041, 9728, + 3042, 9728, + 3042, 9730, + 3045, 9730, + 3045, 9727, + 3047, 9727, + 3047, 9726, + 3048, 9726, + 3048, 9724, + 3052, 9724, + 3052, 9725, + 3053, 9725, + 3053, 9726, + 3055, 9726, + 3055, 9725, + 3056, 9725, + 3056, 9723, + 3057, 9723, + 3057, 9720, + 3056, 9720, + 3056, 9719, + 3054, 9719, + 3054, 9718, + 3052, 9718, + 3052, 9717, + 3050, 9717, + 3050, 9718, + 3045, 9718, + 3045, 9716, + 3044, 9716, + 3044, 9715, + 3041, 9715, + 3041, 9714, + 3039, 9714, + 3039, 9713, + 3037, 9713, + 3037, 9714, + 3036, 9714, + 3036, 9715, + 3034, 9715, + 3034, 9716, + 3029, 9716, + 3029, 9715, + 3028, 9715, + 3028, 9714, + 3026, 9714, + 3026, 9709, + 3027, 9709, + 3027, 9708, + 3028, 9708, + 3028, 9705, + 3029, 9705, + 3029, 9701, + 3028, 9701, + 3028, 9700, + 3027, 9700, + 3027, 9699, + 3023, 9699, + 3023, 9700, + 3019, 9700, + 3019, 9701, + 3018, 9701, + 3018, 9705, + 3019, 9705, + 3019, 9707, + 3020, 9707, + 3020, 9708, + 3021, 9708, + 3021, 9709, + 3022, 9709, + 3022, 9713, + 3021, 9713, + 3021, 9714, + 3019, 9714, + 3019, 9715, + 3018, 9715, + 3018, 9717, + 3015, 9717, + 3015, 9716, + 3013, 9716, + 3013, 9717, + 3012, 9717, + 3012, 9720, + 3013, 9720, + 3013, 9721, + 3015, 9721, + 3015, 9723, + 3016, 9723, + 3016, 9727, + 3017, 9727, + 3017, 9730, + 3018, 9730); + + // Motherlode mine bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 3760, 5671, + 3760, 5668, + 3761, 5668, + 3761, 5665, + 3760, 5665, + 3760, 5663, + 3758, 5663, + 3758, 5671); + + // Mos le harmles bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3679, 2980, + 3679, 2985, + 3681, 2985, + 3681, 2984, + 3682, 2984, + 3682, 2985, + 3684, 2985, + 3684, 2980, + 3682, 2980, + 3682, 2981, + 3681, 2981, + 3681, 2980); + + // Zanaris bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2388, 4454, + 2380, 4454, + 2380, 4463, + 2388, 4463); + + // Wodcuting guild bank underground + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 1550, 9872, + 1550, 9874, + 1553, 9874, + 1553, 9872); + } + + private static void defineWilderness() + { + // Above ground + addPolygonTo(ROUGH_WILDERNESS, + 2944, 3523, + 3392, 3523, + 3392, 3971, + 2944, 3971); + + // Underground + addPolygonTo(ROUGH_WILDERNESS, + 2944, 9918, + 2944, 10360, + 3264, 10360, + 3264, 9918); + } + + private static void addPolygonTo(List[] shapes, int... coords) + { + Polygon poly = new Polygon(); + for (int i = 0; i < coords.length; i += 2) + { + poly.addPoint(coords[i], coords[i + 1]); + } + for (int i = 0; i < shapes.length; i++) + { + shapes[i].add(poly); + } + } + + private static void addPolygonOnPlane(List[] shapes, int plane, int... coords) + { + Polygon poly = new Polygon(); + for (int i = 0; i < coords.length; i += 2) + { + poly.addPoint(coords[i], coords[i + 1]); + } + shapes[plane].add(poly); + } + + private static void addPolygonOnPlanes(List[] shapes, int minPlane, int maxPlane, int... coords) + { + Polygon poly = new Polygon(); + for (int i = 0; i < coords.length; i += 2) + { + poly.addPoint(coords[i], coords[i + 1]); + } + for (int i = minPlane; i <= maxPlane; i++) + { + shapes[i].add(poly); + } + } +} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsConfig.java new file mode 100644 index 0000000000..370533dac7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +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 +{ + @ConfigItem( + keyName = "multicombatZoneVisibility", + name = "Multicombat zones", + description = "Determine where multicombat zones should be shown", + position = 1 + ) + default ZoneVisibility multicombatZoneVisibility() + { + return ZoneVisibility.SHOW_IN_PVP; + } + + @ConfigItem( + keyName = "pvpSafeZones", + name = "PvP safe zones", + description = "Show safe zones in PvP worlds", + position = 2 + ) + default boolean showPvpSafeZones() + { + return true; + } + + @ConfigItem( + keyName = "deadmanSafeZones", + name = "Deadman safe zones", + description = "Show safe zones in Deadman worlds", + position = 3 + ) + default boolean showDeadmanSafeZones() + { + return true; + } + + @ConfigItem( + keyName = "collisionDetection", + name = "Collision detection", + description = "Only show lines where they can be walked through", + position = 4 + ) + default boolean collisionDetection() + { + return false; + } + + @ConfigItem( + keyName = "showMinimapLines", + name = "Show on minimap", + description = "Show multicombat and safe zones on the minimap", + position = 5 + ) + default boolean showMinimapLines() + { + return true; + } + + @ConfigItem( + keyName = "multicombatColor", + name = "Multicombat zone color", + description = "Choose color to use for marking multicombat zones", + position = 6 + ) + default Color multicombatColor() + { + return Color.MAGENTA; + } + + @ConfigItem( + keyName = "safeZoneColor", + name = "Safe zone color", + description = "Choose color to use for marking safe zones in PvP/Deadman", + position = 7 + ) + default Color safeZoneColor() + { + return Color.GREEN; + } +} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsMinimapOverlay.java new file mode 100644 index 0000000000..699b0f0ddf --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.geom.GeneralPath; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.geometry.Geometry; +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; + +public class ZoneIndicatorsMinimapOverlay extends Overlay +{ + private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; + + @Inject + private Client client; + + @Inject + private ZoneIndicatorsPlugin plugin; + + @Inject + private ZoneIndicatorsConfig config; + + @Inject + public ZoneIndicatorsMinimapOverlay() + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ALWAYS_ON_TOP); + setPriority(OverlayPriority.LOW); + } + + private Color getTransparentColorVersion(Color c) + { + return new Color(c.getRed(), c.getGreen(), c.getBlue(), 192); + } + + private void renderPath(Graphics2D graphics, GeneralPath path, Color color) + { + LocalPoint playerLp = client.getLocalPlayer().getLocalLocation(); + Rectangle viewArea = new Rectangle( + playerLp.getX() - MAX_LOCAL_DRAW_LENGTH, + playerLp.getY() - MAX_LOCAL_DRAW_LENGTH, + MAX_LOCAL_DRAW_LENGTH * 2, + MAX_LOCAL_DRAW_LENGTH * 2); + + graphics.setColor(color); + + path = Geometry.clipPath(path, viewArea); + path = Geometry.filterPath(path, (p1, p2) -> + Perspective.localToMinimap(client, new LocalPoint((int)p1[0], (int)p1[1])) != null && + Perspective.localToMinimap(client, new LocalPoint((int)p2[0], (int)p2[1])) != null); + path = Geometry.transformPath(path, coords -> + { + Point point = Perspective.localToMinimap(client, new LocalPoint((int)coords[0], (int)coords[1])); + coords[0] = point.getX(); + coords[1] = point.getY(); + }); + + graphics.draw(path); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!config.showMinimapLines()) + { + return null; + } + + GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()]; + GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()]; + + if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null) + { + renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor())); + } + if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null) + { + renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor())); + } + + return null; + } +} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsOverlay.java new file mode 100644 index 0000000000..0f52222e8b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.geom.GeneralPath; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.geometry.Geometry; +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; + +public class ZoneIndicatorsOverlay extends Overlay +{ + private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; + + @Inject + private Client client; + + @Inject + private ZoneIndicatorsPlugin plugin; + + @Inject + private ZoneIndicatorsConfig config; + + @Inject + public ZoneIndicatorsOverlay() + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + setPriority(OverlayPriority.LOW); + } + + private Color getTransparentColorVersion(Color c) + { + return new Color(c.getRed(), c.getGreen(), c.getBlue(), 92); + } + + private void renderPath(Graphics2D graphics, GeneralPath path, Color color) + { + LocalPoint playerLp = client.getLocalPlayer().getLocalLocation(); + Rectangle viewArea = new Rectangle( + playerLp.getX() - MAX_LOCAL_DRAW_LENGTH, + playerLp.getY() - MAX_LOCAL_DRAW_LENGTH, + MAX_LOCAL_DRAW_LENGTH * 2, + MAX_LOCAL_DRAW_LENGTH * 2); + + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2)); + + path = Geometry.clipPath(path, viewArea); + path = Geometry.filterPath(path, (p1, p2) -> + Perspective.localToCanvas(client, new LocalPoint((int)p1[0], (int)p1[1]), client.getPlane()) != null && + Perspective.localToCanvas(client, new LocalPoint((int)p2[0], (int)p2[1]), client.getPlane()) != null); + path = Geometry.transformPath(path, coords -> + { + Point point = Perspective.localToCanvas(client, new LocalPoint((int)coords[0], (int)coords[1]), client.getPlane()); + coords[0] = point.getX(); + coords[1] = point.getY(); + }); + + graphics.draw(path); + } + + @Override + public Dimension render(Graphics2D graphics) + { + GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()]; + GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()]; + + if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null) + { + renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor())); + } + if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null) + { + renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor())); + } + + return null; + } +} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsPlugin.java new file mode 100644 index 0000000000..5f3397e900 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import java.awt.Rectangle; +import java.awt.geom.GeneralPath; +import java.util.Arrays; +import javax.inject.Inject; +import lombok.Getter; +import net.runelite.api.Client; +import net.runelite.api.Constants; +import net.runelite.api.GameState; +import net.runelite.api.ObjectComposition; +import net.runelite.api.Perspective; +import net.runelite.api.Tile; +import net.runelite.api.WallObject; +import net.runelite.api.WorldType; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.geometry.Geometry; +import net.runelite.client.callback.ClientThread; +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; + +@PluginDescriptor( + name = "!MultiLines", + description = "Show borders of multicombat and PvP safezones", + tags = {"multicombat", "lines", "pvp", "deadman", "safezones", "bogla"}, + enabledByDefault = false +) +public class ZoneIndicatorsPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private ZoneIndicatorsConfig config; + + @Inject + private ZoneIndicatorsOverlay overlay; + + @Inject + private ZoneIndicatorsMinimapOverlay minimapOverlay; + + @Inject + private OverlayManager overlayManager; + + @Getter + private GeneralPath[] multicombatPathToDisplay; + + @Getter + private GeneralPath[] pvpPathToDisplay; + + @Getter + private boolean inPvp; + + @Getter + private boolean inDeadman; + + private int currentPlane; + + @Provides + ZoneIndicatorsConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(ZoneIndicatorsConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + overlayManager.add(minimapOverlay); + + multicombatPathToDisplay = new GeneralPath[Constants.MAX_Z]; + pvpPathToDisplay = new GeneralPath[Constants.MAX_Z]; + + clientThread.invokeLater(() -> + { + if (client.getGameState() == GameState.LOGGED_IN) + { + findLinesInScene(); + } + }); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + overlayManager.remove(minimapOverlay); + + multicombatPathToDisplay = null; + pvpPathToDisplay = null; + } + + private void transformWorldToLocal(float[] coords) + { + LocalPoint lp = LocalPoint.fromWorld(client, (int)coords[0], (int)coords[1]); + coords[0] = lp.getX() - Perspective.LOCAL_TILE_SIZE / 2; + coords[1] = lp.getY() - Perspective.LOCAL_TILE_SIZE / 2; + } + + private boolean isOpenableAt(WorldPoint wp) + { + int sceneX = wp.getX() - client.getBaseX(); + int sceneY = wp.getY() - client.getBaseY(); + + Tile tile = client.getScene().getTiles()[wp.getPlane()][sceneX][sceneY]; + if (tile == null) + { + return false; + } + + WallObject wallObject = tile.getWallObject(); + if (wallObject == null) + { + return false; + } + + ObjectComposition objectComposition = client.getObjectDefinition(wallObject.getId()); + if (objectComposition == null) + { + return false; + } + + String[] actions = objectComposition.getActions(); + if (actions == null) + { + return false; + } + + return Arrays.stream(actions).anyMatch(x -> x != null && x.toLowerCase().equals("open")); + } + + private boolean collisionFilter(float[] p1, float[] p2) + { + int x1 = (int)p1[0]; + int y1 = (int)p1[1]; + int x2 = (int)p2[0]; + int y2 = (int)p2[1]; + + if (x1 > x2) + { + int temp = x1; + x1 = x2; + x2 = temp; + } + if (y1 > y2) + { + int temp = y1; + y1 = y2; + y2 = temp; + } + int dx = x2 - x1; + int dy = y2 - y1; + WorldArea wa1 = new WorldArea(new WorldPoint( + x1, y1, currentPlane), 1, 1); + WorldArea wa2 = new WorldArea(new WorldPoint( + x1 - dy, y1 - dx, currentPlane), 1, 1); + + if (isOpenableAt(wa1.toWorldPoint()) || isOpenableAt(wa2.toWorldPoint())) + { + // When there's something with the open option (e.g. a door) on the tile, + // we assume it can be opened and walked through afterwards. Without this + // check, the line for that tile wouldn't render with collision detection + // because the collision check isn't done if collision data changes. + return true; + } + + boolean b1 = wa1.canTravelInDirection(client, -dy, -dx); + boolean b2 = wa2.canTravelInDirection(client, dy, dx); + return b1 && b2; + } + + private void findLinesInScene() + { + inDeadman = client.getWorldType().stream().anyMatch(x -> + x == WorldType.DEADMAN || x == WorldType.SEASONAL_DEADMAN); + inPvp = client.getWorldType().stream().anyMatch(x -> + x == WorldType.PVP || x == WorldType.PVP_HIGH_RISK); + + Rectangle sceneRect = new Rectangle( + client.getBaseX() + 1, client.getBaseY() + 1, + Constants.SCENE_SIZE - 2, Constants.SCENE_SIZE - 2); + + // Generate lines for multicombat zones + if (config.multicombatZoneVisibility() == ZoneVisibility.HIDE) + { + for (int i = 0; i < multicombatPathToDisplay.length; i++) + { + multicombatPathToDisplay[i] = null; + } + } + else + { + for (int i = 0; i < multicombatPathToDisplay.length; i++) + { + currentPlane = i; + + GeneralPath lines = new GeneralPath(MapLocations.getMulticombat(sceneRect, i)); + lines = Geometry.clipPath(lines, sceneRect); + if (config.multicombatZoneVisibility() == ZoneVisibility.SHOW_IN_PVP && + !isInDeadman() && !isInPvp()) + { + lines = Geometry.clipPath(lines, MapLocations.getRoughWilderness(i)); + } + lines = Geometry.splitIntoSegments(lines, 1); + if (config.collisionDetection()) + { + lines = Geometry.filterPath(lines, this::collisionFilter); + } + lines = Geometry.transformPath(lines, this::transformWorldToLocal); + multicombatPathToDisplay[i] = lines; + } + } + + // Generate safezone lines for deadman/pvp worlds + for (int i = 0; i < pvpPathToDisplay.length; i++) + { + currentPlane = i; + + GeneralPath safeZonePath = null; + if (config.showDeadmanSafeZones() && isInDeadman()) + { + safeZonePath = new GeneralPath(MapLocations.getDeadmanSafeZones(sceneRect, i)); + } + else if (config.showPvpSafeZones() && isInPvp()) + { + safeZonePath = new GeneralPath(MapLocations.getPvpSafeZones(sceneRect, i)); + } + if (safeZonePath != null) + { + safeZonePath = Geometry.clipPath(safeZonePath, sceneRect); + safeZonePath = Geometry.splitIntoSegments(safeZonePath, 1); + if (config.collisionDetection()) + { + safeZonePath = Geometry.filterPath(safeZonePath, this::collisionFilter); + } + safeZonePath = Geometry.transformPath(safeZonePath, this::transformWorldToLocal); + } + pvpPathToDisplay[i] = safeZonePath; + } + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getKey().equals("collisionDetection") || + event.getKey().equals("multicombatZoneVisibility") || + event.getKey().equals("deadmanSafeZones") || + event.getKey().equals("pvpSafeZones")) + { + findLinesInScene(); + } + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOGGED_IN) + { + findLinesInScene(); + } + } +} 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/zoneIndicators/ZoneVisibility.java new file mode 100644 index 0000000000..9a457d9e50 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum ZoneVisibility +{ + HIDE("Hide"), + SHOW_IN_PVP("Show in PvP"), + SHOW_EVERYWHERE("Show everywhere"); + + private final String visibility; + + @Override + public String toString() + { + return visibility; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java new file mode 100644 index 0000000000..6f63951785 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java @@ -0,0 +1,138 @@ +/* + * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI + * No rights reserved. Use, redistribute, and modify at your own discretion, + * and in accordance with Yagex and RuneLite guidelines. + * However, aforementioned monkey would prefer if you don't sell this plugin for profit. + * Good luck on your raids! + */ + +package net.runelite.client.plugins.ztob; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("Theatre") + +public interface TheatreConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "MaidenBlood", + name = "Maiden blood attack", + description = "" + ) + default boolean MaidenBlood(){ return false; } + + @ConfigItem( + position = 1, + keyName = "MaidenSpawns", + name = "Maiden blood spawns", + description = "" + ) + default boolean MaidenSpawns(){ return false; } + + @ConfigItem( + position = 2, + keyName = "BloatIndicator", + name = "Bloat indicator", + description = "" + ) + default boolean BloatIndicator(){ return false; } + + @ConfigItem( + position = 3, + keyName = "BloatHands", + name = "Bloat Falling Hands", + description = "" + ) + default boolean BloatHands(){ return false; } + + @ConfigItem( + position = 4, + keyName = "NyloPillars", + name = "Nylocas pillar health", + description = "" + ) + default boolean NyloPillars(){ return false; } + + @ConfigItem( + position = 5, + keyName = "NyloBlasts", + name = "Nylocas explosions", + description = "" + ) + default boolean NyloBlasts(){ return false; } + + @ConfigItem( + position = 6, + keyName = "SotetsegMaze1", + name = "Sotetseg maze", + description = "" + ) + default boolean SotetsegMaze1(){ return false; } + + @ConfigItem( + position = 7, + keyName = "SotetsegMaze2", + name = "Sotetseg maze (solo mode)", + description = "" + ) + default boolean SotetsegMaze2(){ return false; } + + @ConfigItem( + position = 8, + keyName = "SotetsegTick", + name = "Sotetseg tick eat", + description = "" + ) + default boolean SotetsegTick(){ return false; } + + @ConfigItem( + position = 9, + keyName = "XarpusExhumed", + name = "Xarpus exhumed", + description = "" + ) + default boolean XarpusExhumed(){ return false; } + + @ConfigItem( + position = 10, + keyName = "XarpusTick", + name = "Xarpus tick", + description = "" + ) + default boolean XarpusTick(){ return false; } + + @ConfigItem( + position = 11, + keyName = "VerzikCupcakes", + name = "Verzik cupcakes", + description = " " + ) + default boolean VerzikCupcakes(){ return false; } + + @ConfigItem( + position = 12, + keyName = "VerzikTick", + name = "Verzik p3 tick", + description = "" + ) + default boolean VerzikTick(){ return false; } + + @ConfigItem( + position = 13, + keyName = "VerzikMelee", + name = "Verzik p3 melee range", + description = "" + ) + default boolean VerzikMelee(){ return false; } + + @ConfigItem( + position = 14, + keyName = "VerzikYellow", + name = "Verzik yellow timing", + description = "" + ) + default boolean VerzikYellow(){ return false; } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java new file mode 100644 index 0000000000..07f8e2f7b4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java @@ -0,0 +1,347 @@ +/* + * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI + * No rights reserved. Use, redistribute, and modify at your own discretion, + * and in accordance with Yagex and RuneLite guidelines. + * However, aforementioned monkey would prefer if you don't sell this plugin for profit. + * Good luck on your raids! + */ + +package net.runelite.client.plugins.ztob; + +import java.awt.*; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; + +import net.runelite.api.*; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.OverlayUtil; + +public class TheatreOverlay extends Overlay { + private final Client client; + + + private final TheatrePlugin plugin; + private final TheatreConfig config; + + @Inject + private TheatreOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) { + this.client = client; + this.plugin = plugin; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (plugin.isRunMaiden()) + { + if (config.MaidenBlood()) + { + for (WorldPoint point : plugin.getMaiden_BloodSpatters()) + { + drawTile(graphics, point, new Color(0,150,200), 2, 150, 10); + } + } + + if (config.MaidenSpawns()) + { + for (WorldPoint point : plugin.getMaiden_SpawnLocations()) + { + drawTile(graphics, point, new Color(0,150,200), 2, 180, 20); + } + for (WorldPoint point : plugin.getMaiden_SpawnLocations2()) + { + drawTile(graphics, point, new Color(0,150,200), 1,120, 10); + } + } + } + + if (plugin.isRunBloat()) + { + + if (config.BloatHands()) + { + for (WorldPoint p : plugin.getBloat_Hands()) + { + drawTile(graphics, p, Color.BLACK,3,255,0); + } + } + if(config.BloatIndicator()) { + NPC bloat = plugin.getBloat_NPC(); + int state = plugin.getBloat_State(); + if (bloat == null) { + return null; + } + switch (state) { + case 2: + renderNpcOverlay(graphics, bloat, Color.GREEN, 3, 150, 0); + break; + case 3: + renderNpcOverlay(graphics, bloat, Color.YELLOW, 3, 150, 0); + break; + default: + renderNpcOverlay(graphics, bloat, new Color(223, 109, 255), 3, 150, 0); + break; + } + } + } + + if (plugin.isRunNylocas()) + { + if (config.NyloPillars()) + { + Map pillars = plugin.getNylocas_Pillars(); + for (NPC npc : pillars.keySet()) { + final int health = pillars.get(npc); + final String healthStr = String.valueOf(health) + "%"; + WorldPoint p = npc.getWorldLocation(); + LocalPoint lp = LocalPoint.fromWorld(client, p.getX() + 1, p.getY() + 1); + final double rMod = 130.0 * health / 100.0; + final double gMod = 255.0 * health / 100.0; + final double bMod = 125.0 * health / 100.0; + final Color c = new Color((int) (255 - rMod), (int) (0 + gMod), (int) (0 + bMod)); + Point canvasPoint = Perspective.localToCanvas(client, lp, client.getPlane(), + 65); + renderTextLocation(graphics, healthStr, 13, Font.BOLD, c, canvasPoint); + } + } + + if (config.NyloBlasts()) + { + final Map npcMap = plugin.getNylocas_Map(); + for (NPC npc : npcMap.keySet()) + { + int ticksLeft = npcMap.get(npc); + if (ticksLeft > -1) { + if (ticksLeft <= 6) { + Color color = new Color(255, 255,0 ,180); + int outlineWidth = 2; + int outlineAlpha = 150; + renderNpcOverlay(graphics, npc, color, outlineWidth, outlineAlpha, 0); + } + } + } + } + } + + if (plugin.isRunSotetseg()) + { + if (config.SotetsegMaze1()) + { + int i = 1; + for (GroundObject z : plugin.getRedTiles().keySet()) + { + Polygon poly = z.getCanvasTilePoly(); + if (poly != null) + { + graphics.setColor(Color.WHITE); + graphics.setStroke(new BasicStroke(2)); + graphics.draw(poly); + } + Point textLocation = z.getCanvasTextLocation(graphics, String.valueOf(i), 0); + if (textLocation != null) + { + OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(i), Color.WHITE); + } + + i++; + } + } + + if (config.SotetsegMaze2()) + { + for (WorldPoint p : plugin.getRedTilesOverworld()) + { + drawTile(graphics, p, Color.WHITE, 2, 255, 10); + } + } + if (config.SotetsegTick()) { + NPC boss = plugin.getSotetseg_NPC(); + int eattick = plugin.getTickTillEat(); + if (eattick > -1) + { + final String eatTicksStr = String.valueOf(eattick); + Point canvasPoint = boss.getCanvasTextLocation(graphics, eatTicksStr, 130); + renderTextLocation(graphics, eatTicksStr, 12, Font.BOLD, Color.WHITE, canvasPoint); + + } + } + } + + + + if (plugin.isRunXarpus()) + { + NPC boss = plugin.getXarpus_NPC(); + + if (boss.getId() == NpcID.XARPUS_8340 && !plugin.isXarpus_Stare() && config.XarpusTick()) + { + int tick = plugin.getXarpus_TicksUntilShoot(); + if (tick < 1) + { + tick = tick % 4 + 4; + } + final String ticksLeftStr = String.valueOf(tick); + Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 130); + renderTextLocation(graphics, ticksLeftStr, 12, Font.BOLD, Color.WHITE, canvasPoint); + } + if (boss.getId() == NpcID.XARPUS_8339 && config.XarpusExhumed()) + { + for (GroundObject o : plugin.getXarpus_Exhumeds().keySet()) + { + Polygon poly = o.getCanvasTilePoly(); + if (poly != null) + { + graphics.setColor(new Color(0, 255, 0, 130)); + graphics.setStroke(new BasicStroke(1)); + graphics.draw(poly); + } + } + } + } + + if (plugin.isRunVerzik()) + { + if (config.VerzikCupcakes()) + { + for (WorldPoint p : plugin.getVerzik_RangeProjectiles().values()) + { + drawTile(graphics, p, Color.RED, 2, 180, 50); + } + } + + if (config.VerzikYellow()) + { + for (WorldPoint p : plugin.getVerzik_YellowTiles()) + { + drawTile(graphics, p, Color.YELLOW,3,255,0); + + Projectile yellowBall = plugin.getVerzik_YellowBall(); + if (yellowBall != null) + { + final int ticksToImpact = yellowBall.getRemainingCycles()/30; + final String countdownStr = String.valueOf(ticksToImpact); + Point canvasPoint = Perspective.getCanvasTextLocation(client, graphics, LocalPoint.fromWorld(client, p), countdownStr, 0); + renderTextLocation(graphics, countdownStr, 12, Font.BOLD, Color.WHITE, canvasPoint); + } + } + } + if (plugin.getVerzik_NPC_P3() != null) { + final NPC boss = plugin.getVerzik_NPC_P3(); + if (boss.getId() == NpcID.VERZIK_VITUR_8374) + { + if (config.VerzikTick()) + { + final int ticksLeft = plugin.getP3_TicksUntilAttack(); + if (ticksLeft > 0 && ticksLeft < 8) + { + final String ticksLeftStr = String.valueOf(ticksLeft); + Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); + renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); + } + } + + if (config.VerzikMelee() && boss.getAnimation() != 8127) + { + List meleeRange = getHitSquares(boss.getWorldLocation(), 7, 1, false); + + for (WorldPoint p : meleeRange) + { + drawTile(graphics, p, Color.WHITE, 1,155, 10); + } + } + } + } + } + return null; + } + + private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) { + WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); + if (point.distanceTo(playerLocation) >= 32) { + return; + } + LocalPoint lp = LocalPoint.fromWorld(client, point); + if (lp == null) { + return; + } + + Polygon poly = Perspective.getCanvasTilePoly(client, lp); + if (poly == null) { + return; + } + //OverlayUtil.renderPolygon(graphics, poly, color); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); + graphics.setStroke(new BasicStroke(strokeWidth)); + graphics.draw(poly); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); + graphics.fill(poly); + } + + private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha) + { + int size = 1; + NPCComposition composition = actor.getTransformedComposition(); + if (composition != null) + { + size = composition.getSize(); + } + LocalPoint lp = actor.getLocalLocation(); + Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size); + + if (tilePoly != null) + { + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); + graphics.setStroke(new BasicStroke(outlineWidth)); + graphics.draw(tilePoly); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); + graphics.fill(tilePoly); + } + } + + private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) + { + graphics.setFont(new Font("Arial", fontStyle, fontSize)); + if (canvasPoint != null) + { + final Point canvasCenterPoint = new Point( + canvasPoint.getX(), + canvasPoint.getY()); + final Point canvasCenterPoint_shadow = new Point( + canvasPoint.getX() + 1, + canvasPoint.getY() + 1) ; + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); + } + } + + private List getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder) + { + List little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList(); + List big = new WorldArea(npcLoc.getX()-thickness, npcLoc.getY()-thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList(); + if (!includeUnder) + { + for (Iterator it = big.iterator(); it.hasNext();) + { + WorldPoint p = it.next(); + if (little.contains(p)) + { + it.remove(); + } + } + } + return big; + } +} 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 new file mode 100644 index 0000000000..8fa2ee2481 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java @@ -0,0 +1,766 @@ +/* + * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI + * No rights reserved. Use, redistribute, and modify at your own discretion, + * and in accordance with Yagex and RuneLite guidelines. + * However, aforementioned monkey would prefer if you don't sell this plugin for profit. + * Good luck on your raids! + */ + +package net.runelite.client.plugins.ztob; + +import java.util.*; +import java.util.Iterator; +import javax.inject.Inject; + +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.*; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.*; +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; + +@PluginDescriptor( + name = "!Theatre of Blood", + description = "All-in-one plugin for Theatre of Blood", + tags = {"ToB"}, + enabledByDefault = false +) + +public class TheatrePlugin extends Plugin { + private static final int GRAPHICSOBJECT_ID_MAIDEN = 1579; + private static final int NPCID_NYLOCAS_PILLAR = 8358; + private static final int GROUNDOBJECT_ID_BLACKMAZE = 33034; + private static final int GROUNDOBJECT_ID_REDMAZE = 33035; + private static final int GROUNDOBJECT_ID_EXHUMED = 32743; + private static final int ANIMATION_ID_XARPUS = 8059; + private static final int GRAPHICSOBJECT_ID_YELLOW = 1595; + private static final int GRAPHICSOBJECT_ID_BLOAT_HAND1 = 1570; + private static final int GRAPHICSOBJECT_ID_BLOAT_HAND2 = 1571; + private static final int GRAPHICSOBJECT_ID_BLOAT_HAND3 = 1572; + private static final int GRAPHICSOBJECT_ID_BLOAT_HAND4 = 1573; + private static final int GRAPHICSOBJECT_ID_BLOAT_HAND5 = 1576; + private static final int PROJECTILE_ID_P2RANGE = 1583; + private static final int PROJECTILE_ID_YELLOW = 1596; + private static final int ANIMATION_ID_P3_WEB = 8127; + private static final int ANIMATION_ID_P3_YELLOW = 8126; + private static final int ANIMATION_ID_P3_MELEE = 8123; + private static final int ANIMATION_ID_P3_MAGE = 8124; + private static final int ANIMATION_ID_P3_RANGE = 8125; + private static final int VERZIK_ID_P3 = NpcID.VERZIK_VITUR_8374; + private static final int NPC_ID_TORNADO = 8386; + private static final int PROJECTILE_ID_P3_GREEN = 1598; + private static final String sotmsg = "A large ball of energy is shot your way..."; + private static final String sotmsg1 = "A large ball of energy is shot your way..."; + + @Inject + private ChatMessageManager chatMessageManager; + + @Getter(AccessLevel.PACKAGE) + private boolean runMaiden; + + @Getter(AccessLevel.PACKAGE) + private List Maiden_BloodSpatters = new ArrayList<>(); + + private List Maiden_Spawns = new ArrayList<>(); + + @Getter(AccessLevel.PACKAGE) + private List Maiden_SpawnLocations = new ArrayList<>(); + + @Getter(AccessLevel.PACKAGE) + private List Maiden_SpawnLocations2 = new ArrayList<>(); + + + @Getter(AccessLevel.PACKAGE) + private boolean runBloat; + + @Getter(AccessLevel.PACKAGE) + private int TickTillEat = 20; + + @Getter(AccessLevel.PACKAGE) + private NPC Bloat_NPC; + + private int Bloat_downCount; + + @Getter(AccessLevel.PACKAGE) + private Integer Bloat_State; + + + @Getter(AccessLevel.PACKAGE) + private boolean runNylocas; + + @Getter(AccessLevel.PACKAGE) + private Map Nylocas_Pillars = new HashMap<>(); + + @Getter(AccessLevel.PACKAGE) + private Map Nylocas_Map = new HashMap<>(); + + + @Getter(AccessLevel.PACKAGE) + private boolean runSotetseg; + + @Getter(AccessLevel.PACKAGE) + private final Map RedTiles = new LinkedHashMap<>(); + + @Getter(AccessLevel.PACKAGE) + private List RedTilesOverworld = new ArrayList<>(); + + private List BlackTilesOverworld = new ArrayList<>(); + + private List BlackTilesUnderworld= new ArrayList<>(); + + private List RedTilesUnderworld= new ArrayList<>(); + + private List GridPath = new ArrayList<>(); + + @Getter(AccessLevel.PACKAGE) + private boolean runXarpus; + + private int Xarpus_previousAnimation; + + @Getter(AccessLevel.PACKAGE) + private boolean Xarpus_Stare; + + @Getter(AccessLevel.PACKAGE) + private final Map Xarpus_Exhumeds = new HashMap<>(); + + @Getter(AccessLevel.PACKAGE) + private int Xarpus_TicksUntilShoot = 9; + + @Getter(AccessLevel.PACKAGE) + private NPC Xarpus_NPC; + + @Getter(AccessLevel.PACKAGE) + private NPC Sotetseg_NPC; + + @Getter(AccessLevel.PACKAGE) + private boolean runVerzik; + + @Getter(AccessLevel.PACKAGE) + private final Map Verzik_RangeProjectiles = new HashMap<>(); + + @Getter(AccessLevel.PACKAGE) + private int P3_TicksUntilAttack = -1; + + @Getter(AccessLevel.PACKAGE) + private Projectile Verzik_YellowBall; + + @Getter(AccessLevel.PACKAGE) + private List Verzik_YellowTiles = new ArrayList<>(); + + @Getter(AccessLevel.PACKAGE) + private List Bloat_Hands = new ArrayList<>(); + + @Getter(AccessLevel.PACKAGE) + private NPC Verzik_NPC; + + @Getter(AccessLevel.PACKAGE) + private NPC Verzik_NPC_P3; + + @Getter(AccessLevel.PACKAGE) + private NPC Verzik_NPC_P2; + + private int P3_attacksLeft; + + @Inject + private Client client; + + @Inject + private OverlayManager overlayManager; + + @Inject + private TheatreOverlay overlay; + + @Inject + private TheatreConfig config; + + @Provides + TheatreConfig getConfig(ConfigManager configManager) { + return configManager.getConfig(TheatreConfig.class); + } + + @Override + protected void startUp() { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() { + overlayManager.remove(overlay); + } + + @Subscribe + public void onNpcSpawned(NpcSpawned npcSpawned) + { + NPC npc = npcSpawned.getNpc(); + switch (npc.getId()) + { + case NpcID.THE_MAIDEN_OF_SUGADINTI: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8361: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8362: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8363: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8364: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8365: + runMaiden = true; + break; + case NpcID.BLOOD_SPAWN: + Maiden_Spawns.add(npc); + break; + case NpcID.PESTILENT_BLOAT: + runBloat = true; + Bloat_NPC = npc; + break; + case NPCID_NYLOCAS_PILLAR: + runNylocas = true; + if (!Nylocas_Pillars.keySet().contains(npc)) + { + Nylocas_Pillars.put(npc, 100); + } + break; + case 8342: case 8343: case 8344: case 8345: case 8346: case 8347: + case 8348: case 8349: case 8350: case 8351: case 8352: case 8353: + if (runNylocas) + { + Nylocas_Map.put(npc, 52); + } + break; + case NpcID.SOTETSEG: + case NpcID.SOTETSEG_8388: + runSotetseg = true; + Sotetseg_NPC = npc; + RedTiles.clear(); + break; + case NpcID.XARPUS: + case NpcID.XARPUS_8339: + case NpcID.XARPUS_8340: + case NpcID.XARPUS_8341: + runXarpus = true; + Xarpus_NPC = npc; + Xarpus_Stare = false; + Xarpus_TicksUntilShoot = 9; + Xarpus_previousAnimation = -1; + break; + case NpcID.VERZIK_VITUR_8369: + case NpcID.VERZIK_VITUR_8370: + case NpcID.VERZIK_VITUR_8371: + case NpcID.VERZIK_VITUR_8373: + case NpcID.VERZIK_VITUR_8375: + Verzik_NPC = npc; + runVerzik = true; + break; + + case NpcID.VERZIK_VITUR_8372:/*p2 spider*/ + Verzik_NPC_P2 = npc; + runVerzik = true; + break; + + case NpcID.VERZIK_VITUR_8374:/*p3 spider*/ + P3_TicksUntilAttack = 0; + P3_attacksLeft = 9; + Verzik_NPC_P3 = npc; + runVerzik = true; + break; + } + } + + @Subscribe + public void onNpcDespawned(NpcDespawned npcDespawned) { + NPC npc = npcDespawned.getNpc(); + switch (npc.getId()) { + case NpcID.THE_MAIDEN_OF_SUGADINTI: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8361: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8362: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8363: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8364: + case NpcID.THE_MAIDEN_OF_SUGADINTI_8365: + runMaiden = false; + Maiden_Spawns.clear(); + break; + case NpcID.BLOOD_SPAWN: + Maiden_Spawns.remove(npc); + break; + case NpcID.PESTILENT_BLOAT: + runBloat = false; + Bloat_NPC = null; + break; + case NPCID_NYLOCAS_PILLAR: + if (Nylocas_Pillars.keySet().contains(npc)) + { + Nylocas_Pillars.remove(npc); + } + break; + case 8342: case 8343: case 8344: case 8345: case 8346: case 8347: + case 8348: case 8349: case 8350: case 8351: case 8352: case 8353: + if (Nylocas_Map.keySet().contains(npc)) + { + Nylocas_Map.remove(npc); + } + break; + case NpcID.SOTETSEG: + case NpcID.SOTETSEG_8388: + RedTiles.clear(); + if (client.getPlane() != 3) + { + runSotetseg = false; + } + Sotetseg_NPC = null; + break; + case NpcID.XARPUS: + case NpcID.XARPUS_8339: + case NpcID.XARPUS_8340: + case NpcID.XARPUS_8341: + runXarpus = false; + Xarpus_NPC = null; + Xarpus_Stare = false; + Xarpus_TicksUntilShoot = 9; + Xarpus_previousAnimation = -1; + Xarpus_Exhumeds.clear(); + break; + case NpcID.VERZIK_VITUR_8369: + case NpcID.VERZIK_VITUR_8370: + case NpcID.VERZIK_VITUR_8371:/*p2*/ + + case NpcID.VERZIK_VITUR_8373: + + case NpcID.VERZIK_VITUR_8375: + Verzik_NPC = null; + break; + case NpcID.VERZIK_VITUR_8372: + Verzik_NPC_P2 = null; + break; + case NpcID.VERZIK_VITUR_8374:/*p3 spider*/ + Verzik_NPC_P3 = null; + break; + + } + + } + + @Subscribe + public void onGroundObjectSpawned(GroundObjectSpawned event) + { + if (runSotetseg) + { + GroundObject o = event.getGroundObject(); + if (o.getId() == GROUNDOBJECT_ID_BLACKMAZE) + { + Tile t = event.getTile(); + WorldPoint p = t.getWorldLocation(); + if (t.getPlane() == 0) + { + if (!BlackTilesOverworld.contains(p)) + BlackTilesOverworld.add(p); + } + else + { + if (!BlackTilesUnderworld.contains(p)) + BlackTilesUnderworld.add(p); + } + } + + if (o.getId() == GROUNDOBJECT_ID_REDMAZE) + { + Tile t = event.getTile(); + WorldPoint p = t.getWorldLocation(); + if (p.getPlane() == 0) + { + if (!RedTiles.containsValue(t)) + { + RedTiles.put(o,t); + } + } + else + { + if (!RedTilesUnderworld.contains(p)) + RedTilesUnderworld.add(p); + } + } + } + + if (runXarpus) + { + GroundObject o = event.getGroundObject(); + if (o.getId() == GROUNDOBJECT_ID_EXHUMED) + { + Xarpus_Exhumeds.put(o, 18); + } + } + } + + @Subscribe + public void onProjectileMoved(ProjectileMoved event) + { + if (runVerzik) + { + Projectile projectile = event.getProjectile(); + if (projectile.getId() == PROJECTILE_ID_P2RANGE) + { + WorldPoint p = WorldPoint.fromLocal(client,event.getPosition()); + Verzik_RangeProjectiles.put(projectile, p); + } + } + } + + @Subscribe + public void onChatMessage(ChatMessage chatMessage) + { + MessageNode messageNode = chatMessage.getMessageNode(); + + if (messageNode.getValue().toLowerCase().contains(sotmsg.toLowerCase())) + { + TickTillEat = 20; + /*20 ticks*/ + + } + + + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (runMaiden) + { + Maiden_BloodSpatters.clear(); + for (GraphicsObject o : client.getGraphicsObjects()) + { + if (o.getId() == GRAPHICSOBJECT_ID_MAIDEN) + { + Maiden_BloodSpatters.add(WorldPoint.fromLocal(client, o.getLocation())); + } + } + + Maiden_SpawnLocations2.clear(); + Maiden_SpawnLocations2.addAll(Maiden_SpawnLocations); + Maiden_SpawnLocations.clear(); + for (NPC spawn : Maiden_Spawns) + { + Maiden_SpawnLocations.add(spawn.getWorldLocation()); + } + } + + if (runBloat) + { + + Bloat_downCount++; + + Bloat_Hands.clear(); + for (GraphicsObject o : client.getGraphicsObjects()) + { + if (o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND1 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND2 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND3 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND4|| o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND5) + { + Bloat_Hands.add(WorldPoint.fromLocal(client, o.getLocation())); + } + } + + + if (Bloat_NPC.getAnimation() == -1) //1 = up; 2 = down; 3 = warn; + { + Bloat_downCount = 0; + if (Bloat_NPC.getHealth() == 0) + { + Bloat_State = 2; + } + else + Bloat_State = 1; + } + else + { + if (25 it = Nylocas_Map.keySet().iterator(); it.hasNext();) + { + NPC npc = it.next(); + int ticksLeft = Nylocas_Map.get(npc); + + if (ticksLeft < 0) + { + it.remove(); + continue; + } + Nylocas_Map.replace(npc, ticksLeft - 1); + } + + for (NPC pillar : Nylocas_Pillars.keySet()) + { + int healthPercent = pillar.getHealthRatio(); + if (healthPercent > -1) + { + Nylocas_Pillars.replace(pillar, healthPercent); + } + } + for (NPC npc : client.getNpcs()) + { + if (npc.getId() == 8358) + { + runNylocas = true; + break; + } + runNylocas = false; + } + } + + if (runSotetseg) + { + TickTillEat--; + boolean sotetsegFighting = false; + for (NPC npc : client.getNpcs()) + { + if (npc.getId() == NpcID.SOTETSEG_8388) + { + BlackTilesUnderworld.clear(); + BlackTilesOverworld.clear(); + RedTilesOverworld.clear(); + RedTilesUnderworld.clear(); + GridPath.clear(); + sotetsegFighting = true; + RedTiles.clear(); + break; + } + } + + if (!sotetsegFighting) + { + if (!BlackTilesUnderworld.isEmpty() && !RedTilesUnderworld.isEmpty() && GridPath.isEmpty()) + { + int minX = 99999; + int minY = 99999; + for (WorldPoint p : BlackTilesUnderworld) + { + int x = p.getX(); + int y = p.getY(); + if (x < minX) + { + minX = x; + } + if (y < minY) + { + minY = y; + } + } + + + + boolean messageSent = false; + for (WorldPoint p : RedTilesUnderworld) + { + WorldPoint pN = new WorldPoint(p.getX(), p.getY() + 1, p.getPlane()); + WorldPoint pS = new WorldPoint(p.getX(), p.getY() - 1, p.getPlane()); + WorldPoint pE = new WorldPoint(p.getX() + 1, p.getY(), p.getPlane()); + WorldPoint pW = new WorldPoint(p.getX() - 1, p.getY(), p.getPlane()); + + if ( !( (RedTilesUnderworld.contains(pN) && RedTilesUnderworld.contains(pS)) || + (RedTilesUnderworld.contains(pE) && RedTilesUnderworld.contains(pW)) ) ) + { + GridPath.add(new Point(p.getX() - minX, p.getY() - minY)); + if (!messageSent) + { + //client.addChatMessage(ChatMessageType.SERVER, "", "Maze path acquired.", null); + messageSent = true; + } + } + + } + } + + if (!BlackTilesOverworld.isEmpty() && !GridPath.isEmpty() && RedTilesOverworld.isEmpty()) + { + int minX = 99999; + int minY = 99999; + for (WorldPoint p : BlackTilesOverworld) + { + int x = p.getX(); + int y = p.getY(); + if (x < minX) + { + minX = x; + } + if (y < minY) + { + minY = y; + } + } + for (Point p : GridPath) + { + RedTilesOverworld.add(new WorldPoint(minX + p.getX(), minY + p.getY(), 0)); + } + } + } + } + + if (runXarpus) + { + for (Iterator it = Xarpus_Exhumeds.keySet().iterator(); it.hasNext();) + { + GroundObject key = it.next(); + Xarpus_Exhumeds.replace(key, Xarpus_Exhumeds.get(key) - 1); + if (Xarpus_Exhumeds.get(key) < 0) + { + it.remove(); + } + } + if (Xarpus_NPC.getOverheadText() != null ) + { + Xarpus_Stare = true; + } + if (Xarpus_Stare) + { + //dont hit xarpus if it looking at u + } + else if (Xarpus_NPC.getId() == NpcID.XARPUS_8340) + { + Xarpus_TicksUntilShoot--; + if (Xarpus_NPC.getAnimation() == ANIMATION_ID_XARPUS && Xarpus_previousAnimation != ANIMATION_ID_XARPUS) + { + Xarpus_TicksUntilShoot = 3; + } + Xarpus_previousAnimation = Xarpus_NPC.getAnimation(); + } + + } + + if (runVerzik) + { + if (!Verzik_RangeProjectiles.isEmpty()) + { + for (Iterator it = Verzik_RangeProjectiles.keySet().iterator(); it.hasNext();) + { + Projectile projectile = it.next(); + if (projectile.getRemainingCycles() < 1) + { + it.remove(); + } + } + } + + Verzik_YellowBall = null; + Verzik_YellowTiles.clear(); + + for (Projectile projectile : client.getProjectiles()) + { + if (projectile.getId() == PROJECTILE_ID_YELLOW) + { + Verzik_YellowBall = projectile; + break; + } + } + for (GraphicsObject o : client.getGraphicsObjects()) + { + if (o.getId() == GRAPHICSOBJECT_ID_YELLOW) + { + Verzik_YellowTiles.add(WorldPoint.fromLocal(client, o.getLocation())); + } + } + + for (NPC npc : client.getNpcs()) + { + if (npc.getId() == 8379) + { + runVerzik = true; + break; + } + runVerzik = false; + } + + + if (Verzik_NPC_P3 != null) { + boolean tornadosActive = false; + for (NPC npc : client.getNpcs()) + { + if (npc.getId() == NPC_ID_TORNADO) + { + tornadosActive = true; + break; + } + } + + boolean isGreenBall = false; + for (Projectile projectile : client.getProjectiles()) + { + if (projectile.getId() == PROJECTILE_ID_P3_GREEN) { + isGreenBall = projectile.getRemainingCycles() > 210; + break; + } + } + P3_TicksUntilAttack--; + + switch (Verzik_NPC_P3.getAnimation()) { + case ANIMATION_ID_P3_MAGE: + if (P3_TicksUntilAttack < 2) { + P3_attacksLeft--; + if (tornadosActive) { + P3_TicksUntilAttack = 5; + } else { + P3_TicksUntilAttack = 7; + } + if (P3_attacksLeft < 1) { + P3_TicksUntilAttack = 24; + } + } + break; + case ANIMATION_ID_P3_RANGE: + if (P3_TicksUntilAttack < 2) { + P3_attacksLeft--; + if (tornadosActive) { + P3_TicksUntilAttack = 5; + } else { + P3_TicksUntilAttack = 7; + } + if (P3_attacksLeft < 1) { + P3_TicksUntilAttack = 30; + } + if (isGreenBall) { + P3_TicksUntilAttack = 12; + } + } + break; + case ANIMATION_ID_P3_MELEE: + if (P3_TicksUntilAttack < 2) { + P3_attacksLeft--; + if (tornadosActive) { + P3_TicksUntilAttack = 5; + } else { + P3_TicksUntilAttack = 7; + } + if (P3_attacksLeft < 1) { + P3_TicksUntilAttack = 24; + } + } + break; + case ANIMATION_ID_P3_WEB: + P3_attacksLeft = 4; + P3_TicksUntilAttack = 11; // + break; + case ANIMATION_ID_P3_YELLOW: + P3_attacksLeft = 14; + P3_TicksUntilAttack = 11; + break; + } + } + + } + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahConfig.java new file mode 100644 index 0000000000..5e18ef4fc3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahConfig.java @@ -0,0 +1,24 @@ +package net.runelite.client.plugins.zulrah; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("zulrah") +public interface ZulrahConfig extends Config { + @ConfigItem( + position = 0, + keyName = "zulrahenable", + name = "Enable Zulrah Helper", + description = "Configures whether or not to enable Zulrah Helper." + ) + default boolean EnableZulrah() { return true; } + + @ConfigItem( + position = 1, + keyName = "zulrahprayenable", + name = "Show Prayer Helper", + description = "Configures whether or not to show when to pray at Zulrah." + ) + default boolean EnableZulrahPrayerHelper() { return true; } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahOverlay.java new file mode 100644 index 0000000000..ed2dd23991 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahOverlay.java @@ -0,0 +1,72 @@ +package net.runelite.client.plugins.zulrah; + +import java.awt.*; +import javax.inject.Inject; + +import net.runelite.api.*; +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.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +public class ZulrahOverlay extends Overlay { + private final ZulrahConfig config; + private final ZulrahPlugin plugin; + private final PanelComponent panelComponent = new PanelComponent(); + + + @Inject + private Client client; + + @Inject + private ZulrahOverlay(ZulrahConfig config, ZulrahPlugin plugin) { + this.config = config; + this.plugin = plugin; + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.MED); + panelComponent.setPreferredSize(new Dimension(150, 0)); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (!config.EnableZulrahPrayerHelper()) { + return null; + } + NPC Zulrah = plugin.Zulrah; + if (Zulrah != null) { + if (plugin.prayerconserve && plugin.nextprayerendticks == 0) { + Player player = client.getLocalPlayer(); + HeadIcon icon = player.getOverheadIcon(); + if (icon != null) { + final String text = "Disable Overhead Prayer"; + final int textWidth = graphics.getFontMetrics().stringWidth(text); + final int textHeight = graphics.getFontMetrics().getAscent() - graphics.getFontMetrics().getDescent(); + final int width = (int) client.getRealDimensions().getWidth(); + java.awt.Point jpoint = new java.awt.Point((width / 2) - textWidth, textHeight + 75); + panelComponent.getChildren().clear(); + panelComponent.getChildren().add(TitleComponent.builder().text(text).color(Color.RED).build()); + panelComponent.setPreferredLocation(jpoint); + panelComponent.render(graphics); + } + } else if (plugin.nextprayerendticks != 0) { + Player player = client.getLocalPlayer(); + HeadIcon icon = player.getOverheadIcon(); + if (icon == null) { + final String text = "Protect from MAGIC: " + (plugin.nextprayerendticks - plugin.ticks); + final int textWidth = graphics.getFontMetrics().stringWidth(text); + final int textHeight = graphics.getFontMetrics().getAscent() - graphics.getFontMetrics().getDescent(); + final int width = (int) client.getRealDimensions().getWidth(); + java.awt.Point jpoint = new java.awt.Point((width / 2) - textWidth, textHeight + 75); + panelComponent.getChildren().clear(); + panelComponent.getChildren().add(TitleComponent.builder().text(text).color(Color.GREEN).build()); + panelComponent.setPreferredLocation(jpoint); + panelComponent.render(graphics); + } + } + } + return null; + } +} 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 new file mode 100644 index 0000000000..10c9f89e74 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java @@ -0,0 +1,640 @@ +package net.runelite.client.plugins.zulrah; + +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import javax.inject.Inject; +import java.awt.*; +import java.awt.image.*; +import java.util.*; +import java.util.List; + +import net.runelite.api.*; + +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.ImageUtil; + +@PluginDescriptor( + name = "!Zulrah", + description = "Zulrah Helper", + tags = {"Zulrah", "Helper"} +) +public class ZulrahPlugin extends Plugin +{ + @Inject + private OverlayManager overlayManager; + + @Inject + private ZulrahConfig config; + + @Inject + private ZulrahOverlay ZulrahOverlay; + + @Inject + private ZulrahTileOverlay ZulrahTileOverlay; + + @Inject + private Client client; + + @Inject + private SpriteManager spriteManager; + + @Provides + ZulrahConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(ZulrahConfig.class); + } + + private static final int[] PROTECTION_ICONS = { + SpriteID.PRAYER_PROTECT_FROM_MISSILES, + SpriteID.PRAYER_PROTECT_FROM_MELEE, + SpriteID.PRAYER_PROTECT_FROM_MAGIC + }; + + private static final Dimension PROTECTION_ICON_DIMENSION = new Dimension(33, 33); + private static final Color PROTECTION_ICON_OUTLINE_COLOR = new Color(33, 33, 33); + public final BufferedImage[] ProtectionIcons = new BufferedImage[PROTECTION_ICONS.length]; + int zulrahstart = 0; + NPC Zulrah; + + @Subscribe + public void onGameStateChanged(GameStateChanged gameStateChanged) + { + if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { + loadProtectionIcons(); + } + } + + @Override + protected void startUp() throws Exception { + overlayManager.add(ZulrahOverlay); + overlayManager.add(ZulrahTileOverlay); + } + + @Override + protected void shutDown() throws Exception { + overlayManager.remove(ZulrahOverlay); + overlayManager.remove(ZulrahTileOverlay); + } + + LocalPoint ZulrahPosCenter = new LocalPoint(6720, 7616); + LocalPoint ZulrahPosWest = new LocalPoint(8000, 7360); + LocalPoint ZulrahPosEast = new LocalPoint(5440, 7360); + LocalPoint ZulrahPosNorth = new LocalPoint(6720, 6208); + + LocalPoint SWCornerTile = new LocalPoint(7488, 7872); + LocalPoint SWCornerTileMelee = new LocalPoint(7232, 8000); + LocalPoint WPillar = new LocalPoint(7232, 7232); + LocalPoint WPillarN = new LocalPoint(7232, 7104); + LocalPoint EPillar = new LocalPoint(6208, 7232); + LocalPoint EPillarN = new LocalPoint(6208, 7104); + LocalPoint SECornerTile = new LocalPoint(6208, 8000); + LocalPoint SECornerTileMelee = new LocalPoint(5952, 7744); + LocalPoint Middle = new LocalPoint(6720, 6848); + + int ticks; + int phaseticks; + int not; + int lastphase; + int phase; + int nextprayerendticks; + boolean phase1 = true; + boolean phase2 = true; + boolean phase3 = true; + boolean phase4 = true; + boolean restart = false; + boolean prayerconserve = false; + Color nztcolor; + LocalPoint nextzulrahtile; + LocalPoint nexttile; + LocalPoint currenttile; + LocalPoint lastloc; + LocalPoint MeleeTile; + List phases = new ArrayList<>(); + List locations = new ArrayList<>(); + + ArrayList Phase1types = new ArrayList<>(Arrays.asList(2042, 2043, 2044, 2042, 2044, 2043, 2042, 2044, 2042, 2043)); + ArrayList Phase1pos = new ArrayList<>(Arrays.asList(ZulrahPosCenter, ZulrahPosCenter, ZulrahPosCenter, ZulrahPosEast, ZulrahPosNorth, ZulrahPosCenter, ZulrahPosWest, ZulrahPosNorth, ZulrahPosEast, ZulrahPosCenter)); + ArrayList Phase1tiles = new ArrayList<>(Arrays.asList(SWCornerTile, SWCornerTile, SWCornerTile, EPillar, EPillarN, EPillar, Middle, EPillar, EPillar, SWCornerTile)); + ArrayList Phase1ticks = new ArrayList<>(Arrays.asList(28, 20, 18, 28, 39, 22, 20, 36, 48, 20)); + + ArrayList Phase2types = new ArrayList<>(Arrays.asList(2042, 2043, 2044, 2042, 2043, 2044, 2042, 2044, 2042, 2043)); + ArrayList Phase2pos = new ArrayList<>(Arrays.asList(ZulrahPosCenter, ZulrahPosCenter, ZulrahPosCenter, ZulrahPosNorth, ZulrahPosCenter, ZulrahPosEast, ZulrahPosNorth, ZulrahPosNorth, ZulrahPosEast, ZulrahPosCenter)); + ArrayList Phase2tiles = new ArrayList<>(Arrays.asList(SWCornerTile, SWCornerTile, SWCornerTile, EPillar, EPillar, EPillar, WPillar, WPillarN, EPillar, SWCornerTile)); + ArrayList Phase2ticks = new ArrayList<>(Arrays.asList(28, 20, 17, 39, 22, 20, 28, 36, 48, 21)); + + ArrayList Phase3types = new ArrayList<>(Arrays.asList(2042, 2042, 2043, 2044, 2042, 2044, 2042, 2042, 2044, 2042, 2044)); + ArrayList Phase3pos = new ArrayList<>(Arrays.asList(ZulrahPosCenter, ZulrahPosWest, ZulrahPosCenter, ZulrahPosEast, ZulrahPosNorth, ZulrahPosWest, ZulrahPosCenter, ZulrahPosEast, ZulrahPosCenter, ZulrahPosWest, ZulrahPosCenter)); + ArrayList Phase3tiles = new ArrayList<>(Arrays.asList(SWCornerTile, SWCornerTile, SECornerTile, EPillar, WPillar, WPillar, EPillar, EPillar, WPillar, WPillar, SWCornerTile)); + ArrayList Phase3ticks = new ArrayList<>(Arrays.asList(28, 30, 40, 20, 20, 20, 25, 20, 36, 35, 18)); + + ArrayList Phase4types = new ArrayList<>(Arrays.asList(2042, 2044, 2042, 2044, 2043, 2042, 2042, 2044, 2042, 2044, 2042, 2044)); + ArrayList Phase4pos = new ArrayList<>(Arrays.asList(ZulrahPosCenter, ZulrahPosWest, ZulrahPosNorth, ZulrahPosEast, ZulrahPosCenter, ZulrahPosWest, ZulrahPosNorth, ZulrahPosEast, ZulrahPosCenter, ZulrahPosCenter, ZulrahPosWest, ZulrahPosCenter)); + ArrayList Phase4tiles = new ArrayList<>(Arrays.asList(SWCornerTile, SWCornerTile, EPillar, EPillar, WPillar, WPillar, WPillar, EPillar, WPillar, WPillar, WPillar, SWCornerTile)); + ArrayList Phase4ticks = new ArrayList<>(Arrays.asList(28, 36, 24, 30, 28, 17, 34, 33, 20, 27, 29, 18)); + + @Subscribe + public void onGameTick(GameTick event) { + if (!config.EnableZulrah()) { + return; + } + + boolean foundzulrah = false; + for (NPC monster : client.getNpcs()) + { + if (monster == null || monster.getName() == null) + { + continue; + } + if (monster.getName().equalsIgnoreCase("zulrah")) { + foundzulrah = true; + Zulrah = monster; + break; + } + } + if (!foundzulrah) { + Zulrah = null; + } + + if (Zulrah != null) { + if (zulrahstart == 0) { + currenttile = SWCornerTile; + lastloc = Zulrah.getLocalLocation(); + lastphase = Zulrah.getId(); + zulrahstart = client.getTickCount(); + phases.add(lastphase); + locations.add(lastloc); + phaseticks = 28; + } else { + if (!Zulrah.getLocalLocation().equals(lastloc) || Zulrah.getId() != lastphase) { + if (restart) { + phases.clear(); + locations.clear(); + zulrahstart = client.getTickCount(); + lastphase = 0; + lastloc = null; + phase = 0; + phase1 = true; + phase2 = true; + phase3 = true; + phase4 = true; + nextzulrahtile = null; + nztcolor = null; + nexttile = null; + currenttile = SWCornerTile; + restart = false; + ticks = 0; + prayerconserve = false; + phaseticks = 34; + not = 0; + nextprayerendticks = 0; + } + lastloc = Zulrah.getLocalLocation(); + lastphase = Zulrah.getId(); + ticks = 0; + phases.add(lastphase); + locations.add(lastloc); + if (phase == 0) { + for (int i = 0; i < phases.size(); i++) { + if (phase1) { + if (!phases.get(i).equals(Phase1types.get(i)) || !locations.get(i).equals(Phase1pos.get(i))) { + phase1 = false; + not++; + } + } + if (phase2) { + if (!phases.get(i).equals(Phase2types.get(i)) || !locations.get(i).equals(Phase2pos.get(i))) { + phase2 = false; + not++; + } + } + if (phase3) { + if (!phases.get(i).equals(Phase3types.get(i)) || !locations.get(i).equals(Phase3pos.get(i))) { + phase3 = false; + not++; + } + } + if (phase4) { + if (!phases.get(i).equals(Phase4types.get(i)) || !locations.get(i).equals(Phase4pos.get(i))) { + phase4 = false; + not++; + } + } + } + + if (not == 2) { + if (lastphase == 2043) { + nztcolor = Color.BLUE; + nextzulrahtile = ZulrahPosCenter; + currenttile = SWCornerTile; + nexttile = SWCornerTile; + phaseticks = Phase2ticks.get(phases.size() - 1); + prayerconserve = true; + } else if (lastphase == 2044) { + nztcolor = Color.GREEN; + nextzulrahtile = ZulrahPosNorth; + currenttile = SWCornerTile; + nexttile = EPillar; + phaseticks = Phase2ticks.get(phases.size() - 1); + prayerconserve = false; + } + } else if (not == 3) { + if (phase1) { + nztcolor = zulrahtype(Phase1types.get(phases.size())); + nextzulrahtile = Phase1pos.get(phases.size()); + currenttile = Phase1tiles.get(phases.size() - 1); + nexttile = Phase1tiles.get(phases.size()); + phaseticks = Phase1ticks.get(phases.size() - 1); + prayerconserve = true; + phase = 1; + } else if (phase2) { + nztcolor = zulrahtype(Phase2types.get(phases.size())); + nextzulrahtile = Phase2pos.get(phases.size()); + currenttile = Phase2tiles.get(phases.size() - 1); + nexttile = Phase2tiles.get(phases.size()); + phaseticks = Phase2ticks.get(phases.size() - 1); + prayerconserve = false; + phase = 2; + } else if (phase3) { + nztcolor = zulrahtype(Phase3types.get(phases.size())); + nextzulrahtile = Phase3pos.get(phases.size()); + currenttile = Phase3tiles.get(phases.size() - 1); + nexttile = Phase3tiles.get(phases.size()); + phaseticks = Phase3ticks.get(phases.size() - 1); + prayerconserve = false; + phase = 3; + } else if (phase4) { + nztcolor = zulrahtype(Phase4types.get(phases.size())); + nextzulrahtile = Phase4pos.get(phases.size()); + currenttile = Phase4tiles.get(phases.size() - 1); + nexttile = Phase4tiles.get(phases.size()); + phaseticks = Phase4ticks.get(phases.size() - 1); + prayerconserve = true; + phase = 4; + } else { + System.out.println("ERROR: COULD NOT IDENTIFY ZULRAH PHASE!"); + } + not = 0; + } + } else { + if (phase == 1) { + if (Phase1types.size() == phases.size()) { + nztcolor = null; + nextzulrahtile = null; + nexttile = null; + restart = true; + } else { + nextzulrahtile = Phase1pos.get(phases.size()); + nexttile = Phase1tiles.get(phases.size()); + if (phases.size() == 8) { + nztcolor = Color.YELLOW; + } else { + nztcolor = zulrahtype(Phase1types.get(phases.size())); + } + } + currenttile = Phase1tiles.get(phases.size() - 1); + phaseticks = Phase1ticks.get(phases.size() - 1); + } else if (phase == 2) { + if (Phase2types.size() == phases.size()) { + nztcolor = null; + nextzulrahtile = null; + nexttile = null; + restart = true; + } else { + nextzulrahtile = Phase2pos.get(phases.size()); + nexttile = Phase2tiles.get(phases.size()); + if (phases.size() == 8) { + nztcolor = Color.YELLOW; + } else { + nztcolor = zulrahtype(Phase2types.get(phases.size())); + } + } + currenttile = Phase2tiles.get(phases.size() - 1); + phaseticks = Phase2ticks.get(phases.size() - 1); + } else if (phase == 3) { + if (Phase3types.size() == phases.size()) { + nztcolor = null; + nextzulrahtile = null; + nexttile = null; + restart = true; + } else { + nextzulrahtile = Phase3pos.get(phases.size()); + nexttile = Phase3tiles.get(phases.size()); + if (phases.size() == 9) { + nztcolor = Color.YELLOW; + } else { + nztcolor = zulrahtype(Phase3types.get(phases.size())); + } + } + currenttile = Phase3tiles.get(phases.size() - 1); + phaseticks = Phase3ticks.get(phases.size() - 1); + } else if (phase == 4) { + if (Phase4types.size() == phases.size()) { + nztcolor = null; + nextzulrahtile = null; + nexttile = null; + restart = true; + } else { + nextzulrahtile = Phase4pos.get(phases.size()); + nexttile = Phase4tiles.get(phases.size()); + if (phases.size() == 10) { + nztcolor = Color.YELLOW; + } else { + nztcolor = zulrahtype(Phase4types.get(phases.size())); + } + } + currenttile = Phase4tiles.get(phases.size() - 1); + phaseticks = Phase4ticks.get(phases.size() - 1); + } else { + System.out.println("ERROR: COULD NOT IDENTIFY ZULRAH PHASE!"); + } + } + } else { + ticks++; + if (phases.size() == 1 && phaseticks == 34) { + if (ticks >= 18) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } + if (not == 2) { + if (lastphase == 2043) { + if (ticks >= 12 && ticks <= 13) { + MeleeTile = SWCornerTileMelee; + } else { + MeleeTile = null; + } + } + } else if (phase == 1) { + if (phases.size() == 5) { + if (ticks >= 19) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 8) { + if (ticks >= 19) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 9) { + if (ticks >= 34) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 10) { + if (ticks >= 12 && ticks <= 13) { + MeleeTile = SWCornerTileMelee; + } else { + MeleeTile = null; + } + } else if (phases.size() == 4 || phases.size() == 6 || phases.size() == 10) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phase == 2) { + if (phases.size() == 4) { + if (ticks >= 20) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 8) { + if (ticks >= 18) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 9) { + if (ticks >= 34) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 5 || phases.size() == 7 || phases.size() == 10) { + if (phases.size() == 10) { + if (ticks >= 12 && ticks <= 13) { + MeleeTile = SWCornerTileMelee; + } else { + MeleeTile = null; + } + } + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phase == 3) { + if (phases.size() == 2) { + if (ticks >= 20) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 3) { + prayerconserve = true; + if (ticks >= 24 && ticks <= 25) { + MeleeTile = SECornerTileMelee; + } else if (ticks >= 32 && ticks <= 33) { + MeleeTile = SECornerTile; + } else { + MeleeTile = null; + } + } else if (phases.size() == 7 || phases.size() == 11) { + prayerconserve = true; + } else if (phases.size() == 9) { + if (ticks >= 16) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else { + prayerconserve = false; + } + } else if (phase == 4) { + if (phases.size() == 2) { + if (ticks >= 10 && ticks <= 16) { + nextprayerendticks = 16; + } else { + nextprayerendticks = 0; + } + + if (ticks >= 16) { + prayerconserve = false; + } else { + prayerconserve = true; + } + } else if (phases.size() == 3) { + if (ticks >= 16) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 4) { + if (ticks >= 10 && ticks <= 16) { + nextprayerendticks = 16; + } else { + nextprayerendticks = 0; + } + + if (ticks <= 16) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 5 || phases.size() == 7 || phases.size() == 12) { + prayerconserve = true; + } else if (phases.size() == 8) { + if (ticks >= 18) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else if (phases.size() == 10) { + if (ticks >= 14) { + prayerconserve = true; + } else { + prayerconserve = false; + } + } else { + prayerconserve = false; + } + } + } + } + } else { + if (zulrahstart > 0) { + phases.clear(); + locations.clear(); + zulrahstart = 0; + lastphase= 0; + lastloc = null; + phase = 0; + phase1 = true; + phase2 = true; + phase3 = true; + phase4 = true; + nextzulrahtile = null; + nztcolor = null; + nexttile = null; + currenttile = null; + restart = false; + ticks = 0; + prayerconserve = false; + not = 0; + nextprayerendticks = 0; + } + } + } + + public Color zulrahtype(int type) { + switch(type) { + case 2042: + return Color.GREEN; + case 2043: + return Color.RED; + case 2044: + return Color.BLUE; + } + return null; + } + + private void loadProtectionIcons() { + final IndexedSprite[] protectionIcons = {}; + final IndexedSprite[] newProtectionIcons = Arrays.copyOf(protectionIcons, PROTECTION_ICONS.length); + int curPosition = 0; + + for (int i = 0; i < PROTECTION_ICONS.length; i++, curPosition++) + { + final int resource = PROTECTION_ICONS[i]; + ProtectionIcons[i] = rgbaToIndexedBufferedImage(ProtectionIconFromSprite(spriteManager.getSprite(resource, 0))); + newProtectionIcons[curPosition] = createIndexedSprite(client, ProtectionIcons[i]); + } + } + + private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) { + final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel(); + + final int width = bufferedImage.getWidth(); + final int height = bufferedImage.getHeight(); + final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); + final int[] palette = new int[indexedCM.getMapSize()]; + indexedCM.getRGBs(palette); + + final IndexedSprite newIndexedSprite = client.createIndexedSprite(); + newIndexedSprite.setPixels(pixels); + newIndexedSprite.setPalette(palette); + newIndexedSprite.setWidth(width); + newIndexedSprite.setHeight(height); + newIndexedSprite.setOriginalWidth(width); + newIndexedSprite.setOriginalHeight(height); + newIndexedSprite.setOffsetX(0); + newIndexedSprite.setOffsetY(0); + return newIndexedSprite; + } + + private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) { + final BufferedImage indexedImage = new BufferedImage( + sourceBufferedImage.getWidth(), + sourceBufferedImage.getHeight(), + BufferedImage.TYPE_BYTE_INDEXED); + + final ColorModel cm = indexedImage.getColorModel(); + final IndexColorModel icm = (IndexColorModel) cm; + + final int size = icm.getMapSize(); + final byte[] reds = new byte[size]; + final byte[] greens = new byte[size]; + final byte[] blues = new byte[size]; + icm.getReds(reds); + icm.getGreens(greens); + icm.getBlues(blues); + + final WritableRaster raster = indexedImage.getRaster(); + final int pixel = raster.getSample(0, 0, 0); + final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); + final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); + resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); + return resultIndexedImage; + } + + private static BufferedImage ProtectionIconFromSprite(final BufferedImage freezeSprite) { + final BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, PROTECTION_ICON_DIMENSION.width, PROTECTION_ICON_DIMENSION.height); + return ImageUtil.outlineImage(freezeCanvas, PROTECTION_ICON_OUTLINE_COLOR); + } + + BufferedImage getProtectionIcon() { + int type = 0; + if (phase1) { + type = Phase1types.get(phases.size()); + } else if (phase2) { + type = Phase2types.get(phases.size()); + } else if (phase3) { + type = Phase3types.get(phases.size()); + } else if (phase4) { + type = Phase4types.get(phases.size()); + } else { + System.out.println("ERROR: COULD NOT IDENTIFY ZULRAH PHASE!"); + } + + if (type > 0) { + switch (type) { + case 2042: + return ProtectionIcons[0]; + case 2043: + return ProtectionIcons[1]; + case 2044: + return ProtectionIcons[2]; + } + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahTileOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahTileOverlay.java new file mode 100644 index 0000000000..28d14f026b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahTileOverlay.java @@ -0,0 +1,120 @@ +package net.runelite.client.plugins.zulrah; + +import java.awt.*; +import java.awt.image.BufferedImage; +import javax.inject.Inject; + +import net.runelite.api.*; +import net.runelite.api.Point; +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 ZulrahTileOverlay extends Overlay +{ + private final ZulrahConfig config; + private final ZulrahPlugin plugin; + + @Inject + private Client client; + + @Inject + private ZulrahTileOverlay(ZulrahConfig config, ZulrahPlugin plugin) + { + this.config = config; + this.plugin = plugin; + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.MED); + } + + @Override + public Dimension render(Graphics2D graphics) + { + + NPC Zulrah = plugin.Zulrah; + if (Zulrah != null) { + OverlayUtil.renderTextLocation(graphics, Zulrah.getCanvasTextLocation(graphics, Integer.toString(plugin.phaseticks - plugin.ticks), Zulrah.getLogicalHeight() + 40), Integer.toString(plugin.phaseticks - plugin.ticks), Color.WHITE); + Player player = client.getLocalPlayer(); + if (plugin.currenttile != null) { + if (plugin.currenttile.equals(plugin.nexttile)) { + final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.currenttile); + if (poly != null) { + Point textLocationtile = Perspective.getCanvasTextLocation(client, graphics, plugin.currenttile, "Current & Next", 50); + OverlayUtil.renderTextLocation(graphics, textLocationtile, "Current & Next", Color.WHITE); + OverlayUtil.renderPolygon(graphics, poly, Color.WHITE); + } + } else { + if (!player.getLocalLocation().equals(plugin.currenttile)) { + final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.currenttile); + if (poly != null) { + Point textLocationtile = Perspective.getCanvasTextLocation(client, graphics, plugin.currenttile, "Current", 50); + OverlayUtil.renderTextLocation(graphics, textLocationtile, "Current", Color.WHITE); + OverlayUtil.renderPolygon(graphics, poly, Color.GREEN); + } + } + if (plugin.nexttile != null) { + final Polygon poly2 = Perspective.getCanvasTilePoly(client, plugin.nexttile); + if (poly2 != null) { + Point textLocationtile = Perspective.getCanvasTextLocation(client, graphics, plugin.nexttile, "Next", 50); + OverlayUtil.renderTextLocation(graphics, textLocationtile, "Next", Color.WHITE); + OverlayUtil.renderPolygon(graphics, poly2, Color.RED); + } + } + } + } + if (plugin.nextzulrahtile != null) { + String style = ""; + if (plugin.nztcolor.equals(Color.RED)) { + style = "MELEE"; + } else if (plugin.nztcolor.equals(Color.BLUE)) { + style = "MAGE"; + } else if (plugin.nztcolor.equals(Color.GREEN)) { + style = "RANGE"; + } else if (plugin.nztcolor.equals(Color.YELLOW)) { + style = "JAD"; + } + + final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.nextzulrahtile); + Point textLocation = Perspective.getCanvasTextLocation(client, graphics, plugin.nextzulrahtile, style, 200); + if (poly != null) + { + BufferedImage clanchatImage = null; + if (style.equals("JAD")) { + if (plugin.phase4 && plugin.phases.size() == 10) { + clanchatImage = plugin.ProtectionIcons[2]; + } else if (plugin.phase3 && plugin.phases.size() == 9) { + clanchatImage = plugin.ProtectionIcons[2]; + } else { + clanchatImage = plugin.ProtectionIcons[0]; + } + } else { + clanchatImage = plugin.getProtectionIcon(); + } + + if (clanchatImage != null) { + Point imageLocation = new Point(textLocation.getX(), textLocation.getY() + 15); + OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); + } + + graphics.setFont(FontManager.getRunescapeBoldFont()); + OverlayUtil.renderTextLocation(graphics, textLocation, style, Color.WHITE); + OverlayUtil.renderPolygon(graphics, poly, plugin.nztcolor); + } + } + if (plugin.MeleeTile != null) { + final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.MeleeTile); + if (poly != null) { + Point textLocationtile = Perspective.getCanvasTextLocation(client, graphics, plugin.MeleeTile, "MOVE HERE NOW!", 50); + graphics.setFont(FontManager.getRunescapeBoldFont()); + OverlayUtil.renderTextLocation(graphics, textLocationtile, "MOVE HERE NOW!", Color.WHITE); + OverlayUtil.renderPolygon(graphics, poly, Color.BLACK); + } + } + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/util/MiscUtils.java b/runelite-client/src/main/java/net/runelite/client/util/MiscUtils.java new file mode 100644 index 0000000000..039c3cfa2b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/util/MiscUtils.java @@ -0,0 +1,79 @@ +package net.runelite.client.util; + +import net.runelite.api.Client; +import net.runelite.api.Player; +import net.runelite.api.WorldType; +import net.runelite.api.coords.WorldPoint; + +import java.awt.*; + +public class MiscUtils +{ + private static int[] abovePointsX = { 2944, 3392, 3392, 2944 }; + private static int[] abovePointsY = { 3523, 3523, 3971, 3971 }; + private static int[] belowPointsX = { 2944, 2944, 3264, 3264 }; + private static int[] belowPointsY = { 9918, 10360, 10360, 9918 }; + + private static Polygon abovePoly = new Polygon(abovePointsX, abovePointsY, abovePointsX.length); + private static Polygon belowPoly = new Polygon(belowPointsX, belowPointsY, belowPointsX.length); + + //test replacement so private for now + private static boolean inWildy(WorldPoint point) + { + if (point == null) + return false; + + return abovePoly.contains(point.getX(), point.getY()) || belowPoly.contains(point.getX(), point.getY()); + } + + public static int getWildernessLevelFrom(Client client, WorldPoint point) + { + if (client == null) + return 0; + + if (point == null) + return 0; + + int x = point.getX(); + + if (point.getPlane() == 0 && (x < 2940 || x > 3391)) + return 0; + + int y = point.getY(); + //v underground //v above ground + int wildernessLevel = clamp(y > 6400 ? ((y - 9920) / 8) + 1 : ((y - 3520) / 8) + 1, 0, 56); + + if (point.getPlane() > 0) + if (y < 9920) + wildernessLevel = 0; + + if (client.getWorldType().stream().anyMatch(worldType -> worldType == WorldType.PVP || worldType == WorldType.PVP_HIGH_RISK)) + { + wildernessLevel += 15; + } + + return Math.max(0, wildernessLevel); + } + + public static int clamp(int val, int min, int max) + { + return Math.max(min, Math.min(max, val)); + } + + public static float clamp(float val, float min, float max) + { + return Math.max(min, Math.min(max, val)); + } + + public static boolean inWilderness(Client client) + { + Player localPlayer = client.getLocalPlayer(); + + if (localPlayer == null) + return false; + + return inWildy(localPlayer.getWorldLocation()); + + //return getWildernessLevelFrom(client, localPlayer.getWorldLocation()) > 0; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/util/WildernessLocation.java b/runelite-client/src/main/java/net/runelite/client/util/WildernessLocation.java new file mode 100644 index 0000000000..19e62c64a4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/util/WildernessLocation.java @@ -0,0 +1,98 @@ + +package net.runelite.client.util; + +import net.runelite.api.coords.WorldArea; + +public enum WildernessLocation { + REV_CAVE_OTHER("Rev Cave", new Location(3128, 10232, 3225, 10059), 0), + REV_BLACK_DRAGS("Rev Black Drags", new Location(3223, 10216, 3254, 10190), 0), + REV_DARK_BEAST("Rev Dark Beast", new Location(3243, 10154, 3264, 10136), 0), + REV_MAIN_CHAMBER("Main Rev Chamber", new Location(3227, 10187, 3261, 10157), 0), + REV_ENTRANCE_INSIDE("Inside Rev Ent.", new Location(3238, 10236, 3243, 10231), 0), + ICE_ROCK("Ice Rock", new Location(2957, 3942, 2984, 3929), 0), + WILDY_AGILITY_COURSE("Wildy Agility Course", new Location(2988, 3967, 3008, 3906), 0), + FIRE_GIANT_ENTRANCE("Fire Giant Entrance", new Location(3042, 3929, 3051, 3920), 0), + PIRATE_HUT("Pirate Hut", new Location(3037, 3959, 3045, 3948), 0), + MAGE_BANK("Mage Bank", new Location(3082, 3960, 3103, 3952), 0), + MAGE_ARENA("Mage Arena", new Location(3088, 3949, 3123, 3919), 0), + LEVER("Lever", new Location(3149, 3933, 3162, 3917), 0), + WEB("Web", new Location(3153, 3961, 3163, 3948), 0), + RESOURCE_ARENA("Resource Arena", new Location(3174, 3946, 3195, 3923), 0), + AXE_HUT("Axe Hut", new Location(3187, 3962, 3194, 3957), 0), + SCORPIA("Scorpia", new Location(3216, 3949, 3248, 3935), 0), + ROGUE_CASTLE("Rogue Castle", new Location(3275, 3947, 3299, 3920), 0), + FIFTY_PORTS("50 ports", new Location(3301, 3923, 3315, 3909), 0), + VOLCANO("Volcano", new Location(3345, 3957, 3390, 3916), 0), + NEW_GATE("New Gate", new Location(3345, 3957, 3390, 3916), 0), + GLORY_HOLE("Glory Hole", new Location(3352, 3897, 3386, 3869), 0), + GLORY_HILL("Glory Hill", new Location(3331, 3890, 3348, 3866), 0), + GDZ("Gdz", new Location(3279, 3895, 3296, 3875), 0), + GAP("Gap", new Location(3238, 3855, 3258, 3841), 0), + OLD_GATE("Old Gate", new Location(3211, 3906, 3238, 3882), 0), + LAVA_DRAGS("Lava Drags", new Location(3175, 3857, 3221, 3805), 0), + SPIDER_HILL("Spider Hill", new Location(3156, 3896, 3182, 3871), 0), + RUNE_ROCKS("Rune Rocks", new Location(3055, 3890, 3072, 3876), 0), + ICE_GATE("Ice Gate", new Location(2945, 3913, 2978, 3878), 0), + VENENATIS("Venenatis", new Location(3298, 3759, 3353, 3722), 0), + SINGLE_STRIP("Single Strip", new Location(3333, 3842, 3348, 3774), 0), + CALLISTO("Callisto", new Location(3266, 3863, 3315, 3827), 0), + DWARVES("Dwarves", new Location(3230, 3805, 3264, 3779), 0), + VETTION("Vet'tion", new Location(3183, 3796, 3227, 3765), 0), + EAST_DRAGONS("East Drags", new Location(3326, 3704, 3365, 3671), 0), + HILL_GIANTS("Hill Giants", new Location(3282, 3687, 3300, 3674), 0), + ENTS("Ents", new Location(3300, 3627, 3320, 3584), 0), + CHAOS_TEMPLE("Chaos Temple", new Location(3220, 3632, 3255, 3593), 0), + NINETEEN_OBELISK("19s", new Location(3220, 3672, 3234, 3660), 0), + CORP_CAVE("Corp Cave", new Location(3201, 3684, 3219, 3672), 0), + THIRTEEN_OBELISK("13s", new Location(3145, 3628, 3168, 3609), 0), + SOUTH_REV_ENTRANCE("Lvl 18 Rev Ent", new Location(3071, 3660, 3092, 3645), 0), + GRAVES("Graves", new Location(3128, 3686, 3181, 3658), 0), + GRAVEYARD_DRAGS("Graveyard Drags", new Location(3129, 3717, 3172, 3691), 0), + CHINS("Chins", new Location(3128, 3792, 3160, 3754), 0), + REV_ENTRANCE("Rev Entrance", new Location(3118, 3837, 3142, 3818), 0), + HOB_OBELISK("35 Obelisk", new Location(3097, 3804, 3115, 3785), 0), + HOBGOBLINS("Hobgoblins", new Location(3073, 3775, 3104, 3745), 0), + GWD("God Wars Dungeon", new Location(3010, 3745, 3027, 3727), 0), + LAVA_MAZE_TELE("Lava Maze Tele", new Location(3019, 3842, 3044, 3812), 0), + KBD_CAGE("KBD CAGE", new Location(3007, 3855, 3021, 3839), 0), + GHORROCK("44s", new Location(2973, 3870, 2987, 3859), 0), + CHAOS_FANATIC("Chaos Fanatic", new Location(2971, 3854, 2992, 3834), 0), + HIGH_ALTAR("High Altar", new Location(2945, 3826, 2970, 3813), 0), + CEMETERY("Cemetery", new Location(2956, 3767, 2996, 3736), 0), + CRAZY_ARCHAEOLOGIST("Crazy Archaeologist", new Location(2952, 3709, 2985, 3678), 0), + DARK_WARRIOR_FORTRESS("Dark Warriors", new Location(3014, 3648, 3046, 3616), 0), + WEST_DRAGONS("West Drags", new Location(2960, 3627, 2992, 3598), 0), + BANDIT_CAMP("Bandit Camp", new Location(3017, 3712, 3059, 3681), 0); + + private final String name1; + private final WorldArea worldArea; + + private WildernessLocation(String name, Location location, int plane) { + name1 = name; + worldArea = new WorldArea(location.x, location.y, location.width, location.height, plane); + } + + public String getName() { + return name1; + } + + public WorldArea getWorldArea() { + return worldArea; + } + + public static class Location { + public int x; + public int y; + public int width; + public int height; + + Location(int x, int y, int x1, int y1) { + x = x; + y = y1; + width = x1 - x; + height = y - y1; + } + } + +} + diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/profiles/delete_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/profiles/delete_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..18b67f23f3454d38f3758f3f42009f5a1fe03214 GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mI14-?iy0WWg+Z8+Vb&Z8pkR}y zi(`n!#I+Y4xegf!uwHm1$rYQjwENzFCcRY^?Kw^_ZCjo@DfSu)EZIE!{CxZW=Xnk{ zrk0t8y?F6#(rwm@ApvTF-fT_0nwNcq%o6RzRhF1Xlr8;}zU|uD*fra3CC*fD`Z4$G zm*&4YE8bjNd$v^en6=-9QlIbhwx5yfWuHIW^8Xs~u!i*|FD#yH0lJ34)78&qol`;+ E08pz??f?J) literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/profiles/profiles_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/profiles/profiles_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a733eaf4a19343c3416d4b12cea60d735d9f7170 GIT binary patch literal 77 zcmZ?wbhEHb6k!l#n8*ME|NsBLFxLl2D*j|)WME)s&;f~p Date: Fri, 19 Apr 2019 22:15:29 -0700 Subject: [PATCH 10/75] Nothing --- .../MenuEntrySwapperConfig.java | 568 +++++++++--------- 1 file changed, 284 insertions(+), 284 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index 23ab63df16..5326b220b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -1,284 +1,284 @@ -/* - * Copyright (c) 2018, Adam - * 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.menuentryswapper; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("menuentryswapper") -public interface MenuEntrySwapperConfig extends Config -{ - @ConfigItem( - position = -2, - keyName = "shiftClickCustomization", - name = "Customizable shift-click", - description = "Allows customization of shift-clicks on items" - ) - default boolean shiftClickCustomization() - { - return true; - } - - @ConfigItem( - keyName = "swapAdmire", - name = "Admire", - description = "Swap Admire with Teleport, Spellbook and Perks (max cape) for mounted skill capes." - ) - default boolean swapAdmire() - { - return true; - } - - @ConfigItem( - keyName = "swapAssignment", - name = "Assignment", - description = "Swap Talk-to with Assignment for Slayer Masters. This will take priority over swapping Trade." - ) - default boolean swapAssignment() - { - return true; - } - - @ConfigItem( - keyName = "swapBanker", - name = "Bank", - description = "Swap Talk-to with Bank on Bank NPC
Example: Banker" - ) - default boolean swapBank() - { - return true; - } - - @ConfigItem( - keyName = "swapBirdhouseEmpty", - name = "Birdhouse", - description = "Swap Interact with Empty for birdhouses on Fossil Island" - ) - default boolean swapBirdhouseEmpty() - { - return true; - } - - @ConfigItem( - keyName = "swapBones", - name = "Bury", - description = "Swap Bury with Use on Bones" - ) - default boolean swapBones() - { - return false; - } - - @ConfigItem( - keyName = "swapContract", - name = "Contract", - description = "Swap Talk-to with Contract on Guildmaster Jane" - ) - default boolean swapContract() - { - return true; - } - - @ConfigItem( - keyName = "swapChase", - name = "Chase", - description = "Allows to left click your cat to chase" - ) - default boolean swapChase() - { - return true; - } - - @ConfigItem( - keyName = "claimSlime", - name = "Claim Slime", - description = "Swap Talk-to with Claim Slime from Morytania diaries" - ) - default boolean claimSlime() - { - return true; - } - - @ConfigItem( - keyName = "swapDarkMage", - name = "Repairs", - description = "Swap Talk-to with Repairs for Dark Mage" - ) - default boolean swapDarkMage() - { - return true; - } - - @ConfigItem( - keyName = "swapDecant", - name = "Decant", - description = "Swap Talk-to with Decant for Bob Barter and Murky Matt at the Grand Exchange." - ) - default boolean swapDecant() - { - return false; - } - - @ConfigItem( - keyName = "swapExchange", - name = "Exchange", - description = "Swap Talk-to with Exchange on NPC
Example: Grand Exchange Clerk, Tool Leprechaun, Void Knight" - ) - default boolean swapExchange() - { - return true; - } - - @ConfigItem( - keyName = "swapFairyRing", - name = "Fairy ring", - description = "Swap Zanaris with Last-destination or Configure on Fairy rings" - ) - default FairyRingMode swapFairyRing() - { - return FairyRingMode.LAST_DESTINATION; - } - - @ConfigItem( - keyName = "swapHarpoon", - name = "Harpoon", - description = "Swap Cage, Big Net with Harpoon on Fishing spot" - ) - default boolean swapHarpoon() - { - return false; - } - - @ConfigItem( - keyName = "swapHomePortal", - name = "Home", - description = "Swap Enter with Home or Build or Friend's house on Portal" - ) - default HouseMode swapHomePortal() - { - return HouseMode.HOME; - } - - @ConfigItem( - keyName = "swapPickpocket", - name = "Pickpocket on H.A.M.", - description = "Swap Talk-to with Pickpocket on H.A.M members" - ) - default boolean swapPickpocket() - { - return true; - } - - @ConfigItem( - keyName = "swapPay", - name = "Pay", - description = "Swap Talk-to with Pay on NPC
Example: Elstan, Heskel, Fayeth" - ) - default boolean swapPay() - { - return true; - } - - @ConfigItem( - keyName = "swapPrivate", - name = "Private", - description = "Swap Shared with Private on the Chambers of Xeric storage units." - ) - default boolean swapPrivate() - { - return false; - } - - @ConfigItem( - keyName = "swapPick", - name = "Pick", - description = "Swap Pick with Pick-lots of the Gourd tree in the Chambers of Xeric" - ) - default boolean swapPick() - { - return false; - } - - @ConfigItem( - keyName = "swapQuick", - name = "Quick Pass/Open/Start/Travel", - description = "Swap Pass with Quick-Pass, Open with Quick-Open, Ring with Quick-Start and Talk-to with Quick-Travel" - ) - default boolean swapQuick() - { - return true; - } - - @ConfigItem( - keyName = "swapBoxTrap", - name = "Reset", - description = "Swap Check with Reset on box trap" - ) - default boolean swapBoxTrap() - { - return true; - } - - @ConfigItem( - keyName = "swapTeleportItem", - name = "Teleport item", - description = "Swap Wear, Wield with Rub, Teleport on teleport item
Example: Amulet of glory, Explorer's ring, Chronicle" - ) - default boolean swapTeleportItem() - { - return false; - } - - @ConfigItem( - keyName = "swapAbyssTeleport", - name = "Teleport to Abyss", - description = "Swap Talk-to with Teleport for the Mage of Zamorak" - ) - default boolean swapAbyssTeleport() - { - return true; - } - - @ConfigItem( - keyName = "swapTrade", - name = "Trade", - description = "Swap Talk-to with Trade on NPC
Example: Shop keeper, Shop assistant" - ) - default boolean swapTrade() - { - return true; - } - - @ConfigItem( - keyName = "swapTravel", - name = "Travel", - description = "Swap Talk-to with Travel, Take-boat, Pay-fare, Charter on NPC
Example: Squire, Monk of Entrana, Customs officer, Trader Crewmember" - ) - default boolean swapTravel() - { - return true; - } -} +/* + * Copyright (c) 2018, Adam + * 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.menuentryswapper; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("menuentryswapper") +public interface MenuEntrySwapperConfig extends Config +{ + @ConfigItem( + position = -2, + keyName = "shiftClickCustomization", + name = "Customizable shift-click", + description = "Allows customization of shift-clicks on items" + ) + default boolean shiftClickCustomization() + { + return true; + } + + @ConfigItem( + keyName = "swapAdmire", + name = "Admire", + description = "Swap Admire with Teleport, Spellbook and Perks (max cape) for mounted skill capes." + ) + default boolean swapAdmire() + { + return true; + } + + @ConfigItem( + keyName = "swapAssignment", + name = "Assignment", + description = "Swap Talk-to with Assignment for Slayer Masters. This will take priority over swapping Trade." + ) + default boolean swapAssignment() + { + return true; + } + + @ConfigItem( + keyName = "swapBanker", + name = "Bank", + description = "Swap Talk-to with Bank on Bank NPC
Example: Banker" + ) + default boolean swapBank() + { + return true; + } + + @ConfigItem( + keyName = "swapBirdhouseEmpty", + name = "Birdhouse", + description = "Swap Interact with Empty for birdhouses on Fossil Island" + ) + default boolean swapBirdhouseEmpty() + { + return true; + } + + @ConfigItem( + keyName = "swapBones", + name = "Bury", + description = "Swap Bury with Use on Bones" + ) + default boolean swapBones() + { + return false; + } + + @ConfigItem( + keyName = "swapContract", + name = "Contract", + description = "Swap Talk-to with Contract on Guildmaster Jane" + ) + default boolean swapContract() + { + return true; + } + + @ConfigItem( + keyName = "swapChase", + name = "Chase", + description = "Allows to left click your cat to chase" + ) + default boolean swapChase() + { + return true; + } + + @ConfigItem( + keyName = "claimSlime", + name = "Claim Slime", + description = "Swap Talk-to with Claim Slime from Morytania diaries" + ) + default boolean claimSlime() + { + return true; + } + + @ConfigItem( + keyName = "swapDarkMage", + name = "Repairs", + description = "Swap Talk-to with Repairs for Dark Mage" + ) + default boolean swapDarkMage() + { + return true; + } + + @ConfigItem( + keyName = "swapDecant", + name = "Decant", + description = "Swap Talk-to with Decant for Bob Barter and Murky Matt at the Grand Exchange." + ) + default boolean swapDecant() + { + return false; + } + + @ConfigItem( + keyName = "swapExchange", + name = "Exchange", + description = "Swap Talk-to with Exchange on NPC
Example: Grand Exchange Clerk, Tool Leprechaun, Void Knight" + ) + default boolean swapExchange() + { + return true; + } + + @ConfigItem( + keyName = "swapFairyRing", + name = "Fairy ring", + description = "Swap Zanaris with Last-destination or Configure on Fairy rings" + ) + default FairyRingMode swapFairyRing() + { + return FairyRingMode.LAST_DESTINATION; + } + + @ConfigItem( + keyName = "swapHarpoon", + name = "Harpoon", + description = "Swap Cage, Big Net with Harpoon on Fishing spot" + ) + default boolean swapHarpoon() + { + return false; + } + + @ConfigItem( + keyName = "swapHomePortal", + name = "Home", + description = "Swap Enter with Home or Build or Friend's house on Portal" + ) + default HouseMode swapHomePortal() + { + return HouseMode.HOME; + } + + @ConfigItem( + keyName = "swapPickpocket", + name = "Pickpocket on H.A.M.", + description = "Swap Talk-to with Pickpocket on H.A.M members" + ) + default boolean swapPickpocket() + { + return true; + } + + @ConfigItem( + keyName = "swapPay", + name = "Pay", + description = "Swap Talk-to with Pay on NPC
Example: Elstan, Heskel, Fayeth" + ) + default boolean swapPay() + { + return true; + } + + @ConfigItem( + keyName = "swapPrivate", + name = "Private", + description = "Swap Shared with Private on the Chambers of Xeric storage units." + ) + default boolean swapPrivate() + { + return false; + } + + @ConfigItem( + keyName = "swapPick", + name = "Pick", + description = "Swap Pick with Pick-lots of the Gourd tree in the Chambers of Xeric" + ) + default boolean swapPick() + { + return false; + } + + @ConfigItem( + keyName = "swapQuick", + name = "Quick Pass/Open/Start/Travel", + description = "Swap Pass with Quick-Pass, Open with Quick-Open, Ring with Quick-Start and Talk-to with Quick-Travel" + ) + default boolean swapQuick() + { + return true; + } + + @ConfigItem( + keyName = "swapBoxTrap", + name = "Reset", + description = "Swap Check with Reset on box trap" + ) + default boolean swapBoxTrap() + { + return true; + } + + @ConfigItem( + keyName = "swapTeleportItem", + name = "Teleport item", + description = "Swap Wear, Wield with Rub, Teleport on teleport item
Example: Amulet of glory, Explorer's ring, Chronicle" + ) + default boolean swapTeleportItem() + { + return false; + } + + @ConfigItem( + keyName = "swapAbyssTeleport", + name = "Teleport to Abyss", + description = "Swap Talk-to with Teleport for the Mage of Zamorak" + ) + default boolean swapAbyssTeleport() + { + return true; + } + + @ConfigItem( + keyName = "swapTrade", + name = "Trade", + description = "Swap Talk-to with Trade on NPC
Example: Shop keeper, Shop assistant" + ) + default boolean swapTrade() + { + return true; + } + + @ConfigItem( + keyName = "swapTravel", + name = "Travel", + description = "Swap Talk-to with Travel, Take-boat, Pay-fare, Charter on NPC
Example: Squire, Monk of Entrana, Customs officer, Trader Crewmember" + ) + default boolean swapTravel() + { + return true; + } +} \ No newline at end of file From 4f4c8c0be919bf12d555a0e72874f86747e333e9 Mon Sep 17 00:00:00 2001 From: James <38226001+james-munson@users.noreply.github.com> Date: Fri, 19 Apr 2019 22:37:07 -0700 Subject: [PATCH 11/75] Custom BA Plugin (#13) * Nothing * Added custom barbarianassault plugin --- .../net/runelite/api/widgets/WidgetID.java | 2 +- .../net/runelite/api/widgets/WidgetInfo.java | 1 + .../BarbarianAssaultConfig.java | 45 ++- .../BarbarianAssaultOverlay.java | 98 +++++- .../BarbarianAssaultPlugin.java | 278 +++++++++++++++--- .../plugins/barbarianassault/Calls.java | 83 ++++++ 6 files changed, 453 insertions(+), 54 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Calls.java 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 8577438af2..fb3825b8e1 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 @@ -556,7 +556,7 @@ public class WidgetID static final int CURRENT_WAVE_WIDGET = 4; static final int CURRENT_WAVE = 5; static final int CALL_WIDGET = 6; - static final int CALL_TEXT = 7; + static final int HEARD_CALL = 7; static final int TO_CALL_WIDGET = 8; static final int TO_CALL = 9; static final int ROLE_SPRITE = 10; 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 65e82471d7..c6a818fc63 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 @@ -351,6 +351,7 @@ public enum WidgetInfo 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), + BA_COLL_HEARD_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.HEARD_CALL), BA_COLL_ROLE_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.ROLE), BA_COLL_ROLE_SPRITE(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.ROLE_SPRITE), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultConfig.java index 52d6a18af5..8ff9ead8da 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultConfig.java @@ -37,17 +37,52 @@ public interface BarbarianAssaultConfig extends Config name = "Show call change timer", description = "Show time to next call change" ) - default boolean showTimer() - { - return true; - } + default boolean showTimer() { return true; } @ConfigItem( keyName = "waveTimes", name = "Show wave and game duration", description = "Displays wave and game duration" + ) + default boolean waveTimes() { return true; } + @ConfigItem( + keyName = "showEggCountMessage", + name = "Show count of eggs collected as collector.", + description = "Display egg count as collector after each wave", + position = 0 + ) + default boolean showEggCount() { return false; } + + @ConfigItem( + keyName = "showEggCountOverlay", + name = "Overlay of eggs counted", + description = "Display current egg count as collector", + position = 1 + ) + default boolean showEggCountOverlay() { return false; } + + @ConfigItem( + keyName = "showHpCountMessage", + name = "Show count of Hp healed as healer.", + description = "Display healed count as healer after each wave", + position = 2 + ) + default boolean showHpCount() { return false; } + + @ConfigItem( + keyName = "showHpCountOverlay", + name = "Overlay of Hp counted", + description = "Display current healed count as healer", + position = 3 + ) + default boolean showHpCountOverlay() { return false; } + + @ConfigItem( + keyName = "highlightCollectorEggs", + name = "Highlight collector eggs", + description = "Highlight called egg colors" ) - default boolean waveTimes() + default boolean highlightCollectorEggs() { return true; } 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 0fdf9edc2e..5bc5959622 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 @@ -24,24 +24,37 @@ */ package net.runelite.client.plugins.barbarianassault; +import java.awt.BasicStroke; +import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; +import java.awt.Polygon; import java.awt.Rectangle; +import java.awt.Stroke; +import java.util.Map; import javax.inject.Inject; import lombok.Getter; import lombok.Setter; import net.runelite.api.Client; import net.runelite.api.GameState; import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import net.runelite.api.Perspective; +import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; import net.runelite.api.widgets.Widget; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayUtil; class BarbarianAssaultOverlay extends Overlay { + private static final int MAX_EGG_DISTANCE = 2500; + private final Client client; private final BarbarianAssaultPlugin plugin; private final BarbarianAssaultConfig config; @@ -82,12 +95,95 @@ class BarbarianAssaultOverlay extends Overlay if (config.showTimer() && roleText != null && roleSprite != null) { - roleText.setText(String.format("00:%02d", currentRound.getTimeToChange())); + if (config.showEggCountOverlay() && role.equals(Role.COLLECTOR)) + { + roleText.setText(String.format("(%d) 00:%02d", plugin.getCollectedEggCount(), currentRound.getTimeToChange())); + } + else if (config.showHpCountOverlay() && role.equals(Role.HEALER)) + { + roleText.setText(String.format("(%d) 00:%02d", plugin.getHpHealed(), currentRound.getTimeToChange())); + } + else + { + roleText.setText(String.format("00:%02d", currentRound.getTimeToChange())); + } Rectangle spriteBounds = roleSprite.getBounds(); roleSprite.setHidden(true); graphics.drawImage(plugin.getClockImage(), spriteBounds.x, spriteBounds.y, null); } + if (role == Role.COLLECTOR && config.highlightCollectorEggs()) + { + String heardCall = plugin.getCollectorHeardCall(); + Color highlightColor; + Map calledEggMap; + + Map yellowEggMap = plugin.getYellowEggs(); + + switch (heardCall) + { + case "Red eggs": + calledEggMap = plugin.getRedEggs(); + highlightColor = Color.RED; + break; + case "Green eggs": + calledEggMap = plugin.getGreenEggs(); + highlightColor = Color.GREEN; + break; + case "Blue eggs": + calledEggMap = plugin.getBlueEggs(); + highlightColor = Color.BLUE; + break; + default: + calledEggMap = null; + highlightColor = null; + } + + if (calledEggMap != null) + { + for (WorldPoint worldPoint : calledEggMap.keySet()) + { + int quantity = calledEggMap.get(worldPoint); + renderEggLocation(graphics, worldPoint, quantity, highlightColor); + } + } + + // Always show yellow eggs + for (WorldPoint worldPoint : yellowEggMap.keySet()) + { + int quantity = yellowEggMap.get(worldPoint); + renderEggLocation(graphics, worldPoint, quantity, highlightColor); + } + } + return null; } + + private void renderEggLocation(Graphics2D graphics, WorldPoint location, int quantity, Color color) + { + LocalPoint groundPoint = LocalPoint.fromWorld(client, location); + Player player = client.getLocalPlayer(); + + if (groundPoint == null || player == null) + { + return; + } + + if (player.getLocalLocation().distanceTo(groundPoint) > MAX_EGG_DISTANCE) + { + return; + } + + Polygon poly = Perspective.getCanvasTilePoly(client, groundPoint); + final Stroke originalStroke = graphics.getStroke(); + + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2)); + graphics.drawPolygon(poly); + graphics.setStroke(originalStroke); + + String quantityText = "x" + quantity; + Point textPoint = Perspective.getCanvasTextLocation(client, graphics, groundPoint, quantityText, 0); + OverlayUtil.renderTextLocation(graphics, textPoint, quantityText, Color.WHITE); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java index 985ef626f5..30e6a56b90 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java @@ -28,13 +28,21 @@ package net.runelite.client.plugins.barbarianassault; import com.google.inject.Provides; import java.awt.Font; import java.awt.Image; +import java.util.HashMap; import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.ItemID; +import net.runelite.api.Player; +import net.runelite.api.Tile; import net.runelite.api.Varbits; +import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; +import net.runelite.api.events.ItemDespawned; +import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.kit.KitType; @@ -58,18 +66,42 @@ import net.runelite.client.util.ImageUtil; description = "Show a timer to the next call change and game/wave duration in chat.", tags = {"minigame", "overlay", "timer"} ) -public class BarbarianAssaultPlugin extends Plugin -{ +public class BarbarianAssaultPlugin extends Plugin { private static final int BA_WAVE_NUM_INDEX = 2; private static final String START_WAVE = "1"; private static final String ENDGAME_REWARD_NEEDLE_TEXT = "
5"; + @Getter + private int collectedEggCount = 0; + @Getter + private int positiveEggCount = 0; + @Getter + private int wrongEggs = 0; + @Getter + private int HpHealed = 0; + @Getter + private int totalCollectedEggCount = 0; + @Getter + private int totalHpHealed = 0; + private Font font; private Image clockImage; private int inGameBit = 0; private String currentWave = START_WAVE; private GameTimer gameTime; + @Getter(AccessLevel.PACKAGE) + private HashMap redEggs; + + @Getter(AccessLevel.PACKAGE) + private HashMap greenEggs; + + @Getter(AccessLevel.PACKAGE) + private HashMap blueEggs; + + @Getter(AccessLevel.PACKAGE) + private HashMap yellowEggs; + @Inject private Client client; @@ -86,45 +118,69 @@ public class BarbarianAssaultPlugin extends Plugin private BarbarianAssaultOverlay overlay; @Provides - BarbarianAssaultConfig provideConfig(ConfigManager configManager) - { + BarbarianAssaultConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(BarbarianAssaultConfig.class); } @Override - protected void startUp() throws Exception - { + protected void startUp() throws Exception { overlayManager.add(overlay); font = FontManager.getRunescapeFont() - .deriveFont(Font.BOLD, 24); + .deriveFont(Font.BOLD, 24); clockImage = ImageUtil.getResourceStreamFromClass(getClass(), "clock.png"); + + redEggs = new HashMap<>(); + greenEggs = new HashMap<>(); + blueEggs = new HashMap<>(); + yellowEggs = new HashMap<>(); } @Override - protected void shutDown() throws Exception - { + protected void shutDown() throws Exception { overlayManager.remove(overlay); gameTime = null; currentWave = START_WAVE; inGameBit = 0; + collectedEggCount = 0; + positiveEggCount = 0; + wrongEggs = 0; + HpHealed = 0; } @Subscribe - public void onWidgetLoaded(WidgetLoaded event) - { - if (event.getGroupId() == WidgetID.BA_REWARD_GROUP_ID) - { + public void onWidgetLoaded(WidgetLoaded event) { + if (event.getGroupId() == WidgetID.BA_REWARD_GROUP_ID) { Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT); + String amt,type,totalMsg,total; + amt=type=totalMsg=total=""; + if (config.waveTimes() && rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null) { + if (config.showHpCount() && HpHealed > 0) { + totalMsg = "; Total Healed: "; + total = ""+totalHpHealed; + if (HpHealed > 504) + { + total = ""+504; + } + } + else if (config.showEggCount() && collectedEggCount > 0) { + collectedEggCount -= wrongEggs; //true positive egg count + if (collectedEggCount > 60) + { + collectedEggCount = 60; + } + collectedEggCount -= wrongEggs; //true positive - negative egg count\ + totalMsg = "; Total Collected: "; + total = "" + totalCollectedEggCount; - if (config.waveTimes() && rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null) - { - announceTime("Game finished, duration: ", gameTime.getTime(false)); + } + announceTime("Game finished, duration: ", gameTime.getTime(false),type, amt, totalMsg, total); } } } @Subscribe + public void onChatMessage(ChatMessage event) { if (event.getType() == ChatMessageType.GAMEMESSAGE @@ -132,28 +188,36 @@ public class BarbarianAssaultPlugin extends Plugin { String[] message = event.getMessage().split(" "); currentWave = message[BA_WAVE_NUM_INDEX]; + collectedEggCount = 0; + HpHealed = 0; - if (currentWave.equals(START_WAVE)) - { + if (currentWave.equals(START_WAVE)) { gameTime = new GameTimer(); - } - else if (gameTime != null) - { + totalHpHealed = 0; + totalCollectedEggCount = 0; + } else if (gameTime != null) { gameTime.setWaveStartTime(); } + } else if (event.getType() == ChatMessageType.GAMEMESSAGE + && event.getMessage().contains("egg explode")) { + wrongEggs --; + } else if (event.getType() == ChatMessageType.GAMEMESSAGE + && event.getMessage().contains("healed")) { + String message = event.getMessage(); + String[] tokens = message.split(" "); + if (Integer.parseInt(tokens[2]) > 0) { + int Hp = Integer.parseInt(tokens[2]); + HpHealed += Hp; + } } } @Subscribe - public void onGameTick(GameTick event) - { - if (client.getVar(Varbits.IN_GAME_BA) == 0 || client.getLocalPlayer() == null || overlay.getCurrentRound() != null) - { + public void onGameTick(GameTick event) { + if (client.getVar(Varbits.IN_GAME_BA) == 0 || client.getLocalPlayer() == null || overlay.getCurrentRound() != null) { return; } - - switch (client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.CAPE)) - { + switch (client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.CAPE)) { case ItemID.ATTACKER_ICON: overlay.setCurrentRound(new Round(Role.ATTACKER)); break; @@ -170,39 +234,159 @@ public class BarbarianAssaultPlugin extends Plugin } @Subscribe - public void onVarbitChanged(VarbitChanged event) - { + public void onVarbitChanged(VarbitChanged event) { int inGame = client.getVar(Varbits.IN_GAME_BA); - - if (inGameBit != inGame) - { - if (inGameBit == 1) - { + String amt,type,totalMsg,total; + amt=type=totalMsg=total=""; + if (inGameBit != inGame) { + if (inGameBit == 1) { overlay.setCurrentRound(null); - if (config.waveTimes() && gameTime != null) - { - announceTime("Wave " + currentWave + " duration: ", gameTime.getTime(true)); + if (config.waveTimes() && gameTime != null) { + totalCollectedEggCount += collectedEggCount; + totalHpHealed += HpHealed; + if (config.showHpCount() && HpHealed > 0) { + amt = "" + HpHealed; + type = "; Healed: "; + totalMsg = "; Total Healed: "; + total = ""+totalHpHealed; + } + else if (config.showEggCount() && collectedEggCount > 0) { + amt = "" + collectedEggCount; + type = "; Collected: "; + totalMsg = "; Total Collected: "; + total = ""+totalCollectedEggCount; + } + if (currentWave.equals("10")) + { + totalMsg=total=""; + } + announceTime("Wave " + currentWave + " duration: ", gameTime.getTime(true), type, amt, totalMsg, total); } + } } inGameBit = inGame; } - private void announceTime(String preText, String time) + @Subscribe + public void onItemSpawned(ItemSpawned itemSpawned) { + int itemId = itemSpawned.getItem().getId(); + WorldPoint worldPoint = itemSpawned.getTile().getWorldLocation(); + HashMap eggMap = getEggMap(itemId); + + if (eggMap != null) + { + Integer existingQuantity = eggMap.putIfAbsent(worldPoint, 1); + if (existingQuantity != null) + { + eggMap.put(worldPoint, existingQuantity + 1); + } + } + } + + @Subscribe + public void onItemDespawned(ItemDespawned itemDespawned) + { + int itemId = itemDespawned.getItem().getId(); + WorldPoint worldPoint = itemDespawned.getTile().getWorldLocation(); + HashMap eggMap = getEggMap(itemId); + + if (eggMap != null && eggMap.containsKey(worldPoint)) + { + int quantity = eggMap.get(worldPoint); + if (quantity > 1) + { + eggMap.put(worldPoint, quantity - 1); + } + else + { + eggMap.remove(worldPoint); + } + } + if (client.getVar(Varbits.IN_GAME_BA) == 0 || !isEgg(itemDespawned.getItem().getId())) + { + return; + } + if (isUnderPlayer(itemDespawned.getTile())) + { + collectedEggCount++; + } + } + + String getCollectorHeardCall() + { + Widget widget = client.getWidget(WidgetInfo.BA_COLL_HEARD_TEXT); + String call = null; + + if (widget != null) + { + call = widget.getText(); + } + + return call; + } + + private HashMap getEggMap(int itemID) + { + switch (itemID) + { + case ItemID.RED_EGG: + return redEggs; + case ItemID.GREEN_EGG: + return greenEggs; + case ItemID.BLUE_EGG: + return blueEggs; + case ItemID.YELLOW_EGG: + return yellowEggs; + default: + return null; + } + } + + + private void announceTime(String preText, String time, String type, String amt, String totalMsg, String total) { final String chatMessage = new ChatMessageBuilder() - .append(ChatColorType.NORMAL) - .append(preText) - .append(ChatColorType.HIGHLIGHT) - .append(time) - .build(); + .append(ChatColorType.NORMAL) + .append(preText) + .append(ChatColorType.HIGHLIGHT) + .append(time) + .append(ChatColorType.NORMAL) + .append(type) + .append(ChatColorType.HIGHLIGHT) + .append(amt) + .append(ChatColorType.NORMAL) + .append(totalMsg) + .append(ChatColorType.HIGHLIGHT) + .append(total) + .build(); chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.CONSOLE) - .runeLiteFormattedMessage(chatMessage) - .build()); + .type(ChatMessageType.CONSOLE) + .runeLiteFormattedMessage(chatMessage) + .build()); + } + + private boolean isEgg(int itemID) + { + if (itemID == ItemID.RED_EGG || itemID == ItemID.GREEN_EGG + || itemID == ItemID.BLUE_EGG || itemID == ItemID.YELLOW_EGG) + { + return true; + } + return false; + } + + private boolean isUnderPlayer(Tile tile) { + Player local = client.getLocalPlayer(); + if (local == null) + { + return false; + } + + return (tile.getWorldLocation().equals(local.getWorldLocation())); } public Font getFont() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Calls.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Calls.java new file mode 100644 index 0000000000..23d726f10e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Calls.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2018, Cameron + * 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 java.util.HashMap; +import java.util.Map; + +public enum Calls +{ //Attacker Calls + RED_EGG("Red egg", "Tell-red"), + GREEN_EGG("Green egg", "Tell-green"), + BLUE_EGG("Blue egg", "Tell-blue"), + //Collector Calls + CONTROLLED("Controlled/Bullet/Wind", "Tell-controlled"), + ACCURATE("Accurate/Field/Water", "Tell-accurate"), + AGGRESSIVE("Aggressive/Blunt/Earth", "Tell-aggressive"), + DEFENSIVE("Defensive/Barbed/Fire", "Tell-defensive"), + //Healer Calls + TOFU("Tofu", "Tell-tofu"), + CRACKERS("Crackers", "Tell-crackers"), + WORMS("Worms", "Tell-worms"), + //Defender Calls + POIS_WORMS("Pois. Worms", "Tell-worms"), + POIS_TOFU("Pois. Tofu", "Tell-tofu"), + POIS_MEAT("Pois. Meat", "Tell-meat"); + + private final String call; + private final String option; + + private static final Map CALL_MENU = new HashMap<>(); + + static + { + for (Calls s : values()) + { + CALL_MENU.put(s.getCall(), s.getOption()); + } + } + + Calls(String call, String option) + { + this.call = call; + this.option = option; + } + + public String getCall() + { + return call; + } + + public String getOption() + { + return option; + } + + public static String getOption(String call) + { + return CALL_MENU.get(call); + } + +} \ No newline at end of file From 3f729479457a9a47efd7a597302136422affa523 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 06:38:08 +0100 Subject: [PATCH 12/75] Whale Watchers plugin (#12) Whale Watchers plugin --- whalewatchers/WhaleWatchersConfig.java | 34 +++ whalewatchers/WhaleWatchersGloryOverlay.java | 48 +++++ whalewatchers/WhaleWatchersOverlay.java | 51 +++++ whalewatchers/WhaleWatchersPlugin.java | 194 ++++++++++++++++++ whalewatchers/WhaleWatchersProtOverlay.java | 44 ++++ .../WhaleWatchersSmiteableOverlay.java | 39 ++++ 6 files changed, 410 insertions(+) create mode 100644 whalewatchers/WhaleWatchersConfig.java create mode 100644 whalewatchers/WhaleWatchersGloryOverlay.java create mode 100644 whalewatchers/WhaleWatchersOverlay.java create mode 100644 whalewatchers/WhaleWatchersPlugin.java create mode 100644 whalewatchers/WhaleWatchersProtOverlay.java create mode 100644 whalewatchers/WhaleWatchersSmiteableOverlay.java diff --git a/whalewatchers/WhaleWatchersConfig.java b/whalewatchers/WhaleWatchersConfig.java new file mode 100644 index 0000000000..75436c045c --- /dev/null +++ b/whalewatchers/WhaleWatchersConfig.java @@ -0,0 +1,34 @@ +package net.runelite.client.plugins.whalewatchers; + +import java.awt.*; +import net.runelite.client.config.*; + +@ConfigGroup("WhaleWatchers") +public interface WhaleWatchersConfig extends Config +{ + @ConfigItem(position = 1, keyName = "protectItemWarning", name = "Protect Item Warning", description = "Warns you when you are skulled and don't have protect item turned on.") + default boolean protectItemWarning() { + return false; + } + + @ConfigItem(position = 2, keyName = "showDamageCounter", name = "Damage Counter", description = "Shows damage you've done and damage your opponent has done to you while in a fight") + default boolean showDamageCounter() { + return true; + } + + @Alpha + @ConfigItem(position = 3, keyName = "damageBackgroundColor", name = "Counter Background Color", description = "The background color for the damage counter overlay") + default Color damageBackgroundColor() { + return Color.darkGray; + } + + @ConfigItem(position = 4, keyName = "smiteableWarning", name = "Smite Warning", description = "Displays a warning overlay when your prayer is at a smiteable level") + default boolean smiteableWarning() { + return true; + } + + @ConfigItem(position = 5, keyName = "gloryWarning", name = "Glory Warning", description = "Displays a warning box while you are wearing an uncharged glory") + default boolean gloryWarning() { + return true; + } +} diff --git a/whalewatchers/WhaleWatchersGloryOverlay.java b/whalewatchers/WhaleWatchersGloryOverlay.java new file mode 100644 index 0000000000..dd30579485 --- /dev/null +++ b/whalewatchers/WhaleWatchersGloryOverlay.java @@ -0,0 +1,48 @@ +package net.runelite.client.plugins.whalewatchers; + +import net.runelite.api.*; +import javax.inject.*; +import net.runelite.client.ui.overlay.*; +import net.runelite.api.kit.*; +import java.awt.*; +import net.runelite.client.ui.overlay.components.*; +import java.awt.image.*; +import net.runelite.client.game.*; + +public class WhaleWatchersGloryOverlay extends Overlay +{ + private Client client; + private final WhaleWatchersConfig config; + private WhaleWatchersPlugin plugin; + private PanelComponent panelComponent; + @Inject + private ItemManager itemManager; + + @Inject + public WhaleWatchersGloryOverlay(final WhaleWatchersConfig config, final Client client, final WhaleWatchersPlugin plugin) { + this.client = client; + this.config = config; + this.plugin = plugin; + this.setLayer(OverlayLayer.ABOVE_WIDGETS); + this.setPriority(OverlayPriority.HIGH); + this.setPosition(OverlayPosition.DETACHED); + this.panelComponent = new PanelComponent(); + } + + @Override + public Dimension render(final Graphics2D graphics) { + this.panelComponent.getChildren().clear(); + int amuletID = 0; + try { + amuletID = this.client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.AMULET); + } + catch (NullPointerException ex) {} + if (this.config.gloryWarning() && amuletID == 1704) { + this.panelComponent.setBackgroundColor(Color.lightGray); + final AsyncBufferedImage gloryImage = this.itemManager.getImage(1704); + this.panelComponent.getChildren().add(TitleComponent.builder().text("Uncharged Glory").color(Color.BLACK).build()); + this.panelComponent.getChildren().add(new ImageComponent(gloryImage)); + } + return this.panelComponent.render(graphics); + } +} diff --git a/whalewatchers/WhaleWatchersOverlay.java b/whalewatchers/WhaleWatchersOverlay.java new file mode 100644 index 0000000000..2365bbfe38 --- /dev/null +++ b/whalewatchers/WhaleWatchersOverlay.java @@ -0,0 +1,51 @@ +package net.runelite.client.plugins.whalewatchers; + +import net.runelite.api.*; +import net.runelite.client.ui.overlay.*; +import javax.inject.*; +import net.runelite.client.ui.overlay.components.*; +import java.awt.*; + +public class WhaleWatchersOverlay extends Overlay +{ + private Client client; + private final WhaleWatchersConfig config; + private WhaleWatchersPlugin plugin; + private PanelComponent panelComponent; + private String lastOpponent; + + @Inject + public WhaleWatchersOverlay(final WhaleWatchersConfig config, final Client client, final WhaleWatchersPlugin plugin) { + this.lastOpponent = "-"; + this.client = client; + this.config = config; + this.plugin = plugin; + this.setLayer(OverlayLayer.ABOVE_WIDGETS); + this.setPriority(OverlayPriority.HIGH); + this.setPosition(OverlayPosition.DETACHED); + this.panelComponent = new PanelComponent(); + } + + @Override + public Dimension render(final Graphics2D graphics) { + this.panelComponent.getChildren().clear(); + if (this.plugin.inCombat && this.config.showDamageCounter()) { + this.panelComponent.setBackgroundColor(this.config.damageBackgroundColor()); + final String opp = (this.client.getLocalPlayer().getInteracting() != null) ? this.client.getLocalPlayer().getInteracting().getName() : this.lastOpponent; + if (this.client.getLocalPlayer().getInteracting() != null) { + this.lastOpponent = this.client.getLocalPlayer().getInteracting().getName(); + } + final String opponent = "Fight vs " + opp; + final String damageTaken = "Damage Taken: " + this.plugin.damageTaken; + final String damageDealt = "Damage Dealt: " + this.plugin.damageDone; + this.panelComponent.getChildren().add(TitleComponent.builder().text(opponent).color(Color.BLACK).build()); + this.panelComponent.getChildren().add(TitleComponent.builder().text(damageDealt).color(Color.BLACK).build()); + this.panelComponent.getChildren().add(TitleComponent.builder().text(damageTaken).color(Color.BLACK).build()); + this.panelComponent.setPreferredSize(new Dimension(graphics.getFontMetrics().stringWidth(damageDealt) + graphics.getFontMetrics().stringWidth(opponent) + 10, 0)); + } + else { + this.panelComponent.getChildren().clear(); + } + return this.panelComponent.render(graphics); + } +} diff --git a/whalewatchers/WhaleWatchersPlugin.java b/whalewatchers/WhaleWatchersPlugin.java new file mode 100644 index 0000000000..3d6fc5fe97 --- /dev/null +++ b/whalewatchers/WhaleWatchersPlugin.java @@ -0,0 +1,194 @@ +package net.runelite.client.plugins.whalewatchers; + + +import org.jetbrains.annotations.*; +import net.runelite.client.plugins.*; +import net.runelite.client.game.*; +import net.runelite.client.config.*; +import com.google.inject.*; +import net.runelite.client.ui.overlay.*; +import net.runelite.client.eventbus.*; +import net.runelite.api.kit.*; +import org.apache.commons.lang3.*; +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) +public class WhaleWatchersPlugin extends Plugin +{ + @Inject + private Client client; + @Inject + private WhaleWatchersConfig config; + @Inject + private WhaleWatchersOverlay overlay; + @Inject + private WhaleWatchersProtOverlay whaleWatchersProtOverlay; + @Inject + private WhaleWatchersSmiteableOverlay whaleWatchersSmiteableOverlay; + @Inject + private WhaleWatchersGloryOverlay whaleWatchersGloryOverlay; + @Inject + private OverlayManager overlayManager; + @Inject + private ItemManager itemManager; + public boolean enableOverlay; + private int lastXP; + public int damageDone; + public int damageTaken; + public boolean inCombat; + private int tickCountdown; + private boolean displaySmiteOverlay; + private boolean displayGloryOverlay; + + public WhaleWatchersPlugin() { + this.enableOverlay = false; + this.lastXP = 0; + this.damageDone = 0; + this.damageTaken = 0; + this.inCombat = false; + this.tickCountdown = 0; + } + + @Provides + WhaleWatchersConfig getConfig(final ConfigManager configManager) { + return configManager.getConfig(WhaleWatchersConfig.class); + } + + @Override + protected void startUp() throws Exception { + this.overlayManager.add(this.overlay); + this.overlayManager.add(this.whaleWatchersProtOverlay); + this.overlayManager.add(this.whaleWatchersSmiteableOverlay); + this.overlayManager.add(this.whaleWatchersGloryOverlay); + } + + @Override + protected void shutDown() throws Exception { + this.overlayManager.remove(this.overlay); + this.overlayManager.remove(this.whaleWatchersProtOverlay); + this.overlayManager.remove(this.whaleWatchersSmiteableOverlay); + this.overlayManager.remove(this.whaleWatchersGloryOverlay); + } + + @Subscribe + public void onHitsplatApplied(final HitsplatApplied event) { + if (this.config.showDamageCounter()) { + if (!(event.getActor() == this.client.getLocalPlayer() | event.getActor() == this.client.getLocalPlayer().getInteracting())) { + return; + } + if (this.isAttackingPlayer(this.client) || this.inCombat) { + this.inCombat = true; + if (event.getActor() == this.client.getLocalPlayer()) { + this.damageTaken += event.getHitsplat().getAmount(); + } + if (event.getActor() == this.client.getLocalPlayer().getInteracting()) { + this.damageDone += event.getHitsplat().getAmount(); + } + } + } + } + + @Subscribe + public void onItemContainerChanged(final ItemContainerChanged event) { + if (this.config.gloryWarning() && event.getItemContainer().equals(InventoryID.EQUIPMENT)) { + final int amuletID = ObjectUtils.defaultIfNull(this.client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.AMULET), 0); + if (amuletID == 1704) { + this.displayGloryOverlay = true; + } + else { + this.displayGloryOverlay = false; + } + } + else { + this.displayGloryOverlay = false; + } + } + + @Subscribe + public void onExperienceChanged(final ExperienceChanged event) { + final Skill skill = event.getSkill(); + final Player player = this.client.getLocalPlayer(); + if (skill.equals(Skill.HITPOINTS) && player.getInteracting() instanceof Player) { + this.lastXP = this.client.getSkillExperience(skill); + } + } + + @Subscribe + public void onMenuOptionClicked(final MenuOptionClicked event) { + if (this.config.showDamageCounter() && event.getMenuAction().equals(MenuAction.SPELL_CAST_ON_PLAYER)) { + this.inCombat = true; + } + } + + @Subscribe + public void onVarbitChanged(final VarbitChanged event) { + if (this.config.showDamageCounter() && this.client.getVar(VarPlayer.ATTACKING_PLAYER) == -1 && this.inCombat) { + this.tickCountdown = 10; + } + if (this.config.protectItemWarning()) { + try { + if (this.client.getLocalPlayer().getSkullIcon() == SkullIcon.SKULL) { + if ((this.client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 0 && this.client.getVar(Varbits.IN_WILDERNESS) == 1) || this.client.getWorldType().contains(WorldType.PVP)) { + this.enableOverlay = true; + } + if (this.client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 1 || this.client.getVar(Varbits.IN_WILDERNESS) == 0 || this.client.getWorldType().contains(WorldType.PVP_HIGH_RISK) || this.client.getWorld() == 365) { + this.enableOverlay = false; + } + } + else { + this.enableOverlay = false; + } + } + catch (NullPointerException ex) {} + } + } + + @Subscribe + public void onGameTick(final GameTick event) { + if (this.tickCountdown > 0 && this.tickCountdown < 11) { + --this.tickCountdown; + if (this.tickCountdown == 1 && !this.isAttackingPlayer(this.client)) { + this.inCombat = false; + this.damageDone = 0; + this.damageTaken = 0; + return; + } + } + if (this.config.smiteableWarning() && (this.client.getVar(Varbits.IN_WILDERNESS) == 1 || WorldType.isPvpWorld(this.client.getWorldType()))) { + if (this.client.getLocalPlayer().getSkullIcon() != null && this.client.getLocalPlayer().getSkullIcon().equals(SkullIcon.SKULL)) { + final int currentHealth = this.client.getLocalPlayer().getHealth(); + final int currentPrayer = this.client.getBoostedSkillLevel(Skill.PRAYER); + if (currentPrayer <= Math.ceil(currentHealth / 4)) { + this.displaySmiteOverlay = true; + } + else { + this.displaySmiteOverlay = false; + } + } + else { + this.displaySmiteOverlay = false; + } + } + else { + this.displaySmiteOverlay = false; + } + } + + public boolean isAttackingPlayer(@NotNull final Client c) { + if (this.client.getVar(Varbits.IN_WILDERNESS) == 1 && this.client.getLocalPlayer().getInteracting() != null) { + return true; + } + final int varp = c.getVar(VarPlayer.ATTACKING_PLAYER); + return varp != -1; + } + + public boolean isDisplaySmiteOverlay() { + return this.displaySmiteOverlay; + } + + public boolean isDisplayGloryOverlay() { + return this.displayGloryOverlay; + } +} diff --git a/whalewatchers/WhaleWatchersProtOverlay.java b/whalewatchers/WhaleWatchersProtOverlay.java new file mode 100644 index 0000000000..5c8fa24b84 --- /dev/null +++ b/whalewatchers/WhaleWatchersProtOverlay.java @@ -0,0 +1,44 @@ +package net.runelite.client.plugins.whalewatchers; + +import javax.inject.*; + +import net.runelite.api.Point; +import net.runelite.client.ui.*; +import net.runelite.api.*; +import net.runelite.client.ui.overlay.*; +import java.awt.*; + +public class WhaleWatchersProtOverlay extends Overlay +{ + private Client client; + private final WhaleWatchersConfig config; + private WhaleWatchersPlugin plugin; + + @Inject + public WhaleWatchersProtOverlay(final WhaleWatchersConfig config, final Client client, final WhaleWatchersPlugin plugin) { + this.client = client; + this.config = config; + this.plugin = plugin; + this.setLayer(OverlayLayer.ABOVE_WIDGETS); + this.setPriority(OverlayPriority.HIGH); + this.setPosition(OverlayPosition.DYNAMIC); + } + + @Override + public Dimension render(final Graphics2D graphics) { + if (this.plugin.enableOverlay && this.config.protectItemWarning()) { + final Rectangle rectangle = new Rectangle(); + rectangle.setBounds(this.client.getCanvas().getBounds()); + rectangle.setLocation(this.client.getCanvas().getLocation()); + final Stroke oldStroke = graphics.getStroke(); + graphics.setStroke(new BasicStroke(10.0f)); + graphics.setColor(Color.RED); + graphics.draw(rectangle); + final Font font = FontManager.getRunescapeBoldFont().deriveFont(1, 72.0f); + graphics.setFont(font); + OverlayUtil.renderTextLocation(graphics, new Point((int)rectangle.getCenterX() - 50, font.getSize()), "Protect item prayer disabled!!!", Color.red); + graphics.setStroke(oldStroke); + } + return null; + } +} diff --git a/whalewatchers/WhaleWatchersSmiteableOverlay.java b/whalewatchers/WhaleWatchersSmiteableOverlay.java new file mode 100644 index 0000000000..683841d246 --- /dev/null +++ b/whalewatchers/WhaleWatchersSmiteableOverlay.java @@ -0,0 +1,39 @@ +package net.runelite.client.plugins.whalewatchers; + +import net.runelite.api.*; +import net.runelite.client.ui.overlay.*; +import javax.inject.*; +import java.awt.*; +import net.runelite.client.ui.overlay.components.*; + +public class WhaleWatchersSmiteableOverlay extends Overlay +{ + private Client client; + private WhaleWatchersPlugin plugin; + private PanelComponent panelComponent; + + @Inject + public WhaleWatchersSmiteableOverlay(final WhaleWatchersPlugin plugin) { + this.plugin = plugin; + this.setLayer(OverlayLayer.ABOVE_WIDGETS); + this.setPriority(OverlayPriority.HIGH); + this.setPosition(OverlayPosition.BOTTOM_RIGHT); + this.panelComponent = new PanelComponent(); + } + + @Override + public Dimension render(final Graphics2D graphics) { + final String subText = "You could be smited in 1 tick"; + this.panelComponent.getChildren().clear(); + if (this.plugin.isDisplaySmiteOverlay()) { + this.panelComponent.setBackgroundColor(Color.WHITE); + this.panelComponent.getChildren().add(TitleComponent.builder().text("LOW PRAYER WARNING").color(Color.BLACK).build()); + this.panelComponent.getChildren().add(TitleComponent.builder().text(subText).color(Color.BLACK).build()); + this.panelComponent.setPreferredSize(new Dimension(graphics.getFontMetrics().stringWidth(subText) + 20, 0)); + } + else { + this.panelComponent.getChildren().clear(); + } + return this.panelComponent.render(graphics); + } +} From b172851dc366bd7e80c0ebed734b79230d4f25e6 Mon Sep 17 00:00:00 2001 From: zeruth Date: Sat, 20 Apr 2019 05:00:24 -0400 Subject: [PATCH 13/75] Plugin Organizer Allows Hiding, and recoloring of types of plugins: Currently Types are PVM, PVP, Utility All types are organized alphabetically individually Types are declared in PluginDescriptor as type = "PVP" etc HTML tags are removed, and we use Java colors now All current plugins updated to use the new system Plugin Organizer is located at the bottom of plugin list for less visibilty. Plugins enabled/disabled is remembered and applied automatically on startup --- .../client/plugins/PluginDescriptor.java | 2 + .../plugins/aoewarnings/AoeWarningConfig.java | 13 ++ .../plugins/aoewarnings/AoeWarningPlugin.java | 5 +- .../clanmanmode/ClanManModePlugin.java | 5 +- .../client/plugins/config/ConfigPanel.java | 100 ++++++++++++-- .../client/plugins/config/PluginListItem.java | 24 ++-- .../EquipmentInspectorPlugin.java | 6 +- .../FightCaveJadHelperPlugin.java | 3 +- .../FightCaveWaveHelperPlugin.java | 3 +- .../freezetimers/FreezeTimersPlugin.java | 5 +- .../GrotesqueGuardiansPlugin.java | 5 +- .../hideprayers/HidePrayersPlugin.java | 5 +- .../kittennotifier/KittenNotifierPlugin.java | 7 +- .../LizardmenShamanPlugin.java | 5 +- .../menumodifier/MenuModifierPlugin.java | 5 +- .../MapLocations.java | 2 +- .../MultiIndicatorsConfig.java} | 6 +- .../MultiIndicatorsMinimapOverlay.java} | 10 +- .../MultiIndicatorsOverlay.java} | 10 +- .../MultiIndicatorsPlugin.java} | 19 +-- .../ZoneVisibility.java | 2 +- .../NextHitNotifierPlugin.java | 5 +- .../plugins/pkvision/PKVisionPlugin.java | 5 +- .../pluginsorter/PluginSorterConfig.java | 60 +++++++++ .../pluginsorter/PluginSorterPlugin.java | 124 ++++++++++++++++++ .../PrayAgainstPlayerPlugin.java | 5 +- .../shiftwalker/ShiftWalkerPlugin.java | 5 +- .../slayermusiq/SlayermusiqPlugin.java | 5 +- .../tickcounter/TickCounterPlugin.java | 5 +- .../client/plugins/vetion/VetionPlugin.java | 5 +- .../client/plugins/vorkath/VorkathPlugin.java | 5 +- .../client/plugins/ztob/TheatrePlugin.java | 3 +- .../client/plugins/zulrah/ZulrahPlugin.java | 5 +- 33 files changed, 393 insertions(+), 81 deletions(-) rename runelite-client/src/main/java/net/runelite/client/plugins/{zoneIndicators => multiindicators}/MapLocations.java (99%) rename runelite-client/src/main/java/net/runelite/client/plugins/{zoneIndicators/ZoneIndicatorsConfig.java => multiindicators/MultiIndicatorsConfig.java} (96%) rename runelite-client/src/main/java/net/runelite/client/plugins/{zoneIndicators/ZoneIndicatorsMinimapOverlay.java => multiindicators/MultiIndicatorsMinimapOverlay.java} (94%) rename runelite-client/src/main/java/net/runelite/client/plugins/{zoneIndicators/ZoneIndicatorsOverlay.java => multiindicators/MultiIndicatorsOverlay.java} (95%) rename runelite-client/src/main/java/net/runelite/client/plugins/{zoneIndicators/ZoneIndicatorsPlugin.java => multiindicators/MultiIndicatorsPlugin.java} (95%) rename runelite-client/src/main/java/net/runelite/client/plugins/{zoneIndicators => multiindicators}/ZoneVisibility.java (96%) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java 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/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/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..02ad6e0b35 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 = "PVP" ) @Slf4j 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/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/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/kittennotifier/KittenNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java index 921dcd4a46..4b6baf66a9 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 @@ -54,7 +55,7 @@ public class KittenNotifierPlugin extends Plugin{ 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/PKVisionPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionPlugin.java index 6fc74fb2c2..5aeb136c66 100644 --- 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 @@ -18,10 +18,11 @@ import net.runelite.client.util.MiscUtils; import net.runelite.client.util.Text; @PluginDescriptor( - name = "!PK Vision", + name = "PK Vision", description = "Highlight players on-screen and/or on the minimap", tags = {"highlight", "minimap", "overlay", "players", "pk", "helper", "vision", "bogla"}, - enabledByDefault = false + enabledByDefault = false, + type = "PVP" ) public class PKVisionPlugin extends Plugin { 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..2e7604f536 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java @@ -0,0 +1,124 @@ +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/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/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/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/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/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 { From 3533a07f30f2146f7f58cdcc2ce8a73e22bb6f61 Mon Sep 17 00:00:00 2001 From: zeruth Date: Sat, 20 Apr 2019 05:12:41 -0400 Subject: [PATCH 14/75] Update PluginSorterPlugin.java Fix NPE --- .../client/plugins/pluginsorter/PluginSorterPlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 index 2e7604f536..ca7f54c836 100644 --- 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 @@ -92,7 +92,7 @@ public class PluginSorterPlugin extends Plugin { Iterator iter = ConfigPanel.pluginList.iterator(); while (iter.hasNext()) { PluginListItem pli = iter.next(); - if (pli.getPlugin() != null) + 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(); @@ -108,6 +108,7 @@ public class PluginSorterPlugin extends Plugin { iter.remove(); removedPlugins.add(pli); } + } } } From 5bd8aaa148a3e25923091fa23daa480b648985b0 Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Sat, 20 Apr 2019 12:48:41 +0100 Subject: [PATCH 15/75] Add Ammo plugin (#8113) Shows the current ammo the player has equipped. If the player is using a stackable weapon (chinchompas, darts, etc) those will show, otherwise it'll show the ammo slot (unless the item is a blessing or empty) If the value is over 1,000,000 the number will have an M. If it's over 10,000 the number will have a K. Closes #864 --- .../client/plugins/ammo/AmmoCounter.java | 57 +++++++ .../client/plugins/ammo/AmmoPlugin.java | 142 ++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoCounter.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoPlugin.java 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..f7f12c497a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoCounter.java @@ -0,0 +1,57 @@ +/* + * 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; + +class AmmoCounter extends Counter +{ + @Getter + private final int itemID; + private final String name; + + 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..c42838f07c --- /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", "equipment"} +) +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 + protected void startUp() throws Exception + { + clientThread.invokeLater(() -> + { + final ItemContainer container = client.getItemContainer(InventoryID.EQUIPMENT); + + if (container != null) + { + checkInventory(container.getItems()); + } + }); + } + + @Override + protected void shutDown() throws Exception + { + infoBoxManager.removeInfoBox(counterBox); + counterBox = null; + } + + @Subscribe + public void onItemContainerChanged(ItemContainerChanged event) + { + if (event.getItemContainer() != client.getItemContainer(InventoryID.EQUIPMENT)) + { + return; + } + + checkInventory(event.getItemContainer().getItems()); + } + + private void checkInventory(final 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(final Item item, final 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); + } +} From 3d98e215a2b75f8ccc3872937c27d1f9b3be1799 Mon Sep 17 00:00:00 2001 From: Sergz39 <45315230+ksergio39@users.noreply.github.com> Date: Sat, 20 Apr 2019 08:05:08 -0400 Subject: [PATCH 16/75] Fix Pirate's tresure quest start location (#8564) Closes #8560 --- .../runelite/client/plugins/worldmap/QuestStartLocation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 77157bb490..b49a56a2a0 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 @@ -41,7 +41,7 @@ enum QuestStartLocation IMP_CATCHER("Imp Catcher", new WorldPoint(3108, 3160, 0)), THE_KNIGHTS_SWORD("The Knight's Sword", new WorldPoint(2976, 3342, 0)), MISTHALIN_MYSTERY("Misthalin Mystery", new WorldPoint(3234, 3155, 0)), - PIRATES_TREASURE("Pirate's Treasure", new WorldPoint(3050, 3248, 0)), + PIRATES_TREASURE("Pirate's Treasure", new WorldPoint(3051, 3252, 0)), PRINCE_ALI_RESCUE("Prince Ali Rescue", new WorldPoint(3301, 3163, 0)), THE_RESTLESS_GHOST("The Restless Ghost", new WorldPoint(3240, 3210, 0)), RUNE_MYSTERIES("Rune Mysteries", new WorldPoint(3210, 3220, 0)), From e7cdf50cfb0184510bd0e9f65eec1b67aeb1c85e Mon Sep 17 00:00:00 2001 From: Jamy C Date: Thu, 18 Apr 2019 22:09:38 +0200 Subject: [PATCH 17/75] Add missing Neitiznot bridges agility shortcuts --- .../main/java/net/runelite/client/game/AgilityShortcut.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java index 6c62b3e081..33cbdb1510 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java +++ b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java @@ -108,6 +108,10 @@ public enum AgilityShortcut AL_KHARID_MINING_PITCLIFF_SCRAMBLE(38, "Rocks", new WorldPoint(3305, 3315, 0), ROCKS_16549, ROCKS_16550), YANILLE_WALL_GRAPPLE(39, "Grapple Wall", new WorldPoint(2552, 3072, 0), WALL_17047), NEITIZNOT_BRIDGE_REPAIR(40, "Bridge Repair - Quest", new WorldPoint(2315, 3828, 0), ROPE_BRIDGE_21306, ROPE_BRIDGE_21307), + NEITIZNOT_BRIDGE_SOUTHEAST(40, "Rope Bridge", null, ROPE_BRIDGE_21308, ROPE_BRIDGE_21309), + NEITIZNOT_BRIDGE_NORTHWEST(40, "Rope Bridge", null, ROPE_BRIDGE_21310, ROPE_BRIDGE_21311), + NEITIZNOT_BRIDGE_NORTH(40, "Rope Bridge", null, ROPE_BRIDGE_21312, ROPE_BRIDGE_21313), + NEITIZNOT_BRIDGE_NORTHEAST(40, "Broken Rope bridge", null, ROPE_BRIDGE_21314, ROPE_BRIDGE_21315), KOUREND_LAKE_JUMP_EAST(40, "Stepping Stones", new WorldPoint(1612, 3570, 0), STEPPING_STONE_29729, STEPPING_STONE_29730), KOUREND_LAKE_JUMP_WEST(40, "Stepping Stones", new WorldPoint(1604, 3572, 0), STEPPING_STONE_29729, STEPPING_STONE_29730), YANILLE_DUNGEON_BALANCE(40, "Balancing Ledge", null, BALANCING_LEDGE_23548), From 78906dfd683b603aecee0e5f0bf5252261ea4fd2 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 17:30:23 +0100 Subject: [PATCH 18/75] update --- .../plugins/antidrag/AntiDragConfig.java | 7 +- .../plugins/antidrag/AntiDragPlugin.java | 30 +- .../client/plugins/batools/BAToolsPlugin.java | 3 +- .../plugins/clanchat/ClanChatPlugin.java | 629 ++++++------------ .../EquipmentInspectorPlugin.java | 2 +- .../client/plugins/hydra/HydraPlugin.java | 3 +- .../pvptools/CurrentPlayersJFrame.java | 74 +++ .../pvptools/MissingPlayersJFrame.java | 74 +++ .../plugins/pvptools/PvpToolsConfig.java | 69 ++ .../plugins/pvptools/PvpToolsOverlay.java | 61 ++ .../plugins/pvptools/PvpToolsPanel.java | 138 ++++ .../plugins/pvptools/PvpToolsPlugin.java | 475 +++++++++++++ .../client/plugins/pvptools/skull.png | Bin 0 -> 448 bytes .../ShayzienInfirmaryPlugin.java | 3 +- .../spellbookfixer/SpellbookFixerPlugin.java | 3 +- .../plugins/templetrek/TempleTrekPlugin.java | 3 +- .../tobdamagecount/DamageCounterPlugin.java | 1 + .../whalewatchers}/WhaleWatchersConfig.java | 0 .../WhaleWatchersGloryOverlay.java | 0 .../whalewatchers}/WhaleWatchersOverlay.java | 0 .../whalewatchers}/WhaleWatchersPlugin.java | 8 +- .../WhaleWatchersProtOverlay.java | 0 .../WhaleWatchersSmiteableOverlay.java | 0 .../WildernessLocationsPlugin.java | 3 +- .../net/runelite/client/util/PvPUtil.java | 61 ++ .../client/plugins/pvptools/skull.png | Bin 0 -> 448 bytes 26 files changed, 1218 insertions(+), 429 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/CurrentPlayersJFrame.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/MissingPlayersJFrame.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/skull.png rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersConfig.java (100%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersGloryOverlay.java (100%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersOverlay.java (100%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersPlugin.java (96%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersProtOverlay.java (100%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersSmiteableOverlay.java (100%) create mode 100644 runelite-client/src/main/java/net/runelite/client/util/PvPUtil.java create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/pvptools/skull.png 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/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/equipmentinspector/EquipmentInspectorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java index 02ad6e0b35..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 @@ -35,7 +35,7 @@ import java.util.concurrent.ScheduledExecutorService; name = "Equipment Inspector", description = "Inspects enemy equipment", enabledByDefault = false, - type = "PVP" + type = "utility" ) @Slf4j 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/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 0000000000000000000000000000000000000000..09869ea0e1c2e15208ccac2839127b0c42ae7d6f GIT binary patch literal 448 zcmV;x0YCnUP)TQr$`dK^Q$VO1C|N+GS}7rM-cVqS3WUk6_YWWGKBv zP=V5Qm_+^r-C6VwYwjxU>1Jn}*_j}y10VbCH{YB&bG`xo2_lgT05Xcy-gf2_02nnq zzkX~22m!342(_??Q>A>C!F$!N z)r!mIl0gvA_kH@l&magmylqn>k%}mtAR+)rDKNdi!r}3$vDj`kAca756&ibzlFEf# zD1?Yf29p^ElNkWusL_Iy0;PO*9T70OUnioDFbs_#$#NlQ5u|kjm5=*f06?))g%ICf zs=D4ke0di}QDM~Uuw2N+Uj@CEtQ$n5UWcPz$0Bnbp#D|OFuPW7TJmf4CdU0P#{F)* zuJ`CQ>oKVlI%g-YS;U(SZ+?RE!F4s)#0*8M;c@zAT|uE(smA%i?v|}AIW^bmx=LNC qWwx%s<%7yyLvi}zUj2Ljuki)1TS~g;MmS3V0000!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/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 0000000000000000000000000000000000000000..09869ea0e1c2e15208ccac2839127b0c42ae7d6f GIT binary patch literal 448 zcmV;x0YCnUP)TQr$`dK^Q$VO1C|N+GS}7rM-cVqS3WUk6_YWWGKBv zP=V5Qm_+^r-C6VwYwjxU>1Jn}*_j}y10VbCH{YB&bG`xo2_lgT05Xcy-gf2_02nnq zzkX~22m!342(_??Q>A>C!F$!N z)r!mIl0gvA_kH@l&magmylqn>k%}mtAR+)rDKNdi!r}3$vDj`kAca756&ibzlFEf# zD1?Yf29p^ElNkWusL_Iy0;PO*9T70OUnioDFbs_#$#NlQ5u|kjm5=*f06?))g%ICf zs=D4ke0di}QDM~Uuw2N+Uj@CEtQ$n5UWcPz$0Bnbp#D|OFuPW7TJmf4CdU0P#{F)* zuJ`CQ>oKVlI%g-YS;U(SZ+?RE!F4s)#0*8M;c@zAT|uE(smA%i?v|}AIW^bmx=LNC qWwx%s<%7yyLvi}zUj2Ljuki)1TS~g;MmS3V0000 Date: Sat, 20 Apr 2019 17:50:45 +0100 Subject: [PATCH 19/75] fkeyremapping --- .../fkeyremapping/fKeyRemappingConfig.java | 58 +++++++++++ .../fkeyremapping/fKeyRemappingListener.java | 95 +++++++++++++++++++ .../fkeyremapping/fKeyRemappingPlugin.java | 83 ++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingListener.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java 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; + } + + + + + + + +} From 8ba59f833ec88370eb79fad2e339786ee097da40 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 18:00:17 +0100 Subject: [PATCH 20/75] update (#17) * update * fkeyremapping --- .../plugins/antidrag/AntiDragConfig.java | 7 +- .../plugins/antidrag/AntiDragPlugin.java | 30 +- .../client/plugins/batools/BAToolsPlugin.java | 3 +- .../plugins/clanchat/ClanChatPlugin.java | 629 ++++++------------ .../EquipmentInspectorPlugin.java | 2 +- .../fkeyremapping/fKeyRemappingConfig.java | 58 ++ .../fkeyremapping/fKeyRemappingListener.java | 95 +++ .../fkeyremapping/fKeyRemappingPlugin.java | 83 +++ .../client/plugins/hydra/HydraPlugin.java | 3 +- .../pvptools/CurrentPlayersJFrame.java | 74 +++ .../pvptools/MissingPlayersJFrame.java | 74 +++ .../plugins/pvptools/PvpToolsConfig.java | 69 ++ .../plugins/pvptools/PvpToolsOverlay.java | 61 ++ .../plugins/pvptools/PvpToolsPanel.java | 138 ++++ .../plugins/pvptools/PvpToolsPlugin.java | 475 +++++++++++++ .../client/plugins/pvptools/skull.png | Bin 0 -> 448 bytes .../ShayzienInfirmaryPlugin.java | 3 +- .../spellbookfixer/SpellbookFixerPlugin.java | 3 +- .../plugins/templetrek/TempleTrekPlugin.java | 3 +- .../tobdamagecount/DamageCounterPlugin.java | 1 + .../whalewatchers}/WhaleWatchersConfig.java | 0 .../WhaleWatchersGloryOverlay.java | 0 .../whalewatchers}/WhaleWatchersOverlay.java | 0 .../whalewatchers}/WhaleWatchersPlugin.java | 8 +- .../WhaleWatchersProtOverlay.java | 0 .../WhaleWatchersSmiteableOverlay.java | 0 .../WildernessLocationsPlugin.java | 3 +- .../net/runelite/client/util/PvPUtil.java | 61 ++ .../client/plugins/pvptools/skull.png | Bin 0 -> 448 bytes 29 files changed, 1454 insertions(+), 429 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingListener.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/CurrentPlayersJFrame.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/MissingPlayersJFrame.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pvptools/skull.png rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersConfig.java (100%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersGloryOverlay.java (100%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersOverlay.java (100%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersPlugin.java (96%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersProtOverlay.java (100%) rename {whalewatchers => runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers}/WhaleWatchersSmiteableOverlay.java (100%) create mode 100644 runelite-client/src/main/java/net/runelite/client/util/PvPUtil.java create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/pvptools/skull.png 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/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/equipmentinspector/EquipmentInspectorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java index 02ad6e0b35..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 @@ -35,7 +35,7 @@ import java.util.concurrent.ScheduledExecutorService; name = "Equipment Inspector", description = "Inspects enemy equipment", enabledByDefault = false, - type = "PVP" + type = "utility" ) @Slf4j 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/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/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 0000000000000000000000000000000000000000..09869ea0e1c2e15208ccac2839127b0c42ae7d6f GIT binary patch literal 448 zcmV;x0YCnUP)TQr$`dK^Q$VO1C|N+GS}7rM-cVqS3WUk6_YWWGKBv zP=V5Qm_+^r-C6VwYwjxU>1Jn}*_j}y10VbCH{YB&bG`xo2_lgT05Xcy-gf2_02nnq zzkX~22m!342(_??Q>A>C!F$!N z)r!mIl0gvA_kH@l&magmylqn>k%}mtAR+)rDKNdi!r}3$vDj`kAca756&ibzlFEf# zD1?Yf29p^ElNkWusL_Iy0;PO*9T70OUnioDFbs_#$#NlQ5u|kjm5=*f06?))g%ICf zs=D4ke0di}QDM~Uuw2N+Uj@CEtQ$n5UWcPz$0Bnbp#D|OFuPW7TJmf4CdU0P#{F)* zuJ`CQ>oKVlI%g-YS;U(SZ+?RE!F4s)#0*8M;c@zAT|uE(smA%i?v|}AIW^bmx=LNC qWwx%s<%7yyLvi}zUj2Ljuki)1TS~g;MmS3V0000!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/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 0000000000000000000000000000000000000000..09869ea0e1c2e15208ccac2839127b0c42ae7d6f GIT binary patch literal 448 zcmV;x0YCnUP)TQr$`dK^Q$VO1C|N+GS}7rM-cVqS3WUk6_YWWGKBv zP=V5Qm_+^r-C6VwYwjxU>1Jn}*_j}y10VbCH{YB&bG`xo2_lgT05Xcy-gf2_02nnq zzkX~22m!342(_??Q>A>C!F$!N z)r!mIl0gvA_kH@l&magmylqn>k%}mtAR+)rDKNdi!r}3$vDj`kAca756&ibzlFEf# zD1?Yf29p^ElNkWusL_Iy0;PO*9T70OUnioDFbs_#$#NlQ5u|kjm5=*f06?))g%ICf zs=D4ke0di}QDM~Uuw2N+Uj@CEtQ$n5UWcPz$0Bnbp#D|OFuPW7TJmf4CdU0P#{F)* zuJ`CQ>oKVlI%g-YS;U(SZ+?RE!F4s)#0*8M;c@zAT|uE(smA%i?v|}AIW^bmx=LNC qWwx%s<%7yyLvi}zUj2Ljuki)1TS~g;MmS3V0000 Date: Sat, 20 Apr 2019 13:10:59 -0400 Subject: [PATCH 21/75] Remove PkVision --- .../plugins/pkvision/PKVisionConfig.java | 55 ------- .../pkvision/PKVisionMinimapOverlay.java | 43 ------ .../plugins/pkvision/PKVisionOverlay.java | 55 ------- .../plugins/pkvision/PKVisionPlugin.java | 136 ------------------ .../plugins/pkvision/PKVisionService.java | 63 -------- .../plugins/pkvision/PKVisionTileOverlay.java | 44 ------ 6 files changed, 396 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionMinimapOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionService.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionTileOverlay.java 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 5aeb136c66..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pkvision/PKVisionPlugin.java +++ /dev/null @@ -1,136 +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, - type = "PVP" -) -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; - } -} From 22ca3f43e4e7fe7fa8a320d405eb12e7a6ea97e5 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 18:51:11 +0100 Subject: [PATCH 22/75] additonal plugins --- .../groupitemlist/GroupItemListPlugin.java | 69 + .../plugins/groupitemlist/GroupedItem.java | 61 + .../rememberclan/RememberClanConfig.java | 48 + .../rememberclan/RememberClanPlugin.java | 78 + .../plugins/stronghold/StrongholdAnswer.java | 93 + .../plugins/stronghold/StrongholdPlugin.java | 107 + .../warindicators/WarIndicatorConfig.java | 164 + .../WarIndicatorMiniMapOverlay.java | 87 + .../warindicators/WarIndicatorOverlay.java | 101 + .../warindicators/WarIndicatorPlugin.java | 170 + .../warindicators/WarIndicatorService.java | 106 + .../plugins/zoneIndicators/MapLocations.java | 3479 +++++++++++++++++ .../zoneIndicators/ZoneIndicatorsConfig.java | 111 + .../ZoneIndicatorsMinimapOverlay.java | 116 + .../zoneIndicators/ZoneIndicatorsOverlay.java | 113 + .../zoneIndicators/ZoneIndicatorsPlugin.java | 297 ++ .../zoneIndicators/ZoneVisibility.java | 43 + 17 files changed, 5243 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupedItem.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java new file mode 100644 index 0000000000..a01716d388 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java @@ -0,0 +1,69 @@ +package net.runelite.client.plugins.groupitemlist; + +import net.runelite.api.Client; +import net.runelite.api.MenuEntry; +import net.runelite.api.events.MenuOpened; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.input.KeyManager; +import net.runelite.client.input.MouseManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.LinkedHashMap; + +@PluginDescriptor( + name = "!Group Item List", + description = "Group the right click menu of a pile of items.", + tags = {"ground", "compress", "pile", "group"}, + enabledByDefault = false +) + +/** + * Main class of plugin - Groups duplicate right click menu options to singular entries with a quantity. + * + */ +public class GroupItemListPlugin extends Plugin { + + @Inject + private Client client; + + /** + * Fired on a right click menu opening. Count all menu entries and build a new list of entries + * displaying item quantities. + * + * @param menu Right click menu opened + */ + @Subscribe + public void onMenuOpened(MenuOpened menu) { + + LinkedHashMap entryCount = new LinkedHashMap<>(); + ArrayList temp = new ArrayList<>(); + MenuEntry[] updatedMenuEntries; + + // Iterate over menu entries + for (MenuEntry e : menu.getMenuEntries()) { + + // Increment the count if entry has been seen before + if (entryCount.containsKey(e)) { + entryCount.get(e).incrementCount(); + } + + // Store in map if entry has not been seen before + else { + entryCount.put(e, new GroupedItem(e)); + } + } + + // Create a list of updated menu entries from the map of GroupedItem + for (MenuEntry e : entryCount.keySet()) { + MenuEntry entry = entryCount.get(e).getEntry(); + temp.add(entry); + } + + // Parse to an array and set the new menu entries + updatedMenuEntries = temp.toArray(new MenuEntry[0]); + client.setMenuEntries(updatedMenuEntries); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupedItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupedItem.java new file mode 100644 index 0000000000..b4fbbda77f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupedItem.java @@ -0,0 +1,61 @@ +package net.runelite.client.plugins.groupitemlist; + +import net.runelite.api.MenuEntry; + +/** + * Object used to store a MenuEntry and the quantity. Updates the entry target if necessary + * e.g Shark to Shark [4]. + */ +public class GroupedItem { + + private int count; + private MenuEntry entry; + + /** + * Constructor for GroupedItem. + * + * @param entry The menu entry to be tracked for duplicates + */ + public GroupedItem(MenuEntry entry) { + this.entry = entry; + this.count = 1; + } + + /** + * Getter for the count. + * + * @return count + */ + public int getCount() { + return count; + } + + /** + * Getter for the menu entry, updates the target to reflect the quantity if more than 1 + * was found. + * + * @return Updated MenuEntry containing quantity + */ + public MenuEntry getEntry() { + if (count > 1) { + updateTarget(); + } + return entry; + } + + /** + * Updates the target of the menu entry to contain the quantity found. + */ + private void updateTarget() { + String target = entry.getTarget(); + target = target + " [" + count + "]"; + entry.setTarget(target); + } + + /** + * Increment count when duplicate entries are found. + */ + public void incrementCount() { + count += 1; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java new file mode 100644 index 0000000000..20775b1d35 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, Infinitay + * Copyright (c) 2018, Shaun Dreclin + * + * 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.rememberclan; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("rememberclan") +public interface RememberClanConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "clanname", + name = "Clan Name", + description = "Clanname to always remember" + ) + default String clanname() + { + return ""; + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java new file mode 100644 index 0000000000..be4d85e9fe --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018, Infinitay + * Copyright (c) 2018, Shaun Dreclin + * 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.rememberclan; + +import com.google.inject.Provides; +import javax.inject.Inject; + +import net.runelite.api.*; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.vars.AccountType; +import net.runelite.client.chat.ChatColorType; +import net.runelite.client.chat.ChatMessageBuilder; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +@PluginDescriptor( + name = "!Remember Clan", + description = "Remember a specific clan!", + enabledByDefault = false +) +public class RememberClanPlugin extends Plugin +{ + + @Inject + private Client client; + + @Inject + private RememberClanConfig config; + + @Inject + private ChatMessageManager chatMessageManager; + + private boolean loggingIn; + + @Provides + RememberClanConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(RememberClanConfig.class); + } + + @Subscribe + public void onGameTick(GameTick event) + { + client.setVar(VarClientStr.RECENT_CLAN_CHAT,config.clanname()); + + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java new file mode 100644 index 0000000000..2146cd8708 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019, FlaxOnEm + * 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.stronghold; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import net.runelite.api.widgets.Widget; + +import java.util.HashMap; +import java.util.Map; + +@Getter +@RequiredArgsConstructor +enum StrongholdAnswer { + PAIR_0("To pass you must answer me this: Hey adventurer!
You've been randomly selected for a prize of 1 year of
free membership! I'm just going to need some of your
account details so I can put it on your account!", "No way! I'm reporting you to Jagex!"), + PAIR_1("To pass you must answer me this: Can I leave my
account logged in while I'm out of the room?", "No."), + PAIR_2("To pass you must answer me this: How do I remove a
hijacker from my account?", "Use the Account Recovery System."), + PAIR_3("To pass you must answer me this: What do you do if
someone asks you for your password or bank PIN to
make you a player moderator?", "Don't give them the information and send an 'Abuse report'."), + PAIR_4("To pass you must answer me this: You're watching a
stream by someone claiming to be Jagex offering double
xp. What do you do?", "Report the stream as a scam. Real Jagex streams have a 'verified' mark."), + PAIR_5("To pass you must answer me this: My friend asks me
for my password so that he can do a difficult quest for
me. Do I give it to them?", "Don't give them my password."), + PAIR_6("To pass you must answer me this: Who can I give my
password to?", "Nobody."), + PAIR_7("To pass you must answer me this: How do I set up
two-factor authentication for my Old School RuneScape
account?", "Through account settings on oldschool.runescape.com."), + PAIR_8("To pass you must answer me this: What is an example
of a good bank PIN?", "The birthday of a famous person or event."), + PAIR_9("To pass you must answer me this: What should you do
if your real-life friend asks for your password so he
can check your stats?", "Don't give out your password to anyone. Not even close friends."), + PAIR_A("To pass you must answer me this: A player tells you to
search for a video online, click the link in the description
and comment on the forum post to win a cash prize.
What do you do?", "Report the player for phishing."), + PAIR_B("To pass you must answer me this: You have been
offered an opportunity to check out a free giveaway or
double XP signup via email or in game chat. What
should I do?", "Report the incident and do not click any links."), + PAIR_C("To pass you must answer me this: How do I set a
bank PIN?", "Talk to any banker."), + PAIR_D("To pass you must answer me this: What do I do if a
moderator asks me for my account details?", "Politely tell them no and then use the 'Report Abuse' button."), + PAIR_E("To pass you must answer me this: You are part way
through the Stronghold of Security when you have to
answer another question. After you answer the question,
you should...", "Read the text and follow the advice given."), + PAIR_F("To pass you must answer me this: Will Jagex prevent
me from saying my PIN in game?", "No."), + PAIR_G("that sound?", "No way! You'll just take my gold for your own! Reported!"), + PAIR_H("To pass you must answer me this: What should I do if
I receive an email asking me to verify my identity or
Account details due to suspicious activity?", "Don't click any links, forward the email to reportphishing@jagex.com."), + PAIR_I("To pass you must answer me this: A website claims that
they can make me a player moderator. What should I
do?", "Inform Jagex by emailing reportphishing@jagex.com."), + PAIR_J("react?", "Don't share your information and report the player."), + PAIR_K("To pass you must answer me this: What do you do if
someone asks you for your password or bank PIN to
make you a member for free?", "Don't tell them anything and click the 'Report Abuse' button."), + PAIR_L("To pass you must answer me this: Is it OK to buy an
Old School RuneScape account?", "No, you should never buy an account."), + PAIR_M("To pass you must answer me this: You have been
offered an opportunity to check out a free giveaway or
double XP signup via social media or stream. What
should I do?", "Report the incident and do not click any links."), + PAIR_N("To pass you must answer me this: Where is it safe to
use my Old School RuneScape password?", "Only on the Old School RuneScape website."), + PAIR_O("To pass you must answer me this: What is the best
way to secure your account?", "Authenticator and two-step login on my registered email."), + PAIR_P("To pass you must answer me this: Who is it ok to
share my account with?", "Nobody."), + PAIR_Q("To pass you must answer me this: What should you do
if another player messages you recommending a website
to purchase items and/or gold?", "Do not visit the website and report the player who messaged you."), + PAIR_R("To pass you must answer me this: Whose responsibility
is it to keep your account secure?", "Me."), + PAIR_S("To pass you must answer me this: Is it safe to pay
someone to level your account?", "No, you should never allow anyone to level your account."), + PAIR_T("To pass you must answer me this: What do I do if my
account is compromised?", "Secure my device and reset my password."), + PAIR_U("respond?", "Decline the offer and report that player."), + PAIR_V("To pass you must answer me this: A player says that
Jagex prevents you from saying your password
backwards in game. What do you do?", "Don't type in my password backwards and report the player."), + PAIR_W("To pass you must answer me this: What do I do if I
think I have a keylogger or virus?", "Virus scan my device then change my password."), + PAIR_X("To pass you must answer me this: What is the best
security step you can take to keep your registered
email secure?", "Set up 2 step authentication with my email provider."); + + static final Map MATCHES = new HashMap<>(); + + static { + for (StrongholdAnswer strongholdAnswer : StrongholdAnswer.values()) { + MATCHES.put(strongholdAnswer.question, strongholdAnswer.answer); + } + } + + private final String question; + private final String answer; + + static Widget findCorrect(final String question, final Widget[] widgets) { + final String s = MATCHES.get(question); + + for (Widget widget: widgets) { + if (widget != null && widget.getText().equals(s)) + return widget; + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java new file mode 100644 index 0000000000..d1de9d419b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019, FlaxOnEm + * 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.stronghold; + +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.events.ClientTick; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.ColorUtil; + +import javax.inject.Inject; +import java.awt.Color; + +@PluginDescriptor( + name = "!Stronghold", + description = "Highlights the correct answer to Stronghold of Security questions", + tags = {"stronghold", "security", "overlay", "answer", "highlight"} +) +@Slf4j +public class StrongholdPlugin extends Plugin { + private static final Color ANSWER_COLOR = new Color(230, 0, 230); + + @Inject + private Client client; + + private boolean queueNPCDialogue; + private boolean queueNPCOption; + private String questionCache; + + @Subscribe + public void onWidgetLoaded(WidgetLoaded widgetLoaded) { + switch (widgetLoaded.getGroupId()) { + case WidgetID.DIALOG_NPC_GROUP_ID: + queueNPCDialogue = true; + break; + case WidgetID.DIALOG_OPTION_GROUP_ID: + queueNPCOption = true; + break; + } + } + + @Subscribe + public void onClientTick(ClientTick t) { + if (queueNPCDialogue) { + queueNPCDialogue = false; + onNPCDialogue(); + } + if (queueNPCOption) { + queueNPCOption = false; + onNPCOption(); + } + } + + private void onNPCDialogue() { + final Widget debugWidget = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT); + final String npcText = debugWidget.getText(); + if (StrongholdAnswer.MATCHES.containsKey(npcText)) + questionCache = npcText; + } + + private void onNPCOption() { + if (questionCache == null) + return; + + final Widget optionsWidget = client.getWidget(WidgetInfo.DIALOG_OPTION); + if (optionsWidget == null) + return; + + final Widget[] widgets = optionsWidget.getParent().getChildren(); + + final Widget answerWidget = StrongholdAnswer.findCorrect(questionCache, widgets); + questionCache = null; + if (answerWidget == null) + return; + + final String answerText = answerWidget.getText(); + answerWidget.setText(ColorUtil.wrapWithColorTag(answerText, ANSWER_COLOR)); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java new file mode 100644 index 0000000000..c665baaa70 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("warIndicators") + +public interface WarIndicatorConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "highLightCallers", + name = "Highlight Callers", + description = "Highlight listed caller(s)" + ) + default boolean highLightCallers() + { + return true; + } + + @ConfigItem( + position = 1, + keyName = "callerColor", + name = "Caller(s) Color", + description = "Color to highlight caller's name" + ) + default Color getCallerColor() + { + return new Color(36, 255, 237); + } + + @ConfigItem( + position = 2, + keyName = "callerMinimap", + name = "Callers on Minimap", + description = "Show your caller(s) on the minimap" + ) + default boolean callerMinimap() + { + return false; + } + + + @ConfigItem( + position = 3, + keyName = "callerTile", + name = "Show Caller's Tile", + description = "Show the tile your target is standing on" + ) + default boolean callerTile() + { + return false; + } + + @ConfigItem( + position = 4, + keyName = "activeCallers", + name = "Callers", + description = "Adds a user to your caller list. Format: (caller), (caller)" + ) + default String getActiveCallers() + { + return ""; + } + + @ConfigItem( + position = 5, + keyName = "activeCallers", + name = "", + description = "" + ) + void setActiveCallers(String key); + + + @ConfigItem( + position = 6, + keyName = "highlightSnipes", + name = "Highlight Targets", + description = "Highlight listed target(s)" + ) + default boolean highlightSnipes() + { + return true; + } + + @ConfigItem( + position = 7, + keyName = "snipeColor", + name = "Target(s) Color", + description = "Color to highlight target name" + ) + default Color getSnipeColor() + { + return new Color(255, 0, 0); + } + + @ConfigItem( + position = 8, + keyName = "snipeMinimap", + name = "Targets on Minimap", + description = "Show your target on the minimap" + ) + default boolean snipeMinimap() + { + return false; + } + + @ConfigItem( + position = 9, + keyName = "snipeTile", + name = "Show Target's Tile", + description = "Show the tile your target is standing on" + ) + default boolean snipeTile() + { + return false; + } + + @ConfigItem( + position = 10, + keyName = "targetedSnipes", + name = "Targets", + description = "Adds a user to your snipe list. Format: (target), (target)" + ) + default String getTargetedSnipes() + { + return ""; + } + + @ConfigItem( + position = 11, + keyName = "targetedSnipes", + name = "", + description = "" + ) + + void setTargetedSnipe(String key); +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java new file mode 100644 index 0000000000..d7fa0cc92a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +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; +import org.apache.commons.lang3.ArrayUtils; + +@Singleton +public class WarIndicatorMiniMapOverlay extends Overlay +{ + private final WarIndicatorService warIndicatorService; + private final WarIndicatorConfig config; + + @Inject + private WarIndicatorMiniMapOverlay(WarIndicatorConfig config, WarIndicatorService warIndicatorService) + { + this.config = config; + this.warIndicatorService = warIndicatorService; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + warIndicatorService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); + return null; + } + + private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) + { + final String name = actor.getName().replace('\u00A0', ' '); + final net.runelite.api.Point minimapLocation = actor.getMinimapLocation(); + + String[] callers = config.getActiveCallers().split(", "); + String[] targets = config.getTargetedSnipes().split(", "); + + if (config.callerMinimap() && ArrayUtils.contains(callers, actor.getName())) + { + if (minimapLocation != null) + { + OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); + } + } + + if (config.snipeMinimap() && ArrayUtils.contains(targets, actor.getName())) + { + if (minimapLocation != null) + { + OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); + } + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java new file mode 100644 index 0000000000..7ca7cc20c0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.apache.commons.lang3.ArrayUtils; +import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.OverlayUtil; + +@Singleton +public class WarIndicatorOverlay extends Overlay +{ + private final WarIndicatorService warIndicatorService; + private final WarIndicatorConfig config; + + @Inject + private WarIndicatorOverlay(WarIndicatorConfig config, WarIndicatorService warIndicatorService) + { + this.config = config; + this.warIndicatorService = warIndicatorService; + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + warIndicatorService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); + return null; + } + + private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) + { + if (!config.highlightSnipes() && !config.highLightCallers()) + { + return; + } + + Polygon poly = actor.getCanvasTilePoly(); + String[] callers = config.getActiveCallers().split(", "); + String[] targets = config.getTargetedSnipes().split(", "); + + if (config.callerTile() && ArrayUtils.contains(callers, actor.getName())) + { + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, color); + } + } + + if (config.snipeTile() && ArrayUtils.contains(targets, actor.getName())) + { + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, color); + } + } + + String name = actor.getName().replace('\u00A0', ' '); + int offset = actor.getLogicalHeight() + 40; + Point textLocation = actor.getCanvasTextLocation(graphics, name, offset); + + if (textLocation != null) + { + OverlayUtil.renderTextLocation(graphics, textLocation, name, color); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java new file mode 100644 index 0000000000..af7cf94ab7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +import com.google.common.collect.Sets; +import com.google.common.eventbus.Subscribe; +import com.google.inject.Provides; +import java.awt.Color; +import java.util.Collection; +import javax.inject.Inject; +import org.apache.commons.lang3.ArrayUtils; +import net.runelite.api.Client; +import static net.runelite.api.MenuAction.FOLLOW; +import static net.runelite.api.MenuAction.ITEM_USE_ON_PLAYER; +import static net.runelite.api.MenuAction.PLAYER_EIGTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION; +import static net.runelite.api.MenuAction.PLAYER_FOURTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_SECOND_OPTION; +import static net.runelite.api.MenuAction.PLAYER_SEVENTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_SIXTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_THIRD_OPTION; +import static net.runelite.api.MenuAction.SPELL_CAST_ON_PLAYER; +import static net.runelite.api.MenuAction.TRADE; +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.Overlay; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "!War", + description = "War War War.", + tags = {"skill", "total", "max", "PVP"}, + enabledByDefault = false +) +public class WarIndicatorPlugin extends Plugin +{ + @Inject + private OverlayManager overlayManager; + + @Inject + private WarIndicatorConfig config; + + @Inject + private WarIndicatorOverlay warIndicatorOverlay; + + @Inject + private WarIndicatorMiniMapOverlay warIndicatorMiniMapOverlay; + + @Inject + private Client client; + + @Provides + WarIndicatorConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(WarIndicatorConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(warIndicatorOverlay); + overlayManager.add(warIndicatorMiniMapOverlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(warIndicatorOverlay); + overlayManager.remove(warIndicatorMiniMapOverlay); + } + + @Subscribe + public void onMenuEntryAdd(MenuEntryAdded menuEntryAdded) + { + int type = menuEntryAdded.getType(); + + if (type >= 2000) + { + type -= 2000; + } + + int identifier = menuEntryAdded.getIdentifier(); + if (type == FOLLOW.getId() || type == TRADE.getId() + || type == SPELL_CAST_ON_PLAYER.getId() + || type == ITEM_USE_ON_PLAYER.getId() + || type == PLAYER_FIRST_OPTION.getId() + || type == PLAYER_SECOND_OPTION.getId() + || type == PLAYER_THIRD_OPTION.getId() + || type == PLAYER_FOURTH_OPTION.getId() + || type == PLAYER_FIFTH_OPTION.getId() + || type == PLAYER_SIXTH_OPTION.getId() + || type == PLAYER_SEVENTH_OPTION.getId() + || type == PLAYER_EIGTH_OPTION.getId()) + { + Player[] players = client.getCachedPlayers(); + Player player = null; + String player2 = null; + + String[] callers = config.getActiveCallers().split(", "); + String[] targets = config.getTargetedSnipes().split(", "); + + if (identifier >= 0 && identifier < players.length) + { + player = players[identifier]; + player2 = players[identifier].getName(); + } + + if (player == null) + { + return; + } + + Color color = null; + + if (config.highLightCallers() && ArrayUtils.contains(callers, player2)) + { + color = config.getCallerColor(); + } + + if (config.highlightSnipes() && ArrayUtils.contains(targets, player2)) + { + color = config.getSnipeColor(); + } + + if (color != null) + { + MenuEntry[] menuEntries = client.getMenuEntries(); + MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; + String target = lastEntry.getTarget(); + + int idx = target.indexOf('>'); + if (idx != -1) + { + target = target.substring(idx + 1); + } + + lastEntry.setTarget("" + target); + client.setMenuEntries(menuEntries); + } + + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java new file mode 100644 index 0000000000..cb6c8127b5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +import net.runelite.api.Client; +import net.runelite.api.Player; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.awt.*; +import java.util.function.BiConsumer; + +@Singleton +public class WarIndicatorService +{ + private final Client client; + private final WarIndicatorConfig config; + + @Inject + private WarIndicatorService(Client client, WarIndicatorConfig config) + { + this.config = config; + this.client = client; + } + + public void forEachPlayer(final BiConsumer consumer) + { + if (!config.highlightSnipes() && !config.highLightCallers()) + { + return; + } + + if (config.highlightSnipes()) + { + for (Player player : client.getPlayers()) + { + if (player == null || player.getName() == null) + { + continue; + } + + String[] targets = config.getTargetedSnipes().split(", "); + + if (targets == null) + { + return; + } + + for (int i = 0; i < targets.length; i++) + { + if (player.getName().equalsIgnoreCase(targets[i])) + { + consumer.accept(player, config.getSnipeColor()); + } + } + } + } + + if (config.highLightCallers()) + { + for (Player player : client.getPlayers()) + { + if (player == null || player.getName() == null) + { + continue; + } + + String[] callers = config.getActiveCallers().split(", "); + + if (callers == null) + { + return; + } + + for (int i = 0; i < callers.length; i++) + { + if (player.getName().equalsIgnoreCase(callers[i])) + { + consumer.accept(player, config.getCallerColor()); + } + } + } + } + } +} 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/zoneIndicators/MapLocations.java new file mode 100644 index 0000000000..81e8e0f527 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java @@ -0,0 +1,3479 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.Area; +import java.util.ArrayList; +import java.util.List; +import net.runelite.api.Constants; + +public class MapLocations +{ + private static final List[] MULTICOMBAT = new List[Constants.MAX_Z]; + private static final List[] NOT_MULTICOMBAT = new List[Constants.MAX_Z]; + private static final List[] ROUGH_WILDERNESS = new List[Constants.MAX_Z]; + private static final List[] DEADMAN_SAFE_ZONES = new List[Constants.MAX_Z]; + private static final List[] PVP_WORLD_SAFE_ZONES = new List[Constants.MAX_Z]; + + private static Area getArea(List shapes) + { + Area area = new Area(); + for (Shape shape : shapes) + { + area.add(new Area(shape)); + } + return area; + } + + private static Area getArea(List shapes, Rectangle view) + { + Area area = new Area(); + for (Shape shape : shapes) + { + if (shape.intersects(view)) + { + area.add(new Area(shape)); + } + } + return area; + } + + public static Area getMulticombat(int plane) + { + Area area = getArea(MULTICOMBAT[plane]); + area.subtract(getArea(NOT_MULTICOMBAT[plane])); + return area; + } + + public static Area getMulticombat(Rectangle view, int plane) + { + Area area = getArea(MULTICOMBAT[plane], view); + area.subtract(getArea(NOT_MULTICOMBAT[plane], view)); + return area; + } + + public static Area getRoughWilderness(int plane) + { + return getArea(ROUGH_WILDERNESS[plane]); + } + + public static Area getRoughWilderness(Rectangle view, int plane) + { + return getArea(ROUGH_WILDERNESS[plane], view); + } + + public static Area getDeadmanSafeZones(int plane) + { + return getArea(DEADMAN_SAFE_ZONES[plane]); + } + + public static Area getDeadmanSafeZones(Rectangle view, int plane) + { + return getArea(DEADMAN_SAFE_ZONES[plane], view); + } + + public static Area getPvpSafeZones(int plane) + { + return getArea(PVP_WORLD_SAFE_ZONES[plane]); + } + + public static Area getPvpSafeZones(Rectangle view, int plane) + { + return getArea(PVP_WORLD_SAFE_ZONES[plane], view); + } + + static + { + for (int i = 0; i < MULTICOMBAT.length; i++) + { + MULTICOMBAT[i] = new ArrayList<>(); + } + for (int i = 0; i < NOT_MULTICOMBAT.length; i++) + { + NOT_MULTICOMBAT[i] = new ArrayList<>(); + } + for (int i = 0; i < ROUGH_WILDERNESS.length; i++) + { + ROUGH_WILDERNESS[i] = new ArrayList<>(); + } + for (int i = 0; i < DEADMAN_SAFE_ZONES.length; i++) + { + DEADMAN_SAFE_ZONES[i] = new ArrayList<>(); + } + for (int i = 0; i < PVP_WORLD_SAFE_ZONES.length; i++) + { + PVP_WORLD_SAFE_ZONES[i] = new ArrayList<>(); + } + + defineMulticombatAreas(); + defineDeadmanSafeZones(); + definePvpSafeZones(); + defineWilderness(); + } + + private static void defineMulticombatAreas() + { + // Main Wilderness + addPolygonOnPlane(MULTICOMBAT, 0, + 3200, 3968, + 3392, 3968, + 3392, 3840, + 3328, 3840, + 3328, 3520, + 3136, 3520, + 3136, 3648, + 3192, 3648, + 3192, 3752, + 3152, 3752, + 3152, 3840, + 3136, 3840, + 3136, 3872, + 3112, 3872, + 3112, 3880, + 3072, 3880, + 3072, 3896, + 3048, 3896, + 3048, 3872, + 3056, 3872, + 3056, 3864, + 3048, 3864, + 3048, 3856, + 3008, 3856, + 3008, 3904, + 3200, 3904); + + // South of wildy agility training arena + addPolygonOnPlane(MULTICOMBAT, 0, + 2984, 3928, + 3008, 3928, + 3008, 3912, + 2984, 3912); + + // Wildy zamorak temple + addPolygonOnPlane(MULTICOMBAT, 0, + 2944, 3832, + 2960, 3832, + 2960, 3816, + 2944, 3816); + + // Wildy bandit camp + addPolygonOnPlane(MULTICOMBAT, 0, + 3008, 3712, + 3072, 3712, + 3072, 3600, + 3008, 3600); + + // Chaos temple north of Falador + addPolygonOnPlane(MULTICOMBAT, 0, + 2928, 3520, + 2944, 3520, + 2944, 3512, + 2928, 3512); + + // Burthorpe + addPolygonOnPlane(MULTICOMBAT, 0, + 2880, 3544, + 2904, 3544, + 2904, 3520, + 2880, 3520); + + // White Wolf Mountain + addPolygonOnPlane(MULTICOMBAT, 0, + 2880, 3520, + 2816, 3520, + 2816, 3456, + 2880, 3456); + + // Death Plateu + addPolygonOnPlane(MULTICOMBAT, 0, + 2848, 3608, + 2880, 3608, + 2880, 3600, + 2848, 3600); + + // Trollheim/Godwars + addPolygonOnPlane(MULTICOMBAT, 0, + 2880, 3776, + 2912, 3776, + 2912, 3696, + 2920, 3696, + 2920, 3688, + 2896, 3688, + 2896, 3696, + 2880, 3696, + 2880, 3728, + 2888, 3728, + 2888, 3744, + 2880, 3744); + + // Northen Rellekka + addPolygonOnPlane(MULTICOMBAT, 0, + 2656, 3736, + 2704, 3736, + 2704, 3728, + 2712, 3728, + 2712, 3736, + 2736, 3736, + 2736, 3712, + 2656, 3712); + + // Northen Fremennik Isles + addPolygonOnPlane(MULTICOMBAT, 0, + 2304, 3904, + 2432, 3904, + 2432, 3840, + 2368, 3840, + 2368, 3816, + 2352, 3816, + 2352, 3824, + 2304, 3824); + + // Pirates Cove + addPolygonOnPlane(MULTICOMBAT, 0, + 2176, 3840, + 2240, 3840, + 2240, 3776, + 2176, 3776); + + // Lunar Isle + addPolygonOnPlane(MULTICOMBAT, 0, + 2048, 3968, + 2176, 3968, + 2176, 3840, + 2048, 3840); + + // Piscatoris Fishing Colony + addPolygonOnPlane(MULTICOMBAT, 0, + 2304, 3712, + 2368, 3712, + 2368, 3648, + 2304, 3648); + + // Ranging Guild + addPolygonOnPlane(MULTICOMBAT, 0, + 2656, 3448, + 2680, 3448, + 2680, 3440, + 2688, 3440, + 2688, 3416, + 2680, 3416, + 2680, 3408, + 2656, 3408, + 2656, 3416, + 2648, 3416, + 2648, 3440, + 2656, 3440); + + // Necromancer house, southeast of Ardy + addPolygonOnPlane(MULTICOMBAT, 0, + 2656, 3256, + 2680, 3256, + 2680, 3216, + 2664, 3216, + 2664, 3232, + 2656, 3232); + + // Battlefield noth of Tree Gnome Village + addPolygonOnPlane(MULTICOMBAT, 0, + 2504, 3248, + 2544, 3248, + 2544, 3232, + 2552, 3232, + 2552, 3208, + 2504, 3208); + + // Castle Wars + addPolygonOnPlane(MULTICOMBAT, 0, + 2368, 3136, + 2432, 3136, + 2432, 3072, + 2368, 3072); + + // Jiggig + addPolygonOnPlane(MULTICOMBAT, 0, + 2456, 3056, + 2496, 3056, + 2496, 3032, + 2456, 3032); + + // East feldip hills, near rantz + addPolygonOnPlane(MULTICOMBAT, 0, + 2648, 2976, + 2656, 2976, + 2656, 2952, + 2648, 2952); + + // Ape Atoll + addPolygonOnPlane(MULTICOMBAT, 0, + 2688, 2816, + 2816, 2816, + 2816, 2688, + 2688, 2688); + + // Pest Control + addPolygonOnPlane(MULTICOMBAT, 0, + 2624, 2624, + 2688, 2624, + 2688, 2560, + 2624, 2560); + + // Desert Bandit Camp + addPolygonOnPlane(MULTICOMBAT, 0, + 3152, 3000, + 3192, 3000, + 3192, 2960, + 3152, 2960); + + // Al Kharid + addPolygonOnPlane(MULTICOMBAT, 0, + 3264, 3200, + 3328, 3200, + 3328, 3136, + 3264, 3136); + + // Wizards Tower + addPolygonOnPlane(MULTICOMBAT, 0, + 3094, 3176, + 3126, 3176, + 3126, 3144, + 3094, 3144); + + // Draynor Village + addPolygonOnPlane(MULTICOMBAT, 0, + 3112, 3264, + 3136, 3264, + 3136, 3232, + 3104, 3232, + 3104, 3256, + 3112, 3256); + + // Falador + addPolygonOnPlane(MULTICOMBAT, 0, + 2944, 3456, + 3008, 3456, + 3008, 3328, + 3016, 3328, + 3016, 3304, + 2944, 3304); + + // Southwest fally castle isn't multicombat downstairs + addPolygonOnPlane(NOT_MULTICOMBAT, 0, + 2968, 3336, + 2968, 3328, + 2960, 3328, + 2960, 3336); + + // Barbarian Village + addPolygonOnPlane(MULTICOMBAT, 0, + 3072, 3456, + 3136, 3456, + 3136, 3392, + 3048, 3392, + 3048, 3408, + 3056, 3408, + 3056, 3440, + 3064, 3440, + 3064, 3448, + 3072, 3448); + + // Ammoniate crabs at northwest fossil island + addPolygonOnPlane(MULTICOMBAT, 0, + 3648, 3885, + 3663, 3885, + 3663, 3882, + 3664, 3882, + 3664, 3872, + 3663, 3872, + 3663, 3868, + 3648, 3868); + + // Ammoniate crabs at north fossil island + addPolygonOnPlane(MULTICOMBAT, 0, + 3680, 3904, + 3744, 3904, + 3744, 3856, + 3756, 3856, + 3756, 3852, + 3755, 3852, + 3755, 3851, + 3754, 3851, + 3754, 3850, + 3751, 3850, + 3751, 3849, + 3750, 3849, + 3750, 3848, + 3749, 3848, + 3749, 3847, + 3748, 3847, + 3748, 3846, + 3747, 3846, + 3747, 3845, + 3746, 3845, + 3746, 3844, + 3742, 3844, + 3742, 3845, + 3740, 3845, + 3740, 3844, + 3732, 3844, + 3732, 3843, + 3730, 3843, + 3730, 3842, + 3724, 3842, + 3724, 3843, + 3717, 3843, + 3717, 3842, + 3712, 3842, + 3712, 3846, + 3710, 3846, + 3710, 3847, + 3709, 3847, + 3709, 3848, + 3708, 3848, + 3708, 3859, + 3709, 3859, + 3709, 3860, + 3710, 3860, + 3710, 3861, + 3712, 3861, + 3712, 3866, + 3713, 3866, + 3713, 3870, + 3714, 3870, + 3714, 3873, + 3713, 3873, + 3713, 3876, + 3712, 3876, + 3712, 3881, + 3710, 3881, + 3710, 3888, + 3712, 3888, + 3712, 3890, + 3714, 3890, + 3714, 3891, + 3716, 3891, + 3716, 3892, + 3717, 3892, + 3717, 3893, + 3716, 3893, + 3716, 3894, + 3714, 3894, + 3714, 3895, + 3713, 3895, + 3713, 3896, + 3712, 3896, + 3712, 3897, + 3705, 3897, + 3705, 3898, + 3704, 3898, + 3704, 3899, + 3692, 3899, + 3692, 3898, + 3688, 3898, + 3688, 3897, + 3686, 3897, + 3686, 3896, + 3680, 3896); + + // Zeah, southwest of Wintertodt, snowy area with ice giants and wolves + addPolygonOnPlane(MULTICOMBAT, 0, + 1540, 3898, + 1543, 3898, + 1543, 3901, + 1546, 3901, + 1546, 3903, + 1547, 3903, + 1547, 3904, + 1550, 3904, + 1550, 3903, + 1553, 3903, + 1553, 3904, + 1559, 3904, + 1559, 3902, + 1564, 3902, + 1564, 3903, + 1565, 3903, + 1565, 3904, + 1568, 3904, + 1568, 3903, + 1569, 3903, + 1569, 3902, + 1570, 3902, + 1570, 3901, + 1573, 3901, + 1573, 3898, + 1577, 3898, + 1577, 3899, + 1578, 3899, + 1578, 3902, + 1579, 3902, + 1579, 3903, + 1584, 3903, + 1584, 3902, + 1586, 3902, + 1586, 3901, + 1590, 3901, + 1590, 3891, + 1588, 3891, + 1588, 3887, + 1572, 3887, + 1572, 3872, + 1567, 3872, + 1567, 3868, + 1563, 3868, + 1563, 3867, + 1558, 3867, + 1558, 3868, + 1557, 3868, + 1557, 3870, + 1549, 3870, + 1549, 3874, + 1545, 3874, + 1545, 3876, + 1543, 3876, + 1543, 3877, + 1542, 3877, + 1542, 3879, + 1541, 3879, + 1541, 3882, + 1539, 3882, + 1539, 3887, + 1540, 3887, + 1540, 3888, + 1539, 3888, + 1539, 3894, + 1540, 3894); + + // Zeah arceuus area + addPolygonOnPlane(MULTICOMBAT, 0, + 1664, 3776, + 1664, 3785, + 1667, 3785, + 1667, 3805, + 1671, 3805, + 1671, 3811, + 1675, 3811, + 1675, 3819, + 1690, 3819, + 1690, 3814, + 1695, 3814, + 1695, 3806, + 1719, 3806, + 1719, 3787, + 1725, 3787, + 1725, 3778, + 1711, 3778, + 1711, 3776); + + // Arceuus teletab-making house + addPolygonOnPlane(MULTICOMBAT, 0, + 1667, 3772, + 1679, 3772, + 1679, 3775, + 1691, 3775, + 1691, 3761, + 1679, 3761, + 1679, 3764, + 1667, 3764); + // Next house east + addPolygonOnPlane(MULTICOMBAT, 0, + 1696, 3775, + 1708, 3775, + 1708, 3763, + 1696, 3763); + // Next house east + addPolygonOnPlane(MULTICOMBAT, 0, + 1713, 3775, + 1727, 3775, + 1727, 3763, + 1724, 3763, + 1724, 3752, + 1716, 3752, + 1716, 3763, + 1713, 3763); + // Arceuus rune shop house + addPolygonOnPlane(MULTICOMBAT, 0, + 1716, 3750, + 1728, 3750, + 1728, 3736, + 1716, 3736); + // Arceuus general store house + addPolygonOnPlane(MULTICOMBAT, 0, + 1717, 3732, + 1725, 3732, + 1725, 3715, + 1715, 3715, + 1715, 3725, + 1717, 3725); + // Arceuus pub + addPolygonOnPlane(MULTICOMBAT, 0, + 1683, 3732, + 1691, 3732, + 1691, 3725, + 1697, 3725, + 1697, 3730, + 1703, 3730, + 1703, 3712, + 1683, 3712); + // Arceuus staff store + addPolygonOnPlane(MULTICOMBAT, 0, + 1664, 3732, + 1676, 3732, + 1676, 3720, + 1664, 3720); + // Next house to the west + addPolygonOnPlane(MULTICOMBAT, 0, + 1647, 3738, + 1655, 3738, + 1655, 3726, + 1658, 3726, + 1658, 3714, + 1644, 3714, + 1644, 3726, + 1647, 3726); + // Next house to the north + addPolygonOnPlane(MULTICOMBAT, 0, + 1647, 3762, + 1657, 3762, + 1657, 3752, + 1655, 3752, + 1655, 3745, + 1647, 3745); + + // Arceuus house magic trees + addPolygonOnPlane(MULTICOMBAT, 0, + 1682, 3755, + 1692, 3755, + 1692, 3745, + 1690, 3745, + 1690, 3738, + 1682, 3738); + // West of that ^ + addPolygonOnPlane(MULTICOMBAT, 0, + 1667, 3756, + 1675, 3756, + 1675, 3740, + 1665, 3740, + 1665, 3746, + 1667, 3746); + + // This one goes through western piscarilius, northen hosidius + // and southwestern arceuus + addPolygonOnPlane(MULTICOMBAT, 0, + 1728, 3808, + 1792, 3808, + 1792, 3764, + 1856, 3764, + 1856, 3712, + 1792, 3712, + 1792, 3648, + 1664, 3648, + 1664, 3706, + 1665, 3706, + 1665, 3705, + 1668, 3705, + 1668, 3706, + 1671, 3706, + 1671, 3705, + 1675, 3705, + 1675, 3704, + 1683, 3704, + 1683, 3701, + 1684, 3701, + 1684, 3700, + 1686, 3700, + 1686, 3702, + 1687, 3702, + 1687, 3700, + 1688, 3700, + 1688, 3701, + 1690, 3701, + 1690, 3703, + 1689, 3703, + 1689, 3704, + 1690, 3704, + 1690, 3705, + 1704, 3705, + 1704, 3707, + 1706, 3707, + 1706, 3712, + 1711, 3712, + 1711, 3711, + 1710, 3711, + 1710, 3710, + 1712, 3710, + 1712, 3707, + 1728, 3707); + + // Kourend castle + addPolygonOnPlane(MULTICOMBAT, 0, + 1614, 3691, + 1619, 3691, + 1619, 3690, + 1620, 3690, + 1620, 3689, + 1653, 3689, + 1653, 3690, + 1654, 3690, + 1654, 3691, + 1657, 3691, + 1657, 3690, + 1658, 3690, + 1658, 3689, + 1659, 3689, + 1659, 3686, + 1658, 3686, + 1658, 3685, + 1657, 3685, + 1657, 3662, + 1658, 3662, + 1658, 3661, + 1659, 3661, + 1659, 3658, + 1658, 3658, + 1658, 3657, + 1657, 3657, + 1657, 3656, + 1654, 3656, + 1654, 3657, + 1653, 3657, + 1653, 3658, + 1620, 3658, + 1620, 3657, + 1619, 3657, + 1619, 3656, + 1614, 3656, + 1614, 3657, + 1613, 3657, + 1613, 3661, + 1612, 3661, + 1612, 3662, + 1611, 3662, + 1611, 3663, + 1600, 3663, + 1600, 3662, + 1599, 3662, + 1599, 3661, + 1594, 3661, + 1594, 3662, + 1593, 3662, + 1593, 3685, + 1594, 3685, + 1594, 3686, + 1599, 3686, + 1599, 3685, + 1600, 3685, + 1600, 3684, + 1611, 3684, + 1611, 3685, + 1612, 3685, + 1612, 3686, + 1613, 3686, + 1613, 3690, + 1614, 3690); + + // Western hosidius area, including woodcutting guild and western sand crabs + addPolygonOnPlane(MULTICOMBAT, 0, + 1650, 3648, + 1664, 3648, + 1664, 3520, + 1689, 3520, + 1689, 3496, + 1707, 3496, + 1707, 3485, + 1708, 3485, + 1708, 3484, + 1710, 3484, + 1710, 3483, + 1713, 3483, + 1713, 3482, + 1720, 3482, + 1720, 3481, + 1721, 3481, + 1721, 3480, + 1722, 3480, + 1722, 3479, + 1723, 3479, + 1723, 3478, + 1724, 3478, + 1724, 3477, + 1726, 3477, + 1726, 3476, + 1728, 3476, + 1728, 3472, + 1708, 3472, + 1708, 3456, + 1600, 3456, + 1600, 3584, + 1608, 3584, + 1608, 3616, + 1650, 3616); + + // Hosidius sand crabs + addPolygonOnPlane(MULTICOMBAT, 0, + 1740, 3478, + 1741, 3478, + 1741, 3479, + 1745, 3479, + 1745, 3480, + 1751, 3480, + 1751, 3479, + 1752, 3479, + 1752, 3478, + 1753, 3478, + 1753, 3477, + 1755, 3477, + 1755, 3476, + 1757, 3476, + 1757, 3475, + 1758, 3475, + 1758, 3474, + 1759, 3474, + 1759, 3473, + 1779, 3473, + 1779, 3474, + 1781, 3474, + 1781, 3475, + 1786, 3475, + 1786, 3476, + 1800, 3476, + 1800, 3475, + 1805, 3475, + 1805, 3474, + 1807, 3474, + 1807, 3473, + 1808, 3473, + 1808, 3472, + 1810, 3472, + 1810, 3471, + 1833, 3471, + 1833, 3470, + 1834, 3470, + 1834, 3469, + 1852, 3469, + 1852, 3449, + 1792, 3449, + 1792, 3424, + 1800, 3424, + 1800, 3449, + 1800, 3400, + 1728, 3400, + 1728, 3462, + 1729, 3462, + 1729, 3466, + 1730, 3466, + 1730, 3469, + 1731, 3469, + 1731, 3470, + 1732, 3470, + 1732, 3471, + 1733, 3471, + 1733, 3473, + 1734, 3473, + 1734, 3474, + 1736, 3474, + 1736, 3475, + 1737, 3475, + 1737, 3476, + 1738, 3476, + 1738, 3477, + 1740, 3477); + + // Apparently there is a 1x1 single zone on the sand crab island + addPolygonOnPlane(NOT_MULTICOMBAT, 0, + 1777, 3416, + 1777, 3417, + 1778, 3417, + 1778, 3416); + + // Eastern hosidius area + addPolygonOnPlane(MULTICOMBAT, 0, + 1834, 3584, + 1888, 3584, + 1888, 3528, + 1856, 3528, + 1856, 3520, + 1834, 3520, + 1834, 3522, + 1833, 3522, + 1833, 3535, + 1834, 3535, + 1834, 3538, + 1835, 3538, + 1835, 3539, + 1836, 3539, + 1836, 3540, + 1837, 3540, + 1837, 3541, + 1838, 3541, + 1838, 3542, + 1840, 3542, + 1840, 3543, + 1841, 3543, + 1841, 3545, + 1842, 3545, + 1842, 3546, + 1844, 3546, + 1844, 3547, + 1845, 3547, + 1845, 3548, + 1851, 3548, + 1851, 3551, + 1853, 3551, + 1853, 3563, + 1851, 3563, + 1851, 3566, + 1847, 3566, + 1847, 3567, + 1845, 3567, + 1845, 3568, + 1844, 3568, + 1844, 3569, + 1843, 3569, + 1843, 3571, + 1842, 3571, + 1842, 3573, + 1841, 3573, + 1841, 3574, + 1840, 3574, + 1840, 3575, + 1839, 3575, + 1839, 3576, + 1838, 3576, + 1838, 3577, + 1837, 3577, + 1837, 3578, + 1836, 3578, + 1836, 3579, + 1835, 3579, + 1835, 3581, + 1834, 3581); + + // Eastern hosidius area also has a 1x1 multi area + addPolygonOnPlane(MULTICOMBAT, 0, + 1849, 3563, + 1849, 3564, + 1850, 3564, + 1850, 3563); + + // Hosidius cows/chickens/pigs + addPolygonOnPlane(MULTICOMBAT, 0, + 1792, 3513, + 1802, 3513, + 1802, 3520, + 1810, 3520, + 1810, 3513, + 1816, 3513, + 1816, 3512, + 1836, 3512, + 1836, 3494, + 1796, 3494, + 1796, 3495, + 1792, 3495); + + // Hosidius southeast of tithe farm + addPolygonOnPlane(MULTICOMBAT, 0, + 1777, 3597, + 1794, 3597, + 1794, 3561, + 1777, 3561, + 1777, 3591, + 1779, 3591, + 1779, 3592, + 1777, 3592); + + // West of shayzien house + addPolygonOnPlane(MULTICOMBAT, 0, + 1408, 3584, + 1408, 3582, + 1486, 3582, + 1486, 3568, + 1528, 3568, + 1528, 3520, + 1408, 3520, + 1408, 3464, + 1380, 3464, + 1380, 3486, + 1377, 3486, + 1377, 3488, + 1373, 3488, + 1373, 3492, + 1364, 3492, + 1364, 3512, + 1358, 3512, + 1358, 3520, + 1356, 3520, + 1356, 3532, + 1358, 3532, + 1358, 3540, + 1359, 3540, + 1359, 3542, + 1360, 3542, + 1360, 3557, + 1356, 3557, + 1356, 3560, + 1351, 3560, + 1351, 3570, + 1354, 3570, + 1354, 3581, + 1346, 3581, + 1346, 3584); + + // South of chambers of xeric + addPolygonOnPlane(MULTICOMBAT, 0, + 1261, 3489, + 1259, 3489, + 1259, 3488, + 1255, 3488, + 1255, 3487, + 1243, 3487, + 1243, 3490, + 1234, 3490, + 1234, 3480, + 1192, 3480, + 1192, 3568, + 1209, 3568, + 1209, 3548, + 1215, 3548, + 1215, 3544, + 1217, 3544, + 1217, 3536, + 1235, 3536, + 1235, 3532, + 1249, 3532, + 1249, 3525, + 1248, 3525, + 1248, 3517, + 1254, 3517, + 1254, 3513, + 1274, 3513, + 1274, 3510, + 1296, 3510, + 1296, 3511, + 1300, 3511, + 1300, 3501, + 1287, 3501, + 1287, 3490, + 1280, 3490, + 1280, 3489, + 1264, 3489, + 1264, 3490, + 1261, 3490); + + // Lizardman shamans + addPolygonOnPlane(MULTICOMBAT, 0, + 1416, 3728, + 1456, 3728, + 1456, 3688, + 1416, 3688); + + // Other lizardman area at shayzien (west side) + addPolygonOnPlane(MULTICOMBAT, 0, + 1472, 3712, + 1510, 3712, + 1510, 3702, + 1509, 3702, + 1509, 3701, + 1506, 3701, + 1506, 3696, + 1500, 3696, + 1500, 3680, + 1472, 3680); + + // Other lizardman area at shayzien (east side) + addPolygonOnPlane(MULTICOMBAT, 0, + 1538, 3704, + 1560, 3704, + 1560, 3672, + 1538, 3672); + + // Lovakengj house + addPolygonOnPlane(MULTICOMBAT, 0, + 1600, 3712, + 1472, 3712, + 1472, 3840, + 1547, 3840, + 1547, 3816, + 1556, 3816, + 1556, 3809, + 1562, 3809, + 1562, 3800, + 1568, 3800, + 1568, 3793, + 1571, 3793, + 1571, 3816, + 1571, 3776, + 1600, 3776); + + // Shayzien house + addPolygonOnPlane(MULTICOMBAT, 0, + 1475, 3587, + 1475, 3641, + 1534, 3641, + 1534, 3587); + + // Shayzien house bank is non-multi + addPolygonOnPlane(NOT_MULTICOMBAT, 0, + 1495, 3622, + 1515, 3622, + 1515, 3612, + 1495, 3612); + + // Shayzien house general store + addPolygonOnPlane(MULTICOMBAT, 0, + 1539, 3640, + 1551, 3640, + 1551, 3621, + 1539, 3621); + + // Kourend woodland barbarian area + addPolygonOnPlane(MULTICOMBAT, 0, + 1572, 3442, + 1591, 3442, + 1591, 3424, + 1572, 3424); + + // Catacombs + addPolygonTo(MULTICOMBAT, + 1600, 9984, + 1600, 10067, + 1628, 10067, + 1628, 10070, + 1639, 10070, + 1639, 10112, + 1730, 10112, + 1730, 9984); + + // Zeah dungeon with sand crabs + addPolygonTo(MULTICOMBAT, + 1632, 9792, + 1632, 9856, + 1728, 9856, + 1728, 9792); + + // Waterbirth island near the doors where people use rune throwing axes + addPolygonTo(MULTICOMBAT, + 2536, 10136, + 2536, 10152, + 2552, 10152, + 2552, 10136); + + // Waterbirth island dungeon, on the path to dks + addPolygonTo(MULTICOMBAT, + 1792, 4352, + 1792, 4416, + 1984, 4416, + 1984, 4352); + + // Dagannoths in lighthouse + addPolygonTo(MULTICOMBAT, + 2496, 10048, + 2560, 10048, + 2560, 9984, + 2496, 9984); + + // Dagannoth kings (DKs) including slayer only dks + addPolygonTo(MULTICOMBAT, + 2944, 4352, + 2944, 4480, + 2880, 4480, + 2880, 4352); + + // White wolf mountain dungeon at ice queen + addPolygonTo(MULTICOMBAT, + 2856, 9928, + 2856, 9968, + 2880, 9968, + 2880, 9928); + + // Kharazi jungle dungeon (in dragon slayer 2 quest) + addPolygonTo(MULTICOMBAT, + 2816, 9296, + 2880, 9296, + 2880, 9216, + 2816, 9216); + + // Tzhaar, fight pits and inferno area + addPolygonTo(MULTICOMBAT, + 2368, 5184, + 2560, 5184, + 2560, 5056, + 2368, 5056); + + // Smoke devils + addPolygonTo(MULTICOMBAT, + 2432, 9408, + 2344, 9408, + 2344, 9472, + 2432, 9472); + + // Kraken + addPolygonTo(MULTICOMBAT, + 2270, 10045, + 2291, 10045, + 2291, 10022, + 2270, 10022); + + // Giant mole + addPolygonTo(MULTICOMBAT, + 1728, 5240, + 1792, 5240, + 1792, 5120, + 1728, 5120); + + // Godwars dungeon + addPolygonTo(MULTICOMBAT, + 2816, 5376, + 2944, 5376, + 2944, 5248, + 2816, 5248); + + // Desert treasure shadow diamond area + addPolygonTo(MULTICOMBAT, + 2752, 5064, + 2728, 5064, + 2728, 5088, + 2720, 5088, + 2720, 5096, + 2712, 5096, + 2712, 5112, + 2736, 5112, + 2736, 5120, + 2752, 5120); + + // Kalphite slayer area + addPolygonTo(MULTICOMBAT, + 3264, 9544, + 3344, 9544, + 3344, 9472, + 3264, 9472); + + // Normal kalphite area including kalphite queen + addPolygonTo(MULTICOMBAT, + 3456, 9536, + 3520, 9536, + 3520, 9472, + 3456, 9472); + + // Tarns lair + addPolygonTo(MULTICOMBAT, + 3136, 4664, + 3200, 4664, + 3200, 4544, + 3136, 4544); + + // Haunted mine boss area + addPolygonTo(MULTICOMBAT, + 2752, 4416, + 2752, 4480, + 2816, 4480, + 2816, 4416); + + // Entrance to dorgesh kaan + addPolygonTo(MULTICOMBAT, + 3328, 9600, + 3312, 9600, + 3312, 9640, + 3304, 9640, + 3304, 9664, + 3328, 9664); + + // Hammerspikes hangout in dwarven mines + addPolygonTo(MULTICOMBAT, + 2960, 9824, + 2976, 9824, + 2976, 9800, + 2960, 9800); + + // Fremennik isles dungeon + addPolygonTo(MULTICOMBAT, + 2432, 10304, + 2432, 10240, + 2368, 10240, + 2368, 10304); + + // Varrock sewers + addPolygonTo(MULTICOMBAT, + 3152, 9920, + 3288, 9920, + 3288, 9856, + 3152, 9856); + + // Stronghold of security 1st floor + addPolygonTo(MULTICOMBAT, + 1856, 5248, + 1920, 5248, + 1920, 5184, + 1856, 5184); + + // Corp cave + addPolygonTo(MULTICOMBAT, + 2960, 4400, + 3000, 4400, + 3000, 4368, + 2960, 4368); + + // ZMI altar area + addPolygonTo(MULTICOMBAT, + 3008, 5632, + 3072, 5632, + 3072, 5568, + 3008, 5568); + + // Dragon slayer 2 zeah underground puzzle + addPolygonTo(MULTICOMBAT, + 1472, 9984, + 1536, 9984, + 1536, 9920, + 1472, 9920); + + // Wildy revenant caves + addPolygonTo(MULTICOMBAT, + 3136, 10062, + 3136, 10240, + 3236, 10240, + 3236, 10229, + 3264, 10229, + 3264, 10048, + 3208, 10048, + 3208, 10062); + + // King black dragon (Kbd) + addPolygonTo(MULTICOMBAT, + 2240, 4672, + 2240, 4736, + 2304, 4736, + 2304, 4672); + + // Scorpia + addPolygonTo(MULTICOMBAT, + 3248, 10352, + 3248, 10328, + 3216, 10328, + 3216, 10352); + + // Inside mage bank + addPolygonTo(MULTICOMBAT, + 2496, 4672, + 2496, 4736, + 2560, 4736, + 2560, 4672); + + // Wildy godwars dungeon + addPolygonTo(MULTICOMBAT, + 3072, 10112, + 3008, 10112, + 3008, 10176, + 3048, 10176, + 3048, 10152, + 3056, 10152, + 3056, 10144, + 3064, 10144, + 3064, 10136, + 3072, 10136); + + // Enchanted valley + addPolygonTo(MULTICOMBAT, + 3008, 4480, + 3008, 4544, + 3072, 4544, + 3072, 4480); + + // Zulrah + addPolygonTo(MULTICOMBAT, + 2256, 3080, + 2280, 3080, + 2280, 3064, + 2256, 3064); + + // Abyssal sire and abyss + addPolygonTo(MULTICOMBAT, + 3008, 4736, + 2944, 4736, + 2944, 4864, + 3136, 4864, + 3136, 4736, + 3072, 4736, + 3072, 4800, + 3008, 4800); + } + + private static void defineDeadmanSafeZones() + { + // Varrock + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3182, 3382, + 3182, 3399, + 3174, 3399, + 3174, 3448, + 3198, 3448, + 3198, 3449, + 3197, 3449, + 3197, 3450, + 3196, 3450, + 3196, 3451, + 3195, 3451, + 3195, 3452, + 3194, 3452, + 3194, 3453, + 3193, 3453, + 3193, 3454, + 3192, 3454, + 3192, 3455, + 3191, 3455, + 3191, 3456, + 3190, 3456, + 3190, 3457, + 3185, 3457, + 3185, 3463, + 3186, 3463, + 3186, 3464, + 3187, 3464, + 3187, 3467, + 3167, 3467, + 3167, 3468, + 3163, 3468, + 3163, 3467, + 3142, 3467, + 3142, 3468, + 3141, 3468, + 3141, 3469, + 3140, 3469, + 3140, 3470, + 3139, 3470, + 3139, 3471, + 3138, 3471, + 3138, 3484, + 3139, 3484, + 3139, 3485, + 3140, 3485, + 3140, 3486, + 3141, 3486, + 3141, 3491, + 3140, 3491, + 3140, 3492, + 3139, 3492, + 3139, 3493, + 3138, 3493, + 3138, 3515, + 3139, 3515, + 3139, 3516, + 3140, 3516, + 3140, 3517, + 3141, 3517, + 3141, 3518, + 3160, 3518, + 3160, 3517, + 3161, 3517, + 3161, 3516, + 3162, 3516, + 3162, 3515, + 3167, 3515, + 3167, 3516, + 3168, 3516, + 3168, 3517, + 3169, 3517, + 3169, 3518, + 3191, 3518, + 3191, 3517, + 3192, 3517, + 3192, 3516, + 3193, 3516, + 3193, 3515, + 3194, 3515, + 3194, 3514, + 3195, 3514, + 3195, 3513, + 3196, 3513, + 3196, 3512, + 3197, 3512, + 3197, 3511, + 3198, 3511, + 3198, 3510, + 3199, 3510, + 3199, 3509, + 3200, 3509, + 3200, 3508, + 3230, 3508, + 3230, 3507, + 3231, 3507, + 3231, 3506, + 3232, 3506, + 3232, 3505, + 3233, 3505, + 3233, 3504, + 3234, 3504, + 3234, 3503, + 3235, 3503, + 3235, 3502, + 3252, 3502, + 3252, 3496, + 3253, 3496, + 3253, 3495, + 3254, 3495, + 3254, 3494, + 3255, 3494, + 3255, 3493, + 3263, 3493, + 3263, 3472, + 3264, 3472, + 3264, 3471, + 3265, 3471, + 3265, 3470, + 3266, 3470, + 3266, 3469, + 3267, 3469, + 3267, 3468, + 3268, 3468, + 3268, 3467, + 3269, 3467, + 3269, 3466, + 3270, 3466, + 3270, 3465, + 3271, 3465, + 3271, 3437, + 3274, 3437, + 3274, 3424, + 3277, 3424, + 3277, 3420, + 3274, 3420, + 3274, 3411, + 3275, 3411, + 3275, 3410, + 3276, 3410, + 3276, 3409, + 3277, 3409, + 3277, 3408, + 3288, 3408, + 3288, 3391, + 3289, 3391, + 3289, 3385, + 3290, 3385, + 3290, 3378, + 3289, 3378, + 3289, 3377, + 3288, 3377, + 3288, 3376, + 3265, 3376, + 3265, 3380, + 3253, 3380, + 3253, 3382, + 3245, 3382, + 3245, 3380, + 3242, 3380, + 3242, 3382, + 3239, 3382, + 3239, 3381, + 3209, 3381, + 3209, 3382, + 3282, 3382); + + // Lumbridge + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3201, 3257, + 3213, 3257, + 3213, 3264, + 3233, 3264, + 3233, 3257, + 3235, 3257, + 3235, 3241, + 3237, 3241, + 3237, 3237, + 3239, 3237, + 3239, 3231, + 3243, 3231, + 3243, 3220, + 3253, 3220, + 3253, 3217, + 3256, 3217, + 3256, 3212, + 3259, 3212, + 3259, 3190, + 3247, 3190, + 3247, 3191, + 3238, 3191, + 3238, 3195, + 3230, 3195, + 3230, 3201, + 3228, 3201, + 3228, 3202, + 3227, 3202, + 3227, 3205, + 3228, 3205, + 3228, 3207, + 3225, 3207, + 3225, 3206, + 3224, 3206, + 3224, 3205, + 3223, 3205, + 3223, 3204, + 3222, 3204, + 3222, 3203, + 3215, 3203, + 3215, 3202, + 3214, 3202, + 3214, 3201, + 3203, 3201, + 3203, 3202, + 3202, 3202, + 3202, 3203, + 3201, 3203, + 3201, 3217, + 3199, 3217, + 3199, 3220, + 3201, 3220); + + // Falador + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2986, 3395, + 2986, 3394, + 2987, 3394, + 2987, 3393, + 2996, 3393, + 2996, 3394, + 3002, 3394, + 3002, 3395, + 3009, 3395, + 3009, 3394, + 3010, 3394, + 3010, 3393, + 3011, 3393, + 3011, 3392, + 3021, 3392, + 3021, 3391, + 3022, 3391, + 3022, 3390, + 3041, 3390, + 3041, 3389, + 3047, 3389, + 3047, 3390, + 3062, 3390, + 3062, 3389, + 3063, 3389, + 3063, 3388, + 3064, 3388, + 3064, 3387, + 3065, 3387, + 3065, 3386, + 3066, 3386, + 3066, 3368, + 3065, 3368, + 3065, 3367, + 3064, 3367, + 3064, 3366, + 3063, 3366, + 3063, 3365, + 3062, 3365, + 3062, 3364, + 3061, 3364, + 3061, 3363, + 3060, 3363, + 3060, 3331, + 3061, 3331, + 3061, 3328, + 3058, 3328, + 3058, 3329, + 3025, 3329, + 3025, 3328, + 3024, 3328, + 3024, 3327, + 3016, 3327, + 3016, 3326, + 3015, 3326, + 3015, 3325, + 3014, 3325, + 3014, 3324, + 3013, 3324, + 3013, 3323, + 3008, 3323, + 3008, 3324, + 3006, 3324, + 3006, 3323, + 3002, 3323, + 3002, 3322, + 3001, 3322, + 3001, 3321, + 3000, 3321, + 3000, 3320, + 2999, 3320, + 2999, 3319, + 2998, 3319, + 2998, 3318, + 2997, 3318, + 2997, 3317, + 2996, 3317, + 2996, 3316, + 2992, 3316, + 2992, 3315, + 2991, 3315, + 2991, 3314, + 2990, 3314, + 2990, 3313, + 2989, 3313, + 2989, 3312, + 2988, 3312, + 2988, 3311, + 2987, 3311, + 2987, 3310, + 2986, 3310, + 2986, 3309, + 2966, 3309, + 2966, 3310, + 2956, 3310, + 2956, 3311, + 2941, 3311, + 2941, 3312, + 2940, 3312, + 2940, 3320, + 2936, 3320, + 2936, 3354, + 2937, 3354, + 2937, 3357, + 2936, 3357, + 2936, 3389, + 2937, 3389, + 2937, 3390, + 2938, 3390, + 2938, 3391, + 2939, 3391, + 2939, 3392, + 2940, 3392, + 2940, 3393, + 2943, 3393, + 2943, 3394, + 2944, 3394, + 2944, 3395, + 2950, 3395, + 2950, 3394, + 2956, 3394, + 2956, 3395); + + // Port phasmatys + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3650, 3456, + 3650, 3472, + 3651, 3472, + 3651, 3473, + 3652, 3473, + 3652, 3474, + 3653, 3474, + 3653, 3507, + 3654, 3507, + 3654, 3508, + 3668, 3508, + 3668, 3509, + 3669, 3509, + 3669, 3510, + 3670, 3510, + 3670, 3511, + 3671, 3511, + 3671, 3512, + 3672, 3512, + 3672, 3513, + 3673, 3513, + 3673, 3514, + 3674, 3514, + 3674, 3515, + 3675, 3515, + 3675, 3516, + 3676, 3516, + 3676, 3517, + 3687, 3517, + 3687, 3494, + 3690, 3494, + 3690, 3493, + 3696, 3493, + 3696, 3482, + 3699, 3482, + 3699, 3481, + 3712, 3481, + 3712, 3456); + + // Sophanem + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3274, 2752, + 3274, 2784, + 3277, 2784, + 3277, 2786, + 3274, 2786, + 3274, 2789, + 3272, 2789, + 3272, 2810, + 3322, 2810, + 3322, 2752); + + // Ardy + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2560, 3256, + 2560, 3264, + 2559, 3264, + 2559, 3328, + 2560, 3328, + 2560, 3339, + 2561, 3339, + 2561, 3340, + 2562, 3340, + 2562, 3341, + 2563, 3341, + 2563, 3342, + 2616, 3342, + 2616, 3341, + 2617, 3341, + 2617, 3340, + 2669, 3340, + 2669, 3339, + 2670, 3339, + 2670, 3338, + 2671, 3338, + 2671, 3337, + 2672, 3337, + 2672, 3336, + 2673, 3336, + 2673, 3335, + 2674, 3335, + 2674, 3334, + 2683, 3334, + 2683, 3333, + 2684, 3333, + 2684, 3332, + 2685, 3332, + 2685, 3331, + 2686, 3331, + 2686, 3330, + 2687, 3330, + 2687, 3329, + 2688, 3329, + 2688, 3264, + 2638, 3264, + 2638, 3263, + 2625, 3263, + 2625, 3264, + 2611, 3264, + 2611, 3257, + 2602, 3257, + 2602, 3264, + 2587, 3264, + 2587, 3263, + 2586, 3263, + 2586, 3262, + 2584, 3262, + 2584, 3261, + 2583, 3261, + 2583, 3260, + 2582, 3260, + 2582, 3259, + 2581, 3259, + 2581, 3258, + 2572, 3258, + 2572, 3260, + 2571, 3260, + 2571, 3261, + 2566, 3261, + 2566, 3260, + 2565, 3260, + 2565, 3259, + 2564, 3259, + 2564, 3256); + + // Yanille + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2613, 3103, + 2614, 3103, + 2614, 3102, + 2615, 3102, + 2615, 3101, + 2616, 3101, + 2616, 3100, + 2617, 3100, + 2617, 3099, + 2618, 3099, + 2618, 3098, + 2619, 3098, + 2619, 3097, + 2620, 3097, + 2620, 3075, + 2590, 3075, + 2590, 3074, + 2589, 3074, + 2589, 3073, + 2584, 3073, + 2584, 3074, + 2583, 3074, + 2583, 3075, + 2543, 3075, + 2543, 3076, + 2542, 3076, + 2542, 3077, + 2539, 3077, + 2539, 3107, + 2542, 3107, + 2542, 3108, + 2543, 3108, + 2543, 3109, + 2608, 3109, + 2608, 3108, + 2609, 3108, + 2609, 3107, + 2610, 3107, + 2610, 3106, + 2611, 3106, + 2611, 3105, + 2612, 3105, + 2612, 3104, + 2613, 3104); + + // Gnome stronghold + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2495, 3439, + 2494, 3439, + 2494, 3432, + 2495, 3432, + 2495, 3431, + 2496, 3431, + 2496, 3430, + 2497, 3430, + 2497, 3429, + 2498, 3429, + 2498, 3417, + 2497, 3417, + 2497, 3416, + 2496, 3416, + 2496, 3412, + 2495, 3412, + 2495, 3408, + 2494, 3408, + 2494, 3404, + 2495, 3404, + 2495, 3403, + 2496, 3403, + 2496, 3402, + 2497, 3402, + 2497, 3401, + 2498, 3401, + 2498, 3400, + 2499, 3400, + 2499, 3399, + 2500, 3399, + 2500, 3398, + 2501, 3398, + 2501, 3397, + 2502, 3397, + 2502, 3396, + 2506, 3396, + 2506, 3391, + 2502, 3391, + 2502, 3390, + 2492, 3390, + 2492, 3391, + 2489, 3391, + 2489, 3390, + 2488, 3390, + 2488, 3389, + 2485, 3389, + 2485, 3390, + 2482, 3390, + 2482, 3389, + 2476, 3389, + 2476, 3390, + 2471, 3390, + 2471, 3391, + 2468, 3391, + 2468, 3390, + 2467, 3390, + 2467, 3389, + 2466, 3389, + 2466, 3385, + 2465, 3385, + 2465, 3384, + 2458, 3384, + 2458, 3385, + 2457, 3385, + 2457, 3389, + 2456, 3389, + 2456, 3390, + 2455, 3390, + 2455, 3391, + 2450, 3391, + 2450, 3390, + 2446, 3390, + 2446, 3391, + 2443, 3391, + 2443, 3390, + 2442, 3390, + 2442, 3389, + 2440, 3389, + 2440, 3388, + 2434, 3388, + 2434, 3389, + 2433, 3389, + 2433, 3390, + 2432, 3390, + 2432, 3391, + 2428, 3391, + 2428, 3392, + 2427, 3392, + 2427, 3393, + 2420, 3393, + 2420, 3394, + 2419, 3394, + 2419, 3395, + 2418, 3395, + 2418, 3396, + 2417, 3396, + 2417, 3397, + 2416, 3397, + 2416, 3399, + 2415, 3399, + 2415, 3400, + 2414, 3400, + 2414, 3408, + 2413, 3408, + 2413, 3409, + 2412, 3409, + 2412, 3410, + 2411, 3410, + 2411, 3411, + 2410, 3411, + 2410, 3412, + 2387, 3412, + 2387, 3407, + 2383, 3407, + 2383, 3408, + 2380, 3408, + 2380, 3409, + 2379, 3409, + 2379, 3410, + 2377, 3410, + 2377, 3411, + 2376, 3411, + 2376, 3413, + 2375, 3413, + 2375, 3417, + 2374, 3417, + 2374, 3418, + 2373, 3418, + 2373, 3419, + 2372, 3419, + 2372, 3420, + 2371, 3420, + 2371, 3421, + 2370, 3421, + 2370, 3422, + 2369, 3422, + 2369, 3433, + 2370, 3433, + 2370, 3434, + 2371, 3434, + 2371, 3444, + 2372, 3444, + 2372, 3445, + 2373, 3445, + 2373, 3446, + 2374, 3446, + 2374, 3447, + 2375, 3447, + 2375, 3459, + 2376, 3459, + 2376, 3460, + 2377, 3460, + 2377, 3461, + 2378, 3461, + 2378, 3462, + 2379, 3462, + 2379, 3463, + 2380, 3463, + 2380, 3464, + 2381, 3464, + 2381, 3476, + 2379, 3476, + 2379, 3477, + 2378, 3477, + 2378, 3478, + 2377, 3478, + 2377, 3485, + 2376, 3485, + 2376, 3486, + 2375, 3486, + 2375, 3499, + 2376, 3499, + 2376, 3500, + 2377, 3500, + 2377, 3507, + 2378, 3507, + 2378, 3508, + 2379, 3508, + 2379, 3509, + 2380, 3509, + 2380, 3521, + 2382, 3521, + 2382, 3522, + 2384, 3522, + 2384, 3523, + 2393, 3523, + 2393, 3524, + 2399, 3524, + 2399, 3525, + 2404, 3525, + 2404, 3524, + 2405, 3524, + 2405, 3523, + 2407, 3523, + 2407, 3522, + 2415, 3522, + 2415, 3521, + 2425, 3521, + 2425, 3522, + 2427, 3522, + 2427, 3523, + 2430, 3523, + 2430, 3522, + 2431, 3522, + 2431, 3521, + 2432, 3521, + 2432, 3520, + 2448, 3520, + 2448, 3517, + 2454, 3517, + 2454, 3516, + 2455, 3516, + 2455, 3515, + 2456, 3515, + 2456, 3514, + 2457, 3514, + 2457, 3513, + 2460, 3513, + 2460, 3512, + 2461, 3512, + 2461, 3511, + 2465, 3511, + 2465, 3510, + 2468, 3510, + 2468, 3511, + 2472, 3511, + 2472, 3512, + 2473, 3512, + 2473, 3513, + 2475, 3513, + 2475, 3514, + 2476, 3514, + 2476, 3515, + 2477, 3515, + 2477, 3516, + 2478, 3516, + 2478, 3517, + 2483, 3517, + 2483, 3516, + 2487, 3516, + 2487, 3515, + 2488, 3515, + 2488, 3512, + 2487, 3512, + 2487, 3509, + 2488, 3509, + 2488, 3508, + 2489, 3508, + 2489, 3507, + 2491, 3507, + 2491, 3506, + 2492, 3506, + 2492, 3505, + 2493, 3505, + 2493, 3499, + 2492, 3499, + 2492, 3498, + 2491, 3498, + 2491, 3497, + 2490, 3497, + 2490, 3495, + 2491, 3495, + 2491, 3494, + 2492, 3494, + 2492, 3493, + 2493, 3493, + 2493, 3485, + 2490, 3485, + 2490, 3484, + 2489, 3484, + 2489, 3483, + 2488, 3483, + 2488, 3482, + 2487, 3482, + 2487, 3481, + 2486, 3481, + 2486, 3474, + 2488, 3474, + 2488, 3471, + 2489, 3471, + 2489, 3470, + 2490, 3470, + 2490, 3460, + 2491, 3460, + 2491, 3456, + 2496, 3456, + 2496, 3440, + 2495, 3440); + + // Rellekka + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2620, 3682, + 2624, 3682, + 2624, 3683, + 2625, 3683, + 2625, 3687, + 2629, 3687, + 2629, 3686, + 2630, 3686, + 2630, 3685, + 2632, 3685, + 2632, 3686, + 2636, 3686, + 2636, 3692, + 2645, 3692, + 2645, 3695, + 2647, 3695, + 2647, 3696, + 2649, 3696, + 2649, 3702, + 2650, 3702, + 2650, 3703, + 2651, 3703, + 2651, 3704, + 2652, 3704, + 2652, 3711, + 2653, 3711, + 2653, 3712, + 2691, 3712, + 2691, 3709, + 2692, 3709, + 2692, 3707, + 2693, 3707, + 2693, 3703, + 2692, 3703, + 2692, 3701, + 2691, 3701, + 2691, 3699, + 2690, 3699, + 2690, 3695, + 2691, 3695, + 2691, 3693, + 2692, 3693, + 2692, 3691, + 2693, 3691, + 2693, 3685, + 2692, 3685, + 2692, 3683, + 2691, 3683, + 2691, 3681, + 2690, 3681, + 2690, 3680, + 2689, 3680, + 2689, 3672, + 2690, 3672, + 2690, 3671, + 2691, 3671, + 2691, 3666, + 2690, 3666, + 2690, 3664, + 2689, 3664, + 2689, 3660, + 2690, 3660, + 2690, 3658, + 2691, 3658, + 2691, 3656, + 2692, 3656, + 2692, 3654, + 2693, 3654, + 2693, 3651, + 2692, 3651, + 2692, 3649, + 2690, 3649, + 2690, 3648, + 2688, 3648, + 2688, 3647, + 2686, 3647, + 2686, 3646, + 2673, 3646, + 2673, 3645, + 2636, 3645, + 2636, 3647, + 2627, 3647, + 2627, 3648, + 2625, 3648, + 2625, 3649, + 2624, 3649, + 2624, 3650, + 2622, 3650, + 2622, 3651, + 2620, 3651, + 2620, 3652, + 2618, 3652, + 2618, 3653, + 2616, 3653, + 2616, 3654, + 2609, 3654, + 2609, 3655, + 2607, 3655, + 2607, 3656, + 2603, 3656, + 2603, 3657, + 2602, 3657, + 2602, 3658, + 2601, 3658, + 2601, 3663, + 2602, 3663, + 2602, 3664, + 2603, 3664, + 2603, 3665, + 2604, 3665, + 2604, 3666, + 2605, 3666, + 2605, 3667, + 2606, 3667, + 2606, 3671, + 2609, 3671, + 2609, 3672, + 2610, 3672, + 2610, 3673, + 2611, 3673, + 2611, 3675, + 2612, 3675, + 2612, 3676, + 2614, 3676, + 2614, 3677, + 2616, 3677, + 2616, 3679, + 2618, 3679, + 2618, 3681, + 2620, 3681); + + // Jatizo + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2407, 3797, + 2407, 3793, + 2399, 3793, + 2399, 3792, + 2391, 3792, + 2391, 3791, + 2386, 3791, + 2386, 3796, + 2388, 3796, + 2388, 3802, + 2386, 3802, + 2386, 3807, + 2388, 3807, + 2388, 3809, + 2402, 3809, + 2402, 3819, + 2406, 3819, + 2406, 3824, + 2408, 3824, + 2408, 3826, + 2413, 3826, + 2413, 3824, + 2419, 3824, + 2419, 3826, + 2424, 3826, + 2424, 3821, + 2423, 3821, + 2423, 3798, + 2422, 3798, + 2422, 3797); + + // Neitiznot + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2329, 3812, + 2333, 3812, + 2333, 3813, + 2334, 3813, + 2334, 3814, + 2335, 3814, + 2335, 3815, + 2338, 3815, + 2338, 3816, + 2339, 3816, + 2339, 3817, + 2368, 3817, + 2368, 3776, + 2352, 3776, + 2352, 3796, + 2344, 3796, + 2344, 3795, + 2331, 3795, + 2331, 3797, + 2330, 3797, + 2330, 3798, + 2329, 3798); + + // Pest control + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2624, 2688, + 2688, 2688, + 2688, 2624, + 2624, 2624); + + // Tutorial island + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 3052, 3135, + 3156, 3135, + 3156, 3057, + 3052, 3057); + + // Camelot bank + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2724, 3487, + 2724, 3490, + 2721, 3490, + 2721, 3494, + 2719, 3494, + 2719, 3497, + 2721, 3497, + 2721, 3498, + 2731, 3498, + 2731, 3490, + 2728, 3490, + 2728, 3487); + + // Catherby bank + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 2806, 3438, + 2806, 3446, + 2813, 3446, + 2813, 3438); + + // Kourend castle + addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, + 1627, 3658, + 1620, 3658, + 1620, 3657, + 1619, 3657, + 1619, 3656, + 1614, 3656, + 1614, 3657, + 1613, 3657, + 1613, 3661, + 1612, 3661, + 1612, 3662, + 1611, 3662, + 1611, 3663, + 1600, 3663, + 1600, 3662, + 1599, 3662, + 1599, 3661, + 1594, 3661, + 1594, 3662, + 1593, 3662, + 1593, 3685, + 1594, 3685, + 1594, 3686, + 1599, 3686, + 1599, 3685, + 1600, 3685, + 1600, 3684, + 1611, 3684, + 1611, 3685, + 1612, 3685, + 1612, 3686, + 1613, 3686, + 1613, 3690, + 1614, 3690, + 1614, 3691, + 1619, 3691, + 1619, 3690, + 1620, 3690, + 1620, 3689, + 1630, 3689, + 1630, 3686, + 1620, 3686, + 1620, 3685, + 1619, 3685, + 1619, 3683, + 1620, 3683, + 1620, 3682, + 1621, 3682, + 1621, 3681, + 1622, 3681, + 1622, 3680, + 1623, 3680, + 1623, 3679, + 1624, 3679, + 1624, 3668, + 1623, 3668, + 1623, 3667, + 1622, 3667, + 1622, 3666, + 1621, 3666, + 1621, 3665, + 1620, 3665, + 1620, 3664, + 1619, 3664, + 1619, 3662, + 1620, 3662, + 1620, 3661, + 1627, 3661); + } + + private static void definePvpSafeZones() + { + // Grand exchange + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3159, 3473, + 3159, 3474, + 3157, 3474, + 3157, 3475, + 3155, 3475, + 3155, 3476, + 3153, 3476, + 3153, 3477, + 3152, 3477, + 3152, 3478, + 3151, 3478, + 3151, 3480, + 3150, 3480, + 3150, 3482, + 3149, 3482, + 3149, 3484, + 3148, 3484, + 3148, 3496, + 3149, 3496, + 3149, 3498, + 3150, 3498, + 3150, 3500, + 3151, 3500, + 3151, 3502, + 3152, 3502, + 3152, 3503, + 3153, 3503, + 3153, 3504, + 3155, 3504, + 3155, 3505, + 3157, 3505, + 3157, 3506, + 3159, 3506, + 3159, 3507, + 3171, 3507, + 3171, 3506, + 3173, 3506, + 3173, 3505, + 3175, 3505, + 3175, 3504, + 3177, 3504, + 3177, 3503, + 3178, 3503, + 3178, 3502, + 3179, 3502, + 3179, 3500, + 3180, 3500, + 3180, 3498, + 3181, 3498, + 3181, 3496, + 3182, 3496, + 3182, 3484, + 3181, 3484, + 3181, 3482, + 3180, 3482, + 3180, 3480, + 3179, 3480, + 3179, 3478, + 3178, 3478, + 3178, 3477, + 3177, 3477, + 3177, 3476, + 3175, 3476, + 3175, 3475, + 3173, 3475, + 3173, 3474, + 3171, 3474, + 3171, 3473); + + // Edgeville + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3091, 3488, + 3091, 3493, + 3090, 3493, + 3090, 3498, + 3091, 3498, + 3091, 3500, + 3099, 3500, + 3099, 3488); + + // Fally west bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2943, 3368, + 2943, 3374, + 2948, 3374, + 2948, 3370, + 2950, 3370, + 2950, 3366, + 2949, 3366, + 2949, 3359, + 2945, 3359, + 2945, 3362, + 2946, 3362, + 2946, 3366, + 2945, 3366, + 2945, 3368); + + // Fally east bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3009, 3353, + 3009, 3359, + 3019, 3359, + 3019, 3357, + 3022, 3357, + 3022, 3353); + + // Fally castle + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2964, 3354, + 2966, 3354, + 2966, 3352, + 2967, 3352, + 2967, 3349, + 2976, 3349, + 2976, 3348, + 2977, 3348, + 2977, 3347, + 2981, 3347, + 2981, 3343, + 2982, 3343, + 2982, 3339, + 2981, 3339, + 2981, 3337, + 2967, 3337, + 2967, 3330, + 2963, 3330, + 2963, 3331, + 2962, 3331, + 2962, 3332, + 2961, 3332, + 2961, 3334, + 2964, 3334, + 2964, 3335, + 2965, 3335, + 2965, 3343, + 2964, 3343, + 2964, 3344, + 2961, 3344, + 2961, 3350, + 2963, 3350, + 2963, 3352, + 2964, 3352); + + // Varrock east bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3250, 3425, + 3258, 3425, + 3258, 3416, + 3250, 3416); + + // Varrock west bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3180, 3433, + 3180, 3448, + 3191, 3448, + 3191, 3433); + + // Port phasmatys + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3686, 3472, + 3700, 3472, + 3700, 3461, + 3686, 3461); + + // Yanille bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2609, 3088, + 2609, 3098, + 2617, 3098, + 2617, 3088); + + // Ardy east bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2649, 3280, + 2649, 3288, + 2659, 3288, + 2659, 3280); + + // Ardy west bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2612, 3330, + 2612, 3336, + 2615, 3336, + 2615, 3335, + 2619, 3335, + 2619, 3336, + 2622, 3336, + 2622, 3330); + + // Fishing guild bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2593, 3413, + 2588, 3413, + 2588, 3418, + 2583, 3418, + 2583, 3423, + 2590, 3423, + 2590, 3420, + 2593, 3420); + + // Gnome stronghold bank near slayer cave (2nd floor) + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, + 2444, 3431, + 2444, 3435, + 2448, 3435, + 2448, 3431, + 2447, 3431, + 2447, 3428, + 2449, 3428, + 2449, 3422, + 2447, 3422, + 2447, 3419, + 2448, 3419, + 2448, 3415, + 2444, 3415, + 2444, 3419, + 2445, 3419, + 2445, 3422, + 2443, 3422, + 2443, 3428, + 2445, 3428, + 2445, 3431); + + // Gnome stronghold bank in grand tree + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, + 2456, 3488, + 2452, 3488, + 2452, 3486, + 2450, 3486, + 2450, 3483, + 2451, 3483, + 2451, 3478, + 2448, 3478, + 2448, 3483, + 2449, 3483, + 2449, 3486, + 2447, 3486, + 2447, 3488, + 2443, 3488, + 2443, 3487, + 2438, 3487, + 2438, 3490, + 2443, 3490, + 2443, 3489, + 2447, 3489, + 2447, 3491, + 2449, 3491, + 2449, 3494, + 2448, 3494, + 2448, 3496, + 2451, 3496, + 2451, 3494, + 2450, 3494, + 2450, 3491, + 2452, 3491, + 2452, 3489, + 2456, 3489); + + // Al kharid bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3265, 3161, + 3265, 3174, + 3273, 3174, + 3273, 3161); + + // Shantay pass bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3308, 3119, + 3308, 3125, + 3310, 3125, + 3310, 3119); + + // Nardah bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3431, 2891, + 3431, 2889, + 3427, 2889, + 3427, 2887, + 3424, 2887, + 3424, 2895, + 3431, 2895, + 3431, 2893, + 3432, 2893, + 3432, 2891); + + // Sophanem bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2807, 5158, + 2792, 5158, + 2792, 5175, + 2807, 5175); + + // Canifis bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3509, 3474, + 3509, 3478, + 3508, 3478, + 3508, 3483, + 3509, 3483, + 3509, 3484, + 3517, 3484, + 3517, 3477, + 3516, 3477, + 3516, 3476, + 3513, 3476, + 3513, 3474); + + // Lumbridge castle outside + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3216, 3209, + 3216, 3210, + 3217, 3210, + 3217, 3228, + 3216, 3228, + 3216, 3229, + 3227, 3229, + 3227, 3221, + 3230, 3221, + 3230, 3217, + 3227, 3217, + 3227, 3209); + + // Lumbridge bank upstairs + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 2, + 3211, 3223, + 3211, 3215, + 3207, 3215, + 3207, 3223); + + // Draynor bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3098, 3240, + 3088, 3240, + 3088, 3247, + 3098, 3247); + + // Pest control bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2665, 2656, + 2670, 2656, + 2670, 2651, + 2665, 2651); + + // Shilo village bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2843, 2957, + 2846, 2957, + 2846, 2956, + 2849, 2956, + 2849, 2957, + 2850, 2957, + 2850, 2958, + 2855, 2958, + 2855, 2957, + 2856, 2957, + 2856, 2956, + 2858, 2956, + 2858, 2957, + 2862, 2957, + 2862, 2952, + 2858, 2952, + 2858, 2953, + 2856, 2953, + 2856, 2952, + 2855, 2952, + 2855, 2951, + 2850, 2951, + 2850, 2952, + 2849, 2952, + 2849, 2953, + 2847, 2953, + 2847, 2952, + 2843, 2952); + + // Legends guild bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 2, + 2731, 3374, + 2731, 3383, + 2734, 3383, + 2734, 3374); + + // Legends guild middle floor + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, + 2724, 3374, + 2724, 3383, + 2734, 3383, + 2734, 3382, + 2736, 3382, + 2736, 3375, + 2734, 3375, + 2734, 3374); + + // Warriors guild bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2843, 3537, + 2843, 3540, + 2841, 3540, + 2841, 3546, + 2849, 3546, + 2849, 3537, + 2847, 3537, + 2847, 3536, + 2846, 3536, + 2846, 3537); + + // Camelot bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2724, 3487, + 2724, 3490, + 2721, 3490, + 2721, 3494, + 2719, 3494, + 2719, 3497, + 2721, 3497, + 2721, 3498, + 2731, 3498, + 2731, 3490, + 2728, 3490, + 2728, 3487); + + // Camelot respawn point + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2761, 3483, + 2761, 3476, + 2755, 3476, + 2755, 3483); + + // Catherby bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2806, 3438, + 2806, 3446, + 2813, 3446, + 2813, 3438); + + // Barbarian outpost bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2536, 3572, + 2536, 3575, + 2538, 3575, + 2538, 3572); + + // Piscatoris bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2327, 3686, + 2327, 3694, + 2333, 3694, + 2333, 3686); + + // Lletya bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2350, 3161, + 2350, 3165, + 2351, 3165, + 2351, 3167, + 2357, 3167, + 2357, 3165, + 2356, 3165, + 2356, 3164, + 2355, 3164, + 2355, 3161); + + // Castle wars bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2446, 3087, + 2445, 3087, + 2445, 3085, + 2447, 3085, + 2447, 3081, + 2443, 3081, + 2443, 3082, + 2439, 3082, + 2439, 3081, + 2435, 3081, + 2435, 3099, + 2439, 3099, + 2439, 3098, + 2443, 3098, + 2443, 3099, + 2447, 3099, + 2447, 3095, + 2445, 3095, + 2445, 3093, + 2446, 3093); + + // Duel arena bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3380, 3267, + 3380, 3273, + 3381, 3273, + 3381, 3274, + 3385, 3274, + 3385, 3267); + + // Clan wars bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3375, 3165, + 3361, 3165, + 3361, 3173, + 3375, 3173); + + // Lumbridge cellar bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 3218, 9622, + 3218, 9624, + 3220, 9624, + 3220, 9622); + + // Dorgesh kaan bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2709, 5348, + 2707, 5348, + 2707, 5345, + 2701, 5345, + 2701, 5347, + 2697, 5347, + 2697, 5353, + 2701, 5353, + 2701, 5355, + 2707, 5355, + 2707, 5350, + 2709, 5350); + + // Keldagrim bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2842, 10204, + 2834, 10204, + 2834, 10216, + 2842, 10216); + + // Tzhaar bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2438, 5176, + 2438, 5180, + 2441, 5180, + 2441, 5182, + 2449, 5182, + 2449, 5181, + 2450, 5181, + 2450, 5180, + 2452, 5180, + 2452, 5175, + 2441, 5175, + 2441, 5176); + + // Inferno bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2542, 5135, + 2542, 5139, + 2539, 5139, + 2539, 5140, + 2538, 5140, + 2538, 5141, + 2537, 5141, + 2537, 5144, + 2541, 5144, + 2541, 5145, + 2543, 5145, + 2543, 5144, + 2544, 5144, + 2544, 5142, + 2545, 5142, + 2545, 5135); + + // Port khazard bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2661, 3160, + 2661, 3163, + 2666, 3163, + 2666, 3160); + + // Corsair cove bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2569, 2863, + 2569, 2868, + 2572, 2868, + 2572, 2863); + + // Burgh de rott bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3495, 3210, + 3495, 3214, + 3501, 3214, + 3501, 3210); + + // Edgeville respawn point + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3092, 3468, + 3092, 3474, + 3098, 3474, + 3098, 3468); + + // Mage bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2529, 4711, + 2529, 4724, + 2548, 4724, + 2548, 4711); + + // Lunar bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2097, 3917, + 2097, 3922, + 2105, 3922, + 2105, 3917); + + // Jatizo bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2414, 3801, + 2414, 3804, + 2420, 3804, + 2420, 3801); + + // Neitiznot bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2334, 3805, + 2334, 3809, + 2340, 3809, + 2340, 3805); + + // Hosidius bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1671, 3558, + 1671, 3577, + 1682, 3577, + 1682, 3558); + + // Woodcutting guild bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1589, 3475, + 1589, 3481, + 1594, 3481, + 1594, 3475); + + // Lands end bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1508, 3415, + 1508, 3424, + 1514, 3424, + 1514, 3415); + + // Chambers of xeric bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1252, 3570, + 1252, 3574, + 1257, 3574, + 1257, 3570); + + // Arceuus bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1621, 3736, + 1621, 3754, + 1627, 3754, + 1627, 3751, + 1633, 3751, + 1633, 3754, + 1639, 3754, + 1639, 3736); + + // Piscarilius bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1794, 3784, + 1794, 3794, + 1812, 3794, + 1812, 3784); + + // Lovakengj bank southeast + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1518, 3735, + 1518, 3744, + 1535, 3744, + 1535, 3735); + + // Lovakenj bank west + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1433, 3820, + 1433, 3837, + 1442, 3837, + 1442, 3820); + + // Lovakenj sulphur mine bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1452, 3855, + 1452, 3860, + 1455, 3860, + 1455, 3855); + + // Blast mine bank southeast + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1500, 3856, + 1500, 3858, + 1503, 3858, + 1503, 3856); + + // Wintertodt bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1638, 3942, + 1638, 3947, + 1642, 3947, + 1642, 3942); + + // Shayzien bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1495, 3612, + 1495, 3622, + 1515, 3622, + 1515, 3612); + + // Hosidius grape farm bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1804, 3571, + 1804, 3572, + 1808, 3572, + 1808, 3571); + + // Hosidius cooking bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 1652, 3605, + 1652, 3615, + 1661, 3615, + 1661, 3605); + + // Ecteria bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 2618, 3893, + 2618, 3897, + 2622, 3897, + 2622, 3893); + + // Mining guild expanded area + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 3018, 9733, + 3021, 9733, + 3021, 9729, + 3022, 9729, + 3022, 9728, + 3023, 9728, + 3023, 9727, + 3025, 9727, + 3025, 9726, + 3026, 9726, + 3026, 9725, + 3030, 9725, + 3030, 9726, + 3032, 9726, + 3032, 9727, + 3035, 9727, + 3035, 9726, + 3038, 9726, + 3038, 9727, + 3041, 9727, + 3041, 9728, + 3042, 9728, + 3042, 9730, + 3045, 9730, + 3045, 9727, + 3047, 9727, + 3047, 9726, + 3048, 9726, + 3048, 9724, + 3052, 9724, + 3052, 9725, + 3053, 9725, + 3053, 9726, + 3055, 9726, + 3055, 9725, + 3056, 9725, + 3056, 9723, + 3057, 9723, + 3057, 9720, + 3056, 9720, + 3056, 9719, + 3054, 9719, + 3054, 9718, + 3052, 9718, + 3052, 9717, + 3050, 9717, + 3050, 9718, + 3045, 9718, + 3045, 9716, + 3044, 9716, + 3044, 9715, + 3041, 9715, + 3041, 9714, + 3039, 9714, + 3039, 9713, + 3037, 9713, + 3037, 9714, + 3036, 9714, + 3036, 9715, + 3034, 9715, + 3034, 9716, + 3029, 9716, + 3029, 9715, + 3028, 9715, + 3028, 9714, + 3026, 9714, + 3026, 9709, + 3027, 9709, + 3027, 9708, + 3028, 9708, + 3028, 9705, + 3029, 9705, + 3029, 9701, + 3028, 9701, + 3028, 9700, + 3027, 9700, + 3027, 9699, + 3023, 9699, + 3023, 9700, + 3019, 9700, + 3019, 9701, + 3018, 9701, + 3018, 9705, + 3019, 9705, + 3019, 9707, + 3020, 9707, + 3020, 9708, + 3021, 9708, + 3021, 9709, + 3022, 9709, + 3022, 9713, + 3021, 9713, + 3021, 9714, + 3019, 9714, + 3019, 9715, + 3018, 9715, + 3018, 9717, + 3015, 9717, + 3015, 9716, + 3013, 9716, + 3013, 9717, + 3012, 9717, + 3012, 9720, + 3013, 9720, + 3013, 9721, + 3015, 9721, + 3015, 9723, + 3016, 9723, + 3016, 9727, + 3017, 9727, + 3017, 9730, + 3018, 9730); + + // Motherlode mine bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 3760, 5671, + 3760, 5668, + 3761, 5668, + 3761, 5665, + 3760, 5665, + 3760, 5663, + 3758, 5663, + 3758, 5671); + + // Mos le harmles bank + addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, + 3679, 2980, + 3679, 2985, + 3681, 2985, + 3681, 2984, + 3682, 2984, + 3682, 2985, + 3684, 2985, + 3684, 2980, + 3682, 2980, + 3682, 2981, + 3681, 2981, + 3681, 2980); + + // Zanaris bank + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 2388, 4454, + 2380, 4454, + 2380, 4463, + 2388, 4463); + + // Wodcuting guild bank underground + addPolygonTo(PVP_WORLD_SAFE_ZONES, + 1550, 9872, + 1550, 9874, + 1553, 9874, + 1553, 9872); + } + + private static void defineWilderness() + { + // Above ground + addPolygonTo(ROUGH_WILDERNESS, + 2944, 3523, + 3392, 3523, + 3392, 3971, + 2944, 3971); + + // Underground + addPolygonTo(ROUGH_WILDERNESS, + 2944, 9918, + 2944, 10360, + 3264, 10360, + 3264, 9918); + } + + private static void addPolygonTo(List[] shapes, int... coords) + { + Polygon poly = new Polygon(); + for (int i = 0; i < coords.length; i += 2) + { + poly.addPoint(coords[i], coords[i + 1]); + } + for (int i = 0; i < shapes.length; i++) + { + shapes[i].add(poly); + } + } + + private static void addPolygonOnPlane(List[] shapes, int plane, int... coords) + { + Polygon poly = new Polygon(); + for (int i = 0; i < coords.length; i += 2) + { + poly.addPoint(coords[i], coords[i + 1]); + } + shapes[plane].add(poly); + } + + private static void addPolygonOnPlanes(List[] shapes, int minPlane, int maxPlane, int... coords) + { + Polygon poly = new Polygon(); + for (int i = 0; i < coords.length; i += 2) + { + poly.addPoint(coords[i], coords[i + 1]); + } + for (int i = minPlane; i <= maxPlane; i++) + { + shapes[i].add(poly); + } + } +} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsConfig.java new file mode 100644 index 0000000000..370533dac7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +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 +{ + @ConfigItem( + keyName = "multicombatZoneVisibility", + name = "Multicombat zones", + description = "Determine where multicombat zones should be shown", + position = 1 + ) + default ZoneVisibility multicombatZoneVisibility() + { + return ZoneVisibility.SHOW_IN_PVP; + } + + @ConfigItem( + keyName = "pvpSafeZones", + name = "PvP safe zones", + description = "Show safe zones in PvP worlds", + position = 2 + ) + default boolean showPvpSafeZones() + { + return true; + } + + @ConfigItem( + keyName = "deadmanSafeZones", + name = "Deadman safe zones", + description = "Show safe zones in Deadman worlds", + position = 3 + ) + default boolean showDeadmanSafeZones() + { + return true; + } + + @ConfigItem( + keyName = "collisionDetection", + name = "Collision detection", + description = "Only show lines where they can be walked through", + position = 4 + ) + default boolean collisionDetection() + { + return false; + } + + @ConfigItem( + keyName = "showMinimapLines", + name = "Show on minimap", + description = "Show multicombat and safe zones on the minimap", + position = 5 + ) + default boolean showMinimapLines() + { + return true; + } + + @ConfigItem( + keyName = "multicombatColor", + name = "Multicombat zone color", + description = "Choose color to use for marking multicombat zones", + position = 6 + ) + default Color multicombatColor() + { + return Color.MAGENTA; + } + + @ConfigItem( + keyName = "safeZoneColor", + name = "Safe zone color", + description = "Choose color to use for marking safe zones in PvP/Deadman", + position = 7 + ) + default Color safeZoneColor() + { + return Color.GREEN; + } +} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsMinimapOverlay.java new file mode 100644 index 0000000000..699b0f0ddf --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.geom.GeneralPath; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.geometry.Geometry; +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; + +public class ZoneIndicatorsMinimapOverlay extends Overlay +{ + private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; + + @Inject + private Client client; + + @Inject + private ZoneIndicatorsPlugin plugin; + + @Inject + private ZoneIndicatorsConfig config; + + @Inject + public ZoneIndicatorsMinimapOverlay() + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ALWAYS_ON_TOP); + setPriority(OverlayPriority.LOW); + } + + private Color getTransparentColorVersion(Color c) + { + return new Color(c.getRed(), c.getGreen(), c.getBlue(), 192); + } + + private void renderPath(Graphics2D graphics, GeneralPath path, Color color) + { + LocalPoint playerLp = client.getLocalPlayer().getLocalLocation(); + Rectangle viewArea = new Rectangle( + playerLp.getX() - MAX_LOCAL_DRAW_LENGTH, + playerLp.getY() - MAX_LOCAL_DRAW_LENGTH, + MAX_LOCAL_DRAW_LENGTH * 2, + MAX_LOCAL_DRAW_LENGTH * 2); + + graphics.setColor(color); + + path = Geometry.clipPath(path, viewArea); + path = Geometry.filterPath(path, (p1, p2) -> + Perspective.localToMinimap(client, new LocalPoint((int)p1[0], (int)p1[1])) != null && + Perspective.localToMinimap(client, new LocalPoint((int)p2[0], (int)p2[1])) != null); + path = Geometry.transformPath(path, coords -> + { + Point point = Perspective.localToMinimap(client, new LocalPoint((int)coords[0], (int)coords[1])); + coords[0] = point.getX(); + coords[1] = point.getY(); + }); + + graphics.draw(path); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!config.showMinimapLines()) + { + return null; + } + + GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()]; + GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()]; + + if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null) + { + renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor())); + } + if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null) + { + renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor())); + } + + return null; + } +} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsOverlay.java new file mode 100644 index 0000000000..0f52222e8b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.geom.GeneralPath; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.geometry.Geometry; +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; + +public class ZoneIndicatorsOverlay extends Overlay +{ + private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; + + @Inject + private Client client; + + @Inject + private ZoneIndicatorsPlugin plugin; + + @Inject + private ZoneIndicatorsConfig config; + + @Inject + public ZoneIndicatorsOverlay() + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + setPriority(OverlayPriority.LOW); + } + + private Color getTransparentColorVersion(Color c) + { + return new Color(c.getRed(), c.getGreen(), c.getBlue(), 92); + } + + private void renderPath(Graphics2D graphics, GeneralPath path, Color color) + { + LocalPoint playerLp = client.getLocalPlayer().getLocalLocation(); + Rectangle viewArea = new Rectangle( + playerLp.getX() - MAX_LOCAL_DRAW_LENGTH, + playerLp.getY() - MAX_LOCAL_DRAW_LENGTH, + MAX_LOCAL_DRAW_LENGTH * 2, + MAX_LOCAL_DRAW_LENGTH * 2); + + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2)); + + path = Geometry.clipPath(path, viewArea); + path = Geometry.filterPath(path, (p1, p2) -> + Perspective.localToCanvas(client, new LocalPoint((int)p1[0], (int)p1[1]), client.getPlane()) != null && + Perspective.localToCanvas(client, new LocalPoint((int)p2[0], (int)p2[1]), client.getPlane()) != null); + path = Geometry.transformPath(path, coords -> + { + Point point = Perspective.localToCanvas(client, new LocalPoint((int)coords[0], (int)coords[1]), client.getPlane()); + coords[0] = point.getX(); + coords[1] = point.getY(); + }); + + graphics.draw(path); + } + + @Override + public Dimension render(Graphics2D graphics) + { + GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()]; + GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()]; + + if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null) + { + renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor())); + } + if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null) + { + renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor())); + } + + return null; + } +} \ No newline at end of file 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/zoneIndicators/ZoneIndicatorsPlugin.java new file mode 100644 index 0000000000..5f3397e900 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import net.runelite.client.eventbus.Subscribe; +import com.google.inject.Provides; +import java.awt.Rectangle; +import java.awt.geom.GeneralPath; +import java.util.Arrays; +import javax.inject.Inject; +import lombok.Getter; +import net.runelite.api.Client; +import net.runelite.api.Constants; +import net.runelite.api.GameState; +import net.runelite.api.ObjectComposition; +import net.runelite.api.Perspective; +import net.runelite.api.Tile; +import net.runelite.api.WallObject; +import net.runelite.api.WorldType; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.geometry.Geometry; +import net.runelite.client.callback.ClientThread; +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; + +@PluginDescriptor( + name = "!MultiLines", + description = "Show borders of multicombat and PvP safezones", + tags = {"multicombat", "lines", "pvp", "deadman", "safezones", "bogla"}, + enabledByDefault = false +) +public class ZoneIndicatorsPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private ZoneIndicatorsConfig config; + + @Inject + private ZoneIndicatorsOverlay overlay; + + @Inject + private ZoneIndicatorsMinimapOverlay minimapOverlay; + + @Inject + private OverlayManager overlayManager; + + @Getter + private GeneralPath[] multicombatPathToDisplay; + + @Getter + private GeneralPath[] pvpPathToDisplay; + + @Getter + private boolean inPvp; + + @Getter + private boolean inDeadman; + + private int currentPlane; + + @Provides + ZoneIndicatorsConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(ZoneIndicatorsConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + overlayManager.add(minimapOverlay); + + multicombatPathToDisplay = new GeneralPath[Constants.MAX_Z]; + pvpPathToDisplay = new GeneralPath[Constants.MAX_Z]; + + clientThread.invokeLater(() -> + { + if (client.getGameState() == GameState.LOGGED_IN) + { + findLinesInScene(); + } + }); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + overlayManager.remove(minimapOverlay); + + multicombatPathToDisplay = null; + pvpPathToDisplay = null; + } + + private void transformWorldToLocal(float[] coords) + { + LocalPoint lp = LocalPoint.fromWorld(client, (int)coords[0], (int)coords[1]); + coords[0] = lp.getX() - Perspective.LOCAL_TILE_SIZE / 2; + coords[1] = lp.getY() - Perspective.LOCAL_TILE_SIZE / 2; + } + + private boolean isOpenableAt(WorldPoint wp) + { + int sceneX = wp.getX() - client.getBaseX(); + int sceneY = wp.getY() - client.getBaseY(); + + Tile tile = client.getScene().getTiles()[wp.getPlane()][sceneX][sceneY]; + if (tile == null) + { + return false; + } + + WallObject wallObject = tile.getWallObject(); + if (wallObject == null) + { + return false; + } + + ObjectComposition objectComposition = client.getObjectDefinition(wallObject.getId()); + if (objectComposition == null) + { + return false; + } + + String[] actions = objectComposition.getActions(); + if (actions == null) + { + return false; + } + + return Arrays.stream(actions).anyMatch(x -> x != null && x.toLowerCase().equals("open")); + } + + private boolean collisionFilter(float[] p1, float[] p2) + { + int x1 = (int)p1[0]; + int y1 = (int)p1[1]; + int x2 = (int)p2[0]; + int y2 = (int)p2[1]; + + if (x1 > x2) + { + int temp = x1; + x1 = x2; + x2 = temp; + } + if (y1 > y2) + { + int temp = y1; + y1 = y2; + y2 = temp; + } + int dx = x2 - x1; + int dy = y2 - y1; + WorldArea wa1 = new WorldArea(new WorldPoint( + x1, y1, currentPlane), 1, 1); + WorldArea wa2 = new WorldArea(new WorldPoint( + x1 - dy, y1 - dx, currentPlane), 1, 1); + + if (isOpenableAt(wa1.toWorldPoint()) || isOpenableAt(wa2.toWorldPoint())) + { + // When there's something with the open option (e.g. a door) on the tile, + // we assume it can be opened and walked through afterwards. Without this + // check, the line for that tile wouldn't render with collision detection + // because the collision check isn't done if collision data changes. + return true; + } + + boolean b1 = wa1.canTravelInDirection(client, -dy, -dx); + boolean b2 = wa2.canTravelInDirection(client, dy, dx); + return b1 && b2; + } + + private void findLinesInScene() + { + inDeadman = client.getWorldType().stream().anyMatch(x -> + x == WorldType.DEADMAN || x == WorldType.SEASONAL_DEADMAN); + inPvp = client.getWorldType().stream().anyMatch(x -> + x == WorldType.PVP || x == WorldType.PVP_HIGH_RISK); + + Rectangle sceneRect = new Rectangle( + client.getBaseX() + 1, client.getBaseY() + 1, + Constants.SCENE_SIZE - 2, Constants.SCENE_SIZE - 2); + + // Generate lines for multicombat zones + if (config.multicombatZoneVisibility() == ZoneVisibility.HIDE) + { + for (int i = 0; i < multicombatPathToDisplay.length; i++) + { + multicombatPathToDisplay[i] = null; + } + } + else + { + for (int i = 0; i < multicombatPathToDisplay.length; i++) + { + currentPlane = i; + + GeneralPath lines = new GeneralPath(MapLocations.getMulticombat(sceneRect, i)); + lines = Geometry.clipPath(lines, sceneRect); + if (config.multicombatZoneVisibility() == ZoneVisibility.SHOW_IN_PVP && + !isInDeadman() && !isInPvp()) + { + lines = Geometry.clipPath(lines, MapLocations.getRoughWilderness(i)); + } + lines = Geometry.splitIntoSegments(lines, 1); + if (config.collisionDetection()) + { + lines = Geometry.filterPath(lines, this::collisionFilter); + } + lines = Geometry.transformPath(lines, this::transformWorldToLocal); + multicombatPathToDisplay[i] = lines; + } + } + + // Generate safezone lines for deadman/pvp worlds + for (int i = 0; i < pvpPathToDisplay.length; i++) + { + currentPlane = i; + + GeneralPath safeZonePath = null; + if (config.showDeadmanSafeZones() && isInDeadman()) + { + safeZonePath = new GeneralPath(MapLocations.getDeadmanSafeZones(sceneRect, i)); + } + else if (config.showPvpSafeZones() && isInPvp()) + { + safeZonePath = new GeneralPath(MapLocations.getPvpSafeZones(sceneRect, i)); + } + if (safeZonePath != null) + { + safeZonePath = Geometry.clipPath(safeZonePath, sceneRect); + safeZonePath = Geometry.splitIntoSegments(safeZonePath, 1); + if (config.collisionDetection()) + { + safeZonePath = Geometry.filterPath(safeZonePath, this::collisionFilter); + } + safeZonePath = Geometry.transformPath(safeZonePath, this::transformWorldToLocal); + } + pvpPathToDisplay[i] = safeZonePath; + } + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getKey().equals("collisionDetection") || + event.getKey().equals("multicombatZoneVisibility") || + event.getKey().equals("deadmanSafeZones") || + event.getKey().equals("pvpSafeZones")) + { + findLinesInScene(); + } + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOGGED_IN) + { + findLinesInScene(); + } + } +} 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/zoneIndicators/ZoneVisibility.java new file mode 100644 index 0000000000..9a457d9e50 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018, Woox + * 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.zoneIndicators; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum ZoneVisibility +{ + HIDE("Hide"), + SHOW_IN_PVP("Show in PvP"), + SHOW_EVERYWHERE("Show everywhere"); + + private final String visibility; + + @Override + public String toString() + { + return visibility; + } +} \ No newline at end of file From 447aaf6a2503e36a33f3439f419c90f9fe7d6e6f Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 18:59:13 +0100 Subject: [PATCH 23/75] additional plugins --- .../fkeyremapping/fKeyRemappingPlugin.java | 1 + .../groupitemlist/GroupItemListPlugin.java | 1 + .../inventorysetups/InventorySetup.java | 15 + .../InventorySetupBankOverlay.java | 113 +++++ .../inventorysetups/InventorySetupConfig.java | 84 ++++ .../inventorysetups/InventorySetupItem.java | 15 + .../inventorysetups/InventorySetupPlugin.java | 403 ++++++++++++++++++ .../ui/InventorySetupContainerPanel.java | 109 +++++ .../ui/InventorySetupEquipmentPanel.java | 91 ++++ .../ui/InventorySetupInventoryPanel.java | 78 ++++ .../ui/InventorySetupPluginPanel.java | 287 +++++++++++++ .../ui/InventorySetupSlot.java | 45 ++ .../LootingBagViewerOverlay.java | 123 ++++++ .../LootingBagViewerPlugin.java | 60 +++ .../raidsthieving/BatSolver/BatSolver.java | 193 +++++++++ .../BatSolver/ChestIdentifier.java | 261 ++++++++++++ .../raidsthieving/BatSolver/SolutionSet.java | 165 +++++++ .../BatSolver/ThievingRoomType.java | 61 +++ .../plugins/raidsthieving/ChestOverlay.java | 172 ++++++++ .../plugins/raidsthieving/InstancePoint.java | 98 +++++ .../raidsthieving/RaidsThievingConfig.java | 67 +++ .../raidsthieving/RaidsThievingConstants.java | 35 ++ .../raidsthieving/RaidsThievingPlugin.java | 270 ++++++++++++ .../plugins/raidsthieving/ThievingChest.java | 78 ++++ .../rememberclan/RememberClanPlugin.java | 1 + .../plugins/safespot/SafeSpotConfig.java | 25 ++ .../plugins/safespot/SafeSpotOverlay.java | 40 ++ .../plugins/safespot/SafeSpotPlugin.java | 135 ++++++ .../plugins/stronghold/StrongholdPlugin.java | 1 + .../warindicators/WarIndicatorPlugin.java | 1 + .../zoneIndicators/ZoneIndicatorsPlugin.java | 1 + 31 files changed, 3029 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java 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 index 78199bfcc5..050d452811 100644 --- 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 @@ -16,6 +16,7 @@ import net.runelite.client.plugins.PluginDescriptor; name = "fKeyRemapping", description = "Used for interface hotkeys", tags = {"hotkey", "remapping"}, + type = "utility", enabledByDefault = true ) public class fKeyRemappingPlugin extends Plugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java index a01716d388..99d9b14831 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java @@ -17,6 +17,7 @@ import java.util.LinkedHashMap; name = "!Group Item List", description = "Group the right click menu of a pile of items.", tags = {"ground", "compress", "pile", "group"}, + type = "utility", enabledByDefault = false ) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java new file mode 100644 index 0000000000..043d22a30c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java @@ -0,0 +1,15 @@ +package net.runelite.client.plugins.inventorysetups; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.ArrayList; + +@AllArgsConstructor +public class InventorySetup +{ + @Getter + private ArrayList inventory; + @Getter + private ArrayList equipment; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java new file mode 100644 index 0000000000..34ba341fc7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java @@ -0,0 +1,113 @@ +package net.runelite.client.plugins.inventorysetups; + +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.api.Query; +import net.runelite.api.SpritePixels; +import net.runelite.api.queries.BankItemQuery; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetItem; +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.util.QueryRunner; + +import javax.inject.Inject; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.util.Arrays; +import java.util.Objects; + +@Slf4j +public class InventorySetupBankOverlay extends Overlay +{ + private final Client client; + private final QueryRunner queryRunner; + private final InventorySetupPlugin plugin; + private final InventorySetupConfig config; + + @Inject + public InventorySetupBankOverlay(Client client, QueryRunner queryRunner, InventorySetupPlugin plugin, InventorySetupConfig config) + { + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.LOW); + setLayer(OverlayLayer.ABOVE_WIDGETS); + this.client = client; + this.queryRunner = queryRunner; + this.plugin = plugin; + this.config = config; + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (config.getBankHighlight()) + { + int[] ids = plugin.getCurrentInventorySetupIds(); + if (ids == null) + { + return null; + } + ids = Arrays.stream(ids) + .filter(Objects::nonNull) + .filter(id -> id != -1) + .toArray(); + final Query query = new BankItemQuery().idEquals(ids); + final WidgetItem[] widgetItems = queryRunner.runQuery(query); + final Widget bankContainer = client.getWidget(WidgetInfo.BANK_CONTAINER); + for (final WidgetItem item : widgetItems) + { + Point canvasLocation = item.getCanvasLocation(); + Rectangle canvasBounds = item.getCanvasBounds(); + Point windowLocation = bankContainer.getCanvasLocation(); + + if (canvasLocation == null || windowLocation == null) + { + return null; + } + + if (!(canvasLocation.getY() + 60 >= windowLocation.getY() + bankContainer.getHeight()) && !(canvasLocation.getY() + canvasBounds.getHeight() <= windowLocation.getY() + 90)) + { + final Color color = config.getBankHighlightColor(); + + if (color != null) + { + final BufferedImage outline = loadItemOutline(item.getId(), item.getQuantity(), color); + graphics.drawImage(outline, item.getCanvasLocation().getX() + 1, item.getCanvasLocation().getY() + 1, null); + if (item.getQuantity() > 1) + { + drawQuantity(graphics, item, Color.YELLOW); + } + else if (item.getQuantity() == 0) + { + drawQuantity(graphics, item, Color.YELLOW.darker()); + } + } + } + } + } + return null; + } + + private void drawQuantity(Graphics2D graphics, WidgetItem item, Color darker) + { + graphics.setColor(Color.BLACK); + graphics.drawString(String.valueOf(item.getQuantity()), item.getCanvasLocation().getX() + 2, item.getCanvasLocation().getY() + 11); + graphics.setColor(darker); + graphics.setFont(FontManager.getRunescapeSmallFont()); + graphics.drawString(String.valueOf(item.getQuantity()), item.getCanvasLocation().getX() + 1, item.getCanvasLocation().getY() + 10); + } + + private BufferedImage loadItemOutline(final int itemId, final int itemQuantity, final Color outlineColor) + { + final SpritePixels itemSprite = client.createItemSprite(itemId, itemQuantity, 2, 0, 0, true, 710); + return itemSprite.toBufferedOutline(outlineColor); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java new file mode 100644 index 0000000000..edcc47cd9c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java @@ -0,0 +1,84 @@ +package net.runelite.client.plugins.inventorysetups; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +import java.awt.Color; + +@ConfigGroup("inventorysetups") +public interface InventorySetupConfig extends Config +{ + @ConfigItem( + keyName = "highlightDifferences", + name = "Highlight Differences", + description = "Highlight slots that don't match the selected setup", + position = 0 + ) + + default boolean getHighlightDifferences() + { + return false; + } + + @ConfigItem( + keyName = "highlightDifferenceColor", + name = "Highlight Color", + description = "The color used to highlight differences between setups", + position = 1 + ) + + default Color getHighlightColor() + { + return Color.RED; + } + + @ConfigItem( + keyName = "stackDifference", + name = "Stack Difference", + description = "Differences between setups will be highlighted if the stack size is different", + position = 2 + ) + + default boolean getStackDifference() + { + return false; + } + + @ConfigItem( + keyName = "variationDifference", + name = "Variation Difference", + description = "Variations of items (E.g., charged jewellery) will be counted as different", + position = 2 + ) + + default boolean getVariationDifference() + { + return false; + } + + @ConfigItem( + keyName = "bankHighlight", + name = "Bank Highlight", + description = "Highlight setup items in bank", + position = 4 + ) + + default boolean getBankHighlight() + { + return false; + } + + @ConfigItem( + keyName = "bankHighlightColor", + name = "Bank Highlight Color", + description = "The color used to highlight setup items in bank", + position = 5 + ) + + default Color getBankHighlightColor() + { + return Color.RED; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java new file mode 100644 index 0000000000..c1af4e68fd --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java @@ -0,0 +1,15 @@ +package net.runelite.client.plugins.inventorysetups; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public class InventorySetupItem +{ + @Getter + private final int id; + @Getter + private final String name; + @Getter + private final int quantity; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java new file mode 100644 index 0000000000..8b9c632498 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java @@ -0,0 +1,403 @@ +package net.runelite.client.plugins.inventorysetups; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.google.inject.Provides; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +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.ConfigChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.ItemContainerChanged; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; +import net.runelite.client.game.ItemVariationMapping; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.inventorysetups.ui.InventorySetupPluginPanel; +import net.runelite.client.ui.ClientToolbar; +import net.runelite.client.ui.NavigationButton; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.ImageUtil; + +import javax.inject.Inject; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import java.awt.image.BufferedImage; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; + +@PluginDescriptor( + name = "Inventory Setups", + description = "Save inventory setups", + tags = { "items", "inventory", "setups"}, + type = "utility", + enabledByDefault = false +) + +@Slf4j +public class InventorySetupPlugin extends Plugin +{ + + private static final String CONFIG_GROUP = "inventorysetups"; + private static final String CONFIG_KEY = "setups"; + private static final int NUM_INVENTORY_ITEMS = 28; + private static final int NUM_EQUIPMENT_ITEMS = 14; + + @Inject + private Client client; + + @Inject + private ItemManager itemManager; + + @Inject + private InventorySetupBankOverlay overlay; + + @Inject + private ClientToolbar clientToolbar; + + @Inject + private InventorySetupConfig config; + + @Inject + private OverlayManager overlayManager; + + @Inject + private ClientThread clientThread; + + @Inject + private ConfigManager configManager; + + private InventorySetupPluginPanel panel; + + private HashMap inventorySetups; + + private NavigationButton navButton; + + private boolean highlightDifference; + + @Override + public void startUp() + { + overlayManager.add(overlay); + + panel = new InventorySetupPluginPanel(this, itemManager); + + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "inventorysetups_icon.png"); + + navButton = NavigationButton.builder() + .tooltip("Inventory Setups") + .icon(icon) + .priority(9) + .panel(panel) + .build(); + + clientToolbar.addNavigation(navButton); + + // load all the inventory setups from the config file + clientThread.invokeLater(() -> + { + if (client.getGameState() != GameState.LOGIN_SCREEN) + { + return false; + } + + loadConfig(); + panel.showNoSetupsPanel(); + return true; + }); + + } + + public void addInventorySetup() + { + final String name = JOptionPane.showInputDialog(panel, + "Enter the name of this setup.", + "Add New Setup", + JOptionPane.PLAIN_MESSAGE); + + // cancel button was clicked + if (name == null) + { + return; + } + + if (name.isEmpty()) + { + JOptionPane.showMessageDialog(panel, + "Invalid Setup Name", + "Names must not be empty.", + JOptionPane.PLAIN_MESSAGE); + return; + } + + if (inventorySetups.containsKey(name)) + { + String builder = "The setup " + name + " already exists. " + + "Would you like to replace it with the current setup?"; + int confirm = JOptionPane.showConfirmDialog(panel, + builder, + "Warning", + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.PLAIN_MESSAGE); + + if (confirm == JOptionPane.CANCEL_OPTION) + { + return; + } + + // delete the old setup, no need to ask for confirmation + // because the user confirmed above + removeInventorySetup(name, false); + } + + clientThread.invoke(() -> + { + ArrayList inv = getNormalizedContainer(InventoryID.INVENTORY); + ArrayList eqp = getNormalizedContainer(InventoryID.EQUIPMENT); + + final InventorySetup invSetup = new InventorySetup(inv, eqp); + SwingUtilities.invokeLater(() -> + { + inventorySetups.put(name, invSetup); + panel.addInventorySetup(name); + panel.setCurrentInventorySetup(name); + + updateConfig(); + }); + }); + } + + public void removeInventorySetup(final String name, boolean askForConfirmation) + { + if (inventorySetups.containsKey(name)) + { + int confirm = JOptionPane.YES_OPTION; + + if (askForConfirmation) + { + confirm = JOptionPane.showConfirmDialog(panel, + "Are you sure you want to remove this setup?", + "Warning", + JOptionPane.YES_NO_OPTION, + JOptionPane.PLAIN_MESSAGE); + } + + if (confirm == JOptionPane.YES_OPTION) + { + inventorySetups.remove(name); + panel.removeInventorySetup(name); + } + + updateConfig(); + } + } + + public final InventorySetup getInventorySetup(final String name) + { + return inventorySetups.get(name); + } + + @Provides + InventorySetupConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(InventorySetupConfig.class); + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals(CONFIG_GROUP)) + { + // only allow highlighting if the config is enabled and the player is logged in + highlightDifference = config.getHighlightDifferences() && client.getGameState() == GameState.LOGGED_IN; + final String setupName = panel.getSelectedInventorySetup(); + if (highlightDifference && !setupName.isEmpty()) + { + panel.setCurrentInventorySetup(setupName); + } + } + } + + private void updateConfig() + { + if (inventorySetups.isEmpty()) + { + configManager.unsetConfiguration(CONFIG_GROUP, CONFIG_KEY); + return; + } + + final Gson gson = new Gson(); + final String json = gson.toJson(inventorySetups); + configManager.setConfiguration(CONFIG_GROUP, CONFIG_KEY, json); + } + + private void loadConfig() + { + // serialize the internal data structure from the json in the configuration + final String json = configManager.getConfiguration(CONFIG_GROUP, CONFIG_KEY); + if (json == null || json.isEmpty()) + { + inventorySetups = new HashMap<>(); + } + else + { + // TODO add last resort?, serialize exception just make empty map + final Gson gson = new Gson(); + Type type = new TypeToken>() + { + + }.getType(); + inventorySetups = gson.fromJson(json, type); + } + + for (final String key : inventorySetups.keySet()) + { + panel.addInventorySetup(key); + } + + highlightDifference = false; + } + + @Subscribe + public void onItemContainerChanged(ItemContainerChanged event) + { + + if (!highlightDifference || client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + // empty entry, no need to compare anything + final String selectedInventorySetup = panel.getSelectedInventorySetup(); + if (selectedInventorySetup.isEmpty()) + { + return; + } + + // check to see that the container is the equipment or inventory + ItemContainer container = event.getItemContainer(); + + if (container == client.getItemContainer(InventoryID.INVENTORY)) + { + ArrayList normContainer = getNormalizedContainer(InventoryID.INVENTORY); + final InventorySetup setup = inventorySetups.get(selectedInventorySetup); + panel.highlightDifferences(normContainer, setup, InventoryID.INVENTORY); + } + else if (container == client.getItemContainer(InventoryID.EQUIPMENT)) + { + ArrayList normContainer = getNormalizedContainer(InventoryID.EQUIPMENT); + final InventorySetup setup = inventorySetups.get(selectedInventorySetup); + panel.highlightDifferences(normContainer, setup, InventoryID.EQUIPMENT); + } + + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + switch (event.getGameState()) + { + // set the highlighting off if login screen shows up + case LOGIN_SCREEN: + highlightDifference = false; + final String setupName = panel.getSelectedInventorySetup(); + if (!setupName.isEmpty()) + { + panel.setCurrentInventorySetup(setupName); + } + break; + + // set highlighting + case LOGGED_IN: + highlightDifference = config.getHighlightDifferences(); + break; + } + } + + public ArrayList getNormalizedContainer(final InventoryID id) + { + assert id == InventoryID.INVENTORY || id == InventoryID.EQUIPMENT : "invalid inventory ID"; + + final ItemContainer container = client.getItemContainer(id); + + ArrayList newContainer = new ArrayList<>(); + + Item[] items = null; + if (container != null) + { + items = container.getItems(); + } + + int size = id == InventoryID.INVENTORY ? NUM_INVENTORY_ITEMS : NUM_EQUIPMENT_ITEMS; + + for (int i = 0; i < size; i++) + { + if (items == null || i >= items.length) + { + newContainer.add(new InventorySetupItem(-1, "", 0)); + } + else + { + final Item item = items[i]; + String itemName = ""; + if (client.isClientThread()) + { + itemName = itemManager.getItemComposition(item.getId()).getName(); + } + newContainer.add(new InventorySetupItem(item.getId(), itemName, item.getQuantity())); + } + } + + return newContainer; + } + + public final InventorySetupConfig getConfig() + { + return config; + } + + public boolean getHighlightDifference() + { + return highlightDifference; + } + + @Override + public void shutDown() + { + overlayManager.remove(overlay); + clientToolbar.removeNavigation(navButton); + } + + final int[] getCurrentInventorySetupIds() + { + InventorySetup setup = inventorySetups.get(panel.getSelectedInventorySetup()); + if (setup == null) + { + return null; + } + ArrayList items = new ArrayList<>(); + items.addAll(setup.getEquipment()); + items.addAll(setup.getInventory()); + ArrayList itemIds = new ArrayList<>(); + for (InventorySetupItem item : items) + { + int id = item.getId(); + ItemComposition itemComposition = itemManager.getItemComposition(id); + if (id > 0) + { + itemIds.add(ItemVariationMapping.map(id)); + itemIds.add(itemComposition.getPlaceholderId()); + } + + } + return itemIds.stream().mapToInt(i -> i).toArray(); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java new file mode 100644 index 0000000000..d5eda3697f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java @@ -0,0 +1,109 @@ +package net.runelite.client.plugins.inventorysetups.ui; + +import net.runelite.client.game.AsyncBufferedImage; +import net.runelite.client.game.ItemManager; +import net.runelite.client.game.ItemVariationMapping; +import net.runelite.client.plugins.inventorysetups.InventorySetupConfig; +import net.runelite.client.plugins.inventorysetups.InventorySetupItem; +import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; +import net.runelite.client.ui.ColorScheme; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.util.ArrayList; + +public abstract class InventorySetupContainerPanel extends JPanel +{ + + protected ItemManager itemManager; + + private final InventorySetupPlugin plugin; + + InventorySetupContainerPanel(final ItemManager itemManager, final InventorySetupPlugin plugin, String captionText) + { + this.itemManager = itemManager; + this.plugin = plugin; + JPanel containerPanel = new JPanel(); + + final JPanel containerSlotsPanel = new JPanel(); + + setupContainerPanel(containerSlotsPanel); + + // caption + final JLabel caption = new JLabel(captionText); + caption.setHorizontalAlignment(JLabel.CENTER); + caption.setVerticalAlignment(JLabel.CENTER); + + // panel that holds the caption and any other graphics + final JPanel captionPanel = new JPanel(); + captionPanel.add(caption); + + containerPanel.setLayout(new BorderLayout()); + containerPanel.add(captionPanel, BorderLayout.NORTH); + containerPanel.add(containerSlotsPanel, BorderLayout.CENTER); + + add(containerPanel); + } + + void setContainerSlot(int index, + final InventorySetupSlot containerSlot, + final ArrayList items) + { + if (index >= items.size() || items.get(index).getId() == -1) + { + containerSlot.setImageLabel(null, null); + return; + } + + int itemId = items.get(index).getId(); + int quantity = items.get(index).getQuantity(); + final String itemName = items.get(index).getName(); + AsyncBufferedImage itemImg = itemManager.getImage(itemId, quantity, quantity > 1); + String toolTip = itemName; + if (quantity > 1) + { + toolTip += " (" + quantity + ")"; + } + containerSlot.setImageLabel(toolTip, itemImg); + } + + void highlightDifferentSlotColor(InventorySetupItem savedItem, + InventorySetupItem currItem, + final InventorySetupSlot containerSlot) + { + // important note: do not use item names for comparisons + // they are all empty to avoid clientThread usage when highlighting + + final InventorySetupConfig config = plugin.getConfig(); + final Color highlightColor = config.getHighlightColor(); + + if (config.getStackDifference() && currItem.getQuantity() != savedItem.getQuantity()) + { + containerSlot.setBackground(highlightColor); + return; + } + + int currId = currItem.getId(); + int checkId = savedItem.getId(); + + if (!config.getVariationDifference()) + { + currId = ItemVariationMapping.map(currId); + checkId = ItemVariationMapping.map(checkId); + } + + if (currId != checkId) + { + containerSlot.setBackground(highlightColor); + return; + } + + // set the color back to the original, because they match + containerSlot.setBackground(ColorScheme.DARKER_GRAY_COLOR); + } + + abstract public void setupContainerPanel(final JPanel containerSlotsPanel); + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java new file mode 100644 index 0000000000..7e0fecfa2b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java @@ -0,0 +1,91 @@ +package net.runelite.client.plugins.inventorysetups.ui; + +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.inventorysetups.InventorySetup; +import net.runelite.client.plugins.inventorysetups.InventorySetupItem; +import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; +import net.runelite.client.ui.ColorScheme; + +import javax.swing.JPanel; +import java.awt.GridLayout; +import java.util.ArrayList; +import java.util.HashMap; + +public class InventorySetupEquipmentPanel extends InventorySetupContainerPanel +{ + private HashMap equipmentSlots; + + InventorySetupEquipmentPanel(final ItemManager itemManager, final InventorySetupPlugin plugin) + { + super(itemManager, plugin, "Equipment"); + } + + @Override + public void setupContainerPanel(final JPanel containerSlotsPanel) + { + this.equipmentSlots = new HashMap<>(); + for (EquipmentInventorySlot slot : EquipmentInventorySlot.values()) + { + equipmentSlots.put(slot, new InventorySetupSlot(ColorScheme.DARKER_GRAY_COLOR)); + } + + final GridLayout gridLayout = new GridLayout(5, 3, 1, 1); + containerSlotsPanel.setLayout(gridLayout); + + // add the grid layouts, including invisible ones + containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.HEAD)); + containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.CAPE)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.AMULET)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.AMMO)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.WEAPON)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.BODY)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.SHIELD)); + containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.LEGS)); + containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.GLOVES)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.BOOTS)); + containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.RING)); + + } + + void setEquipmentSetupSlots(final InventorySetup setup) + { + final ArrayList equipment = setup.getEquipment(); + + for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values()) + { + int i = slot.getSlotIdx(); + super.setContainerSlot(i, equipmentSlots.get(slot), equipment); + } + + validate(); + repaint(); + + } + + void highlightDifferences(final ArrayList currEquipment, final InventorySetup inventorySetup) + { + final ArrayList equipToCheck = inventorySetup.getEquipment(); + + assert currEquipment.size() == equipToCheck.size() : "size mismatch"; + + for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values()) + { + + int slotIdx = slot.getSlotIdx(); + super.highlightDifferentSlotColor(equipToCheck.get(slotIdx), currEquipment.get(slotIdx), equipmentSlots.get(slot)); + } + } + + void resetEquipmentSlotsColor() + { + for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values()) + { + equipmentSlots.get(slot).setBackground(ColorScheme.DARKER_GRAY_COLOR); + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java new file mode 100644 index 0000000000..136f4603ea --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java @@ -0,0 +1,78 @@ +package net.runelite.client.plugins.inventorysetups.ui; + +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.inventorysetups.InventorySetup; +import net.runelite.client.plugins.inventorysetups.InventorySetupItem; +import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; +import net.runelite.client.ui.ColorScheme; + +import javax.swing.JPanel; +import java.awt.GridLayout; +import java.util.ArrayList; + +public class InventorySetupInventoryPanel extends InventorySetupContainerPanel +{ + + private static final int ITEMS_PER_ROW = 4; + private static final int NUM_INVENTORY_ITEMS = 28; + + private ArrayList inventorySlots; + + InventorySetupInventoryPanel(final ItemManager itemManager, final InventorySetupPlugin plugin) + { + super(itemManager, plugin, "Inventory"); + } + + + @Override + public void setupContainerPanel(final JPanel containerSlotsPanel) + { + this.inventorySlots = new ArrayList<>(); + for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) + { + inventorySlots.add(new InventorySetupSlot(ColorScheme.DARKER_GRAY_COLOR)); + } + + int numRows = (NUM_INVENTORY_ITEMS + ITEMS_PER_ROW - 1) / ITEMS_PER_ROW; + containerSlotsPanel.setLayout(new GridLayout(numRows, ITEMS_PER_ROW, 1, 1)); + for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) + { + containerSlotsPanel.add(inventorySlots.get(i)); + } + } + + void setInventorySetupSlots(final InventorySetup setup) + { + ArrayList inventory = setup.getInventory(); + + for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) + { + super.setContainerSlot(i, inventorySlots.get(i), inventory); + } + + validate(); + repaint(); + + } + + void highlightDifferentSlots(final ArrayList currInventory, final InventorySetup inventorySetup) + { + + final ArrayList inventoryToCheck = inventorySetup.getInventory(); + + assert currInventory.size() == inventoryToCheck.size() : "size mismatch"; + + for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) + { + super.highlightDifferentSlotColor(inventoryToCheck.get(i), currInventory.get(i), inventorySlots.get(i)); + } + } + + void resetInventorySlotsColor() + { + for (InventorySetupSlot inventorySlot : inventorySlots) + { + inventorySlot.setBackground(ColorScheme.DARKER_GRAY_COLOR); + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java new file mode 100644 index 0000000000..b1b88a02c7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java @@ -0,0 +1,287 @@ +package net.runelite.client.plugins.inventorysetups.ui; + +import net.runelite.api.InventoryID; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.inventorysetups.InventorySetup; +import net.runelite.client.plugins.inventorysetups.InventorySetupItem; +import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; +import net.runelite.client.ui.PluginPanel; +import net.runelite.client.ui.components.PluginErrorPanel; +import net.runelite.client.util.ImageUtil; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.border.EmptyBorder; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ItemEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.util.ArrayList; + +public class InventorySetupPluginPanel extends PluginPanel +{ + + private static ImageIcon ADD_ICON; + private static ImageIcon ADD_HOVER_ICON; + private static ImageIcon REMOVE_ICON; + private static ImageIcon REMOVE_HOVER_ICON; + + private final JPanel noSetupsPanel; + private final JPanel invEqPanel; + + private final InventorySetupInventoryPanel invPanel; + private final InventorySetupEquipmentPanel eqpPanel; + + private final JComboBox setupComboBox; + + private final JLabel removeMarker; + + private final InventorySetupPlugin plugin; + + static + { + final BufferedImage addIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "add_icon.png"); + ADD_ICON = new ImageIcon(addIcon); + ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f)); + + final BufferedImage removeIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "remove_icon.png"); + REMOVE_ICON = new ImageIcon(removeIcon); + REMOVE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(removeIcon, 0.53f)); + } + + public InventorySetupPluginPanel(final InventorySetupPlugin plugin, final ItemManager itemManager) + { + super(false); + this.plugin = plugin; + this.removeMarker = new JLabel(REMOVE_ICON); + this.invPanel = new InventorySetupInventoryPanel(itemManager, plugin); + this.eqpPanel = new InventorySetupEquipmentPanel(itemManager, plugin); + this.noSetupsPanel = new JPanel(); + this.invEqPanel = new JPanel(); + this.setupComboBox = new JComboBox<>(); + + // setup the title + final JLabel addMarker = new JLabel(ADD_ICON); + final JLabel title = new JLabel(); + title.setText("Inventory Setups"); + title.setForeground(Color.WHITE); + + // setup the add marker (+ sign in the top right) + addMarker.setToolTipText("Add a new inventory setup"); + addMarker.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + plugin.addInventorySetup(); + } + + @Override + public void mouseEntered(MouseEvent e) + { + addMarker.setIcon(ADD_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent e) + { + addMarker.setIcon(ADD_ICON); + } + }); + + // setup the remove marker (X sign in the top right) + removeMarker.setToolTipText("Remove the current inventory setup"); + removeMarker.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + final String name = (String)setupComboBox.getSelectedItem(); + plugin.removeInventorySetup(name, true); + } + + @Override + public void mouseEntered(MouseEvent e) + { + if (removeMarker.isEnabled()) + { + removeMarker.setIcon(REMOVE_HOVER_ICON); + } + } + + @Override + public void mouseExited(MouseEvent e) + { + removeMarker.setIcon(REMOVE_ICON); + } + }); + + // setup the combo box for selection switching + // add empty to indicate the empty position + setupComboBox.addItem(""); + setupComboBox.setSelectedIndex(0); + setupComboBox.addItemListener(e -> + { + if (e.getStateChange() == ItemEvent.SELECTED) + { + String selection = (String)e.getItem(); + setCurrentInventorySetup(selection); + } + }); + + // the panel on the top right that holds the add and delete buttons + final JPanel markersPanel = new JPanel(); + markersPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 0)); + markersPanel.add(removeMarker); + markersPanel.add(addMarker); + + // the top panel that has the title and the buttons + final JPanel titleAndMarkersPanel = new JPanel(); + titleAndMarkersPanel.setLayout(new BorderLayout()); + titleAndMarkersPanel.add(title, BorderLayout.WEST); + titleAndMarkersPanel.add(markersPanel, BorderLayout.EAST); + + // the panel that stays at the top and doesn't scroll + // contains the title, buttons, and the combo box + final JPanel northAnchoredPanel = new JPanel(); + northAnchoredPanel.setLayout(new BoxLayout(northAnchoredPanel, BoxLayout.Y_AXIS)); + northAnchoredPanel.setBorder(new EmptyBorder(0, 0, 10, 0)); + northAnchoredPanel.add(titleAndMarkersPanel); + northAnchoredPanel.add(Box.createRigidArea(new Dimension(0, 10))); + northAnchoredPanel.add(setupComboBox); + + // the panel that holds the inventory and equipment panels + final BoxLayout invEqLayout = new BoxLayout(invEqPanel, BoxLayout.Y_AXIS); + invEqPanel.setLayout(invEqLayout); + invEqPanel.add(invPanel); + invEqPanel.add(Box.createRigidArea(new Dimension(0, 10))); + invEqPanel.add(eqpPanel); + + // setup the error panel. It's wrapped around a normal panel + // so it doesn't stretch to fill the parent panel + final PluginErrorPanel errorPanel = new PluginErrorPanel(); + errorPanel.setContent("Inventory Setups", "Select or create an inventory setup."); + noSetupsPanel.add(errorPanel); + + // the panel that holds the inventory panels, and the error panel + final JPanel contentPanel = new JPanel(); + final BoxLayout contentLayout = new BoxLayout(contentPanel, BoxLayout.Y_AXIS); + contentPanel.setLayout(contentLayout); + contentPanel.add(invEqPanel); + contentPanel.add(noSetupsPanel); + + // wrapper for the main content panel to keep it from stretching + final JPanel contentWrapper = new JPanel(new BorderLayout()); + contentWrapper.add(Box.createGlue(), BorderLayout.CENTER); + contentWrapper.add(contentPanel, BorderLayout.NORTH); + final JScrollPane contentWrapperPane = new JScrollPane(contentWrapper); + contentWrapperPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + setLayout(new BorderLayout()); + setBorder(new EmptyBorder(10, 10, 10, 10)); + add(northAnchoredPanel, BorderLayout.NORTH); + add(contentWrapperPane, BorderLayout.CENTER); + + // show the no setups panel on startup + showNoSetupsPanel(); + + } + + public void showNoSetupsPanel() + { + setupComboBox.setSelectedIndex(0); + removeMarker.setEnabled(false); + noSetupsPanel.setVisible(true); + invEqPanel.setVisible(false); + } + + private void showHasSetupPanel(final String name) + { + setupComboBox.setSelectedItem(name); + removeMarker.setEnabled(true); + noSetupsPanel.setVisible(false); + invEqPanel.setVisible(true); + } + + public void setCurrentInventorySetup(final String name) + { + if (name.isEmpty()) + { + showNoSetupsPanel(); + return; + } + + showHasSetupPanel(name); + + final InventorySetup inventorySetup = plugin.getInventorySetup(name); + + invPanel.setInventorySetupSlots(inventorySetup); + eqpPanel.setEquipmentSetupSlots(inventorySetup); + + if (plugin.getHighlightDifference()) + { + final ArrayList normInv = plugin.getNormalizedContainer(InventoryID.INVENTORY); + final ArrayList normEqp = plugin.getNormalizedContainer(InventoryID.EQUIPMENT); + + highlightDifferences(normInv, inventorySetup, InventoryID.INVENTORY); + highlightDifferences(normEqp, inventorySetup, InventoryID.EQUIPMENT); + } + else + { + invPanel.resetInventorySlotsColor(); + eqpPanel.resetEquipmentSlotsColor(); + } + + validate(); + repaint(); + } + + public void addInventorySetup(final String name) + { + setupComboBox.addItem(name); + } + + public void removeInventorySetup(final String name) + { + setupComboBox.removeItem(name); + showNoSetupsPanel(); + + invPanel.resetInventorySlotsColor(); + eqpPanel.resetEquipmentSlotsColor(); + + validate(); + repaint(); + } + + public void highlightDifferences(final ArrayList container, + final InventorySetup setupToCheck, + final InventoryID type) + { + switch (type) + { + case INVENTORY: + invPanel.highlightDifferentSlots(container, setupToCheck); + break; + + case EQUIPMENT: + eqpPanel.highlightDifferences(container, setupToCheck); + break; + } + } + + public final String getSelectedInventorySetup() + { + return (String)setupComboBox.getSelectedItem(); + } + + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java new file mode 100644 index 0000000000..13bbbaef14 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java @@ -0,0 +1,45 @@ +package net.runelite.client.plugins.inventorysetups.ui; + +import net.runelite.client.game.AsyncBufferedImage; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.Color; +import java.awt.Dimension; + +public class InventorySetupSlot extends JPanel +{ + + private final JLabel imageLabel; + + public InventorySetupSlot(Color color) + { + imageLabel = new JLabel(); + imageLabel.setVerticalAlignment(SwingConstants.CENTER); + setPreferredSize(new Dimension(46, 42)); + setBackground(color); + add(imageLabel); + + } + + public void setImageLabel(String toolTip, AsyncBufferedImage itemImage) + { + if (itemImage == null || toolTip == null) + { + imageLabel.setToolTipText(""); + imageLabel.setIcon(null); + imageLabel.revalidate(); + return; + } + + imageLabel.setToolTipText(toolTip); + itemImage.addTo(imageLabel); + + validate(); + repaint(); + } + + + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java new file mode 100644 index 0000000000..85a07780de --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018 AWPH-I + * 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.lootingbagviewer; + +import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +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.ImageComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +import javax.inject.Inject; +import java.awt.*; +import java.awt.image.BufferedImage; + +class LootingBagViewerOverlay extends Overlay +{ + private static final int INVENTORY_SIZE = 28; + private static final int PLACEHOLDER_WIDTH = 36; + private static final int PLACEHOLDER_HEIGHT = 32; + private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(new BufferedImage(PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR)); + + private final Client client; + private final ItemManager itemManager; + + private final PanelComponent panelComponent = new PanelComponent(); + + private ItemContainer itemContainer; + private Item[] items; + + @Inject + private LootingBagViewerOverlay(Client client, ItemManager itemManager) + { + setPosition(OverlayPosition.BOTTOM_RIGHT); + panelComponent.setWrapping(4); + panelComponent.setGap(new Point(6, 4)); + panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + this.itemManager = itemManager; + this.client = client; + + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (itemContainer == null) + { + if(client.getItemContainer(InventoryID.LOOTING_BAG) != null) { + itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); + items = itemContainer.getItems(); + } + return null; + } + else if(itemContainer != null && client.getItemContainer(InventoryID.LOOTING_BAG) != null) + { + itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); + Item[] tempItems = itemContainer.getItems(); + + for(int i = 0; i < items.length; i++) + { + if(!items[i].equals(tempItems[i])) + { + items = tempItems; + } + } + } + + panelComponent.getChildren().clear(); + + for (int i = 0; i < INVENTORY_SIZE; i++) + { + if (i < items.length) + { + final Item item = items[i]; + if (item.getQuantity() > 0) + { + final BufferedImage image = getImage(item); + if (image != null) + { + panelComponent.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); + } + + return panelComponent.render(graphics); + } + + private BufferedImage getImage(Item item) + { + return itemManager.getImage(item.getId(), item.getQuantity(), item.getQuantity() > 1); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java new file mode 100644 index 0000000000..5729c69993 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018 AWPH-I + * 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.lootingbagviewer; + +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +import javax.inject.Inject; + +@PluginDescriptor( + name = "PvP Looting Bag Viewer", + description = "Add an overlay showing the contents of your looting bag", + tags = {"alternate", "items", "overlay", "second"}, + type = "utility", + enabledByDefault = false +) +public class LootingBagViewerPlugin extends Plugin +{ + @Inject + private net.runelite.client.plugins.lootingbagviewer.LootingBagViewerOverlay overlay; + + @Inject + private OverlayManager overlayManager; + + @Override + public void startUp() + { + overlayManager.add(overlay); + } + + @Override + public void shutDown() + { + overlayManager.remove(overlay); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java new file mode 100644 index 0000000000..ebbad81a54 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving.BatSolver; + +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.TreeSet; +import java.util.List; +import java.util.ArrayList; +import static net.runelite.client.plugins.raidsthieving.BatSolver.SolutionSet.SOLUTION_SETS; + +public class BatSolver +{ + private Map numberOfSolutionsWithPoison; + private final SolutionSet solution; + + private final HashSet grubsChests; + + public BatSolver(ThievingRoomType roomType) + { + solution = new SolutionSet(roomType); + grubsChests = new HashSet<>(); + } + + public void addEmptyChest(int chestId) + { + // When a new empty chest is found, add it to the current solution set + solution.addEmptyChest(chestId); + calculateChanceOfPoison(); + } + + public void addGrubsChest(int chestId) + { + // When a chest with grubs is found, keep track of it to invalidate solutions + grubsChests.add(chestId); + calculateChanceOfPoison(); + } + + public TreeSet matchSolutions() + { + TreeSet possibleEmptyChests = new TreeSet<>(); + for (SolutionSet knownSolution : SolutionSet.SOLUTION_SETS) + { + if (knownSolution.getType() == solution.getType() && matchSolution(knownSolution)) + { + possibleEmptyChests.addAll(knownSolution.getEmptyChests()); + } + } + + return possibleEmptyChests; + } + + private boolean matchSolution(SolutionSet testSolution) + { + for (Integer grubsChest : grubsChests) + { + if (testSolution.containsChest(grubsChest)) + { + // If one of the chests is known to have grubs, it cannot be a solution + return false; + } + } + + boolean matchesAll = true; + boolean everMatched = false; + for (int i : solution.getEmptyChests()) + { + if (!testSolution.containsChest(i)) + { + matchesAll = false; + } + else + { + everMatched = true; + } + } + return matchesAll && everMatched; + } + + public ThievingRoomType getType() + { + return solution.getType(); + } + + + public void calculateChanceOfPoison() + { + if (getType() == null) + { + numberOfSolutionsWithPoison = null; + return; + } + + numberOfSolutionsWithPoison = new HashMap<>(); + for (SolutionSet sol : getPosssibleSolutions()) + { + if (getType() == sol.getType() && (solution.getEmptyChests().size() == 0 || matchSolution(sol))) + { + for (Integer i : sol.getEmptyChests()) + { + if (numberOfSolutionsWithPoison.containsKey(i)) + { + numberOfSolutionsWithPoison.put(i, numberOfSolutionsWithPoison.get(i) + 1); + } + else + { + numberOfSolutionsWithPoison.put(i, 1); + } + } + } + } + } + + private List getPosssibleSolutions() + { + List possibleSolutions = new ArrayList<>(); + for (SolutionSet soln : SOLUTION_SETS) + { + // Check if we've found grubs in one of the chests, invalidating it as an solution + boolean foundMatch = false; + for (int i : grubsChests) + { + if (soln.containsChest(i)) + { + foundMatch = true; + } + } + if (!foundMatch) + { + possibleSolutions.add(soln); + } + } + return possibleSolutions; + } + + public double relativeLikelihoodPoison(int chestId) + { + // Returns a double between 0 and 1 of how likely the chest has poison based on the number of possible solutions + // Uses a Sigmoid like function to give good contrast in drawn opacity, + // perhaps could be changed to something more accurate quantitavely. + if (numberOfSolutionsWithPoison == null) + { + calculateChanceOfPoison(); + } + if (numberOfSolutionsWithPoison == null) + { + return 1.0; + } + int mostFrequentPoison = 0; + for (Map.Entry entry : numberOfSolutionsWithPoison.entrySet()) + { + if (entry.getValue() > mostFrequentPoison) + { + mostFrequentPoison = entry.getValue(); + } + } + int timesFound = 0; + if (numberOfSolutionsWithPoison.containsKey(chestId)) + { + timesFound = numberOfSolutionsWithPoison.get(chestId); + } + double chestChance = (double) (timesFound) / (double) (mostFrequentPoison); + return 1. / (1 + Math.exp(5 - 10 * chestChance)); + } + + public int getNumberOfEmptyChests() + { + return solution.getEmptyChests().size(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java new file mode 100644 index 0000000000..7346e4ecf6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving.BatSolver; + +import net.runelite.client.plugins.raidsthieving.InstancePoint; +import net.runelite.client.plugins.raidsthieving.ThievingChest; +import java.util.HashMap; +import java.util.Map; + +public class ChestIdentifier +{ + public ChestIdentifier(ThievingRoomType roomType) + { + chestIds = new HashMap<>(); + switch (roomType) + { + case LEFT_TURN: + chestIds.put(new InstancePoint(3283, 5379), 1); + chestIds.put(new InstancePoint(3285, 5380), 2); + chestIds.put(new InstancePoint(3279, 5381), 3); + chestIds.put(new InstancePoint(3287, 5382), 4); + chestIds.put(new InstancePoint(3281, 5382), 5); + chestIds.put(new InstancePoint(3284, 5383), 6); + chestIds.put(new InstancePoint(3283, 5384), 7); + chestIds.put(new InstancePoint(3286, 5384), 8); + chestIds.put(new InstancePoint(3288, 5384), 9); + chestIds.put(new InstancePoint(3277, 5385), 10); + chestIds.put(new InstancePoint(3280, 5385), 11); + chestIds.put(new InstancePoint(3285, 5386), 12); + chestIds.put(new InstancePoint(3290, 5386), 13); + chestIds.put(new InstancePoint(3275, 5387), 14); + chestIds.put(new InstancePoint(3287, 5387), 15); + chestIds.put(new InstancePoint(3288, 5387), 16); + chestIds.put(new InstancePoint(3281, 5388), 17); + chestIds.put(new InstancePoint(3291, 5388), 18); + chestIds.put(new InstancePoint(3280, 5389), 19); + chestIds.put(new InstancePoint(3285, 5389), 20); + chestIds.put(new InstancePoint(3289, 5389), 21); + chestIds.put(new InstancePoint(3283, 5390), 22); + chestIds.put(new InstancePoint(3285, 5390), 23); + chestIds.put(new InstancePoint(3288, 5390), 24); + chestIds.put(new InstancePoint(3290, 5390), 25); + chestIds.put(new InstancePoint(3282, 5391), 26); + chestIds.put(new InstancePoint(3289, 5391), 27); + chestIds.put(new InstancePoint(3292, 5391), 28); + chestIds.put(new InstancePoint(3279, 5392), 29); + chestIds.put(new InstancePoint(3276, 5393), 30); + chestIds.put(new InstancePoint(3279, 5393), 31); + chestIds.put(new InstancePoint(3284, 5393), 32); + chestIds.put(new InstancePoint(3285, 5393), 33); + chestIds.put(new InstancePoint(3291, 5393), 34); + chestIds.put(new InstancePoint(3275, 5394), 35); + chestIds.put(new InstancePoint(3277, 5394), 36); + chestIds.put(new InstancePoint(3288, 5394), 37); + chestIds.put(new InstancePoint(3276, 5395), 38); + chestIds.put(new InstancePoint(3281, 5395), 39); + chestIds.put(new InstancePoint(3285, 5395), 40); + chestIds.put(new InstancePoint(3287, 5395), 41); + chestIds.put(new InstancePoint(3289, 5395), 42); + chestIds.put(new InstancePoint(3274, 5396), 43); + chestIds.put(new InstancePoint(3283, 5396), 44); + chestIds.put(new InstancePoint(3285, 5396), 45); + chestIds.put(new InstancePoint(3288, 5396), 46); + chestIds.put(new InstancePoint(3272, 5397), 47); + chestIds.put(new InstancePoint(3280, 5397), 48); + chestIds.put(new InstancePoint(3277, 5398), 49); + chestIds.put(new InstancePoint(3281, 5398), 50); + chestIds.put(new InstancePoint(3284, 5398), 51); + chestIds.put(new InstancePoint(3276, 5399), 52); + chestIds.put(new InstancePoint(3278, 5399), 53); + chestIds.put(new InstancePoint(3283, 5399), 54); + chestIds.put(new InstancePoint(3285, 5399), 55); + chestIds.put(new InstancePoint(3277, 5400), 56); + chestIds.put(new InstancePoint(3284, 5400), 57); + chestIds.put(new InstancePoint(3288, 5400), 58); + chestIds.put(new InstancePoint(3281, 5401), 59); + chestIds.put(new InstancePoint(3286, 5401), 60); + chestIds.put(new InstancePoint(3279, 5402), 61); + chestIds.put(new InstancePoint(3285, 5402), 62); + chestIds.put(new InstancePoint(3280, 5403), 63); + chestIds.put(new InstancePoint(3283, 5403), 64); + break; + case RIGHT_TURN: + chestIds.put(new InstancePoint(3338, 5405), 1); + chestIds.put(new InstancePoint(3334, 5405), 2); + chestIds.put(new InstancePoint(3342, 5404), 3); + chestIds.put(new InstancePoint(3340, 5404), 4); + chestIds.put(new InstancePoint(3345, 5403), 5); + chestIds.put(new InstancePoint(3334, 5403), 6); + chestIds.put(new InstancePoint(3330, 5403), 7); + chestIds.put(new InstancePoint(3343, 5402), 8); + chestIds.put(new InstancePoint(3342, 5402), 9); + chestIds.put(new InstancePoint(3339, 5402), 10); + chestIds.put(new InstancePoint(3338, 5402), 11); + chestIds.put(new InstancePoint(3336, 5402), 12); + chestIds.put(new InstancePoint(3347, 5401), 13); + chestIds.put(new InstancePoint(3330, 5401), 14); + chestIds.put(new InstancePoint(3345, 5400), 15); + chestIds.put(new InstancePoint(3341, 5400), 16); + chestIds.put(new InstancePoint(3337, 5400), 17); + chestIds.put(new InstancePoint(3334, 5400), 18); + chestIds.put(new InstancePoint(3345, 5399), 19); + chestIds.put(new InstancePoint(3343, 5399), 20); + chestIds.put(new InstancePoint(3340, 5399), 21); + chestIds.put(new InstancePoint(3335, 5399), 22); + chestIds.put(new InstancePoint(3331, 5399), 23); + chestIds.put(new InstancePoint(3338, 5398), 24); + chestIds.put(new InstancePoint(3337, 5398), 25); + chestIds.put(new InstancePoint(3345, 5397), 26); + chestIds.put(new InstancePoint(3341, 5397), 27); + chestIds.put(new InstancePoint(3334, 5397), 28); + chestIds.put(new InstancePoint(3331, 5397), 29); + chestIds.put(new InstancePoint(3346, 5396), 30); + chestIds.put(new InstancePoint(3343, 5396), 31); + chestIds.put(new InstancePoint(3339, 5396), 32); + chestIds.put(new InstancePoint(3335, 5396), 33); + chestIds.put(new InstancePoint(3333, 5396), 34); + chestIds.put(new InstancePoint(3340, 5395), 35); + chestIds.put(new InstancePoint(3337, 5395), 36); + chestIds.put(new InstancePoint(3334, 5395), 37); + chestIds.put(new InstancePoint(3345, 5394), 38); + chestIds.put(new InstancePoint(3342, 5394), 39); + chestIds.put(new InstancePoint(3332, 5394), 40); + chestIds.put(new InstancePoint(3343, 5393), 41); + chestIds.put(new InstancePoint(3341, 5393), 42); + chestIds.put(new InstancePoint(3338, 5393), 43); + chestIds.put(new InstancePoint(3335, 5393), 44); + chestIds.put(new InstancePoint(3334, 5393), 45); + chestIds.put(new InstancePoint(3346, 5392), 46); + chestIds.put(new InstancePoint(3342, 5392), 47); + chestIds.put(new InstancePoint(3332, 5392), 48); + chestIds.put(new InstancePoint(3350, 5391), 49); + chestIds.put(new InstancePoint(3346, 5391), 50); + chestIds.put(new InstancePoint(3340, 5391), 51); + chestIds.put(new InstancePoint(3339, 5391), 52); + chestIds.put(new InstancePoint(3336, 5391), 53); + chestIds.put(new InstancePoint(3333, 5391), 54); + chestIds.put(new InstancePoint(3349, 5390), 55); + chestIds.put(new InstancePoint(3343, 5390), 56); + chestIds.put(new InstancePoint(3337, 5390), 57); + chestIds.put(new InstancePoint(3335, 5390), 58); + chestIds.put(new InstancePoint(3344, 5389), 59); + chestIds.put(new InstancePoint(3340, 5389), 60); + chestIds.put(new InstancePoint(3336, 5389), 61); + chestIds.put(new InstancePoint(3333, 5389), 62); + chestIds.put(new InstancePoint(3346, 5388), 63); + chestIds.put(new InstancePoint(3340, 5387), 64); + chestIds.put(new InstancePoint(3337, 5386), 65); + chestIds.put(new InstancePoint(3333, 5386), 66); + chestIds.put(new InstancePoint(3338, 5385), 67); + chestIds.put(new InstancePoint(3336, 5385), 68); + chestIds.put(new InstancePoint(3337, 5384), 69); + chestIds.put(new InstancePoint(3340, 5382), 70); + chestIds.put(new InstancePoint(3334, 5383), 71); + chestIds.put(new InstancePoint(3340, 5379), 72); + chestIds.put(new InstancePoint(3338, 5380), 73); + chestIds.put(new InstancePoint(3336, 5381), 74); + break; + case STRAIGHT: + chestIds.put(new InstancePoint(3308, 5378), 1); + chestIds.put(new InstancePoint(3305, 5379), 2); + chestIds.put(new InstancePoint(3307, 5379), 3); + chestIds.put(new InstancePoint(3304, 5381), 4); + chestIds.put(new InstancePoint(3310, 5381), 5); + chestIds.put(new InstancePoint(3302, 5382), 6); + chestIds.put(new InstancePoint(3307, 5382), 7); + chestIds.put(new InstancePoint(3312, 5382), 8); + chestIds.put(new InstancePoint(3317, 5382), 9); + chestIds.put(new InstancePoint(3319, 5382), 10); + chestIds.put(new InstancePoint(3304, 5383), 11); + chestIds.put(new InstancePoint(3305, 5383), 12); + chestIds.put(new InstancePoint(3307, 5383), 13); + chestIds.put(new InstancePoint(3310, 5383), 14); + chestIds.put(new InstancePoint(3315, 5383), 15); + chestIds.put(new InstancePoint(3320, 5383), 16); + chestIds.put(new InstancePoint(3300, 5384), 17); + chestIds.put(new InstancePoint(3309, 5384), 18); + chestIds.put(new InstancePoint(3311, 5384), 19); + chestIds.put(new InstancePoint(3313, 5384), 20); + chestIds.put(new InstancePoint(3317, 5384), 21); + chestIds.put(new InstancePoint(3318, 5384), 22); + chestIds.put(new InstancePoint(3302, 5385), 23); + chestIds.put(new InstancePoint(3306, 5385), 24); + chestIds.put(new InstancePoint(3310, 5385), 25); + chestIds.put(new InstancePoint(3313, 5385), 26); + chestIds.put(new InstancePoint(3320, 5385), 27); + chestIds.put(new InstancePoint(3302, 5386), 28); + chestIds.put(new InstancePoint(3305, 5386), 29); + chestIds.put(new InstancePoint(3316, 5386), 30); + chestIds.put(new InstancePoint(3321, 5386), 31); + chestIds.put(new InstancePoint(3300, 5387), 32); + chestIds.put(new InstancePoint(3308, 5387), 33); + chestIds.put(new InstancePoint(3314, 5387), 34); + chestIds.put(new InstancePoint(3317, 5387), 35); + chestIds.put(new InstancePoint(3301, 5388), 36); + chestIds.put(new InstancePoint(3306, 5388), 37); + chestIds.put(new InstancePoint(3312, 5388), 38); + chestIds.put(new InstancePoint(3322, 5388), 39); + chestIds.put(new InstancePoint(3309, 5389), 40); + chestIds.put(new InstancePoint(3311, 5389), 41); + chestIds.put(new InstancePoint(3313, 5389), 42); + chestIds.put(new InstancePoint(3316, 5389), 43); + chestIds.put(new InstancePoint(3320, 5389), 44); + chestIds.put(new InstancePoint(3300, 5390), 45); + chestIds.put(new InstancePoint(3303, 5390), 46); + chestIds.put(new InstancePoint(3304, 5390), 47); + chestIds.put(new InstancePoint(3312, 5390), 48); + chestIds.put(new InstancePoint(3320, 5390), 49); + chestIds.put(new InstancePoint(3307, 5391), 50); + chestIds.put(new InstancePoint(3310, 5391), 51); + chestIds.put(new InstancePoint(3317, 5391), 52); + chestIds.put(new InstancePoint(3318, 5391), 53); + chestIds.put(new InstancePoint(3323, 5391), 54); + chestIds.put(new InstancePoint(3301, 5392), 55); + chestIds.put(new InstancePoint(3303, 5392), 56); + chestIds.put(new InstancePoint(3309, 5392), 57); + chestIds.put(new InstancePoint(3314, 5392), 58); + chestIds.put(new InstancePoint(3322, 5392), 59); + chestIds.put(new InstancePoint(3305, 5393), 60); + chestIds.put(new InstancePoint(3307, 5393), 61); + chestIds.put(new InstancePoint(3316, 5393), 62); + chestIds.put(new InstancePoint(3309, 5394), 63); + chestIds.put(new InstancePoint(3312, 5394), 64); + chestIds.put(new InstancePoint(3322, 5394), 65); + chestIds.put(new InstancePoint(3310, 5379), 66); + break; + } + + } + + public int indentifyChest(ThievingChest chest) + { + int id = chestIds.get(chest.getInstancePoint()); + chest.setChestId(id); + return id; + } + + private Map chestIds; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java new file mode 100644 index 0000000000..dc1c3c3dc2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving.BatSolver; + +import lombok.Getter; +import java.util.HashSet; +import java.util.Arrays; +import java.util.Set; + +// Each Thieving room has 4 empty chests +// User-reported data shows these 4 come in groups, +// +// e.g. if there is an empty chest in L room chest 1, the other empty chests could be 16, 17, 38, 54, 55 +// See https://dikkenoob.github.io/ for more information + +public class SolutionSet +{ + public static final SolutionSet[] SOLUTION_SETS = + { + new SolutionSet(ThievingRoomType.LEFT_TURN, 1, 16, 17, 55), + new SolutionSet(ThievingRoomType.LEFT_TURN, 1, 17, 38, 54), + new SolutionSet(ThievingRoomType.LEFT_TURN, 2, 7, 21, 37), + new SolutionSet(ThievingRoomType.LEFT_TURN, 3, 5, 19, 30), + new SolutionSet(ThievingRoomType.LEFT_TURN, 3, 11, 15, 40), + new SolutionSet(ThievingRoomType.LEFT_TURN, 4, 22, 27, 46), + new SolutionSet(ThievingRoomType.LEFT_TURN, 5, 9, 19, 45), + new SolutionSet(ThievingRoomType.LEFT_TURN, 6, 24, 26, 41), + new SolutionSet(ThievingRoomType.LEFT_TURN, 6, 26, 32, 52), + new SolutionSet(ThievingRoomType.LEFT_TURN, 7, 13, 44, 59), + new SolutionSet(ThievingRoomType.LEFT_TURN, 8, 14, 41, 43), + new SolutionSet(ThievingRoomType.LEFT_TURN, 8, 10, 28, 33), + new SolutionSet(ThievingRoomType.LEFT_TURN, 8, 31, 47, 50), + new SolutionSet(ThievingRoomType.LEFT_TURN, 10, 35, 54, 63), + new SolutionSet(ThievingRoomType.LEFT_TURN, 10, 30, 32, 59), + new SolutionSet(ThievingRoomType.LEFT_TURN, 12, 40, 53, 56), + new SolutionSet(ThievingRoomType.LEFT_TURN, 12, 13, 42, 54), + new SolutionSet(ThievingRoomType.LEFT_TURN, 13, 22, 27, 46), + new SolutionSet(ThievingRoomType.LEFT_TURN, 14, 18, 23, 51), + new SolutionSet(ThievingRoomType.LEFT_TURN, 15, 43, 44, 58), + new SolutionSet(ThievingRoomType.LEFT_TURN, 15, 16, 42, 45), + new SolutionSet(ThievingRoomType.LEFT_TURN, 20, 29, 45, 51), + new SolutionSet(ThievingRoomType.LEFT_TURN, 20, 25, 32, 34), + new SolutionSet(ThievingRoomType.LEFT_TURN, 20, 28, 51, 62), + new SolutionSet(ThievingRoomType.LEFT_TURN, 21, 39, 41, 58), + new SolutionSet(ThievingRoomType.LEFT_TURN, 22, 25, 54, 64), + new SolutionSet(ThievingRoomType.LEFT_TURN, 23, 31, 47, 55), + new SolutionSet(ThievingRoomType.LEFT_TURN, 23, 33, 37, 60), + new SolutionSet(ThievingRoomType.LEFT_TURN, 24, 34, 55), + new SolutionSet(ThievingRoomType.LEFT_TURN, 26, 50, 63, 27), + new SolutionSet(ThievingRoomType.LEFT_TURN, 29, 39, 41, 61), + new SolutionSet(ThievingRoomType.LEFT_TURN, 33, 46, 52, 57), + new SolutionSet(ThievingRoomType.LEFT_TURN, 34, 45, 49, 60), + new SolutionSet(ThievingRoomType.LEFT_TURN, 36, 40, 42, 62), + new SolutionSet(ThievingRoomType.LEFT_TURN, 37, 38, 51, 64), + new SolutionSet(ThievingRoomType.LEFT_TURN, 48, 53, 55, 56), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 1, 6, 28, 41), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 1, 42, 55, 60), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 2, 10, 31, 44), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 2, 33, 51, 68), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 3, 31, 43, 46), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 3, 5, 21, 48), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 4, 20, 24, 33), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 4, 38, 47), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 5, 21, 48), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 5, 17, 35, 63), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 7, 17, 45, 47), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 7, 37, 41, 52), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 8, 13, 40, 42), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 8, 20, 24, 30), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 9, 15, 23, 35), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 11, 13, 21, 50), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 11, 18, 37, 39), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 12, 14, 27, 34), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 14, 45, 67, 71), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 16, 22, 29, 32), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 18, 28, 31, 64), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 19, 21, 63, 69), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 20, 51, 68, 72), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 22, 29, 56, 61), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 23, 53, 66, 74), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 26, 35, 53, 59), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 27, 30, 55, 57), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 31, 58, 60, 73), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 34, 57, 58, 70), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 38, 56, 61, 70), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 40, 54, 65, 72), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 42, 46, 65), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 47, 49, 66, 67), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 48, 62, 69), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 9, 19, 32, 41), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 16, 26, 36, 39), + new SolutionSet(ThievingRoomType.STRAIGHT, 1, 39, 43, 51), + new SolutionSet(ThievingRoomType.STRAIGHT, 2, 15, 20, 53), + new SolutionSet(ThievingRoomType.STRAIGHT, 3, 10, 42, 44), + new SolutionSet(ThievingRoomType.STRAIGHT, 4, 14, 38, 52), + new SolutionSet(ThievingRoomType.STRAIGHT, 5, 6, 35, 41), + new SolutionSet(ThievingRoomType.STRAIGHT, 7, 16, 34, 49), + new SolutionSet(ThievingRoomType.STRAIGHT, 9, 12, 26, 27), + new SolutionSet(ThievingRoomType.STRAIGHT, 13, 25, 30, 31), + new SolutionSet(ThievingRoomType.STRAIGHT, 15, 20, 53), + new SolutionSet(ThievingRoomType.STRAIGHT, 17, 24, 34, 58), + new SolutionSet(ThievingRoomType.STRAIGHT, 18, 23, 35, 57), + new SolutionSet(ThievingRoomType.STRAIGHT, 19, 26, 47, 65), + new SolutionSet(ThievingRoomType.STRAIGHT, 21, 33, 36, 61), + new SolutionSet(ThievingRoomType.STRAIGHT, 21, 54, 66), + new SolutionSet(ThievingRoomType.STRAIGHT, 22, 25, 46, 55), + new SolutionSet(ThievingRoomType.STRAIGHT, 24, 34, 58), + new SolutionSet(ThievingRoomType.STRAIGHT, 28, 40, 52, 62), + new SolutionSet(ThievingRoomType.STRAIGHT, 29, 41, 42, 63), + new SolutionSet(ThievingRoomType.STRAIGHT, 30, 32, 37, 64), + new SolutionSet(ThievingRoomType.STRAIGHT, 39, 43, 51), + new SolutionSet(ThievingRoomType.STRAIGHT, 43, 45, 50, 60), + new SolutionSet(ThievingRoomType.STRAIGHT, 51, 53, 56, 59) + }; + + SolutionSet(ThievingRoomType type) + { + this.type = type; + emptyChests = new HashSet<>(); + } + + private SolutionSet(ThievingRoomType type, Integer... emptyChests) + { + this.type = type; + this.emptyChests = new HashSet<>(Arrays.asList(emptyChests)); + } + + public void addEmptyChest(int chestId) + { + emptyChests.add(chestId); + } + + public boolean containsChest(int chestId) + { + return emptyChests.contains(chestId); + } + + @Getter + private ThievingRoomType type; + + @Getter + private Set emptyChests; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java new file mode 100644 index 0000000000..f709b2d435 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving.BatSolver; + +// There are three distinct Thieving rooms, distinguished by the position of the entrance relative to the exit +// e.g. If you enter the room and must turn left to get to the exit and trough, this is a LEFT_TURN + +import net.runelite.client.plugins.raidsthieving.InstancePoint; + +public enum ThievingRoomType +{ + LEFT_TURN(3271, 5389), + RIGHT_TURN(3350, 5399), + STRAIGHT(3317, 5397); + + private final int x; + private final int y; + + ThievingRoomType(int x, int y) + { + this.x = x; + this.y = y; + } + + public static ThievingRoomType IdentifyByInstancePoint(InstancePoint point) + { + for (ThievingRoomType type : ThievingRoomType.values()) + { + if (Math.abs(type.x - point.getX()) <= 1 && + Math.abs(type.y - point.getY()) <= 1) + { + return type; + } + } + + return null; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java new file mode 100644 index 0000000000..5e09486f89 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving; + +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.raidsthieving.BatSolver.BatSolver; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ProgressPieComponent; +import javax.inject.Inject; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.util.Map; +import java.util.TreeSet; + +/** + * Represents the overlay that shows timers on traps that are placed by the + * player. + */ +public class ChestOverlay extends Overlay +{ + + private final Client client; + private final RaidsThievingPlugin plugin; + private final RaidsThievingConfig config; + + @Inject + ChestOverlay(Client client, RaidsThievingPlugin plugin, RaidsThievingConfig config) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + this.plugin = plugin; + this.config = config; + this.client = client; + } + + @Override + public Dimension render(Graphics2D graphics) + { + drawChests(graphics); + return null; + } + + /** + * Updates the timer colors. + */ + public void updateConfig() + { + } + + /** + * Iterates over all the traps that were placed by the local player, and + * draws a circle or a timer on the trap, depending on the trap state. + * + * @param graphics + */ + private void drawChests(Graphics2D graphics) + { + + for (Map.Entry entry : plugin.getChests().entrySet()) + { + ThievingChest chest = entry.getValue(); + WorldPoint pos = entry.getKey(); + + + if (chest != null) + { + if (!plugin.isBatsFound() && !chest.isEverOpened()) + { + if (shouldDrawChest(pos)) + { + Color drawColor = new Color(config.getPotentialBatColor().getRed(), + config.getPotentialBatColor().getGreen(), + config.getPotentialBatColor().getBlue(), + getChestOpacity(pos)); + drawCircleOnTrap(graphics, chest, drawColor); + } + } + if (chest.isPoison()) + { + drawCircleOnTrap(graphics, chest, config.getPoisonTrapColor()); + } + } + } + } + + private boolean shouldDrawChest(WorldPoint chestPos) + { + if (plugin.numberOfEmptyChestsFound() == 0) + { + return true; + } + int chestId = plugin.getChestId(chestPos); + BatSolver solver = plugin.getSolver(); + if (solver != null && chestId != -1) + { + TreeSet matches = solver.matchSolutions(); + return matches.contains(chestId) || matches.size() == 0; + } + return true; + } + + /** + * Draws a timer on a given trap. + * + * @param graphics + * @param chest The chest on which the circle needs to be drawn + * @param fill The fill color of the timer + */ + private void drawCircleOnTrap(Graphics2D graphics, ThievingChest chest, Color fill) + { + if (chest.getLocalPoint().getPlane() != client.getPlane()) + { + return; + } + LocalPoint localLoc = LocalPoint.fromWorld(client, chest.getLocalPoint()); + if (localLoc == null) + { + return; + } + Point loc = Perspective.localToCanvas(client, localLoc, chest.getLocalPoint().getPlane()); + + ProgressPieComponent pie = new ProgressPieComponent(); + pie.setFill(fill); + pie.setBorderColor(Color.BLACK); + pie.setPosition(loc); + pie.setProgress(1); + if (graphics != null && loc != null) + { + pie.render(graphics); + } + } + + private int getChestOpacity(WorldPoint chestPos) + { + int chestId = plugin.getChestId(chestPos); + BatSolver solver = plugin.getSolver(); + if (solver != null && chestId != -1) + { + return (int) (255 * solver.relativeLikelihoodPoison(chestId)); + } + return 255; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java new file mode 100644 index 0000000000..0df80aeb65 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java @@ -0,0 +1,98 @@ +package net.runelite.client.plugins.raidsthieving; + +import lombok.Getter; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.api.coords.WorldPoint; + +import java.util.Objects; + +/** + * Represents a point in the instance chunk, invariant of rotation. + */ +@Getter +public class InstancePoint +{ + private static final int CHUNK_SIZE = 8; + private static final double CHUNK_OFFSET = 3.5; + + public InstancePoint(int x, int y, int rot) + { + this.x = x; + this.y = y; + this.rot = rot; + } + + public InstancePoint(int x, int y) + { + this.x = x; + this.y = y; + this.rot = 0; + } + + public static InstancePoint buildFromPoint(WorldPoint worldPoint, Client client) + { + Point point = new Point(worldPoint.getX(), worldPoint.getY()); + Point base = new Point(client.getBaseX(), client.getBaseY()); + int plane = worldPoint.getPlane(); + + int deltaX = point.getX() - base.getX(); + int deltaY = point.getY() - base.getY(); + int chunkIndexX = deltaX / CHUNK_SIZE; + int chunkIndexY = deltaY / CHUNK_SIZE; + + int chunkData = client.getInstanceTemplateChunks()[plane][chunkIndexX][chunkIndexY]; + int rotation = chunkData >> 1 & 0x3; + int y = (chunkData >> 3 & 0x7FF) * 8; + int x = (chunkData >> 14 & 0x3FF) * 8; + + return buildFromTile(base, point, rotation, new Point(x, y)); + } + + public static InstancePoint buildFromTile(Point base, Point tile, int rot, Point chunkOrigin) + { + int deltaX = tile.getX() - base.getX(); + int deltaY = tile.getY() - base.getY(); + + double chunkOffsetX = (deltaX % CHUNK_SIZE) - CHUNK_OFFSET; + double chunkOffsetY = (deltaY % CHUNK_SIZE) - CHUNK_OFFSET; + + for (int i = 0; i < rot; i++) + { + double temp = chunkOffsetX; + chunkOffsetX = -chunkOffsetY; + chunkOffsetY = temp; + } + + chunkOffsetX += CHUNK_OFFSET; + chunkOffsetY += CHUNK_OFFSET; + + int invariantChunkOffsetX = (int) chunkOffsetX; + int invariantChunkOffsetY = (int) chunkOffsetY; + + return new InstancePoint( + chunkOrigin.getX() + invariantChunkOffsetX, + chunkOrigin.getY() + invariantChunkOffsetY, + rot); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InstancePoint that = (InstancePoint) o; + return x == that.x && + y == that.y; + } + + @Override + public int hashCode() + { + return Objects.hash(x, y); + } + + private int x; + private int y; + private int rot; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java new file mode 100644 index 0000000000..bb055edf4e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017, Tim Lehner + * 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.raidsthieving; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import java.awt.Color; + +@ConfigGroup("raidsthievingplugin") +public interface RaidsThievingConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "hexColorPotentialBat", + name = "Potential Bat", + description = "Color of marker for chests which could have bat" + ) + default Color getPotentialBatColor() + { + return Color.YELLOW; + } + + @ConfigItem( + position = 2, + keyName = "hexColorPoison", + name = "Poison trap", + description = "Color of chest with poison" + ) + default Color getPoisonTrapColor() + { + return Color.GREEN; + } + + @ConfigItem( + position = 5, + keyName = "batNotify", + name = "Notify when found", + description = "Send notification if you see bats being found." + ) + default boolean batFoundNotify() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java new file mode 100644 index 0000000000..965934a01b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017, Tim Lehner + * 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.raidsthieving; + +public class RaidsThievingConstants +{ + public static final int CLOSED_CHEST_ID = 29742; + public static final int OPEN_EMPTY_CHEST = 29743; + public static final int OPEN_FULL_CHEST_1 = 29744; + public static final int OPEN_FULL_CHEST_2 = 29745; + public static final int EMPTY_TROUGH = 29746; + public static final int[] STORAGE = {29769, 29770, 29771, 29772}; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java new file mode 100644 index 0000000000..d9f7de646c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2017, Tim Lehner + * 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.raidsthieving; + +import com.google.inject.Provides; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameObject; +import net.runelite.api.GraphicsObject; +import net.runelite.api.Varbits; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameObjectSpawned; +import net.runelite.api.events.GraphicsObjectCreated; +import net.runelite.api.events.VarbitChanged; +import net.runelite.client.Notifier; +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.raidsthieving.BatSolver.BatSolver; +import net.runelite.client.plugins.raidsthieving.BatSolver.ChestIdentifier; +import net.runelite.client.plugins.raidsthieving.BatSolver.ThievingRoomType; +import net.runelite.client.ui.overlay.OverlayManager; +import javax.inject.Inject; +import java.text.MessageFormat; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@PluginDescriptor( + name = "!Raids Bat Finder", + description = "Tracks which chests need to be searched for bats and which poison", + tags = {"overlay", "skilling", "raid"} +) +public class RaidsThievingPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private OverlayManager overlayManager; + + @Inject + private ChestOverlay overlay; + + @Inject + private Notifier notifier; + + @Inject + private RaidsThievingConfig config; + + @Getter + private final Map chests = new HashMap<>(); + + @Getter + private Instant lastActionTime = Instant.ofEpochMilli(0); + + private boolean inRaidChambers; + + @Getter + private boolean batsFound; + + @Getter + private BatSolver solver; + + @Getter + private ChestIdentifier mapper; + + + @Provides + RaidsThievingConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(RaidsThievingConfig.class); + } + + @Override + protected void startUp() + { + overlayManager.add(overlay); + overlay.updateConfig(); + reset(); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + lastActionTime = Instant.ofEpochMilli(0); + chests.clear(); + } + + + @Subscribe + public void onGameObjectSpawned(GameObjectSpawned event) + { + GameObject obj = event.getGameObject(); + WorldPoint loc = obj.getWorldLocation(); + InstancePoint absLoc = InstancePoint.buildFromPoint(loc, client); + + if (obj.getId() == RaidsThievingConstants.EMPTY_TROUGH) + { + ThievingRoomType type = ThievingRoomType.IdentifyByInstancePoint(absLoc); + + if (type != null) + { + solver = new BatSolver(type); + mapper = new ChestIdentifier(type); + for (ThievingChest chest : chests.values()) + { + mapper.indentifyChest(chest); + } + } + else + { + log.error(MessageFormat.format("Unable to identify room type with: {0} {1} {2} {3} {4}.", + loc.getX(), loc.getY(), absLoc.getX(), absLoc.getY(), absLoc.getRot())); + log.error("Please report this @https://github.com/runelite/runelite/pull/4914!"); + } + } + if (obj.getId() == RaidsThievingConstants.CLOSED_CHEST_ID) + { + if (!chests.containsKey(loc)) + { + ThievingChest chest = new ThievingChest(obj, absLoc); + + if (mapper != null) + { + mapper.indentifyChest(chest); + } + + chests.put(loc, chest); + } + else + { + checkForBats(); + } + } + + if (obj.getId() == RaidsThievingConstants.OPEN_FULL_CHEST_1 || + obj.getId() == RaidsThievingConstants.OPEN_FULL_CHEST_2) + { + ThievingChest chest = chests.get(obj.getWorldLocation()); + // We found a chest that has grubs + log.info(MessageFormat.format("Found grubs at {0}, {1} chestId: {2}", loc.getX(), loc.getY(), chest.getChestId())); + if (solver != null && chest.getChestId() != -1) + { + chest.setEverOpened(true); + solver.addGrubsChest(chest.getChestId()); + } + checkForBats(); + } + + if (obj.getId() == RaidsThievingConstants.OPEN_EMPTY_CHEST) + { + ThievingChest chest = chests.get(obj.getWorldLocation()); + // We found a chest that could have poison + if (solver != null && chest.getChestId() != -1) + { + chest.setEmpty(true); + chest.setEverOpened(true); + solver.addEmptyChest(chest.getChestId()); + } + } + } + + + @Subscribe + public void onGraphicsObjectCreated(GraphicsObjectCreated event) + { + GraphicsObject obj = event.getGraphicsObject(); + if (obj.getId() == 184) + { + log.debug("Found poison splat"); + WorldPoint loc = WorldPoint.fromLocal(client, obj.getLocation()); + chests.get(loc).setPoison(true); + } + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + boolean setting = client.getVar(Varbits.IN_RAID) == 1; + + if (inRaidChambers != setting) + { + inRaidChambers = setting; + reset(); + } + + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals("raidsthievingplugin")) + { + overlay.updateConfig(); + } + } + + private void reset() + { + chests.clear(); + batsFound = false; + solver = null; + mapper = null; + } + + public int numberOfEmptyChestsFound() + { + int total = 0; + for (ThievingChest chest : chests.values()) + { + if (chest.isEmpty()) + { + total++; + } + } + return total; + } + + + private boolean checkForBats() + { + for (ThievingChest chest : chests.values()) + { + if (chest.isEmpty() && !chest.isPoison()) + { + batsFound = true; + if (config.batFoundNotify()) + { + notifier.notify("Bats have been found!"); + } + return true; + } + } + return false; + } + + public int getChestId(WorldPoint worldPoint) + { + return chests.get(worldPoint).getChestId(); + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java new file mode 100644 index 0000000000..05a58d554e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019, Tim Lehner + * 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.raidsthieving; + +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.GameObject; +import net.runelite.api.coords.WorldPoint; + +/** + * Wrapper class for a GameObject that represents a chest in the thieving room of Chambers of Xeric. + */ +@Getter +public class ThievingChest +{ + /** + * If the chest has never been opened, it could have bats. + */ + @Setter + private boolean everOpened; + + /** + * If the chest is empty, it could have bats. + */ + @Setter + private boolean empty; + + /** + * If the chest contains a poison trap instead. + */ + @Setter + private boolean poison; + + + @Setter + private int chestId; + + private final WorldPoint localPoint; + private final InstancePoint instancePoint; + + /** + * Constructor for a ThievingChest object + * + * @param gameObject The gameobject thats corresponds with this trap. + */ + ThievingChest(GameObject gameObject, InstancePoint instancePoint) + { + this.everOpened = false; + this.poison = false; + this.empty = false; + localPoint = gameObject.getWorldLocation(); + this.instancePoint = instancePoint; + this.chestId = -1; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java index be4d85e9fe..33f702e072 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java @@ -45,6 +45,7 @@ import net.runelite.client.plugins.PluginDescriptor; @PluginDescriptor( name = "!Remember Clan", description = "Remember a specific clan!", + type = "utility", enabledByDefault = false ) public class RememberClanPlugin extends Plugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java new file mode 100644 index 0000000000..ec2e3cc105 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java @@ -0,0 +1,25 @@ +package net.runelite.client.plugins.safespot; + +import java.awt.Color; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.Config; + +@ConfigGroup("safespot") +public interface SafeSpotConfig extends Config +{ + @ConfigItem(position = 1, keyName = "playerSafeSpots", name = "Render for Players", description = "Renders 1 way safe spots vs other players") + default boolean playerSafeSpots() { + return true; + } + + @ConfigItem(position = 2, keyName = "npcSafeSpots", name = "Render for NPCs", description = "Renders 1 way safe spots vs NPCs") + default boolean npcSafeSpots() { + return false; + } + + @ConfigItem(position = 3, keyName = "tileColor", name = "Tile Color", description = "Color of safe spot tile") + default Color tileColor() { + return Color.MAGENTA; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java new file mode 100644 index 0000000000..7259957f15 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java @@ -0,0 +1,40 @@ +package net.runelite.client.plugins.safespot; + +import javax.inject.*; +import net.runelite.client.ui.overlay.*; +import java.awt.*; +import net.runelite.api.*; + +public class SafeSpotOverlay extends Overlay +{ + private final Client client; + private final SafeSpotPlugin safeSpotPlugin; + private final SafeSpotConfig config; + + @Inject + public SafeSpotOverlay( Client client, SafeSpotPlugin safeSpotPlugin, SafeSpotConfig config) { + this.client = client; + this.safeSpotPlugin = safeSpotPlugin; + this.config = config; + this.setPosition(OverlayPosition.DYNAMIC); + this.setPriority(OverlayPriority.LOW); + this.setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) { + if (safeSpotPlugin.isSafeSpotsRenderable() && safeSpotPlugin.getSafeSpotList() != null && safeSpotPlugin.getSafeSpotList().size() > 0) { + safeSpotPlugin.getSafeSpotList().forEach(tile -> { + Polygon poly; + if (tile != null && tile.getLocalLocation() != null) { + poly = Perspective.getCanvasTilePoly(client, tile.getLocalLocation()); + if (poly != null) { + OverlayUtil.renderPolygon(graphics, poly, config.tileColor()); + } + } + return; + }); + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java new file mode 100644 index 0000000000..9955332d11 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java @@ -0,0 +1,135 @@ +package net.runelite.client.plugins.safespot; + + +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import java.util.List; +import net.runelite.api.Actor; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.NPC; +import net.runelite.api.Player; +import net.runelite.api.events.GameTick; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.api.events.InteractingChanged; +import com.google.inject.Provides; +import net.runelite.client.config.ConfigManager; +import net.runelite.api.Tile; +import java.util.ArrayList; +import net.runelite.client.ui.overlay.OverlayManager; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.Plugin; + +@PluginDescriptor( + name = "1 Way Safe Spots", + description = "Renders tile overlays for one way safe spots", + tags = { "safe spot", "pvp", "safespots", "pklite" }, + type = "PVP", + enabledByDefault = false +) + +// TODO : filter tiles you cant stand on + +public class SafeSpotPlugin extends Plugin +{ + @Inject + private Client client; + @Inject + OverlayManager overlayManager; + @Inject + private SafeSpotConfig config; + private ArrayList safeSpotList; + private boolean safeSpotsRenderable; + private SafeSpotOverlay safeSpotOverlay; + private int tickCount; + + public SafeSpotPlugin() { + this.safeSpotsRenderable = false; + this.tickCount = 0; + } + + @Provides + SafeSpotConfig config(ConfigManager configManager) { + return configManager.getConfig(SafeSpotConfig.class); + } + + @Override + protected void startUp() throws Exception { + this.safeSpotOverlay = new SafeSpotOverlay(this.client, this, this.config); + this.overlayManager.add(safeSpotOverlay); + } + + @Override + protected void shutDown() throws Exception { + this.overlayManager.remove(safeSpotOverlay); + } + + @Subscribe + private void onInteractingChanged(InteractingChanged event) { + if (event.getSource() != client.getLocalPlayer()) { + return; + } + if (event.getTarget() == null && (config.npcSafeSpots() || config.playerSafeSpots())) { + tickCount = 10; + } + } + + @Subscribe + public void onGameTick(GameTick event) { + if (client.getLocalPlayer().getInteracting() != null) { + if (client.getLocalPlayer().getInteracting() instanceof Player && config.playerSafeSpots()) { + safeSpotsRenderable = true; + updateSafeSpots(); + } + if (client.getLocalPlayer().getInteracting() instanceof NPC && config.npcSafeSpots()) { + safeSpotsRenderable = true; + updateSafeSpots(); + } + } + else { + safeSpotsRenderable = false; + } + if (tickCount > 0) { + --tickCount; + safeSpotsRenderable = true; + } + } + + private void updateSafeSpots() + { + if (client.getLocalPlayer().getInteracting() != null) + { + Actor enemy = client.getLocalPlayer().getInteracting(); + + WorldArea worldArea = new WorldArea(enemy.getWorldLocation().getX() - 12, enemy.getWorldLocation().getY() - 12, 24, 24, client.getPlane()); + List worldPoints = worldArea.toWorldPointList(); + safeSpotList = getSafeSpotList(enemy, worldPoints); + } + } + + private ArrayList getSafeSpotList(Actor actor, List worldPoints) + { + ArrayList safeSpotList = new ArrayList(); + Tile[][][] tiles = client.getScene().getTiles(); + for (WorldPoint w : worldPoints) + { + LocalPoint toPoint = LocalPoint.fromWorld(client, w); + Tile fromTile = tiles[client.getPlane()][actor.getLocalLocation().getSceneX()][actor.getLocalLocation().getSceneY()]; + Tile toTile = tiles[client.getPlane()][toPoint.getSceneX()][toPoint.getSceneY()]; + if ((toTile.hasLineOfSightTo(fromTile)) && (!fromTile.hasLineOfSightTo(toTile))) + { + safeSpotList.add(toTile); + } + } + return safeSpotList; + } + + public ArrayList getSafeSpotList() { + return safeSpotList; + } + + public boolean isSafeSpotsRenderable() { + return safeSpotsRenderable; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java index d1de9d419b..37e3d0507b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java @@ -43,6 +43,7 @@ import java.awt.Color; name = "!Stronghold", description = "Highlights the correct answer to Stronghold of Security questions", tags = {"stronghold", "security", "overlay", "answer", "highlight"} + type = "utility", ) @Slf4j public class StrongholdPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java index af7cf94ab7..a05322590d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java @@ -57,6 +57,7 @@ import net.runelite.client.ui.overlay.OverlayManager; name = "!War", description = "War War War.", tags = {"skill", "total", "max", "PVP"}, + type = "PVP", enabledByDefault = false ) public class WarIndicatorPlugin extends Plugin 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/zoneIndicators/ZoneIndicatorsPlugin.java index 5f3397e900..df3a773aaa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java @@ -55,6 +55,7 @@ import net.runelite.client.ui.overlay.OverlayManager; name = "!MultiLines", description = "Show borders of multicombat and PvP safezones", tags = {"multicombat", "lines", "pvp", "deadman", "safezones", "bogla"}, + type = "utility", enabledByDefault = false ) public class ZoneIndicatorsPlugin extends Plugin From 72de982de897a67109f292e3d3d309bb63145ca0 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 19:09:19 +0100 Subject: [PATCH 24/75] changes + security fix --- .../client/plugins/groupitemlist/GroupItemListPlugin.java | 2 +- .../client/plugins/raidsthieving/RaidsThievingPlugin.java | 5 +++-- .../client/plugins/rememberclan/RememberClanPlugin.java | 2 +- .../runelite/client/plugins/stronghold/StrongholdPlugin.java | 4 ++-- .../client/plugins/warindicators/WarIndicatorPlugin.java | 2 +- .../client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java index 99d9b14831..c0939f04c9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java @@ -14,7 +14,7 @@ import java.util.ArrayList; import java.util.LinkedHashMap; @PluginDescriptor( - name = "!Group Item List", + name = "Group Item List", description = "Group the right click menu of a pile of items.", tags = {"ground", "compress", "pile", "group"}, type = "utility", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java index d9f7de646c..10873e02d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java @@ -53,9 +53,10 @@ import java.util.Map; @Slf4j @PluginDescriptor( - name = "!Raids Bat Finder", + name = "Raids Bat Finder", description = "Tracks which chests need to be searched for bats and which poison", - tags = {"overlay", "skilling", "raid"} + tags = {"overlay", "skilling", "raid"}, + type = "PVM" ) public class RaidsThievingPlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java index 33f702e072..2b5dd54b35 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java @@ -43,7 +43,7 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @PluginDescriptor( - name = "!Remember Clan", + name = "Remember Clan", description = "Remember a specific clan!", type = "utility", enabledByDefault = false diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java index 37e3d0507b..b150748e0a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java @@ -40,9 +40,9 @@ import javax.inject.Inject; import java.awt.Color; @PluginDescriptor( - name = "!Stronghold", + name = "Stronghold", description = "Highlights the correct answer to Stronghold of Security questions", - tags = {"stronghold", "security", "overlay", "answer", "highlight"} + tags = {"stronghold", "security", "overlay", "answer", "highlight"}, type = "utility", ) @Slf4j diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java index a05322590d..9dc378547c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java @@ -54,7 +54,7 @@ import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( - name = "!War", + name = "War calling indicators", description = "War War War.", tags = {"skill", "total", "max", "PVP"}, type = "PVP", 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/zoneIndicators/ZoneIndicatorsPlugin.java index df3a773aaa..b48ffa41e9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java @@ -52,7 +52,7 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( - name = "!MultiLines", + name = "MultiLines", description = "Show borders of multicombat and PvP safezones", tags = {"multicombat", "lines", "pvp", "deadman", "safezones", "bogla"}, type = "utility", From 08015501b0e5a6c75f131d4e6f5412f3d029b7f2 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 19:12:28 +0100 Subject: [PATCH 25/75] Update StrongholdPlugin.java --- .../runelite/client/plugins/stronghold/StrongholdPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java index b150748e0a..cae099dc1e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java @@ -43,7 +43,7 @@ import java.awt.Color; name = "Stronghold", description = "Highlights the correct answer to Stronghold of Security questions", tags = {"stronghold", "security", "overlay", "answer", "highlight"}, - type = "utility", + type = "utility" ) @Slf4j public class StrongholdPlugin extends Plugin { From b26e2bdf0a27e4e15211a03593a9b0bdc478bebd Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 19:16:35 +0100 Subject: [PATCH 26/75] remove inventorysetups --- .../inventorysetups/InventorySetup.java | 15 - .../InventorySetupBankOverlay.java | 113 ----- .../inventorysetups/InventorySetupConfig.java | 84 ---- .../inventorysetups/InventorySetupItem.java | 15 - .../inventorysetups/InventorySetupPlugin.java | 403 ------------------ .../ui/InventorySetupContainerPanel.java | 109 ----- .../ui/InventorySetupEquipmentPanel.java | 91 ---- .../ui/InventorySetupInventoryPanel.java | 78 ---- .../ui/InventorySetupPluginPanel.java | 287 ------------- .../ui/InventorySetupSlot.java | 45 -- 10 files changed, 1240 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java deleted file mode 100644 index 043d22a30c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetup.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.ArrayList; - -@AllArgsConstructor -public class InventorySetup -{ - @Getter - private ArrayList inventory; - @Getter - private ArrayList equipment; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java deleted file mode 100644 index 34ba341fc7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupBankOverlay.java +++ /dev/null @@ -1,113 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.Point; -import net.runelite.api.Query; -import net.runelite.api.SpritePixels; -import net.runelite.api.queries.BankItemQuery; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.widgets.WidgetItem; -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.util.QueryRunner; - -import javax.inject.Inject; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.image.BufferedImage; -import java.util.Arrays; -import java.util.Objects; - -@Slf4j -public class InventorySetupBankOverlay extends Overlay -{ - private final Client client; - private final QueryRunner queryRunner; - private final InventorySetupPlugin plugin; - private final InventorySetupConfig config; - - @Inject - public InventorySetupBankOverlay(Client client, QueryRunner queryRunner, InventorySetupPlugin plugin, InventorySetupConfig config) - { - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.LOW); - setLayer(OverlayLayer.ABOVE_WIDGETS); - this.client = client; - this.queryRunner = queryRunner; - this.plugin = plugin; - this.config = config; - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (config.getBankHighlight()) - { - int[] ids = plugin.getCurrentInventorySetupIds(); - if (ids == null) - { - return null; - } - ids = Arrays.stream(ids) - .filter(Objects::nonNull) - .filter(id -> id != -1) - .toArray(); - final Query query = new BankItemQuery().idEquals(ids); - final WidgetItem[] widgetItems = queryRunner.runQuery(query); - final Widget bankContainer = client.getWidget(WidgetInfo.BANK_CONTAINER); - for (final WidgetItem item : widgetItems) - { - Point canvasLocation = item.getCanvasLocation(); - Rectangle canvasBounds = item.getCanvasBounds(); - Point windowLocation = bankContainer.getCanvasLocation(); - - if (canvasLocation == null || windowLocation == null) - { - return null; - } - - if (!(canvasLocation.getY() + 60 >= windowLocation.getY() + bankContainer.getHeight()) && !(canvasLocation.getY() + canvasBounds.getHeight() <= windowLocation.getY() + 90)) - { - final Color color = config.getBankHighlightColor(); - - if (color != null) - { - final BufferedImage outline = loadItemOutline(item.getId(), item.getQuantity(), color); - graphics.drawImage(outline, item.getCanvasLocation().getX() + 1, item.getCanvasLocation().getY() + 1, null); - if (item.getQuantity() > 1) - { - drawQuantity(graphics, item, Color.YELLOW); - } - else if (item.getQuantity() == 0) - { - drawQuantity(graphics, item, Color.YELLOW.darker()); - } - } - } - } - } - return null; - } - - private void drawQuantity(Graphics2D graphics, WidgetItem item, Color darker) - { - graphics.setColor(Color.BLACK); - graphics.drawString(String.valueOf(item.getQuantity()), item.getCanvasLocation().getX() + 2, item.getCanvasLocation().getY() + 11); - graphics.setColor(darker); - graphics.setFont(FontManager.getRunescapeSmallFont()); - graphics.drawString(String.valueOf(item.getQuantity()), item.getCanvasLocation().getX() + 1, item.getCanvasLocation().getY() + 10); - } - - private BufferedImage loadItemOutline(final int itemId, final int itemQuantity, final Color outlineColor) - { - final SpritePixels itemSprite = client.createItemSprite(itemId, itemQuantity, 2, 0, 0, true, 710); - return itemSprite.toBufferedOutline(outlineColor); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java deleted file mode 100644 index edcc47cd9c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupConfig.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -import java.awt.Color; - -@ConfigGroup("inventorysetups") -public interface InventorySetupConfig extends Config -{ - @ConfigItem( - keyName = "highlightDifferences", - name = "Highlight Differences", - description = "Highlight slots that don't match the selected setup", - position = 0 - ) - - default boolean getHighlightDifferences() - { - return false; - } - - @ConfigItem( - keyName = "highlightDifferenceColor", - name = "Highlight Color", - description = "The color used to highlight differences between setups", - position = 1 - ) - - default Color getHighlightColor() - { - return Color.RED; - } - - @ConfigItem( - keyName = "stackDifference", - name = "Stack Difference", - description = "Differences between setups will be highlighted if the stack size is different", - position = 2 - ) - - default boolean getStackDifference() - { - return false; - } - - @ConfigItem( - keyName = "variationDifference", - name = "Variation Difference", - description = "Variations of items (E.g., charged jewellery) will be counted as different", - position = 2 - ) - - default boolean getVariationDifference() - { - return false; - } - - @ConfigItem( - keyName = "bankHighlight", - name = "Bank Highlight", - description = "Highlight setup items in bank", - position = 4 - ) - - default boolean getBankHighlight() - { - return false; - } - - @ConfigItem( - keyName = "bankHighlightColor", - name = "Bank Highlight Color", - description = "The color used to highlight setup items in bank", - position = 5 - ) - - default Color getBankHighlightColor() - { - return Color.RED; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java deleted file mode 100644 index c1af4e68fd..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupItem.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -public class InventorySetupItem -{ - @Getter - private final int id; - @Getter - private final String name; - @Getter - private final int quantity; -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java deleted file mode 100644 index 8b9c632498..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java +++ /dev/null @@ -1,403 +0,0 @@ -package net.runelite.client.plugins.inventorysetups; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameState; -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.ConfigChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.ItemContainerChanged; -import net.runelite.client.callback.ClientThread; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.game.ItemManager; -import net.runelite.client.game.ItemVariationMapping; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.inventorysetups.ui.InventorySetupPluginPanel; -import net.runelite.client.ui.ClientToolbar; -import net.runelite.client.ui.NavigationButton; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.ImageUtil; - -import javax.inject.Inject; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; -import java.awt.image.BufferedImage; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; - -@PluginDescriptor( - name = "Inventory Setups", - description = "Save inventory setups", - tags = { "items", "inventory", "setups"}, - type = "utility", - enabledByDefault = false -) - -@Slf4j -public class InventorySetupPlugin extends Plugin -{ - - private static final String CONFIG_GROUP = "inventorysetups"; - private static final String CONFIG_KEY = "setups"; - private static final int NUM_INVENTORY_ITEMS = 28; - private static final int NUM_EQUIPMENT_ITEMS = 14; - - @Inject - private Client client; - - @Inject - private ItemManager itemManager; - - @Inject - private InventorySetupBankOverlay overlay; - - @Inject - private ClientToolbar clientToolbar; - - @Inject - private InventorySetupConfig config; - - @Inject - private OverlayManager overlayManager; - - @Inject - private ClientThread clientThread; - - @Inject - private ConfigManager configManager; - - private InventorySetupPluginPanel panel; - - private HashMap inventorySetups; - - private NavigationButton navButton; - - private boolean highlightDifference; - - @Override - public void startUp() - { - overlayManager.add(overlay); - - panel = new InventorySetupPluginPanel(this, itemManager); - - final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "inventorysetups_icon.png"); - - navButton = NavigationButton.builder() - .tooltip("Inventory Setups") - .icon(icon) - .priority(9) - .panel(panel) - .build(); - - clientToolbar.addNavigation(navButton); - - // load all the inventory setups from the config file - clientThread.invokeLater(() -> - { - if (client.getGameState() != GameState.LOGIN_SCREEN) - { - return false; - } - - loadConfig(); - panel.showNoSetupsPanel(); - return true; - }); - - } - - public void addInventorySetup() - { - final String name = JOptionPane.showInputDialog(panel, - "Enter the name of this setup.", - "Add New Setup", - JOptionPane.PLAIN_MESSAGE); - - // cancel button was clicked - if (name == null) - { - return; - } - - if (name.isEmpty()) - { - JOptionPane.showMessageDialog(panel, - "Invalid Setup Name", - "Names must not be empty.", - JOptionPane.PLAIN_MESSAGE); - return; - } - - if (inventorySetups.containsKey(name)) - { - String builder = "The setup " + name + " already exists. " + - "Would you like to replace it with the current setup?"; - int confirm = JOptionPane.showConfirmDialog(panel, - builder, - "Warning", - JOptionPane.OK_CANCEL_OPTION, - JOptionPane.PLAIN_MESSAGE); - - if (confirm == JOptionPane.CANCEL_OPTION) - { - return; - } - - // delete the old setup, no need to ask for confirmation - // because the user confirmed above - removeInventorySetup(name, false); - } - - clientThread.invoke(() -> - { - ArrayList inv = getNormalizedContainer(InventoryID.INVENTORY); - ArrayList eqp = getNormalizedContainer(InventoryID.EQUIPMENT); - - final InventorySetup invSetup = new InventorySetup(inv, eqp); - SwingUtilities.invokeLater(() -> - { - inventorySetups.put(name, invSetup); - panel.addInventorySetup(name); - panel.setCurrentInventorySetup(name); - - updateConfig(); - }); - }); - } - - public void removeInventorySetup(final String name, boolean askForConfirmation) - { - if (inventorySetups.containsKey(name)) - { - int confirm = JOptionPane.YES_OPTION; - - if (askForConfirmation) - { - confirm = JOptionPane.showConfirmDialog(panel, - "Are you sure you want to remove this setup?", - "Warning", - JOptionPane.YES_NO_OPTION, - JOptionPane.PLAIN_MESSAGE); - } - - if (confirm == JOptionPane.YES_OPTION) - { - inventorySetups.remove(name); - panel.removeInventorySetup(name); - } - - updateConfig(); - } - } - - public final InventorySetup getInventorySetup(final String name) - { - return inventorySetups.get(name); - } - - @Provides - InventorySetupConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(InventorySetupConfig.class); - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (event.getGroup().equals(CONFIG_GROUP)) - { - // only allow highlighting if the config is enabled and the player is logged in - highlightDifference = config.getHighlightDifferences() && client.getGameState() == GameState.LOGGED_IN; - final String setupName = panel.getSelectedInventorySetup(); - if (highlightDifference && !setupName.isEmpty()) - { - panel.setCurrentInventorySetup(setupName); - } - } - } - - private void updateConfig() - { - if (inventorySetups.isEmpty()) - { - configManager.unsetConfiguration(CONFIG_GROUP, CONFIG_KEY); - return; - } - - final Gson gson = new Gson(); - final String json = gson.toJson(inventorySetups); - configManager.setConfiguration(CONFIG_GROUP, CONFIG_KEY, json); - } - - private void loadConfig() - { - // serialize the internal data structure from the json in the configuration - final String json = configManager.getConfiguration(CONFIG_GROUP, CONFIG_KEY); - if (json == null || json.isEmpty()) - { - inventorySetups = new HashMap<>(); - } - else - { - // TODO add last resort?, serialize exception just make empty map - final Gson gson = new Gson(); - Type type = new TypeToken>() - { - - }.getType(); - inventorySetups = gson.fromJson(json, type); - } - - for (final String key : inventorySetups.keySet()) - { - panel.addInventorySetup(key); - } - - highlightDifference = false; - } - - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) - { - - if (!highlightDifference || client.getGameState() != GameState.LOGGED_IN) - { - return; - } - - // empty entry, no need to compare anything - final String selectedInventorySetup = panel.getSelectedInventorySetup(); - if (selectedInventorySetup.isEmpty()) - { - return; - } - - // check to see that the container is the equipment or inventory - ItemContainer container = event.getItemContainer(); - - if (container == client.getItemContainer(InventoryID.INVENTORY)) - { - ArrayList normContainer = getNormalizedContainer(InventoryID.INVENTORY); - final InventorySetup setup = inventorySetups.get(selectedInventorySetup); - panel.highlightDifferences(normContainer, setup, InventoryID.INVENTORY); - } - else if (container == client.getItemContainer(InventoryID.EQUIPMENT)) - { - ArrayList normContainer = getNormalizedContainer(InventoryID.EQUIPMENT); - final InventorySetup setup = inventorySetups.get(selectedInventorySetup); - panel.highlightDifferences(normContainer, setup, InventoryID.EQUIPMENT); - } - - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - switch (event.getGameState()) - { - // set the highlighting off if login screen shows up - case LOGIN_SCREEN: - highlightDifference = false; - final String setupName = panel.getSelectedInventorySetup(); - if (!setupName.isEmpty()) - { - panel.setCurrentInventorySetup(setupName); - } - break; - - // set highlighting - case LOGGED_IN: - highlightDifference = config.getHighlightDifferences(); - break; - } - } - - public ArrayList getNormalizedContainer(final InventoryID id) - { - assert id == InventoryID.INVENTORY || id == InventoryID.EQUIPMENT : "invalid inventory ID"; - - final ItemContainer container = client.getItemContainer(id); - - ArrayList newContainer = new ArrayList<>(); - - Item[] items = null; - if (container != null) - { - items = container.getItems(); - } - - int size = id == InventoryID.INVENTORY ? NUM_INVENTORY_ITEMS : NUM_EQUIPMENT_ITEMS; - - for (int i = 0; i < size; i++) - { - if (items == null || i >= items.length) - { - newContainer.add(new InventorySetupItem(-1, "", 0)); - } - else - { - final Item item = items[i]; - String itemName = ""; - if (client.isClientThread()) - { - itemName = itemManager.getItemComposition(item.getId()).getName(); - } - newContainer.add(new InventorySetupItem(item.getId(), itemName, item.getQuantity())); - } - } - - return newContainer; - } - - public final InventorySetupConfig getConfig() - { - return config; - } - - public boolean getHighlightDifference() - { - return highlightDifference; - } - - @Override - public void shutDown() - { - overlayManager.remove(overlay); - clientToolbar.removeNavigation(navButton); - } - - final int[] getCurrentInventorySetupIds() - { - InventorySetup setup = inventorySetups.get(panel.getSelectedInventorySetup()); - if (setup == null) - { - return null; - } - ArrayList items = new ArrayList<>(); - items.addAll(setup.getEquipment()); - items.addAll(setup.getInventory()); - ArrayList itemIds = new ArrayList<>(); - for (InventorySetupItem item : items) - { - int id = item.getId(); - ItemComposition itemComposition = itemManager.getItemComposition(id); - if (id > 0) - { - itemIds.add(ItemVariationMapping.map(id)); - itemIds.add(itemComposition.getPlaceholderId()); - } - - } - return itemIds.stream().mapToInt(i -> i).toArray(); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java deleted file mode 100644 index d5eda3697f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupContainerPanel.java +++ /dev/null @@ -1,109 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.client.game.AsyncBufferedImage; -import net.runelite.client.game.ItemManager; -import net.runelite.client.game.ItemVariationMapping; -import net.runelite.client.plugins.inventorysetups.InventorySetupConfig; -import net.runelite.client.plugins.inventorysetups.InventorySetupItem; -import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; -import net.runelite.client.ui.ColorScheme; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Color; -import java.util.ArrayList; - -public abstract class InventorySetupContainerPanel extends JPanel -{ - - protected ItemManager itemManager; - - private final InventorySetupPlugin plugin; - - InventorySetupContainerPanel(final ItemManager itemManager, final InventorySetupPlugin plugin, String captionText) - { - this.itemManager = itemManager; - this.plugin = plugin; - JPanel containerPanel = new JPanel(); - - final JPanel containerSlotsPanel = new JPanel(); - - setupContainerPanel(containerSlotsPanel); - - // caption - final JLabel caption = new JLabel(captionText); - caption.setHorizontalAlignment(JLabel.CENTER); - caption.setVerticalAlignment(JLabel.CENTER); - - // panel that holds the caption and any other graphics - final JPanel captionPanel = new JPanel(); - captionPanel.add(caption); - - containerPanel.setLayout(new BorderLayout()); - containerPanel.add(captionPanel, BorderLayout.NORTH); - containerPanel.add(containerSlotsPanel, BorderLayout.CENTER); - - add(containerPanel); - } - - void setContainerSlot(int index, - final InventorySetupSlot containerSlot, - final ArrayList items) - { - if (index >= items.size() || items.get(index).getId() == -1) - { - containerSlot.setImageLabel(null, null); - return; - } - - int itemId = items.get(index).getId(); - int quantity = items.get(index).getQuantity(); - final String itemName = items.get(index).getName(); - AsyncBufferedImage itemImg = itemManager.getImage(itemId, quantity, quantity > 1); - String toolTip = itemName; - if (quantity > 1) - { - toolTip += " (" + quantity + ")"; - } - containerSlot.setImageLabel(toolTip, itemImg); - } - - void highlightDifferentSlotColor(InventorySetupItem savedItem, - InventorySetupItem currItem, - final InventorySetupSlot containerSlot) - { - // important note: do not use item names for comparisons - // they are all empty to avoid clientThread usage when highlighting - - final InventorySetupConfig config = plugin.getConfig(); - final Color highlightColor = config.getHighlightColor(); - - if (config.getStackDifference() && currItem.getQuantity() != savedItem.getQuantity()) - { - containerSlot.setBackground(highlightColor); - return; - } - - int currId = currItem.getId(); - int checkId = savedItem.getId(); - - if (!config.getVariationDifference()) - { - currId = ItemVariationMapping.map(currId); - checkId = ItemVariationMapping.map(checkId); - } - - if (currId != checkId) - { - containerSlot.setBackground(highlightColor); - return; - } - - // set the color back to the original, because they match - containerSlot.setBackground(ColorScheme.DARKER_GRAY_COLOR); - } - - abstract public void setupContainerPanel(final JPanel containerSlotsPanel); - -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java deleted file mode 100644 index 7e0fecfa2b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupEquipmentPanel.java +++ /dev/null @@ -1,91 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.api.EquipmentInventorySlot; -import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.inventorysetups.InventorySetup; -import net.runelite.client.plugins.inventorysetups.InventorySetupItem; -import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; -import net.runelite.client.ui.ColorScheme; - -import javax.swing.JPanel; -import java.awt.GridLayout; -import java.util.ArrayList; -import java.util.HashMap; - -public class InventorySetupEquipmentPanel extends InventorySetupContainerPanel -{ - private HashMap equipmentSlots; - - InventorySetupEquipmentPanel(final ItemManager itemManager, final InventorySetupPlugin plugin) - { - super(itemManager, plugin, "Equipment"); - } - - @Override - public void setupContainerPanel(final JPanel containerSlotsPanel) - { - this.equipmentSlots = new HashMap<>(); - for (EquipmentInventorySlot slot : EquipmentInventorySlot.values()) - { - equipmentSlots.put(slot, new InventorySetupSlot(ColorScheme.DARKER_GRAY_COLOR)); - } - - final GridLayout gridLayout = new GridLayout(5, 3, 1, 1); - containerSlotsPanel.setLayout(gridLayout); - - // add the grid layouts, including invisible ones - containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.HEAD)); - containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.CAPE)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.AMULET)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.AMMO)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.WEAPON)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.BODY)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.SHIELD)); - containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.LEGS)); - containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.GLOVES)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.BOOTS)); - containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.RING)); - - } - - void setEquipmentSetupSlots(final InventorySetup setup) - { - final ArrayList equipment = setup.getEquipment(); - - for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values()) - { - int i = slot.getSlotIdx(); - super.setContainerSlot(i, equipmentSlots.get(slot), equipment); - } - - validate(); - repaint(); - - } - - void highlightDifferences(final ArrayList currEquipment, final InventorySetup inventorySetup) - { - final ArrayList equipToCheck = inventorySetup.getEquipment(); - - assert currEquipment.size() == equipToCheck.size() : "size mismatch"; - - for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values()) - { - - int slotIdx = slot.getSlotIdx(); - super.highlightDifferentSlotColor(equipToCheck.get(slotIdx), currEquipment.get(slotIdx), equipmentSlots.get(slot)); - } - } - - void resetEquipmentSlotsColor() - { - for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values()) - { - equipmentSlots.get(slot).setBackground(ColorScheme.DARKER_GRAY_COLOR); - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java deleted file mode 100644 index 136f4603ea..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupInventoryPanel.java +++ /dev/null @@ -1,78 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.inventorysetups.InventorySetup; -import net.runelite.client.plugins.inventorysetups.InventorySetupItem; -import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; -import net.runelite.client.ui.ColorScheme; - -import javax.swing.JPanel; -import java.awt.GridLayout; -import java.util.ArrayList; - -public class InventorySetupInventoryPanel extends InventorySetupContainerPanel -{ - - private static final int ITEMS_PER_ROW = 4; - private static final int NUM_INVENTORY_ITEMS = 28; - - private ArrayList inventorySlots; - - InventorySetupInventoryPanel(final ItemManager itemManager, final InventorySetupPlugin plugin) - { - super(itemManager, plugin, "Inventory"); - } - - - @Override - public void setupContainerPanel(final JPanel containerSlotsPanel) - { - this.inventorySlots = new ArrayList<>(); - for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) - { - inventorySlots.add(new InventorySetupSlot(ColorScheme.DARKER_GRAY_COLOR)); - } - - int numRows = (NUM_INVENTORY_ITEMS + ITEMS_PER_ROW - 1) / ITEMS_PER_ROW; - containerSlotsPanel.setLayout(new GridLayout(numRows, ITEMS_PER_ROW, 1, 1)); - for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) - { - containerSlotsPanel.add(inventorySlots.get(i)); - } - } - - void setInventorySetupSlots(final InventorySetup setup) - { - ArrayList inventory = setup.getInventory(); - - for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) - { - super.setContainerSlot(i, inventorySlots.get(i), inventory); - } - - validate(); - repaint(); - - } - - void highlightDifferentSlots(final ArrayList currInventory, final InventorySetup inventorySetup) - { - - final ArrayList inventoryToCheck = inventorySetup.getInventory(); - - assert currInventory.size() == inventoryToCheck.size() : "size mismatch"; - - for (int i = 0; i < NUM_INVENTORY_ITEMS; i++) - { - super.highlightDifferentSlotColor(inventoryToCheck.get(i), currInventory.get(i), inventorySlots.get(i)); - } - } - - void resetInventorySlotsColor() - { - for (InventorySetupSlot inventorySlot : inventorySlots) - { - inventorySlot.setBackground(ColorScheme.DARKER_GRAY_COLOR); - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java deleted file mode 100644 index b1b88a02c7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupPluginPanel.java +++ /dev/null @@ -1,287 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.api.InventoryID; -import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.inventorysetups.InventorySetup; -import net.runelite.client.plugins.inventorysetups.InventorySetupItem; -import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin; -import net.runelite.client.ui.PluginPanel; -import net.runelite.client.ui.components.PluginErrorPanel; -import net.runelite.client.util.ImageUtil; - -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.ImageIcon; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.border.EmptyBorder; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.event.ItemEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; -import java.util.ArrayList; - -public class InventorySetupPluginPanel extends PluginPanel -{ - - private static ImageIcon ADD_ICON; - private static ImageIcon ADD_HOVER_ICON; - private static ImageIcon REMOVE_ICON; - private static ImageIcon REMOVE_HOVER_ICON; - - private final JPanel noSetupsPanel; - private final JPanel invEqPanel; - - private final InventorySetupInventoryPanel invPanel; - private final InventorySetupEquipmentPanel eqpPanel; - - private final JComboBox setupComboBox; - - private final JLabel removeMarker; - - private final InventorySetupPlugin plugin; - - static - { - final BufferedImage addIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "add_icon.png"); - ADD_ICON = new ImageIcon(addIcon); - ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f)); - - final BufferedImage removeIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "remove_icon.png"); - REMOVE_ICON = new ImageIcon(removeIcon); - REMOVE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(removeIcon, 0.53f)); - } - - public InventorySetupPluginPanel(final InventorySetupPlugin plugin, final ItemManager itemManager) - { - super(false); - this.plugin = plugin; - this.removeMarker = new JLabel(REMOVE_ICON); - this.invPanel = new InventorySetupInventoryPanel(itemManager, plugin); - this.eqpPanel = new InventorySetupEquipmentPanel(itemManager, plugin); - this.noSetupsPanel = new JPanel(); - this.invEqPanel = new JPanel(); - this.setupComboBox = new JComboBox<>(); - - // setup the title - final JLabel addMarker = new JLabel(ADD_ICON); - final JLabel title = new JLabel(); - title.setText("Inventory Setups"); - title.setForeground(Color.WHITE); - - // setup the add marker (+ sign in the top right) - addMarker.setToolTipText("Add a new inventory setup"); - addMarker.addMouseListener(new MouseAdapter() - { - @Override - public void mouseClicked(MouseEvent e) - { - plugin.addInventorySetup(); - } - - @Override - public void mouseEntered(MouseEvent e) - { - addMarker.setIcon(ADD_HOVER_ICON); - } - - @Override - public void mouseExited(MouseEvent e) - { - addMarker.setIcon(ADD_ICON); - } - }); - - // setup the remove marker (X sign in the top right) - removeMarker.setToolTipText("Remove the current inventory setup"); - removeMarker.addMouseListener(new MouseAdapter() - { - @Override - public void mouseClicked(MouseEvent e) - { - final String name = (String)setupComboBox.getSelectedItem(); - plugin.removeInventorySetup(name, true); - } - - @Override - public void mouseEntered(MouseEvent e) - { - if (removeMarker.isEnabled()) - { - removeMarker.setIcon(REMOVE_HOVER_ICON); - } - } - - @Override - public void mouseExited(MouseEvent e) - { - removeMarker.setIcon(REMOVE_ICON); - } - }); - - // setup the combo box for selection switching - // add empty to indicate the empty position - setupComboBox.addItem(""); - setupComboBox.setSelectedIndex(0); - setupComboBox.addItemListener(e -> - { - if (e.getStateChange() == ItemEvent.SELECTED) - { - String selection = (String)e.getItem(); - setCurrentInventorySetup(selection); - } - }); - - // the panel on the top right that holds the add and delete buttons - final JPanel markersPanel = new JPanel(); - markersPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 0)); - markersPanel.add(removeMarker); - markersPanel.add(addMarker); - - // the top panel that has the title and the buttons - final JPanel titleAndMarkersPanel = new JPanel(); - titleAndMarkersPanel.setLayout(new BorderLayout()); - titleAndMarkersPanel.add(title, BorderLayout.WEST); - titleAndMarkersPanel.add(markersPanel, BorderLayout.EAST); - - // the panel that stays at the top and doesn't scroll - // contains the title, buttons, and the combo box - final JPanel northAnchoredPanel = new JPanel(); - northAnchoredPanel.setLayout(new BoxLayout(northAnchoredPanel, BoxLayout.Y_AXIS)); - northAnchoredPanel.setBorder(new EmptyBorder(0, 0, 10, 0)); - northAnchoredPanel.add(titleAndMarkersPanel); - northAnchoredPanel.add(Box.createRigidArea(new Dimension(0, 10))); - northAnchoredPanel.add(setupComboBox); - - // the panel that holds the inventory and equipment panels - final BoxLayout invEqLayout = new BoxLayout(invEqPanel, BoxLayout.Y_AXIS); - invEqPanel.setLayout(invEqLayout); - invEqPanel.add(invPanel); - invEqPanel.add(Box.createRigidArea(new Dimension(0, 10))); - invEqPanel.add(eqpPanel); - - // setup the error panel. It's wrapped around a normal panel - // so it doesn't stretch to fill the parent panel - final PluginErrorPanel errorPanel = new PluginErrorPanel(); - errorPanel.setContent("Inventory Setups", "Select or create an inventory setup."); - noSetupsPanel.add(errorPanel); - - // the panel that holds the inventory panels, and the error panel - final JPanel contentPanel = new JPanel(); - final BoxLayout contentLayout = new BoxLayout(contentPanel, BoxLayout.Y_AXIS); - contentPanel.setLayout(contentLayout); - contentPanel.add(invEqPanel); - contentPanel.add(noSetupsPanel); - - // wrapper for the main content panel to keep it from stretching - final JPanel contentWrapper = new JPanel(new BorderLayout()); - contentWrapper.add(Box.createGlue(), BorderLayout.CENTER); - contentWrapper.add(contentPanel, BorderLayout.NORTH); - final JScrollPane contentWrapperPane = new JScrollPane(contentWrapper); - contentWrapperPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - - setLayout(new BorderLayout()); - setBorder(new EmptyBorder(10, 10, 10, 10)); - add(northAnchoredPanel, BorderLayout.NORTH); - add(contentWrapperPane, BorderLayout.CENTER); - - // show the no setups panel on startup - showNoSetupsPanel(); - - } - - public void showNoSetupsPanel() - { - setupComboBox.setSelectedIndex(0); - removeMarker.setEnabled(false); - noSetupsPanel.setVisible(true); - invEqPanel.setVisible(false); - } - - private void showHasSetupPanel(final String name) - { - setupComboBox.setSelectedItem(name); - removeMarker.setEnabled(true); - noSetupsPanel.setVisible(false); - invEqPanel.setVisible(true); - } - - public void setCurrentInventorySetup(final String name) - { - if (name.isEmpty()) - { - showNoSetupsPanel(); - return; - } - - showHasSetupPanel(name); - - final InventorySetup inventorySetup = plugin.getInventorySetup(name); - - invPanel.setInventorySetupSlots(inventorySetup); - eqpPanel.setEquipmentSetupSlots(inventorySetup); - - if (plugin.getHighlightDifference()) - { - final ArrayList normInv = plugin.getNormalizedContainer(InventoryID.INVENTORY); - final ArrayList normEqp = plugin.getNormalizedContainer(InventoryID.EQUIPMENT); - - highlightDifferences(normInv, inventorySetup, InventoryID.INVENTORY); - highlightDifferences(normEqp, inventorySetup, InventoryID.EQUIPMENT); - } - else - { - invPanel.resetInventorySlotsColor(); - eqpPanel.resetEquipmentSlotsColor(); - } - - validate(); - repaint(); - } - - public void addInventorySetup(final String name) - { - setupComboBox.addItem(name); - } - - public void removeInventorySetup(final String name) - { - setupComboBox.removeItem(name); - showNoSetupsPanel(); - - invPanel.resetInventorySlotsColor(); - eqpPanel.resetEquipmentSlotsColor(); - - validate(); - repaint(); - } - - public void highlightDifferences(final ArrayList container, - final InventorySetup setupToCheck, - final InventoryID type) - { - switch (type) - { - case INVENTORY: - invPanel.highlightDifferentSlots(container, setupToCheck); - break; - - case EQUIPMENT: - eqpPanel.highlightDifferences(container, setupToCheck); - break; - } - } - - public final String getSelectedInventorySetup() - { - return (String)setupComboBox.getSelectedItem(); - } - - -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java deleted file mode 100644 index 13bbbaef14..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/ui/InventorySetupSlot.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.runelite.client.plugins.inventorysetups.ui; - -import net.runelite.client.game.AsyncBufferedImage; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.SwingConstants; -import java.awt.Color; -import java.awt.Dimension; - -public class InventorySetupSlot extends JPanel -{ - - private final JLabel imageLabel; - - public InventorySetupSlot(Color color) - { - imageLabel = new JLabel(); - imageLabel.setVerticalAlignment(SwingConstants.CENTER); - setPreferredSize(new Dimension(46, 42)); - setBackground(color); - add(imageLabel); - - } - - public void setImageLabel(String toolTip, AsyncBufferedImage itemImage) - { - if (itemImage == null || toolTip == null) - { - imageLabel.setToolTipText(""); - imageLabel.setIcon(null); - imageLabel.revalidate(); - return; - } - - imageLabel.setToolTipText(toolTip); - itemImage.addTo(imageLabel); - - validate(); - repaint(); - } - - - -} \ No newline at end of file From 7740d4f6a061ceaa2e897c812af278f8cee1a886 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 19:34:13 +0100 Subject: [PATCH 27/75] remove lootingbagviewer --- .../LootingBagViewerOverlay.java | 123 ------------------ .../LootingBagViewerPlugin.java | 60 --------- 2 files changed, 183 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java deleted file mode 100644 index 85a07780de..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2018 AWPH-I - * 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.lootingbagviewer; - -import net.runelite.api.Client; -import net.runelite.api.InventoryID; -import net.runelite.api.Item; -import net.runelite.api.ItemContainer; -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.ImageComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; - -import javax.inject.Inject; -import java.awt.*; -import java.awt.image.BufferedImage; - -class LootingBagViewerOverlay extends Overlay -{ - private static final int INVENTORY_SIZE = 28; - private static final int PLACEHOLDER_WIDTH = 36; - private static final int PLACEHOLDER_HEIGHT = 32; - private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(new BufferedImage(PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR)); - - private final Client client; - private final ItemManager itemManager; - - private final PanelComponent panelComponent = new PanelComponent(); - - private ItemContainer itemContainer; - private Item[] items; - - @Inject - private LootingBagViewerOverlay(Client client, ItemManager itemManager) - { - setPosition(OverlayPosition.BOTTOM_RIGHT); - panelComponent.setWrapping(4); - panelComponent.setGap(new Point(6, 4)); - panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); - this.itemManager = itemManager; - this.client = client; - - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (itemContainer == null) - { - if(client.getItemContainer(InventoryID.LOOTING_BAG) != null) { - itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); - items = itemContainer.getItems(); - } - return null; - } - else if(itemContainer != null && client.getItemContainer(InventoryID.LOOTING_BAG) != null) - { - itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); - Item[] tempItems = itemContainer.getItems(); - - for(int i = 0; i < items.length; i++) - { - if(!items[i].equals(tempItems[i])) - { - items = tempItems; - } - } - } - - panelComponent.getChildren().clear(); - - for (int i = 0; i < INVENTORY_SIZE; i++) - { - if (i < items.length) - { - final Item item = items[i]; - if (item.getQuantity() > 0) - { - final BufferedImage image = getImage(item); - if (image != null) - { - panelComponent.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); - } - - return panelComponent.render(graphics); - } - - private BufferedImage getImage(Item item) - { - return itemManager.getImage(item.getId(), item.getQuantity(), item.getQuantity() > 1); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java deleted file mode 100644 index 5729c69993..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2018 AWPH-I - * 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.lootingbagviewer; - -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; - -import javax.inject.Inject; - -@PluginDescriptor( - name = "PvP Looting Bag Viewer", - description = "Add an overlay showing the contents of your looting bag", - tags = {"alternate", "items", "overlay", "second"}, - type = "utility", - enabledByDefault = false -) -public class LootingBagViewerPlugin extends Plugin -{ - @Inject - private net.runelite.client.plugins.lootingbagviewer.LootingBagViewerOverlay overlay; - - @Inject - private OverlayManager overlayManager; - - @Override - public void startUp() - { - overlayManager.add(overlay); - } - - @Override - public void shutDown() - { - overlayManager.remove(overlay); - } -} \ No newline at end of file From 50a054ec86aff451a69f916035fd54733a1995ef Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 19:38:40 +0100 Subject: [PATCH 28/75] lootingbagviewer --- .../java/net/runelite/api/InventoryID.java | 6 +- .../LootingBagViewerOverlay.java | 123 ++++++++++++++++++ .../LootingBagViewerPlugin.java | 59 +++++++++ 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java diff --git a/runelite-api/src/main/java/net/runelite/api/InventoryID.java b/runelite-api/src/main/java/net/runelite/api/InventoryID.java index 000bb8aa52..ff099afd70 100644 --- a/runelite-api/src/main/java/net/runelite/api/InventoryID.java +++ b/runelite-api/src/main/java/net/runelite/api/InventoryID.java @@ -57,6 +57,10 @@ public enum InventoryID * Chambers of Xeric chest inventory. */ CHAMBERS_OF_XERIC_CHEST(581), + /** + * Looting Bag inventory + */ + LOOTING_BAG(516), /** * Theater of Blood reward chest inventory (Raids 2) */ @@ -78,4 +82,4 @@ public enum InventoryID { return id; } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java new file mode 100644 index 0000000000..85a07780de --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018 AWPH-I + * 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.lootingbagviewer; + +import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +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.ImageComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +import javax.inject.Inject; +import java.awt.*; +import java.awt.image.BufferedImage; + +class LootingBagViewerOverlay extends Overlay +{ + private static final int INVENTORY_SIZE = 28; + private static final int PLACEHOLDER_WIDTH = 36; + private static final int PLACEHOLDER_HEIGHT = 32; + private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(new BufferedImage(PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR)); + + private final Client client; + private final ItemManager itemManager; + + private final PanelComponent panelComponent = new PanelComponent(); + + private ItemContainer itemContainer; + private Item[] items; + + @Inject + private LootingBagViewerOverlay(Client client, ItemManager itemManager) + { + setPosition(OverlayPosition.BOTTOM_RIGHT); + panelComponent.setWrapping(4); + panelComponent.setGap(new Point(6, 4)); + panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + this.itemManager = itemManager; + this.client = client; + + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (itemContainer == null) + { + if(client.getItemContainer(InventoryID.LOOTING_BAG) != null) { + itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); + items = itemContainer.getItems(); + } + return null; + } + else if(itemContainer != null && client.getItemContainer(InventoryID.LOOTING_BAG) != null) + { + itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); + Item[] tempItems = itemContainer.getItems(); + + for(int i = 0; i < items.length; i++) + { + if(!items[i].equals(tempItems[i])) + { + items = tempItems; + } + } + } + + panelComponent.getChildren().clear(); + + for (int i = 0; i < INVENTORY_SIZE; i++) + { + if (i < items.length) + { + final Item item = items[i]; + if (item.getQuantity() > 0) + { + final BufferedImage image = getImage(item); + if (image != null) + { + panelComponent.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); + } + + return panelComponent.render(graphics); + } + + private BufferedImage getImage(Item item) + { + return itemManager.getImage(item.getId(), item.getQuantity(), item.getQuantity() > 1); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java new file mode 100644 index 0000000000..d9cfdd7bf9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018 AWPH-I + * 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.lootingbagviewer; + +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +import javax.inject.Inject; + +@PluginDescriptor( + name = "PvP Looting Bag Viewer", + description = "Add an overlay showing the contents of your looting bag", + tags = {"alternate", "items", "overlay", "second"}, + enabledByDefault = false +) +public class LootingBagViewerPlugin extends Plugin +{ + @Inject + private net.runelite.client.plugins.lootingbagviewer.LootingBagViewerOverlay overlay; + + @Inject + private OverlayManager overlayManager; + + @Override + public void startUp() + { + overlayManager.add(overlay); + } + + @Override + public void shutDown() + { + overlayManager.remove(overlay); + } +} \ No newline at end of file From c0bc66fb9c2dc7deaee54ab4da51e40b6cdf3e4c Mon Sep 17 00:00:00 2001 From: James <38226001+james-munson@users.noreply.github.com> Date: Sat, 20 Apr 2019 12:06:29 -0700 Subject: [PATCH 29/75] Changes (#15) * Add config option to hide inventory viewer when player inventory is open * Fix style error * Adds world history to world hopper plugin.\n- Adds support for converting strings to Maps\n- Ability to clear history * Fixed code style issues * Fixed code style issues in another file * Adds ability to not show tabs if you don't want * Tabs are not shown by default * Fix indentation in InventoryViewerConfig * mixes checkstyle * mixes checkstyle * Adds ability to see your xp drops as damage, overlayed above your opponent * Adds building to jar capabilities and fixes 0s * added output * Add grouping option to Inventory Viewer * Add option to show free slots Works on both the Grouped and Full modes * skybox: calculate brightness increase in HSB format * mixins: renderWidgetLayer: skip hidden widgets * World Map: Identify Both Shield of Arrav Quest Start Points (#8442) Closes #8437 * Add Ammo plugin Shows the contents of the Ammo slot as an Infobox * Add support for weapon slot items, such as darts * Add stack formatting * Improve Ammo's Documentation * widgetitem: associate Widget with WidgetItem * widgetitem overlay: allow configuring which interfaces to overlay Update overlays to behave consistent with how they behaved before removal of query api, with the exception of adding the rune pouch overlay to the bank. * Displays teammate health bars for BA Healer overlay Parses teammate hp and outputs to System.out Removed useless class Displays offset inverted health bars Set accurate values for location and size of health bars Checkstyle Checkstyle * Nothing * Removes max draw distance of ground markers * Added vanguard hp tracker * Vanguard Disabled by default * Add player indicator config to show offline friends * Better player indicator plugin, removed pk vison. added InteractChanged api * Add a toggle to only show player indicators in the wilderness. * Dont limit level by default in playerindicators * Added type to plugins --- .../java/net/runelite/api/VarClientInt.java | 5 + .../main/java/net/runelite/api/Varbits.java | 5 + .../net/runelite/api/coords/WorldPoint.java | 21 + .../runelite/api/events/InteractChanged.java | 34 + .../net/runelite/api/widgets/WidgetID.java | 10 + .../net/runelite/api/widgets/WidgetInfo.java | 23 +- .../runelite/client/config/ConfigManager.java | 16 + .../client/plugins/ammo/AmmoCounter.java | 59 + .../client/plugins/ammo/AmmoPlugin.java | 142 +++ .../plugins/attackstyles/AttackStyle.java | 2 +- .../plugins/attackstyles/WeaponType.java | 2 +- .../BarbarianAssaultOverlay.java | 47 +- .../plugins/barbarianassault/HealerTeam.java | 44 + .../plugins/experiencedrop/XpDropConfig.java | 22 + .../plugins/experiencedrop/XpDropOverlay.java | 73 ++ .../plugins/experiencedrop/XpDropPlugin.java | 214 +++- .../groundmarkers/GroundMarkerOverlay.java | 7 - .../InventoryViewerConfig.java | 63 + .../inventoryviewer/InventoryViewerMode.java | 44 + .../InventoryViewerOverlay.java | 101 +- .../InventoryViewerPlugin.java | 10 + .../PlayerIndicatorsConfig.java | 175 ++- .../PlayerIndicatorsOverlay.java | 95 +- .../PlayerIndicatorsPlugin.java | 162 ++- .../PlayerIndicatorsService.java | 92 +- .../client/plugins/skybox/Skybox.java | 9 +- .../plugins/vanguards/VanguardOverlay.java | 119 ++ .../plugins/vanguards/VanguardPlugin.java | 45 + .../worldhopper/WorldHopperConfig.java | 11 + .../worldhopper/WorldHopperPlugin.java | 47 + .../worldhopper/WorldSwitcherPanel.java | 1036 ++++++++++------- .../plugins/worldhopper/WorldTableHeader.java | 9 +- .../plugins/worldhopper/WorldTableRow.java | 1 + .../plugins/worldmap/QuestStartLocation.java | 2 - .../net/runelite/mixins/RSActorMixin.java | 6 +- 35 files changed, 2208 insertions(+), 545 deletions(-) create mode 100644 runelite-api/src/main/java/net/runelite/api/events/InteractChanged.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoCounter.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/HealerTeam.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerMode.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vanguards/VanguardOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/vanguards/VanguardPlugin.java 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/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/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/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/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/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/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/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/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/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-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 From 1931a7e580bbf828e8b4a8e714e6949fec7fc678 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 20:33:06 +0100 Subject: [PATCH 30/75] Update LootingBagViewerPlugin.java --- .../plugins/lootingbagviewer/LootingBagViewerPlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java index d9cfdd7bf9..5d28a4bbea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java @@ -35,6 +35,7 @@ import javax.inject.Inject; name = "PvP Looting Bag Viewer", description = "Add an overlay showing the contents of your looting bag", tags = {"alternate", "items", "overlay", "second"}, + type = "utility", enabledByDefault = false ) public class LootingBagViewerPlugin extends Plugin @@ -56,4 +57,4 @@ public class LootingBagViewerPlugin extends Plugin { overlayManager.remove(overlay); } -} \ No newline at end of file +} From ab7ca3ebedba249eee698c98041546a0f83d8f37 Mon Sep 17 00:00:00 2001 From: zeruth Date: Sat, 20 Apr 2019 15:39:55 -0400 Subject: [PATCH 31/75] Update KittenNotifierPlugin.java Prevent stack overflow, not sure if this is a complete fix, but stopped my crashes at GE --- .../client/plugins/kittennotifier/KittenNotifierPlugin.java | 1 + 1 file changed, 1 insertion(+) 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 4b6baf66a9..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 @@ -52,6 +52,7 @@ 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) { From 7efc3c1dcd2f83e19fd211e24ce50fb113fe05fe Mon Sep 17 00:00:00 2001 From: lordzuku <47382776+lordzuku@users.noreply.github.com> Date: Sat, 20 Apr 2019 15:44:19 -0400 Subject: [PATCH 32/75] Plugin additions (#19) * Added getProjectile tranform & zeruths player transform cleaned up a bit of the imports / code * fixed equipment inspector & added more features to tob --- .../main/java/net/runelite/api/Varbits.java | 813 +++++++++--------- .../EquipmentInspectorPanel.java | 5 - .../EquipmentInspectorPlugin.java | 350 ++++---- .../plugins/equipmentinspector/ItemPanel.java | 3 +- .../plugins/ztob/BloatTimerOverlay.java | 83 ++ .../client/plugins/ztob/TheatreConfig.java | 171 ++-- .../client/plugins/ztob/TheatreOverlay.java | 304 +++---- .../client/plugins/ztob/TheatrePlugin.java | 743 ++++++++++------ .../plugins/ztob/TheatreXarpusOverlay.java | 68 ++ .../plugins/ztob/VerzikNyloOverlay.java | 81 ++ .../plugins/equipmentinspector/normal.png | Bin 0 -> 624 bytes 11 files changed, 1554 insertions(+), 1067 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/equipmentinspector/normal.png 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 8c4c18bf91..038362c66d 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -32,472 +32,471 @@ import lombok.Getter; */ @AllArgsConstructor @Getter -public enum Varbits -{ - /* - * If chatbox is transparent or not - */ - TRANSPARENT_CHATBOX(4608), +public enum Varbits { + /* + * If chatbox is transparent or not + */ + TRANSPARENT_CHATBOX(4608), - /* - * If the player has an active stamina potion effect or not - */ - RUN_SLOWED_DEPLETION_ACTIVE(25), + /* + * If the player has an active stamina potion effect or not + */ + RUN_SLOWED_DEPLETION_ACTIVE(25), - /** - * If scrollbar in resizable mode chat is on the left - */ - CHAT_SCROLLBAR_ON_LEFT(6374), + /** + * If scrollbar in resizable mode chat is on the left + */ + CHAT_SCROLLBAR_ON_LEFT(6374), - /** - * Runepouch - */ - RUNE_POUCH_RUNE1(29), - RUNE_POUCH_RUNE2(1622), - RUNE_POUCH_RUNE3(1623), - RUNE_POUCH_AMOUNT1(1624), - RUNE_POUCH_AMOUNT2(1625), - RUNE_POUCH_AMOUNT3(1626), + /** + * Runepouch + */ + RUNE_POUCH_RUNE1(29), + RUNE_POUCH_RUNE2(1622), + RUNE_POUCH_RUNE3(1623), + RUNE_POUCH_AMOUNT1(1624), + RUNE_POUCH_AMOUNT2(1625), + RUNE_POUCH_AMOUNT3(1626), - /** - * Prayers - */ - QUICK_PRAYER(4103), - PRAYER_THICK_SKIN(4104), - PRAYER_BURST_OF_STRENGTH(4105), - PRAYER_CLARITY_OF_THOUGHT(4106), - PRAYER_SHARP_EYE(4122), - PRAYER_MYSTIC_WILL(4123), - PRAYER_ROCK_SKIN(4107), - PRAYER_SUPERHUMAN_STRENGTH(4108), - PRAYER_IMPROVED_REFLEXES(4109), - PRAYER_RAPID_RESTORE(4110), - PRAYER_RAPID_HEAL(4111), - PRAYER_PROTECT_ITEM(4112), - PRAYER_HAWK_EYE(4124), - PRAYER_MYSTIC_LORE(4125), - PRAYER_STEEL_SKIN(4113), - PRAYER_ULTIMATE_STRENGTH(4114), - PRAYER_INCREDIBLE_REFLEXES(4115), - PRAYER_PROTECT_FROM_MAGIC(4116), - PRAYER_PROTECT_FROM_MISSILES(4117), - PRAYER_PROTECT_FROM_MELEE(4118), - PRAYER_EAGLE_EYE(4126), - PRAYER_MYSTIC_MIGHT(4127), - PRAYER_RETRIBUTION(4119), - PRAYER_REDEMPTION(4120), - PRAYER_SMITE(4121), - PRAYER_CHIVALRY(4128), - PRAYER_PIETY(4129), - PRAYER_PRESERVE(5466), - PRAYER_RIGOUR(5464), - PRAYER_AUGURY(5465), + /** + * Prayers + */ + QUICK_PRAYER(4103), + PRAYER_THICK_SKIN(4104), + PRAYER_BURST_OF_STRENGTH(4105), + PRAYER_CLARITY_OF_THOUGHT(4106), + PRAYER_SHARP_EYE(4122), + PRAYER_MYSTIC_WILL(4123), + PRAYER_ROCK_SKIN(4107), + PRAYER_SUPERHUMAN_STRENGTH(4108), + PRAYER_IMPROVED_REFLEXES(4109), + PRAYER_RAPID_RESTORE(4110), + PRAYER_RAPID_HEAL(4111), + PRAYER_PROTECT_ITEM(4112), + PRAYER_HAWK_EYE(4124), + PRAYER_MYSTIC_LORE(4125), + PRAYER_STEEL_SKIN(4113), + PRAYER_ULTIMATE_STRENGTH(4114), + PRAYER_INCREDIBLE_REFLEXES(4115), + PRAYER_PROTECT_FROM_MAGIC(4116), + PRAYER_PROTECT_FROM_MISSILES(4117), + PRAYER_PROTECT_FROM_MELEE(4118), + PRAYER_EAGLE_EYE(4126), + PRAYER_MYSTIC_MIGHT(4127), + PRAYER_RETRIBUTION(4119), + PRAYER_REDEMPTION(4120), + PRAYER_SMITE(4121), + PRAYER_CHIVALRY(4128), + PRAYER_PIETY(4129), + PRAYER_PRESERVE(5466), + PRAYER_RIGOUR(5464), + PRAYER_AUGURY(5465), - /** - * Diary Entries - */ - DIARY_ARDOUGNE_EASY(4458), - DIARY_ARDOUGNE_MEDIUM(4459), - DIARY_ARDOUGNE_HARD(4460), - DIARY_ARDOUGNE_ELITE(4461), + /** + * Diary Entries + */ + DIARY_ARDOUGNE_EASY(4458), + DIARY_ARDOUGNE_MEDIUM(4459), + DIARY_ARDOUGNE_HARD(4460), + DIARY_ARDOUGNE_ELITE(4461), - DIARY_DESERT_EASY(4483), - DIARY_DESERT_MEDIUM(4484), - DIARY_DESERT_HARD(4485), - DIARY_DESERT_ELITE(4486), + DIARY_DESERT_EASY(4483), + DIARY_DESERT_MEDIUM(4484), + DIARY_DESERT_HARD(4485), + DIARY_DESERT_ELITE(4486), - DIARY_FALADOR_EASY(4462), - DIARY_FALADOR_MEDIUM(4463), - DIARY_FALADOR_HARD(4464), - DIARY_FALADOR_ELITE(4465), + DIARY_FALADOR_EASY(4462), + DIARY_FALADOR_MEDIUM(4463), + DIARY_FALADOR_HARD(4464), + DIARY_FALADOR_ELITE(4465), - DIARY_FREMENNIK_EASY(4491), - DIARY_FREMENNIK_MEDIUM(4492), - DIARY_FREMENNIK_HARD(4493), - DIARY_FREMENNIK_ELITE(4494), + DIARY_FREMENNIK_EASY(4491), + DIARY_FREMENNIK_MEDIUM(4492), + DIARY_FREMENNIK_HARD(4493), + DIARY_FREMENNIK_ELITE(4494), - DIARY_KANDARIN_EASY(4475), - DIARY_KANDARIN_MEDIUM(4476), - DIARY_KANDARIN_HARD(4477), - DIARY_KANDARIN_ELITE(4478), + DIARY_KANDARIN_EASY(4475), + DIARY_KANDARIN_MEDIUM(4476), + DIARY_KANDARIN_HARD(4477), + DIARY_KANDARIN_ELITE(4478), - DIARY_KARAMJA_EASY(3578), - DIARY_KARAMJA_MEDIUM(3599), - DIARY_KARAMJA_HARD(3611), - DIARY_KARAMJA_ELITE(4566), + DIARY_KARAMJA_EASY(3578), + DIARY_KARAMJA_MEDIUM(3599), + DIARY_KARAMJA_HARD(3611), + DIARY_KARAMJA_ELITE(4566), - DIARY_LUMBRIDGE_EASY(4495), - DIARY_LUMBRIDGE_MEDIUM(4496), - DIARY_LUMBRIDGE_HARD(4497), - DIARY_LUMBRIDGE_ELITE(4498), + DIARY_LUMBRIDGE_EASY(4495), + DIARY_LUMBRIDGE_MEDIUM(4496), + DIARY_LUMBRIDGE_HARD(4497), + DIARY_LUMBRIDGE_ELITE(4498), - DIARY_MORYTANIA_EASY(4487), - DIARY_MORYTANIA_MEDIUM(4488), - DIARY_MORYTANIA_HARD(4489), - DIARY_MORYTANIA_ELITE(4490), + DIARY_MORYTANIA_EASY(4487), + DIARY_MORYTANIA_MEDIUM(4488), + DIARY_MORYTANIA_HARD(4489), + DIARY_MORYTANIA_ELITE(4490), - DIARY_VARROCK_EASY(4479), - DIARY_VARROCK_MEDIUM(4480), - DIARY_VARROCK_HARD(4481), - DIARY_VARROCK_ELITE(4482), + DIARY_VARROCK_EASY(4479), + DIARY_VARROCK_MEDIUM(4480), + DIARY_VARROCK_HARD(4481), + DIARY_VARROCK_ELITE(4482), - DIARY_WESTERN_EASY(4471), - DIARY_WESTERN_MEDIUM(4472), - DIARY_WESTERN_HARD(4473), - DIARY_WESTERN_ELITE(4474), + DIARY_WESTERN_EASY(4471), + DIARY_WESTERN_MEDIUM(4472), + DIARY_WESTERN_HARD(4473), + DIARY_WESTERN_ELITE(4474), - DIARY_WILDERNESS_EASY(4466), - DIARY_WILDERNESS_MEDIUM(4467), - DIARY_WILDERNESS_HARD(4468), - DIARY_WILDERNESS_ELITE(4469), + DIARY_WILDERNESS_EASY(4466), + DIARY_WILDERNESS_MEDIUM(4467), + DIARY_WILDERNESS_HARD(4468), + DIARY_WILDERNESS_ELITE(4469), - /** - * Kourend house favours - */ - KOUREND_FAVOR_ARCEUUS(4896), - KOUREND_FAVOR_HOSIDIUS(4895), - KOUREND_FAVOR_LOVAKENGJ(4898), - KOUREND_FAVOR_PISCARILIUS(4899), - KOUREND_FAVOR_SHAYZIEN(4894), + /** + * Kourend house favours + */ + KOUREND_FAVOR_ARCEUUS(4896), + KOUREND_FAVOR_HOSIDIUS(4895), + KOUREND_FAVOR_LOVAKENGJ(4898), + KOUREND_FAVOR_PISCARILIUS(4899), + KOUREND_FAVOR_SHAYZIEN(4894), - /** - * Equipped weapon type - */ - EQUIPPED_WEAPON_TYPE(357), + /** + * Equipped weapon type + */ + EQUIPPED_WEAPON_TYPE(357), - /** - * Defensive casting mode - */ - DEFENSIVE_CASTING_MODE(2668), + /** + * Defensive casting mode + */ + DEFENSIVE_CASTING_MODE(2668), - /** - * Options - */ - SIDE_PANELS(4607), + /** + * Options + */ + SIDE_PANELS(4607), - /** - * Herbiboar Trails - */ - HB_TRAIL_31303(5737), - HB_TRAIL_31306(5738), - HB_TRAIL_31309(5739), - HB_TRAIL_31312(5740), - HB_TRAIL_31315(5741), - HB_TRAIL_31318(5742), - HB_TRAIL_31321(5743), - HB_TRAIL_31324(5744), - HB_TRAIL_31327(5745), - HB_TRAIL_31330(5746), + /** + * Herbiboar Trails + */ + HB_TRAIL_31303(5737), + HB_TRAIL_31306(5738), + HB_TRAIL_31309(5739), + HB_TRAIL_31312(5740), + HB_TRAIL_31315(5741), + HB_TRAIL_31318(5742), + HB_TRAIL_31321(5743), + HB_TRAIL_31324(5744), + HB_TRAIL_31327(5745), + HB_TRAIL_31330(5746), - HB_TRAIL_31333(5768), - HB_TRAIL_31336(5769), - HB_TRAIL_31339(5770), - HB_TRAIL_31342(5771), - HB_TRAIL_31345(5772), - HB_TRAIL_31348(5773), - HB_TRAIL_31351(5774), - HB_TRAIL_31354(5775), - HB_TRAIL_31357(5776), - HB_TRAIL_31360(5777), + HB_TRAIL_31333(5768), + HB_TRAIL_31336(5769), + HB_TRAIL_31339(5770), + HB_TRAIL_31342(5771), + HB_TRAIL_31345(5772), + HB_TRAIL_31348(5773), + HB_TRAIL_31351(5774), + HB_TRAIL_31354(5775), + HB_TRAIL_31357(5776), + HB_TRAIL_31360(5777), - HB_TRAIL_31363(5747), - HB_TRAIL_31366(5748), - HB_TRAIL_31369(5749), - HB_TRAIL_31372(5750), + HB_TRAIL_31363(5747), + HB_TRAIL_31366(5748), + HB_TRAIL_31369(5749), + HB_TRAIL_31372(5750), - HB_FINISH(5766), - HB_STARTED(5767), //not working + HB_FINISH(5766), + HB_STARTED(5767), //not working - /** - * Barbarian Assault - */ - IN_GAME_BA(3923), + /** + * Barbarian Assault + */ + IN_GAME_BA(3923), - /** - * 0 = Outside wilderness - * 1 = In wilderness - */ - IN_WILDERNESS(5963), + /** + * 0 = Outside wilderness + * 1 = In wilderness + */ + IN_WILDERNESS(5963), - /** - * Fishing Trawler - * FISHING_TRAWLER_ACTIVITY Expected values: 0-255 - */ - FISHING_TRAWLER_ACTIVITY(3377), + /** + * Fishing Trawler + * FISHING_TRAWLER_ACTIVITY Expected values: 0-255 + */ + FISHING_TRAWLER_ACTIVITY(3377), - /** - * Blast Furnace Bar Dispenser - * - * These are the expected values: - * 0 = No bars being processed - * 1 = Ores are being processed on the conveyor belt, bar dispenser cannot be checked - * 2 = Bars are cooling down - * 3 = Bars can be collected - */ - BAR_DISPENSER(936), + /** + * Blast Furnace Bar Dispenser + *

+ * These are the expected values: + * 0 = No bars being processed + * 1 = Ores are being processed on the conveyor belt, bar dispenser cannot be checked + * 2 = Bars are cooling down + * 3 = Bars can be collected + */ + BAR_DISPENSER(936), - /** - * Motherlode mine sack - */ - SACK_NUMBER(5558), - SACK_UPGRADED(5556), + /** + * Motherlode mine sack + */ + SACK_NUMBER(5558), + SACK_UPGRADED(5556), - /** - * Experience tracker - * - * EXPERIENCE_TRACKER_POSITION expected values: - * 0 = Right - * 1 = Middle - * 2 = Left - */ - EXPERIENCE_TRACKER_POSITION(4692), - EXPERIENCE_TRACKER_COUNTER(4697), - EXPERIENCE_TRACKER_PROGRESS_BAR(4698), + /** + * Experience tracker + *

+ * EXPERIENCE_TRACKER_POSITION expected values: + * 0 = Right + * 1 = Middle + * 2 = Left + */ + EXPERIENCE_TRACKER_POSITION(4692), + EXPERIENCE_TRACKER_COUNTER(4697), + EXPERIENCE_TRACKER_PROGRESS_BAR(4698), - /** - * Experience drop color - */ - EXPERIENCE_DROP_COLOR(4695), + /** + * Experience drop color + */ + EXPERIENCE_DROP_COLOR(4695), - /** - * Tithe Farm - */ - TITHE_FARM_SACK_AMOUNT(4900), - TITHE_FARM_SACK_ICON(5370), - TITHE_FARM_POINTS(4893), - - /** - * Blast Mine - */ - BLAST_MINE_COAL(4924), - BLAST_MINE_GOLD(4925), - BLAST_MINE_MITHRIL(4926), - BLAST_MINE_ADAMANTITE(4921), - BLAST_MINE_RUNITE(4922), + /** + * Tithe Farm + */ + TITHE_FARM_SACK_AMOUNT(4900), + TITHE_FARM_SACK_ICON(5370), + TITHE_FARM_POINTS(4893), - /** - * Raids - */ - IN_RAID(5432), - TOTAL_POINTS(5431), - PERSONAL_POINTS(5422), - RAID_PARTY_SIZE(5424), + /** + * Blast Mine + */ + BLAST_MINE_COAL(4924), + BLAST_MINE_GOLD(4925), + BLAST_MINE_MITHRIL(4926), + BLAST_MINE_ADAMANTITE(4921), + BLAST_MINE_RUNITE(4922), - /** - * Theatre of Blood 1=In Party, 2=Inside/Spectator, 3=Dead Spectating - */ - THEATRE_OF_BLOOD(6440), + /** + * Raids + */ + IN_RAID(5432), + TOTAL_POINTS(5431), + PERSONAL_POINTS(5422), + RAID_PARTY_SIZE(5424), - /** - * Nightmare Zone - */ - NMZ_ABSORPTION(3956), - NMZ_POINTS(3949), + /** + * Theatre of Blood 1=In Party, 2=Inside/Spectator, 3=Dead Spectating + */ + THEATRE_OF_BLOOD(6440), - /** - * Blast Furnace - */ - BLAST_FURNACE_COPPER_ORE(959), - BLAST_FURNACE_TIN_ORE(950), - BLAST_FURNACE_IRON_ORE(951), - BLAST_FURNACE_COAL(949), - BLAST_FURNACE_MITHRIL_ORE(952), - BLAST_FURNACE_ADAMANTITE_ORE(953), - BLAST_FURNACE_RUNITE_ORE(954), - BLAST_FURNACE_SILVER_ORE(956), - BLAST_FURNACE_GOLD_ORE(955), + /** + * Nightmare Zone + */ + NMZ_ABSORPTION(3956), + NMZ_POINTS(3949), - BLAST_FURNACE_BRONZE_BAR(941), - BLAST_FURNACE_IRON_BAR(942), - BLAST_FURNACE_STEEL_BAR(943), - BLAST_FURNACE_MITHRIL_BAR(944), - BLAST_FURNACE_ADAMANTITE_BAR(945), - BLAST_FURNACE_RUNITE_BAR(946), - BLAST_FURNACE_SILVER_BAR(948), - BLAST_FURNACE_GOLD_BAR(947), + /** + * Blast Furnace + */ + BLAST_FURNACE_COPPER_ORE(959), + BLAST_FURNACE_TIN_ORE(950), + BLAST_FURNACE_IRON_ORE(951), + BLAST_FURNACE_COAL(949), + BLAST_FURNACE_MITHRIL_ORE(952), + BLAST_FURNACE_ADAMANTITE_ORE(953), + BLAST_FURNACE_RUNITE_ORE(954), + BLAST_FURNACE_SILVER_ORE(956), + BLAST_FURNACE_GOLD_ORE(955), - BLAST_FURNACE_COFFER(5357), + BLAST_FURNACE_BRONZE_BAR(941), + BLAST_FURNACE_IRON_BAR(942), + BLAST_FURNACE_STEEL_BAR(943), + BLAST_FURNACE_MITHRIL_BAR(944), + BLAST_FURNACE_ADAMANTITE_BAR(945), + BLAST_FURNACE_RUNITE_BAR(946), + BLAST_FURNACE_SILVER_BAR(948), + BLAST_FURNACE_GOLD_BAR(947), - /** - * Pyramid plunder - */ - PYRAMID_PLUNDER_TIMER(2375), - PYRAMID_PLUNDER_ROOM(2377), + BLAST_FURNACE_COFFER(5357), - /** - * Barrows - */ - BARROWS_KILLED_AHRIM(457), - BARROWS_KILLED_DHAROK(458), - BARROWS_KILLED_GUTHAN(459), - BARROWS_KILLED_KARIL(460), - BARROWS_KILLED_TORAG(461), - BARROWS_KILLED_VERAC(462), - BARROWS_REWARD_POTENTIAL(463), - BARROWS_NPCS_SLAIN(464), + /** + * Pyramid plunder + */ + PYRAMID_PLUNDER_TIMER(2375), + PYRAMID_PLUNDER_ROOM(2377), - /** - * Spicy stew ingredients - */ - SPICY_STEW_RED_SPICES(1879), - SPICY_STEW_YELLOW_SPICES(1880), - SPICY_STEW_BROWN_SPICES(1881), - SPICY_STEW_ORANGE_SPICES(1882), + /** + * Barrows + */ + BARROWS_KILLED_AHRIM(457), + BARROWS_KILLED_DHAROK(458), + BARROWS_KILLED_GUTHAN(459), + BARROWS_KILLED_KARIL(460), + BARROWS_KILLED_TORAG(461), + BARROWS_KILLED_VERAC(462), + BARROWS_REWARD_POTENTIAL(463), + BARROWS_NPCS_SLAIN(464), - /** - * Multicombat area - */ - MULTICOMBAT_AREA(4605), + /** + * Spicy stew ingredients + */ + SPICY_STEW_RED_SPICES(1879), + SPICY_STEW_YELLOW_SPICES(1880), + SPICY_STEW_BROWN_SPICES(1881), + SPICY_STEW_ORANGE_SPICES(1882), - /** - * In the Wilderness - */ - IN_THE_WILDERNESS(5963), + /** + * Multicombat area + */ + MULTICOMBAT_AREA(4605), - /** - * Kingdom Management - */ - KINGDOM_FAVOR(72), - KINGDOM_COFFER(74), + /** + * In the Wilderness + */ + IN_THE_WILDERNESS(5963), - /** - * The Hand in the Sand quest status - */ - QUEST_THE_HAND_IN_THE_SAND(1527), + /** + * Kingdom Management + */ + KINGDOM_FAVOR(72), + KINGDOM_COFFER(74), - /** - * Daily Tasks (Collection availability) - */ - DAILY_HERB_BOXES_COLLECTED(3961), - DAILY_STAVES_COLLECTED(4539), - DAILY_ESSENCE_COLLECTED(4547), - DAILY_RUNES_COLLECTED(4540), - DAILY_SAND_COLLECTED(4549), - DAILY_FLAX_STATE(4559), - /** - * This varbit tracks how much bonemeal has been redeemed from Robin - * The player gets 13 for each diary completed above and including Medium, for a maxiumum of 39 - */ - DAILY_BONEMEAL_STATE(4543), + /** + * The Hand in the Sand quest status + */ + QUEST_THE_HAND_IN_THE_SAND(1527), - /** - * Fairy Ring - */ - FAIR_RING_LAST_DESTINATION(5374), - FAIRY_RING_DIAL_ADCB(3985), //Left dial - FAIRY_RIGH_DIAL_ILJK(3986), //Middle dial - FAIRY_RING_DIAL_PSRQ(3987), //Right dial + /** + * Daily Tasks (Collection availability) + */ + DAILY_HERB_BOXES_COLLECTED(3961), + DAILY_STAVES_COLLECTED(4539), + DAILY_ESSENCE_COLLECTED(4547), + DAILY_RUNES_COLLECTED(4540), + DAILY_SAND_COLLECTED(4549), + DAILY_FLAX_STATE(4559), + /** + * This varbit tracks how much bonemeal has been redeemed from Robin + * The player gets 13 for each diary completed above and including Medium, for a maxiumum of 39 + */ + DAILY_BONEMEAL_STATE(4543), - /** - * Transmog controllers for farming - */ - FARMING_4771(4771), - FARMING_4772(4772), - FARMING_4773(4773), - FARMING_4774(4774), - FARMING_4775(4775), - FARMING_7904(7904), - FARMING_7905(7905), - FARMING_7906(7906), - FARMING_7907(7907), - FARMING_7908(7908), - FARMING_7909(7909), - FARMING_7910(7910), - FARMING_7911(7911), + /** + * Fairy Ring + */ + FAIR_RING_LAST_DESTINATION(5374), + FAIRY_RING_DIAL_ADCB(3985), //Left dial + FAIRY_RIGH_DIAL_ILJK(3986), //Middle dial + FAIRY_RING_DIAL_PSRQ(3987), //Right dial - /** - * Transmog controllers for grapes - */ - GRAPES_4953(4953), - GRAPES_4954(4954), - GRAPES_4955(4955), - GRAPES_4956(4956), - GRAPES_4957(4957), - GRAPES_4958(4958), - GRAPES_4959(4959), - GRAPES_4960(4960), - GRAPES_4961(4961), - GRAPES_4962(4962), - GRAPES_4963(4963), - GRAPES_4964(4964), + /** + * Transmog controllers for farming + */ + FARMING_4771(4771), + FARMING_4772(4772), + FARMING_4773(4773), + FARMING_4774(4774), + FARMING_4775(4775), + FARMING_7904(7904), + FARMING_7905(7905), + FARMING_7906(7906), + FARMING_7907(7907), + FARMING_7908(7908), + FARMING_7909(7909), + FARMING_7910(7910), + FARMING_7911(7911), - /** - * Automatically weed farming patches - */ - AUTOWEED(5557), + /** + * Transmog controllers for grapes + */ + GRAPES_4953(4953), + GRAPES_4954(4954), + GRAPES_4955(4955), + GRAPES_4956(4956), + GRAPES_4957(4957), + GRAPES_4958(4958), + GRAPES_4959(4959), + GRAPES_4960(4960), + GRAPES_4961(4961), + GRAPES_4962(4962), + GRAPES_4963(4963), + GRAPES_4964(4964), - /** - * The varbit that stores the players {@code AccountType}. - */ - ACCOUNT_TYPE(1777), + /** + * Automatically weed farming patches + */ + AUTOWEED(5557), - /** - * The varbit that stores the oxygen percentage for player - */ - OXYGEN_LEVEL(5811), - - /** - * Corp beast damage - */ - CORP_DAMAGE(999), + /** + * The varbit that stores the players {@code AccountType}. + */ + ACCOUNT_TYPE(1777), - /** - * Toggleable slayer unlocks - */ - SUPERIOR_ENABLED(5362), - FOSSIL_ISLAND_WYVERN_DISABLE(6251), + /** + * The varbit that stores the oxygen percentage for player + */ + OXYGEN_LEVEL(5811), - CURRENT_BANK_TAB(4150), + /** + * Corp beast damage + */ + CORP_DAMAGE(999), - WORLDHOPPER_FAVROITE_1(4597), - WORLDHOPPER_FAVROITE_2(4598), + /** + * Toggleable slayer unlocks + */ + SUPERIOR_ENABLED(5362), + FOSSIL_ISLAND_WYVERN_DISABLE(6251), - /** - * Vengeance is active - */ - VENGEANCE_ACTIVE(2450), + CURRENT_BANK_TAB(4150), - /** - * Spell cooldowns - */ - VENGEANCE_COOLDOWN(2451), + WORLDHOPPER_FAVROITE_1(4597), + WORLDHOPPER_FAVROITE_2(4598), - /** - * Amount of items in each bank tab - */ - BANK_TAB_ONE_COUNT(4171), - BANK_TAB_TWO_COUNT(4172), - BANK_TAB_THREE_COUNT(4173), - BANK_TAB_FOUR_COUNT(4174), - BANK_TAB_FIVE_COUNT(4175), - BANK_TAB_SIX_COUNT(4176), - BANK_TAB_SEVEN_COUNT(4177), - BANK_TAB_EIGHT_COUNT(4178), - BANK_TAB_NINE_COUNT(4179), + /** + * Vengeance is active + */ + VENGEANCE_ACTIVE(2450), - /** - * Type of GE offer currently being created - * 0 = buy - * 1 = sell - */ - GE_OFFER_CREATION_TYPE(4397), + /** + * Spell cooldowns + */ + VENGEANCE_COOLDOWN(2451), - /** - * The active tab within the quest interface - */ - QUEST_TAB(8168), - - /** - * Temple Trekking - */ - TREK_POINTS(1955), - TREK_STARTED(1956), - TREK_EVENT(1958), - TREK_STATUS(6719); + /** + * Amount of items in each bank tab + */ + BANK_TAB_ONE_COUNT(4171), + BANK_TAB_TWO_COUNT(4172), + BANK_TAB_THREE_COUNT(4173), + BANK_TAB_FOUR_COUNT(4174), + BANK_TAB_FIVE_COUNT(4175), + BANK_TAB_SIX_COUNT(4176), + BANK_TAB_SEVEN_COUNT(4177), + BANK_TAB_EIGHT_COUNT(4178), + BANK_TAB_NINE_COUNT(4179), + /** + * Type of GE offer currently being created + * 0 = buy + * 1 = sell + */ + GE_OFFER_CREATION_TYPE(4397), - /** - * The raw varbit ID. - */ - private final int id; + /** + * The active tab within the quest interface + */ + QUEST_TAB(8168), + + /** + * Temple Trekking + */ + TREK_POINTS(1955), + TREK_STARTED(1956), + TREK_EVENT(1958), + TREK_STATUS(6719), + BLOAT_ENTERED_ROOM(6447); + + /** + * The raw varbit ID. + */ + private final int id; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java index e630c28b4f..1d54442c6d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java @@ -44,7 +44,6 @@ public class EquipmentInspectorPanel extends PluginPanel c.weightx = 1; c.gridx = 0; c.gridy = 0; - header = new JPanel(); header.setLayout(new BorderLayout()); header.setBorder(new CompoundBorder( @@ -53,9 +52,7 @@ public class EquipmentInspectorPanel extends PluginPanel nameLabel = new JLabel(NO_PLAYER_SELECTED); nameLabel.setForeground(Color.WHITE); - header.add(nameLabel, BorderLayout.CENTER); - layout.setHorizontalGroup(layout.createParallelGroup() .addComponent(equipmentPanels) .addComponent(header) @@ -65,7 +62,6 @@ public class EquipmentInspectorPanel extends PluginPanel .addGap(10) .addComponent(equipmentPanels) ); - update(new HashMap<>(), ""); } @@ -79,7 +75,6 @@ public class EquipmentInspectorPanel extends PluginPanel { nameLabel.setText("Player: " + playerName); } - SwingUtilities.invokeLater(() -> { equipmentPanels.removeAll(); 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 5ea9ea76b6..29904c2fb8 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 @@ -3,7 +3,10 @@ package net.runelite.client.plugins.equipmentinspector; import com.google.inject.Provides; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.*; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.ItemComposition; +import net.runelite.api.Player; import net.runelite.api.events.PlayerMenuOptionClicked; import net.runelite.api.kit.KitType; import net.runelite.client.chat.ChatColorType; @@ -18,11 +21,10 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; +import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; -import net.runelite.http.api.item.ItemPrice; import javax.annotation.Nullable; -import javax.imageio.ImageIO; import javax.inject.Inject; import javax.swing.*; import java.awt.image.BufferedImage; @@ -32,211 +34,195 @@ import java.util.*; import java.util.concurrent.ScheduledExecutorService; @PluginDescriptor( - name = "Equipment Inspector", - description = "Inspects enemy equipment", - enabledByDefault = false, - type = "utility" + name = "Equipment Inspector", + enabledByDefault = false, + type = "utility" ) @Slf4j public class EquipmentInspectorPlugin extends Plugin { - private static final String INSPECT_EQUIPMENT = "Gear"; - private static final String KICK_OPTION = "Kick"; + private static final String INSPECT_EQUIPMENT = "Gear"; + private static final String KICK_OPTION = "Kick"; - @Inject - @Nullable - private Client client; + @Inject + @Nullable + private Client client; - @Inject - private ItemManager itemManager; + @Inject + private ItemManager itemManager; - @Inject - private EquipmentInspectorConfig config; + @Inject + private EquipmentInspectorConfig config; - @Inject - private ChatMessageManager chatMessageManager; - @Inject - private MenuManager menuManager; + @Inject + private ChatMessageManager chatMessageManager; + @Inject + private MenuManager menuManager; - @Inject - private ScheduledExecutorService executor; + @Inject + private ScheduledExecutorService executor; - @Inject - private ClientToolbar pluginToolbar; + @Inject + private ClientToolbar pluginToolbar; + private NavigationButton navButton; + private EquipmentInspectorPanel equipmentInspectorPanel; + private int TotalPrice = 0; + private int Prot1 = 0; + private int Prot2 = 0; + private int Prot3 = 0; + private int Prot4 = 0; - @Provides - EquipmentInspectorConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(EquipmentInspectorConfig.class); - } + @Provides + EquipmentInspectorConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(EquipmentInspectorConfig.class); + } - private NavigationButton navButton; - private EquipmentInspectorPanel equipmentInspectorPanel; - private int TotalPrice = 0; - private int Prot1 = 0; - private int Prot2 = 0; - private int Prot3 = 0; - private int Prot4 = 0; + @Override + protected void startUp() throws Exception { + + equipmentInspectorPanel = injector.getInstance(EquipmentInspectorPanel.class); + if (client != null) { + menuManager.addPlayerMenuItem(INSPECT_EQUIPMENT); + } + + //synchronized (ImageIO.class) + //{ + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(this.getClass(), "normal.png"); + //} + + navButton = NavigationButton.builder() + .tooltip("Equipment Inspector") + .icon(icon) + .priority(5) + .panel(equipmentInspectorPanel) + .build(); - @Override - protected void startUp() throws Exception - { + pluginToolbar.addNavigation(navButton); - equipmentInspectorPanel = injector.getInstance(EquipmentInspectorPanel.class); - if(client != null) { - menuManager.addPlayerMenuItem(INSPECT_EQUIPMENT); - } + } - BufferedImage icon; - synchronized (ImageIO.class) - { - icon = ImageIO.read(getClass().getResourceAsStream("normal.png")); - } + @Override + protected void shutDown() throws Exception { - navButton = NavigationButton.builder() - .tooltip("Equipment Inspector") - .icon(icon) - .priority(5) - .panel(equipmentInspectorPanel) - .build(); + menuManager.removePlayerMenuItem(INSPECT_EQUIPMENT); + } + + @Subscribe + public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) { + if (event.getMenuOption().equals(INSPECT_EQUIPMENT)) { - pluginToolbar.addNavigation(navButton); + executor.execute(() -> + { + try { + SwingUtilities.invokeAndWait(() -> + { + if (!navButton.isSelected()) { + navButton.getOnSelect().run(); + } + }); + } catch (InterruptedException | InvocationTargetException e) { - } + throw new RuntimeException(e); - @Override - protected void shutDown() throws Exception - { + } + String playerName = Text.removeTags(event.getMenuTarget()); + // The player menu uses a non-breaking space in the player name, we need to replace this to compare + // against the playerName in the player cache. + String finalPlayerName = playerName.replace('\u00A0', ' '); + System.out.println(finalPlayerName); + List players = client.getPlayers(); + Optional targetPlayer = players.stream() + .filter(Objects::nonNull) + .filter(p -> p.getName().equals(finalPlayerName)).findFirst(); - menuManager.removePlayerMenuItem(INSPECT_EQUIPMENT); - } + if (targetPlayer.isPresent()) { + TotalPrice = 0; + Prot1 = 0; + Prot2 = 0; + Prot3 = 0; + Prot4 = 0; + Player p = targetPlayer.get(); + Map playerEquipment = new HashMap<>(); - @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) - { - if (event.getMenuOption().equals(INSPECT_EQUIPMENT)) - { + for (KitType kitType : KitType.values()) { + int itemId = p.getPlayerComposition().getEquipmentId(kitType); + if (itemId != -1) { + ItemComposition itemComposition = client.getItemDefinition(itemId); + playerEquipment.put(kitType, itemComposition); + int ItemPrice = itemManager.getItemPrice(itemId); + TotalPrice += ItemPrice; + if (ItemPrice > Prot1) { + Prot4 = Prot3; + Prot3 = Prot2; + Prot2 = Prot1; + Prot1 = ItemPrice; + } else if (ItemPrice > Prot2) { + Prot4 = Prot3; + Prot3 = Prot2; + Prot2 = ItemPrice; + } else if (ItemPrice > Prot3) { + Prot4 = Prot3; + Prot3 = ItemPrice; + } else if (ItemPrice > Prot4) { + Prot4 = ItemPrice; + } + } + } + int IgnoredItems = config.protecteditems(); + if (IgnoredItems != 0 && IgnoredItems != 1 && IgnoredItems != 2 && IgnoredItems != 3) { + IgnoredItems = 4; - executor.execute(() -> - { - try - { - SwingUtilities.invokeAndWait(() -> - { - if (!navButton.isSelected()) - { - navButton.getOnSelect().run(); - } - }); - } - catch (InterruptedException | InvocationTargetException e) - { + } + if (config.ShowValue()) { + switch (IgnoredItems) { + case 1: + TotalPrice = TotalPrice - Prot1; + break; + case 2: + TotalPrice = TotalPrice - Prot1; + TotalPrice = TotalPrice - Prot2; - throw new RuntimeException(e); + break; + case 3: + TotalPrice = TotalPrice - Prot1; + TotalPrice = TotalPrice - Prot2; + TotalPrice = TotalPrice - Prot3; + break; + case 4: + TotalPrice = TotalPrice - Prot1; + TotalPrice = TotalPrice - Prot2; + TotalPrice = TotalPrice - Prot3; + TotalPrice = TotalPrice - Prot4; + break; + } + String StringPrice = ""; + if (!config.ExactValue()) { + TotalPrice = TotalPrice / 1000; + StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); + StringPrice = StringPrice + 'K'; + } + if (config.ExactValue()) { + StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); + } + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.FRIENDSCHATNOTIFICATION) + .runeLiteFormattedMessage(new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append("Risked Value: ") + .append(ChatColorType.NORMAL) + .append(StringPrice) + .build()) + .build()); + } + equipmentInspectorPanel.update(playerEquipment, playerName); - } - String playerName = Text.removeTags(event.getMenuTarget()); - // The player menu uses a non-breaking space in the player name, we need to replace this to compare - // against the playerName in the player cache. - String finalPlayerName = playerName.replace('\u00A0', ' '); - System.out.println(finalPlayerName); - List players = client.getPlayers(); - Optional targetPlayer = players.stream() - .filter(Objects::nonNull) - .filter(p -> p.getName().equals(finalPlayerName)).findFirst(); - - if (targetPlayer.isPresent()) - { - TotalPrice = 0; - Prot1 = 0; - Prot2 = 0; - Prot3 = 0; - Prot4 = 0; - Player p = targetPlayer.get(); - Map playerEquipment = new HashMap<>(); - - for (KitType kitType : KitType.values()) - { - int itemId = p.getPlayerComposition().getEquipmentId(kitType); - if (itemId != -1) - { - ItemComposition itemComposition = client.getItemDefinition(itemId); - playerEquipment.put(kitType, itemComposition); - int ItemPrice = itemManager.getItemPrice(itemId); - TotalPrice += ItemPrice; - if (ItemPrice > Prot1 ) { - Prot4 = Prot3; - Prot3 = Prot2; - Prot2 = Prot1; - - Prot1 = ItemPrice; - } else if (ItemPrice > Prot2){ - Prot4 = Prot3; - Prot3 = Prot2; - Prot2 = ItemPrice; - } else if (ItemPrice > Prot3){ - Prot4 = Prot3; - Prot3 = ItemPrice; - } else if (ItemPrice > Prot4){ - Prot4 = ItemPrice; - } - } - } - int IgnoredItems = config.protecteditems(); - if (IgnoredItems != 0 && IgnoredItems != 1 && IgnoredItems != 2 && IgnoredItems != 3) { - IgnoredItems = 4; - - } - if (config.ShowValue()) { - switch (IgnoredItems) { - case 1: - TotalPrice = TotalPrice - Prot1; - break; - case 2: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - - break; - case 3: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - TotalPrice = TotalPrice - Prot3; - break; - case 4: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - TotalPrice = TotalPrice - Prot3; - TotalPrice = TotalPrice - Prot4; - break; - } - String StringPrice = ""; - if (!config.ExactValue()) { - TotalPrice = TotalPrice / 1000; - StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); - StringPrice = StringPrice + 'K'; - } - if (config.ExactValue()) { - StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); - } - chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.FRIENDSCHATNOTIFICATION) - .runeLiteFormattedMessage(new ChatMessageBuilder() - .append(ChatColorType.HIGHLIGHT) - .append("Risked Value: ") - .append(ChatColorType.NORMAL) - .append(StringPrice) - .build()) - .build()); - } - equipmentInspectorPanel.update(playerEquipment, playerName); - - } - }); - } - } -} + } + }); + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java index 873bf058b6..fadc684588 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java @@ -15,7 +15,8 @@ class ItemPanel extends JPanel ItemPanel(ItemComposition item, KitType kitType, AsyncBufferedImage icon) { - setBorder(new EmptyBorder(3, 3, 3, 3)); + + setBorder(new EmptyBorder(3, 3, 3, 3)); setBackground(ColorScheme.DARK_GRAY_COLOR); GroupLayout layout = new GroupLayout(this); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java new file mode 100644 index 0000000000..fec801ab51 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java @@ -0,0 +1,83 @@ +package net.runelite.client.plugins.ztob; + +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.*; + +import javax.inject.Inject; +import java.awt.*; + +public class BloatTimerOverlay extends Overlay { + + private final Client client; + private final TheatrePlugin plugin; + private final TheatreConfig config; + + @Inject + private BloatTimerOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) { + this.client = client; + this.plugin = plugin; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + public Dimension render(Graphics2D graphics) { + + if (config.bloatTimer()) { + final String tickCounter = String.valueOf(plugin.bloatTimer); + int secondConversion = (int) (plugin.bloatTimer * .6); + if (plugin.getBloat_NPC() != null) { + Point canvasPoint = plugin.getBloat_NPC().getCanvasTextLocation(graphics, tickCounter, 60); + if (plugin.bloatTimer <= 37) { + renderTextLocation(graphics, tickCounter + "( " + secondConversion + " )", 15, Font.BOLD, Color.WHITE, canvasPoint); + } else { + renderTextLocation(graphics, tickCounter + "( " + secondConversion + " )", 15, Font.BOLD, Color.RED, canvasPoint); + } + } + } + + + return null; + } + + private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) { + WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); + if (point.distanceTo(playerLocation) >= 32) { + return; + } + LocalPoint lp = LocalPoint.fromWorld(client, point); + if (lp == null) { + return; + } + + Polygon poly = Perspective.getCanvasTilePoly(client, lp); + if (poly == null) { + return; + } + //OverlayUtil.renderPolygon(graphics, poly, color); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); + graphics.setStroke(new BasicStroke(strokeWidth)); + graphics.draw(poly); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); + graphics.fill(poly); + } + + private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, net.runelite.api.Point canvasPoint) { + graphics.setFont(new Font("Arial", fontStyle, fontSize)); + if (canvasPoint != null) { + final net.runelite.api.Point canvasCenterPoint = new net.runelite.api.Point( + canvasPoint.getX(), + canvasPoint.getY()); + final net.runelite.api.Point canvasCenterPoint_shadow = new Point( + canvasPoint.getX() + 1, + canvasPoint.getY() + 1); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java index 6f63951785..0a0a33d982 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java @@ -14,15 +14,16 @@ import net.runelite.client.config.ConfigItem; @ConfigGroup("Theatre") -public interface TheatreConfig extends Config -{ +public interface TheatreConfig extends Config { @ConfigItem( position = 0, keyName = "MaidenBlood", name = "Maiden blood attack", description = "" ) - default boolean MaidenBlood(){ return false; } + default boolean MaidenBlood() { + return true; + } @ConfigItem( position = 1, @@ -30,109 +31,181 @@ public interface TheatreConfig extends Config name = "Maiden blood spawns", description = "" ) - default boolean MaidenSpawns(){ return false; } + default boolean MaidenSpawns() { + return true; + } @ConfigItem( position = 2, keyName = "BloatIndicator", - name = "Bloat indicator", + name = "Bloat Indicator", description = "" ) - default boolean BloatIndicator(){ return false; } + default boolean BloatIndicator() { + return true; + } @ConfigItem( position = 3, - keyName = "BloatHands", - name = "Bloat Falling Hands", + keyName = "bloat Timer", + name = "Bloat Timer", description = "" ) - default boolean BloatHands(){ return false; } + default boolean bloatTimer() { + return true; + } @ConfigItem( position = 4, + keyName = "bloatFeet", + name = "Bloat Feet", + description = "" + ) + default boolean bloatFeetIndicator() { + return true; + } + + @ConfigItem( + position = 5, keyName = "NyloPillars", name = "Nylocas pillar health", description = "" ) - default boolean NyloPillars(){ return false; } + default boolean NyloPillars() { + return true; + } + @ConfigItem( - position = 5, + position = 6, keyName = "NyloBlasts", name = "Nylocas explosions", description = "" ) - default boolean NyloBlasts(){ return false; } + default boolean NyloBlasts() { + return true; + } @ConfigItem( - position = 6, + position = 7, + keyName = "NyloMenu", + name = "Hide Attack options for Nylocas", + description = "" + ) + + default boolean NyloMenu() { + return true; + } + + @ConfigItem( + position = 8, keyName = "SotetsegMaze1", name = "Sotetseg maze", description = "" ) - default boolean SotetsegMaze1(){ return false; } + default boolean SotetsegMaze1() { + return true; + } @ConfigItem( - position = 7, + position = 9, keyName = "SotetsegMaze2", name = "Sotetseg maze (solo mode)", description = "" ) - default boolean SotetsegMaze2(){ return false; } - - @ConfigItem( - position = 8, - keyName = "SotetsegTick", - name = "Sotetseg tick eat", - description = "" - ) - default boolean SotetsegTick(){ return false; } - - @ConfigItem( - position = 9, - keyName = "XarpusExhumed", - name = "Xarpus exhumed", - description = "" - ) - default boolean XarpusExhumed(){ return false; } + default boolean SotetsegMaze2() { + return true; + } @ConfigItem( position = 10, - keyName = "XarpusTick", - name = "Xarpus tick", + keyName = "XarpusExhumed", + name = "Xarpus Exhumed", description = "" ) - default boolean XarpusTick(){ return false; } + default boolean XarpusExhumed() { + return true; + } @ConfigItem( position = 11, - keyName = "VerzikCupcakes", - name = "Verzik cupcakes", - description = " " + keyName = "XarpusTick", + name = "Xarpus Tick", + description = "" ) - default boolean VerzikCupcakes(){ return false; } + default boolean XarpusTick() { + return false; + } @ConfigItem( position = 12, - keyName = "VerzikTick", - name = "Verzik p3 tick", + keyName = "xarpusExhumes", + name = "Xarpus Exhume Counter", description = "" ) - default boolean VerzikTick(){ return false; } + default boolean XarpusExhumeOverlay() { + return false; + } @ConfigItem( position = 13, - keyName = "VerzikMelee", - name = "Verzik p3 melee range", + keyName = "VerzikCupcakes", + name = "Verzik Projectile Markers", description = "" ) - default boolean VerzikMelee(){ return false; } + default boolean VerzikCupcakes() { + return false; + } @ConfigItem( position = 14, - keyName = "VerzikYellow", - name = "Verzik yellow timing", + keyName = "VerzikTick", + name = "Verzik P3 Tick", description = "" ) - default boolean VerzikYellow(){ return false; } -} + default boolean VerzikTick() { + return false; + } + + @ConfigItem( + position = 15, + keyName = "VerzikMelee", + name = "Verzik P3 Melee Range", + description = "" + ) + default boolean VerzikMelee() { + return false; + } + + @ConfigItem( + position = 16, + keyName = "VerzikYellow", + name = "Verzik Yellow Timing", + description = "" + ) + default boolean VerzikYellow() { + return false; + } + + @ConfigItem( + position = 17, + keyName = "Verzik Nylo", + name = "Verzik Nylo Overlay", + description = "" + ) + default boolean NyloTargetOverlay() { + return false; + } + + @ConfigItem( + position = 18, + keyName = "VerzikTankTile", + name = "Verzik P3 Tile Overlay", + description = "" + ) + default boolean verzikTankTile() { + return true; + } + + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java index 07f8e2f7b4..8e650295a7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java @@ -8,27 +8,21 @@ package net.runelite.client.plugins.ztob; +import net.runelite.api.Point; +import net.runelite.api.*; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.*; + +import javax.inject.Inject; import java.awt.*; import java.util.Iterator; import java.util.List; import java.util.Map; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldArea; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.OverlayUtil; public class TheatreOverlay extends Overlay { private final Client client; - - private final TheatrePlugin plugin; private final TheatreConfig config; @@ -43,69 +37,71 @@ public class TheatreOverlay extends Overlay { } @Override - public Dimension render(Graphics2D graphics) - { - if (plugin.isRunMaiden()) - { - if (config.MaidenBlood()) - { - for (WorldPoint point : plugin.getMaiden_BloodSpatters()) - { - drawTile(graphics, point, new Color(0,150,200), 2, 150, 10); + public Dimension render(Graphics2D graphics) { + if (plugin.isRunMaiden()) { + if (config.MaidenBlood()) { + for (WorldPoint point : plugin.getMaiden_BloodSpatters()) { + drawTile(graphics, point, new Color(36, 248, 229), 2, 150, 10); } } - if (config.MaidenSpawns()) - { - for (WorldPoint point : plugin.getMaiden_SpawnLocations()) - { - drawTile(graphics, point, new Color(0,150,200), 2, 180, 20); + if (config.MaidenSpawns()) { + for (WorldPoint point : plugin.getMaiden_SpawnLocations()) { + drawTile(graphics, point, new Color(36, 248, 229), 2, 180, 20); } - for (WorldPoint point : plugin.getMaiden_SpawnLocations2()) - { - drawTile(graphics, point, new Color(0,150,200), 1,120, 10); + for (WorldPoint point : plugin.getMaiden_SpawnLocations2()) { + drawTile(graphics, point, new Color(36, 248, 229), 1, 120, 10); } } } - if (plugin.isRunBloat()) - { + if (plugin.isRunBloat() && config.BloatIndicator()) { + if (config.bloatFeetIndicator()) { + if (plugin.getTemp().size() > 0) { + if (plugin.isTempFlag()) { + for (WorldPoint point : plugin.getTemp()) { - if (config.BloatHands()) - { - for (WorldPoint p : plugin.getBloat_Hands()) - { - drawTile(graphics, p, Color.BLACK,3,255,0); + drawTile(graphics, point, Color.black, 4, 255, 0); + + } + + } + } else if (plugin.getTemp2().size() > 0) { + if (plugin.isTemp2Flag()) { + for (WorldPoint point : plugin.getTemp2()) { + + drawTile(graphics, point, Color.black, 4, 255, 0); + + + } + + } } } - if(config.BloatIndicator()) { - NPC bloat = plugin.getBloat_NPC(); - int state = plugin.getBloat_State(); - if (bloat == null) { - return null; - } - switch (state) { - case 2: - renderNpcOverlay(graphics, bloat, Color.GREEN, 3, 150, 0); - break; - case 3: - renderNpcOverlay(graphics, bloat, Color.YELLOW, 3, 150, 0); - break; - default: - renderNpcOverlay(graphics, bloat, new Color(223, 109, 255), 3, 150, 0); - break; - } + NPC bloat = plugin.getBloat_NPC(); + int state = plugin.getBloat_State(); + if (bloat == null) { + return null; + } + switch (state) { + case 2: + renderNpcOverlay(graphics, bloat, Color.GREEN, 3, 150, 0); + break; + case 3: + renderNpcOverlay(graphics, bloat, Color.YELLOW, 3, 150, 0); + break; + default: + renderNpcOverlay(graphics, bloat, new Color(223, 109, 255), 3, 150, 0); + break; } } - if (plugin.isRunNylocas()) - { - if (config.NyloPillars()) - { + if (plugin.isRunNylocas()) { + if (config.NyloPillars()) { Map pillars = plugin.getNylocas_Pillars(); for (NPC npc : pillars.keySet()) { final int health = pillars.get(npc); - final String healthStr = String.valueOf(health) + "%"; + final String healthStr = health + "%"; WorldPoint p = npc.getWorldLocation(); LocalPoint lp = LocalPoint.fromWorld(client, p.getX() + 1, p.getY() + 1); final double rMod = 130.0 * health / 100.0; @@ -118,41 +114,34 @@ public class TheatreOverlay extends Overlay { } } - if (config.NyloBlasts()) - { + if (config.NyloBlasts()) { final Map npcMap = plugin.getNylocas_Map(); - for (NPC npc : npcMap.keySet()) - { + for (NPC npc : npcMap.keySet()) { int ticksLeft = npcMap.get(npc); if (ticksLeft > -1) { if (ticksLeft <= 6) { - Color color = new Color(255, 255,0 ,180); + Color color = new Color(255, 255, 0, 180); int outlineWidth = 2; int outlineAlpha = 150; - renderNpcOverlay(graphics, npc, color, outlineWidth, outlineAlpha, 0); + renderNpcOverlay(graphics, npc, color, outlineWidth, outlineAlpha, 15); } } } } } - if (plugin.isRunSotetseg()) - { - if (config.SotetsegMaze1()) - { + if (plugin.isRunSotetseg()) { + if (config.SotetsegMaze1()) { int i = 1; - for (GroundObject z : plugin.getRedTiles().keySet()) - { - Polygon poly = z.getCanvasTilePoly(); - if (poly != null) - { + for (GroundObject o : plugin.getRedTiles().keySet()) { + Polygon poly = o.getCanvasTilePoly(); + if (poly != null) { graphics.setColor(Color.WHITE); graphics.setStroke(new BasicStroke(2)); graphics.draw(poly); } - Point textLocation = z.getCanvasTextLocation(graphics, String.valueOf(i), 0); - if (textLocation != null) - { + Point textLocation = o.getCanvasTextLocation(graphics, String.valueOf(i), 0); + if (textLocation != null) { OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(i), Color.WHITE); } @@ -160,111 +149,111 @@ public class TheatreOverlay extends Overlay { } } - if (config.SotetsegMaze2()) - { - for (WorldPoint p : plugin.getRedTilesOverworld()) - { + if (config.SotetsegMaze2()) { + for (WorldPoint p : plugin.getRedTilesOverworld()) { drawTile(graphics, p, Color.WHITE, 2, 255, 10); } } - if (config.SotetsegTick()) { - NPC boss = plugin.getSotetseg_NPC(); - int eattick = plugin.getTickTillEat(); - if (eattick > -1) - { - final String eatTicksStr = String.valueOf(eattick); - Point canvasPoint = boss.getCanvasTextLocation(graphics, eatTicksStr, 130); - renderTextLocation(graphics, eatTicksStr, 12, Font.BOLD, Color.WHITE, canvasPoint); - - } - } } - - if (plugin.isRunXarpus()) - { + if (plugin.isRunXarpus()) { NPC boss = plugin.getXarpus_NPC(); - if (boss.getId() == NpcID.XARPUS_8340 && !plugin.isXarpus_Stare() && config.XarpusTick()) - { + if (boss.getId() == NpcID.XARPUS_8340 && !plugin.isXarpus_Stare() && config.XarpusTick()) { int tick = plugin.getXarpus_TicksUntilShoot(); - if (tick < 1) - { + if (tick < 1) { tick = tick % 4 + 4; } final String ticksLeftStr = String.valueOf(tick); Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 130); renderTextLocation(graphics, ticksLeftStr, 12, Font.BOLD, Color.WHITE, canvasPoint); } - if (boss.getId() == NpcID.XARPUS_8339 && config.XarpusExhumed()) - { - for (GroundObject o : plugin.getXarpus_Exhumeds().keySet()) - { + if (boss.getId() == NpcID.XARPUS_8339 && config.XarpusExhumed()) { + for (GroundObject o : plugin.getXarpus_Exhumeds().keySet()) { + + Polygon poly = o.getCanvasTilePoly(); - if (poly != null) - { + if (poly != null) { graphics.setColor(new Color(0, 255, 0, 130)); graphics.setStroke(new BasicStroke(1)); graphics.draw(poly); } } + for (Map.Entry exhumes : plugin.getXarpusExhumedsTimer().entrySet()) { + final String ticksremaining = String.valueOf(exhumes.getValue()); + if (Integer.valueOf(ticksremaining) > 0) { + GroundObject ex = exhumes.getKey(); + Point point = ex.getCanvasTextLocation(graphics, ticksremaining, 0); + renderTextLocation(graphics, ticksremaining, 12, Font.BOLD, Color.white, point); + } + + } + + } + } - if (plugin.isRunVerzik()) - { - if (config.VerzikCupcakes()) - { - for (WorldPoint p : plugin.getVerzik_RangeProjectiles().values()) - { + + if (plugin.isRunVerzik()) { + + + if (config.VerzikCupcakes()) { + for (WorldPoint p : plugin.getVerzik_RangeProjectiles().values()) { drawTile(graphics, p, Color.RED, 2, 180, 50); } } - if (config.VerzikYellow()) - { - for (WorldPoint p : plugin.getVerzik_YellowTiles()) - { - drawTile(graphics, p, Color.YELLOW,3,255,0); - + if (config.VerzikYellow()) { + for (WorldPoint p : plugin.getVerzik_YellowTiles()) { + drawTile(graphics, p, Color.YELLOW, 3, 255, 0); Projectile yellowBall = plugin.getVerzik_YellowBall(); - if (yellowBall != null) - { - final int ticksToImpact = yellowBall.getRemainingCycles()/30; + if (yellowBall != null) { + final int ticksToImpact = yellowBall.getRemainingCycles() / 30; final String countdownStr = String.valueOf(ticksToImpact); Point canvasPoint = Perspective.getCanvasTextLocation(client, graphics, LocalPoint.fromWorld(client, p), countdownStr, 0); renderTextLocation(graphics, countdownStr, 12, Font.BOLD, Color.WHITE, canvasPoint); + } } } - if (plugin.getVerzik_NPC_P3() != null) { - final NPC boss = plugin.getVerzik_NPC_P3(); - if (boss.getId() == NpcID.VERZIK_VITUR_8374) - { - if (config.VerzikTick()) - { - final int ticksLeft = plugin.getP3_TicksUntilAttack(); - if (ticksLeft > 0 && ticksLeft < 8) - { - final String ticksLeftStr = String.valueOf(ticksLeft); - Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); - renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); - } + + final NPC boss = plugin.getVerzik_NPC(); + if (boss.getId() == NpcID.VERZIK_VITUR_8374) { + if (config.verzikTankTile()) { + renderNpcOverlay(graphics, boss, new Color(75, 0, 130), 1, 255, 0); + } + + if (config.VerzikTick()) { + final int ticksLeft = plugin.getP3_TicksUntilAttack(); + if (ticksLeft > 0 && ticksLeft < 8) { + final String ticksLeftStr = String.valueOf(ticksLeft); + Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); + renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); } + } - if (config.VerzikMelee() && boss.getAnimation() != 8127) - { - List meleeRange = getHitSquares(boss.getWorldLocation(), 7, 1, false); + if (config.VerzikMelee()) { + List meleeRange = getHitSquares(boss.getWorldLocation(), 7, 1, false); - for (WorldPoint p : meleeRange) - { - drawTile(graphics, p, Color.WHITE, 1,155, 10); - } + for (WorldPoint p : meleeRange) { + drawTile(graphics, p, Color.WHITE, 1, 155, 10); } } } + + if (boss.getAnimation() == 8117) { + final int ticksLeft = plugin.getRedCrabsTimer(); + if (ticksLeft > 0) { + final String ticksLeftStr = String.valueOf(ticksLeft); + Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); + renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); + } + } + } + return null; } @@ -290,19 +279,16 @@ public class TheatreOverlay extends Overlay { graphics.fill(poly); } - private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha) - { + private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha) { int size = 1; NPCComposition composition = actor.getTransformedComposition(); - if (composition != null) - { + if (composition != null) { size = composition.getSize(); } LocalPoint lp = actor.getLocalLocation(); Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size); - if (tilePoly != null) - { + if (tilePoly != null) { graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); graphics.setStroke(new BasicStroke(outlineWidth)); graphics.draw(tilePoly); @@ -311,37 +297,31 @@ public class TheatreOverlay extends Overlay { } } - private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) - { + private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) { graphics.setFont(new Font("Arial", fontStyle, fontSize)); - if (canvasPoint != null) - { + if (canvasPoint != null) { final Point canvasCenterPoint = new Point( canvasPoint.getX(), canvasPoint.getY()); final Point canvasCenterPoint_shadow = new Point( canvasPoint.getX() + 1, - canvasPoint.getY() + 1) ; + canvasPoint.getY() + 1); OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); } } - private List getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder) - { + private List getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder) { List little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList(); - List big = new WorldArea(npcLoc.getX()-thickness, npcLoc.getY()-thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList(); - if (!includeUnder) - { - for (Iterator it = big.iterator(); it.hasNext();) - { + List big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList(); + if (!includeUnder) { + for (Iterator it = big.iterator(); it.hasNext(); ) { WorldPoint p = it.next(); - if (little.contains(p)) - { + if (little.contains(p)) { it.remove(); } } } return big; } -} +} \ No newline at end of file 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 ee7cee5f4a..3eb223c0c6 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 @@ -8,29 +8,30 @@ package net.runelite.client.plugins.ztob; -import java.util.*; -import java.util.Iterator; -import javax.inject.Inject; - -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.eventbus.Subscribe; import com.google.inject.Provides; import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.*; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.*; +import net.runelite.api.kit.KitType; +import net.runelite.client.chat.ChatMessageManager; 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.ui.overlay.OverlayManager; +import net.runelite.client.util.Text; + +import javax.inject.Inject; +import java.util.*; @PluginDescriptor( - name = "Theatre of Blood", + name = "Theater of Blood", description = "All-in-one plugin for Theatre of Blood", tags = {"ToB"}, - type = "PVM", - enabledByDefault = false + enabledByDefault = false, + type = "PVM" ) public class TheatrePlugin extends Plugin { @@ -41,11 +42,6 @@ public class TheatrePlugin extends Plugin { private static final int GROUNDOBJECT_ID_EXHUMED = 32743; private static final int ANIMATION_ID_XARPUS = 8059; private static final int GRAPHICSOBJECT_ID_YELLOW = 1595; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND1 = 1570; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND2 = 1571; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND3 = 1572; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND4 = 1573; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND5 = 1576; private static final int PROJECTILE_ID_P2RANGE = 1583; private static final int PROJECTILE_ID_YELLOW = 1596; private static final int ANIMATION_ID_P3_WEB = 8127; @@ -56,11 +52,30 @@ public class TheatrePlugin extends Plugin { private static final int VERZIK_ID_P3 = NpcID.VERZIK_VITUR_8374; private static final int NPC_ID_TORNADO = 8386; private static final int PROJECTILE_ID_P3_GREEN = 1598; - private static final String sotmsg = "A large ball of energy is shot your way..."; - private static final String sotmsg1 = "A large ball of energy is shot your way..."; - @Inject - private ChatMessageManager chatMessageManager; + + @Getter(AccessLevel.PACKAGE) + private final Map xarpusExhumedsTimer = new HashMap<>(); + @Getter + int exhumecount; + @Getter + int bloatTimer = 0; + + int bloatFeetTimer = 0; + NPC BossNylo = null; + private boolean bloatFlag = false; + @Getter + private Set bloatTiles = new HashSet<>(); + @Getter + private Set temp = new HashSet<>(); + @Getter + private Set temp2 = new HashSet<>(); + @Getter + private Set localTemp = new HashSet<>(); + + //@Getter + //private List bloatTiles = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) private boolean runMaiden; @@ -80,9 +95,6 @@ public class TheatrePlugin extends Plugin { @Getter(AccessLevel.PACKAGE) private boolean runBloat; - @Getter(AccessLevel.PACKAGE) - private int TickTillEat = 20; - @Getter(AccessLevel.PACKAGE) private NPC Bloat_NPC; @@ -112,12 +124,13 @@ public class TheatrePlugin extends Plugin { private List RedTilesOverworld = new ArrayList<>(); private List BlackTilesOverworld = new ArrayList<>(); - - private List BlackTilesUnderworld= new ArrayList<>(); - - private List RedTilesUnderworld= new ArrayList<>(); + @Getter + private boolean tempFlag = false; + @Getter + private boolean temp2Flag = false; private List GridPath = new ArrayList<>(); + private List BlackTilesUnderworld = new ArrayList<>(); @Getter(AccessLevel.PACKAGE) private boolean runXarpus; @@ -129,6 +142,7 @@ public class TheatrePlugin extends Plugin { @Getter(AccessLevel.PACKAGE) private final Map Xarpus_Exhumeds = new HashMap<>(); + private List RedTilesUnderworld = new ArrayList<>(); @Getter(AccessLevel.PACKAGE) private int Xarpus_TicksUntilShoot = 9; @@ -136,9 +150,6 @@ public class TheatrePlugin extends Plugin { @Getter(AccessLevel.PACKAGE) private NPC Xarpus_NPC; - @Getter(AccessLevel.PACKAGE) - private NPC Sotetseg_NPC; - @Getter(AccessLevel.PACKAGE) private boolean runVerzik; @@ -154,17 +165,16 @@ public class TheatrePlugin extends Plugin { @Getter(AccessLevel.PACKAGE) private List Verzik_YellowTiles = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private List Bloat_Hands = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) private NPC Verzik_NPC; + @Getter(AccessLevel.PACKAGE) + private List tornadoList; @Getter(AccessLevel.PACKAGE) - private NPC Verzik_NPC_P3; + private List crabList; - @Getter(AccessLevel.PACKAGE) - private NPC Verzik_NPC_P2; + @Getter + private int redCrabsTimer; private int P3_attacksLeft; @@ -180,6 +190,18 @@ public class TheatrePlugin extends Plugin { @Inject private TheatreConfig config; + @Inject + private TheatreXarpusOverlay xarpusOverlay; + + @Inject + private ChatMessageManager chatMessageManager; + + @Inject + private VerzikNyloOverlay verzikNyloOverlay; + + @Inject + private BloatTimerOverlay bloatTimerOverlay; + @Provides TheatreConfig getConfig(ConfigManager configManager) { return configManager.getConfig(TheatreConfig.class); @@ -188,19 +210,116 @@ public class TheatrePlugin extends Plugin { @Override protected void startUp() { overlayManager.add(overlay); + overlayManager.add(xarpusOverlay); + overlayManager.add(verzikNyloOverlay); + overlayManager.add(bloatTimerOverlay); } @Override protected void shutDown() { overlayManager.remove(overlay); + overlayManager.remove(xarpusOverlay); + overlayManager.remove(xarpusOverlay); + overlayManager.remove(bloatTimerOverlay); + } + + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) { + if (client.getGameState() != GameState.LOGGED_IN || !config.NyloMenu() || !runNylocas) { + return; + } + + final String pOptionToReplace = Text.removeTags(event.getOption()).toUpperCase(); + Map playerEquipment = new HashMap<>(); + + int attackType = 0; //0=idk 1= melee 2= range 3= mage + + for (KitType kitType : KitType.values()) { + + int itemId = client.getLocalPlayer().getPlayerComposition().getEquipmentId(kitType); + switch (itemId) { + case ItemID.DRAGON_CLAWS: + case ItemID.SCYTHE_OF_VITUR: + case ItemID.SCYTHE_OF_VITUR_UNCHARGED: + case ItemID.SCYTHE_10735: + case ItemID.SCYTHE_OF_VITUR_22664: + case ItemID.HAM_JOINT: + case ItemID.EVENT_RPG: + case ItemID.ABYSSAL_WHIP: + case ItemID.ABYSSAL_TENTACLE: + case ItemID.FROZEN_ABYSSAL_WHIP: + case ItemID.VOLCANIC_ABYSSAL_WHIP: + case ItemID.GHRAZI_RAPIER: + case ItemID.DRAGON_WARHAMMER: + case ItemID.DRAGON_WARHAMMER_20785: + case ItemID.BANDOS_GODSWORD: + case ItemID.BANDOS_GODSWORD_OR: + case ItemID.BANDOS_GODSWORD_20782: + case ItemID.BANDOS_GODSWORD_21060: + case ItemID.CRYSTAL_HALBERD_510: + case ItemID.CRYSTAL_HALBERD_510_I: + case ItemID.CRYSTAL_HALBERD_610: + case ItemID.CRYSTAL_HALBERD_610_I: + case ItemID.CRYSTAL_HALBERD_710_I: + case ItemID.CRYSTAL_HALBERD_710: + case ItemID.CRYSTAL_HALBERD_110: + case ItemID.CRYSTAL_HALBERD_110_I: + case ItemID.CRYSTAL_HALBERD_210: + case ItemID.CRYSTAL_HALBERD_310: + case ItemID.CRYSTAL_HALBERD_310_I: + case ItemID.CRYSTAL_HALBERD_410: + case ItemID.CRYSTAL_HALBERD_410_I: + case ItemID.CRYSTAL_HALBERD_810: + case ItemID.CRYSTAL_HALBERD_810_I: + case ItemID.CRYSTAL_HALBERD_910: + case ItemID.CRYSTAL_HALBERD_910_I: + attackType = 1; + break; + case ItemID.TOXIC_BLOWPIPE: + case ItemID.TOXIC_BLOWPIPE_EMPTY: + case ItemID.RED_CHINCHOMPA_10034: + case ItemID.BLACK_CHINCHOMPA: + case ItemID.CHINCHOMPA_10033: + case ItemID.TWISTED_BOW: + attackType = 2; + break; + case ItemID.SANGUINESTI_STAFF: + case ItemID.TOXIC_STAFF_OF_THE_DEAD: + case ItemID.TRIDENT_OF_THE_SWAMP: + case ItemID.TRIDENT_OF_THE_SEAS_E: + case ItemID.TRIDENT_OF_THE_SEAS: + case ItemID.TRIDENT_OF_THE_SWAMP_E: + case ItemID.KODAI_WAND: + case ItemID.MASTER_WAND: + case ItemID.MASTER_WAND_20560: + attackType = 3; + break; + } + if (attackType != 0) { + break; + } + + } + if (pOptionToReplace.equals("CANCEL") || pOptionToReplace.equals("WALK HERE") || pOptionToReplace.equals("PASS")) { + return; + } + int Id = 0; + if (BossNylo != null) { + Id = BossNylo.getId(); + } + String target = Text.removeTags(event.getTarget()).toLowerCase(); + if (attackType != 0) { + stripEntries(attackType, target, Id); + } + } @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) - { + public void onNpcSpawned(NpcSpawned npcSpawned) { + NPC npc = npcSpawned.getNpc(); - switch (npc.getId()) - { + switch (npc.getId()) { case NpcID.THE_MAIDEN_OF_SUGADINTI: case NpcID.THE_MAIDEN_OF_SUGADINTI_8361: case NpcID.THE_MAIDEN_OF_SUGADINTI_8362: @@ -215,25 +334,40 @@ public class TheatrePlugin extends Plugin { case NpcID.PESTILENT_BLOAT: runBloat = true; Bloat_NPC = npc; + bloatTimer = 0; + bloatFlag = false; + break; + case NpcID.NYLOCAS_VASILIAS: + case NpcID.NYLOCAS_VASILIAS_8355: + case NpcID.NYLOCAS_VASILIAS_8356: + case NpcID.NYLOCAS_VASILIAS_8357: + BossNylo = npc; break; case NPCID_NYLOCAS_PILLAR: runNylocas = true; - if (!Nylocas_Pillars.keySet().contains(npc)) - { + if (!Nylocas_Pillars.keySet().contains(npc)) { Nylocas_Pillars.put(npc, 100); } break; - case 8342: case 8343: case 8344: case 8345: case 8346: case 8347: - case 8348: case 8349: case 8350: case 8351: case 8352: case 8353: - if (runNylocas) - { + case 8342: + case 8343: + case 8344: + case 8345: + case 8346: + case 8347: + case 8348: + case 8349: + case 8350: + case 8351: + case 8352: + case 8353: + if (runNylocas) { Nylocas_Map.put(npc, 52); } break; case NpcID.SOTETSEG: case NpcID.SOTETSEG_8388: runSotetseg = true; - Sotetseg_NPC = npc; RedTiles.clear(); break; case NpcID.XARPUS: @@ -241,6 +375,7 @@ public class TheatrePlugin extends Plugin { case NpcID.XARPUS_8340: case NpcID.XARPUS_8341: runXarpus = true; + exhumecount = 25; Xarpus_NPC = npc; Xarpus_Stare = false; Xarpus_TicksUntilShoot = 9; @@ -249,22 +384,17 @@ public class TheatrePlugin extends Plugin { case NpcID.VERZIK_VITUR_8369: case NpcID.VERZIK_VITUR_8370: case NpcID.VERZIK_VITUR_8371: + case NpcID.VERZIK_VITUR_8372: case NpcID.VERZIK_VITUR_8373: + case NpcID.VERZIK_VITUR_8374: case NpcID.VERZIK_VITUR_8375: + P3_TicksUntilAttack = -1; + P3_attacksLeft = 9; + redCrabsTimer = 13; Verzik_NPC = npc; runVerzik = true; - break; - - case NpcID.VERZIK_VITUR_8372:/*p2 spider*/ - Verzik_NPC_P2 = npc; - runVerzik = true; - break; - - case NpcID.VERZIK_VITUR_8374:/*p3 spider*/ - P3_TicksUntilAttack = 0; - P3_attacksLeft = 9; - Verzik_NPC_P3 = npc; - runVerzik = true; + tornadoList = new ArrayList<>(); + crabList = new ArrayList<>(); break; } } @@ -288,28 +418,35 @@ public class TheatrePlugin extends Plugin { case NpcID.PESTILENT_BLOAT: runBloat = false; Bloat_NPC = null; + bloatTimer = 0; break; case NPCID_NYLOCAS_PILLAR: - if (Nylocas_Pillars.keySet().contains(npc)) - { + if (Nylocas_Pillars.keySet().contains(npc)) { Nylocas_Pillars.remove(npc); } break; - case 8342: case 8343: case 8344: case 8345: case 8346: case 8347: - case 8348: case 8349: case 8350: case 8351: case 8352: case 8353: - if (Nylocas_Map.keySet().contains(npc)) - { + case 8342: + case 8343: + case 8344: + case 8345: + case 8346: + case 8347: + case 8348: + case 8349: + case 8350: + case 8351: + case 8352: + case 8353: + if (Nylocas_Map.keySet().contains(npc)) { Nylocas_Map.remove(npc); } break; case NpcID.SOTETSEG: case NpcID.SOTETSEG_8388: RedTiles.clear(); - if (client.getPlane() != 3) - { + if (client.getPlane() != 3) { runSotetseg = false; } - Sotetseg_NPC = null; break; case NpcID.XARPUS: case NpcID.XARPUS_8339: @@ -321,117 +458,119 @@ public class TheatrePlugin extends Plugin { Xarpus_TicksUntilShoot = 9; Xarpus_previousAnimation = -1; Xarpus_Exhumeds.clear(); + exhumecount = 0; break; case NpcID.VERZIK_VITUR_8369: case NpcID.VERZIK_VITUR_8370: - case NpcID.VERZIK_VITUR_8371:/*p2*/ - + case NpcID.VERZIK_VITUR_8371: + case NpcID.VERZIK_VITUR_8372: case NpcID.VERZIK_VITUR_8373: - + case NpcID.VERZIK_VITUR_8374: case NpcID.VERZIK_VITUR_8375: + runVerzik = false; + redCrabsTimer = 0; Verzik_NPC = null; break; - case NpcID.VERZIK_VITUR_8372: - Verzik_NPC_P2 = null; - break; - case NpcID.VERZIK_VITUR_8374:/*p3 spider*/ - Verzik_NPC_P3 = null; - break; - } } @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) - { - if (runSotetseg) - { + public void onGroundObjectSpawned(GroundObjectSpawned event) { + if (runSotetseg) { GroundObject o = event.getGroundObject(); - if (o.getId() == GROUNDOBJECT_ID_BLACKMAZE) - { + if (o.getId() == GROUNDOBJECT_ID_BLACKMAZE) { Tile t = event.getTile(); WorldPoint p = t.getWorldLocation(); - if (t.getPlane() == 0) - { + if (t.getPlane() == 0) { if (!BlackTilesOverworld.contains(p)) BlackTilesOverworld.add(p); - } - else - { + } else { if (!BlackTilesUnderworld.contains(p)) BlackTilesUnderworld.add(p); } } - if (o.getId() == GROUNDOBJECT_ID_REDMAZE) - { + if (o.getId() == GROUNDOBJECT_ID_REDMAZE) { Tile t = event.getTile(); WorldPoint p = t.getWorldLocation(); - if (p.getPlane() == 0) - { - if (!RedTiles.containsValue(t)) - { - RedTiles.put(o,t); + if (p.getPlane() == 0) { + if (!RedTiles.containsValue(t)) { + RedTiles.put(o, t); } - } - else - { + } else { if (!RedTilesUnderworld.contains(p)) RedTilesUnderworld.add(p); } } } - if (runXarpus) - { + if (runXarpus) { GroundObject o = event.getGroundObject(); - if (o.getId() == GROUNDOBJECT_ID_EXHUMED) - { + if (o.getId() == GROUNDOBJECT_ID_EXHUMED) { + + xarpusExhumedsTimer.put(o, 18); + Xarpus_Exhumeds.put(o, 18); + } + } } @Subscribe - public void onProjectileMoved(ProjectileMoved event) - { - if (runVerzik) - { + public void onProjectileMoved(ProjectileMoved event) { + if (runVerzik) { Projectile projectile = event.getProjectile(); - if (projectile.getId() == PROJECTILE_ID_P2RANGE) - { - WorldPoint p = WorldPoint.fromLocal(client,event.getPosition()); + if (projectile.getId() == PROJECTILE_ID_P2RANGE) { + WorldPoint p = WorldPoint.fromLocal(client, event.getPosition()); Verzik_RangeProjectiles.put(projectile, p); } } } @Subscribe - public void onChatMessage(ChatMessage chatMessage) - { - MessageNode messageNode = chatMessage.getMessageNode(); - - if (messageNode.getValue().toLowerCase().contains(sotmsg.toLowerCase())) - { - TickTillEat = 20; - /*20 ticks*/ - + public void onAnimationChanged(AnimationChanged event) { + if (runVerzik) { + if (event.getActor().getAnimation() == 8117) { + redCrabsTimer = 11; + } } - - } @Subscribe - public void onGameTick(GameTick event) - { - if (runMaiden) - { + public void onVarbitChanged(VarbitChanged event) { + if (runBloat) { + + if (client.getVar(Varbits.BLOAT_ENTERED_ROOM) == 1) { + if (!bloatFlag) { + bloatTimer = 0; + bloatFlag = true; + } + } + } + } + + @Subscribe + public void onGraphicsObjectCreated(GraphicsObjectCreated event) { + GraphicsObject obj = event.getGraphicsObject(); + if (obj.getId() == 1570 || obj.getId() == 1571 || obj.getId() == 1572 || obj.getId() == 1573 || obj.getId() == 1574 || obj.getId() == 1575 || obj.getId() == 1576) { + WorldPoint p = WorldPoint.fromLocal(client, obj.getLocation()); + if (temp.size() == 0) { + + } else { + + } + } + } + + + @Subscribe + public void onGameTick(GameTick event) { + if (runMaiden) { Maiden_BloodSpatters.clear(); - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_MAIDEN) - { + for (GraphicsObject o : client.getGraphicsObjects()) { + if (o.getId() == GRAPHICSOBJECT_ID_MAIDEN) { Maiden_BloodSpatters.add(WorldPoint.fromLocal(client, o.getLocation())); } } @@ -439,98 +578,117 @@ public class TheatrePlugin extends Plugin { Maiden_SpawnLocations2.clear(); Maiden_SpawnLocations2.addAll(Maiden_SpawnLocations); Maiden_SpawnLocations.clear(); - for (NPC spawn : Maiden_Spawns) - { + for (NPC spawn : Maiden_Spawns) { Maiden_SpawnLocations.add(spawn.getWorldLocation()); } } - if (runBloat) - { + if (runBloat) { + + localTemp.clear(); + + //System.out.println("Temp flag" + tempFlag); + //System.out.println("Temp2 flag" + temp2Flag); + + + for (GraphicsObject obj : client.getGraphicsObjects()) { + if (obj.getId() == 1570 || obj.getId() == 1571 || obj.getId() == 1572 || obj.getId() == 1573 || obj.getId() == 1574 || obj.getId() == 1575 || obj.getId() == 1576) { + WorldPoint p = WorldPoint.fromLocal(client, obj.getLocation()); + //Already have some feet in temp Set + if (temp.size() > 0) { + //System.out.println("temp size > 0, tempflag set false, tempflag2 set true"); + tempFlag = false; + temp2Flag = true; + } else { + //System.out.println("temp size 0, tempflag set true, tempflag2 set false"); + tempFlag = true; + temp2Flag = false; + + } + localTemp.add(p); + } + } + + if (tempFlag) { + temp2.clear(); + temp2Flag = false; + temp.addAll(localTemp); + + + //System.out.println("temp2 cleared, temp2flag set false, added to temp set"); + } else if (temp2Flag) { + temp.clear(); + tempFlag = false; + temp2.addAll(localTemp); + //System.out.println("temp cleared, tempflag set false, added to temp2 set"); + + } Bloat_downCount++; - Bloat_Hands.clear(); - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND1 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND2 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND3 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND4|| o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND5) - { - Bloat_Hands.add(WorldPoint.fromLocal(client, o.getLocation())); - } - } - - if (Bloat_NPC.getAnimation() == -1) //1 = up; 2 = down; 3 = warn; { + bloatTimer++; Bloat_downCount = 0; - if (Bloat_NPC.getHealth() == 0) - { + if (Bloat_NPC.getHealth() == 0) { Bloat_State = 2; - } - else + } else Bloat_State = 1; - } - else - { - if (25 it = Nylocas_Map.keySet().iterator(); it.hasNext();) - { + if (runNylocas) { + for (Iterator it = Nylocas_Map.keySet().iterator(); it.hasNext(); ) { NPC npc = it.next(); int ticksLeft = Nylocas_Map.get(npc); - if (ticksLeft < 0) - { + if (ticksLeft < 0) { it.remove(); continue; } Nylocas_Map.replace(npc, ticksLeft - 1); } - for (NPC pillar : Nylocas_Pillars.keySet()) - { + for (NPC pillar : Nylocas_Pillars.keySet()) { int healthPercent = pillar.getHealthRatio(); - if (healthPercent > -1) - { + if (healthPercent > -1) { Nylocas_Pillars.replace(pillar, healthPercent); } } - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == 8358) - { + for (NPC npc : client.getNpcs()) { + if (npc.getId() == 8358) { runNylocas = true; break; } runNylocas = false; + BossNylo = null; } } - if (runSotetseg) - { - TickTillEat--; + if (runSotetseg) { boolean sotetsegFighting = false; - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == NpcID.SOTETSEG_8388) - { + for (NPC npc : client.getNpcs()) { + if (npc.getId() == NpcID.SOTETSEG_8388) { BlackTilesUnderworld.clear(); BlackTilesOverworld.clear(); RedTilesOverworld.clear(); @@ -542,42 +700,33 @@ public class TheatrePlugin extends Plugin { } } - if (!sotetsegFighting) - { - if (!BlackTilesUnderworld.isEmpty() && !RedTilesUnderworld.isEmpty() && GridPath.isEmpty()) - { + if (!sotetsegFighting) { + if (!BlackTilesUnderworld.isEmpty() && !RedTilesUnderworld.isEmpty() && GridPath.isEmpty()) { int minX = 99999; int minY = 99999; - for (WorldPoint p : BlackTilesUnderworld) - { + for (WorldPoint p : BlackTilesUnderworld) { int x = p.getX(); int y = p.getY(); - if (x < minX) - { + if (x < minX) { minX = x; } - if (y < minY) - { + if (y < minY) { minY = y; } } - boolean messageSent = false; - for (WorldPoint p : RedTilesUnderworld) - { + for (WorldPoint p : RedTilesUnderworld) { WorldPoint pN = new WorldPoint(p.getX(), p.getY() + 1, p.getPlane()); WorldPoint pS = new WorldPoint(p.getX(), p.getY() - 1, p.getPlane()); WorldPoint pE = new WorldPoint(p.getX() + 1, p.getY(), p.getPlane()); WorldPoint pW = new WorldPoint(p.getX() - 1, p.getY(), p.getPlane()); - if ( !( (RedTilesUnderworld.contains(pN) && RedTilesUnderworld.contains(pS)) || - (RedTilesUnderworld.contains(pE) && RedTilesUnderworld.contains(pW)) ) ) - { + if (!((RedTilesUnderworld.contains(pN) && RedTilesUnderworld.contains(pS)) || + (RedTilesUnderworld.contains(pE) && RedTilesUnderworld.contains(pW)))) { GridPath.add(new Point(p.getX() - minX, p.getY() - minY)); - if (!messageSent) - { + if (!messageSent) { //client.addChatMessage(ChatMessageType.SERVER, "", "Maze path acquired.", null); messageSent = true; } @@ -586,71 +735,74 @@ public class TheatrePlugin extends Plugin { } } - if (!BlackTilesOverworld.isEmpty() && !GridPath.isEmpty() && RedTilesOverworld.isEmpty()) - { + if (!BlackTilesOverworld.isEmpty() && !GridPath.isEmpty() && RedTilesOverworld.isEmpty()) { int minX = 99999; int minY = 99999; - for (WorldPoint p : BlackTilesOverworld) - { + for (WorldPoint p : BlackTilesOverworld) { int x = p.getX(); int y = p.getY(); - if (x < minX) - { + if (x < minX) { minX = x; } - if (y < minY) - { + if (y < minY) { minY = y; } } - for (Point p : GridPath) - { + for (Point p : GridPath) { RedTilesOverworld.add(new WorldPoint(minX + p.getX(), minY + p.getY(), 0)); } } } } - if (runXarpus) - { - for (Iterator it = Xarpus_Exhumeds.keySet().iterator(); it.hasNext();) - { + if (runXarpus) { + int size = xarpusExhumedsTimer.size(); + for (Map.Entry exhumes : xarpusExhumedsTimer.entrySet()) { + if (size > 0) { + exhumes.setValue(exhumes.getValue() - 1); + } + + } + for (Iterator it = Xarpus_Exhumeds.keySet().iterator(); it.hasNext(); ) { GroundObject key = it.next(); Xarpus_Exhumeds.replace(key, Xarpus_Exhumeds.get(key) - 1); - if (Xarpus_Exhumeds.get(key) < 0) - { + if (Xarpus_Exhumeds.get(key) < 0) { it.remove(); + exhumecount--; } } - if (Xarpus_NPC.getOverheadText() != null ) - { + if ((Xarpus_NPC.getComposition().getOverheadIcon() != null)) { Xarpus_Stare = true; } - if (Xarpus_Stare) - { + if (Xarpus_Stare) { //dont hit xarpus if it looking at u - } - else if (Xarpus_NPC.getId() == NpcID.XARPUS_8340) - { + } else if (Xarpus_NPC.getId() == NpcID.XARPUS_8340) { Xarpus_TicksUntilShoot--; - if (Xarpus_NPC.getAnimation() == ANIMATION_ID_XARPUS && Xarpus_previousAnimation != ANIMATION_ID_XARPUS) - { - Xarpus_TicksUntilShoot = 3; - } - Xarpus_previousAnimation = Xarpus_NPC.getAnimation(); + //if (Xarpus_NPC.getAnimation() == ANIMATION_ID_XARPUS && Xarpus_previousAnimation != ANIMATION_ID_XARPUS) + //{ + //Xarpus_TicksUntilShoot = 3; + //} + //Xarpus_previousAnimation = Xarpus_NPC.getAnimation(); } } - if (runVerzik) - { - if (!Verzik_RangeProjectiles.isEmpty()) - { - for (Iterator it = Verzik_RangeProjectiles.keySet().iterator(); it.hasNext();) - { + if (runVerzik) { + crabList.clear(); + for (NPC npc : client.getNpcs()) { + + if (npc.getName().toLowerCase().contains("nylo")) { + crabList.add(npc); + } + } + + if (Verzik_NPC.getAnimation() == 8117) { + redCrabsTimer = redCrabsTimer - 1; + } + if (!Verzik_RangeProjectiles.isEmpty()) { + for (Iterator it = Verzik_RangeProjectiles.keySet().iterator(); it.hasNext(); ) { Projectile projectile = it.next(); - if (projectile.getRemainingCycles() < 1) - { + if (projectile.getRemainingCycles() < 1) { it.remove(); } } @@ -659,55 +811,40 @@ public class TheatrePlugin extends Plugin { Verzik_YellowBall = null; Verzik_YellowTiles.clear(); - for (Projectile projectile : client.getProjectiles()) - { - if (projectile.getId() == PROJECTILE_ID_YELLOW) - { + for (Projectile projectile : client.getProjectiles()) { + if (projectile.getId() == PROJECTILE_ID_YELLOW) { Verzik_YellowBall = projectile; break; } } - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_YELLOW) - { + for (GraphicsObject o : client.getGraphicsObjects()) { + if (o.getId() == GRAPHICSOBJECT_ID_YELLOW) { + Verzik_YellowTiles.add(WorldPoint.fromLocal(client, o.getLocation())); } } - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == 8379) - { - runVerzik = true; - break; - } - runVerzik = false; - } - - - if (Verzik_NPC_P3 != null) { + if (Verzik_NPC.getId() == VERZIK_ID_P3) { boolean tornadosActive = false; - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == NPC_ID_TORNADO) - { + for (NPC npc : client.getNpcs()) { + if (npc.getId() == NPC_ID_TORNADO) { + tornadoList.add(npc); tornadosActive = true; break; } } boolean isGreenBall = false; - for (Projectile projectile : client.getProjectiles()) - { + for (Projectile projectile : client.getProjectiles()) { if (projectile.getId() == PROJECTILE_ID_P3_GREEN) { isGreenBall = projectile.getRemainingCycles() > 210; break; } } + P3_TicksUntilAttack--; - switch (Verzik_NPC_P3.getAnimation()) { + switch (Verzik_NPC.getAnimation()) { case ANIMATION_ID_P3_MAGE: if (P3_TicksUntilAttack < 2) { P3_attacksLeft--; @@ -762,6 +899,90 @@ public class TheatrePlugin extends Plugin { } } + + } -} + private void stripEntries(int style, String target, int NyloID) { + String Keep = null; + if (NyloID == 0) { + switch (style) { + case 1: + Keep = "Nylocas Ischyros"; + break; + case 2: + Keep = "Nylocal Toxobolos"; + break; + case 3: + Keep = "Nylocas Hagios"; + break; + } + } else { + Keep = "fuckaadamhypocrticalpos"; + switch (NyloID) { + case 8356://0=idk 1= melee 2= range 3= mage + if (style == 3) { + + Keep = "Nylocas Vasilias"; + } + break; + case 8357: + if (style == 2) { + Keep = "Nylocas Vasilias"; + } + break; + default: + if (style == 1) { + Keep = "Nylocas Vasilias"; + } + } + + } + int entryLength = 0; + List entryList = new ArrayList<>(); + for (MenuEntry entry : client.getMenuEntries()) { + if (Text.removeTags(entry.getTarget()).contains(Keep) && entry.getOption().equals("Attack")) { + + entryList.add(entry); + entryLength++; + } + if (entry.getOption().equalsIgnoreCase("walk here") || entry.getOption().equalsIgnoreCase("pass") || entry.getOption().equalsIgnoreCase("take")) { + entryList.add(entry); + entryLength++; + } + } + + //System.out.println("i see " + entryLength + " good options using style" + style); + if (entryLength != 0) { + MenuEntry[] newEntries = new MenuEntry[entryLength]; + + + for (int i = 0; i < (entryLength); i++) { + newEntries[i] = entryList.get(i); + } + client.setMenuEntries(newEntries); + } + + + } + + private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict) { + for (int i = entries.length - 1; i >= 0; i--) { + MenuEntry entry = entries[i]; + String entryOption = Text.removeTags(entry.getOption()).toLowerCase(); + String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase(); + + if (strict) { + if (entryOption.equals(option) && entryTarget.equals(target)) { + return i; + } + } else { + if (entryOption.contains(option.toLowerCase()) && entryTarget.equals(target)) { + return i; + } + } + } + + return -1; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java new file mode 100644 index 0000000000..72757be422 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java @@ -0,0 +1,68 @@ +package net.runelite.client.plugins.ztob; + +import com.google.inject.Inject; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayMenuEntry; +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 java.awt.*; + +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; + +public class TheatreXarpusOverlay extends Overlay { + private final TheatrePlugin plugin; + private final TheatreConfig config; + PanelComponent panelComponent = new PanelComponent(); + + @Inject + private TheatreXarpusOverlay(TheatrePlugin plugin, TheatreConfig config) { + super(plugin); + setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); + setPosition(OverlayPosition.DYNAMIC); + setPosition(OverlayPosition.DETACHED); + this.plugin = plugin; + this.config = config; + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Theatre xarpus overlay")); + + } + + @Override + public Dimension render(Graphics2D graphics) { + if (plugin.isRunXarpus()) { + if (config.XarpusExhumeOverlay()) { + if (plugin.getXarpus_NPC().getId() == 8339) { + panelComponent.getChildren().clear(); + String overlayTitle = "Exhume Counter"; + + + // Build overlay title + panelComponent.getChildren().add(TitleComponent.builder() + .text(overlayTitle) + .color(Color.GREEN) + .build()); + + //Set the size of overlay + panelComponent.setPreferredSize(new Dimension( + graphics.getFontMetrics().stringWidth(overlayTitle) + 30, 0 + )); + + panelComponent.getChildren().add(LineComponent.builder() + .left("Exhumes: ") + .right(String.valueOf(plugin.getExhumecount())) + .build()); + } + } + return panelComponent.render(graphics); + } + + return null; + + } + + +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java new file mode 100644 index 0000000000..68f0630c12 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java @@ -0,0 +1,81 @@ +package net.runelite.client.plugins.ztob; + +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.Point; +import net.runelite.client.ui.overlay.*; + +import javax.inject.Inject; +import java.awt.*; + +public class VerzikNyloOverlay extends Overlay { + + private final Client client; + private final TheatrePlugin plugin; + private final TheatreConfig config; + + @Inject + private VerzikNyloOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) { + this.client = client; + this.plugin = plugin; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + public Dimension render(Graphics2D graphics) { + + if (plugin.isRunVerzik()) { + if (config.NyloTargetOverlay()) { + if (plugin.getCrabList().size() > 0) { + + for (NPC npc : plugin.getCrabList()) { + if (npc.isDead()) { + continue; + } + String renderText = ""; + if (npc.getInteracting() != null) { + + renderText = npc.getInteracting().getName(); + Point point = npc.getCanvasTextLocation(graphics, npc.getInteracting().getName(), 0); + + + if (npc.getInteracting().getName().toLowerCase().equals(client.getLocalPlayer().getName().toLowerCase())) { + point = npc.getCanvasTextLocation(graphics, client.getLocalPlayer().getName(), 0); + renderText = "YOU NIGGA RUN!"; + + } else if (npc.getInteracting().getName().toLowerCase().equals("afyy")) { + point = npc.getCanvasTextLocation(graphics, "Ricecup", 0); + renderText = "Ricecup"; + } + if (renderText.equals("YOU NIGGA RUN!")) { + renderTextLocation(graphics, renderText, 12, Font.BOLD, Color.RED, point); + } else { + renderTextLocation(graphics, renderText, 12, Font.BOLD, Color.GREEN, point); + } + } + + } + } + + } + } + + return null; + } + + private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) { + graphics.setFont(new Font("Arial", fontStyle, fontSize)); + if (canvasPoint != null) { + final Point canvasCenterPoint = new Point( + canvasPoint.getX(), + canvasPoint.getY()); + final Point canvasCenterPoint_shadow = new Point( + canvasPoint.getX() + 1, + canvasPoint.getY() + 1); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); + } + } +} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/equipmentinspector/normal.png b/runelite-client/src/main/resources/net/runelite/client/plugins/equipmentinspector/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..613f95e46d5235a49ec0843faaa35384e9b0896b GIT binary patch literal 624 zcmV-$0+0QPP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0tHD#K~z{r?Uuhw z!$1_rUmcyLn~P8fmrQ~BGyq5#M;t!sDe|AI9PCT z5L;*0n(yTB<#Ji>Y`9Ti3&7jKIc7LRzA=EB!@v>HuhtrJNg@rXeB>M9M-je0Kgy>A zylh?sDMIn)l}ej(`+H8v(E%7b5cc-@C3nN&w2Fwp-R+IopcXQj3?*h0Vy~0lOgpUz zIPDlH0yrEs;AVPiQm$;Ucia462~d@01* literal 0 HcmV?d00001 From f06078cb9de3c4f8330255e86fd166a99474a795 Mon Sep 17 00:00:00 2001 From: James Munson Date: Sat, 20 Apr 2019 12:46:02 -0700 Subject: [PATCH 33/75] Added config group item --- .../client/config/ConfigDescriptor.java | 25 +++++++-- .../runelite/client/config/ConfigItem.java | 3 ++ .../client/config/ConfigItemsGroup.java | 52 +++++++++++++++++++ .../runelite/client/config/ConfigManager.java | 32 +++++++++++- 4 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/config/ConfigItemsGroup.java diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java index 34db13d2e9..20013adc67 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java @@ -24,17 +24,18 @@ */ package net.runelite.client.config; +import java.util.ArrayList; import java.util.Collection; public class ConfigDescriptor { private final ConfigGroup group; - private final Collection items; + private final Collection itemGroups; - public ConfigDescriptor(ConfigGroup group, Collection items) + public ConfigDescriptor(ConfigGroup group, Collection itemGroups) { this.group = group; - this.items = items; + this.itemGroups = itemGroups; } public ConfigGroup getGroup() @@ -42,8 +43,22 @@ public class ConfigDescriptor return group; } + public Collection getItemGroups() + { + return itemGroups; + } + public Collection getItems() { - return items; + Collection allItems = new ArrayList<>(); + for (ConfigItemsGroup g : itemGroups) + { + for (ConfigItemDescriptor item : g.getItems()) + { + allItems.add(item); + } + } + return allItems; } -} + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java index b50094826e..44b93f2e1c 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java @@ -46,4 +46,7 @@ public @interface ConfigItem String warning() default ""; boolean secret() default false; + + String group() default ""; + } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItemsGroup.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItemsGroup.java new file mode 100644 index 0000000000..51363c81c4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItemsGroup.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018, Craftiii4 + * 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.config; + +import lombok.AccessLevel; +import lombok.Getter; +import java.util.ArrayList; +import java.util.Collection; + +public class ConfigItemsGroup +{ + + @Getter(AccessLevel.PUBLIC) + private final String group; + + @Getter(AccessLevel.PUBLIC) + private Collection items; + + public ConfigItemsGroup(String group) + { + this.group = group; + this.items = new ArrayList<>(); + } + + public void addItem(ConfigItemDescriptor item) + { + items.add(item); + } + +} 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 7306ab0a51..57a4a9d0cc 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 @@ -47,7 +47,9 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -459,7 +461,35 @@ public class ConfigManager .result()) .collect(Collectors.toList()); - return new ConfigDescriptor(group, items); + Collection itemGroups = new ArrayList<>(); + + for (ConfigItemDescriptor item : items) + { + String groupName = item.getItem().group(); + boolean found = false; + for (ConfigItemsGroup g : itemGroups) + { + if (g.getGroup().equals(groupName)) + { + g.addItem(item); + found = true; + break; + } + } + if (!found) + { + ConfigItemsGroup newGroup = new ConfigItemsGroup(groupName); + newGroup.addItem(item); + itemGroups.add(newGroup); + } + } + + itemGroups = itemGroups.stream().sorted((a, b) -> ComparisonChain.start() + .compare(a.getGroup(), b.getGroup()) + .result()) + .collect(Collectors.toList()); + + return new ConfigDescriptor(group, itemGroups); } /** From 88785dccf134ea18daf880b3b6e130609b695635 Mon Sep 17 00:00:00 2001 From: James Munson Date: Sat, 20 Apr 2019 13:19:51 -0700 Subject: [PATCH 34/75] Updated pvp plugins --- .../net/runelite/api/widgets/WidgetInfo.java | 2 + .../client/plugins/freezetimers/Barrage.java | 73 +- .../freezetimers/FreezeTimersOverlay.java | 69 +- .../freezetimers/FreezeTimersPlugin.java | 579 +++++---- .../freezetimers/FreezeTimersService.java | 130 +- .../freezetimers/FreezeTimersTileOverlay.java | 47 +- .../freezetimers/PlayerSpellEffect.java | 54 +- .../client/plugins/freezetimers/Spell.java | 40 +- .../pvptools/CurrentPlayersJFrame.java | 126 +- .../pvptools/MissingPlayersJFrame.java | 109 +- .../plugins/pvptools/PvpToolsConfig.java | 176 ++- .../plugins/pvptools/PvpToolsOverlay.java | 98 +- .../plugins/pvptools/PvpToolsPanel.java | 250 ++-- .../plugins/pvptools/PvpToolsPlugin.java | 1100 ++++++++++------- .../SuppliesTrackerPlugin.java | 1 + .../whalewatchers/WhaleWatchersConfig.java | 88 +- .../WhaleWatchersGloryOverlay.java | 108 +- .../whalewatchers/WhaleWatchersOverlay.java | 118 +- .../whalewatchers/WhaleWatchersPlugin.java | 494 +++++--- .../WhaleWatchersProtOverlay.java | 89 +- .../WhaleWatchersSmiteableOverlay.java | 86 +- .../worldmaphider/WorldMapHiderConfig.java | 29 + .../worldmaphider/WorldMapHiderPlugin.java | 120 ++ 23 files changed, 2429 insertions(+), 1557 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/worldmaphider/WorldMapHiderConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/worldmaphider/WorldMapHiderPlugin.java 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 d345b27aa8..df7951b840 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 @@ -54,6 +54,7 @@ public enum WidgetInfo WORLD_MAP_SURFACE_SELECTOR(WidgetID.WORLD_MAP_GROUP_ID, WidgetID.WorldMap.SURFACE_SELECTOR), WORLD_MAP_TOOLTIP(WidgetID.WORLD_MAP_GROUP_ID, WidgetID.WorldMap.TOOLTIP), WORLD_MAP_OPTION(WidgetID.WORLD_MAP_MENU_GROUP_ID, WidgetID.WorldMap.OPTION), + WORLD_MAP_BUTTON_BORDER(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), CLUE_SCROLL_TEXT(WidgetID.CLUE_SCROLL_GROUP_ID, WidgetID.Cluescroll.CLUE_TEXT), CLUE_SCROLL_REWARD_ITEM_CONTAINER(WidgetID.CLUE_SCROLL_REWARD_GROUP_ID, WidgetID.Cluescroll.CLUE_SCROLL_ITEM_CONTAINER), @@ -161,6 +162,7 @@ public enum WidgetInfo MINIMAP_HEALTH_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.HEALTH_ORB), MINIMAP_SPEC_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.SPEC_ORB), MINIMAP_WORLDMAP_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), + MINIMAP_WORLD_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), LOGIN_CLICK_TO_PLAY_SCREEN(WidgetID.LOGIN_CLICK_TO_PLAY_GROUP_ID, 0), LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY(WidgetID.LOGIN_CLICK_TO_PLAY_GROUP_ID, WidgetID.LoginClickToPlayScreen.MESSAGE_OF_THE_DAY), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java index 6b80dd4ce3..3e9fc7d6ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Barrage.java @@ -1,43 +1,68 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.freezetimers; +import lombok.Getter; import net.runelite.api.Actor; -import net.runelite.client.plugins.freezetimers.Spell; import net.runelite.client.util.Text; +import org.jetbrains.annotations.NotNull; -public class Barrage -extends Spell { - public static final long DURATION = 20000L; +public class Barrage extends Spell +{ + + + @Getter + public static final long DURATION = 20000; private long remainingTime; + @Getter private boolean isFinished; - public Barrage(Actor affectedTarget, Actor caster) { + + public Barrage(Actor affectedTarget, Actor caster) + { super(affectedTarget, caster); } - public long getRemainingTime() { + public long getRemainingTime() + { long elapsedTime = System.currentTimeMillis() - this.startTime; - if (Barrage.getDURATION() > elapsedTime) { - return Barrage.getDURATION() - elapsedTime; + if (getDURATION() > elapsedTime) + { + return getDURATION() - elapsedTime; } - this.isFinished = true; - return 0L; - } - - public boolean equals(Object o) { - if (o instanceof Barrage) { - Barrage barrage = (Barrage)o; - return Text.standardize(this.getAffectedTarget().getName()).equals(Text.standardize(((Barrage)o).getAffectedTarget().getName())) && this.getStartTime() == ((Barrage)o).getStartTime(); + else + { + this.isFinished = true; + return 0; } - return false; } - public static long getDURATION() { - return 20000L; + public boolean equals(Object o) + { + if (o instanceof Barrage) + { + Barrage barrage = (Barrage) o; + if (Text.standardize(this.getAffectedTarget().getName()).equals(Text.standardize(((Barrage) o) + .getAffectedTarget().getName())) && this.getStartTime() == ((Barrage) o).getStartTime()) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } } - @Override - public boolean isFinished() { - return this.isFinished; - } } - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java index 1d7dbd162e..7f0a5aae81 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java @@ -16,9 +16,6 @@ import net.runelite.api.HeadIcon; import net.runelite.api.Player; import net.runelite.api.Point; import net.runelite.client.game.SpriteManager; -import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; -import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin; -import net.runelite.client.plugins.freezetimers.FreezeTimersService; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; @@ -27,7 +24,7 @@ import net.runelite.client.ui.overlay.OverlayUtil; @Singleton public class FreezeTimersOverlay -extends Overlay { + extends Overlay { private final FreezeTimersService FreezeTimersService; private final FreezeTimersConfig config; private final FreezeTimersPlugin plugin; @@ -59,10 +56,10 @@ extends Overlay { int timer = 0; String name = actor.getName(); int freezetype = this.plugin.freezetype(name); - boolean frozenoverlay = false; + boolean frozenoverlay = false; int offset = 5; long dtime = this.plugin.opponentfreezetime(name); - long tbed = plugin.istbed(name); + long tbed = plugin.istbed(name); Point textLocation = null; HeadIcon headIcon = actor.getOverheadIcon(); int freezetime = 0; @@ -97,7 +94,7 @@ extends Overlay { if (headIcon != null) { textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); } - frozenoverlay = true; + frozenoverlay = true; OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), this.config.RefreezeTimerColor()); return; } @@ -111,7 +108,7 @@ extends Overlay { graphics.setFont(FontManager.getRunescapeFont()); graphics.setStroke(new BasicStroke(3.0f)); if (this.config.spellIcon()) { - frozenoverlay = true; + frozenoverlay = true; graphics.drawOval(imageLocation.getX(), imageLocation.getY(), clanchatImage.getWidth(), clanchatImage.getHeight()); OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), color); @@ -124,34 +121,34 @@ extends Overlay { } } - if (config.TBTimer()) { - if (tbed > 0) { - int type = plugin.tbtype(name); - int tbexpiry; - if (type > 0) { - if (type == 1) { - tbexpiry = 300000; - } else if (type == 2) { - tbexpiry = 150000; - } else { - return; - } - long tbtime = currenttime - tbed; - int tbtimer = (tbexpiry - (int) tbtime) / 1000; - if (tbtime < tbexpiry) { - textLocation = actor.getCanvasTextLocation(graphics, Integer.toString(tbtimer), actor.getLogicalHeight() + config.FreezeTimerPos()); - if (frozenoverlay) { - textLocation = new Point(textLocation.getX() + 40, textLocation.getY() - config.FreezeTimerPos()); - } else { - textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); - } - } else { - plugin.deletetb(name); - } - } + if (config.TBTimer()) { + if (tbed > 0) { + int type = plugin.tbtype(name); + int tbexpiry; + if (type > 0) { + if (type == 1) { + tbexpiry = 300000; + } else if (type == 2) { + tbexpiry = 150000; + } else { + return; + } + long tbtime = currenttime - tbed; + int tbtimer = (tbexpiry - (int) tbtime) / 1000; + if (tbtime < tbexpiry) { + textLocation = actor.getCanvasTextLocation(graphics, Integer.toString(tbtimer), actor.getLogicalHeight() + config.FreezeTimerPos()); + if (frozenoverlay) { + textLocation = new Point(textLocation.getX() + 40, textLocation.getY() - config.FreezeTimerPos()); + } else { + textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); + } + } else { + plugin.deletetb(name); + } + } - } - } - } + } + } + } } 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 50f81cf94f..a8009d4ae8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java @@ -1,99 +1,86 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.freezetimers; - - - - +import net.runelite.api.events.*; +import net.runelite.client.eventbus.Subscribe; import com.google.inject.Provides; +import javax.inject.Inject; import java.awt.*; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; import java.awt.image.*; -import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferByte; -import java.awt.image.ImageObserver; -import java.awt.image.IndexColorModel; -import java.awt.image.WritableRaster; import java.util.*; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.inject.Inject; + import net.runelite.api.*; -import net.runelite.api.Actor; -import net.runelite.api.Client; -import net.runelite.api.events.*; -import net.runelite.api.GameState; -import net.runelite.api.HeadIcon; -import net.runelite.api.IndexedSprite; -import net.runelite.api.Player; -import net.runelite.api.Skill; + import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.AnimationChanged; -import net.runelite.api.events.ExperienceChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.freezetimers.Barrage; -import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; -import net.runelite.client.plugins.freezetimers.FreezeTimersOverlay; -import net.runelite.client.plugins.freezetimers.FreezeTimersTileOverlay; -import net.runelite.client.plugins.freezetimers.Spell; -import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ImageUtil; import org.slf4j.Logger; @PluginDescriptor( - name = "Freeze Timers", - description = "PVP Freeze Timers", - tags = {"PvP", "Freeze", "Timers"}, - type = "PVP" + name = "Freeze Timers", + description = "PVP Freeze Timers", + type = "PVP", + tags = {"PvP", "Freeze", "Timers", "pklite"} ) - -public class FreezeTimersPlugin -extends Plugin { +public class FreezeTimersPlugin extends Plugin +{ @Inject private OverlayManager overlayManager; + @Inject private FreezeTimersConfig config; + @Inject private FreezeTimersOverlay FreezeTimersOverlay; + @Inject private FreezeTimersTileOverlay FreezeTimersTileOverlay; + @Inject private Client client; + @Inject private SpriteManager spriteManager; - - private static final int[] FREEZE_ICONS = { - SpriteID.SPELL_BIND, - SpriteID.SPELL_SNARE, - SpriteID.SPELL_ENTANGLE, - SpriteID.SPELL_ICE_RUSH, - SpriteID.SPELL_ICE_BURST, - SpriteID.SPELL_ICE_BLITZ, - SpriteID.SPELL_ICE_BARRAGE, - SpriteID.SPELL_BIND, - SpriteID.SPELL_SNARE, - SpriteID.SPELL_ENTANGLE, - SpriteID.SPELL_TELE_BLOCK - }; - private static final Dimension FREEZE_ICON_DIMENSION = new Dimension(25, 25); + + @Provides + FreezeTimersConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(FreezeTimersConfig.class); + } + + private static final int[] FREEZE_ICONS = + { + SpriteID.SPELL_BIND, + SpriteID.SPELL_SNARE, + SpriteID.SPELL_ENTANGLE, + SpriteID.SPELL_ICE_RUSH, + SpriteID.SPELL_ICE_BURST, + SpriteID.SPELL_ICE_BLITZ, + SpriteID.SPELL_ICE_BARRAGE, + SpriteID.SPELL_BIND, + SpriteID.SPELL_SNARE, + SpriteID.SPELL_ENTANGLE, + SpriteID.SPELL_TELE_BLOCK + }; + + private static final Dimension FREEZE_ICON_DIMENSION = new Dimension(17, 17); private static final Color FREEZE_ICON_OUTLINE_COLOR = new Color(33, 33, 33); private final BufferedImage[] FreezeIcons = new BufferedImage[FREEZE_ICONS.length]; + private final int SPLASH_ID = 85; Map tbedthings = new HashMap<>(); Map tbtypes = new HashMap<>(); @@ -108,259 +95,333 @@ extends Plugin { String currtarget; String spell; - @Provides - FreezeTimersConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(FreezeTimersConfig.class); - } @Subscribe public void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { - this.loadFreezeIcons(); + loadFreezeIcons(); } } @Override protected void startUp() throws Exception { - this.overlayManager.add(this.FreezeTimersOverlay); - this.overlayManager.add(this.FreezeTimersTileOverlay); + overlayManager.add(FreezeTimersOverlay); + overlayManager.add(FreezeTimersTileOverlay); } @Override protected void shutDown() throws Exception { - this.overlayManager.remove(this.FreezeTimersOverlay); - this.overlayManager.remove(this.FreezeTimersTileOverlay); - this.frozenthings.clear(); - this.frozenthingpoints.clear(); - this.tbedthings.clear(); - this.tbtypes.clear(); + overlayManager.remove(FreezeTimersOverlay); + overlayManager.remove(FreezeTimersTileOverlay); + frozenthings.clear(); + frozenthingpoints.clear(); + tbedthings.clear(); + tbtypes.clear(); } + @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getMenuTarget().contains("->")) { - Pattern spattern = Pattern.compile(">(.+?)"); - Pattern ppattern = Pattern.compile("> (.+?)")) + { + final Pattern spattern = Pattern.compile(">(.+?)"); + final Pattern ppattern = Pattern.compile("> (.+?) 0 && this.currtarget != null) { - if (this.frozenthings.containsKey(this.currtarget)) { - this.currtarget = null; + if (xp > 0 && currtarget != null) + { + if (frozenthings.containsKey(currtarget)) + { + currtarget = null; return; } WorldPoint targetPosition = null; - for (Player player : this.client.getPlayers()) { - String playerName; - if (player == null || !(playerName = player.getName()).equals(this.currtarget)) continue; - if (player.getOverheadIcon() != null && player.getOverheadIcon().equals((Object)HeadIcon.MAGIC)) { - praymage = true; + for (Player player : client.getPlayers()) + { + if (player == null) + { + continue; + } + String playerName = player.getName(); + if (playerName.equals(currtarget)) + { + if (player.getOverheadIcon() != null) + { + if (player.getOverheadIcon().equals(HeadIcon.MAGIC)) + { + praymage = true; + } + } + targetPosition = player.getWorldLocation(); + break; } - targetPosition = player.getWorldLocation(); - break; } - if (targetPosition != null) { - if (this.spell.equals("Bind") && xp > 30) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - if (praymage) { - this.freezetype.put(this.currtarget, 8); - } else { - this.freezetype.put(this.currtarget, 1); + if (targetPosition != null) + { + if (spell.equals("Bind") && xp > 30) + { + frozenthings.put(currtarget, System.currentTimeMillis()); + frozenthingpoints.put(currtarget, targetPosition); + if (praymage) + { + freezetype.put(currtarget, 8); } - } else if (this.spell.equals("Snare") && xp > 60) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - if (praymage) { - this.freezetype.put(this.currtarget, 9); - } else { - this.freezetype.put(this.currtarget, 2); + else + { + freezetype.put(currtarget, 1); } - } else if (this.spell.equals("Entangle") && xp >= 89) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - if (praymage) { - this.freezetype.put(this.currtarget, 10); - } else { - this.freezetype.put(this.currtarget, 3); + } + else if (spell.equals("Snare") && xp > 60) + { + frozenthings.put(currtarget, System.currentTimeMillis()); + frozenthingpoints.put(currtarget, targetPosition); + if (praymage) + { + freezetype.put(currtarget, 9); } - } else if (this.spell.equals("Ice Rush") && xp > 34) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - this.freezetype.put(this.currtarget, 4); - } else if (this.spell.equals("Ice Burst") && xp > 40) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - this.freezetype.put(this.currtarget, 5); - } else if (this.spell.equals("Ice Blitz") && xp > 46) { - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - this.freezetype.put(this.currtarget, 6); - } else if (this.spell.equals("Ice Barrage") && xp > 52) { - Barrage barrage = new Barrage(this.client.getLocalPlayer().getInteracting(), this.client.getLocalPlayer()); - this.testMap.put(this.currtarget, barrage); - this.frozenthings.put(this.currtarget, System.currentTimeMillis()); - this.frozenthingpoints.put(this.currtarget, targetPosition); - this.freezetype.put(this.currtarget, 7); - } else if (spell.equals("Tele Block") && xp == 95) { - if (config.TBTimer()) { - if (praymage) { - this.tbtypes.put(this.currtarget, 2); - } else { - this.tbtypes.put(this.currtarget, 1); - } - this.tbedthings.put(this.currtarget, System.currentTimeMillis()); - } + else + { + freezetype.put(currtarget, 2); + } + } + else if (spell.equals("Entangle") && xp >= 89) + { + frozenthings.put(currtarget, System.currentTimeMillis()); + frozenthingpoints.put(currtarget, targetPosition); + if (praymage) + { + freezetype.put(currtarget, 10); + } + else + { + freezetype.put(currtarget, 3); + } + } + else if (spell.equals("Ice Rush") && xp > 34) + { + frozenthings.put(currtarget, System.currentTimeMillis()); + frozenthingpoints.put(currtarget, targetPosition); + freezetype.put(currtarget, 4); + } + else if (spell.equals("Ice Burst") && xp > 40) + { + frozenthings.put(currtarget, System.currentTimeMillis()); + frozenthingpoints.put(currtarget, targetPosition); + freezetype.put(currtarget, 5); + } + else if (spell.equals("Ice Blitz") && xp > 46) + { + frozenthings.put(currtarget, System.currentTimeMillis()); + frozenthingpoints.put(currtarget, targetPosition); + freezetype.put(currtarget, 6); + } + else if (spell.equals("Ice Barrage") && xp > 52) + { + Barrage barrage = new Barrage(client.getLocalPlayer().getInteracting(), client.getLocalPlayer()); + testMap.put(currtarget, barrage); + frozenthings.put(currtarget, System.currentTimeMillis()); + frozenthingpoints.put(currtarget, targetPosition); + freezetype.put(currtarget, 7); + } + } else if (spell.equals("Tele Block") && xp == 95) { + if (config.TBTimer()) { + if (praymage) { + tbtypes.put(currtarget, 2); + } else { + tbtypes.put(currtarget, 1); + } + tbedthings.put(currtarget, System.currentTimeMillis()); } } } - if (this.currtarget != null && this.ticks > this.currticks + 1) { - Player local = this.client.getLocalPlayer(); + if (currtarget != null && ticks > currticks + 1) + { + Player local = client.getLocalPlayer(); Actor interacting = local.getInteracting(); - if (interacting != null) { - if (!interacting.getName().equals(this.currtarget)) { - this.currtarget = null; + if (interacting != null) + { + if (!interacting.getName().equals(currtarget)) + { + currtarget = null; } - } else { - this.currtarget = null; + } + else + { + currtarget = null; } } - ++this.ticks; + ticks++; } - public long opponentfreezetime(String name) { - if (this.frozenthings.containsKey(name)) { - return this.frozenthings.get(name); + public long opponentfreezetime(String name) + { + if (frozenthings.containsKey(name)) + { + return frozenthings.get(name); } - return 0L; + return 0; } - public WorldPoint playerpos(String name) { - if (this.frozenthingpoints.containsKey(name)) { - return this.frozenthingpoints.get(name); + public WorldPoint playerpos(String name) + { + if (frozenthingpoints.containsKey(name)) + { + return frozenthingpoints.get(name); } return null; } - public void updatePosition(String name, WorldPoint point) { - if (this.frozenthingpoints.containsKey(name)) { - this.frozenthingpoints.remove(name); - this.frozenthingpoints.put(name, point); + public void updatePosition(String name, WorldPoint point) + { + if (frozenthingpoints.containsKey(name)) + { + frozenthingpoints.remove(name); + frozenthingpoints.put(name, point); } } - public int freezetype(String name) { - if (this.freezetype.containsKey(name)) { - return this.freezetype.get(name); + public int freezetype(String name) + { + if (freezetype.containsKey(name)) + { + return freezetype.get(name); } return 0; } - public long istbed(String name) { - if (this.tbedthings.containsKey(name)) { - return this.tbedthings.get(name); - } - return 0; - } - public int tbtype(String name) { - if (this.tbtypes.containsKey(name)) { - return this.tbtypes.get(name); - } - return 0; - } - public void deleteopponent(String name) { - if (this.frozenthings.containsKey(name)) { - this.frozenthings.remove(name); - } - if (this.frozenthingpoints.containsKey(name)) { - this.frozenthingpoints.remove(name); - } - if (this.freezetype.containsKey(name)) { - this.freezetype.remove(name); + + public long istbed(String name) { + if (tbedthings.containsKey(name)) { + return tbedthings.get(name); } + return 0; } - public void deletetb(String name) { - if (this.tbedthings.containsKey(name)) { - this.tbedthings.remove(name); - } - if (this.tbtypes.containsKey(name)) { - this.tbtypes.remove(name); - } - } - private void loadFreezeIcons() { - IndexedSprite[] freezeIcons = new IndexedSprite[]{}; - IndexedSprite[] newfreezeIcons = Arrays.copyOf(freezeIcons, FREEZE_ICONS.length); - int curPosition = 0; - int i = 0; - while (i < FREEZE_ICONS.length) { - int resource = FREEZE_ICONS[i]; - this.FreezeIcons[i] = FreezeTimersPlugin.rgbaToIndexedBufferedImage(FreezeTimersPlugin.FreezeIconFromSprite(this.spriteManager.getSprite(resource, 0))); - newfreezeIcons[curPosition] = FreezeTimersPlugin.createIndexedSprite(this.client, this.FreezeIcons[i]); - ++i; - ++curPosition; + public int tbtype(String name) { + if (tbtypes.containsKey(name)) { + return tbtypes.get(name); + } + return 0; + } + + public void deleteopponent(String name) + { + if (frozenthings.containsKey(name)) + { + frozenthings.remove(name); + } + if (frozenthingpoints.containsKey(name)) + { + frozenthingpoints.remove(name); + } + if (freezetype.containsKey(name)) + { + freezetype.remove(name); } } - private static IndexedSprite createIndexedSprite(Client client, BufferedImage bufferedImage) { - IndexColorModel indexedCM = (IndexColorModel)bufferedImage.getColorModel(); - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - byte[] pixels = ((DataBufferByte)bufferedImage.getRaster().getDataBuffer()).getData(); - int[] palette = new int[indexedCM.getMapSize()]; + public void deletetb(String name) { + if (tbedthings.containsKey(name)) { + tbedthings.remove(name); + } + if (tbtypes.containsKey(name)) { + tbtypes.remove(name); + } + } + + private void loadFreezeIcons() + { + final IndexedSprite[] freezeIcons = {}; + final IndexedSprite[] newfreezeIcons = Arrays.copyOf(freezeIcons, FREEZE_ICONS.length); + int curPosition = 0; + + for (int i = 0; i < FREEZE_ICONS.length; i++, curPosition++) + { + final int resource = FREEZE_ICONS[i]; + FreezeIcons[i] = rgbaToIndexedBufferedImage(FreezeIconFromSprite(spriteManager.getSprite(resource, 0))); + newfreezeIcons[curPosition] = createIndexedSprite(client, FreezeIcons[i]); + } + } + + private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) + { + final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel(); + + final int width = bufferedImage.getWidth(); + final int height = bufferedImage.getHeight(); + final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); + final int[] palette = new int[indexedCM.getMapSize()]; indexedCM.getRGBs(palette); - IndexedSprite newIndexedSprite = client.createIndexedSprite(); + + final IndexedSprite newIndexedSprite = client.createIndexedSprite(); newIndexedSprite.setPixels(pixels); newIndexedSprite.setPalette(palette); newIndexedSprite.setWidth(width); @@ -372,32 +433,40 @@ extends Plugin { return newIndexedSprite; } - private static BufferedImage rgbaToIndexedBufferedImage(BufferedImage sourceBufferedImage) { - BufferedImage indexedImage = new BufferedImage(sourceBufferedImage.getWidth(), sourceBufferedImage.getHeight(), 13); - ColorModel cm = indexedImage.getColorModel(); - IndexColorModel icm = (IndexColorModel)cm; - int size = icm.getMapSize(); - byte[] reds = new byte[size]; - byte[] greens = new byte[size]; - byte[] blues = new byte[size]; + private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) + { + final BufferedImage indexedImage = new BufferedImage( + sourceBufferedImage.getWidth(), + sourceBufferedImage.getHeight(), + BufferedImage.TYPE_BYTE_INDEXED); + + final ColorModel cm = indexedImage.getColorModel(); + final IndexColorModel icm = (IndexColorModel) cm; + + final int size = icm.getMapSize(); + final byte[] reds = new byte[size]; + final byte[] greens = new byte[size]; + final byte[] blues = new byte[size]; icm.getReds(reds); icm.getGreens(greens); icm.getBlues(blues); - WritableRaster raster = indexedImage.getRaster(); - int pixel = raster.getSample(0, 0, 0); - IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); - BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); + + final WritableRaster raster = indexedImage.getRaster(); + final int pixel = raster.getSample(0, 0, 0); + final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); + final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); return resultIndexedImage; } - private static BufferedImage FreezeIconFromSprite(BufferedImage freezeSprite) { - BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.width, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.height); + private static BufferedImage FreezeIconFromSprite(final BufferedImage freezeSprite) + { + final BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, FREEZE_ICON_DIMENSION.width, FREEZE_ICON_DIMENSION.height); return ImageUtil.outlineImage(freezeCanvas, FREEZE_ICON_OUTLINE_COLOR); } - BufferedImage GetFreezeIcon(int id) { - return this.FreezeIcons[id]; + BufferedImage GetFreezeIcon(int id) + { + return FreezeIcons[id]; } } - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java index 257aae69b8..912c106ba1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersService.java @@ -1,81 +1,123 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.freezetimers; import java.awt.Color; -import java.util.List; +import java.util.Objects; 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.api.coords.WorldPoint; -import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; -import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin; + @Singleton -public class FreezeTimersService { +public class FreezeTimersService +{ private final Client client; private final FreezeTimersConfig config; private final FreezeTimersPlugin plugin; @Inject - private FreezeTimersService(Client client, FreezeTimersConfig config, FreezeTimersPlugin plugin) { + private FreezeTimersService(Client client, FreezeTimersConfig config, FreezeTimersPlugin plugin) + { this.config = config; this.plugin = plugin; this.client = client; } - public void forEachPlayer(BiConsumer consumer) { - for (Player player : this.client.getPlayers()) { - if (player == null || player.getName() == null) continue; + public void forEachPlayer(final BiConsumer consumer) + { + + for (Player player : client.getPlayers()) + { + if (player == null || player.getName() == null) + { + continue; + } + String name = player.getName(); - int freezetype = this.plugin.freezetype(name); - long tbed = plugin.istbed(name); - long dtime = this.plugin.opponentfreezetime(name); + int freezetype = plugin.freezetype(name); + long dtime = plugin.opponentfreezetime(name); + long tbed = plugin.istbed(name); int freezetime = 0; - if (freezetype == 1 || freezetype == 4) { + if (freezetype == 1 || freezetype == 4) + { freezetime = 5000; - } else if (freezetype == 2 || freezetype == 5) { + } + else if (freezetype == 2 || freezetype == 5) + { freezetime = 10000; - } else if (freezetype == 3 || freezetype == 6) { + } + else if (freezetype == 3 || freezetype == 6) + { freezetime = 15000; - } else if (freezetype == 7) { + } + else if (freezetype == 7) + { freezetime = 20000; - } else if (freezetype == 8) { + } + else if (freezetype == 8) + { freezetime = 2500; - } else if (freezetype == 9) { + } + else if (freezetype == 9) + { freezetime = 5000; - } else if (freezetype == 10) { + } + else if (freezetype == 10) + { freezetime = 7500; } - if (dtime <= 0L) continue; - long currenttime = System.currentTimeMillis(); - long timediff = currenttime - dtime; - if (timediff < (long)freezetime) { - WorldPoint lastWorldPoint; - WorldPoint currentWorldPoint = player.getWorldLocation(); - if (currentWorldPoint.equals(lastWorldPoint = this.plugin.playerpos(name))) { - consumer.accept(player, this.config.FreezeTimerColor()); - continue; + if (dtime > 0) + { + long currenttime = System.currentTimeMillis(); + long timediff = currenttime - dtime; + if (timediff < freezetime) + { + WorldPoint currentWorldPoint = player.getWorldLocation(); + WorldPoint lastWorldPoint = plugin.playerpos(name); + if (currentWorldPoint.equals(lastWorldPoint)) + { + consumer.accept(player, config.FreezeTimerColor()); + } + else + { + if (timediff < 605) + { + plugin.updatePosition(name, currentWorldPoint); + consumer.accept(player, config.FreezeTimerColor()); + } + else + { + plugin.deleteopponent(name); + } + } } - if (timediff < 605L) { - this.plugin.updatePosition(name, currentWorldPoint); - consumer.accept(player, this.config.FreezeTimerColor()); - continue; + else + { + if (timediff < freezetime + 3000) + { + consumer.accept(player, Color.YELLOW); + } + else + { + plugin.deleteopponent(name); + } + if (tbed > 0) { + consumer.accept(player, config.FreezeTimerColor()); + return; + } } - this.plugin.deleteopponent(name); - continue; } - if (timediff < (long)(freezetime + 3000)) { - consumer.accept(player, Color.YELLOW); - continue; - } else { - this.plugin.deleteopponent(name); - } - if (tbed > 0) { - consumer.accept(player, config.FreezeTimerColor()); - return; - } } } } - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java index a945470c85..37eea87b7a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersTileOverlay.java @@ -1,46 +1,57 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.freezetimers; -import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Polygon; -import java.util.function.BiConsumer; import javax.inject.Inject; -import net.runelite.api.Player; -import net.runelite.client.plugins.freezetimers.FreezeTimersConfig; -import net.runelite.client.plugins.freezetimers.FreezeTimersService; 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 FreezeTimersTileOverlay -extends Overlay { +public class FreezeTimersTileOverlay extends Overlay +{ private final FreezeTimersService FreezeTimersService; private final FreezeTimersConfig config; @Inject - private FreezeTimersTileOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2) { + private FreezeTimersTileOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService) + { this.config = config; - this.FreezeTimersService = FreezeTimersService2; - this.setLayer(OverlayLayer.ABOVE_SCENE); - this.setPosition(OverlayPosition.DYNAMIC); - this.setPriority(OverlayPriority.MED); + this.FreezeTimersService = FreezeTimersService; + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.MED); } @Override - public Dimension render(Graphics2D graphics) { - if (!this.config.drawTiles()) { + public Dimension render(Graphics2D graphics) + { + if (!config.drawTiles()) + { return null; } - this.FreezeTimersService.forEachPlayer((player, color) -> { - Polygon poly = player.getCanvasTilePoly(); - if (poly != null) { + + FreezeTimersService.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/freezetimers/PlayerSpellEffect.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java index 8bc136fbb5..a2d47b7695 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/PlayerSpellEffect.java @@ -1,35 +1,41 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.freezetimers; -public enum PlayerSpellEffect { +import lombok.Getter; +import lombok.Setter; + +public enum PlayerSpellEffect +{ + + BARRAGE("Ice Barrage", 20000, false), BLITZ("Ice Blitz", 15000, false); - - private final String SPELL_NAME; - private long startTime; - private int duration; - private boolean halvable; - private PlayerSpellEffect(String name, int duration, boolean halvable) { + @Getter + private final String SPELL_NAME; + @Getter + private long startTime; + @Getter + private int duration; + @Getter + private boolean halvable; + //private final BufferedImage SPELL_ICON; + + + + PlayerSpellEffect(String name, int duration, boolean halvable) + { this.SPELL_NAME = name; this.duration = duration; this.halvable = halvable; this.startTime = System.currentTimeMillis(); } - - public String getSPELL_NAME() { - return this.SPELL_NAME; - } - - public long getStartTime() { - return this.startTime; - } - - public int getDuration() { - return this.duration; - } - - public boolean isHalvable() { - return this.halvable; - } } - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java index d9033a7c0d..5407951aa8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/Spell.java @@ -1,34 +1,34 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.freezetimers; +import lombok.Getter; import net.runelite.api.Actor; -public abstract class Spell { +public abstract class Spell +{ + + @Getter private final Actor affectedTarget; + @Getter private final Actor caster; + @Getter public final long startTime; private long remainingTime; + @Getter private boolean isFinished; - protected Spell(Actor affectedTarget, Actor caster) { + protected Spell(Actor affectedTarget, Actor caster) + { this.affectedTarget = affectedTarget; this.caster = caster; - this.startTime = System.currentTimeMillis(); - } - - public Actor getAffectedTarget() { - return this.affectedTarget; - } - - public Actor getCaster() { - return this.caster; - } - - public long getStartTime() { - return this.startTime; - } - - public boolean isFinished() { - return this.isFinished; + startTime = System.currentTimeMillis(); } } - 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 index e61b94fc95..e55b528c11 100644 --- 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 @@ -1,74 +1,70 @@ /* - * Decompiled with CFR 0.139. + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * */ + package net.runelite.client.plugins.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; +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionListener; +import java.util.List; - 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); - } +public class CurrentPlayersJFrame extends JFrame +{ + + public JList currentPlayersJList; + + CurrentPlayersJFrame(Client client, PvpToolsPlugin pvpToolsPlugin, List list) + { + super(); + 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"); + currentPlayersJList = new JList(list.toArray()); + ActionListener copyButtonActionListener = e -> + { + StringSelection stringSelection; + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringBuilder stringBuilder = new StringBuilder(); + list.forEach(s -> + { + stringBuilder.append(s); + stringBuilder.append(System.getProperty("line.separator")); + }); + stringSelection = new StringSelection(stringBuilder.toString()); + clipboard.setContents(stringSelection, stringSelection); + }; + copyJButton.addActionListener(copyButtonActionListener); + this.setTitle("Current CC Members"); + this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + JLabel titleLabel = new JLabel("Current CC Members"); + titleLabel.setFont(FontManager.getRunescapeFont().deriveFont(Font.BOLD, 18)); + currentPlayersJList.setFont(new Font("Arial", Font.PLAIN, 14)); + scrollContainerCurrent.add(refreshJButton, BorderLayout.NORTH); + scrollContainerCurrent.add(titleLabel, BorderLayout.CENTER); + JPanel footerPanel = new JPanel(new BorderLayout()); + footerPanel.add(currentPlayersJList, BorderLayout.NORTH); + footerPanel.add(copyJButton, BorderLayout.CENTER); + scrollContainerCurrent.add(footerPanel, BorderLayout.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 index 324db3869a..a30dd9a04e 100644 --- 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 @@ -1,74 +1,79 @@ /* - * Decompiled with CFR 0.139. + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * */ + package net.runelite.client.plugins.pvptools; import java.awt.BorderLayout; -import java.awt.Canvas; -import java.awt.Component; -import java.awt.Dimension; +import java.awt.Container; 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 java.util.Vector; 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.ClanMember; 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; +public class MissingPlayersJFrame extends JFrame +{ - 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); - } + public JList missingPlayersJList; + + MissingPlayersJFrame(Client client, PvpToolsPlugin pvpToolsPlugin, List list) + { + super(); + 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"); + missingPlayersJList = new JList(list.toArray()); + ActionListener copyButtonActionListener = e -> + { + StringSelection stringSelection; + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringBuilder stringBuilder = new StringBuilder(); + list.forEach(s -> + { + stringBuilder.append(s); + stringBuilder.append(System.getProperty("line.separator")); + }); + stringSelection = new StringSelection(stringBuilder.toString()); + clipboard.setContents(stringSelection, stringSelection); + }; + copyJButton.addActionListener(copyButtonActionListener); + this.setTitle("Missing CC Members"); + this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + JLabel titleLabel = new JLabel("Missing CC Members"); + titleLabel.setFont(FontManager.getRunescapeFont().deriveFont(Font.BOLD, 18)); + missingPlayersJList.setFont(new Font("Arial", Font.PLAIN, 14)); + scrollConatiner.add(refreshJButton, BorderLayout.NORTH); + scrollConatiner.add(titleLabel, BorderLayout.CENTER); + JPanel footerPanel = new JPanel(new BorderLayout()); + footerPanel.add(missingPlayersJList, BorderLayout.NORTH); + footerPanel.add(copyJButton, BorderLayout.CENTER); + scrollConatiner.add(footerPanel, BorderLayout.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 index d88182db0e..a6a1392763 100644 --- 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 @@ -1,69 +1,147 @@ /* - * Decompiled with CFR 0.139. + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * */ + package net.runelite.client.plugins.pvptools; +import java.awt.Color; +import java.security.Key; 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; - } +@ConfigGroup("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 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 = "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 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 = "fallInHelper", + name = "Fall In Helper", + description = "Hides all non-friendly player entities other than the one that is attacking you.", + position = 5 + ) + default 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 = "hotkey", + name = "Fall In Hotkey", + description = "Turns the fall in helper on or off when you press this hotkey", + position = 6 + ) + default 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 = "attackOptionsClan", + name = "Move CC Attack Option", + description = "Moves the attack option for people in the same CC", + position = 7, + group = "Right-Click Attack Options" + ) + default 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 = "attackOptionsFriend", + name = "Move Friend Attack Options", + description = "Moves the attack option for people on your friends list", + position = 8, + group = "Right-Click Attack Options" + ) + default 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 = "attackOptionsHotkey", + name = "Attack Option Hotkey", + description = "Enables a hotkey for attack options to disable or enable hiding quickly", + position = 10, + group = "Right-Click Attack Options" + ) + default 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 = "levelRangeAttackOptions", + name = "Moves Other Attack Options", + description = "Moves the attack option for people that are outside your level range", + position = 9, + group = "Right-Click Attack Options" + ) + default 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 = "riskCalculator", + name = "Risk Calculator", + description = "Enables a panel in the PvP Tools Panel that shows the players current risk", + position = 13 + ) + default 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 = "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 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 boolean currentPlayersEnabled() + { + 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 index b24b66dab7..f9abf719c7 100644 --- 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 @@ -1,21 +1,23 @@ /* - * Decompiled with CFR 0.139. + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * */ + package net.runelite.client.plugins.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 java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; import javax.inject.Inject; + +import net.runelite.api.Actor; import net.runelite.api.Client; +import net.runelite.api.Player; 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; @@ -23,39 +25,47 @@ 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; +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); - } - } + @Inject + private PvpToolsOverlay(PvpToolsConfig pvpToolsConfig, PvpToolsPlugin pvpToolsPlugin, Client client) + { + this.pvpToolsPlugin = pvpToolsPlugin; + this.pvpToolsConfig = pvpToolsConfig; + this.client = client; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPriority(OverlayPriority.HIGH); + setPosition(OverlayPosition.DYNAMIC); } + + @Override + public Dimension render(Graphics2D graphics) + { + if (pvpToolsConfig.fallInHelper()) + { + if (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)); + 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 index 8856c37b32..9d82932fa2 100644 --- 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 @@ -1,138 +1,166 @@ /* - * Decompiled with CFR 0.139. + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * */ + package net.runelite.client.plugins.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 lombok.extern.slf4j.Slf4j; 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(); +@Slf4j +public class PvpToolsPanel extends PluginPanel +{ - public static String htmlLabel(String key, String value) { - return "" + key + "" + value + ""; - } + 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(); - 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 static String htmlLabel(String key, String value) + { + return "" + key + "" + value + ""; + } - public void disablePrayerCount() { - this.numMageJLabel.setText("disabled"); - this.numRangeJLabel.setText("disabled"); - this.numMeleeJLabel.setText("disabled"); - this.numMageJLabel.repaint(); - this.numRangeJLabel.repaint(); - this.numMeleeJLabel.repaint(); - } + void init() + { + setLayout(new BorderLayout()); + setBackground(ColorScheme.DARK_GRAY_COLOR); + setBorder(new EmptyBorder(10, 10, 10, 10)); - public void disableRiskCalculator() { - this.totalRiskLabel.setText("disabled"); - this.riskProtectingItem.setText("disabled"); - this.biggestItemLabel.setText("disabled"); - this.totalRiskLabel.repaint(); - this.riskProtectingItem.repaint(); - this.biggestItemLabel.repaint(); - } + + + 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)); + + final Font smallFont = FontManager.getRunescapeSmallFont(); + + numCC.setText(htmlLabel("Friendly Player Count: ", "0")); + numOther.setText(htmlLabel("Other Player Count: ", "0")); + numBrews.setText(htmlLabel("Player brew count: ", "0")); + numMageJLabel.setText(htmlLabel("Enemies Praying Mage: ", "0")); + numMageJLabel.setFont(FontManager.getRunescapeFont()); + numRangeJLabel.setText(htmlLabel("Enemies Praying Range: ", "0")); + numRangeJLabel.setFont(FontManager.getRunescapeFont()); + numMeleeJLabel.setText(htmlLabel("Enemies Praying Melee: ", "0")); + numMeleeJLabel.setFont(FontManager.getRunescapeFont()); + + totalRiskLabel.setText(htmlLabel("Total risk: ", "0")); + totalRiskLabel.setFont(FontManager.getRunescapeFont()); + riskProtectingItem.setText(htmlLabel("Risk Protecting Item: ", "0")); + riskProtectingItem.setFont(FontManager.getRunescapeFont()); + biggestItemLabel.setText("Most Valuable Item: "); + + + JLabel revision = new JLabel(); + revision.setFont(smallFont); + + revision.setText("Oldschool revision: "); + + JLabel launcher = new JLabel(htmlLabel("Launcher version: ", MoreObjects + .firstNonNull(RuneLiteProperties.getLauncherVersion(), "Unknown"))); + launcher.setFont(smallFont); + + loggedLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + loggedLabel.setFont(smallFont); + + emailLabel.setForeground(Color.WHITE); + emailLabel.setFont(smallFont); + + versionPanel.add(numCC); + versionPanel.add(numOther); + versionPanel.add(numBrews); + versionPanel.add(numMageJLabel); + versionPanel.add(numRangeJLabel); + versionPanel.add(numMeleeJLabel); + + versionPanel.add(Box.createGlue()); + versionPanel.add(loggedLabel); + versionPanel.add(emailLabel); + + riskPanel.add(totalRiskLabel); + riskPanel.add(riskProtectingItem); + riskPanel.add(biggestItemLabel); + + add(versionPanel, BorderLayout.NORTH); + add(riskPanel, BorderLayout.CENTER); + + currentPlayers.setVisible(false); + missingPlayers.setVisible(false); + missingPlayersPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + missingPlayersPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); + missingPlayersPanel.setLayout(new GridLayout(0, 1)); + missingPlayersPanel.add(missingPlayers, BorderLayout.AFTER_LAST_LINE); + missingPlayersPanel.add(currentPlayers, BorderLayout.AFTER_LAST_LINE); + add(missingPlayersPanel, BorderLayout.AFTER_LAST_LINE); + + } + + 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 index 4bf40b3a9a..b36894ab54 100644 --- 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 @@ -1,475 +1,691 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.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.*; +import com.google.inject.Provides; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.NavigableMap; +import java.util.Objects; +import java.util.TreeMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ScheduledExecutorService; +import java.util.stream.Collectors; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.ClanMember; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemComposition; +import net.runelite.api.MenuEntry; +import net.runelite.api.Player; +import net.runelite.api.SkullIcon; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.FocusChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.ItemContainerChanged; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.PlayerDespawned; +import net.runelite.api.events.PlayerSpawned; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.AsyncBufferedImage; +import net.runelite.client.game.ClanManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.input.KeyManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginManager; +import net.runelite.client.plugins.clanchat.ClanChatPlugin; +import static net.runelite.client.plugins.pvptools.PvpToolsPanel.htmlLabel; +import net.runelite.client.ui.ClientToolbar; +import net.runelite.client.ui.NavigationButton; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.HotkeyListener; +import net.runelite.client.util.ImageUtil; +import net.runelite.client.util.PvPUtil; +import static net.runelite.client.util.StackFormatter.quantityToRSDecimalStack; +import net.runelite.client.util.Text; +import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( - name = "PvP Tools", - description = "Enable the PvP Tools panel", - tags = { "panel", "pvp", "pk", "pklite" }, - type="PVP" + name = "PvP Tools", + description = "Enable the PvP Tools panel", + tags = {"panel", "pvp", "pk", "pklite"} ) 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; + @Inject + PvpToolsOverlay pvpToolsOverlay; + boolean fallinHelperEnabled = false; + private PvpToolsPanel panel; + private MissingPlayersJFrame missingPlayersJFrame; + private CurrentPlayersJFrame currentPlayersJFrame; + private NavigationButton navButton; + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private boolean attackHotKeyPressed; + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private boolean hideAll; + @Inject + private ScheduledExecutorService executorService; + @Inject + private OverlayManager overlayManager; + @Inject + private Client client; + @Inject + private ItemManager itemManager; + private PvpToolsPlugin uhPvpToolsPlugin = this; - 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; + /** + * ActionListener for the missing cc members and refresh buttons + */ + final ActionListener playersButtonActionListener = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if (missingPlayersJFrame != null) + { + missingPlayersJFrame.dispose(); + missingPlayersJFrame = null; + missingPlayersJFrame = new MissingPlayersJFrame(client, uhPvpToolsPlugin, getMissingMembers()); + } + else + { + missingPlayersJFrame = new MissingPlayersJFrame(client, uhPvpToolsPlugin, getMissingMembers()); + } + } + }; - @Override - public void keyPressed(final KeyEvent e) { - PvpToolsPlugin.this.attackHotKeyPressed = true; - } + final ActionListener currentPlayersActionListener = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if (currentPlayersJFrame != null) + { + currentPlayersJFrame.dispose(); + currentPlayersJFrame = null; + currentPlayersJFrame = new CurrentPlayersJFrame(client, uhPvpToolsPlugin, getCurrentMembers()); + } + else + { + currentPlayersJFrame = new CurrentPlayersJFrame(client, uhPvpToolsPlugin, getCurrentMembers()); + } + } + }; - @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; - } + @Inject + private ClientToolbar clientToolbar; - 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; - } + @Inject + private KeyManager keyManager; - @Provides - PvpToolsConfig config(final ConfigManager configManager) { - return configManager.getConfig(PvpToolsConfig.class); - } + @Inject + private PvpToolsConfig config; - @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); - } - } + @Inject + private PluginManager pluginManager; - @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); - } + @Inject + private ClanManager clanManager; - @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(); - } - } + private ClanChatPlugin clanChatPlugin; + /** + * The HotKeyListener for the hot key assigned in the config that triggers the Fall In Helper feature + */ + private final HotkeyListener hotkeyListener = new HotkeyListener(() -> config.hotkey()) + { + public void hotkeyPressed() + { + toggleFallinHelper(); + } + }; - @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(); - } - } + private final HotkeyListener attackOptionsHotKeyListener = new HotkeyListener(() -> config.attackOptionsHotkey()) + { + long lastPress = 0; - @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(); - } - } + @Override + public void keyPressed(KeyEvent e) + { + attackHotKeyPressed = true; + } - @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); - } - } - } - } + @Override + public void keyReleased(KeyEvent e) + { + attackHotKeyPressed = (System.currentTimeMillis() - lastPress) < 800; + lastPress = System.currentTimeMillis(); + } + }; - 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); - } + private int[] overheadCount = new int[]{0, 0, 0}; - @Subscribe - public void onFocusChanged(final FocusChanged focusChanged) { - if (!focusChanged.isFocused()) { - this.setAttackHotKeyPressed(false); - } - } + private Comparator itemPriceComparator = new Comparator() + { + @Override + public int compare(Item o1, Item o2) + { + return (itemManager.getItemPrice(itemManager.getItemComposition(o1.getId()).getPrice()) + - itemManager.getItemPrice(itemManager.getItemComposition(o2.getId()).getPrice())); + } + }; + private String mtarget; - 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; - } - } + public List getMissingMembers() + { + CopyOnWriteArrayList ccMembers = ClanChatPlugin.getClanMembers(); + ArrayList missingMembers = new ArrayList(); + for (ClanMember clanMember:client.getClanMembers()) + { + if (!Objects.isNull(clanMember)) + { + List arrayList = ccMembers.stream().map(player -> Text.removeTags(Text.standardize(player.getName()))).collect(Collectors.toList()); + if (!arrayList.contains(Text.removeTags(Text.standardize(clanMember.getUsername())))) + { + if (!missingMembers.contains(clanMember.getUsername())) + { + missingMembers.add("[W" + clanMember.getWorld() + "] - " + clanMember.getUsername()); + } + } + } + } - 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(); - } + return missingMembers; - 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(); - } - } + //Arrays.stream(Arrays.stream(client.getClanMembers()).filter(Objects::nonNull).map(ClanMember::getUsername) + //.toArray()).collect(Collectors.toList()); + } - 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(); - } + public List getCurrentMembers() + { + CopyOnWriteArrayList ccMembers = ClanChatPlugin.getClanMembers(); + ArrayList currentMembers = new ArrayList(); + for (ClanMember clanMember:client.getClanMembers()) + { + if (!Objects.isNull(clanMember)) + { + List arrayList = ccMembers.stream().map(player -> Text.removeTags(Text.standardize(player.getName()))).collect(Collectors.toList()); + if (arrayList.contains(Text.removeTags(Text.standardize(clanMember.getUsername())))) + { + if (!currentMembers.contains(clanMember.getUsername())) + { + currentMembers.add(clanMember.getUsername()); + } + } + } + } - 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(); - } + return currentMembers; - boolean isAttackHotKeyPressed() { - return this.attackHotKeyPressed; - } + //Arrays.stream(Arrays.stream(client.getClanMembers()).filter(Objects::nonNull).map(ClanMember::getUsername) + //.toArray()).collect(Collectors.toList()); + } - void setAttackHotKeyPressed(final boolean attackHotKeyPressed) { - this.attackHotKeyPressed = attackHotKeyPressed; - } - boolean isHideAll() { - return this.hideAll; - } - void setHideAll(final boolean hideAll) { - this.hideAll = hideAll; - } + @Provides + PvpToolsConfig config(ConfigManager configManager) + { + return configManager.getConfig(PvpToolsConfig.class); + } + + @Override + protected void startUp() throws Exception + { + + overlayManager.add(pvpToolsOverlay); + + keyManager.registerKeyListener(hotkeyListener); + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "skull.png"); + + panel = new PvpToolsPanel(); + panel.init(); + + navButton = NavigationButton.builder() + .tooltip("PvP Tools") + .icon(icon) + .priority(5) + .panel(panel) + .build(); + + panel.missingPlayers.addActionListener(playersButtonActionListener); + panel.currentPlayers.addActionListener(currentPlayersActionListener); + clientToolbar.addNavigation(navButton); + + + keyManager.registerKeyListener(attackOptionsHotKeyListener); + + if (config.missingPlayersEnabled()) + { + panel.missingPlayers.setVisible(true); + } + + if (config.currentPlayersEnabled()) + { + panel.currentPlayers.setVisible(true); + } + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(pvpToolsOverlay); + keyManager.unregisterKeyListener(hotkeyListener); + keyManager.unregisterKeyListener(attackOptionsHotKeyListener); + clientToolbar.removeNavigation(navButton); + } + + @Subscribe + public void onConfigChanged(ConfigChanged configChanged) + { + if (configChanged.getGroup().equals("pvptools")) + { + switch (configChanged.getKey()) + { + case "countPlayers": + if (config.countPlayers()) + { + updatePlayers(); + } + if (!config.countPlayers()) + { + panel.disablePlayerCount(); + } + break; + case "countOverHeads": + if (config.countOverHeads()) + { + countOverHeads(); + } + if (!config.countOverHeads()) + { + panel.disablePrayerCount(); + } + break; + case "riskCalculator": + if (config.riskCalculatorEnabled()) + { + getCarriedWealth(); + } + if (!config.riskCalculatorEnabled()) + { + panel.disableRiskCalculator(); + } + break; + case "missingPlayers": + if (config.missingPlayersEnabled()) + { + panel.missingPlayers.setVisible(true); + } + break; + case "currentPlayers": + if (config.currentPlayersEnabled()) + { + panel.currentPlayers.setVisible(true); + } + break; + default: + break; + } + } + } + + @Subscribe + public void onItemContainerChanged(ItemContainerChanged event) + { + if (event.getItemContainer().equals(client.getItemContainer(InventoryID.INVENTORY)) && + config.riskCalculatorEnabled()) + { + getCarriedWealth(); + } + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState().equals(GameState.LOGGED_IN) && config.riskCalculatorEnabled()) + { + getCarriedWealth(); + } + if (event.getGameState().equals(GameState.LOGGED_IN)) + { + if (config.countPlayers()) + { + updatePlayers(); + } + } + } + + @Subscribe + public void onPlayerSpawned(PlayerSpawned event) + { + if (config.countPlayers() && PvPUtil.isAttackable(client, event.getPlayer())) + { + updatePlayers(); + } + if (config.countOverHeads()) + { + countOverHeads(); + } + } + + @Subscribe + public void onPlayerDespawned(PlayerDespawned event) + { + if (config.countPlayers() && PvPUtil.isAttackable(client, event.getPlayer())) + { + updatePlayers(); + } + if (config.countOverHeads()) + { + countOverHeads(); + } + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) + { + if (!attackHotKeyPressed) + { + if (config.attackOptionsFriend() || config.attackOptionsClan() || config.levelRangeAttackOptions()) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + return; + } + Player[] players = client.getCachedPlayers(); + Player player = null; + 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 (attackHotKeyPressed && config.attackOptionsClan() || config.attackOptionsFriend() || + config.levelRangeAttackOptions()) + { + if (config.attackOptionsFriend() && player.isFriend()) + { + moveEntry(mtarget); + } + if (config.attackOptionsClan() && player.isClanMember()) + { + moveEntry(mtarget); + } + if (config.levelRangeAttackOptions() && !PvPUtil.isAttackable(client, player)) + { + moveEntry(mtarget); + } + } + } + } + } + + + private void moveEntry(String mtarget) + { + this.mtarget = mtarget; + MenuEntry[] menuEntries = client.getMenuEntries(); + MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; + + // strip out existing '); + if (idx != -1) + { + target = target.substring(idx + 1); + } + /*System.out.println("Contents : " + lastEntry.getTarget()); + System.out.println("Contents : " + lastEntry.getIdentifier()); + System.out.println("Contents : " + lastEntry.getOption()); + System.out.println("length : " + menuEntries.length);*/ + if (menuEntries[menuEntries.length - 1] != null) + { + //System.out.println(menuEntries.length + ": " + menuEntries[menuEntries.length-1]); + } + if (lastEntry.getOption().contains("attack".toLowerCase())) + { + ArrayUtils.shift(menuEntries, 1); + //ArrayUtils.add(menuEntries, menuEntries.length - 2); + //menuEntries = ArrayUtils.remove(menuEntries, menuEntries.length - 1); + //menuEntrySwapperPlugin.swap("attack", option, mtarget, false); + } + if (lastEntry.getOption().equals("Attack")) + { + ArrayUtils.shift(menuEntries, 1); + + //menuEntries = ArrayUtils.sremove(menuEntries, menuEntries.length - 1); + //menuEntrySwapperPlugin.swap("attack", option, mtarget, false); + } + client.setMenuEntries(menuEntries); + + } + + @Subscribe + public void onFocusChanged(FocusChanged focusChanged) + { + if (!focusChanged.isFocused()) + { + setAttackHotKeyPressed(false); + } + } + + /** + * Enables or disables the fall in helper feature + */ + private void toggleFallinHelper() + { + if (!fallinHelperEnabled) + { + client.setIsHidingEntities(true); + client.setPlayersHidden(true); + fallinHelperEnabled = true; + } + else + { + client.setIsHidingEntities(false); + client.setPlayersHidden(false); + fallinHelperEnabled = false; + } + + } + + /** + * Updates the PvP Tools panel with the numbers for enemy protection prayers + */ + private void updatePrayerNumbers() + { + panel.numMageJLabel.setText(htmlLabel("Enemies Praying Mage: ", String.valueOf(overheadCount[0]))); + panel.numRangeJLabel.setText(htmlLabel("Enemies Praying Range: ", String.valueOf(overheadCount[1]))); + panel.numMeleeJLabel.setText(htmlLabel("Enemies Praying Melee: ", String.valueOf(overheadCount[2]))); + panel.numMageJLabel.repaint(); + panel.numRangeJLabel.repaint(); + panel.numMeleeJLabel.repaint(); + } + + /** + * + */ + private void updatePlayers() + { + if (config.countPlayers()) + { + int cc = 0; + int other = 0; + for (Player p : client.getPlayers()) + { + if (Objects.nonNull(p)) + { + if (PvPUtil.isAttackable(client, p)) + { + if (p.isClanMember()) + { + cc++; + } + else + { + other++; + } + } + } + } + + panel.numOther.setText(htmlLabel("Other Player Count: ", String.valueOf(other))); + panel.numCC.setText(htmlLabel("Friendly Player Count: ", String.valueOf(cc))); + panel.numCC.repaint(); + panel.numOther.repaint(); + } + } + + private void countOverHeads() + { + overheadCount = new int[]{0, 0, 0}; + for (Player p : client.getPlayers()) + { + if (Objects.nonNull(p)) + { + if (PvPUtil.isAttackable(client, p)) + { + if (!p.isClanMember() && !(p.getOverheadIcon() == null)) + { + switch (p.getOverheadIcon()) + { + case MAGIC: + overheadCount[0]++; + break; + case RANGED: + overheadCount[1]++; + break; + case MELEE: + overheadCount[2]++; + break; + } + } + } + } + } + updatePrayerNumbers(); + } + + /** + * Calculates the player's risk based on Item Price of all items in their inventory and equipment + */ + private void getCarriedWealth() + { + if (!config.riskCalculatorEnabled()) + { + return; + } + if (client.getItemContainer(InventoryID.EQUIPMENT) == null) + { + return; + } + if (client.getItemContainer(InventoryID.INVENTORY).getItems() == null) + { + return; + } + Item[] items = ArrayUtils.addAll(Objects.requireNonNull(client.getItemContainer(InventoryID.EQUIPMENT)).getItems(), + Objects.requireNonNull(client.getItemContainer(InventoryID.INVENTORY)).getItems()); + TreeMap priceMap = new TreeMap<>(Comparator.comparingInt(Integer::intValue)); + int wealth = 0; + for (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(value, i); + } + else + { + value = itemManager.getItemPrice(i.getId()) * i.getQuantity(); + if (i.getId() > 0 && value > 0) + { + priceMap.put(value, i); + } + } + wealth += value; + } + panel.totalRiskLabel.setText(htmlLabel("Total risk: ", quantityToRSDecimalStack(wealth))); + panel.totalRiskLabel.repaint(); + + int itemLimit = 0; + if (client.getLocalPlayer().getSkullIcon() != null) + { + if (client.getLocalPlayer().getSkullIcon() == SkullIcon.SKULL) + { + itemLimit = 1; + } + } + if (client.getLocalPlayer().getSkullIcon() == null) + { + itemLimit = 4; + } + + AsyncBufferedImage itemImage = null; + + NavigableMap descendingMap = priceMap.descendingMap(); + + for (int i = 0; i < itemLimit; i++) + { + if (i == 0) + { + if (!descendingMap.isEmpty()) + { + itemImage = itemManager.getImage(descendingMap.pollFirstEntry().getValue().getId()); + } + } + else + { + if (!descendingMap.isEmpty()) + { + itemManager.getItemComposition(priceMap.descendingMap().pollFirstEntry().getValue().getId()) + .getName(); + } + } + } + panel.riskProtectingItem.setText(htmlLabel("Risk Protecting Item: ", + quantityToRSDecimalStack(descendingMap.keySet().stream().mapToInt(Integer::intValue).sum()))); + panel.riskProtectingItem.repaint(); + + panel.biggestItemLabel.setText("Most Valuable Item: "); + if (itemImage != null) + { + itemImage.addTo(panel.biggestItemLabel); + } + panel.biggestItemLabel.repaint(); + } + } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java index f7034af63f..9212432d7e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java @@ -63,6 +63,7 @@ import java.awt.image.BufferedImage; name = "Supplies Used Tracker", description = "Tracks supplies used during the session", tags = {"cost"}, + type = "PVM", enabledByDefault = false ) @Slf4j diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersConfig.java index 75436c045c..9da7fa9ece 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersConfig.java @@ -1,34 +1,68 @@ package net.runelite.client.plugins.whalewatchers; -import java.awt.*; -import net.runelite.client.config.*; +import java.awt.Color; +import net.runelite.client.config.Alpha; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; @ConfigGroup("WhaleWatchers") public interface WhaleWatchersConfig extends Config { - @ConfigItem(position = 1, keyName = "protectItemWarning", name = "Protect Item Warning", description = "Warns you when you are skulled and don't have protect item turned on.") - default boolean protectItemWarning() { - return false; - } - - @ConfigItem(position = 2, keyName = "showDamageCounter", name = "Damage Counter", description = "Shows damage you've done and damage your opponent has done to you while in a fight") - default boolean showDamageCounter() { - return true; - } - - @Alpha - @ConfigItem(position = 3, keyName = "damageBackgroundColor", name = "Counter Background Color", description = "The background color for the damage counter overlay") - default Color damageBackgroundColor() { - return Color.darkGray; - } - - @ConfigItem(position = 4, keyName = "smiteableWarning", name = "Smite Warning", description = "Displays a warning overlay when your prayer is at a smiteable level") - default boolean smiteableWarning() { - return true; - } - - @ConfigItem(position = 5, keyName = "gloryWarning", name = "Glory Warning", description = "Displays a warning box while you are wearing an uncharged glory") - default boolean gloryWarning() { - return true; - } + + @ConfigItem( + position = 1, + keyName = "protectItemWarning", + name = "Protect Item Warning", + description = "Warns you when you are skulled and don't have protect item turned on." + ) + default boolean protectItemWarning() + { + return false; + } + + @ConfigItem( + position = 2, + keyName = "showDamageCounter", + name = "Damage Counter", + description = "Shows damage you've done and damage your opponent has done to you while in a fight" + ) + default boolean showDamageCounter() + { + return true; + } + + @Alpha + @ConfigItem( + position = 3, + keyName = "damageBackgroundColor", + name = "Counter Background Color", + description = "The background color for the damage counter overlay" + ) + default Color damageBackgroundColor() + { + return Color.darkGray; + } + + @ConfigItem( + position = 4, + keyName = "smiteableWarning", + name = "Smite Warning", + description = "Displays a warning overlay when your prayer is at a smiteable level" + ) + default boolean smiteableWarning() + { + return true; + } + + @ConfigItem( + position = 5, + keyName = "gloryWarning", + name = "Glory Warning", + description = "Displays a warning box while you are wearing an uncharged glory" + ) + default boolean gloryWarning() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersGloryOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersGloryOverlay.java index dd30579485..61bfaf0d47 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersGloryOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersGloryOverlay.java @@ -1,48 +1,72 @@ package net.runelite.client.plugins.whalewatchers; -import net.runelite.api.*; -import javax.inject.*; -import net.runelite.client.ui.overlay.*; -import net.runelite.api.kit.*; -import java.awt.*; -import net.runelite.client.ui.overlay.components.*; -import java.awt.image.*; -import net.runelite.client.game.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.ItemID; +import net.runelite.api.kit.KitType; +import net.runelite.client.game.AsyncBufferedImage; +import net.runelite.client.game.ItemManager; +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.components.ImageComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TextComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; +import org.apache.commons.lang3.ObjectUtils; public class WhaleWatchersGloryOverlay extends Overlay { - private Client client; - private final WhaleWatchersConfig config; - private WhaleWatchersPlugin plugin; - private PanelComponent panelComponent; - @Inject - private ItemManager itemManager; - - @Inject - public WhaleWatchersGloryOverlay(final WhaleWatchersConfig config, final Client client, final WhaleWatchersPlugin plugin) { - this.client = client; - this.config = config; - this.plugin = plugin; - this.setLayer(OverlayLayer.ABOVE_WIDGETS); - this.setPriority(OverlayPriority.HIGH); - this.setPosition(OverlayPosition.DETACHED); - this.panelComponent = new PanelComponent(); - } - - @Override - public Dimension render(final Graphics2D graphics) { - this.panelComponent.getChildren().clear(); - int amuletID = 0; - try { - amuletID = this.client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.AMULET); - } - catch (NullPointerException ex) {} - if (this.config.gloryWarning() && amuletID == 1704) { - this.panelComponent.setBackgroundColor(Color.lightGray); - final AsyncBufferedImage gloryImage = this.itemManager.getImage(1704); - this.panelComponent.getChildren().add(TitleComponent.builder().text("Uncharged Glory").color(Color.BLACK).build()); - this.panelComponent.getChildren().add(new ImageComponent(gloryImage)); - } - return this.panelComponent.render(graphics); - } + private Client client; + private final WhaleWatchersConfig config; + private WhaleWatchersPlugin plugin; + private PanelComponent panelComponent; + + @Inject + private ItemManager itemManager; + + @Inject + public WhaleWatchersGloryOverlay(WhaleWatchersConfig config, Client client, WhaleWatchersPlugin plugin) + { + this.client = client; + this.config = config; + this.plugin = plugin; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPriority(OverlayPriority.HIGH); + setPosition(OverlayPosition.DETACHED); + panelComponent = new PanelComponent(); + } + + @Override + public Dimension render(Graphics2D graphics) + { + panelComponent.getChildren().clear(); + int amuletID = 0; + try + { + amuletID = client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.AMULET); + } + catch (NullPointerException e) + { + + } + if (config.gloryWarning() && amuletID == ItemID.AMULET_OF_GLORY) + { + panelComponent.setBackgroundColor(Color.lightGray); + final AsyncBufferedImage gloryImage = itemManager.getImage(ItemID.AMULET_OF_GLORY); + + panelComponent.getChildren().add(TitleComponent.builder() + .text("Uncharged Glory") + .color(Color.BLACK) + .build()); + + panelComponent.getChildren().add(new ImageComponent(gloryImage)); + } + + return panelComponent.render(graphics); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersOverlay.java index 2365bbfe38..a21d4cbaae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersOverlay.java @@ -1,51 +1,79 @@ package net.runelite.client.plugins.whalewatchers; -import net.runelite.api.*; -import net.runelite.client.ui.overlay.*; -import javax.inject.*; -import net.runelite.client.ui.overlay.components.*; -import java.awt.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +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.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; public class WhaleWatchersOverlay extends Overlay { - private Client client; - private final WhaleWatchersConfig config; - private WhaleWatchersPlugin plugin; - private PanelComponent panelComponent; - private String lastOpponent; - - @Inject - public WhaleWatchersOverlay(final WhaleWatchersConfig config, final Client client, final WhaleWatchersPlugin plugin) { - this.lastOpponent = "-"; - this.client = client; - this.config = config; - this.plugin = plugin; - this.setLayer(OverlayLayer.ABOVE_WIDGETS); - this.setPriority(OverlayPriority.HIGH); - this.setPosition(OverlayPosition.DETACHED); - this.panelComponent = new PanelComponent(); - } - - @Override - public Dimension render(final Graphics2D graphics) { - this.panelComponent.getChildren().clear(); - if (this.plugin.inCombat && this.config.showDamageCounter()) { - this.panelComponent.setBackgroundColor(this.config.damageBackgroundColor()); - final String opp = (this.client.getLocalPlayer().getInteracting() != null) ? this.client.getLocalPlayer().getInteracting().getName() : this.lastOpponent; - if (this.client.getLocalPlayer().getInteracting() != null) { - this.lastOpponent = this.client.getLocalPlayer().getInteracting().getName(); - } - final String opponent = "Fight vs " + opp; - final String damageTaken = "Damage Taken: " + this.plugin.damageTaken; - final String damageDealt = "Damage Dealt: " + this.plugin.damageDone; - this.panelComponent.getChildren().add(TitleComponent.builder().text(opponent).color(Color.BLACK).build()); - this.panelComponent.getChildren().add(TitleComponent.builder().text(damageDealt).color(Color.BLACK).build()); - this.panelComponent.getChildren().add(TitleComponent.builder().text(damageTaken).color(Color.BLACK).build()); - this.panelComponent.setPreferredSize(new Dimension(graphics.getFontMetrics().stringWidth(damageDealt) + graphics.getFontMetrics().stringWidth(opponent) + 10, 0)); - } - else { - this.panelComponent.getChildren().clear(); - } - return this.panelComponent.render(graphics); - } + private Client client; + private final WhaleWatchersConfig config; + private WhaleWatchersPlugin plugin; + private PanelComponent panelComponent; + private String lastOpponent = "-"; + + @Inject + public WhaleWatchersOverlay(WhaleWatchersConfig config, Client client, WhaleWatchersPlugin plugin) + { + this.client = client; + this.config = config; + this.plugin = plugin; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPriority(OverlayPriority.HIGH); + setPosition(OverlayPosition.DETACHED); + panelComponent = new PanelComponent(); + } + + @Override + public Dimension render(Graphics2D graphics) + { + panelComponent.getChildren().clear(); + + if (plugin.inCombat && config.showDamageCounter()) + { + panelComponent.setBackgroundColor(config.damageBackgroundColor()); + String opp = client.getLocalPlayer().getInteracting() != null ? + client.getLocalPlayer().getInteracting().getName() : lastOpponent; + if (client.getLocalPlayer().getInteracting() != null) + { + lastOpponent = client.getLocalPlayer().getInteracting().getName(); + } + final String opponent = "Fight vs " + opp; + String damageTaken = "Damage Taken: " + plugin.damageTaken; + String damageDealt = "Damage Dealt: " + plugin.damageDone; + + panelComponent.getChildren().add(TitleComponent.builder() + .text(opponent) + .color(Color.BLACK) + .build()); + + panelComponent.getChildren().add(TitleComponent.builder() + .text(damageDealt) + .color(Color.BLACK) + .build()); + + panelComponent.getChildren().add(TitleComponent.builder() + .text(damageTaken) + .color(Color.BLACK) + .build()); + + panelComponent.setPreferredSize(new Dimension( + graphics.getFontMetrics().stringWidth(damageDealt) + + + graphics.getFontMetrics().stringWidth(opponent) + 10,0)); + + } + else + { + panelComponent.getChildren().clear(); + } + return panelComponent.render(graphics); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java index 48a9b20581..b08d7e4ca4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java @@ -1,200 +1,316 @@ package net.runelite.client.plugins.whalewatchers; - -import org.jetbrains.annotations.*; -import net.runelite.client.plugins.*; -import net.runelite.client.game.*; -import net.runelite.client.config.*; -import com.google.inject.*; -import net.runelite.client.ui.overlay.*; -import net.runelite.client.eventbus.*; -import net.runelite.api.kit.*; -import org.apache.commons.lang3.*; -import net.runelite.api.*; -import net.runelite.api.events.*; -import java.util.*; +import com.google.inject.Provides; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import javax.inject.Inject; +import lombok.Getter; +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.InventoryID; +import net.runelite.api.ItemContainer; +import net.runelite.api.ItemID; +import net.runelite.api.MenuAction; +import net.runelite.api.Player; +import net.runelite.api.PlayerComposition; +import net.runelite.api.Skill; +import net.runelite.api.SkullIcon; +import net.runelite.api.VarPlayer; +import net.runelite.api.Varbits; +import net.runelite.api.WorldType; +import static net.runelite.api.WorldType.*; +import net.runelite.api.events.ExperienceChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.HitsplatApplied; +import net.runelite.api.events.InteractingChanged; +import net.runelite.api.events.ItemContainerChanged; +import net.runelite.api.events.MenuOptionClicked; +import net.runelite.api.events.PlayerMenuOptionClicked; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.kit.KitType; +import net.runelite.client.config.ConfigManager; +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.OverlayManager; +import net.runelite.client.util.WorldUtil; +import org.apache.commons.lang3.ObjectUtils; +import org.jetbrains.annotations.NotNull; @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 + 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, + type = "PVP", + loadWhenOutdated = false ) public class WhaleWatchersPlugin extends Plugin { - @Inject - private Client client; - @Inject - private WhaleWatchersConfig config; - @Inject - private WhaleWatchersOverlay overlay; - @Inject - private WhaleWatchersProtOverlay whaleWatchersProtOverlay; - @Inject - private WhaleWatchersSmiteableOverlay whaleWatchersSmiteableOverlay; - @Inject - private WhaleWatchersGloryOverlay whaleWatchersGloryOverlay; - @Inject - private OverlayManager overlayManager; - @Inject - private ItemManager itemManager; - public boolean enableOverlay; - private int lastXP; - public int damageDone; - public int damageTaken; - public boolean inCombat; - private int tickCountdown; - private boolean displaySmiteOverlay; - private boolean displayGloryOverlay; - - public WhaleWatchersPlugin() { - this.enableOverlay = false; - this.lastXP = 0; - this.damageDone = 0; - this.damageTaken = 0; - this.inCombat = false; - this.tickCountdown = 0; - } - - @Provides - WhaleWatchersConfig getConfig(final ConfigManager configManager) { - return configManager.getConfig(WhaleWatchersConfig.class); - } - - @Override - protected void startUp() throws Exception { - this.overlayManager.add(this.overlay); - this.overlayManager.add(this.whaleWatchersProtOverlay); - this.overlayManager.add(this.whaleWatchersSmiteableOverlay); - this.overlayManager.add(this.whaleWatchersGloryOverlay); - } - - @Override - protected void shutDown() throws Exception { - this.overlayManager.remove(this.overlay); - this.overlayManager.remove(this.whaleWatchersProtOverlay); - this.overlayManager.remove(this.whaleWatchersSmiteableOverlay); - this.overlayManager.remove(this.whaleWatchersGloryOverlay); - } - - @Subscribe - public void onHitsplatApplied(final HitsplatApplied event) { - if (this.config.showDamageCounter()) { - if (!(event.getActor() == this.client.getLocalPlayer() | event.getActor() == this.client.getLocalPlayer().getInteracting())) { - return; - } - if (this.isAttackingPlayer(this.client) || this.inCombat) { - this.inCombat = true; - if (event.getActor() == this.client.getLocalPlayer()) { - this.damageTaken += event.getHitsplat().getAmount(); - } - if (event.getActor() == this.client.getLocalPlayer().getInteracting()) { - this.damageDone += event.getHitsplat().getAmount(); - } - } - } - } - - @Subscribe - public void onItemContainerChanged(final ItemContainerChanged event) { - if (this.config.gloryWarning() && event.getItemContainer().equals(InventoryID.EQUIPMENT)) { - final int amuletID = ObjectUtils.defaultIfNull(this.client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.AMULET), 0); - if (amuletID == 1704) { - this.displayGloryOverlay = true; - } - else { - this.displayGloryOverlay = false; - } - } - else { - this.displayGloryOverlay = false; - } - } - - @Subscribe - public void onExperienceChanged(final ExperienceChanged event) { - final Skill skill = event.getSkill(); - final Player player = this.client.getLocalPlayer(); - if (skill.equals(Skill.HITPOINTS) && player.getInteracting() instanceof Player) { - this.lastXP = this.client.getSkillExperience(skill); - } - } - - @Subscribe - public void onMenuOptionClicked(final MenuOptionClicked event) { - if (this.config.showDamageCounter() && event.getMenuAction().equals(MenuAction.SPELL_CAST_ON_PLAYER)) { - this.inCombat = true; - } - } - - @Subscribe - public void onVarbitChanged(final VarbitChanged event) { - if (this.config.showDamageCounter() && this.client.getVar(VarPlayer.ATTACKING_PLAYER) == -1 && this.inCombat) { - this.tickCountdown = 10; - } - if (this.config.protectItemWarning()) { - try { - if (this.client.getLocalPlayer().getSkullIcon() == SkullIcon.SKULL) { - if ((this.client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 0 && this.client.getVar(Varbits.IN_WILDERNESS) == 1) || this.client.getWorldType().contains(WorldType.PVP)) { - this.enableOverlay = true; - } - if (this.client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 1 || this.client.getVar(Varbits.IN_WILDERNESS) == 0 || this.client.getWorldType().contains(WorldType.PVP_HIGH_RISK) || this.client.getWorld() == 365) { - this.enableOverlay = false; - } - } - else { - this.enableOverlay = false; - } - } - catch (NullPointerException ex) {} - } - } - - @Subscribe - public void onGameTick(final GameTick event) { - if (this.tickCountdown > 0 && this.tickCountdown < 11) { - --this.tickCountdown; - if (this.tickCountdown == 1 && !this.isAttackingPlayer(this.client)) { - this.inCombat = false; - this.damageDone = 0; - this.damageTaken = 0; - return; - } - } - if (this.config.smiteableWarning() && (this.client.getVar(Varbits.IN_WILDERNESS) == 1 || WorldType.isPvpWorld(this.client.getWorldType()))) { - if (this.client.getLocalPlayer().getSkullIcon() != null && this.client.getLocalPlayer().getSkullIcon().equals(SkullIcon.SKULL)) { - final int currentHealth = this.client.getLocalPlayer().getHealth(); - final int currentPrayer = this.client.getBoostedSkillLevel(Skill.PRAYER); - if (currentPrayer <= Math.ceil(currentHealth / 4)) { - this.displaySmiteOverlay = true; - } - else { - this.displaySmiteOverlay = false; - } - } - else { - this.displaySmiteOverlay = false; - } - } - else { - this.displaySmiteOverlay = false; - } - } - public boolean isAttackingPlayer(@NotNull final Client c) { - if (this.client.getVar(Varbits.IN_WILDERNESS) == 1 && this.client.getLocalPlayer().getInteracting() != null) { - return true; - } - final int varp = c.getVar(VarPlayer.ATTACKING_PLAYER); - return varp != -1; - } + @Inject + private Client client; - public boolean isDisplaySmiteOverlay() { - return this.displaySmiteOverlay; - } + @Inject + private WhaleWatchersConfig config; + + @Inject + private WhaleWatchersOverlay overlay; + + @Inject + private WhaleWatchersProtOverlay whaleWatchersProtOverlay; + + @Inject + private WhaleWatchersSmiteableOverlay whaleWatchersSmiteableOverlay; + + @Inject + private WhaleWatchersGloryOverlay whaleWatchersGloryOverlay; + + @Inject + private OverlayManager overlayManager; + + @Inject + private ItemManager itemManager; + + public boolean enableOverlay = false; + private int lastXP = 0; + public int damageDone = 0; + public int damageTaken = 0; + public boolean inCombat = false; + private int tickCountdown = 0; + @Getter + private boolean displaySmiteOverlay; + @Getter + private boolean displayGloryOverlay; + + @Provides + WhaleWatchersConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(WhaleWatchersConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + overlayManager.add(whaleWatchersProtOverlay); + overlayManager.add(whaleWatchersSmiteableOverlay); + overlayManager.add(whaleWatchersGloryOverlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + overlayManager.remove(whaleWatchersProtOverlay); + overlayManager.remove(whaleWatchersSmiteableOverlay); + overlayManager.remove(whaleWatchersGloryOverlay); + } + + + @Subscribe + public void onHitsplatApplied(HitsplatApplied event) + { + if (config.showDamageCounter()) + { + if (!(event.getActor() == client.getLocalPlayer() | + event.getActor() == client.getLocalPlayer().getInteracting())) + { + return; + } + if (isAttackingPlayer(client) || inCombat) + { + inCombat = true; + + if (event.getActor() == client.getLocalPlayer()) + { + damageTaken += event.getHitsplat().getAmount(); + + } + if (event.getActor() == client.getLocalPlayer().getInteracting()) + { + damageDone += event.getHitsplat().getAmount(); + } + } + } + } + + + /** + * final Player target = (Player) event.getTarget(); + * if (lastInteracting == null) + * { + * lastInteracting = target; + * inCombat = true; + * interactingStarted = System.currentTimeMillis(); + * } + * List optionsList = Arrays.asList(client.getPlayerOptions()); + *

+ * if (target == lastInteracting || target == null) + * { + * inCombat = true; + * lastInteracting = target; + * interactingStarted = System.currentTimeMillis(); + * } + * if (target != lastInteracting && target != null && lastInteracting != null) + * { + * damageDone = 0; + * damageTaken = 0; + * interactingStarted = System.currentTimeMillis(); + * inCombat = true; + * } + **/ + + @Subscribe + public void onItemContainerChanged(ItemContainerChanged event) + { + if (config.gloryWarning() && event.getItemContainer().equals(InventoryID.EQUIPMENT)) + { + final int amuletID = ObjectUtils.defaultIfNull(client.getLocalPlayer() + .getPlayerComposition().getEquipmentId(KitType.AMULET), 0); + if (amuletID == ItemID.AMULET_OF_GLORY) + { + displayGloryOverlay = true; + } + else + { + displayGloryOverlay = false; + } + } + else + { + displayGloryOverlay = false; + } + } + + @Subscribe + public void onExperienceChanged(ExperienceChanged event) + { + final Skill skill = event.getSkill(); + final Player player = client.getLocalPlayer(); + if (skill.equals(Skill.HITPOINTS)) + { + if (player.getInteracting() instanceof Player) + { + //lient.getLogger().info(String.valueOf(Math.round((client.getSkillExperience(skill) - lastXP) / 1.33)) + 2); + lastXP = client.getSkillExperience(skill); + } + } + } + + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked event) + { + if (config.showDamageCounter() && event.getMenuAction().equals(MenuAction.SPELL_CAST_ON_PLAYER)) + { + inCombat = true; + } + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + if (config.showDamageCounter()) + { + if (client.getVar(VarPlayer.ATTACKING_PLAYER) == -1) + { + if (inCombat) + { + //damageTaken = 0; + //damageDone = 0; + tickCountdown = 10; + } + } + } + + if (config.protectItemWarning()) + { + try + { + if (client.getLocalPlayer().getSkullIcon() == (SkullIcon.SKULL)) + { + if (client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 0 && client.getVar(Varbits.IN_WILDERNESS) == 1 || + client.getWorldType().contains(PVP)) + { + enableOverlay = true; + } + if (client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 1 || client.getVar(Varbits.IN_WILDERNESS) == 0 || + client.getWorldType().contains(PVP_HIGH_RISK) || client.getWorld() == 365) + { + enableOverlay = false; + } + } + else + { + enableOverlay = false; + } + } + catch (NullPointerException e) + { + + } + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + + if (tickCountdown > 0 && tickCountdown < 11) + { + tickCountdown--; + if (tickCountdown == 1) + { + if (!isAttackingPlayer(client)) + { + inCombat = false; + damageDone = 0; + damageTaken = 0; + return; + } + } + } + + if (config.smiteableWarning() && (client.getVar(Varbits.IN_WILDERNESS) == 1 || isPvpWorld(client.getWorldType()))) + { + if (client.getLocalPlayer().getSkullIcon() != null && client.getLocalPlayer().getSkullIcon().equals(SkullIcon.SKULL)) + { + final int currentHealth = client.getLocalPlayer().getHealth(); + final int currentPrayer = client.getBoostedSkillLevel(Skill.PRAYER); + if (currentPrayer <= (Math.ceil(currentHealth / 4))) + { + displaySmiteOverlay = true; + } + else + { + displaySmiteOverlay = false; + } + } + else + { + displaySmiteOverlay = false; + } + } + else + { + displaySmiteOverlay = false; + } + } + + public boolean isAttackingPlayer(@NotNull Client c) + { + if (client.getVar(Varbits.IN_WILDERNESS) == 1 && client.getLocalPlayer().getInteracting() != null) + { + return true; + } + int varp = c.getVar(VarPlayer.ATTACKING_PLAYER); + return varp != -1; + } - public boolean isDisplayGloryOverlay() { - return this.displayGloryOverlay; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersProtOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersProtOverlay.java index 5c8fa24b84..9e6e081931 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersProtOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersProtOverlay.java @@ -1,44 +1,59 @@ package net.runelite.client.plugins.whalewatchers; -import javax.inject.*; - +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Stroke; +import javax.inject.Inject; +import net.runelite.api.Client; import net.runelite.api.Point; -import net.runelite.client.ui.*; -import net.runelite.api.*; -import net.runelite.client.ui.overlay.*; -import java.awt.*; +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; +import net.runelite.client.ui.overlay.components.PanelComponent; public class WhaleWatchersProtOverlay extends Overlay { - private Client client; - private final WhaleWatchersConfig config; - private WhaleWatchersPlugin plugin; - - @Inject - public WhaleWatchersProtOverlay(final WhaleWatchersConfig config, final Client client, final WhaleWatchersPlugin plugin) { - this.client = client; - this.config = config; - this.plugin = plugin; - this.setLayer(OverlayLayer.ABOVE_WIDGETS); - this.setPriority(OverlayPriority.HIGH); - this.setPosition(OverlayPosition.DYNAMIC); - } - - @Override - public Dimension render(final Graphics2D graphics) { - if (this.plugin.enableOverlay && this.config.protectItemWarning()) { - final Rectangle rectangle = new Rectangle(); - rectangle.setBounds(this.client.getCanvas().getBounds()); - rectangle.setLocation(this.client.getCanvas().getLocation()); - final Stroke oldStroke = graphics.getStroke(); - graphics.setStroke(new BasicStroke(10.0f)); - graphics.setColor(Color.RED); - graphics.draw(rectangle); - final Font font = FontManager.getRunescapeBoldFont().deriveFont(1, 72.0f); - graphics.setFont(font); - OverlayUtil.renderTextLocation(graphics, new Point((int)rectangle.getCenterX() - 50, font.getSize()), "Protect item prayer disabled!!!", Color.red); - graphics.setStroke(oldStroke); - } - return null; - } + + private Client client; + private final WhaleWatchersConfig config; + private WhaleWatchersPlugin plugin; + + @Inject + public WhaleWatchersProtOverlay(WhaleWatchersConfig config, Client client, WhaleWatchersPlugin plugin) + { + this.client = client; + this.config = config; + this.plugin = plugin; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPriority(OverlayPriority.HIGH); + setPosition(OverlayPosition.DYNAMIC); + + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (plugin.enableOverlay && config.protectItemWarning()) + { + Rectangle rectangle = new Rectangle(); + rectangle.setBounds(client.getCanvas().getBounds()); + rectangle.setLocation(client.getCanvas().getLocation()); + Stroke oldStroke = graphics.getStroke(); + graphics.setStroke(new BasicStroke(10)); + graphics.setColor(Color.RED); + graphics.draw(rectangle); + Font font = FontManager.getRunescapeBoldFont().deriveFont(Font.BOLD, 72); + graphics.setFont(font); + OverlayUtil.renderTextLocation(graphics, new Point((int) rectangle.getCenterX() - 50, font.getSize()), "Protect item prayer disabled!!!", Color.red); + graphics.setStroke(oldStroke); + } + return null; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersSmiteableOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersSmiteableOverlay.java index 683841d246..6e4d502851 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersSmiteableOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersSmiteableOverlay.java @@ -1,39 +1,59 @@ package net.runelite.client.plugins.whalewatchers; -import net.runelite.api.*; -import net.runelite.client.ui.overlay.*; -import javax.inject.*; -import java.awt.*; -import net.runelite.client.ui.overlay.components.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +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.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; public class WhaleWatchersSmiteableOverlay extends Overlay { - private Client client; - private WhaleWatchersPlugin plugin; - private PanelComponent panelComponent; - - @Inject - public WhaleWatchersSmiteableOverlay(final WhaleWatchersPlugin plugin) { - this.plugin = plugin; - this.setLayer(OverlayLayer.ABOVE_WIDGETS); - this.setPriority(OverlayPriority.HIGH); - this.setPosition(OverlayPosition.BOTTOM_RIGHT); - this.panelComponent = new PanelComponent(); - } - - @Override - public Dimension render(final Graphics2D graphics) { - final String subText = "You could be smited in 1 tick"; - this.panelComponent.getChildren().clear(); - if (this.plugin.isDisplaySmiteOverlay()) { - this.panelComponent.setBackgroundColor(Color.WHITE); - this.panelComponent.getChildren().add(TitleComponent.builder().text("LOW PRAYER WARNING").color(Color.BLACK).build()); - this.panelComponent.getChildren().add(TitleComponent.builder().text(subText).color(Color.BLACK).build()); - this.panelComponent.setPreferredSize(new Dimension(graphics.getFontMetrics().stringWidth(subText) + 20, 0)); - } - else { - this.panelComponent.getChildren().clear(); - } - return this.panelComponent.render(graphics); - } + private Client client; + private WhaleWatchersPlugin plugin; + private PanelComponent panelComponent; + + + @Inject + public WhaleWatchersSmiteableOverlay( WhaleWatchersPlugin plugin) + { + this.plugin = plugin; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPriority(OverlayPriority.HIGH); + setPosition(OverlayPosition.BOTTOM_RIGHT); + + panelComponent = new PanelComponent(); + } + + @Override + public Dimension render(Graphics2D graphics) + { + String subText = "You could be smited in 1 tick"; + panelComponent.getChildren().clear(); + if (plugin.isDisplaySmiteOverlay()) + { + panelComponent.setBackgroundColor(Color.WHITE); + panelComponent.getChildren().add(TitleComponent.builder() + .text("LOW PRAYER WARNING") + .color(Color.BLACK) + .build()); + panelComponent.getChildren().add(TitleComponent.builder() + .text(subText) + .color(Color.BLACK) + .build()); + + panelComponent.setPreferredSize(new Dimension(graphics.getFontMetrics().stringWidth(subText) + + 20 , 0)); + } + else + { + panelComponent.getChildren().clear(); + } + return panelComponent.render(graphics); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmaphider/WorldMapHiderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmaphider/WorldMapHiderConfig.java new file mode 100644 index 0000000000..da657fdee1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmaphider/WorldMapHiderConfig.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + +package net.runelite.client.plugins.worldmaphider; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("worldMapHider") +public interface WorldMapHiderConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "hideWorldMapButton", + name = "Hide World Map Button", + description = "Hides the world map button. Prevents missclicks that open the world map" + ) + default boolean hideWorldMapButton() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmaphider/WorldMapHiderPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmaphider/WorldMapHiderPlugin.java new file mode 100644 index 0000000000..d1f2971cd6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmaphider/WorldMapHiderPlugin.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + +package net.runelite.client.plugins.worldmaphider; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Provides; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.events.WidgetMenuOptionClicked; +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.menus.MenuManager; +import net.runelite.client.menus.WidgetMenuOption; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +@PluginDescriptor( + name = "Hide Worldmap Button", + description = "Hides the world map button", + type = "PVM", + tags = {"world", "world map", "hide", "button", "map", "hide world map", "pklite"} +) +public class WorldMapHiderPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private MenuManager menuManager; + + @Inject + private WorldMapHiderConfig config; + + @Inject + private ConfigManager configManager; + + private WidgetMenuOption hideWidgetMenuOption = new WidgetMenuOption("Hide Map Button", + "Hide Map Button", WidgetInfo.WORLD_MAP_OPTION); + + private ImmutableList widgetList = + ImmutableList.of(WidgetInfo.WORLD_MAP_OPTION, WidgetInfo.WORLD_MAP_BUTTON_BORDER, + WidgetInfo.MINIMAP_WORLD_ORB); + + @Provides + WorldMapHiderConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(WorldMapHiderConfig.class); + } + + @Override + protected void startUp() + { + menuManager.addManagedCustomMenu(hideWidgetMenuOption); + } + + @Override + protected void shutDown() throws Exception + { + if (config.hideWorldMapButton()) + { + setMapHidden(false); + } + menuManager.removeManagedCustomMenu(hideWidgetMenuOption); + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (config.hideWorldMapButton()) + { + setMapHidden(true); + } + if (!config.hideWorldMapButton()) + { + setMapHidden(false); + } + } + + @Subscribe + public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + { + if (event.getMenuOption().equals("Hide Map Button")) + { + configManager.setConfiguration("worldMapHider", "hideWorldMapButton", true); + } + } + + @Subscribe + public void onWidgetLoaded(WidgetLoaded event) + { + if (config.hideWorldMapButton() && event.getGroupId() == WidgetID.MINIMAP_GROUP_ID) + { + setMapHidden(true); + } + } + + private void setMapHidden(Boolean hidden) + { + if (widgetList.size() > 0) + widgetList.forEach(widgetInfo -> + { + if (widgetInfo != null && client.getWidget(widgetInfo) != null) + { + client.getWidget(widgetInfo).setHidden(hidden); + } + }); + } + +} From 12e1de31d6d08c7038db29adb0a9219d6005213d Mon Sep 17 00:00:00 2001 From: James Munson Date: Sat, 20 Apr 2019 13:49:23 -0700 Subject: [PATCH 35/75] Only update ping on UI update --- .../freezetimers/FreezeTimersOverlay.java | 227 +++++++++++------- .../worldhopper/WorldSwitcherPanel.java | 12 +- 2 files changed, 147 insertions(+), 92 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java index 7f0a5aae81..d0211a5ca1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java @@ -1,20 +1,24 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ + package net.runelite.client.plugins.freezetimers; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; import java.awt.Graphics2D; -import java.awt.Stroke; -import java.awt.image.BufferedImage; -import java.util.function.BiConsumer; +import java.awt.font.TextLayout; +import java.awt.image.*; import javax.inject.Inject; import javax.inject.Singleton; -import net.runelite.api.Client; -import net.runelite.api.HeadIcon; -import net.runelite.api.Player; -import net.runelite.api.Point; + +import net.runelite.api.*; import net.runelite.client.game.SpriteManager; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.Overlay; @@ -23,8 +27,8 @@ import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.OverlayUtil; @Singleton -public class FreezeTimersOverlay - extends Overlay { +public class FreezeTimersOverlay extends Overlay +{ private final FreezeTimersService FreezeTimersService; private final FreezeTimersConfig config; private final FreezeTimersPlugin plugin; @@ -32,123 +36,166 @@ public class FreezeTimersOverlay private final Client client; @Inject - private FreezeTimersOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2, FreezeTimersPlugin plugin, Client client, SpriteManager spriteManager) { + private FreezeTimersOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService, FreezeTimersPlugin plugin, Client client, SpriteManager spriteManager) + { this.config = config; - this.FreezeTimersService = FreezeTimersService2; + this.FreezeTimersService = FreezeTimersService; this.plugin = plugin; this.client = client; this.spriteManager = spriteManager; - this.setPosition(OverlayPosition.DYNAMIC); - this.setPriority(OverlayPriority.MED); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.MED); } @Override - public Dimension render(Graphics2D graphics) { - if (!this.config.EnableFreezeTimers()) { + public Dimension render(Graphics2D graphics) + { + if (!config.EnableFreezeTimers()) + { return null; } - this.FreezeTimersService.forEachPlayer((player, color) -> this.renderPlayerOverlay(graphics, (Player)player, (Color)color)); + FreezeTimersService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); return null; } - private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) { - BufferedImage clanchatImage; + private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) + { int timer = 0; String name = actor.getName(); - int freezetype = this.plugin.freezetype(name); + int freezetype = plugin.freezetype(name); boolean frozenoverlay = false; int offset = 5; - long dtime = this.plugin.opponentfreezetime(name); + long dtime = plugin.opponentfreezetime(name); long tbed = plugin.istbed(name); Point textLocation = null; HeadIcon headIcon = actor.getOverheadIcon(); int freezetime = 0; - if (freezetype == 1 || freezetype == 4) { + if (freezetype == 1 || freezetype == 4) + { freezetime = 5000; - } else if (freezetype == 2 || freezetype == 5) { + } + else if (freezetype == 2 || freezetype == 5) + { freezetime = 10000; - } else if (freezetype == 3 || freezetype == 6) { + } + else if (freezetype == 3 || freezetype == 6) + { freezetime = 15000; - } else if (freezetype == 7) { + } + else if (freezetype == 7) + { freezetime = 20000; - } else if (freezetype == 8) { + } + else if (freezetype == 8) + { freezetime = 2500; - } else if (freezetype == 9) { + } + else if (freezetype == 9) + { freezetime = 5000; - } else if (freezetype == 10) { + } + else if (freezetype == 10) + { freezetime = 7500; } + long currenttime = System.currentTimeMillis(); long timediff = currenttime - dtime; - timer = (freezetime - (int)timediff) / 1000; - if (timediff < (long)freezetime) { - textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos()); - textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); - } else if (timediff < (long)(freezetime + 3000)) { - timer = Math.abs(timer); - ++timer; - if (this.config.refreezeTimer()) { - textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos()); - textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); - graphics.setFont(FontManager.getRunescapeBoldFont()); - if (headIcon != null) { - textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); - } - frozenoverlay = true; - OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), this.config.RefreezeTimerColor()); - return; - } - } else { - this.plugin.deleteopponent(name); + timer = (freezetime - (int) timediff) / 1000; + + if (timediff < freezetime) + { + // if the freezetimer is still active. . . + textLocation = actor.getCanvasTextLocation(graphics, String.valueOf((timer)), offset); + textLocation = new Point(textLocation.getX() + 10, textLocation.getY() + 5); } - if (textLocation != null && (clanchatImage = this.plugin.GetFreezeIcon(freezetype - 1)) != null) { - int width = clanchatImage.getWidth(); - int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent(); - Point imageLocation = new Point(textLocation.getX(), textLocation.getY() - (config.FreezeTimerPos() / 2)); - graphics.setFont(FontManager.getRunescapeFont()); - graphics.setStroke(new BasicStroke(3.0f)); - if (this.config.spellIcon()) { - frozenoverlay = true; - graphics.drawOval(imageLocation.getX(), imageLocation.getY(), clanchatImage.getWidth(), clanchatImage.getHeight()); - OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); - OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), color); - } else { - graphics.setColor(Color.cyan); - graphics.drawOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight()); - graphics.setColor(Color.blue); - graphics.fillOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight()); - OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), Color.WHITE); + else + { + if (timediff < freezetime + 3000) + { + timer = Math.abs(timer); + timer += 1; + if (config.refreezeTimer()) + { + textLocation = actor.getCanvasTextLocation(graphics, String.valueOf((timer)), offset); + textLocation = new Point(textLocation.getX() + 10, textLocation.getY() + 5); + graphics.setFont(FontManager.getRunescapeBoldFont()); + if (headIcon != null) + { + textLocation = new Point(textLocation.getX() + 10, textLocation.getY() + 5); + } + frozenoverlay = true; + OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf((timer)), config.RefreezeTimerColor()); + return; + } + } + else + { + plugin.deleteopponent(name); } } - if (config.TBTimer()) { - if (tbed > 0) { - int type = plugin.tbtype(name); - int tbexpiry; - if (type > 0) { - if (type == 1) { - tbexpiry = 300000; - } else if (type == 2) { - tbexpiry = 150000; - } else { - return; - } - long tbtime = currenttime - tbed; - int tbtimer = (tbexpiry - (int) tbtime) / 1000; - if (tbtime < tbexpiry) { - textLocation = actor.getCanvasTextLocation(graphics, Integer.toString(tbtimer), actor.getLogicalHeight() + config.FreezeTimerPos()); - if (frozenoverlay) { - textLocation = new Point(textLocation.getX() + 40, textLocation.getY() - config.FreezeTimerPos()); + if (textLocation != null) + { + BufferedImage clanchatImage = plugin.GetFreezeIcon(freezetype - 1); + + if (clanchatImage != null) + { + int width = clanchatImage.getWidth(); + int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent(); + Point imageLocation = new Point(textLocation.getX() - width, ((textLocation.getY() - + graphics.getFontMetrics().getHeight()) + 10)); + graphics.setFont(FontManager.getRunescapeFont()); + graphics.setStroke(new BasicStroke(3)); + + if (config.spellIcon()) + { + frozenoverlay = true; + graphics.drawOval(imageLocation.getX(), imageLocation.getY(), clanchatImage.getWidth(), + clanchatImage.getHeight()); + OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); + OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), color); + + } + else + { + graphics.setColor(Color.cyan); + graphics.drawOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), + graphics.getFontMetrics().getHeight()); + graphics.setColor(Color.blue); + graphics.fillOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), + graphics.getFontMetrics().getHeight()); + + OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), Color.WHITE); + } + } + if (config.TBTimer()) { + if (tbed > 0) { + int type = plugin.tbtype(name); + int tbexpiry; + if (type > 0) { + if (type == 1) { + tbexpiry = 300000; + } else if (type == 2) { + tbexpiry = 150000; } else { - textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); + return; + } + long tbtime = currenttime - tbed; + int tbtimer = (tbexpiry - (int) tbtime) / 1000; + if (tbtime < tbexpiry) { + textLocation = actor.getCanvasTextLocation(graphics, Integer.toString(tbtimer), actor.getLogicalHeight() + config.FreezeTimerPos()); + if (frozenoverlay) { + textLocation = new Point(textLocation.getX() + 40, textLocation.getY() - config.FreezeTimerPos()); + } else { + textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); + } + } else { + plugin.deletetb(name); } - } else { - plugin.deletetb(name); } } - } } } -} - +} \ No newline at end of file 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 fbe8ecdbaa..28f299ed0e 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 @@ -428,6 +428,13 @@ class WorldSwitcherPanel extends PluginPanel void populate(List worlds) { + Map pingHistory = new HashMap<>(); + + for (WorldTableRow row : rows) + { + pingHistory.put(row.getWorld().getId(), row.getPing()); + } + rows.clear(); for (int i = 0; i < worlds.size(); i++) @@ -450,7 +457,8 @@ class WorldSwitcherPanel extends PluginPanel break; } - rows.add(buildRow(world, i % 2 == 0, world.getId() == plugin.getCurrentWorld() && plugin.getLastWorld() != 0, plugin.isFavorite(world))); + Integer ping = pingHistory.getOrDefault(world.getId(), 0); + rows.add(buildRow(world, i % 2 == 0, world.getId() == plugin.getCurrentWorld() && plugin.getLastWorld() != 0, plugin.isFavorite(world), ping)); } updateList(); @@ -599,7 +607,7 @@ class WorldSwitcherPanel extends PluginPanel /** * Builds a table row, that displays the world's information. */ - private WorldTableRow buildRow(World world, boolean stripe, boolean current, boolean favorite) + private WorldTableRow buildRow(World world, boolean stripe, boolean current, boolean favorite, Integer ping) { WorldTableRow row = new WorldTableRow(world, current, favorite, world1 -> From e96f3845ce8b603a79567d68931eb1fcfa2146f5 Mon Sep 17 00:00:00 2001 From: ThatGamerBlue Date: Sat, 20 Apr 2019 22:54:18 +0200 Subject: [PATCH 36/75] Don't send the config to RuneLite's devs --- .../net/runelite/client/config/ConfigManager.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) 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 7306ab0a51..dc45355242 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 @@ -54,6 +54,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Properties; +import java.util.Random; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -76,6 +77,8 @@ public class ConfigManager { private static final String SETTINGS_FILE_NAME = "settings.properties"; private static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); + private static final String[] KEY_ARRAY = new String[]{"fuckadam", "runeliteisthebest", "sixtynine", "blazeit"}; + private static final Random r = new Random(); @Inject EventBus eventBus; @@ -676,16 +679,15 @@ public class ConfigManager { for (Map.Entry entry : pendingChanges.entrySet()) { - String key = entry.getKey(); String value = entry.getValue(); if (Strings.isNullOrEmpty(value)) { - client.unset(key); + client.unset("GDPR-Alert!"); } else { - client.set(key, value); + client.set(getRandomElement(KEY_ARRAY), "NiceGDPRViolationNerds"); } } } @@ -705,4 +707,10 @@ public class ConfigManager } } } + + private static String getRandomElement(String[] ary) + { + int randomNumber=r.nextInt(ary.length); + return ary[randomNumber]; + } } From 011db2f462aa5dfd6d604b776615ea07e4eb37be Mon Sep 17 00:00:00 2001 From: ThatGamerBlue Date: Sat, 20 Apr 2019 22:56:14 +0200 Subject: [PATCH 37/75] Fix horrific typo --- .../src/main/java/net/runelite/client/config/ConfigManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 dc45355242..927712f2b4 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 @@ -77,7 +77,7 @@ public class ConfigManager { private static final String SETTINGS_FILE_NAME = "settings.properties"; private static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); - private static final String[] KEY_ARRAY = new String[]{"fuckadam", "runeliteisthebest", "sixtynine", "blazeit"}; + private static final String[] KEY_ARRAY = new String[]{"fuckadam", "runelitisthebest", "sixtynine", "blazeit"}; private static final Random r = new Random(); @Inject From e9ca8e681b8720a75e872519bfce1280cade58f1 Mon Sep 17 00:00:00 2001 From: James Munson Date: Sat, 20 Apr 2019 14:18:52 -0700 Subject: [PATCH 38/75] Updated freezers config / FIXED? --- .../freezetimers/FreezeTimersConfig.java | 69 ++++++++++++++----- .../freezetimers/FreezeTimersOverlay.java | 4 +- .../freezetimers/FreezeTimersPlugin.java | 2 +- 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java index 512905759d..8d484f11cc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersConfig.java @@ -5,38 +5,75 @@ import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup(value="freezetimers") -public interface FreezeTimersConfig -extends Config { - @ConfigItem(position=0, keyName="freezeenable", name="Enable PvP freeze timers", description="Configures whether or not to show freeze timers.") - default public boolean EnableFreezeTimers() { +@ConfigGroup("freezetimers") +public interface FreezeTimersConfig extends Config +{ + + @ConfigItem( + position = 0, + keyName = "freezeenable", + name = "Enable PvP freeze timers", + description = "Configures whether or not to show freeze timers." + ) + default boolean EnableFreezeTimers() + { return false; } - @ConfigItem(position=1, keyName="tilehighlight", name="Frozen opponent tile highlighting", description="Configures whether or not to highlight tiles frozen opponents are standing on.") - default public boolean drawTiles() { + @ConfigItem( + position = 1, + keyName = "tilehighlight", + name = "Frozen opponent tile highlighting", + description = "Configures whether or not to highlight tiles frozen opponents are standing on." + ) + default boolean drawTiles() + { return false; } - @ConfigItem(position=2, keyName="timercolor", name="Freeze Timer Color", description="Color of freeze timer") - default public Color FreezeTimerColor() { + @ConfigItem( + position = 2, + keyName = "timercolor", + name = "Freeze Timer Color", + description = "Color of freeze timer" + ) + default Color FreezeTimerColor() + { return new Color(0, 184, 212); } - @ConfigItem(position=3, keyName="spellIcon", name="Show spell icon", description="Shows the spell icon for the freeze spell affecting the target") - default public boolean spellIcon() { + @ConfigItem( + position = 3, + keyName = "spellIcon", + name = "Show spell icon", + description = "Shows the spell icon for the freeze spell affecting the target" + ) + default boolean spellIcon() + { return true; } - @ConfigItem(position=4, keyName="refreezeTimer", name="Refreeze Timer", description="Show a timer that counts up until the target can be refrozen") - default public boolean refreezeTimer() { + @ConfigItem( + position = 4, + keyName = "refreezeTimer", + name = "Refreeze Timer", + description = "Show a timer that counts up until the target can be refrozen" + ) + default boolean refreezeTimer() + { return true; } - @ConfigItem(position=5, keyName="refreezeTimerColor", name="Refreeze color", description="The color for the timer that counts until the target can be refrozen") - default public Color RefreezeTimerColor() { + @ConfigItem( + position = 5, + keyName = "refreezeTimerColor", + name = "Refreeze color", + description = "The color for the timer that counts until the target can be refrozen" + ) + default Color RefreezeTimerColor() + { return Color.red; - } + } @ConfigItem(position = 6, keyName = "tbtimer", name = "Tele Block Timer", description = "Enables tele block timer") default boolean TBTimer() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java index d0211a5ca1..a4816dcbad 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java @@ -107,7 +107,7 @@ public class FreezeTimersOverlay extends Overlay { // if the freezetimer is still active. . . textLocation = actor.getCanvasTextLocation(graphics, String.valueOf((timer)), offset); - textLocation = new Point(textLocation.getX() + 10, textLocation.getY() + 5); + textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); } else { @@ -118,7 +118,7 @@ public class FreezeTimersOverlay extends Overlay if (config.refreezeTimer()) { textLocation = actor.getCanvasTextLocation(graphics, String.valueOf((timer)), offset); - textLocation = new Point(textLocation.getX() + 10, textLocation.getY() + 5); + textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos()); graphics.setFont(FontManager.getRunescapeBoldFont()); if (headIcon != null) { 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 a8009d4ae8..bdb5e3a7ff 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 @@ -77,7 +77,7 @@ public class FreezeTimersPlugin extends Plugin SpriteID.SPELL_TELE_BLOCK }; - private static final Dimension FREEZE_ICON_DIMENSION = new Dimension(17, 17); + private static final Dimension FREEZE_ICON_DIMENSION = new Dimension(25, 25); private static final Color FREEZE_ICON_OUTLINE_COLOR = new Color(33, 33, 33); private final BufferedImage[] FreezeIcons = new BufferedImage[FREEZE_ICONS.length]; From 55d7f64a08a7458653b373fbaf752b5ab8169b5c Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:31:36 +0100 Subject: [PATCH 39/75] Delete SafeSpotConfig.java --- .../plugins/safespot/SafeSpotConfig.java | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java deleted file mode 100644 index ec2e3cc105..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.runelite.client.plugins.safespot; - -import java.awt.Color; -import net.runelite.client.config.ConfigItem; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.Config; - -@ConfigGroup("safespot") -public interface SafeSpotConfig extends Config -{ - @ConfigItem(position = 1, keyName = "playerSafeSpots", name = "Render for Players", description = "Renders 1 way safe spots vs other players") - default boolean playerSafeSpots() { - return true; - } - - @ConfigItem(position = 2, keyName = "npcSafeSpots", name = "Render for NPCs", description = "Renders 1 way safe spots vs NPCs") - default boolean npcSafeSpots() { - return false; - } - - @ConfigItem(position = 3, keyName = "tileColor", name = "Tile Color", description = "Color of safe spot tile") - default Color tileColor() { - return Color.MAGENTA; - } -} \ No newline at end of file From cb0bb31047f702f4fa0b9acecbdca83743beebe3 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:31:44 +0100 Subject: [PATCH 40/75] Delete SafeSpotOverlay.java --- .../plugins/safespot/SafeSpotOverlay.java | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java deleted file mode 100644 index 7259957f15..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java +++ /dev/null @@ -1,40 +0,0 @@ -package net.runelite.client.plugins.safespot; - -import javax.inject.*; -import net.runelite.client.ui.overlay.*; -import java.awt.*; -import net.runelite.api.*; - -public class SafeSpotOverlay extends Overlay -{ - private final Client client; - private final SafeSpotPlugin safeSpotPlugin; - private final SafeSpotConfig config; - - @Inject - public SafeSpotOverlay( Client client, SafeSpotPlugin safeSpotPlugin, SafeSpotConfig config) { - this.client = client; - this.safeSpotPlugin = safeSpotPlugin; - this.config = config; - this.setPosition(OverlayPosition.DYNAMIC); - this.setPriority(OverlayPriority.LOW); - this.setLayer(OverlayLayer.ABOVE_SCENE); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (safeSpotPlugin.isSafeSpotsRenderable() && safeSpotPlugin.getSafeSpotList() != null && safeSpotPlugin.getSafeSpotList().size() > 0) { - safeSpotPlugin.getSafeSpotList().forEach(tile -> { - Polygon poly; - if (tile != null && tile.getLocalLocation() != null) { - poly = Perspective.getCanvasTilePoly(client, tile.getLocalLocation()); - if (poly != null) { - OverlayUtil.renderPolygon(graphics, poly, config.tileColor()); - } - } - return; - }); - } - return null; - } -} From 82c372247073159457ab0415a9f7bcce3bf9598f Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:31:50 +0100 Subject: [PATCH 41/75] Delete SafeSpotPlugin.java --- .../plugins/safespot/SafeSpotPlugin.java | 135 ------------------ 1 file changed, 135 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java deleted file mode 100644 index 9955332d11..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java +++ /dev/null @@ -1,135 +0,0 @@ -package net.runelite.client.plugins.safespot; - - -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldPoint; -import java.util.List; -import net.runelite.api.Actor; -import net.runelite.api.coords.WorldArea; -import net.runelite.api.NPC; -import net.runelite.api.Player; -import net.runelite.api.events.GameTick; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.api.events.InteractingChanged; -import com.google.inject.Provides; -import net.runelite.client.config.ConfigManager; -import net.runelite.api.Tile; -import java.util.ArrayList; -import net.runelite.client.ui.overlay.OverlayManager; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.Plugin; - -@PluginDescriptor( - name = "1 Way Safe Spots", - description = "Renders tile overlays for one way safe spots", - tags = { "safe spot", "pvp", "safespots", "pklite" }, - type = "PVP", - enabledByDefault = false -) - -// TODO : filter tiles you cant stand on - -public class SafeSpotPlugin extends Plugin -{ - @Inject - private Client client; - @Inject - OverlayManager overlayManager; - @Inject - private SafeSpotConfig config; - private ArrayList safeSpotList; - private boolean safeSpotsRenderable; - private SafeSpotOverlay safeSpotOverlay; - private int tickCount; - - public SafeSpotPlugin() { - this.safeSpotsRenderable = false; - this.tickCount = 0; - } - - @Provides - SafeSpotConfig config(ConfigManager configManager) { - return configManager.getConfig(SafeSpotConfig.class); - } - - @Override - protected void startUp() throws Exception { - this.safeSpotOverlay = new SafeSpotOverlay(this.client, this, this.config); - this.overlayManager.add(safeSpotOverlay); - } - - @Override - protected void shutDown() throws Exception { - this.overlayManager.remove(safeSpotOverlay); - } - - @Subscribe - private void onInteractingChanged(InteractingChanged event) { - if (event.getSource() != client.getLocalPlayer()) { - return; - } - if (event.getTarget() == null && (config.npcSafeSpots() || config.playerSafeSpots())) { - tickCount = 10; - } - } - - @Subscribe - public void onGameTick(GameTick event) { - if (client.getLocalPlayer().getInteracting() != null) { - if (client.getLocalPlayer().getInteracting() instanceof Player && config.playerSafeSpots()) { - safeSpotsRenderable = true; - updateSafeSpots(); - } - if (client.getLocalPlayer().getInteracting() instanceof NPC && config.npcSafeSpots()) { - safeSpotsRenderable = true; - updateSafeSpots(); - } - } - else { - safeSpotsRenderable = false; - } - if (tickCount > 0) { - --tickCount; - safeSpotsRenderable = true; - } - } - - private void updateSafeSpots() - { - if (client.getLocalPlayer().getInteracting() != null) - { - Actor enemy = client.getLocalPlayer().getInteracting(); - - WorldArea worldArea = new WorldArea(enemy.getWorldLocation().getX() - 12, enemy.getWorldLocation().getY() - 12, 24, 24, client.getPlane()); - List worldPoints = worldArea.toWorldPointList(); - safeSpotList = getSafeSpotList(enemy, worldPoints); - } - } - - private ArrayList getSafeSpotList(Actor actor, List worldPoints) - { - ArrayList safeSpotList = new ArrayList(); - Tile[][][] tiles = client.getScene().getTiles(); - for (WorldPoint w : worldPoints) - { - LocalPoint toPoint = LocalPoint.fromWorld(client, w); - Tile fromTile = tiles[client.getPlane()][actor.getLocalLocation().getSceneX()][actor.getLocalLocation().getSceneY()]; - Tile toTile = tiles[client.getPlane()][toPoint.getSceneX()][toPoint.getSceneY()]; - if ((toTile.hasLineOfSightTo(fromTile)) && (!fromTile.hasLineOfSightTo(toTile))) - { - safeSpotList.add(toTile); - } - } - return safeSpotList; - } - - public ArrayList getSafeSpotList() { - return safeSpotList; - } - - public boolean isSafeSpotsRenderable() { - return safeSpotsRenderable; - } -} \ No newline at end of file From cb397e566b3735654b017ff35709e24f4c5ffd39 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:33:29 +0100 Subject: [PATCH 42/75] Delete GroupItemListPlugin.java --- .../groupitemlist/GroupItemListPlugin.java | 70 ------------------- 1 file changed, 70 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java deleted file mode 100644 index c0939f04c9..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupItemListPlugin.java +++ /dev/null @@ -1,70 +0,0 @@ -package net.runelite.client.plugins.groupitemlist; - -import net.runelite.api.Client; -import net.runelite.api.MenuEntry; -import net.runelite.api.events.MenuOpened; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.input.KeyManager; -import net.runelite.client.input.MouseManager; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; - -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.LinkedHashMap; - -@PluginDescriptor( - name = "Group Item List", - description = "Group the right click menu of a pile of items.", - tags = {"ground", "compress", "pile", "group"}, - type = "utility", - enabledByDefault = false -) - -/** - * Main class of plugin - Groups duplicate right click menu options to singular entries with a quantity. - * - */ -public class GroupItemListPlugin extends Plugin { - - @Inject - private Client client; - - /** - * Fired on a right click menu opening. Count all menu entries and build a new list of entries - * displaying item quantities. - * - * @param menu Right click menu opened - */ - @Subscribe - public void onMenuOpened(MenuOpened menu) { - - LinkedHashMap entryCount = new LinkedHashMap<>(); - ArrayList temp = new ArrayList<>(); - MenuEntry[] updatedMenuEntries; - - // Iterate over menu entries - for (MenuEntry e : menu.getMenuEntries()) { - - // Increment the count if entry has been seen before - if (entryCount.containsKey(e)) { - entryCount.get(e).incrementCount(); - } - - // Store in map if entry has not been seen before - else { - entryCount.put(e, new GroupedItem(e)); - } - } - - // Create a list of updated menu entries from the map of GroupedItem - for (MenuEntry e : entryCount.keySet()) { - MenuEntry entry = entryCount.get(e).getEntry(); - temp.add(entry); - } - - // Parse to an array and set the new menu entries - updatedMenuEntries = temp.toArray(new MenuEntry[0]); - client.setMenuEntries(updatedMenuEntries); - } -} From 7955ae016bf53d9cb7be63ce44eaa82a59912a1f Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:33:36 +0100 Subject: [PATCH 43/75] Delete GroupedItem.java --- .../plugins/groupitemlist/GroupedItem.java | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupedItem.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupedItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupedItem.java deleted file mode 100644 index b4fbbda77f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groupitemlist/GroupedItem.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.runelite.client.plugins.groupitemlist; - -import net.runelite.api.MenuEntry; - -/** - * Object used to store a MenuEntry and the quantity. Updates the entry target if necessary - * e.g Shark to Shark [4]. - */ -public class GroupedItem { - - private int count; - private MenuEntry entry; - - /** - * Constructor for GroupedItem. - * - * @param entry The menu entry to be tracked for duplicates - */ - public GroupedItem(MenuEntry entry) { - this.entry = entry; - this.count = 1; - } - - /** - * Getter for the count. - * - * @return count - */ - public int getCount() { - return count; - } - - /** - * Getter for the menu entry, updates the target to reflect the quantity if more than 1 - * was found. - * - * @return Updated MenuEntry containing quantity - */ - public MenuEntry getEntry() { - if (count > 1) { - updateTarget(); - } - return entry; - } - - /** - * Updates the target of the menu entry to contain the quantity found. - */ - private void updateTarget() { - String target = entry.getTarget(); - target = target + " [" + count + "]"; - entry.setTarget(target); - } - - /** - * Increment count when duplicate entries are found. - */ - public void incrementCount() { - count += 1; - } -} From 06d036780247a47a66211ed18b9284fb59e3054d Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:35:55 +0100 Subject: [PATCH 44/75] Delete MapLocations.java --- .../plugins/zoneIndicators/MapLocations.java | 3479 ----------------- 1 file changed, 3479 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java 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/zoneIndicators/MapLocations.java deleted file mode 100644 index 81e8e0f527..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/MapLocations.java +++ /dev/null @@ -1,3479 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import java.awt.Polygon; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.geom.Area; -import java.util.ArrayList; -import java.util.List; -import net.runelite.api.Constants; - -public class MapLocations -{ - private static final List[] MULTICOMBAT = new List[Constants.MAX_Z]; - private static final List[] NOT_MULTICOMBAT = new List[Constants.MAX_Z]; - private static final List[] ROUGH_WILDERNESS = new List[Constants.MAX_Z]; - private static final List[] DEADMAN_SAFE_ZONES = new List[Constants.MAX_Z]; - private static final List[] PVP_WORLD_SAFE_ZONES = new List[Constants.MAX_Z]; - - private static Area getArea(List shapes) - { - Area area = new Area(); - for (Shape shape : shapes) - { - area.add(new Area(shape)); - } - return area; - } - - private static Area getArea(List shapes, Rectangle view) - { - Area area = new Area(); - for (Shape shape : shapes) - { - if (shape.intersects(view)) - { - area.add(new Area(shape)); - } - } - return area; - } - - public static Area getMulticombat(int plane) - { - Area area = getArea(MULTICOMBAT[plane]); - area.subtract(getArea(NOT_MULTICOMBAT[plane])); - return area; - } - - public static Area getMulticombat(Rectangle view, int plane) - { - Area area = getArea(MULTICOMBAT[plane], view); - area.subtract(getArea(NOT_MULTICOMBAT[plane], view)); - return area; - } - - public static Area getRoughWilderness(int plane) - { - return getArea(ROUGH_WILDERNESS[plane]); - } - - public static Area getRoughWilderness(Rectangle view, int plane) - { - return getArea(ROUGH_WILDERNESS[plane], view); - } - - public static Area getDeadmanSafeZones(int plane) - { - return getArea(DEADMAN_SAFE_ZONES[plane]); - } - - public static Area getDeadmanSafeZones(Rectangle view, int plane) - { - return getArea(DEADMAN_SAFE_ZONES[plane], view); - } - - public static Area getPvpSafeZones(int plane) - { - return getArea(PVP_WORLD_SAFE_ZONES[plane]); - } - - public static Area getPvpSafeZones(Rectangle view, int plane) - { - return getArea(PVP_WORLD_SAFE_ZONES[plane], view); - } - - static - { - for (int i = 0; i < MULTICOMBAT.length; i++) - { - MULTICOMBAT[i] = new ArrayList<>(); - } - for (int i = 0; i < NOT_MULTICOMBAT.length; i++) - { - NOT_MULTICOMBAT[i] = new ArrayList<>(); - } - for (int i = 0; i < ROUGH_WILDERNESS.length; i++) - { - ROUGH_WILDERNESS[i] = new ArrayList<>(); - } - for (int i = 0; i < DEADMAN_SAFE_ZONES.length; i++) - { - DEADMAN_SAFE_ZONES[i] = new ArrayList<>(); - } - for (int i = 0; i < PVP_WORLD_SAFE_ZONES.length; i++) - { - PVP_WORLD_SAFE_ZONES[i] = new ArrayList<>(); - } - - defineMulticombatAreas(); - defineDeadmanSafeZones(); - definePvpSafeZones(); - defineWilderness(); - } - - private static void defineMulticombatAreas() - { - // Main Wilderness - addPolygonOnPlane(MULTICOMBAT, 0, - 3200, 3968, - 3392, 3968, - 3392, 3840, - 3328, 3840, - 3328, 3520, - 3136, 3520, - 3136, 3648, - 3192, 3648, - 3192, 3752, - 3152, 3752, - 3152, 3840, - 3136, 3840, - 3136, 3872, - 3112, 3872, - 3112, 3880, - 3072, 3880, - 3072, 3896, - 3048, 3896, - 3048, 3872, - 3056, 3872, - 3056, 3864, - 3048, 3864, - 3048, 3856, - 3008, 3856, - 3008, 3904, - 3200, 3904); - - // South of wildy agility training arena - addPolygonOnPlane(MULTICOMBAT, 0, - 2984, 3928, - 3008, 3928, - 3008, 3912, - 2984, 3912); - - // Wildy zamorak temple - addPolygonOnPlane(MULTICOMBAT, 0, - 2944, 3832, - 2960, 3832, - 2960, 3816, - 2944, 3816); - - // Wildy bandit camp - addPolygonOnPlane(MULTICOMBAT, 0, - 3008, 3712, - 3072, 3712, - 3072, 3600, - 3008, 3600); - - // Chaos temple north of Falador - addPolygonOnPlane(MULTICOMBAT, 0, - 2928, 3520, - 2944, 3520, - 2944, 3512, - 2928, 3512); - - // Burthorpe - addPolygonOnPlane(MULTICOMBAT, 0, - 2880, 3544, - 2904, 3544, - 2904, 3520, - 2880, 3520); - - // White Wolf Mountain - addPolygonOnPlane(MULTICOMBAT, 0, - 2880, 3520, - 2816, 3520, - 2816, 3456, - 2880, 3456); - - // Death Plateu - addPolygonOnPlane(MULTICOMBAT, 0, - 2848, 3608, - 2880, 3608, - 2880, 3600, - 2848, 3600); - - // Trollheim/Godwars - addPolygonOnPlane(MULTICOMBAT, 0, - 2880, 3776, - 2912, 3776, - 2912, 3696, - 2920, 3696, - 2920, 3688, - 2896, 3688, - 2896, 3696, - 2880, 3696, - 2880, 3728, - 2888, 3728, - 2888, 3744, - 2880, 3744); - - // Northen Rellekka - addPolygonOnPlane(MULTICOMBAT, 0, - 2656, 3736, - 2704, 3736, - 2704, 3728, - 2712, 3728, - 2712, 3736, - 2736, 3736, - 2736, 3712, - 2656, 3712); - - // Northen Fremennik Isles - addPolygonOnPlane(MULTICOMBAT, 0, - 2304, 3904, - 2432, 3904, - 2432, 3840, - 2368, 3840, - 2368, 3816, - 2352, 3816, - 2352, 3824, - 2304, 3824); - - // Pirates Cove - addPolygonOnPlane(MULTICOMBAT, 0, - 2176, 3840, - 2240, 3840, - 2240, 3776, - 2176, 3776); - - // Lunar Isle - addPolygonOnPlane(MULTICOMBAT, 0, - 2048, 3968, - 2176, 3968, - 2176, 3840, - 2048, 3840); - - // Piscatoris Fishing Colony - addPolygonOnPlane(MULTICOMBAT, 0, - 2304, 3712, - 2368, 3712, - 2368, 3648, - 2304, 3648); - - // Ranging Guild - addPolygonOnPlane(MULTICOMBAT, 0, - 2656, 3448, - 2680, 3448, - 2680, 3440, - 2688, 3440, - 2688, 3416, - 2680, 3416, - 2680, 3408, - 2656, 3408, - 2656, 3416, - 2648, 3416, - 2648, 3440, - 2656, 3440); - - // Necromancer house, southeast of Ardy - addPolygonOnPlane(MULTICOMBAT, 0, - 2656, 3256, - 2680, 3256, - 2680, 3216, - 2664, 3216, - 2664, 3232, - 2656, 3232); - - // Battlefield noth of Tree Gnome Village - addPolygonOnPlane(MULTICOMBAT, 0, - 2504, 3248, - 2544, 3248, - 2544, 3232, - 2552, 3232, - 2552, 3208, - 2504, 3208); - - // Castle Wars - addPolygonOnPlane(MULTICOMBAT, 0, - 2368, 3136, - 2432, 3136, - 2432, 3072, - 2368, 3072); - - // Jiggig - addPolygonOnPlane(MULTICOMBAT, 0, - 2456, 3056, - 2496, 3056, - 2496, 3032, - 2456, 3032); - - // East feldip hills, near rantz - addPolygonOnPlane(MULTICOMBAT, 0, - 2648, 2976, - 2656, 2976, - 2656, 2952, - 2648, 2952); - - // Ape Atoll - addPolygonOnPlane(MULTICOMBAT, 0, - 2688, 2816, - 2816, 2816, - 2816, 2688, - 2688, 2688); - - // Pest Control - addPolygonOnPlane(MULTICOMBAT, 0, - 2624, 2624, - 2688, 2624, - 2688, 2560, - 2624, 2560); - - // Desert Bandit Camp - addPolygonOnPlane(MULTICOMBAT, 0, - 3152, 3000, - 3192, 3000, - 3192, 2960, - 3152, 2960); - - // Al Kharid - addPolygonOnPlane(MULTICOMBAT, 0, - 3264, 3200, - 3328, 3200, - 3328, 3136, - 3264, 3136); - - // Wizards Tower - addPolygonOnPlane(MULTICOMBAT, 0, - 3094, 3176, - 3126, 3176, - 3126, 3144, - 3094, 3144); - - // Draynor Village - addPolygonOnPlane(MULTICOMBAT, 0, - 3112, 3264, - 3136, 3264, - 3136, 3232, - 3104, 3232, - 3104, 3256, - 3112, 3256); - - // Falador - addPolygonOnPlane(MULTICOMBAT, 0, - 2944, 3456, - 3008, 3456, - 3008, 3328, - 3016, 3328, - 3016, 3304, - 2944, 3304); - - // Southwest fally castle isn't multicombat downstairs - addPolygonOnPlane(NOT_MULTICOMBAT, 0, - 2968, 3336, - 2968, 3328, - 2960, 3328, - 2960, 3336); - - // Barbarian Village - addPolygonOnPlane(MULTICOMBAT, 0, - 3072, 3456, - 3136, 3456, - 3136, 3392, - 3048, 3392, - 3048, 3408, - 3056, 3408, - 3056, 3440, - 3064, 3440, - 3064, 3448, - 3072, 3448); - - // Ammoniate crabs at northwest fossil island - addPolygonOnPlane(MULTICOMBAT, 0, - 3648, 3885, - 3663, 3885, - 3663, 3882, - 3664, 3882, - 3664, 3872, - 3663, 3872, - 3663, 3868, - 3648, 3868); - - // Ammoniate crabs at north fossil island - addPolygonOnPlane(MULTICOMBAT, 0, - 3680, 3904, - 3744, 3904, - 3744, 3856, - 3756, 3856, - 3756, 3852, - 3755, 3852, - 3755, 3851, - 3754, 3851, - 3754, 3850, - 3751, 3850, - 3751, 3849, - 3750, 3849, - 3750, 3848, - 3749, 3848, - 3749, 3847, - 3748, 3847, - 3748, 3846, - 3747, 3846, - 3747, 3845, - 3746, 3845, - 3746, 3844, - 3742, 3844, - 3742, 3845, - 3740, 3845, - 3740, 3844, - 3732, 3844, - 3732, 3843, - 3730, 3843, - 3730, 3842, - 3724, 3842, - 3724, 3843, - 3717, 3843, - 3717, 3842, - 3712, 3842, - 3712, 3846, - 3710, 3846, - 3710, 3847, - 3709, 3847, - 3709, 3848, - 3708, 3848, - 3708, 3859, - 3709, 3859, - 3709, 3860, - 3710, 3860, - 3710, 3861, - 3712, 3861, - 3712, 3866, - 3713, 3866, - 3713, 3870, - 3714, 3870, - 3714, 3873, - 3713, 3873, - 3713, 3876, - 3712, 3876, - 3712, 3881, - 3710, 3881, - 3710, 3888, - 3712, 3888, - 3712, 3890, - 3714, 3890, - 3714, 3891, - 3716, 3891, - 3716, 3892, - 3717, 3892, - 3717, 3893, - 3716, 3893, - 3716, 3894, - 3714, 3894, - 3714, 3895, - 3713, 3895, - 3713, 3896, - 3712, 3896, - 3712, 3897, - 3705, 3897, - 3705, 3898, - 3704, 3898, - 3704, 3899, - 3692, 3899, - 3692, 3898, - 3688, 3898, - 3688, 3897, - 3686, 3897, - 3686, 3896, - 3680, 3896); - - // Zeah, southwest of Wintertodt, snowy area with ice giants and wolves - addPolygonOnPlane(MULTICOMBAT, 0, - 1540, 3898, - 1543, 3898, - 1543, 3901, - 1546, 3901, - 1546, 3903, - 1547, 3903, - 1547, 3904, - 1550, 3904, - 1550, 3903, - 1553, 3903, - 1553, 3904, - 1559, 3904, - 1559, 3902, - 1564, 3902, - 1564, 3903, - 1565, 3903, - 1565, 3904, - 1568, 3904, - 1568, 3903, - 1569, 3903, - 1569, 3902, - 1570, 3902, - 1570, 3901, - 1573, 3901, - 1573, 3898, - 1577, 3898, - 1577, 3899, - 1578, 3899, - 1578, 3902, - 1579, 3902, - 1579, 3903, - 1584, 3903, - 1584, 3902, - 1586, 3902, - 1586, 3901, - 1590, 3901, - 1590, 3891, - 1588, 3891, - 1588, 3887, - 1572, 3887, - 1572, 3872, - 1567, 3872, - 1567, 3868, - 1563, 3868, - 1563, 3867, - 1558, 3867, - 1558, 3868, - 1557, 3868, - 1557, 3870, - 1549, 3870, - 1549, 3874, - 1545, 3874, - 1545, 3876, - 1543, 3876, - 1543, 3877, - 1542, 3877, - 1542, 3879, - 1541, 3879, - 1541, 3882, - 1539, 3882, - 1539, 3887, - 1540, 3887, - 1540, 3888, - 1539, 3888, - 1539, 3894, - 1540, 3894); - - // Zeah arceuus area - addPolygonOnPlane(MULTICOMBAT, 0, - 1664, 3776, - 1664, 3785, - 1667, 3785, - 1667, 3805, - 1671, 3805, - 1671, 3811, - 1675, 3811, - 1675, 3819, - 1690, 3819, - 1690, 3814, - 1695, 3814, - 1695, 3806, - 1719, 3806, - 1719, 3787, - 1725, 3787, - 1725, 3778, - 1711, 3778, - 1711, 3776); - - // Arceuus teletab-making house - addPolygonOnPlane(MULTICOMBAT, 0, - 1667, 3772, - 1679, 3772, - 1679, 3775, - 1691, 3775, - 1691, 3761, - 1679, 3761, - 1679, 3764, - 1667, 3764); - // Next house east - addPolygonOnPlane(MULTICOMBAT, 0, - 1696, 3775, - 1708, 3775, - 1708, 3763, - 1696, 3763); - // Next house east - addPolygonOnPlane(MULTICOMBAT, 0, - 1713, 3775, - 1727, 3775, - 1727, 3763, - 1724, 3763, - 1724, 3752, - 1716, 3752, - 1716, 3763, - 1713, 3763); - // Arceuus rune shop house - addPolygonOnPlane(MULTICOMBAT, 0, - 1716, 3750, - 1728, 3750, - 1728, 3736, - 1716, 3736); - // Arceuus general store house - addPolygonOnPlane(MULTICOMBAT, 0, - 1717, 3732, - 1725, 3732, - 1725, 3715, - 1715, 3715, - 1715, 3725, - 1717, 3725); - // Arceuus pub - addPolygonOnPlane(MULTICOMBAT, 0, - 1683, 3732, - 1691, 3732, - 1691, 3725, - 1697, 3725, - 1697, 3730, - 1703, 3730, - 1703, 3712, - 1683, 3712); - // Arceuus staff store - addPolygonOnPlane(MULTICOMBAT, 0, - 1664, 3732, - 1676, 3732, - 1676, 3720, - 1664, 3720); - // Next house to the west - addPolygonOnPlane(MULTICOMBAT, 0, - 1647, 3738, - 1655, 3738, - 1655, 3726, - 1658, 3726, - 1658, 3714, - 1644, 3714, - 1644, 3726, - 1647, 3726); - // Next house to the north - addPolygonOnPlane(MULTICOMBAT, 0, - 1647, 3762, - 1657, 3762, - 1657, 3752, - 1655, 3752, - 1655, 3745, - 1647, 3745); - - // Arceuus house magic trees - addPolygonOnPlane(MULTICOMBAT, 0, - 1682, 3755, - 1692, 3755, - 1692, 3745, - 1690, 3745, - 1690, 3738, - 1682, 3738); - // West of that ^ - addPolygonOnPlane(MULTICOMBAT, 0, - 1667, 3756, - 1675, 3756, - 1675, 3740, - 1665, 3740, - 1665, 3746, - 1667, 3746); - - // This one goes through western piscarilius, northen hosidius - // and southwestern arceuus - addPolygonOnPlane(MULTICOMBAT, 0, - 1728, 3808, - 1792, 3808, - 1792, 3764, - 1856, 3764, - 1856, 3712, - 1792, 3712, - 1792, 3648, - 1664, 3648, - 1664, 3706, - 1665, 3706, - 1665, 3705, - 1668, 3705, - 1668, 3706, - 1671, 3706, - 1671, 3705, - 1675, 3705, - 1675, 3704, - 1683, 3704, - 1683, 3701, - 1684, 3701, - 1684, 3700, - 1686, 3700, - 1686, 3702, - 1687, 3702, - 1687, 3700, - 1688, 3700, - 1688, 3701, - 1690, 3701, - 1690, 3703, - 1689, 3703, - 1689, 3704, - 1690, 3704, - 1690, 3705, - 1704, 3705, - 1704, 3707, - 1706, 3707, - 1706, 3712, - 1711, 3712, - 1711, 3711, - 1710, 3711, - 1710, 3710, - 1712, 3710, - 1712, 3707, - 1728, 3707); - - // Kourend castle - addPolygonOnPlane(MULTICOMBAT, 0, - 1614, 3691, - 1619, 3691, - 1619, 3690, - 1620, 3690, - 1620, 3689, - 1653, 3689, - 1653, 3690, - 1654, 3690, - 1654, 3691, - 1657, 3691, - 1657, 3690, - 1658, 3690, - 1658, 3689, - 1659, 3689, - 1659, 3686, - 1658, 3686, - 1658, 3685, - 1657, 3685, - 1657, 3662, - 1658, 3662, - 1658, 3661, - 1659, 3661, - 1659, 3658, - 1658, 3658, - 1658, 3657, - 1657, 3657, - 1657, 3656, - 1654, 3656, - 1654, 3657, - 1653, 3657, - 1653, 3658, - 1620, 3658, - 1620, 3657, - 1619, 3657, - 1619, 3656, - 1614, 3656, - 1614, 3657, - 1613, 3657, - 1613, 3661, - 1612, 3661, - 1612, 3662, - 1611, 3662, - 1611, 3663, - 1600, 3663, - 1600, 3662, - 1599, 3662, - 1599, 3661, - 1594, 3661, - 1594, 3662, - 1593, 3662, - 1593, 3685, - 1594, 3685, - 1594, 3686, - 1599, 3686, - 1599, 3685, - 1600, 3685, - 1600, 3684, - 1611, 3684, - 1611, 3685, - 1612, 3685, - 1612, 3686, - 1613, 3686, - 1613, 3690, - 1614, 3690); - - // Western hosidius area, including woodcutting guild and western sand crabs - addPolygonOnPlane(MULTICOMBAT, 0, - 1650, 3648, - 1664, 3648, - 1664, 3520, - 1689, 3520, - 1689, 3496, - 1707, 3496, - 1707, 3485, - 1708, 3485, - 1708, 3484, - 1710, 3484, - 1710, 3483, - 1713, 3483, - 1713, 3482, - 1720, 3482, - 1720, 3481, - 1721, 3481, - 1721, 3480, - 1722, 3480, - 1722, 3479, - 1723, 3479, - 1723, 3478, - 1724, 3478, - 1724, 3477, - 1726, 3477, - 1726, 3476, - 1728, 3476, - 1728, 3472, - 1708, 3472, - 1708, 3456, - 1600, 3456, - 1600, 3584, - 1608, 3584, - 1608, 3616, - 1650, 3616); - - // Hosidius sand crabs - addPolygonOnPlane(MULTICOMBAT, 0, - 1740, 3478, - 1741, 3478, - 1741, 3479, - 1745, 3479, - 1745, 3480, - 1751, 3480, - 1751, 3479, - 1752, 3479, - 1752, 3478, - 1753, 3478, - 1753, 3477, - 1755, 3477, - 1755, 3476, - 1757, 3476, - 1757, 3475, - 1758, 3475, - 1758, 3474, - 1759, 3474, - 1759, 3473, - 1779, 3473, - 1779, 3474, - 1781, 3474, - 1781, 3475, - 1786, 3475, - 1786, 3476, - 1800, 3476, - 1800, 3475, - 1805, 3475, - 1805, 3474, - 1807, 3474, - 1807, 3473, - 1808, 3473, - 1808, 3472, - 1810, 3472, - 1810, 3471, - 1833, 3471, - 1833, 3470, - 1834, 3470, - 1834, 3469, - 1852, 3469, - 1852, 3449, - 1792, 3449, - 1792, 3424, - 1800, 3424, - 1800, 3449, - 1800, 3400, - 1728, 3400, - 1728, 3462, - 1729, 3462, - 1729, 3466, - 1730, 3466, - 1730, 3469, - 1731, 3469, - 1731, 3470, - 1732, 3470, - 1732, 3471, - 1733, 3471, - 1733, 3473, - 1734, 3473, - 1734, 3474, - 1736, 3474, - 1736, 3475, - 1737, 3475, - 1737, 3476, - 1738, 3476, - 1738, 3477, - 1740, 3477); - - // Apparently there is a 1x1 single zone on the sand crab island - addPolygonOnPlane(NOT_MULTICOMBAT, 0, - 1777, 3416, - 1777, 3417, - 1778, 3417, - 1778, 3416); - - // Eastern hosidius area - addPolygonOnPlane(MULTICOMBAT, 0, - 1834, 3584, - 1888, 3584, - 1888, 3528, - 1856, 3528, - 1856, 3520, - 1834, 3520, - 1834, 3522, - 1833, 3522, - 1833, 3535, - 1834, 3535, - 1834, 3538, - 1835, 3538, - 1835, 3539, - 1836, 3539, - 1836, 3540, - 1837, 3540, - 1837, 3541, - 1838, 3541, - 1838, 3542, - 1840, 3542, - 1840, 3543, - 1841, 3543, - 1841, 3545, - 1842, 3545, - 1842, 3546, - 1844, 3546, - 1844, 3547, - 1845, 3547, - 1845, 3548, - 1851, 3548, - 1851, 3551, - 1853, 3551, - 1853, 3563, - 1851, 3563, - 1851, 3566, - 1847, 3566, - 1847, 3567, - 1845, 3567, - 1845, 3568, - 1844, 3568, - 1844, 3569, - 1843, 3569, - 1843, 3571, - 1842, 3571, - 1842, 3573, - 1841, 3573, - 1841, 3574, - 1840, 3574, - 1840, 3575, - 1839, 3575, - 1839, 3576, - 1838, 3576, - 1838, 3577, - 1837, 3577, - 1837, 3578, - 1836, 3578, - 1836, 3579, - 1835, 3579, - 1835, 3581, - 1834, 3581); - - // Eastern hosidius area also has a 1x1 multi area - addPolygonOnPlane(MULTICOMBAT, 0, - 1849, 3563, - 1849, 3564, - 1850, 3564, - 1850, 3563); - - // Hosidius cows/chickens/pigs - addPolygonOnPlane(MULTICOMBAT, 0, - 1792, 3513, - 1802, 3513, - 1802, 3520, - 1810, 3520, - 1810, 3513, - 1816, 3513, - 1816, 3512, - 1836, 3512, - 1836, 3494, - 1796, 3494, - 1796, 3495, - 1792, 3495); - - // Hosidius southeast of tithe farm - addPolygonOnPlane(MULTICOMBAT, 0, - 1777, 3597, - 1794, 3597, - 1794, 3561, - 1777, 3561, - 1777, 3591, - 1779, 3591, - 1779, 3592, - 1777, 3592); - - // West of shayzien house - addPolygonOnPlane(MULTICOMBAT, 0, - 1408, 3584, - 1408, 3582, - 1486, 3582, - 1486, 3568, - 1528, 3568, - 1528, 3520, - 1408, 3520, - 1408, 3464, - 1380, 3464, - 1380, 3486, - 1377, 3486, - 1377, 3488, - 1373, 3488, - 1373, 3492, - 1364, 3492, - 1364, 3512, - 1358, 3512, - 1358, 3520, - 1356, 3520, - 1356, 3532, - 1358, 3532, - 1358, 3540, - 1359, 3540, - 1359, 3542, - 1360, 3542, - 1360, 3557, - 1356, 3557, - 1356, 3560, - 1351, 3560, - 1351, 3570, - 1354, 3570, - 1354, 3581, - 1346, 3581, - 1346, 3584); - - // South of chambers of xeric - addPolygonOnPlane(MULTICOMBAT, 0, - 1261, 3489, - 1259, 3489, - 1259, 3488, - 1255, 3488, - 1255, 3487, - 1243, 3487, - 1243, 3490, - 1234, 3490, - 1234, 3480, - 1192, 3480, - 1192, 3568, - 1209, 3568, - 1209, 3548, - 1215, 3548, - 1215, 3544, - 1217, 3544, - 1217, 3536, - 1235, 3536, - 1235, 3532, - 1249, 3532, - 1249, 3525, - 1248, 3525, - 1248, 3517, - 1254, 3517, - 1254, 3513, - 1274, 3513, - 1274, 3510, - 1296, 3510, - 1296, 3511, - 1300, 3511, - 1300, 3501, - 1287, 3501, - 1287, 3490, - 1280, 3490, - 1280, 3489, - 1264, 3489, - 1264, 3490, - 1261, 3490); - - // Lizardman shamans - addPolygonOnPlane(MULTICOMBAT, 0, - 1416, 3728, - 1456, 3728, - 1456, 3688, - 1416, 3688); - - // Other lizardman area at shayzien (west side) - addPolygonOnPlane(MULTICOMBAT, 0, - 1472, 3712, - 1510, 3712, - 1510, 3702, - 1509, 3702, - 1509, 3701, - 1506, 3701, - 1506, 3696, - 1500, 3696, - 1500, 3680, - 1472, 3680); - - // Other lizardman area at shayzien (east side) - addPolygonOnPlane(MULTICOMBAT, 0, - 1538, 3704, - 1560, 3704, - 1560, 3672, - 1538, 3672); - - // Lovakengj house - addPolygonOnPlane(MULTICOMBAT, 0, - 1600, 3712, - 1472, 3712, - 1472, 3840, - 1547, 3840, - 1547, 3816, - 1556, 3816, - 1556, 3809, - 1562, 3809, - 1562, 3800, - 1568, 3800, - 1568, 3793, - 1571, 3793, - 1571, 3816, - 1571, 3776, - 1600, 3776); - - // Shayzien house - addPolygonOnPlane(MULTICOMBAT, 0, - 1475, 3587, - 1475, 3641, - 1534, 3641, - 1534, 3587); - - // Shayzien house bank is non-multi - addPolygonOnPlane(NOT_MULTICOMBAT, 0, - 1495, 3622, - 1515, 3622, - 1515, 3612, - 1495, 3612); - - // Shayzien house general store - addPolygonOnPlane(MULTICOMBAT, 0, - 1539, 3640, - 1551, 3640, - 1551, 3621, - 1539, 3621); - - // Kourend woodland barbarian area - addPolygonOnPlane(MULTICOMBAT, 0, - 1572, 3442, - 1591, 3442, - 1591, 3424, - 1572, 3424); - - // Catacombs - addPolygonTo(MULTICOMBAT, - 1600, 9984, - 1600, 10067, - 1628, 10067, - 1628, 10070, - 1639, 10070, - 1639, 10112, - 1730, 10112, - 1730, 9984); - - // Zeah dungeon with sand crabs - addPolygonTo(MULTICOMBAT, - 1632, 9792, - 1632, 9856, - 1728, 9856, - 1728, 9792); - - // Waterbirth island near the doors where people use rune throwing axes - addPolygonTo(MULTICOMBAT, - 2536, 10136, - 2536, 10152, - 2552, 10152, - 2552, 10136); - - // Waterbirth island dungeon, on the path to dks - addPolygonTo(MULTICOMBAT, - 1792, 4352, - 1792, 4416, - 1984, 4416, - 1984, 4352); - - // Dagannoths in lighthouse - addPolygonTo(MULTICOMBAT, - 2496, 10048, - 2560, 10048, - 2560, 9984, - 2496, 9984); - - // Dagannoth kings (DKs) including slayer only dks - addPolygonTo(MULTICOMBAT, - 2944, 4352, - 2944, 4480, - 2880, 4480, - 2880, 4352); - - // White wolf mountain dungeon at ice queen - addPolygonTo(MULTICOMBAT, - 2856, 9928, - 2856, 9968, - 2880, 9968, - 2880, 9928); - - // Kharazi jungle dungeon (in dragon slayer 2 quest) - addPolygonTo(MULTICOMBAT, - 2816, 9296, - 2880, 9296, - 2880, 9216, - 2816, 9216); - - // Tzhaar, fight pits and inferno area - addPolygonTo(MULTICOMBAT, - 2368, 5184, - 2560, 5184, - 2560, 5056, - 2368, 5056); - - // Smoke devils - addPolygonTo(MULTICOMBAT, - 2432, 9408, - 2344, 9408, - 2344, 9472, - 2432, 9472); - - // Kraken - addPolygonTo(MULTICOMBAT, - 2270, 10045, - 2291, 10045, - 2291, 10022, - 2270, 10022); - - // Giant mole - addPolygonTo(MULTICOMBAT, - 1728, 5240, - 1792, 5240, - 1792, 5120, - 1728, 5120); - - // Godwars dungeon - addPolygonTo(MULTICOMBAT, - 2816, 5376, - 2944, 5376, - 2944, 5248, - 2816, 5248); - - // Desert treasure shadow diamond area - addPolygonTo(MULTICOMBAT, - 2752, 5064, - 2728, 5064, - 2728, 5088, - 2720, 5088, - 2720, 5096, - 2712, 5096, - 2712, 5112, - 2736, 5112, - 2736, 5120, - 2752, 5120); - - // Kalphite slayer area - addPolygonTo(MULTICOMBAT, - 3264, 9544, - 3344, 9544, - 3344, 9472, - 3264, 9472); - - // Normal kalphite area including kalphite queen - addPolygonTo(MULTICOMBAT, - 3456, 9536, - 3520, 9536, - 3520, 9472, - 3456, 9472); - - // Tarns lair - addPolygonTo(MULTICOMBAT, - 3136, 4664, - 3200, 4664, - 3200, 4544, - 3136, 4544); - - // Haunted mine boss area - addPolygonTo(MULTICOMBAT, - 2752, 4416, - 2752, 4480, - 2816, 4480, - 2816, 4416); - - // Entrance to dorgesh kaan - addPolygonTo(MULTICOMBAT, - 3328, 9600, - 3312, 9600, - 3312, 9640, - 3304, 9640, - 3304, 9664, - 3328, 9664); - - // Hammerspikes hangout in dwarven mines - addPolygonTo(MULTICOMBAT, - 2960, 9824, - 2976, 9824, - 2976, 9800, - 2960, 9800); - - // Fremennik isles dungeon - addPolygonTo(MULTICOMBAT, - 2432, 10304, - 2432, 10240, - 2368, 10240, - 2368, 10304); - - // Varrock sewers - addPolygonTo(MULTICOMBAT, - 3152, 9920, - 3288, 9920, - 3288, 9856, - 3152, 9856); - - // Stronghold of security 1st floor - addPolygonTo(MULTICOMBAT, - 1856, 5248, - 1920, 5248, - 1920, 5184, - 1856, 5184); - - // Corp cave - addPolygonTo(MULTICOMBAT, - 2960, 4400, - 3000, 4400, - 3000, 4368, - 2960, 4368); - - // ZMI altar area - addPolygonTo(MULTICOMBAT, - 3008, 5632, - 3072, 5632, - 3072, 5568, - 3008, 5568); - - // Dragon slayer 2 zeah underground puzzle - addPolygonTo(MULTICOMBAT, - 1472, 9984, - 1536, 9984, - 1536, 9920, - 1472, 9920); - - // Wildy revenant caves - addPolygonTo(MULTICOMBAT, - 3136, 10062, - 3136, 10240, - 3236, 10240, - 3236, 10229, - 3264, 10229, - 3264, 10048, - 3208, 10048, - 3208, 10062); - - // King black dragon (Kbd) - addPolygonTo(MULTICOMBAT, - 2240, 4672, - 2240, 4736, - 2304, 4736, - 2304, 4672); - - // Scorpia - addPolygonTo(MULTICOMBAT, - 3248, 10352, - 3248, 10328, - 3216, 10328, - 3216, 10352); - - // Inside mage bank - addPolygonTo(MULTICOMBAT, - 2496, 4672, - 2496, 4736, - 2560, 4736, - 2560, 4672); - - // Wildy godwars dungeon - addPolygonTo(MULTICOMBAT, - 3072, 10112, - 3008, 10112, - 3008, 10176, - 3048, 10176, - 3048, 10152, - 3056, 10152, - 3056, 10144, - 3064, 10144, - 3064, 10136, - 3072, 10136); - - // Enchanted valley - addPolygonTo(MULTICOMBAT, - 3008, 4480, - 3008, 4544, - 3072, 4544, - 3072, 4480); - - // Zulrah - addPolygonTo(MULTICOMBAT, - 2256, 3080, - 2280, 3080, - 2280, 3064, - 2256, 3064); - - // Abyssal sire and abyss - addPolygonTo(MULTICOMBAT, - 3008, 4736, - 2944, 4736, - 2944, 4864, - 3136, 4864, - 3136, 4736, - 3072, 4736, - 3072, 4800, - 3008, 4800); - } - - private static void defineDeadmanSafeZones() - { - // Varrock - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3182, 3382, - 3182, 3399, - 3174, 3399, - 3174, 3448, - 3198, 3448, - 3198, 3449, - 3197, 3449, - 3197, 3450, - 3196, 3450, - 3196, 3451, - 3195, 3451, - 3195, 3452, - 3194, 3452, - 3194, 3453, - 3193, 3453, - 3193, 3454, - 3192, 3454, - 3192, 3455, - 3191, 3455, - 3191, 3456, - 3190, 3456, - 3190, 3457, - 3185, 3457, - 3185, 3463, - 3186, 3463, - 3186, 3464, - 3187, 3464, - 3187, 3467, - 3167, 3467, - 3167, 3468, - 3163, 3468, - 3163, 3467, - 3142, 3467, - 3142, 3468, - 3141, 3468, - 3141, 3469, - 3140, 3469, - 3140, 3470, - 3139, 3470, - 3139, 3471, - 3138, 3471, - 3138, 3484, - 3139, 3484, - 3139, 3485, - 3140, 3485, - 3140, 3486, - 3141, 3486, - 3141, 3491, - 3140, 3491, - 3140, 3492, - 3139, 3492, - 3139, 3493, - 3138, 3493, - 3138, 3515, - 3139, 3515, - 3139, 3516, - 3140, 3516, - 3140, 3517, - 3141, 3517, - 3141, 3518, - 3160, 3518, - 3160, 3517, - 3161, 3517, - 3161, 3516, - 3162, 3516, - 3162, 3515, - 3167, 3515, - 3167, 3516, - 3168, 3516, - 3168, 3517, - 3169, 3517, - 3169, 3518, - 3191, 3518, - 3191, 3517, - 3192, 3517, - 3192, 3516, - 3193, 3516, - 3193, 3515, - 3194, 3515, - 3194, 3514, - 3195, 3514, - 3195, 3513, - 3196, 3513, - 3196, 3512, - 3197, 3512, - 3197, 3511, - 3198, 3511, - 3198, 3510, - 3199, 3510, - 3199, 3509, - 3200, 3509, - 3200, 3508, - 3230, 3508, - 3230, 3507, - 3231, 3507, - 3231, 3506, - 3232, 3506, - 3232, 3505, - 3233, 3505, - 3233, 3504, - 3234, 3504, - 3234, 3503, - 3235, 3503, - 3235, 3502, - 3252, 3502, - 3252, 3496, - 3253, 3496, - 3253, 3495, - 3254, 3495, - 3254, 3494, - 3255, 3494, - 3255, 3493, - 3263, 3493, - 3263, 3472, - 3264, 3472, - 3264, 3471, - 3265, 3471, - 3265, 3470, - 3266, 3470, - 3266, 3469, - 3267, 3469, - 3267, 3468, - 3268, 3468, - 3268, 3467, - 3269, 3467, - 3269, 3466, - 3270, 3466, - 3270, 3465, - 3271, 3465, - 3271, 3437, - 3274, 3437, - 3274, 3424, - 3277, 3424, - 3277, 3420, - 3274, 3420, - 3274, 3411, - 3275, 3411, - 3275, 3410, - 3276, 3410, - 3276, 3409, - 3277, 3409, - 3277, 3408, - 3288, 3408, - 3288, 3391, - 3289, 3391, - 3289, 3385, - 3290, 3385, - 3290, 3378, - 3289, 3378, - 3289, 3377, - 3288, 3377, - 3288, 3376, - 3265, 3376, - 3265, 3380, - 3253, 3380, - 3253, 3382, - 3245, 3382, - 3245, 3380, - 3242, 3380, - 3242, 3382, - 3239, 3382, - 3239, 3381, - 3209, 3381, - 3209, 3382, - 3282, 3382); - - // Lumbridge - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3201, 3257, - 3213, 3257, - 3213, 3264, - 3233, 3264, - 3233, 3257, - 3235, 3257, - 3235, 3241, - 3237, 3241, - 3237, 3237, - 3239, 3237, - 3239, 3231, - 3243, 3231, - 3243, 3220, - 3253, 3220, - 3253, 3217, - 3256, 3217, - 3256, 3212, - 3259, 3212, - 3259, 3190, - 3247, 3190, - 3247, 3191, - 3238, 3191, - 3238, 3195, - 3230, 3195, - 3230, 3201, - 3228, 3201, - 3228, 3202, - 3227, 3202, - 3227, 3205, - 3228, 3205, - 3228, 3207, - 3225, 3207, - 3225, 3206, - 3224, 3206, - 3224, 3205, - 3223, 3205, - 3223, 3204, - 3222, 3204, - 3222, 3203, - 3215, 3203, - 3215, 3202, - 3214, 3202, - 3214, 3201, - 3203, 3201, - 3203, 3202, - 3202, 3202, - 3202, 3203, - 3201, 3203, - 3201, 3217, - 3199, 3217, - 3199, 3220, - 3201, 3220); - - // Falador - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2986, 3395, - 2986, 3394, - 2987, 3394, - 2987, 3393, - 2996, 3393, - 2996, 3394, - 3002, 3394, - 3002, 3395, - 3009, 3395, - 3009, 3394, - 3010, 3394, - 3010, 3393, - 3011, 3393, - 3011, 3392, - 3021, 3392, - 3021, 3391, - 3022, 3391, - 3022, 3390, - 3041, 3390, - 3041, 3389, - 3047, 3389, - 3047, 3390, - 3062, 3390, - 3062, 3389, - 3063, 3389, - 3063, 3388, - 3064, 3388, - 3064, 3387, - 3065, 3387, - 3065, 3386, - 3066, 3386, - 3066, 3368, - 3065, 3368, - 3065, 3367, - 3064, 3367, - 3064, 3366, - 3063, 3366, - 3063, 3365, - 3062, 3365, - 3062, 3364, - 3061, 3364, - 3061, 3363, - 3060, 3363, - 3060, 3331, - 3061, 3331, - 3061, 3328, - 3058, 3328, - 3058, 3329, - 3025, 3329, - 3025, 3328, - 3024, 3328, - 3024, 3327, - 3016, 3327, - 3016, 3326, - 3015, 3326, - 3015, 3325, - 3014, 3325, - 3014, 3324, - 3013, 3324, - 3013, 3323, - 3008, 3323, - 3008, 3324, - 3006, 3324, - 3006, 3323, - 3002, 3323, - 3002, 3322, - 3001, 3322, - 3001, 3321, - 3000, 3321, - 3000, 3320, - 2999, 3320, - 2999, 3319, - 2998, 3319, - 2998, 3318, - 2997, 3318, - 2997, 3317, - 2996, 3317, - 2996, 3316, - 2992, 3316, - 2992, 3315, - 2991, 3315, - 2991, 3314, - 2990, 3314, - 2990, 3313, - 2989, 3313, - 2989, 3312, - 2988, 3312, - 2988, 3311, - 2987, 3311, - 2987, 3310, - 2986, 3310, - 2986, 3309, - 2966, 3309, - 2966, 3310, - 2956, 3310, - 2956, 3311, - 2941, 3311, - 2941, 3312, - 2940, 3312, - 2940, 3320, - 2936, 3320, - 2936, 3354, - 2937, 3354, - 2937, 3357, - 2936, 3357, - 2936, 3389, - 2937, 3389, - 2937, 3390, - 2938, 3390, - 2938, 3391, - 2939, 3391, - 2939, 3392, - 2940, 3392, - 2940, 3393, - 2943, 3393, - 2943, 3394, - 2944, 3394, - 2944, 3395, - 2950, 3395, - 2950, 3394, - 2956, 3394, - 2956, 3395); - - // Port phasmatys - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3650, 3456, - 3650, 3472, - 3651, 3472, - 3651, 3473, - 3652, 3473, - 3652, 3474, - 3653, 3474, - 3653, 3507, - 3654, 3507, - 3654, 3508, - 3668, 3508, - 3668, 3509, - 3669, 3509, - 3669, 3510, - 3670, 3510, - 3670, 3511, - 3671, 3511, - 3671, 3512, - 3672, 3512, - 3672, 3513, - 3673, 3513, - 3673, 3514, - 3674, 3514, - 3674, 3515, - 3675, 3515, - 3675, 3516, - 3676, 3516, - 3676, 3517, - 3687, 3517, - 3687, 3494, - 3690, 3494, - 3690, 3493, - 3696, 3493, - 3696, 3482, - 3699, 3482, - 3699, 3481, - 3712, 3481, - 3712, 3456); - - // Sophanem - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3274, 2752, - 3274, 2784, - 3277, 2784, - 3277, 2786, - 3274, 2786, - 3274, 2789, - 3272, 2789, - 3272, 2810, - 3322, 2810, - 3322, 2752); - - // Ardy - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2560, 3256, - 2560, 3264, - 2559, 3264, - 2559, 3328, - 2560, 3328, - 2560, 3339, - 2561, 3339, - 2561, 3340, - 2562, 3340, - 2562, 3341, - 2563, 3341, - 2563, 3342, - 2616, 3342, - 2616, 3341, - 2617, 3341, - 2617, 3340, - 2669, 3340, - 2669, 3339, - 2670, 3339, - 2670, 3338, - 2671, 3338, - 2671, 3337, - 2672, 3337, - 2672, 3336, - 2673, 3336, - 2673, 3335, - 2674, 3335, - 2674, 3334, - 2683, 3334, - 2683, 3333, - 2684, 3333, - 2684, 3332, - 2685, 3332, - 2685, 3331, - 2686, 3331, - 2686, 3330, - 2687, 3330, - 2687, 3329, - 2688, 3329, - 2688, 3264, - 2638, 3264, - 2638, 3263, - 2625, 3263, - 2625, 3264, - 2611, 3264, - 2611, 3257, - 2602, 3257, - 2602, 3264, - 2587, 3264, - 2587, 3263, - 2586, 3263, - 2586, 3262, - 2584, 3262, - 2584, 3261, - 2583, 3261, - 2583, 3260, - 2582, 3260, - 2582, 3259, - 2581, 3259, - 2581, 3258, - 2572, 3258, - 2572, 3260, - 2571, 3260, - 2571, 3261, - 2566, 3261, - 2566, 3260, - 2565, 3260, - 2565, 3259, - 2564, 3259, - 2564, 3256); - - // Yanille - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2613, 3103, - 2614, 3103, - 2614, 3102, - 2615, 3102, - 2615, 3101, - 2616, 3101, - 2616, 3100, - 2617, 3100, - 2617, 3099, - 2618, 3099, - 2618, 3098, - 2619, 3098, - 2619, 3097, - 2620, 3097, - 2620, 3075, - 2590, 3075, - 2590, 3074, - 2589, 3074, - 2589, 3073, - 2584, 3073, - 2584, 3074, - 2583, 3074, - 2583, 3075, - 2543, 3075, - 2543, 3076, - 2542, 3076, - 2542, 3077, - 2539, 3077, - 2539, 3107, - 2542, 3107, - 2542, 3108, - 2543, 3108, - 2543, 3109, - 2608, 3109, - 2608, 3108, - 2609, 3108, - 2609, 3107, - 2610, 3107, - 2610, 3106, - 2611, 3106, - 2611, 3105, - 2612, 3105, - 2612, 3104, - 2613, 3104); - - // Gnome stronghold - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2495, 3439, - 2494, 3439, - 2494, 3432, - 2495, 3432, - 2495, 3431, - 2496, 3431, - 2496, 3430, - 2497, 3430, - 2497, 3429, - 2498, 3429, - 2498, 3417, - 2497, 3417, - 2497, 3416, - 2496, 3416, - 2496, 3412, - 2495, 3412, - 2495, 3408, - 2494, 3408, - 2494, 3404, - 2495, 3404, - 2495, 3403, - 2496, 3403, - 2496, 3402, - 2497, 3402, - 2497, 3401, - 2498, 3401, - 2498, 3400, - 2499, 3400, - 2499, 3399, - 2500, 3399, - 2500, 3398, - 2501, 3398, - 2501, 3397, - 2502, 3397, - 2502, 3396, - 2506, 3396, - 2506, 3391, - 2502, 3391, - 2502, 3390, - 2492, 3390, - 2492, 3391, - 2489, 3391, - 2489, 3390, - 2488, 3390, - 2488, 3389, - 2485, 3389, - 2485, 3390, - 2482, 3390, - 2482, 3389, - 2476, 3389, - 2476, 3390, - 2471, 3390, - 2471, 3391, - 2468, 3391, - 2468, 3390, - 2467, 3390, - 2467, 3389, - 2466, 3389, - 2466, 3385, - 2465, 3385, - 2465, 3384, - 2458, 3384, - 2458, 3385, - 2457, 3385, - 2457, 3389, - 2456, 3389, - 2456, 3390, - 2455, 3390, - 2455, 3391, - 2450, 3391, - 2450, 3390, - 2446, 3390, - 2446, 3391, - 2443, 3391, - 2443, 3390, - 2442, 3390, - 2442, 3389, - 2440, 3389, - 2440, 3388, - 2434, 3388, - 2434, 3389, - 2433, 3389, - 2433, 3390, - 2432, 3390, - 2432, 3391, - 2428, 3391, - 2428, 3392, - 2427, 3392, - 2427, 3393, - 2420, 3393, - 2420, 3394, - 2419, 3394, - 2419, 3395, - 2418, 3395, - 2418, 3396, - 2417, 3396, - 2417, 3397, - 2416, 3397, - 2416, 3399, - 2415, 3399, - 2415, 3400, - 2414, 3400, - 2414, 3408, - 2413, 3408, - 2413, 3409, - 2412, 3409, - 2412, 3410, - 2411, 3410, - 2411, 3411, - 2410, 3411, - 2410, 3412, - 2387, 3412, - 2387, 3407, - 2383, 3407, - 2383, 3408, - 2380, 3408, - 2380, 3409, - 2379, 3409, - 2379, 3410, - 2377, 3410, - 2377, 3411, - 2376, 3411, - 2376, 3413, - 2375, 3413, - 2375, 3417, - 2374, 3417, - 2374, 3418, - 2373, 3418, - 2373, 3419, - 2372, 3419, - 2372, 3420, - 2371, 3420, - 2371, 3421, - 2370, 3421, - 2370, 3422, - 2369, 3422, - 2369, 3433, - 2370, 3433, - 2370, 3434, - 2371, 3434, - 2371, 3444, - 2372, 3444, - 2372, 3445, - 2373, 3445, - 2373, 3446, - 2374, 3446, - 2374, 3447, - 2375, 3447, - 2375, 3459, - 2376, 3459, - 2376, 3460, - 2377, 3460, - 2377, 3461, - 2378, 3461, - 2378, 3462, - 2379, 3462, - 2379, 3463, - 2380, 3463, - 2380, 3464, - 2381, 3464, - 2381, 3476, - 2379, 3476, - 2379, 3477, - 2378, 3477, - 2378, 3478, - 2377, 3478, - 2377, 3485, - 2376, 3485, - 2376, 3486, - 2375, 3486, - 2375, 3499, - 2376, 3499, - 2376, 3500, - 2377, 3500, - 2377, 3507, - 2378, 3507, - 2378, 3508, - 2379, 3508, - 2379, 3509, - 2380, 3509, - 2380, 3521, - 2382, 3521, - 2382, 3522, - 2384, 3522, - 2384, 3523, - 2393, 3523, - 2393, 3524, - 2399, 3524, - 2399, 3525, - 2404, 3525, - 2404, 3524, - 2405, 3524, - 2405, 3523, - 2407, 3523, - 2407, 3522, - 2415, 3522, - 2415, 3521, - 2425, 3521, - 2425, 3522, - 2427, 3522, - 2427, 3523, - 2430, 3523, - 2430, 3522, - 2431, 3522, - 2431, 3521, - 2432, 3521, - 2432, 3520, - 2448, 3520, - 2448, 3517, - 2454, 3517, - 2454, 3516, - 2455, 3516, - 2455, 3515, - 2456, 3515, - 2456, 3514, - 2457, 3514, - 2457, 3513, - 2460, 3513, - 2460, 3512, - 2461, 3512, - 2461, 3511, - 2465, 3511, - 2465, 3510, - 2468, 3510, - 2468, 3511, - 2472, 3511, - 2472, 3512, - 2473, 3512, - 2473, 3513, - 2475, 3513, - 2475, 3514, - 2476, 3514, - 2476, 3515, - 2477, 3515, - 2477, 3516, - 2478, 3516, - 2478, 3517, - 2483, 3517, - 2483, 3516, - 2487, 3516, - 2487, 3515, - 2488, 3515, - 2488, 3512, - 2487, 3512, - 2487, 3509, - 2488, 3509, - 2488, 3508, - 2489, 3508, - 2489, 3507, - 2491, 3507, - 2491, 3506, - 2492, 3506, - 2492, 3505, - 2493, 3505, - 2493, 3499, - 2492, 3499, - 2492, 3498, - 2491, 3498, - 2491, 3497, - 2490, 3497, - 2490, 3495, - 2491, 3495, - 2491, 3494, - 2492, 3494, - 2492, 3493, - 2493, 3493, - 2493, 3485, - 2490, 3485, - 2490, 3484, - 2489, 3484, - 2489, 3483, - 2488, 3483, - 2488, 3482, - 2487, 3482, - 2487, 3481, - 2486, 3481, - 2486, 3474, - 2488, 3474, - 2488, 3471, - 2489, 3471, - 2489, 3470, - 2490, 3470, - 2490, 3460, - 2491, 3460, - 2491, 3456, - 2496, 3456, - 2496, 3440, - 2495, 3440); - - // Rellekka - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2620, 3682, - 2624, 3682, - 2624, 3683, - 2625, 3683, - 2625, 3687, - 2629, 3687, - 2629, 3686, - 2630, 3686, - 2630, 3685, - 2632, 3685, - 2632, 3686, - 2636, 3686, - 2636, 3692, - 2645, 3692, - 2645, 3695, - 2647, 3695, - 2647, 3696, - 2649, 3696, - 2649, 3702, - 2650, 3702, - 2650, 3703, - 2651, 3703, - 2651, 3704, - 2652, 3704, - 2652, 3711, - 2653, 3711, - 2653, 3712, - 2691, 3712, - 2691, 3709, - 2692, 3709, - 2692, 3707, - 2693, 3707, - 2693, 3703, - 2692, 3703, - 2692, 3701, - 2691, 3701, - 2691, 3699, - 2690, 3699, - 2690, 3695, - 2691, 3695, - 2691, 3693, - 2692, 3693, - 2692, 3691, - 2693, 3691, - 2693, 3685, - 2692, 3685, - 2692, 3683, - 2691, 3683, - 2691, 3681, - 2690, 3681, - 2690, 3680, - 2689, 3680, - 2689, 3672, - 2690, 3672, - 2690, 3671, - 2691, 3671, - 2691, 3666, - 2690, 3666, - 2690, 3664, - 2689, 3664, - 2689, 3660, - 2690, 3660, - 2690, 3658, - 2691, 3658, - 2691, 3656, - 2692, 3656, - 2692, 3654, - 2693, 3654, - 2693, 3651, - 2692, 3651, - 2692, 3649, - 2690, 3649, - 2690, 3648, - 2688, 3648, - 2688, 3647, - 2686, 3647, - 2686, 3646, - 2673, 3646, - 2673, 3645, - 2636, 3645, - 2636, 3647, - 2627, 3647, - 2627, 3648, - 2625, 3648, - 2625, 3649, - 2624, 3649, - 2624, 3650, - 2622, 3650, - 2622, 3651, - 2620, 3651, - 2620, 3652, - 2618, 3652, - 2618, 3653, - 2616, 3653, - 2616, 3654, - 2609, 3654, - 2609, 3655, - 2607, 3655, - 2607, 3656, - 2603, 3656, - 2603, 3657, - 2602, 3657, - 2602, 3658, - 2601, 3658, - 2601, 3663, - 2602, 3663, - 2602, 3664, - 2603, 3664, - 2603, 3665, - 2604, 3665, - 2604, 3666, - 2605, 3666, - 2605, 3667, - 2606, 3667, - 2606, 3671, - 2609, 3671, - 2609, 3672, - 2610, 3672, - 2610, 3673, - 2611, 3673, - 2611, 3675, - 2612, 3675, - 2612, 3676, - 2614, 3676, - 2614, 3677, - 2616, 3677, - 2616, 3679, - 2618, 3679, - 2618, 3681, - 2620, 3681); - - // Jatizo - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2407, 3797, - 2407, 3793, - 2399, 3793, - 2399, 3792, - 2391, 3792, - 2391, 3791, - 2386, 3791, - 2386, 3796, - 2388, 3796, - 2388, 3802, - 2386, 3802, - 2386, 3807, - 2388, 3807, - 2388, 3809, - 2402, 3809, - 2402, 3819, - 2406, 3819, - 2406, 3824, - 2408, 3824, - 2408, 3826, - 2413, 3826, - 2413, 3824, - 2419, 3824, - 2419, 3826, - 2424, 3826, - 2424, 3821, - 2423, 3821, - 2423, 3798, - 2422, 3798, - 2422, 3797); - - // Neitiznot - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2329, 3812, - 2333, 3812, - 2333, 3813, - 2334, 3813, - 2334, 3814, - 2335, 3814, - 2335, 3815, - 2338, 3815, - 2338, 3816, - 2339, 3816, - 2339, 3817, - 2368, 3817, - 2368, 3776, - 2352, 3776, - 2352, 3796, - 2344, 3796, - 2344, 3795, - 2331, 3795, - 2331, 3797, - 2330, 3797, - 2330, 3798, - 2329, 3798); - - // Pest control - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2624, 2688, - 2688, 2688, - 2688, 2624, - 2624, 2624); - - // Tutorial island - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 3052, 3135, - 3156, 3135, - 3156, 3057, - 3052, 3057); - - // Camelot bank - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2724, 3487, - 2724, 3490, - 2721, 3490, - 2721, 3494, - 2719, 3494, - 2719, 3497, - 2721, 3497, - 2721, 3498, - 2731, 3498, - 2731, 3490, - 2728, 3490, - 2728, 3487); - - // Catherby bank - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 2806, 3438, - 2806, 3446, - 2813, 3446, - 2813, 3438); - - // Kourend castle - addPolygonOnPlane(DEADMAN_SAFE_ZONES, 0, - 1627, 3658, - 1620, 3658, - 1620, 3657, - 1619, 3657, - 1619, 3656, - 1614, 3656, - 1614, 3657, - 1613, 3657, - 1613, 3661, - 1612, 3661, - 1612, 3662, - 1611, 3662, - 1611, 3663, - 1600, 3663, - 1600, 3662, - 1599, 3662, - 1599, 3661, - 1594, 3661, - 1594, 3662, - 1593, 3662, - 1593, 3685, - 1594, 3685, - 1594, 3686, - 1599, 3686, - 1599, 3685, - 1600, 3685, - 1600, 3684, - 1611, 3684, - 1611, 3685, - 1612, 3685, - 1612, 3686, - 1613, 3686, - 1613, 3690, - 1614, 3690, - 1614, 3691, - 1619, 3691, - 1619, 3690, - 1620, 3690, - 1620, 3689, - 1630, 3689, - 1630, 3686, - 1620, 3686, - 1620, 3685, - 1619, 3685, - 1619, 3683, - 1620, 3683, - 1620, 3682, - 1621, 3682, - 1621, 3681, - 1622, 3681, - 1622, 3680, - 1623, 3680, - 1623, 3679, - 1624, 3679, - 1624, 3668, - 1623, 3668, - 1623, 3667, - 1622, 3667, - 1622, 3666, - 1621, 3666, - 1621, 3665, - 1620, 3665, - 1620, 3664, - 1619, 3664, - 1619, 3662, - 1620, 3662, - 1620, 3661, - 1627, 3661); - } - - private static void definePvpSafeZones() - { - // Grand exchange - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3159, 3473, - 3159, 3474, - 3157, 3474, - 3157, 3475, - 3155, 3475, - 3155, 3476, - 3153, 3476, - 3153, 3477, - 3152, 3477, - 3152, 3478, - 3151, 3478, - 3151, 3480, - 3150, 3480, - 3150, 3482, - 3149, 3482, - 3149, 3484, - 3148, 3484, - 3148, 3496, - 3149, 3496, - 3149, 3498, - 3150, 3498, - 3150, 3500, - 3151, 3500, - 3151, 3502, - 3152, 3502, - 3152, 3503, - 3153, 3503, - 3153, 3504, - 3155, 3504, - 3155, 3505, - 3157, 3505, - 3157, 3506, - 3159, 3506, - 3159, 3507, - 3171, 3507, - 3171, 3506, - 3173, 3506, - 3173, 3505, - 3175, 3505, - 3175, 3504, - 3177, 3504, - 3177, 3503, - 3178, 3503, - 3178, 3502, - 3179, 3502, - 3179, 3500, - 3180, 3500, - 3180, 3498, - 3181, 3498, - 3181, 3496, - 3182, 3496, - 3182, 3484, - 3181, 3484, - 3181, 3482, - 3180, 3482, - 3180, 3480, - 3179, 3480, - 3179, 3478, - 3178, 3478, - 3178, 3477, - 3177, 3477, - 3177, 3476, - 3175, 3476, - 3175, 3475, - 3173, 3475, - 3173, 3474, - 3171, 3474, - 3171, 3473); - - // Edgeville - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3091, 3488, - 3091, 3493, - 3090, 3493, - 3090, 3498, - 3091, 3498, - 3091, 3500, - 3099, 3500, - 3099, 3488); - - // Fally west bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2943, 3368, - 2943, 3374, - 2948, 3374, - 2948, 3370, - 2950, 3370, - 2950, 3366, - 2949, 3366, - 2949, 3359, - 2945, 3359, - 2945, 3362, - 2946, 3362, - 2946, 3366, - 2945, 3366, - 2945, 3368); - - // Fally east bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3009, 3353, - 3009, 3359, - 3019, 3359, - 3019, 3357, - 3022, 3357, - 3022, 3353); - - // Fally castle - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2964, 3354, - 2966, 3354, - 2966, 3352, - 2967, 3352, - 2967, 3349, - 2976, 3349, - 2976, 3348, - 2977, 3348, - 2977, 3347, - 2981, 3347, - 2981, 3343, - 2982, 3343, - 2982, 3339, - 2981, 3339, - 2981, 3337, - 2967, 3337, - 2967, 3330, - 2963, 3330, - 2963, 3331, - 2962, 3331, - 2962, 3332, - 2961, 3332, - 2961, 3334, - 2964, 3334, - 2964, 3335, - 2965, 3335, - 2965, 3343, - 2964, 3343, - 2964, 3344, - 2961, 3344, - 2961, 3350, - 2963, 3350, - 2963, 3352, - 2964, 3352); - - // Varrock east bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3250, 3425, - 3258, 3425, - 3258, 3416, - 3250, 3416); - - // Varrock west bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3180, 3433, - 3180, 3448, - 3191, 3448, - 3191, 3433); - - // Port phasmatys - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3686, 3472, - 3700, 3472, - 3700, 3461, - 3686, 3461); - - // Yanille bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2609, 3088, - 2609, 3098, - 2617, 3098, - 2617, 3088); - - // Ardy east bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2649, 3280, - 2649, 3288, - 2659, 3288, - 2659, 3280); - - // Ardy west bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2612, 3330, - 2612, 3336, - 2615, 3336, - 2615, 3335, - 2619, 3335, - 2619, 3336, - 2622, 3336, - 2622, 3330); - - // Fishing guild bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2593, 3413, - 2588, 3413, - 2588, 3418, - 2583, 3418, - 2583, 3423, - 2590, 3423, - 2590, 3420, - 2593, 3420); - - // Gnome stronghold bank near slayer cave (2nd floor) - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, - 2444, 3431, - 2444, 3435, - 2448, 3435, - 2448, 3431, - 2447, 3431, - 2447, 3428, - 2449, 3428, - 2449, 3422, - 2447, 3422, - 2447, 3419, - 2448, 3419, - 2448, 3415, - 2444, 3415, - 2444, 3419, - 2445, 3419, - 2445, 3422, - 2443, 3422, - 2443, 3428, - 2445, 3428, - 2445, 3431); - - // Gnome stronghold bank in grand tree - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, - 2456, 3488, - 2452, 3488, - 2452, 3486, - 2450, 3486, - 2450, 3483, - 2451, 3483, - 2451, 3478, - 2448, 3478, - 2448, 3483, - 2449, 3483, - 2449, 3486, - 2447, 3486, - 2447, 3488, - 2443, 3488, - 2443, 3487, - 2438, 3487, - 2438, 3490, - 2443, 3490, - 2443, 3489, - 2447, 3489, - 2447, 3491, - 2449, 3491, - 2449, 3494, - 2448, 3494, - 2448, 3496, - 2451, 3496, - 2451, 3494, - 2450, 3494, - 2450, 3491, - 2452, 3491, - 2452, 3489, - 2456, 3489); - - // Al kharid bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3265, 3161, - 3265, 3174, - 3273, 3174, - 3273, 3161); - - // Shantay pass bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3308, 3119, - 3308, 3125, - 3310, 3125, - 3310, 3119); - - // Nardah bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3431, 2891, - 3431, 2889, - 3427, 2889, - 3427, 2887, - 3424, 2887, - 3424, 2895, - 3431, 2895, - 3431, 2893, - 3432, 2893, - 3432, 2891); - - // Sophanem bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2807, 5158, - 2792, 5158, - 2792, 5175, - 2807, 5175); - - // Canifis bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3509, 3474, - 3509, 3478, - 3508, 3478, - 3508, 3483, - 3509, 3483, - 3509, 3484, - 3517, 3484, - 3517, 3477, - 3516, 3477, - 3516, 3476, - 3513, 3476, - 3513, 3474); - - // Lumbridge castle outside - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3216, 3209, - 3216, 3210, - 3217, 3210, - 3217, 3228, - 3216, 3228, - 3216, 3229, - 3227, 3229, - 3227, 3221, - 3230, 3221, - 3230, 3217, - 3227, 3217, - 3227, 3209); - - // Lumbridge bank upstairs - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 2, - 3211, 3223, - 3211, 3215, - 3207, 3215, - 3207, 3223); - - // Draynor bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3098, 3240, - 3088, 3240, - 3088, 3247, - 3098, 3247); - - // Pest control bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2665, 2656, - 2670, 2656, - 2670, 2651, - 2665, 2651); - - // Shilo village bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2843, 2957, - 2846, 2957, - 2846, 2956, - 2849, 2956, - 2849, 2957, - 2850, 2957, - 2850, 2958, - 2855, 2958, - 2855, 2957, - 2856, 2957, - 2856, 2956, - 2858, 2956, - 2858, 2957, - 2862, 2957, - 2862, 2952, - 2858, 2952, - 2858, 2953, - 2856, 2953, - 2856, 2952, - 2855, 2952, - 2855, 2951, - 2850, 2951, - 2850, 2952, - 2849, 2952, - 2849, 2953, - 2847, 2953, - 2847, 2952, - 2843, 2952); - - // Legends guild bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 2, - 2731, 3374, - 2731, 3383, - 2734, 3383, - 2734, 3374); - - // Legends guild middle floor - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 1, - 2724, 3374, - 2724, 3383, - 2734, 3383, - 2734, 3382, - 2736, 3382, - 2736, 3375, - 2734, 3375, - 2734, 3374); - - // Warriors guild bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2843, 3537, - 2843, 3540, - 2841, 3540, - 2841, 3546, - 2849, 3546, - 2849, 3537, - 2847, 3537, - 2847, 3536, - 2846, 3536, - 2846, 3537); - - // Camelot bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2724, 3487, - 2724, 3490, - 2721, 3490, - 2721, 3494, - 2719, 3494, - 2719, 3497, - 2721, 3497, - 2721, 3498, - 2731, 3498, - 2731, 3490, - 2728, 3490, - 2728, 3487); - - // Camelot respawn point - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2761, 3483, - 2761, 3476, - 2755, 3476, - 2755, 3483); - - // Catherby bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2806, 3438, - 2806, 3446, - 2813, 3446, - 2813, 3438); - - // Barbarian outpost bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2536, 3572, - 2536, 3575, - 2538, 3575, - 2538, 3572); - - // Piscatoris bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2327, 3686, - 2327, 3694, - 2333, 3694, - 2333, 3686); - - // Lletya bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2350, 3161, - 2350, 3165, - 2351, 3165, - 2351, 3167, - 2357, 3167, - 2357, 3165, - 2356, 3165, - 2356, 3164, - 2355, 3164, - 2355, 3161); - - // Castle wars bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2446, 3087, - 2445, 3087, - 2445, 3085, - 2447, 3085, - 2447, 3081, - 2443, 3081, - 2443, 3082, - 2439, 3082, - 2439, 3081, - 2435, 3081, - 2435, 3099, - 2439, 3099, - 2439, 3098, - 2443, 3098, - 2443, 3099, - 2447, 3099, - 2447, 3095, - 2445, 3095, - 2445, 3093, - 2446, 3093); - - // Duel arena bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3380, 3267, - 3380, 3273, - 3381, 3273, - 3381, 3274, - 3385, 3274, - 3385, 3267); - - // Clan wars bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3375, 3165, - 3361, 3165, - 3361, 3173, - 3375, 3173); - - // Lumbridge cellar bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 3218, 9622, - 3218, 9624, - 3220, 9624, - 3220, 9622); - - // Dorgesh kaan bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2709, 5348, - 2707, 5348, - 2707, 5345, - 2701, 5345, - 2701, 5347, - 2697, 5347, - 2697, 5353, - 2701, 5353, - 2701, 5355, - 2707, 5355, - 2707, 5350, - 2709, 5350); - - // Keldagrim bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2842, 10204, - 2834, 10204, - 2834, 10216, - 2842, 10216); - - // Tzhaar bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2438, 5176, - 2438, 5180, - 2441, 5180, - 2441, 5182, - 2449, 5182, - 2449, 5181, - 2450, 5181, - 2450, 5180, - 2452, 5180, - 2452, 5175, - 2441, 5175, - 2441, 5176); - - // Inferno bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2542, 5135, - 2542, 5139, - 2539, 5139, - 2539, 5140, - 2538, 5140, - 2538, 5141, - 2537, 5141, - 2537, 5144, - 2541, 5144, - 2541, 5145, - 2543, 5145, - 2543, 5144, - 2544, 5144, - 2544, 5142, - 2545, 5142, - 2545, 5135); - - // Port khazard bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2661, 3160, - 2661, 3163, - 2666, 3163, - 2666, 3160); - - // Corsair cove bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2569, 2863, - 2569, 2868, - 2572, 2868, - 2572, 2863); - - // Burgh de rott bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3495, 3210, - 3495, 3214, - 3501, 3214, - 3501, 3210); - - // Edgeville respawn point - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3092, 3468, - 3092, 3474, - 3098, 3474, - 3098, 3468); - - // Mage bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2529, 4711, - 2529, 4724, - 2548, 4724, - 2548, 4711); - - // Lunar bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2097, 3917, - 2097, 3922, - 2105, 3922, - 2105, 3917); - - // Jatizo bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2414, 3801, - 2414, 3804, - 2420, 3804, - 2420, 3801); - - // Neitiznot bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2334, 3805, - 2334, 3809, - 2340, 3809, - 2340, 3805); - - // Hosidius bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1671, 3558, - 1671, 3577, - 1682, 3577, - 1682, 3558); - - // Woodcutting guild bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1589, 3475, - 1589, 3481, - 1594, 3481, - 1594, 3475); - - // Lands end bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1508, 3415, - 1508, 3424, - 1514, 3424, - 1514, 3415); - - // Chambers of xeric bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1252, 3570, - 1252, 3574, - 1257, 3574, - 1257, 3570); - - // Arceuus bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1621, 3736, - 1621, 3754, - 1627, 3754, - 1627, 3751, - 1633, 3751, - 1633, 3754, - 1639, 3754, - 1639, 3736); - - // Piscarilius bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1794, 3784, - 1794, 3794, - 1812, 3794, - 1812, 3784); - - // Lovakengj bank southeast - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1518, 3735, - 1518, 3744, - 1535, 3744, - 1535, 3735); - - // Lovakenj bank west - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1433, 3820, - 1433, 3837, - 1442, 3837, - 1442, 3820); - - // Lovakenj sulphur mine bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1452, 3855, - 1452, 3860, - 1455, 3860, - 1455, 3855); - - // Blast mine bank southeast - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1500, 3856, - 1500, 3858, - 1503, 3858, - 1503, 3856); - - // Wintertodt bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1638, 3942, - 1638, 3947, - 1642, 3947, - 1642, 3942); - - // Shayzien bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1495, 3612, - 1495, 3622, - 1515, 3622, - 1515, 3612); - - // Hosidius grape farm bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1804, 3571, - 1804, 3572, - 1808, 3572, - 1808, 3571); - - // Hosidius cooking bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 1652, 3605, - 1652, 3615, - 1661, 3615, - 1661, 3605); - - // Ecteria bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 2618, 3893, - 2618, 3897, - 2622, 3897, - 2622, 3893); - - // Mining guild expanded area - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 3018, 9733, - 3021, 9733, - 3021, 9729, - 3022, 9729, - 3022, 9728, - 3023, 9728, - 3023, 9727, - 3025, 9727, - 3025, 9726, - 3026, 9726, - 3026, 9725, - 3030, 9725, - 3030, 9726, - 3032, 9726, - 3032, 9727, - 3035, 9727, - 3035, 9726, - 3038, 9726, - 3038, 9727, - 3041, 9727, - 3041, 9728, - 3042, 9728, - 3042, 9730, - 3045, 9730, - 3045, 9727, - 3047, 9727, - 3047, 9726, - 3048, 9726, - 3048, 9724, - 3052, 9724, - 3052, 9725, - 3053, 9725, - 3053, 9726, - 3055, 9726, - 3055, 9725, - 3056, 9725, - 3056, 9723, - 3057, 9723, - 3057, 9720, - 3056, 9720, - 3056, 9719, - 3054, 9719, - 3054, 9718, - 3052, 9718, - 3052, 9717, - 3050, 9717, - 3050, 9718, - 3045, 9718, - 3045, 9716, - 3044, 9716, - 3044, 9715, - 3041, 9715, - 3041, 9714, - 3039, 9714, - 3039, 9713, - 3037, 9713, - 3037, 9714, - 3036, 9714, - 3036, 9715, - 3034, 9715, - 3034, 9716, - 3029, 9716, - 3029, 9715, - 3028, 9715, - 3028, 9714, - 3026, 9714, - 3026, 9709, - 3027, 9709, - 3027, 9708, - 3028, 9708, - 3028, 9705, - 3029, 9705, - 3029, 9701, - 3028, 9701, - 3028, 9700, - 3027, 9700, - 3027, 9699, - 3023, 9699, - 3023, 9700, - 3019, 9700, - 3019, 9701, - 3018, 9701, - 3018, 9705, - 3019, 9705, - 3019, 9707, - 3020, 9707, - 3020, 9708, - 3021, 9708, - 3021, 9709, - 3022, 9709, - 3022, 9713, - 3021, 9713, - 3021, 9714, - 3019, 9714, - 3019, 9715, - 3018, 9715, - 3018, 9717, - 3015, 9717, - 3015, 9716, - 3013, 9716, - 3013, 9717, - 3012, 9717, - 3012, 9720, - 3013, 9720, - 3013, 9721, - 3015, 9721, - 3015, 9723, - 3016, 9723, - 3016, 9727, - 3017, 9727, - 3017, 9730, - 3018, 9730); - - // Motherlode mine bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 3760, 5671, - 3760, 5668, - 3761, 5668, - 3761, 5665, - 3760, 5665, - 3760, 5663, - 3758, 5663, - 3758, 5671); - - // Mos le harmles bank - addPolygonOnPlane(PVP_WORLD_SAFE_ZONES, 0, - 3679, 2980, - 3679, 2985, - 3681, 2985, - 3681, 2984, - 3682, 2984, - 3682, 2985, - 3684, 2985, - 3684, 2980, - 3682, 2980, - 3682, 2981, - 3681, 2981, - 3681, 2980); - - // Zanaris bank - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 2388, 4454, - 2380, 4454, - 2380, 4463, - 2388, 4463); - - // Wodcuting guild bank underground - addPolygonTo(PVP_WORLD_SAFE_ZONES, - 1550, 9872, - 1550, 9874, - 1553, 9874, - 1553, 9872); - } - - private static void defineWilderness() - { - // Above ground - addPolygonTo(ROUGH_WILDERNESS, - 2944, 3523, - 3392, 3523, - 3392, 3971, - 2944, 3971); - - // Underground - addPolygonTo(ROUGH_WILDERNESS, - 2944, 9918, - 2944, 10360, - 3264, 10360, - 3264, 9918); - } - - private static void addPolygonTo(List[] shapes, int... coords) - { - Polygon poly = new Polygon(); - for (int i = 0; i < coords.length; i += 2) - { - poly.addPoint(coords[i], coords[i + 1]); - } - for (int i = 0; i < shapes.length; i++) - { - shapes[i].add(poly); - } - } - - private static void addPolygonOnPlane(List[] shapes, int plane, int... coords) - { - Polygon poly = new Polygon(); - for (int i = 0; i < coords.length; i += 2) - { - poly.addPoint(coords[i], coords[i + 1]); - } - shapes[plane].add(poly); - } - - private static void addPolygonOnPlanes(List[] shapes, int minPlane, int maxPlane, int... coords) - { - Polygon poly = new Polygon(); - for (int i = 0; i < coords.length; i += 2) - { - poly.addPoint(coords[i], coords[i + 1]); - } - for (int i = minPlane; i <= maxPlane; i++) - { - shapes[i].add(poly); - } - } -} \ No newline at end of file From 9be2b74747c09b3c3a8bfd84cc3129591a64da42 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:36:00 +0100 Subject: [PATCH 45/75] Delete ZoneIndicatorsConfig.java --- .../zoneIndicators/ZoneIndicatorsConfig.java | 111 ------------------ 1 file changed, 111 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java 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/zoneIndicators/ZoneIndicatorsConfig.java deleted file mode 100644 index 370533dac7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsConfig.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -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 -{ - @ConfigItem( - keyName = "multicombatZoneVisibility", - name = "Multicombat zones", - description = "Determine where multicombat zones should be shown", - position = 1 - ) - default ZoneVisibility multicombatZoneVisibility() - { - return ZoneVisibility.SHOW_IN_PVP; - } - - @ConfigItem( - keyName = "pvpSafeZones", - name = "PvP safe zones", - description = "Show safe zones in PvP worlds", - position = 2 - ) - default boolean showPvpSafeZones() - { - return true; - } - - @ConfigItem( - keyName = "deadmanSafeZones", - name = "Deadman safe zones", - description = "Show safe zones in Deadman worlds", - position = 3 - ) - default boolean showDeadmanSafeZones() - { - return true; - } - - @ConfigItem( - keyName = "collisionDetection", - name = "Collision detection", - description = "Only show lines where they can be walked through", - position = 4 - ) - default boolean collisionDetection() - { - return false; - } - - @ConfigItem( - keyName = "showMinimapLines", - name = "Show on minimap", - description = "Show multicombat and safe zones on the minimap", - position = 5 - ) - default boolean showMinimapLines() - { - return true; - } - - @ConfigItem( - keyName = "multicombatColor", - name = "Multicombat zone color", - description = "Choose color to use for marking multicombat zones", - position = 6 - ) - default Color multicombatColor() - { - return Color.MAGENTA; - } - - @ConfigItem( - keyName = "safeZoneColor", - name = "Safe zone color", - description = "Choose color to use for marking safe zones in PvP/Deadman", - position = 7 - ) - default Color safeZoneColor() - { - return Color.GREEN; - } -} \ No newline at end of file From fd1678463f771262f0fca6b6871b69cc09bd2bfa Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:36:07 +0100 Subject: [PATCH 46/75] Delete ZoneIndicatorsMinimapOverlay.java --- .../ZoneIndicatorsMinimapOverlay.java | 116 ------------------ 1 file changed, 116 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java 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/zoneIndicators/ZoneIndicatorsMinimapOverlay.java deleted file mode 100644 index 699b0f0ddf..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsMinimapOverlay.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.geom.GeneralPath; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.geometry.Geometry; -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; - -public class ZoneIndicatorsMinimapOverlay extends Overlay -{ - private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; - - @Inject - private Client client; - - @Inject - private ZoneIndicatorsPlugin plugin; - - @Inject - private ZoneIndicatorsConfig config; - - @Inject - public ZoneIndicatorsMinimapOverlay() - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ALWAYS_ON_TOP); - setPriority(OverlayPriority.LOW); - } - - private Color getTransparentColorVersion(Color c) - { - return new Color(c.getRed(), c.getGreen(), c.getBlue(), 192); - } - - private void renderPath(Graphics2D graphics, GeneralPath path, Color color) - { - LocalPoint playerLp = client.getLocalPlayer().getLocalLocation(); - Rectangle viewArea = new Rectangle( - playerLp.getX() - MAX_LOCAL_DRAW_LENGTH, - playerLp.getY() - MAX_LOCAL_DRAW_LENGTH, - MAX_LOCAL_DRAW_LENGTH * 2, - MAX_LOCAL_DRAW_LENGTH * 2); - - graphics.setColor(color); - - path = Geometry.clipPath(path, viewArea); - path = Geometry.filterPath(path, (p1, p2) -> - Perspective.localToMinimap(client, new LocalPoint((int)p1[0], (int)p1[1])) != null && - Perspective.localToMinimap(client, new LocalPoint((int)p2[0], (int)p2[1])) != null); - path = Geometry.transformPath(path, coords -> - { - Point point = Perspective.localToMinimap(client, new LocalPoint((int)coords[0], (int)coords[1])); - coords[0] = point.getX(); - coords[1] = point.getY(); - }); - - graphics.draw(path); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (!config.showMinimapLines()) - { - return null; - } - - GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()]; - GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()]; - - if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null) - { - renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor())); - } - if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null) - { - renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor())); - } - - return null; - } -} \ No newline at end of file From 114f3a35a15e14acd36522ee60f3e65dd286d75b Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:36:13 +0100 Subject: [PATCH 47/75] Delete ZoneIndicatorsOverlay.java --- .../zoneIndicators/ZoneIndicatorsOverlay.java | 113 ------------------ 1 file changed, 113 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java 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/zoneIndicators/ZoneIndicatorsOverlay.java deleted file mode 100644 index 0f52222e8b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsOverlay.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.geom.GeneralPath; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.geometry.Geometry; -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; - -public class ZoneIndicatorsOverlay extends Overlay -{ - private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; - - @Inject - private Client client; - - @Inject - private ZoneIndicatorsPlugin plugin; - - @Inject - private ZoneIndicatorsConfig config; - - @Inject - public ZoneIndicatorsOverlay() - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - setPriority(OverlayPriority.LOW); - } - - private Color getTransparentColorVersion(Color c) - { - return new Color(c.getRed(), c.getGreen(), c.getBlue(), 92); - } - - private void renderPath(Graphics2D graphics, GeneralPath path, Color color) - { - LocalPoint playerLp = client.getLocalPlayer().getLocalLocation(); - Rectangle viewArea = new Rectangle( - playerLp.getX() - MAX_LOCAL_DRAW_LENGTH, - playerLp.getY() - MAX_LOCAL_DRAW_LENGTH, - MAX_LOCAL_DRAW_LENGTH * 2, - MAX_LOCAL_DRAW_LENGTH * 2); - - graphics.setColor(color); - graphics.setStroke(new BasicStroke(2)); - - path = Geometry.clipPath(path, viewArea); - path = Geometry.filterPath(path, (p1, p2) -> - Perspective.localToCanvas(client, new LocalPoint((int)p1[0], (int)p1[1]), client.getPlane()) != null && - Perspective.localToCanvas(client, new LocalPoint((int)p2[0], (int)p2[1]), client.getPlane()) != null); - path = Geometry.transformPath(path, coords -> - { - Point point = Perspective.localToCanvas(client, new LocalPoint((int)coords[0], (int)coords[1]), client.getPlane()); - coords[0] = point.getX(); - coords[1] = point.getY(); - }); - - graphics.draw(path); - } - - @Override - public Dimension render(Graphics2D graphics) - { - GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()]; - GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()]; - - if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null) - { - renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor())); - } - if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null) - { - renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor())); - } - - return null; - } -} \ No newline at end of file From 8b81946a9093b31173449034a8388f42f48528e0 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:36:19 +0100 Subject: [PATCH 48/75] Delete ZoneIndicatorsPlugin.java --- .../zoneIndicators/ZoneIndicatorsPlugin.java | 298 ------------------ 1 file changed, 298 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java 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/zoneIndicators/ZoneIndicatorsPlugin.java deleted file mode 100644 index b48ffa41e9..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneIndicatorsPlugin.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import java.awt.Rectangle; -import java.awt.geom.GeneralPath; -import java.util.Arrays; -import javax.inject.Inject; -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.Constants; -import net.runelite.api.GameState; -import net.runelite.api.ObjectComposition; -import net.runelite.api.Perspective; -import net.runelite.api.Tile; -import net.runelite.api.WallObject; -import net.runelite.api.WorldType; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldArea; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.geometry.Geometry; -import net.runelite.client.callback.ClientThread; -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; - -@PluginDescriptor( - name = "MultiLines", - description = "Show borders of multicombat and PvP safezones", - tags = {"multicombat", "lines", "pvp", "deadman", "safezones", "bogla"}, - type = "utility", - enabledByDefault = false -) -public class ZoneIndicatorsPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private ClientThread clientThread; - - @Inject - private ZoneIndicatorsConfig config; - - @Inject - private ZoneIndicatorsOverlay overlay; - - @Inject - private ZoneIndicatorsMinimapOverlay minimapOverlay; - - @Inject - private OverlayManager overlayManager; - - @Getter - private GeneralPath[] multicombatPathToDisplay; - - @Getter - private GeneralPath[] pvpPathToDisplay; - - @Getter - private boolean inPvp; - - @Getter - private boolean inDeadman; - - private int currentPlane; - - @Provides - ZoneIndicatorsConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(ZoneIndicatorsConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - overlayManager.add(minimapOverlay); - - multicombatPathToDisplay = new GeneralPath[Constants.MAX_Z]; - pvpPathToDisplay = new GeneralPath[Constants.MAX_Z]; - - clientThread.invokeLater(() -> - { - if (client.getGameState() == GameState.LOGGED_IN) - { - findLinesInScene(); - } - }); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - overlayManager.remove(minimapOverlay); - - multicombatPathToDisplay = null; - pvpPathToDisplay = null; - } - - private void transformWorldToLocal(float[] coords) - { - LocalPoint lp = LocalPoint.fromWorld(client, (int)coords[0], (int)coords[1]); - coords[0] = lp.getX() - Perspective.LOCAL_TILE_SIZE / 2; - coords[1] = lp.getY() - Perspective.LOCAL_TILE_SIZE / 2; - } - - private boolean isOpenableAt(WorldPoint wp) - { - int sceneX = wp.getX() - client.getBaseX(); - int sceneY = wp.getY() - client.getBaseY(); - - Tile tile = client.getScene().getTiles()[wp.getPlane()][sceneX][sceneY]; - if (tile == null) - { - return false; - } - - WallObject wallObject = tile.getWallObject(); - if (wallObject == null) - { - return false; - } - - ObjectComposition objectComposition = client.getObjectDefinition(wallObject.getId()); - if (objectComposition == null) - { - return false; - } - - String[] actions = objectComposition.getActions(); - if (actions == null) - { - return false; - } - - return Arrays.stream(actions).anyMatch(x -> x != null && x.toLowerCase().equals("open")); - } - - private boolean collisionFilter(float[] p1, float[] p2) - { - int x1 = (int)p1[0]; - int y1 = (int)p1[1]; - int x2 = (int)p2[0]; - int y2 = (int)p2[1]; - - if (x1 > x2) - { - int temp = x1; - x1 = x2; - x2 = temp; - } - if (y1 > y2) - { - int temp = y1; - y1 = y2; - y2 = temp; - } - int dx = x2 - x1; - int dy = y2 - y1; - WorldArea wa1 = new WorldArea(new WorldPoint( - x1, y1, currentPlane), 1, 1); - WorldArea wa2 = new WorldArea(new WorldPoint( - x1 - dy, y1 - dx, currentPlane), 1, 1); - - if (isOpenableAt(wa1.toWorldPoint()) || isOpenableAt(wa2.toWorldPoint())) - { - // When there's something with the open option (e.g. a door) on the tile, - // we assume it can be opened and walked through afterwards. Without this - // check, the line for that tile wouldn't render with collision detection - // because the collision check isn't done if collision data changes. - return true; - } - - boolean b1 = wa1.canTravelInDirection(client, -dy, -dx); - boolean b2 = wa2.canTravelInDirection(client, dy, dx); - return b1 && b2; - } - - private void findLinesInScene() - { - inDeadman = client.getWorldType().stream().anyMatch(x -> - x == WorldType.DEADMAN || x == WorldType.SEASONAL_DEADMAN); - inPvp = client.getWorldType().stream().anyMatch(x -> - x == WorldType.PVP || x == WorldType.PVP_HIGH_RISK); - - Rectangle sceneRect = new Rectangle( - client.getBaseX() + 1, client.getBaseY() + 1, - Constants.SCENE_SIZE - 2, Constants.SCENE_SIZE - 2); - - // Generate lines for multicombat zones - if (config.multicombatZoneVisibility() == ZoneVisibility.HIDE) - { - for (int i = 0; i < multicombatPathToDisplay.length; i++) - { - multicombatPathToDisplay[i] = null; - } - } - else - { - for (int i = 0; i < multicombatPathToDisplay.length; i++) - { - currentPlane = i; - - GeneralPath lines = new GeneralPath(MapLocations.getMulticombat(sceneRect, i)); - lines = Geometry.clipPath(lines, sceneRect); - if (config.multicombatZoneVisibility() == ZoneVisibility.SHOW_IN_PVP && - !isInDeadman() && !isInPvp()) - { - lines = Geometry.clipPath(lines, MapLocations.getRoughWilderness(i)); - } - lines = Geometry.splitIntoSegments(lines, 1); - if (config.collisionDetection()) - { - lines = Geometry.filterPath(lines, this::collisionFilter); - } - lines = Geometry.transformPath(lines, this::transformWorldToLocal); - multicombatPathToDisplay[i] = lines; - } - } - - // Generate safezone lines for deadman/pvp worlds - for (int i = 0; i < pvpPathToDisplay.length; i++) - { - currentPlane = i; - - GeneralPath safeZonePath = null; - if (config.showDeadmanSafeZones() && isInDeadman()) - { - safeZonePath = new GeneralPath(MapLocations.getDeadmanSafeZones(sceneRect, i)); - } - else if (config.showPvpSafeZones() && isInPvp()) - { - safeZonePath = new GeneralPath(MapLocations.getPvpSafeZones(sceneRect, i)); - } - if (safeZonePath != null) - { - safeZonePath = Geometry.clipPath(safeZonePath, sceneRect); - safeZonePath = Geometry.splitIntoSegments(safeZonePath, 1); - if (config.collisionDetection()) - { - safeZonePath = Geometry.filterPath(safeZonePath, this::collisionFilter); - } - safeZonePath = Geometry.transformPath(safeZonePath, this::transformWorldToLocal); - } - pvpPathToDisplay[i] = safeZonePath; - } - } - - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (event.getKey().equals("collisionDetection") || - event.getKey().equals("multicombatZoneVisibility") || - event.getKey().equals("deadmanSafeZones") || - event.getKey().equals("pvpSafeZones")) - { - findLinesInScene(); - } - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - { - findLinesInScene(); - } - } -} From 6444b004e4cf850d0305c236ab4a528d314fc1b2 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:36:25 +0100 Subject: [PATCH 49/75] Delete ZoneVisibility.java --- .../zoneIndicators/ZoneVisibility.java | 43 ------------------- 1 file changed, 43 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java 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/zoneIndicators/ZoneVisibility.java deleted file mode 100644 index 9a457d9e50..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoneIndicators/ZoneVisibility.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * 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.zoneIndicators; - -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public enum ZoneVisibility -{ - HIDE("Hide"), - SHOW_IN_PVP("Show in PvP"), - SHOW_EVERYWHERE("Show everywhere"); - - private final String visibility; - - @Override - public String toString() - { - return visibility; - } -} \ No newline at end of file From 2f7eb665551dcaeb459c5ab479cc94a2aba2376d Mon Sep 17 00:00:00 2001 From: James Munson Date: Sat, 20 Apr 2019 16:19:16 -0700 Subject: [PATCH 50/75] Removed outline from freezetimers --- .../freezetimers/FreezeTimersOverlay.java | 5 +-- .../freezetimers/FreezeTimersPlugin.java | 39 +++++++------------ 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java index a4816dcbad..5718c506d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersOverlay.java @@ -146,13 +146,12 @@ public class FreezeTimersOverlay extends Overlay Point imageLocation = new Point(textLocation.getX() - width, ((textLocation.getY() - graphics.getFontMetrics().getHeight()) + 10)); graphics.setFont(FontManager.getRunescapeFont()); - graphics.setStroke(new BasicStroke(3)); + // graphics.setStroke(new BasicStroke(3)); if (config.spellIcon()) { frozenoverlay = true; - graphics.drawOval(imageLocation.getX(), imageLocation.getY(), clanchatImage.getWidth(), - clanchatImage.getHeight()); + // graphics.drawOval(imageLocation.getX(), imageLocation.getY(), clanchatImage.getWidth(), clanchatImage.getHeight()); OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), color); 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 bdb5e3a7ff..5e0c7a7824 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 @@ -411,17 +411,14 @@ public class FreezeTimersPlugin extends Plugin } } - private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) - { - final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel(); - - final int width = bufferedImage.getWidth(); - final int height = bufferedImage.getHeight(); - final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); - final int[] palette = new int[indexedCM.getMapSize()]; + private static IndexedSprite createIndexedSprite(Client client, BufferedImage bufferedImage) { + IndexColorModel indexedCM = (IndexColorModel)bufferedImage.getColorModel(); + int width = bufferedImage.getWidth(); + int height = bufferedImage.getHeight(); + byte[] pixels = ((DataBufferByte)bufferedImage.getRaster().getDataBuffer()).getData(); + int[] palette = new int[indexedCM.getMapSize()]; indexedCM.getRGBs(palette); - - final IndexedSprite newIndexedSprite = client.createIndexedSprite(); + IndexedSprite newIndexedSprite = client.createIndexedSprite(); newIndexedSprite.setPixels(pixels); newIndexedSprite.setPalette(palette); newIndexedSprite.setWidth(width); @@ -433,20 +430,14 @@ public class FreezeTimersPlugin extends Plugin return newIndexedSprite; } - private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) - { - final BufferedImage indexedImage = new BufferedImage( - sourceBufferedImage.getWidth(), - sourceBufferedImage.getHeight(), - BufferedImage.TYPE_BYTE_INDEXED); - - final ColorModel cm = indexedImage.getColorModel(); - final IndexColorModel icm = (IndexColorModel) cm; - - final int size = icm.getMapSize(); - final byte[] reds = new byte[size]; - final byte[] greens = new byte[size]; - final byte[] blues = new byte[size]; + private static BufferedImage rgbaToIndexedBufferedImage(BufferedImage sourceBufferedImage) { + BufferedImage indexedImage = new BufferedImage(sourceBufferedImage.getWidth(), sourceBufferedImage.getHeight(), BufferedImage.TYPE_BYTE_INDEXED); + ColorModel cm = indexedImage.getColorModel(); + IndexColorModel icm = (IndexColorModel)cm; + int size = icm.getMapSize(); + byte[] reds = new byte[size]; + byte[] greens = new byte[size]; + byte[] blues = new byte[size]; icm.getReds(reds); icm.getGreens(greens); icm.getBlues(blues); From 5f07a0681ef903eb7356d6cc188b317efdae9dfe Mon Sep 17 00:00:00 2001 From: James Munson Date: Sat, 20 Apr 2019 19:02:04 -0700 Subject: [PATCH 51/75] Kitten notifer fix? Remove music indicator, removed nexthitnotifer(Repladed by Show Damage on XP Drop) --- .../kittennotifier/KittenNotifierPlugin.java | 2 +- .../musicindicator/MusicIndicatorPlugin.java | 204 ------------------ .../NextHitNotifierConfig.java | 11 - .../NextHitNotifierOverlay.java | 59 ----- .../NextHitNotifierPlugin.java | 117 ---------- 5 files changed, 1 insertion(+), 392 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java 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 45ef04e0d2..8af4de5513 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 @@ -56,7 +56,7 @@ public class KittenNotifierPlugin extends Plugin{ if (!config.catOwned()) { for (NPC npc : client.getNpcs()) { if (npc.getInteracting() != null) { - if (npc.getName().equals("Cat") && !config.catOwned()) { + if (npc.getName().equalsIgnoreCase("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/musicindicator/MusicIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java deleted file mode 100644 index 25584f3a88..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2019, Shaun Dreclin - * 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.musicindicator; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; -import javax.inject.Inject; -import net.runelite.api.ChatMessageType; -import net.runelite.api.Client; -import net.runelite.api.EnumComposition; -import net.runelite.api.EnumID; -import net.runelite.api.VarPlayer; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.VarbitChanged; -import net.runelite.client.chat.ChatColorType; -import net.runelite.client.chat.ChatMessageBuilder; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; - -@PluginDescriptor( - name = "Music Track Indicator", - description = "Show chat notifications when unlocking music tracks" -) -public class MusicIndicatorPlugin extends Plugin -{ - private static final List MUSIC_TRACK_VARPS = ImmutableList.of( - VarPlayer.MUSIC_TRACKS_UNLOCKED_1, VarPlayer.MUSIC_TRACKS_UNLOCKED_2, VarPlayer.MUSIC_TRACKS_UNLOCKED_3, - VarPlayer.MUSIC_TRACKS_UNLOCKED_4, VarPlayer.MUSIC_TRACKS_UNLOCKED_5, VarPlayer.MUSIC_TRACKS_UNLOCKED_6, - VarPlayer.MUSIC_TRACKS_UNLOCKED_7, VarPlayer.MUSIC_TRACKS_UNLOCKED_8, VarPlayer.MUSIC_TRACKS_UNLOCKED_9, - VarPlayer.MUSIC_TRACKS_UNLOCKED_10, VarPlayer.MUSIC_TRACKS_UNLOCKED_11, VarPlayer.MUSIC_TRACKS_UNLOCKED_12, - VarPlayer.MUSIC_TRACKS_UNLOCKED_13, VarPlayer.MUSIC_TRACKS_UNLOCKED_14, VarPlayer.MUSIC_TRACKS_UNLOCKED_15, - VarPlayer.MUSIC_TRACKS_UNLOCKED_16, VarPlayer.MUSIC_TRACKS_UNLOCKED_17, VarPlayer.MUSIC_TRACKS_UNLOCKED_18, - VarPlayer.MUSIC_TRACKS_UNLOCKED_19 - ); - - private static final Map VARP_INDEX_TO_VARPLAYER = MUSIC_TRACK_VARPS.stream() - .collect(Collectors.collectingAndThen(Collectors.toMap(VarPlayer::getId, Function.identity()), - ImmutableMap::copyOf)); - - @Inject - private Client client; - - @Inject - private ChatMessageManager chatMessageManager; - - // Mapping of relevant varps to their values, used to compare against new values - private final Map musicTrackVarpValues = new HashMap<>(); - - private boolean loggingIn; - - @Override - public void startUp() - { - loggingIn = true; - } - - @Override - public void shutDown() - { - musicTrackVarpValues.clear(); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - switch (event.getGameState()) - { - case LOGGING_IN: - case CONNECTION_LOST: - case HOPPING: - musicTrackVarpValues.clear(); - loggingIn = true; - } - } - - @Subscribe - public void onGameTick(GameTick event) - { - if (!loggingIn) - { - return; - } - - loggingIn = false; - - for (VarPlayer musicTrackVarp : MUSIC_TRACK_VARPS) - { - int value = client.getVar(musicTrackVarp); - musicTrackVarpValues.put(musicTrackVarp, value); - } - } - - @Subscribe - public void onVarbitChanged(VarbitChanged event) - { - int idx = event.getIndex(); - - VarPlayer varPlayer = VARP_INDEX_TO_VARPLAYER.get(idx); - if (varPlayer == null) - { - return; - } - - // Old varplayer values have not been initialized yet - if (musicTrackVarpValues.isEmpty()) - { - return; - } - - assert musicTrackVarpValues.containsKey(varPlayer); - - int newValue = client.getVar(varPlayer); - int oldValue = musicTrackVarpValues.put(varPlayer, newValue); - int musicTracksUnlocked = ~oldValue & newValue; - - if (musicTracksUnlocked == 0) - { - return; - } - - final EnumComposition names = client.getEnum(EnumID.MUSIC_TRACK_NAMES); - final int varpId = MUSIC_TRACK_VARPS.indexOf(varPlayer) + 1; - - for (int bit = 0; bit < Integer.SIZE; ++bit) - { - if ((musicTracksUnlocked & (1 << bit)) == 0) - { - continue; - } - - int musicTrackId = getTrackId(varpId, bit); - String musicTrackName = names.getStringValue(musicTrackId); - - sendChatMessage("You have unlocked a new music track: " + musicTrackName + "."); - } - } - - /** - * Get the id for a track identified by the given varp and a bit index - * @param variableId - * @param bit - * @return - */ - private int getTrackId(int variableId, int bit) - { - // values are packed into a coordgrid - int packed = (variableId << 14) | bit; - EnumComposition ids = client.getEnum(EnumID.MUSIC_TRACK_IDS); - for (int key : ids.getKeys()) - { - int value = ids.getIntValue(key); - if (value == packed) - { - return key; - } - } - return -1; - } - - private void sendChatMessage(String chatMessage) - { - final String message = new ChatMessageBuilder() - .append(ChatColorType.HIGHLIGHT) - .append(chatMessage) - .build(); - - chatMessageManager.queue( - QueuedMessage.builder() - .type(ChatMessageType.CONSOLE) - .runeLiteFormattedMessage(message) - .build()); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java deleted file mode 100644 index 8bce5b84b7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.runelite.client.plugins.nexthitnotifier; - - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; - -@ConfigGroup("nexthitnotifier") -public interface NextHitNotifierConfig extends Config -{ - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java deleted file mode 100644 index fe47f37307..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.runelite.client.plugins.nexthitnotifier; - -import net.runelite.api.Client; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.PanelComponent; -import net.runelite.client.ui.overlay.components.TitleComponent; -import net.runelite.client.util.MiscUtils; - -import javax.inject.Inject; -import java.awt.*; - -public class NextHitNotifierOverlay extends Overlay -{ - private final Client client; - private final NextHitNotifierPlugin plugin; - private final NextHitNotifierConfig config; - - private final PanelComponent panelComponent = new PanelComponent(); - private final Dimension panelSize = new Dimension(48, 0); - - @Inject - private NextHitNotifierOverlay(Client client, NextHitNotifierPlugin plugin, NextHitNotifierConfig config) - { - setPosition(OverlayPosition.BOTTOM_LEFT); - //setPosition(OverlayPosition.DYNAMIC); - //setPosition(OverlayPosition.DETACHED); - - this.client = client; - this.plugin = plugin; - this.config = config; - } - - @Override - public Dimension render(Graphics2D graphics) - { - panelComponent.getChildren().clear(); - panelComponent.setPreferredSize(panelSize); - - String lastHitText = Integer.toString(plugin.lastHit); - int lastHit = plugin.lastHit; - - if (plugin.showTime < 0) - { - lastHitText = "0"; - lastHit = 0; - } - - int g = (int)MiscUtils.clamp((float)Math.floor(lastHit / 30.f) * 255.f, 0.f, 255.f); - int r = 255 - g; - - Color textColor = Color.getHSBColor(Color.RGBtoHSB(r, g, 0, null)[0], 1.f, 1.f); - - panelComponent.getChildren().add(TitleComponent.builder().text("Next hit:").color(Color.YELLOW).build()); - panelComponent.getChildren().add(TitleComponent.builder().text(lastHitText).color(textColor).build()); - - return panelComponent.render(graphics); - } -} \ No newline at end of file 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 deleted file mode 100644 index ce6c1ca925..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java +++ /dev/null @@ -1,117 +0,0 @@ -package net.runelite.client.plugins.nexthitnotifier; - -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.Skill; -import net.runelite.api.events.ExperienceChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -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 javax.inject.Inject; - -@PluginDescriptor( - name = "Next Hit Notifier", - description = "Shows estimated next hit based on xp drop.", - tags = { "experience", "damage", "overlay", "pking", "bogla" }, - enabledByDefault = false, - type = "utility" -) -public class NextHitNotifierPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private NextHitNotifierOverlay overlay; - - private int lastHpXp = 0; - int lastHit = 0; - int showTime = 0; - - @Provides - NextHitNotifierConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(NextHitNotifierConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - { - lastHpXp = client.getSkillExperience(Skill.HITPOINTS); - lastHit = 0; - showTime = 0; - } - else - { - lastHpXp = 0; - lastHit = 0; - showTime = 0; - } - } - - @Subscribe - public void onGameTick(GameTick event) - { - if (showTime > 0) - showTime--; - else - lastHit = 0; - } - - @Subscribe - public void onExperienceChanged(ExperienceChanged event) - { - if (client.getGameState() != GameState.LOGGED_IN) - { - lastHpXp = 0; - lastHit = 0; - showTime = 0; - return; - } - - final Skill skill = event.getSkill(); - - if (skill != Skill.HITPOINTS) - return; - - final int currentXp = client.getSkillExperience(skill); - - int gainedXp = currentXp - lastHpXp; - - //filter out big xp drops (such as login) - if (gainedXp > 1000) - { - lastHpXp = client.getSkillExperience(skill); - return; - } - - lastHit = (int)Math.rint(gainedXp / 1.33f); - lastHpXp = currentXp; - showTime = 3; - } - - -} From e926fce1ce1a2bbfb7e885f673277f94d91d59b4 Mon Sep 17 00:00:00 2001 From: James Munson Date: Sat, 20 Apr 2019 19:23:59 -0700 Subject: [PATCH 52/75] removed fkeyremapping, broken --- .../fkeyremapping/fKeyRemappingConfig.java | 58 ----------- .../fkeyremapping/fKeyRemappingListener.java | 95 ------------------- .../fkeyremapping/fKeyRemappingPlugin.java | 84 ---------------- 3 files changed, 237 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingListener.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java 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 deleted file mode 100644 index cb66dc3e54..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingConfig.java +++ /dev/null @@ -1,58 +0,0 @@ -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 deleted file mode 100644 index 6b2ac82124..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingListener.java +++ /dev/null @@ -1,95 +0,0 @@ -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 deleted file mode 100644 index 4bee22c082..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java +++ /dev/null @@ -1,84 +0,0 @@ -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"}, - type = "utility", - 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; - } - - - - - - - -} From decdb652f216992d3d106e5a13e4c508c3c9ac1a Mon Sep 17 00:00:00 2001 From: James Munson Date: Sat, 20 Apr 2019 19:27:41 -0700 Subject: [PATCH 53/75] revert --- .../client/plugins/kittennotifier/KittenNotifierPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8af4de5513..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 @@ -56,7 +56,7 @@ public class KittenNotifierPlugin extends Plugin{ if (!config.catOwned()) { for (NPC npc : client.getNpcs()) { if (npc.getInteracting() != null) { - if (npc.getName().equalsIgnoreCase("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); From cf5fa63804e27f5c4935b353bef0f6cc7b1cba8d Mon Sep 17 00:00:00 2001 From: Ganom Date: Sat, 20 Apr 2019 22:50:43 -0400 Subject: [PATCH 54/75] Adding type to PlankMake --- .../client/plugins/plankmakehelper/PlankMakePlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java index 4c5a72001e..87c35c17b1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java @@ -10,7 +10,8 @@ import javax.inject.Inject; @PluginDescriptor( name = "Plank Make Helper", description = "Highlights planks and plank make spell", - tags = {"overlay", "plankmaking", "lunar", "money", "moneymaking", "gp"} + tags = {"overlay", "plankmaking", "lunar", "money", "moneymaking", "gp"}, + type = "utility" ) public class PlankMakePlugin extends Plugin { From f243494b4fd9e6e5849edcb284b1bcb9602dc541 Mon Sep 17 00:00:00 2001 From: Ganom Date: Sat, 20 Apr 2019 22:51:02 -0400 Subject: [PATCH 55/75] Adding type to PvpTools --- .../net/runelite/client/plugins/pvptools/PvpToolsPlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 index b36894ab54..47aee1f8b6 100644 --- 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 @@ -69,7 +69,8 @@ import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "PvP Tools", description = "Enable the PvP Tools panel", - tags = {"panel", "pvp", "pk", "pklite"} + tags = {"panel", "pvp", "pk", "pklite"}, + type = "PVP" ) public class PvpToolsPlugin extends Plugin { From 480168e843f0f46dca54662f7a800cc22aaee660 Mon Sep 17 00:00:00 2001 From: Ganom Date: Sat, 20 Apr 2019 22:52:36 -0400 Subject: [PATCH 56/75] Removing next hit notifier as its redundant --- .../NextHitNotifierConfig.java | 11 -- .../NextHitNotifierOverlay.java | 59 --------- .../NextHitNotifierPlugin.java | 117 ------------------ 3 files changed, 187 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java deleted file mode 100644 index 8bce5b84b7..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierConfig.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.runelite.client.plugins.nexthitnotifier; - - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; - -@ConfigGroup("nexthitnotifier") -public interface NextHitNotifierConfig extends Config -{ - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java deleted file mode 100644 index fe47f37307..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierOverlay.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.runelite.client.plugins.nexthitnotifier; - -import net.runelite.api.Client; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.PanelComponent; -import net.runelite.client.ui.overlay.components.TitleComponent; -import net.runelite.client.util.MiscUtils; - -import javax.inject.Inject; -import java.awt.*; - -public class NextHitNotifierOverlay extends Overlay -{ - private final Client client; - private final NextHitNotifierPlugin plugin; - private final NextHitNotifierConfig config; - - private final PanelComponent panelComponent = new PanelComponent(); - private final Dimension panelSize = new Dimension(48, 0); - - @Inject - private NextHitNotifierOverlay(Client client, NextHitNotifierPlugin plugin, NextHitNotifierConfig config) - { - setPosition(OverlayPosition.BOTTOM_LEFT); - //setPosition(OverlayPosition.DYNAMIC); - //setPosition(OverlayPosition.DETACHED); - - this.client = client; - this.plugin = plugin; - this.config = config; - } - - @Override - public Dimension render(Graphics2D graphics) - { - panelComponent.getChildren().clear(); - panelComponent.setPreferredSize(panelSize); - - String lastHitText = Integer.toString(plugin.lastHit); - int lastHit = plugin.lastHit; - - if (plugin.showTime < 0) - { - lastHitText = "0"; - lastHit = 0; - } - - int g = (int)MiscUtils.clamp((float)Math.floor(lastHit / 30.f) * 255.f, 0.f, 255.f); - int r = 255 - g; - - Color textColor = Color.getHSBColor(Color.RGBtoHSB(r, g, 0, null)[0], 1.f, 1.f); - - panelComponent.getChildren().add(TitleComponent.builder().text("Next hit:").color(Color.YELLOW).build()); - panelComponent.getChildren().add(TitleComponent.builder().text(lastHitText).color(textColor).build()); - - return panelComponent.render(graphics); - } -} \ No newline at end of file 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 deleted file mode 100644 index ce6c1ca925..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nexthitnotifier/NextHitNotifierPlugin.java +++ /dev/null @@ -1,117 +0,0 @@ -package net.runelite.client.plugins.nexthitnotifier; - -import net.runelite.client.eventbus.Subscribe; -import com.google.inject.Provides; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.Skill; -import net.runelite.api.events.ExperienceChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -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 javax.inject.Inject; - -@PluginDescriptor( - name = "Next Hit Notifier", - description = "Shows estimated next hit based on xp drop.", - tags = { "experience", "damage", "overlay", "pking", "bogla" }, - enabledByDefault = false, - type = "utility" -) -public class NextHitNotifierPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private NextHitNotifierOverlay overlay; - - private int lastHpXp = 0; - int lastHit = 0; - int showTime = 0; - - @Provides - NextHitNotifierConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(NextHitNotifierConfig.class); - } - - @Override - protected void startUp() throws Exception - { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() throws Exception - { - overlayManager.remove(overlay); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - { - lastHpXp = client.getSkillExperience(Skill.HITPOINTS); - lastHit = 0; - showTime = 0; - } - else - { - lastHpXp = 0; - lastHit = 0; - showTime = 0; - } - } - - @Subscribe - public void onGameTick(GameTick event) - { - if (showTime > 0) - showTime--; - else - lastHit = 0; - } - - @Subscribe - public void onExperienceChanged(ExperienceChanged event) - { - if (client.getGameState() != GameState.LOGGED_IN) - { - lastHpXp = 0; - lastHit = 0; - showTime = 0; - return; - } - - final Skill skill = event.getSkill(); - - if (skill != Skill.HITPOINTS) - return; - - final int currentXp = client.getSkillExperience(skill); - - int gainedXp = currentXp - lastHpXp; - - //filter out big xp drops (such as login) - if (gainedXp > 1000) - { - lastHpXp = client.getSkillExperience(skill); - return; - } - - lastHit = (int)Math.rint(gainedXp / 1.33f); - lastHpXp = currentXp; - showTime = 3; - } - - -} From 428b6dc4dd3bd22a4c5c0a9f1fb70f1a147e4dca Mon Sep 17 00:00:00 2001 From: Ganom Date: Sat, 20 Apr 2019 22:55:05 -0400 Subject: [PATCH 57/75] Fixing issue where you were locked in nylo room --- .../java/net/runelite/client/plugins/ztob/TheatrePlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3eb223c0c6..fe91da0930 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 @@ -301,7 +301,7 @@ public class TheatrePlugin extends Plugin { } } - if (pOptionToReplace.equals("CANCEL") || pOptionToReplace.equals("WALK HERE") || pOptionToReplace.equals("PASS")) { + if (!pOptionToReplace.equals("ATTACK")) { return; } int Id = 0; From 6a73c6f8e6cffccfba5fe8a288afc034479ec4c6 Mon Sep 17 00:00:00 2001 From: zeruth Date: Sun, 21 Apr 2019 00:16:50 -0400 Subject: [PATCH 58/75] ClientTransform Adds all protected menu transforms necessary for blackjacking! Eat shit upstream :) --- .../kittennotifier/KittenNotifierConfig.java | 6 - .../kittennotifier/KittenNotifierPlugin.java | 30 +- .../client/rs/bytecode/ByteCodePatcher.java | 291 +++++++++--------- .../transformers/ClientTransform.java | 194 ++++++++++++ 4 files changed, 359 insertions(+), 162 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java index e9d28f6b26..b4d567b16a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java @@ -18,10 +18,4 @@ public interface KittenNotifierConfig extends Config{ hidden = true ) default boolean catOwned() { return false; } - @ConfigItem( - keyName = "catOwned", - name = "", - description = "" - ) - void catOwned(Boolean bool); } 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 45ef04e0d2..584cbcde8c 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 @@ -2,6 +2,7 @@ package net.runelite.client.plugins.kittennotifier; import com.google.inject.Provides; import net.runelite.api.ChatMessageType; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcActionChanged; import net.runelite.api.events.NpcSpawned; import net.runelite.client.Notifier; @@ -20,6 +21,8 @@ import javax.inject.Inject; type = "utility" ) public class KittenNotifierPlugin extends Plugin{ + + public boolean catOwned = false; @Inject private Notifier notifier; @Inject @@ -51,36 +54,33 @@ public class KittenNotifierPlugin extends Plugin{ } } @Subscribe - public void onNpcActionChanged(NpcActionChanged event) { - if (event.getNpcComposition()!=null) + public void onGameTick(GameTick event) { if (!config.catOwned()) { for (NPC npc : client.getNpcs()) { - if (npc.getInteracting() != null) { - if (npc.getName().equals("Cat") && !config.catOwned()) { - // If this if statement is included in previous it could null. + if (npc.getInteracting()!=null) if (npc.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) { - config.catOwned(true); - notifier.notify("Your kitten has grown into a cat."); + if (npc.getName().equals("Cat") && !config.catOwned()) { + // If this if statement is included in previous it could null. + catOwned = true; + notifier.notify("Your kitten has grown into a cat."); } } } } - } } @Subscribe public void onNpcSpawned(NpcSpawned event) { NPC cat = event.getNpc(); - if (cat.getName() != null) { - if (cat.getName().equalsIgnoreCase("Kitten")) { - if (cat.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) { - config.catOwned(false); + if (cat.getInteracting()!=null) + if (cat.getInteracting().getName().equalsIgnoreCase(client.getLocalPlayer().getName())) { + if (cat.getName().contains("itten") && !config.catOwned()) { + catOwned = false; } } - else if (cat.getName().contentEquals("Cat")) { + else if (cat.getName().equals("Cat")) { if (cat.getInteracting().getName().equalsIgnoreCase(client.getLocalPlayer().getName())) { - config.catOwned(true); + catOwned = true; } } } - } } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java index b75a8c9631..1ab7c2da3e 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java @@ -8,22 +8,19 @@ import javassist.NotFoundException; import net.runelite.client.RuneLite; import net.runelite.client.rs.ClientLoader; import net.runelite.client.rs.bytecode.transformers.ActorTransform; +import net.runelite.client.rs.bytecode.transformers.ClientTransform; import net.runelite.client.rs.bytecode.transformers.PlayerTransform; import net.runelite.client.rs.bytecode.transformers.ProjectileTransform; import net.runelite.http.api.RuneLiteAPI; import org.xeustechnologies.jcl.JarClassLoader; import java.io.BufferedInputStream; -import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; @@ -33,154 +30,166 @@ import java.util.jar.JarInputStream; public class ByteCodePatcher { - public static List modifiedClasses = new ArrayList<>(); - public static Hooks hooks = new Hooks(); - public static String clientInstance; - public static JarClassLoader jcl = new JarClassLoader(); - public static ClassPool classPool = null; - public static ClassLoader cl = ClassLoader.getSystemClassLoader(); + public static List modifiedClasses = new ArrayList<>(); + public static Hooks hooks = new Hooks(); + public static String clientInstance; + public static JarClassLoader jcl = new JarClassLoader(); + public static ClassPool classPool = null; + public static ClassLoader cl = ClassLoader.getSystemClassLoader(); - public static void applyHooks(File jf, Hooks hooks) { - try { - URLClassLoader child = new URLClassLoader( - new URL[] {jf.toURI().toURL()}, - cl - ); - try { - Class actorClass = Class.forName(hooks.actorClass, false, child); - transformActor(actorClass); - Class projectileClass = Class.forName(hooks.projectileClass, false, child); - transformProjectile(projectileClass); - Class playerClass = Class.forName(hooks.playerClass, false, child); - transformPlayer(playerClass); - ByteCodeUtils.updateHijackedJar(); - } catch (Exception e) { - e.printStackTrace(); - } + public static void applyHooks(File jf, Hooks hooks) { + try { + URLClassLoader child = new URLClassLoader( + new URL[] {jf.toURI().toURL()}, + cl + ); + try { + Class actorClass = Class.forName(hooks.actorClass, false, child); + transformActor(actorClass); + Class projectileClass = Class.forName(hooks.projectileClass, false, child); + transformProjectile(projectileClass); + Class playerClass = Class.forName(hooks.playerClass, false, child); + transformPlayer(playerClass); - } catch (Exception e) { - e.printStackTrace(); - } - } + //experimental + Class clientClass = Class.forName("client", false, child); + transformBlackjack(clientClass); - public static void findHooks(String jf) { - try { - classPool = new ClassPool(true); - classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar"); - } catch (NotFoundException e) { - e.printStackTrace(); - } + ByteCodeUtils.updateHijackedJar(); + } catch (Exception e) { + e.printStackTrace(); + } - try { - jcl.add(new FileInputStream(jf)); - try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jf)))) { - JarEntry entry; - while ((entry = in.getNextJarEntry()) != null) { - if (entry.getName().endsWith(".class")) { - checkClasses(new File(jf), entry); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - try { - Writer writer = new FileWriter(ClientLoader.hooksFile); - gson.toJson(hooks, writer); - writer.flush(); - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } - ByteCodeUtils.updateHijackedJar(); - } + } catch (Exception e) { + e.printStackTrace(); + } + } - public static void checkClasses(File jf, JarEntry entry) { - try { - URLClassLoader child = new URLClassLoader( - new URL[] {jf.toURI().toURL()}, - cl - ); - try { - Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child); - checkActor(classToLoad); - checkProjectile(classToLoad); - checkPlayer(classToLoad); - } catch (Exception e) { - e.printStackTrace(); - } + public static void findHooks(String jf) { + try { + classPool = new ClassPool(true); + classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar"); + } catch (NotFoundException e) { + e.printStackTrace(); + } - } catch (Exception e) { - e.printStackTrace(); - System.out.println("Class not found: "+entry.getName()); - } - } + try { + jcl.add(new FileInputStream(jf)); + try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jf)))) { + JarEntry entry; + while ((entry = in.getNextJarEntry()) != null) { + if (entry.getName().endsWith(".class")) { + checkClasses(new File(jf), entry); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + try { + Writer writer = new FileWriter(ClientLoader.hooksFile); + gson.toJson(hooks, writer); + writer.flush(); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + ByteCodeUtils.updateHijackedJar(); + } - public static void checkActor(Class current) { - try { - Method method = current.getDeclaredMethod("setCombatInfo", new Class[] { int.class, int.class, int.class, int.class, int.class, int.class }); - if (method!=null) { - hooks.actorClass = current.getName(); - System.out.println("[RuneLit] Transforming Actor at class: "+current.getName()); - ActorTransform at = new ActorTransform(); - at.modify(current); - } - } catch (NoSuchMethodException e) { - //e.printStackTrace(); - } catch (NoClassDefFoundError e) { - //e.printStackTrace(); - } - } + public static void checkClasses(File jf, JarEntry entry) { + try { + URLClassLoader child = new URLClassLoader( + new URL[] {jf.toURI().toURL()}, + cl + ); + try { + Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child); + checkActor(classToLoad); + checkProjectile(classToLoad); + checkPlayer(classToLoad); + } catch (Exception e) { + e.printStackTrace(); + } - public static void transformActor(Class actor) { - System.out.println("[RuneLit] Transforming Actor at class: "+actor.getName()); - ActorTransform at = new ActorTransform(); - at.modify(actor); - } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Class not found: "+entry.getName()); + } + } - public static void checkProjectile(Class current) { - try { - Method method = current.getDeclaredMethod("projectileMoved", new Class[] { int.class, int.class, int.class, int.class}); - if (method!=null) { - hooks.projectileClass = current.getName(); - System.out.println("[RuneLit] Transforming Projectile at class: "+current.getName()); - ProjectileTransform pt = new ProjectileTransform(); - pt.modify(current); - } - } catch (NoSuchMethodException e) { - //e.printStackTrace(); - } catch (NoClassDefFoundError e) { - //e.printStackTrace(); - } - } + public static void checkActor(Class current) { + try { + Method method = current.getDeclaredMethod("setCombatInfo", new Class[] { int.class, int.class, int.class, int.class, int.class, int.class }); + if (method!=null) { + hooks.actorClass = current.getName(); + System.out.println("[RuneLit] Transforming Actor at class: "+current.getName()); + ActorTransform at = new ActorTransform(); + at.modify(current); + } + } catch (NoSuchMethodException e) { + //e.printStackTrace(); + } catch (NoClassDefFoundError e) { + //e.printStackTrace(); + } + } - public static void transformProjectile(Class projectile) { - System.out.println("[RuneLit] Transforming Projectile at class: "+projectile.getName()); - ProjectileTransform pt = new ProjectileTransform(); - pt.modify(projectile); - } + public static void transformActor(Class actor) { + System.out.println("[RuneLit] Transforming Actor at class: "+actor.getName()); + ActorTransform at = new ActorTransform(); + at.modify(actor); + } - public static void checkPlayer(Class current) { - try { - Method method = current.getDeclaredMethod("getSkullIcon"); - if (method!=null) { - hooks.playerClass = current.getName(); - System.out.println("[RuneLit] Transforming Player at class: "+current.getName()); - PlayerTransform pt = new PlayerTransform(); - pt.modify(current); - } - } catch (NoSuchMethodException e) { - //e.printStackTrace(); - } catch (NoClassDefFoundError e) { - //e.printStackTrace(); - } - } + public static void checkProjectile(Class current) { + try { + Method method = current.getDeclaredMethod("projectileMoved", new Class[] { int.class, int.class, int.class, int.class}); + if (method!=null) { + hooks.projectileClass = current.getName(); + System.out.println("[RuneLit] Transforming Projectile at class: "+current.getName()); + ProjectileTransform pt = new ProjectileTransform(); + pt.modify(current); + } + } catch (NoSuchMethodException e) { + //e.printStackTrace(); + } catch (NoClassDefFoundError e) { + //e.printStackTrace(); + } + } + + public static void transformProjectile(Class projectile) { + System.out.println("[RuneLit] Transforming Projectile at class: "+projectile.getName()); + ProjectileTransform pt = new ProjectileTransform(); + pt.modify(projectile); + } + + public static void checkPlayer(Class current) { + try { + Method method = current.getDeclaredMethod("getSkullIcon"); + if (method!=null) { + hooks.playerClass = current.getName(); + System.out.println("[RuneLit] Transforming Player at class: "+current.getName()); + PlayerTransform pt = new PlayerTransform(); + pt.modify(current); + } + } catch (NoSuchMethodException e) { + //e.printStackTrace(); + } catch (NoClassDefFoundError e) { + //e.printStackTrace(); + } + } + + public static void transformPlayer(Class player) { + System.out.println("[RuneLit] Transforming Player at class: "+player.getName()); + PlayerTransform pt = new PlayerTransform(); + pt.modify(player); + } + + public static void transformBlackjack(Class clazz) { + System.out.println("[RuneLit] Transforming Blackjack at class: "+clazz.getName()); + ClientTransform bt = new ClientTransform(); + bt.modify(clazz); + } - public static void transformPlayer(Class player) { - System.out.println("[RuneLit] Transforming Player at class: "+player.getName()); - PlayerTransform pt = new PlayerTransform(); - pt.modify(player); - } } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java new file mode 100644 index 0000000000..3d0600ba3f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java @@ -0,0 +1,194 @@ +package net.runelite.client.rs.bytecode.transformers; + +import javassist.CtBehavior; +import javassist.CtClass; +import javassist.CtMember; +import javassist.CtMethod; +import javassist.CtNewMethod; +import javassist.bytecode.StackMapTable; +import net.runelite.client.rs.bytecode.ByteCodePatcher; + +public class ClientTransform implements Transform { + + public CtClass ct = null; + + @Override + public void modify(Class clazz) { + try { + ct = ByteCodePatcher.classPool.get(clazz.getName()); + transformProtectedGetMenuOptions(); + transformProtectedGetMenuTargets(); + transformProtectedGetMenuIdentifiers(); + transformProtectedGetMenuTypes(); + transformProtectedGetMenuActionParams0(); + transformProtectedGetMenuActionParams1(); + transformGetMenuEntries(); + transformSetMenuEntries(); + transformOnMenuOptionsChanged(); + + ByteCodePatcher.modifiedClasses.add(ct); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void transformProtectedGetMenuOptions() { + CtMethod protectedGetMenuOptions; + try { + protectedGetMenuOptions = ct.getDeclaredMethod("1protect$getMenuOptions"); + ct.removeMethod(protectedGetMenuOptions); + protectedGetMenuOptions.setName("getMenuOptions"); + ct.addMethod(protectedGetMenuOptions); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void transformProtectedGetMenuTargets() { + CtMethod protectedGetMenuTargets; + try { + protectedGetMenuTargets = ct.getDeclaredMethod("1protect$getMenuTargets"); + ct.removeMethod(protectedGetMenuTargets); + protectedGetMenuTargets.setName("getMenuTargets"); + ct.addMethod(protectedGetMenuTargets); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void transformProtectedGetMenuIdentifiers() { + CtMethod protectedGetMenuIdentifiers; + try { + protectedGetMenuIdentifiers = ct.getDeclaredMethod("1protect$getMenuIdentifiers"); + ct.removeMethod(protectedGetMenuIdentifiers); + protectedGetMenuIdentifiers.setName("getMenuIdentifiers"); + ct.addMethod(protectedGetMenuIdentifiers); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void transformProtectedGetMenuTypes() { + CtMethod protectedGetMenuTypes; + try { + protectedGetMenuTypes = ct.getDeclaredMethod("1protect$getMenuTypes"); + // Don't remove as this is referenced elsewhere in client + //ct.removeMethod(protectedGetMenuTypes); + CtMethod newProtectedGetMenuTypes = CtNewMethod.copy(protectedGetMenuTypes, ct, null); + newProtectedGetMenuTypes.setName("getMenuTypes"); + ct.addMethod(newProtectedGetMenuTypes); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void transformProtectedGetMenuActionParams0() { + CtMethod protectedGetMenuActionParams0; + try { + protectedGetMenuActionParams0 = ct.getDeclaredMethod("1protect$getMenuActionParams0"); + ct.removeMethod(protectedGetMenuActionParams0); + protectedGetMenuActionParams0.setName("getMenuActionParams0"); + ct.addMethod(protectedGetMenuActionParams0); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void transformProtectedGetMenuActionParams1() { + CtMethod protectedGetMenuActionParams1; + try { + protectedGetMenuActionParams1 = ct.getDeclaredMethod("1protect$getMenuActionParams1"); + ct.removeMethod(protectedGetMenuActionParams1); + protectedGetMenuActionParams1.setName("getMenuActionParams1"); + ct.addMethod(protectedGetMenuActionParams1); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void transform() {} + + public void transformGetMenuEntries() { + CtMethod getMenuEntries; + try { + getMenuEntries = ct.getDeclaredMethod("getMenuEntries"); + ct.removeMethod(getMenuEntries); + getMenuEntries = CtMethod.make("public net.runelite.api.MenuEntry[] getMenuEntries() {" + + " int n2 = this.getMenuOptionCount();"+ + " String[] arrstring = this.getMenuOptions();"+ + " String[] arrstring2 = this.getMenuTargets();"+ + " int[] arrn = this.getMenuIdentifiers();"+ + " int[] arrn2 = this.getMenuTypes();"+ + " int[] arrn3 = this.getMenuActionParams0();"+ + " int[] arrn4 = this.getMenuActionParams1();"+ + " boolean[] arrbl = this.getMenuForceLeftClick();"+ + " net.runelite.api.MenuEntry[] arrmenuEntry = new net.runelite.api.MenuEntry[n2];"+ + " int n3 = 0;"+ + " while (n3 < n2) {"+ + " net.runelite.api.MenuEntry menuEntry = arrmenuEntry[n3] = new net.runelite.api.MenuEntry();"+ + " menuEntry.setOption(arrstring[n3]);"+ + " menuEntry.setTarget(arrstring2[n3]);"+ + " menuEntry.setIdentifier(arrn[n3]);"+ + " menuEntry.setType(arrn2[n3]);"+ + " menuEntry.setParam0(arrn3[n3]);"+ + " menuEntry.setParam1(arrn4[n3]);"+ + " menuEntry.setForceLeftClick(arrbl[n3]);"+ + " ++n3;"+ + " }"+ + " return arrmenuEntry;"+ + " }", ct); + ct.addMethod(getMenuEntries); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void transformSetMenuEntries() { + CtMethod setMenuEntries; + try { + setMenuEntries = ct.getDeclaredMethods("setMenuEntries"/*, works for now */)[0]; + ct.removeMethod(setMenuEntries); + String src; + setMenuEntries = CtNewMethod.make( + "public void setMenuEntries(net.runelite.api.MenuEntry[] paramArrayOfMenuEntry) {" + + "int i = 0;" + + "String[] arrayOfString1 = this.getMenuOptions();" + + "String[] arrayOfString2 = this.getMenuTargets();" + + "int[] arrayOfInt1 = this.getMenuIdentifiers();" + + "int[] arrayOfInt2 = this.getMenuTypes();" + + "int[] arrayOfInt3 = this.getMenuActionParams0();" + + "int[] arrayOfInt4 = this.getMenuActionParams1();" + + "boolean[] arrayOfBoolean = getMenuForceLeftClick();" + + "int testingInt[] = {1,2,3,4,5,6};" + + "for (int m = 0 ; m < paramArrayOfMenuEntry.length ; m++) {" + + "net.runelite.api.MenuEntry menuEntry = paramArrayOfMenuEntry[m];" + + "}" + + "}" + , ct); + ct.addMethod(setMenuEntries); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void transformOnMenuOptionsChanged() { + CtMethod onMenuOptionsChanged; + try { + onMenuOptionsChanged = ct.getDeclaredMethod("onMenuOptionsChanged", new CtClass[]{CtClass.intType}); + ct.removeMethod(onMenuOptionsChanged); + onMenuOptionsChanged = CtMethod.make(" public static void onMenuOptionsChanged(int n2) {"+ + " int n3;" + + " int n4 = oldMenuEntryCount;"+ + " oldMenuEntryCount = n3 = "+ByteCodePatcher.clientInstance+".getMenuOptionCount();"+ + " if (n3 != n4 + 1) return;"+ + " net.runelite.api.events.MenuEntryAdded menuEntryAdded = new net.runelite.api.events.MenuEntryAdded("+ByteCodePatcher.clientInstance+".getMenuOptions()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuTargets()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuTypes()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuIdentifiers()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuActionParams0()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuActionParams1()[n3 - 1]);"+ + " "+ByteCodePatcher.clientInstance+".getCallbacks().post((Object)menuEntryAdded);" + + " }" + , ct); + ct.addMethod(onMenuOptionsChanged); + } catch (Exception e) { + e.printStackTrace(); + } + } +} From a99efc343db2e81658ae5a81716a9b90e6cfb256 Mon Sep 17 00:00:00 2001 From: zeruth Date: Sun, 21 Apr 2019 00:52:06 -0400 Subject: [PATCH 59/75] Update ClientTransform.java Finished setMenuEntries, "Whoops" --- .../transformers/ClientTransform.java | 87 ++++++++++++++++--- 1 file changed, 73 insertions(+), 14 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java index 3d0600ba3f..2d1408fc65 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java @@ -147,24 +147,45 @@ public class ClientTransform implements Transform { public void transformSetMenuEntries() { CtMethod setMenuEntries; try { - setMenuEntries = ct.getDeclaredMethods("setMenuEntries"/*, works for now */)[0]; + setMenuEntries = ct.getDeclaredMethod("setMenuEntries"); ct.removeMethod(setMenuEntries); String src; setMenuEntries = CtNewMethod.make( - "public void setMenuEntries(net.runelite.api.MenuEntry[] paramArrayOfMenuEntry) {" + - "int i = 0;" + - "String[] arrayOfString1 = this.getMenuOptions();" + - "String[] arrayOfString2 = this.getMenuTargets();" + - "int[] arrayOfInt1 = this.getMenuIdentifiers();" + - "int[] arrayOfInt2 = this.getMenuTypes();" + - "int[] arrayOfInt3 = this.getMenuActionParams0();" + - "int[] arrayOfInt4 = this.getMenuActionParams1();" + - "boolean[] arrayOfBoolean = getMenuForceLeftClick();" + - "int testingInt[] = {1,2,3,4,5,6};" + - "for (int m = 0 ; m < paramArrayOfMenuEntry.length ; m++) {" + - "net.runelite.api.MenuEntry menuEntry = paramArrayOfMenuEntry[m];" + + "public void setMenuEntries(net.runelite.api.MenuEntry[] arrmenuEntry) {" + + "int n2 = 0;" + + "String[] arrstring = this.getMenuOptions();" + + "String[] arrstring2 = this.getMenuTargets();" + + "int[] arrn = this.getMenuIdentifiers();" + + "int[] arrn2 = this.getMenuTypes();" + + "int[] arrn3 = this.getMenuActionParams0();" + + "int[] arrn4 = this.getMenuActionParams1();" + + "boolean[] arrbl = getMenuForceLeftClick();" + + "net.runelite.api.MenuEntry[] arrmenuEntry2 = arrmenuEntry;" + + "int n3 = arrmenuEntry2.length;" + + "int n4 = 0;" + + "do {" + + "String string;" + + "if (n4 >= n3) {" + + "this.setMenuOptionCount(n2);" + + "oldMenuEntryCount = n2;" + + "return;" + "}" + - "}" + "net.runelite.api.MenuEntry menuEntry = arrmenuEntry2[n4];" + + "int n5 = menuEntry.getType();" + + "if (!(n5 != net.runelite.api.MenuAction.NPC_THIRD_OPTION.getId() && n5 != net.runelite.api.MenuAction.NPC_FIFTH_OPTION.getId() || n2 != arrmenuEntry.length - 1 || "+ByteCodePatcher.clientInstance+".getLocalPlayer().getWorldLocation().getRegionID() != 13358 || (string = menuEntry.getOption().toLowerCase()).hashCode() != 974723797 && string.hashCode() != -1108625161)) {" + + "n5 = net.runelite.api.MenuAction.CANCEL.getId();" + + "}" + + "arrstring[n2] = menuEntry.getOption();" + + "arrstring2[n2] = menuEntry.getTarget();" + + "arrn[n2] = menuEntry.getIdentifier();" + + "arrn2[n2] = n5;" + + "arrn3[n2] = menuEntry.getParam0();" + + "arrn4[n2] = menuEntry.getParam1();" + + "arrbl[n2] = menuEntry.isForceLeftClick();" + + "++n2;" + + "++n4;" + + "} while (true);" + + "}" , ct); ct.addMethod(setMenuEntries); } catch (Exception e) { @@ -172,6 +193,44 @@ public class ClientTransform implements Transform { } } + /* + public void setMenuEntries(MenuEntry[] arrmenuEntry) { + int n2 = 0; + String[] arrstring = this.1protect$getMenuOptions(); + String[] arrstring2 = this.1protect$getMenuTargets(); + int[] arrn = this.1protect$getMenuIdentifiers(); + int[] arrn2 = this.1protect$getMenuTypes(); + int[] arrn3 = this.1protect$getMenuActionParams0(); + int[] arrn4 = this.1protect$getMenuActionParams1(); + boolean[] arrbl = this.getMenuForceLeftClick(); + MenuEntry[] arrmenuEntry2 = arrmenuEntry; + int n3 = arrmenuEntry2.length; + int n4 = 0; + do { + String string; + if (n4 >= n3) { + this.setMenuOptionCount(n2); + oldMenuEntryCount = n2; + return; + } + MenuEntry menuEntry = arrmenuEntry2[n4]; + int n5 = menuEntry.getType(); + if (!(n5 != MenuAction.NPC_THIRD_OPTION.getId() && n5 != MenuAction.NPC_FIFTH_OPTION.getId() || n2 != arrmenuEntry.length - 1 || bv.ak.getLocalPlayer().getWorldLocation().getRegionID() != 13358 || (string = menuEntry.getOption().toLowerCase()).hashCode() != 974723797 && string.hashCode() != -1108625161)) { + n5 = MenuAction.CANCEL.getId(); + } + arrstring[n2] = menuEntry.getOption(); + arrstring2[n2] = menuEntry.getTarget(); + arrn[n2] = menuEntry.getIdentifier(); + arrn2[n2] = n5; + arrn3[n2] = menuEntry.getParam0(); + arrn4[n2] = menuEntry.getParam1(); + arrbl[n2] = menuEntry.isForceLeftClick(); + ++n2; + ++n4; + } while (true); +} + */ + public void transformOnMenuOptionsChanged() { CtMethod onMenuOptionsChanged; try { From 776734c51c55cec65df41a8b0ff1c7a32934ea55 Mon Sep 17 00:00:00 2001 From: zeruth Date: Sun, 21 Apr 2019 00:56:14 -0400 Subject: [PATCH 60/75] Update ClientTransform.java Lol, how many more times --- .../client/rs/bytecode/transformers/ClientTransform.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java index 2d1408fc65..983466e3fc 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java @@ -172,9 +172,6 @@ public class ClientTransform implements Transform { "}" + "net.runelite.api.MenuEntry menuEntry = arrmenuEntry2[n4];" + "int n5 = menuEntry.getType();" + - "if (!(n5 != net.runelite.api.MenuAction.NPC_THIRD_OPTION.getId() && n5 != net.runelite.api.MenuAction.NPC_FIFTH_OPTION.getId() || n2 != arrmenuEntry.length - 1 || "+ByteCodePatcher.clientInstance+".getLocalPlayer().getWorldLocation().getRegionID() != 13358 || (string = menuEntry.getOption().toLowerCase()).hashCode() != 974723797 && string.hashCode() != -1108625161)) {" + - "n5 = net.runelite.api.MenuAction.CANCEL.getId();" + - "}" + "arrstring[n2] = menuEntry.getOption();" + "arrstring2[n2] = menuEntry.getTarget();" + "arrn[n2] = menuEntry.getIdentifier();" + From 2a7625f240851e34a9dffa99b7f7951e47044fb1 Mon Sep 17 00:00:00 2001 From: James <38226001+james-munson@users.noreply.github.com> Date: Sat, 20 Apr 2019 23:41:48 -0700 Subject: [PATCH 61/75] Adds splash screen (#29) * clock manager: wrap panel to run on swing thread * Add splash screen to Runelite Although RuneLite is still fast at loading, it's more user friendly for at least something to pop up before the client. There is also an option (-no-splash) to disable the splash screen. This uses psikoi's design. * splash screen/client ui: don't set up theme twice Setting up the look and feel of RuneLite shouldn't happen twice, so check to see if it has already been set up before setting up the look and feel. --- .../java/net/runelite/client/RuneLite.java | 22 +- .../timetracking/clocks/ClockManager.java | 17 +- .../java/net/runelite/client/ui/ClientUI.java | 10 +- .../client/ui/RuneLiteSplashScreen.java | 213 ++++++++++++++++++ .../net/runelite/client/util/SwingUtil.java | 35 +++ .../main/resources/runelite_transparent.png | Bin 0 -> 19182 bytes .../src/main/resources/runeliteplus.png | Bin 0 -> 25982 bytes .../resources/runeliteplus_transparent.png | Bin 0 -> 23294 bytes 8 files changed, 286 insertions(+), 11 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java create mode 100644 runelite-client/src/main/resources/runelite_transparent.png create mode 100644 runelite-client/src/main/resources/runeliteplus.png create mode 100644 runelite-client/src/main/resources/runeliteplus_transparent.png diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 74594a8ed4..71aad5f534 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -61,6 +61,7 @@ import net.runelite.client.plugins.PluginManager; import net.runelite.client.rs.ClientUpdateCheckMode; import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.DrawManager; +import net.runelite.client.ui.RuneLiteSplashScreen; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayRenderer; import net.runelite.client.ui.overlay.WidgetOverlay; @@ -79,8 +80,10 @@ public class RuneLite public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles"); public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins"); public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots"); + private static final RuneLiteSplashScreen splashScreen = new RuneLiteSplashScreen(); - @Getter + + @Getter private static Injector injector; @Inject @@ -160,6 +163,7 @@ public class RuneLite final OptionParser parser = new OptionParser(); parser.accepts("developer-mode", "Enable developer tools"); parser.accepts("debug", "Show extra debugging output"); + parser.accepts("no-splash", "Do not show the splash screen"); final ArgumentAcceptingOptionSpec updateMode = parser .accepts("rs", "Select client type") @@ -213,6 +217,14 @@ public class RuneLite } }); + if (!options.has("no-splash")) + { + splashScreen.open(4); + } + + // The submessage is shown in case the connection is slow + splashScreen.setMessage("Loading client", "And checking for updates..."); + final long start = System.currentTimeMillis(); injector = Guice.createInjector(new RuneLiteModule( @@ -239,6 +251,7 @@ public class RuneLite } // Load user configuration + splashScreen.setMessage("Loading configuration"); configManager.load(); // Load the session, including saved configuration @@ -252,6 +265,7 @@ public class RuneLite // Load the plugins, but does not start them yet. // This will initialize configuration + splashScreen.setMessage("Loading plugins and patches", "Starting session..."); pluginManager.loadCorePlugins(); // Plugins have provided their config, so set default config @@ -261,9 +275,15 @@ public class RuneLite // Start client session clientSessionManager.start(); + // Load the session, including saved configuration + splashScreen.setMessage("Loading interface"); + // Initialize UI clientUI.open(this); + // Close the splash screen + splashScreen.close(); + // Initialize Discord service discordService.init(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java index 42686dae70..3be9dc053b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.timetracking.clocks; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.google.inject.Singleton; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -34,11 +35,13 @@ import javax.inject.Inject; import javax.swing.SwingUtilities; import joptsimple.internal.Strings; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; import net.runelite.client.plugins.timetracking.TimeTrackingConfig; @Singleton +@Slf4j public class ClockManager { @Inject @@ -57,7 +60,19 @@ public class ClockManager private final List stopwatches = new ArrayList<>(); @Getter - private ClockTabPanel clockTabPanel = new ClockTabPanel(this); + private ClockTabPanel clockTabPanel; + + ClockManager() + { + try + { + SwingUtilities.invokeAndWait(() -> clockTabPanel = new ClockTabPanel(this)); + } + catch (InterruptedException | InvocationTargetException e) + { + log.error("Error constructing ClockManager", e); + } + } void addTimer() { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 96ba6c31e6..4722b0027e 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -83,7 +83,6 @@ import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseAdapter; import net.runelite.client.input.MouseListener; import net.runelite.client.input.MouseManager; -import net.runelite.client.ui.skin.SubstanceRuneLiteLookAndFeel; import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.OSType; @@ -300,14 +299,7 @@ public class ClientUI { SwingUtilities.invokeAndWait(() -> { - // Set some sensible swing defaults - SwingUtil.setupDefaults(); - - // Use substance look and feel - SwingUtil.setTheme(new SubstanceRuneLiteLookAndFeel()); - - // Use custom UI font - SwingUtil.setFont(FontManager.getRunescapeFont()); + SwingUtil.setupRuneLiteLookAndFeel(); // Create main window frame = new ContainableFrame(); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java b/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java new file mode 100644 index 0000000000..925238d58e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2016-2017, Jeremy Plsek + * 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.ui; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Image; +import java.awt.Insets; +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.inject.Singleton; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.SwingUtilities; +import lombok.extern.slf4j.Slf4j; +import net.runelite.client.RuneLiteProperties; +import net.runelite.client.util.SwingUtil; +import org.pushingpixels.substance.internal.SubstanceSynapse; + +/** + * This is a custom Splash Screen and does not use Java's SplashScreen class. This has helper methods to update the + * status while loading RuneLite. All public methods run non-blocking passed to the swing thread. + */ +@Slf4j +@Singleton +public class RuneLiteSplashScreen +{ + private RuneLiteProperties runeLiteProperties = new RuneLiteProperties(); + + private JFrame frame; + private JLabel messageLabel; + private JLabel subMessageLabel; + private JProgressBar progressBar; + + private int currentStep; + + /** + * This is not done in the constructor in order to avoid processing in case the user chooses to not load + * the splash screen. + * @param estimatedSteps steps until completion, used for the progress bar + */ + private void initLayout(final int estimatedSteps) + { + SwingUtil.setupRuneLiteLookAndFeel(); + + // init fields with updated swing look and feel + frame = new JFrame("RuneLitePlus Loading"); + messageLabel = new JLabel("Loading..."); + subMessageLabel = new JLabel(); + progressBar = new JProgressBar(0, estimatedSteps); + + // frame setup + frame.setSize(220, 290); + frame.setLocationRelativeTo(null); + frame.setUndecorated(true); + + // main panel setup + final JPanel panel = new JPanel(); + // To reduce substance's colorization (tinting) + panel.putClientProperty(SubstanceSynapse.COLORIZATION_FACTOR, 1.0); + panel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + final GridBagLayout layout = new GridBagLayout(); + layout.columnWeights = new double[]{1}; + layout.rowWeights = new double[]{1, 0, 0, 1, 0, 1}; + panel.setLayout(layout); + + // logo + synchronized (ImageIO.class) + { + try + { + final BufferedImage logo = ImageIO.read(RuneLiteSplashScreen.class.getResourceAsStream("/runeliteplus.png")); + frame.setIconImage(logo); + + final BufferedImage logoTransparent = ImageIO.read(RuneLiteSplashScreen.class.getResourceAsStream("/runeliteplus_transparent.png")); + final GridBagConstraints logoConstraints = new GridBagConstraints(); + logoConstraints.anchor = GridBagConstraints.SOUTH; + panel.add(new JLabel(new ImageIcon(logoTransparent.getScaledInstance(96, 96, Image.SCALE_SMOOTH))), logoConstraints); + } + catch (IOException e) + { + log.warn("Error loading logo", e); + } + } + + // runelite title + final JLabel title = new JLabel("RuneLitePlus"); + final GridBagConstraints titleConstraints = new GridBagConstraints(); + titleConstraints.gridy = 1; + panel.add(title, titleConstraints); + + // version + final JLabel version = new JLabel("Version " + runeLiteProperties.getVersion()); + version.setFont(FontManager.getRunescapeSmallFont()); + version.setForeground(version.getForeground().darker()); + final GridBagConstraints versionConstraints = new GridBagConstraints(); + versionConstraints.gridy = 2; + panel.add(version, versionConstraints); + + // progressbar + final GridBagConstraints progressConstraints = new GridBagConstraints(); + progressConstraints.insets = new Insets(0, 30, 5, 30); + progressConstraints.fill = GridBagConstraints.HORIZONTAL; + progressConstraints.anchor = GridBagConstraints.SOUTH; + progressConstraints.gridy = 3; + panel.add(progressBar, progressConstraints); + + // main message + messageLabel.setFont(FontManager.getRunescapeSmallFont()); + final GridBagConstraints messageConstraints = new GridBagConstraints(); + messageConstraints.gridy = 4; + panel.add(messageLabel, messageConstraints); + + // alternate message + subMessageLabel.setForeground(subMessageLabel.getForeground().darker()); + subMessageLabel.setFont(FontManager.getRunescapeSmallFont()); + final GridBagConstraints altConstrains = new GridBagConstraints(); + altConstrains.anchor = GridBagConstraints.NORTH; + altConstrains.gridy = 5; + panel.add(subMessageLabel, altConstrains); + + frame.setContentPane(panel); + } + + private boolean notActive() + { + return frame == null || !frame.isDisplayable(); + } + + /** + * Close/dispose of the splash screen + */ + public void close() + { + SwingUtilities.invokeLater(() -> + { + if (notActive()) + { + return; + } + + frame.dispose(); + }); + } + + /** + * Set the splash screen to be visible. + * @param estimatedSteps steps until completion, used for the progress bar + */ + public void open(final int estimatedSteps) + { + SwingUtilities.invokeLater(() -> + { + initLayout(estimatedSteps); + frame.setVisible(true); + }); + } + + /** + * Set a loading message. The subMessage will also be removed. + * @param message The main message. It will automatically append an ellipsis. + */ + public void setMessage(final String message) + { + setMessage(message, " "); + } + + /** + * Set a loading message. + * @param message The main message. It will automatically append an ellipsis. + * @param subMessage A separate alternate title. + */ + public void setMessage(final String message, final String subMessage) + { + SwingUtilities.invokeLater(() -> + { + if (notActive()) + { + return; + } + + messageLabel.setText(message + "..."); + subMessageLabel.setText(subMessage); + progressBar.setValue(++currentStep); + }); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java b/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java index 39fc738f1f..e8aaef79a6 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java @@ -26,6 +26,7 @@ package net.runelite.client.util; import java.awt.AWTException; import java.awt.Color; +import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.Image; @@ -52,11 +53,15 @@ import javax.swing.ToolTipManager; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE; +import javax.swing.border.EmptyBorder; import javax.swing.plaf.FontUIResource; +import javax.swing.plaf.basic.BasicProgressBarUI; import lombok.extern.slf4j.Slf4j; import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.components.CustomScrollBarUI; +import net.runelite.client.ui.skin.SubstanceRuneLiteLookAndFeel; import org.pushingpixels.substance.internal.SubstanceSynapse; /** @@ -65,6 +70,8 @@ import org.pushingpixels.substance.internal.SubstanceSynapse; @Slf4j public class SwingUtil { + private static boolean lookAndFeelIsSet = false; + /** * Sets some sensible defaults for swing. * IMPORTANT! Needs to be called before main frame creation @@ -87,6 +94,14 @@ public class SwingUtil UIManager.put("FormattedTextField.selectionForeground", Color.WHITE); UIManager.put("TextArea.selectionBackground", ColorScheme.BRAND_ORANGE_TRANSPARENT); UIManager.put("TextArea.selectionForeground", Color.WHITE); + UIManager.put("ProgressBar.background", ColorScheme.BRAND_ORANGE_TRANSPARENT.darker()); + UIManager.put("ProgressBar.foreground", ColorScheme.BRAND_ORANGE); + UIManager.put("ProgressBar.selectionBackground", ColorScheme.BRAND_ORANGE); + UIManager.put("ProgressBar.selectionForeground", Color.BLACK); + UIManager.put("ProgressBar.border", new EmptyBorder(0, 0, 0, 0)); + UIManager.put("ProgressBar.verticalSize", new Dimension(12, 10)); + UIManager.put("ProgressBar.horizontalSize", new Dimension(10, 12)); + UIManager.put("ProgressBarUI", BasicProgressBarUI.class.getName()); // Do not render shadows under popups/tooltips. // Fixes black boxes under popups that are above the game applet. @@ -277,4 +292,24 @@ public class SwingUtil navigationButton.setOnSelect(button::doClick); return button; } + + /** + * Sets up the RuneLite look and feel. Checks to see if the look and feel + * was already set up before running in case the splash screen has already + * set up the theme. + * This must be run inside the Swing Event Dispatch thread. + */ + public static void setupRuneLiteLookAndFeel() + { + if (!lookAndFeelIsSet) + { + lookAndFeelIsSet = true; + // Set some sensible swing defaults + SwingUtil.setupDefaults(); + // Use substance look and feel + SwingUtil.setTheme(new SubstanceRuneLiteLookAndFeel()); + // Use custom UI font + SwingUtil.setFont(FontManager.getRunescapeFont()); + } + } } diff --git a/runelite-client/src/main/resources/runelite_transparent.png b/runelite-client/src/main/resources/runelite_transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..c60bc7ee668647c3f70621b154e2f24331f19026 GIT binary patch literal 19182 zcmV)#K##wPP)E+YAOJ~3 zK~#9!?0t8*T}8S6J2R{AzE7_?=?O_l=pagwBGNk|s22ng3-)$ZE-Ky&UdvSw6~&4) zA)<8YAT@=M-cFK})64FA^))lUKlV8x;i5uvQ1ZKc&$Ay0*{r>0=3QTTzp{Y0EpN-)vRh&rIsu>numG3<*xt5=Z?-7<+b6ku zq8#&{_a6K3lTSane)Hz)hRvHt9)0|YKLD7rw=LvbEg)|n=Nps-`yII7y6!FZmcD*j zs#IkZMbdFSxnlL27mZl5<*j<(*XEy z&#Ja9i{*;k+Sf00xtt7wK>9%-e{$oEcLAV#h(*a0?k=zO(daEw})rWt>42`8Lp?v?a z6dz83+*E?R^}xjRAP|)?p^klSb@BgOAndkuO`qAkX6>3$$F}9Ke)DU2?s@0RW8ZUv zWJatAVBfuceGeVm_z?j3-YhHowgz|&+19;j>}waD{?Y-979Mx&U!K8!(_4{pT}*FG zJhySXy=HIUAYG7l0BDJ+DFFHZ-vBTf&W*H8vtfJBR`dwon@9IUug|FG=^ z0Jw5cc+Z{Ge!}BNH{Sf}?^V4>{9gtDZAs{AT{?vb44&&^AXkD@tu_*}=O*S~DIeZs z``0%R^P5&}pOQ)AgqXsPdivPr<97buSi#-$f7S;8KsAMuVyT3-x)dTPhyoXyswf1Y zaxd2c@4Dmw*&OkAA3hSUM&zEJnv#0iEBT*adRoV!H$Tw(?FIFS8D(kzpEdzqO&L0x zFJfhH9wKt#LLOSL|jm8 z7`4NfvJHv;w545o>~qD}NfW6QBnVVSu)co;VlPVpTs>8L%?(}nyG`4A zN9+^oXSK{cb4~aRVeD6#Y;6B@$~bYb;68Zw0|SGv_c!X(*6*L%KRw`5B!Amf+n}4f zNb*;mEOCtn+N??a)|p1jw*cjlqndv~J-<;_J)293p5^5g9|Xw9Mg;eJBKJxM@+|>? zfOATm5+RxiRaH@RBXl*@L8X#nFG>VuI7vTwOhfBy{hbJ+^0R*(T>oFKL=h58=S|6+ zD?*{f5ly`cum2$2AlO!M{hvXItRE2N!F}UOQq$*Lw4GPJ96+>mrr((|)l(ar8I4@; zzEhW#u1%RrdsC~@@fkp#v%oq60Q43bd&@)twilAYLWKy`LcVNcuo7WbbAT}7aRA!h z0)Ti7ilV6}0Qlvj$25L5kcee;bt8!@QvxsgU294c7xe^uaG~~S!3i$5;#xjysYd|i zjjvk+BxCspp3hx<6~KR;0j)Ux{)(hK%*T6QC_Dn-ks7&D{Nqnkgbwt3>$v;w`T@MjTK675p>=VCjBo>`u>t6+g6Z`Zwig^IOwj?TdkX*-cl#x(kh2~< zw(-|xH##(7C|x%`-hbyIf9Uzfsc= zOR(*+Bauy*Q?L5uMe9mE>-Cqn4Wi<6=nUXY!-LPS?czf8ywwl?fy0e@2!41~8f&Xg zC~sWpZT;5qO^*hC_&bFV<@hIZKf7j83;XhlL2(6uGmmS&p>v=5BX0Y{>ILm>R!duJ zvV_sfd7RQ7k6DkM`sDDWGK0UVM?y&}i3>JI18+GVprbCK#hFm*8e3pH4q`NdW#|Z< z3glkk18ltN@QzGt_GgN!e9n-;2~BDBvsWIIzS;3?Qz)YC(ZA+?4*(15ybG_NuEl-? zNJ*kL!=#-DE==D%Yj)lFnV9+*6;U>D14EW8AN=KRK3KnLB@K5>Q`>im9A>DUt`Gms zIQ+lo1F$&@79RM43*Ns-VU+2b21p5A*F)d;RUsuLAy8Gdx_xVRo3vEc+SH2q1slak zL2E)qIh2_D?laDrK7H0e6oyGfVITyMLV|M++jUW?*xt3*T=Q3mXcGW>-0{ax>mL}T zW1~YD86E`y8^8d7NqwSoh6U42{s$8>FHk8@6-*ng_LfMrPDKo zln1x8TUQ>{m;Z@SF*a?wb=|XzlFi`J{+cP`t!?@_BkOzBctdX7Dy1ZG&LiUNCE_qQey4e)ld}$^^J{a zZfF8i6fi=;r9c!$&~+V*Qn;R*JLjD9PFuF*g-!Q7{K!jl=FV-6f(Uh)6nwkFhlWS` z)~#DN*w@>;c-gXLFO|#Xl@I^rFJ%Be@Wwa!`Oh5IWJvF0Gv_s48J28MhJqPMLyhbJ z&=s&agH>;QweZEpu`j?4#)G4u3hX5!iE9Ic29ffvg-41mIiz^0JO_L{)ta~ z{p(-5*0CLhDhfaVN+<}aeOX})1b`$2wr!(#pdYqfMIwSLE(_@PT_~%$zmFP#BWB1|cQbIBy~W z0V&;)k&!h&{^?JD^Mmhx_YTx@^lwN*Z2X@S4rt5jOGUnnFjqljB@l16z@>nijU&pJ zQSK|lF9)a$o_+d;C&G8%vzt{= zcg#{dG(r&9m8>t(1He0JmE*mcCU6%39D4XWXWw?qEvv#PQdM1tN&u#+ShZ%YR4PVT}l=rDBO;~X?(YmNP!7>>r zF$>c1P+32Ok=26;s=ibVmBbno5L`e*i1d^?h)^KjnFZ@;Kxl?o`?CizV4F9e_F(=4 zyK@+iFNn7X5zmZ{y5$SU@K14`cL6~Al&;2m@44rZhWfe%AOwO7+;iXkcYo}%OD_db z8CSW7Ty)8$4}b2npVpJ9G@>xV(C{EeMn|D23X+K=T-U|3&pwC89)BE$N}=lpz?8f0 zz5DJD0SE!ieCUx!7tftNdlq9g-{A2lp1S#h^Uu4abK3O7Z(qFlt|_f;X;WoT6$OM+ z5JGln0!k@3=ir=!F$T}~D?hsK`v17{YhV2}fWjNygdZD79D8#8a;rt3q399J+0&sl zwt|mTG4$LPRC{s=9G_=f(=2iVkT5{&fo(_}vJb>y4i(=A?J!|4S&J1 z9|p)5-`lpG2&rZ>mbZLm-+q~t*>%u!g_qt;0PNzW_w{TWU9|6llY4vnUe;9&KfLbx zyFYf>r57_wbK^EQ0PxJR6)Ug3_r3?9su~jU7+PCvj_an48?kKZi`cMnJ+j#Z&N}lH zoOtSKsB3HlkfH8)cWhK7yr7wPe^_n%0qgIFbx}uMdXtf7m>Rf%_ zE!&G1ZR@WVLZJX-!$9vcu(l)`59&gCMg!vYF{Y>h5du8qC~O*qOe9h19)?dDP%45k zf+-7HmhH|#+yuyNgT;$070(jYa7xw-noiO*6@(BpHZ(L}cG+d;-FoLAS5!)c?tirSW#ewz?}vEr@B78} zPtHqRVB20}!DPvpi-$q(>3IB`QX)#TK7Osx|Pz}%RhSA z^#Do$uyo0i!c|}W_s<@4%yCDoU9;x7z;odSAwUSKu8Zw`18_YL3Z+OG26Tm??0N`- z5K`8{%li8I?2FGnb;tbu4mk1+KMewBXu?=3T`GIm<=}R2h1OaJ5DCRlkZz5m@rc=w zt`B``D{{-bVJ0o8k|GQV2qlP|V4q*rA@PPIfLZ#Yg|p1-Rf0pd50_U^Lg4zrps6eS z)hDeVKX*v_OaC+g{38j2AUfr=Q^#IMBWt6)10IOotb4Rhzr z#a|wI=RdjOhrk;g55m`YyNaZ z5)c80R8+)bacHS51P8oAxuu~FpP#tq?;DV~V+#3)`^*K1X(+)!p?ayQDYMflLu5>& zk%z)lHFiK_UE-Rxhh@)y%P@gwoqQrzuipql3AhkwZ)w4nO&js-k`*YIDqxJER4T*J zHB>9rH*{@TvpJ<7efPVc|F8f2&rd{t5UL7AGL?d+sn8fhQz8xm0)-MtNZ6hWLI}bz zMDNfLX3w3o@cTcy?&>#^@Vap(ZB(_`QCkMwpA8QAfDlmQap-9asn!&@9Uw8Y9pDkd zjeUqp9>PKeVGtnJ(g_hp;DWk>V;BH_oq-`FY>K~K3G|V1M?9M{`s`}>n-ezpx0EX0 zlxIU*6glL&s_rKfuUn z4r60u(6!yp2?e*_{JWpudfP2u7ZOk@g{~@ql!!P-z$0)WpeYK71UTm)ltI;Wlx+vc zop8cM>1?+7bj|ZKyDA}N1gj|l#nO>IbS`M#MpUREH&_Ir3{0U2 zD=wsIz{*%q3^us68@~a7e=ETIz!=2YJ;Iszjo-3eBd;6B8IfGU)dYk9fTPzqqrMk4 z_YIV*8e?ju;vTp7>7i6lZ_#|q0KoNpbhNdCP>PCMYyEQ_8&uOUZ=YFE4Gptr&w_2+ zpmdLNPU4$aUU~gJci;U7N+~F%V2puM3QJW1Dd7hJ+$e+_1h8EfQ5YhU5*lNPGtN5u z^w;}CT`ehb@Vxp1&OLj^Epy*FOY1yr4wQ5nlqwKa7s3nB`}_u!`wCEXhImU7l28ys z1rL41X0$_5N#Cbx(avj14+XhZ1G%qxS0EG%K|YLx`IqTh8UQx0shsTb=*5wO{f*Ir z`{;gMT6)RK(S6@C001N!>+3NzJPZ(EU~~-mTpq_BeFUtyg}@7tN+sZVlR{+K-@f|l zFY+kLO&tCNDP(FI!YD!za`X-iV0&LLhKGl+W#c-yzK@G9x#VmA$QSq{gXMpAzvb^( z*t)T$-u$`Y2aBQ&L-DZaKo0joh9PL&g1uoo6oo-mfaKH`=*?MxND!SuA_91bSZm$? zGCBXlpe$~z)kb_hgg8HdRFnGqcmB=?3UCXBXeCwXi2!hM02h>eOJ^)&Sn9=bL$xn0 zA$SV`fMCw-S-Ah9zd%=16e?9*``zzi&fIxuZft_8s@Sw~^Q1KgjSLNL|H7BP@@-0A zxn&^)KnVPhqgpOORW+nCS*V7Asncg83maHMD{H~(Xav&;xZ{Bu8kCp@HESR$R}hXC4t@1+ zY?t5zBM1TD*@cPopIMl=CuON^zt5oVw^{7)4`c+V>IF+D{`~Hj?I$S3GbgX}Z#wQ} zJNK4}0w#!WTUB`u)>HZEhfJ&AXbW$dK>1t-o^FAuFoiAqvVZY4xOu`?;tJ@AMwAONG(VtL(e~ zX-wemkjU>o@<=%2vAOSiu&Wh}jEq1x3=l#<>7sCFpZ2NJ2{iVOg5(bf6!0D~R8>+x7 zIq)}k14IRhS)g@kuxtX-^P!{@V2TQsO@j*+dQ%;^R8btPV(Py29kC2%BooTdb&ahx z49w>`fg6UiJWpQLm^BV~YPPGzI!59IyGrV9CUe4xAm0A4yQd;SZH64qV=fC zA5uz4As{iS4Ps-f)~s1F;Rs48A%uWsSs)-Nmx?Il$1pV5kAZH=%2?Gauj@aC3$c9rNaYkaipHu{|B?GFTM20JKyn+lj(StkPw2v_h8$#)bxbJ6LAa;453o35&(F7Ry;m?R_5Mv!8xpG zds``EGqP!`J!Y!#-4J%cLn3WLL=sFVh_$9cn;Ri=Hn3#~v^fRnI;a$g?ROwV|0rNu zh@=n1(+CPVjE%(pr@z4eoYvKo&mH7Hf4W|s-rk-*q7p<0d~d_>{X0JkXZFcq0QmEk z+|qKR+lfdfb|;(pFCv0oS&63UwRqfh5s#TD7K-3eglIfv8%2ClZ`!U@mP;w+M24`Y z34mgufFSVUI8_vj1(Zu=*p7>Qr7E5~Fm-k!#g=c`n&VN(kxZCV+gnoYnnF=5JNA~r z;uk}m`dU(hp(wD@7D!x$WEyzBjMBydc}{p0x4hy;PsNkQztuIwbs_=9P%y#X6HNm% zbi}7*0ZG78F|d{l_*f1E5-b&il1_r?F%U0=jCfs7pZHT-Tk0?k^bwA z6I(WUm-9$2?jH-c6sq3u4p>$?U~5nHgA3-h))PB|qy*Gdz?cFOa=*7$Rw?ga4 zLTyYzIxfH^L=b_bV_?&|z?wT@kChRI7(D77EniD0xUFZ@Iir8r`D#-gy-=a@gj=%6 zOswIwO+inkEP5|2)-s{Droomxm;WzMS7z=NKEQ+)5H-m5Le9y;NE)U-iz#!3Ga+dU*G4<<}ywiB_VRfq( zJeQmHD+Y4Rn1AJcoot^}T=|GrZ>IdA3aC&(RSK#Tz*0dnDWF6FC4>wlc&-A{m;`G| zfwZ(h1U`r&z@NVdRyK`!bNPw+?d2s4pRw<{s}a)}MKd9=LXIA)V#=*eXs}&uQ5}#E z6fiomrt^#704j@Z?~%Pu1Jr0)psTYBTuKCC2!%12hK?wT5KQu*I8#%wvja#7!O-v! zLO+1xxERajQK?ozB!}yVC4c*-^|`_FC4>M@5Q;xfR}a02*W9s_w)3@}`*nSr7hDDc zsnr?K+Y?~*CWxf~5eF;_&{U9^2@=)Y*V05sEk%D^@0BAa! zDkP~0iYf>QQ;>~m^e~H{J&0brYWU1efwR|WfSnn+R3d@D{`Id=6cvW9Aq*pM&LM;Z zk&}ynDIIMPJ0PYC+EfoQmIrO91JN~rOUU-Qs0`o3 z!;sv2+*mwE#+A0?4(1-0J{9cCx=f zEf+6*2LUWd3E1PMTAE=3baH1!8KyOl)C7z%+;{)|7#_DejfnuqU5`ZEgr2q^Sh?zjK02wKez7LtNLPjCf*_{AWAQ=#>9Yj@=8ZG=w=Vi6nLsd9gt`B8Ku92rKy?iyZGkkT0ab;!v>RXqdcp#Pg!Fxw@fbK4n9`B? zim8(YU9IGF!ayzucora%BQ1rj^o?N?-XgNw##u;7cGdutQbIHD;^0!?sRtg!%PUtRmC4r9!ny{P5p;KNdZ@2w%OCMNoU21#^7~%W zi(iVTwQGHw_i9#>1pUQ!Vlar&5?K4bkcAZ>&Goe|3Q8b{bMQ6~L5t~Ni~@{-ND2{f z#FKHTkw&$8_0Z5M1>E;n-jgD#ZA)85@caSXb~&OF9lihnAOJ~3K~(UT8K1a28h|vn zb<8ykW7zqh9vIBbSADy$EnkSLa9pREjR7Er9;b zKukd9bHHd07#M=6MhI*d5&+dyKmx=tplS-7vW@zNI0ToF1X6Ng+Xeaf>7&^AWQ3?A zj{4u}u=Z9HAora=|KLnImEDyE9JldIgQC=$L==TV2m#YDps9Oo0@6SI`Om+Xu5Xwo zDaD<4-HG0wZAhk4pp-zN3<2lS#&zqz;FJq@VowH2sB{Y>6uP1T8U@k@U}zvI4g7_E zu;vC(I}fWd1+6{~LJ1_7Ah9?Ujlsz~u#6;ZH-HFu|K=h5sxgKsk2R}JT!?pZiQMWU zziF>E0T*BNZ~t-hF~@!|2t#M*P>^#D4gy`%ppEwdFveYj@!S2!Rw55szvG8bLT70niscA_{gJA9dg*A7l1Kr z?e4~puDcEit5!IpPzu|1$6kEyx$}x6L%#s_oKX4U70<3A*;uG#&6;LYIRTe|q#&S> z1b{-oG8QNsuSyC9Kou}U162s@l8e#diUUIQj^@O-rghbQcIM2+!y8k^pHChU_HO`k z!CPdC>h5}Hf>O$N1^^u&Arg&`&ewGvio&4lIyC(aj|02mu7mylEusZ> zUpJ3u;dZXeqlAD`0wHUC+mupJLZB)C@MpBC)4Jkw=FV^LoI3T`_Z)xRXFI#P+R~XU zn4+Rm$m5DDK7(W;21bC0OH}MiwB&^sPR*v0>++MdnZfvImn-k>d-%?tqN5h#&x92b-l#H<*iC>n3x`1@Mur4=h~l!|($=Q>8Vu0iFJgAxi= zRY4iWRp0m~TALf7C>o-uR&0{aHYhV@&OBrDrcLWHNdUO0P&=60fao_#(`R#1Iy?(V z2!KiuMu4mdC2m5v9ARGpByB;q9E`B6!Ha(jO8$U-u!QrN~Pyr*L$p5DNmY8-Ed@M7n|Ee;5k6Hsg}!N0L_{p zO&Tbp&^j|fC4lfEgkwc$oprD}8UeSAh9-s7Wk?5;1lFQv5DM_3_b-1p@jWL`Z8+uL zt)r7d18Z1r4qYwWD z^XARMtl2Zr+*prHI*E8Pj)vw2w6ruK5s$OO-f{R3tCe!=WNp&$<@=_mo;!Q1OeBF~ z2T)Ht9@D5)5fqyc7WU>XCpOawzC5SjuJjn_aZ6sh@*;C?9kR}P^xRL%XX z0nk01D@*IOQ@9 zI`ClB*Ec}d4Op=Rbi+U@8Al=>Lw!RXvY8aJb=i5xo_Nw?0F&}wzr@0ZJCxH7^T^Aa zG^h*^1PI0f97sq?5MR^+-dh0CRIv6sxI;y78DPVMYp}V`c`(tHMrOYjR0`F>XYW|| zp`q^l;u(Lzjt53b|FwjBs5Kmg30I}hn}7O_|y@puxZ6-PWCM=TaYeSIC`F$>c=I}ToS;K5(R z9+tRmK7Pt!MoZ#2_x2}^?a%eX**pp;q;^$b02%>80$2)IeXZeGcpd_9xGUEpv_tfD z7ap-o?)wH`>cjFsZMdwO^A{hw%0BDIj3_@*UYW^s&&+u8p9ugn#^!7|X$qM%07$uO zP2fa5KoExDT)_7Oc)kz81tj_V<~ibAUj5B){ASha)f*~y6|U#Pc3lX;5jSH$z#9|f>KInkY%$_&@yggZyH8b%s*_6bpJJ>}=q(w50E!B=@t0d~pYq3ka@-K^VJ6rwRd?5$hsbXYo6vavrsbmVA3#h6JMN!6Q2C85RgK3$FC1Oa#V>tY< zLw^QfE_Rb-NxyfWw&9y!bX85IEQnC-EkbPH4w!1q3C(MnFsomN1c++XZvq zIZ!l!Qta|%GfEQmF_!*7J>BQt78d`l2GgmA9hH*zNZ)q*B+kXzZ#DqZZJA^18)NND zx9;i!{OYv1$=wD3dsUG~$R(mEno#Mrxx(WmMhH;@0i_IvX~Hs1sOq@6Q5B@qslf#i2PBg~oC3`Z$g&zuTnxY#bODwDgd9{;K`3?^<8tb->_2sw4{H{gq3ZN( zMMY5GWS)fpYn$8RA_&A?e`+O-Z`R@eDWp@W-(K&lL&vPE zj-1{vx=$OBBX1S}jHEGp>4xEVjgHxs+n3e4q`%s#uomP}ozl~HUjvNu;5)csArXZ& zyYKmaZB7s8HLdW*O2Tqqzw(=(7#9l#?5&~zP|szK8f z#A7C6@fZ|UL1%m0K4+izzH9IX$HWOm7}<_gUD1zLSeB;7(pJrSk=hJEs1)dofv?U% z_#84Dt1&521X=drRHPRK*yRmkPwwAH>N4uNu_o(OVbpk+eUp%1uKNEJD)@ybH{Uj` z*_t}AZqWPc8MCJXz_$k?e)@fVTPcb5nY5zNi3ngKA^;)d_Wun}36b1)pMU)ECqEX1 zk#Ic^pai3%BT$%vYNZ4~LRD3$st(;SVVG8}m0MF0i^pJ?2IkG5^ZxTcaKR7oI^SC~ z_OS)GFfZJf#WXCK*M53)XNKzaanQCF5KRZEw}7b@zV zV*4%*u2Wq|A?~Uay+<`hk^m4f62CR|=GO%L>4@fo;xQ0|Df@hW5Ta$Djw9|kaX}jZ z91ajGsqKjdcon-R1tK9{0fyWofb*xHc=FfFmcH~|&IJNLfbWOs@9%@}`*0i^l-A15 zblrfin@|)LG0TKy8n9v(C}mi*aNiG}bm}P|#y@z0W%t?BKT93|e3|n>>ohdKqn%_9 zYzJ#k0qG<_XwAk|IpFeIcd(Fv!GNfi2_#HGU9*)4qg_YEdtTIkTz62cOX|mUwx~Z? zb8zfy84aX?!+Wy<(9#q;?eeW~{Hk{^037`7M}FOK&|Kw-GdsWZxuYBFN_n?_w*WBF zmi1~%m=X#pM2!^Mi7cYKR~5_`|KZN7hx_~QcimckVQe%H&-3AVwFVFXFbo5lrooCO zV3-yx%Rs z;ZbzZ!d7MXG{9?}C!ymRK(<3W?8q4I{yHkxU3bGrN5}GOL=+;CjKlW>k&jZ$pgQ5ZebK>?)$X4U%^ugId=SOcgQ=YUL-~ha?=F5@6!1v)eE{eq>^7#V#di&rwRY-{)%%i4h&@>&U8Q;MfD2m2TKmD}-KJm0uKl*AA z#A4ccA`+kq;FLTNQ-u@~VbO);096$bO9vQ3G+c!{QU*)MKy(6d0Z}d0EKC%@n$d)Y zjPj93X5(}K!_K`PSf7W%M`qUw7wlD3z+a1e)w<#U}bS`H<_u}(g4jCD&mUasO z@pzmPQk!gSz%&JW*r;e{7ZfME5dN6tv5btpu_ zE%_jfz%6>vG6wYaB$%Z_1QDd~gIOlH9|4R&YeGnOxv^-R{gVP(Qwf*Tc=S{1(D*2Dm&{ditvFt6lILXCpvWF@i?;C465Za1eZ12k6pWm_f-0Nwk`d^4L5zTTCuCPZ6o3wxqJbh z>tW@JRVWm4JA97`0BGZyNKq8%x(?Gc={e_|_0vl~`q9e(Xvu`Ct8oqKv;_%?bV~xM z_5@g?38)lOXSJ$dLBSm#%+$av6NE@m)2J1o@d&~TA%X}>Dp~7KROz5h^%{b(HXI-Uu)d1_ZjNG!p)_$^kkEWEA z5JGmY_g5H$s%c=1?5G8t@Bu)`WaPrRUoPD9=;M!n$aOuZHu{agbv+0v(BC(JVj*7} z7(M>G6GYL@RZ9TK@$WhAf4+UqH8*yC|B-HLYA_526$EB|48%|XUxI`{)SHK38i;N} zdLe|z0WX4ZLl7=&5dhObG#w&e04xLX&I~#iwzX=y9F7!uYS)b9b9IdVFerJqEPA=x zcJOlV^0OS2c!>LhAnN53Ows6!VkIg+zHj_fXAX*?-PxR9EHvZ40QgwJeo!49{jWn$ zpZC}LgmxVqA8s{7AgLS}^+wN}XDPN%!iLWF;M>plgu4X*LI@F3uw6NC3W-?hRG>{6x|!vFMi;`hd)p%SF2;W9EL`7D3_}k8_l7oXFG-l2jDmk#CS-$^QT5w z2>?*$?lb2@-?;X_e?C%;R{Oq`ksl$f1c1iIQx^g(Z2>U@L`o?2Nw}jGh)6&dU5KF) zWT6V=9l&;>PML$qc2U||#OUS{>Sxv++Br4;C2$${szLVwYn%%J;HvR`Sl1U+&ly9t z(#Mxcjx8#U+Dw&R@$wN3|NZwi;JXy`_6D+p+xWviMhpOEOs&82nX{*CZfi?_$;~lo6+9%>6In-+`HFDyPXW8j46=2a^4^m3acId z#GAf$asm^W#46a_@W9;<-FNR%QeqPz5sptJ^IRXpLnFxN$9BvqoQOy`=a`r_KA{;7 zIbh+11BYDH8MrQKXh_I#*amU&U6FVj5zWDu_U22jN2#_udo(xpRuHB;z2rC8=Hl2vua4G>z)$ znDb@33=ZYa~g3MgSEeDB7!gXas#YAIK} zCqGaP2m4Aly<_p#qx%Lc1$U@WdEh;5pFjVujoo{k4dhY801(bOeBa+e%~Hl7@k&3y zL~a0piODU47E;RPk3IJIiLT?U6hgrBe3UB{*tUbQ(HsVchF}*95b_n?Vq%`r&Jl{; zzA!m(;^pW|q(&0^)WPp5K~w`E{b8j_oKjrw*l6=Kk5eWHb z0PwloJnisVgDowoBPJysOer-OWAR$-ZS0^12%%tv?8p-^R+|{2>$;A~e~+;A?egYF zAA0aT!^6YBjW~xN1gKUjC>Bd_SHFZqAN>L7(uWXv?vB^YO=yA%@`@3lw9mT`B-@(Y zLRAtC7+5 zx9y*5>Mz(2*SBT9$)s4{)SUeEw9f3a#e8KDVVIFp?iVuV{r-hwP4l?+`v$wmdUAyQ zd6Mb@h@vP8+qoiWBKapLfG|GDSz!#Crlv3n1*m^RhMs=>v5#)s()~5p^IY5WQ7o3= zM-lGAEG!EW7|!JohQW@al?hEyn`0Ov41A29`vq)O_aT4oZ5SKvtDwAf06cF)XeprT zfkq*;n1-Ml!WpT;oZAFrS{iC|5-b%1frOj)P#vtIw7!>?rF`Lnm#R0%GVH*6-aYHxnWn_ik3Bwm;`zt79SQ*PnE7p;2gypV`sAbl zAf8Otu~#Jn2xS1scsf|@$QP)p0s@i+@Mc!Ux=UYt@jK5y^X&1y>kJ0IkF8wAX0sk6 zr7|{e>_*SF9#ktO1VI4b_iNQlL9k|0|Icy4bhl=D1Tak$d?538x)- z&3nEzvrF&OboC3f4`_KPl`#KXL}DPFu{2f4U4~dac2IWC%-QDA_smn80pM~Dxqe+W z4_*1r=ur8X%(S}u1d-UVWE>CHe|>lxB^*n;H>LI zX>~6ol`t~~_|{>NiTQ_;0D1xleJ}=?O=%>OvH35b)Ab3dlaiTG-e2o50rEdT`NB?< z-%U3R!&y0GX^N;TY|c|61yqww|9|bBX^>rInaBU{+0VJ>+@)uX2sy|tkwRqA>i zbvKwrzj;eP9AJ|%K-jtRpn zgUlR9TU3L(coBF>fpu&Q98chtnsCcaCPgGdOD34-gNqv=ngmwK1C0QpVGtvvpfFnA zWZPaCZt#`+^0cz|#>?adT4N7u20Ry5!095W>4Eu#=xr)7B5Fq{swzAoAG^9oyZ=Ke za$$E|JFZI7znHF5Fv9BS6~k`vSqgS(QtInW8{fWWsaBOF@+q&{kOhJBG((GVK8PR- zhOYBkwP@Z*IBtUk(%Tl-HeX(-|J#4(9p}yL0DL@=SpEC_0l#Sv|5~#MM+iF8>GgOU zFGOz1GW+w*)4Egb<^B6^*|TTgMZRUuxPAb$X`xuDAeYNw=;$y`j%83P+Y0%A)RFW>60ax<@WBD6(yjR? z>$eRgQmNz?0HL=l03KK@gufGcRe<@`O8NO;{c7j>-1N+CZqsxE--m5CQ7RTOGCYbS zhmT<*GmfU&K(%3_efrlB2e%_Mv>mR`Agc-(&)_vpK;ls?G+@`7pg~Xwnzq}VtHHB8 z)KBKYd=GGJ1g--{0DGc<OYAE(-rvE?gPzHNh$uNwAiU#$K<<=M*~IW+jSLqo?mH>#C= zw&O9|YNA$eU}k0p$BvI+aPTlXk8Fdxe>aMY*TbU(M#2CQB+!wgC>A|#im?x}w3>@#JRovB^0ma*ws zzzY!6Erd4pBTxi5lU4Al0KGeeSX}2dl_yTo?ak~M`hmVC@or0zk`>!p-LCm1rqD{? z;^@P*Qn61A>ZE-|zwA~d7hVuV&g@6-#7MJJt=Gym>+A7>u8k4_tyY>NPN}&qB;fLi z+yDBp+?U@S!y8G>ctH$Rt5xuV0FDs&r(UEaSq33IC}Rj{0FKU=UmeGRC`z!J79WmA zI{_TVJIuCziTq7w_Qk#V+4E9ey&qpXu;30#X(XTu0^ft@T7Z27%|-(q+%YWZRH3Ol z5O`o(2>xsxuEY@QjKHrr2pAExn3imswoh0ve@rj|;CVpgAjk}qpEt&+J#nb%w)eWv zAKPDiVTz^(y1-6MfC~~3mURM@!rnj4s49|hhl<+B98A+=GI$bIfn`^(`+)!s@svEx zB~-?nc1L#m@uBXe?QJkb82u|zJeWgmIRA3`jO2!9sR=u9ig}y+D&;Xfbl~Kku5^42 z^SDorWox%eMRRT4W7GZp@#_J6>yO?6Zv59TJ@ed-=l4uxvzW+cF*7@hT5Y}pCx`+l zrKf@-KoHPVmqZ+ljb&chv+Koo{D$oQ_qE?)b5Pj)+?wWGcKq%a_a0b2K9#$}wk>aI z$iemMD0Vkg+^?^J699Uf23``tMMH3<7|h8$sAWS5EAR*hKj0umWC)Thh@u2lk>E~b z!6*R{Tu5C}7>he0P#<2VfX4n;P;xEQ%_dhnkRe<;3Rb9r`3`8g3QuH&_ieC_Bu0k| z<=MH?;M~ltRUXa)UVuiv41se2ehPv0RfKE+019JCL_t)u(tdurOI;Y{S1gxThl~Kp z^ERV#w1C3Cnep~seVOY5g2E6GCEvMnaql&I{js}8!J=_(1yjUoa@B&*96FTS_|d1Q zFR9j?xi_=}05G?F!7D`RHR$d=d!W z(F>A~t<=a_&&+=LwG~9qZqA%MarCB>C&nLo@Y6jH4NiK?m$Cp$OLOSylEA13P87i> zrcey*Hc&f(3dk)Q1HC)rw)L@}XM-bu*ULJ!FyK_@5blt{ zFJB99cogxth;Ww9%eS%TU2Z+VQYZTKzcEkGU=eG1|GnaL7dXL1vG<|Z;TdUd0 znS6b)tGBI7x`3b+B(kOU&g z;EWECuEpS@X>fhZ0W}VYA|Q%{2m+wRfmjc~D~K%Zg4`R2(7OSIdLXGzaLEpEsa{Yy z00pz zxeUfmzgp12!NdOmpoTvoqAFwKy2#x#rOI$LC7nwxFVWqpXOxHm-?WiV8=y^Zr(0{t zp*9hGd<6oFBFN1kwsrxW@hN~%__Zc@Q2-$#ikUhD62Pf9p&0_oBL%eeL_tQ!;b*46 zi9CoZf=@&MK>(9Q5F-q~Tm>JE!Oi92%$32Yi%?G+?B})tN(7#1!Zic%VI7U3F~kPa z;HZz<-Vtz$jQqAikO1)8G>ANb)E+^#Y`LN;DzTJ~+>_J(XHO94p>x6mbGf>CbS8L8 z?~LAI#Ply-_sry{@XX|^*5*wKG`n_e-~FSlEC2nT1j%Ds2 zA3gCj{={5*)T}?b$ot3McC}b?+>A%rqjt?16M0C4GQCl=#x1Ma+yAa~w>Yo}%m=*u zEI7Z3<|{c6*8}GRR?bFrWhaF82qG&I;CX;>1Y*qvlPydfoJ7yYKJY;RzwCp7L9%=x zs)AZB{OTwIRRyYJ@GT#{<3Wn?FsE{W9)(%Uf=CK@5%5S2cBX`~4fypY(DVU^A>eq# z(qSl36+SOw?D^wBn=WuM4UTQIVgU}o*p^+@Q2^L}Mc-w9-I*qq6wBXzF-d;rarTx4 z0D$1(A8)<=y%(H!sUQfws;a{A0`P$i$Mr_{?%Mg!z*|4@`i<~`5x0CerQHxRa7%8w zF`0}BT%*#|jIbPuB(*cTQ*ngT3D9~Ke8d1TZ2%O^5E0N2BvF8vCg2C!A+$%J$_$(& zLNIhFWfMx-g4?jrFdHB|2VRjNg)}f(08?bxxf&<~1W`nwQ9u?!Y#w4lg2Q-Ni_p>$sBIwxZ6Ua}2Y^D8Bv{o38WkHHvmy7lK~@Dp>rcROY-(GWdevDi zk?}R}>b@@drKj%tee3e3CE7|MpZ~@;ZoB^5-@fxHJ){%ryC8yumk%AeDe%1l{)||? ztMXsjs}@`ii@!P^Q~QkG1eouG*CkM%fKP-WrjwwNFvOw?C9H$_H2^+XzKH3A6UgtH z45*-x)IgLIL=93vp`AGZ!E+&*Cfw;9ibGTI9NX+z8VQLDyFo=2+JZ2^b6|v@x6Zi^ z-~(>cfw3+MDPKh3c#zuW$Ix(#Yx9Gv91}z~pb!Ae1ED^2F9NSv1{X`fHGOa@2PLK= zvoCYw=O%F4@pBo#mn+`2g*o$eg}Apuqh~{h27k4G|4UnY7Ib~s^L*s;r3WTQPdozr zc{N4`fUXB7E&zZr=_`~J;qbiLejHK<4X+H$~V|tmhGLX;+t0;#m}~_9euF710Pll z0*;$+r|;PSC!kuk!1%DH$RSyYCPl8qYB^FkQhl zon&pUhWu<5F@r;7VK?ffCh|G=rIEv>9RTqC^@^Z`BTGZc$d$bBw=tjp!s|La-omvV zxa*$p?s@c)pV-g*a>u*jSy}vru=nEbj{ZgAi;q4!^x%6YU~a!q`Cup!e!OD3+h;S? zFDytY*G72t?++d;tx^>bS>~=037Lw<)f*VkZ!cGCQAuQHHR`zQia~q}0B%<}a+6Kj zb7zaM_{7r{O-u!@-_T^44rS~`s*Y74NX9gBexx&eN&l+!LcPBo!}~HPez7gHA*w<1 zDFPnwJr~y07@Ru+`pq?he9l?jw>QhBPujMXx18Xf?*6WgmAQI?1r!lgil3|sw~CBy zinoOY=*HJBy7#5ocOn3={+x5Ko68qQ#)psXz+W)CFG>BpW_t%Giq`k8f5|=x0E3&O z3(Jk*uJiWQ-~a5AFjqsN%d2-MIwBkY=hk0GzF7FfS=0SjF4X*DzP)aGF0bfD zG!g0QiOQ6B-J6?w^d?=@MmPS)^MBA{PSE0a7`Jop5Jv0sKGpcYFNoh)N9Y=5SQr z)ux7ivGV(`xUB&A1KcTsBvp=wz;JDe`G4uZXa5Hm2)zqqof9R;IrD*IbFF{4MT-_K zTC`}004R= z004l4008;_004mL004C`008P>0026e000+nl3&F}003nfNklUM$J#y?4oSl`PwGlV!QL*m231IEnK*aa`}8 z;HVWgiX}8OpiNA;U!Xnwpa>^%5k0gqJ+#sPZ392xFr#yrL7+EbqnN4o)WZX+z|oNL zz_~6)6w!r?FadKSHP@fblC{dC=PBak>**r!l{XDuyVvID76V8Rb90Hv9JB5KX z6GM|#Foq?FF{oXOVzki1hMdEJLwG0xJs?iOJXZ_!IZ!`m8uP6K&W&AQk6pDI5`*)v7iQ3#E8}^ zK@VT(fK7x(nz0Ci2V%iEguUc`pRx)vi4GwM8>xqLaLE5<3<1P0SQL6$q%oE70}n(2 z`g?H5*@pxWDPgAI1%eEYBJ-pgz@Zuj+(J)>G$yeKf^&ZWQp4uN9YIp5dO*=X5Tf5ArKm|pGbhf(TYkK1fm9k7{P!_6jcLJE63>XS}_AhEzMYj%>6A;DZI(t zGhis;gk3-uLlOfBn7kmMPYSH%s2B%BVFwUU^a~Or*mD12KK_CRKg(# zOwX!MwMRCGUR6@BI^n1=T6l&`fasIn=p2+Rr@5$tjWShLOL9T7Qxb=Uj{H>;XyjFG z1px{0r(C*aCTJ{%jB`EMIVI!gBtY;O7Ib#tV4q*%#e!x+MCeW(};1q;0yO!4m^oWt5tq48F?*Ucx2BIYf z$zel-DiL$Qm;(hE`>SM;PFRa7e{(s7A;2wbsTUp~M2VPZPW-jU_lDXsJfRhNtEe|4Z%4)QIy1nAP6EL87KsSi)?}- z21X5JAR@*PXer&YQ^@{Wg;W`OaCLFOCxe8{7}Nw~IBG+|Wf7L_QN$?&7EL7Fq-2=@ z7?9wHoK9d&SuKJn3y%O!0L}TRz(FNC23L1;5wvUx8z@nvCC#7|1~NpDzbXK9)quTF z51F3fR*f5kD#)O~xH(!D354nd9D4d!^}a z4ww!_zcNDfMW1M{?$qGeD~PPvrWIE(6B?OpD$yh4z>b7}jx-?U&87F=EJrgEL z>`0Xf0*eG1ejpHcI2XOkUes0~=0nX22u|*urNj=La6>~uOn+sG2uoQ+1n27lMui}IVRIn?8gwr_$~d6m zaua9^+k!gbkh+kRW(wcMO%;f&m|Z z)kVhcm_-=Sr%*~gyCxR{2;7C(4fh#hrwWuA3WrVCaKz?*Qp`Zmvms<~-l^zEz$aZ% z!(yOY2c8TJ_hr*1ezN}wb4Xn@9ar;Zk+LaCBa(yii$ zuIQNtY83<+vkM_elo2SMgV2$xVUpA;k{Fd7C(IZmn*arH5U>CVLAj5@7_Fe82e?HO z)S`;5XiuN)ngdrmf|ACdWaW0tBCC)RE<`qAcklpL;2?}$Bmn;b5snH10YX58hE;0E zAlQQozw)s{Xe7as4M7l~K|=`e1KhEpVfw3BtAtwiC{R%HNBW~M7zsNi^oE2UCXEo_ zjqBi^TLmk&6@t{TRvoo)3gWQANkB?~B{}qHL!u+Ppe%fe+1E=G-77w_C%vhFQdV=R zCP1{6RS?upK}-NR+lu)vhs`Ex^cWI|=%|Uo@Ho3!lX380H)Nc2S)G6!lCI%mv6kil?hATa=fMF=3E$h!)PJQz4aSi@Lw z1zhO@p!d{9_cCjP6JvX;*wF@@e*E;G+dYe_8D(0ETFFIt(g1yNNEARY24N%|5(q;D z3J{l2z;lwTM!nk0vq) z>T*$C(Hnpkqe71odUTDVN*p;L0C61<7bpp(kQFFlPrSgPqzoc7bSSE%u_{mr&NBcq znoyvOjsgX`QgaLrf)XT#uZ-7^h$t(wjGF`X#6lI=SOtYd+_4mp20%VXpr0)%2LP!@UXX-Mdm7%MJ3c`4yuV<>iic@Fn<=|eop zAznj>Jelw9Hgrfo(5pU$TO|!JzW2^U5}Ux-KN4lM%m;*fz$x6n6)5l#N(wN504J#W zuZHU6OD~zrci7|ny8-oxZWl9h&p%F@a)(ua~PrI>S1#dWWp*t z5^+F=z#M?12{a%?3_Zri=rJ$~Xo46JNm492?a9H@0J0drvIPr7Brd>|e&A4r2?B`? zQA^NG@h8)tLy0|2SY#j>33)VR%r2 z&=N}G0+P}9Owk3|^}$|qShYK9T4_SICCsT00s6*--qmT5hWK6?#!!1wFtG-qA)J8d zglmfvfnBRrV%AHpP7@5zZzLZymJ{M$elYQ!$)OfqkUkzyRpLYi z!ITLAaFDU{_$=Y2X;JkVF;%Xp#nrlT1#ykus2W!k_M#cZ2`~U62IX)DF%v4vkO3vQ zYQU`qW*}-20Kq7?L=<63ynqM^PpSeD1$`J08j+X;p=27M zWGi(Sf`PiNgNP|?=m*flmDrACY6U4(kl{x)rUxO*CLD{%1O%B0|JX1R>?&ynv7g{v z6-TQ;p(l2HSQ9?157hS0jw`T7WLv`K_*R*NJD%tj4(;;NSI%cMXk#aIxsiBz#i!~h8Ei+m(=KH zl*G4`CN!l-t*K5}P@dp3hgx+(SVn*b9?;yZ?TtX02?&)LaoZ-kn({T)#9*T~DAy4= zraHM#z82?-KE5|NIx=d4h7=_%>u;RXN1v4v&IEvv8_LK55|Ek{ROyKtUX+lU6kMAT z!YzURVmr31V{D^&z&TVC*@C&ZvBQB-Tf!HM}V^ z7756;Mbx;Xme=Yw_R%dZk00!fnqL&VrYe4OqpqbYp`~8eCp#wF7G9efGq+Kn?}&gm zvn~jruNj%Tf2w28Wc$kDmNC^y+a{&%obLGD12y~R`)2k{9$1`E=8dY#h+Z+!aCEZm zkr~e8Q=M6<;U=v=ojjkg&b;Q(Nfo-fjA& z5yfc{BZ}fn(;@)9F#$(T&kRdghBXX_0W^}t2#Gt0lbSHGN+ct;hgs9Zo+L=D1_fLd zENFx*QRC79r<6*{7@0&tnZ z&I7C=n6%hQf{_L+5#ElF73@Mqj>rKyapQ{PTPn0`>JrZmH=dtheSMbgtIb*OElD{u z+w#g9$L|hi{`KMf7dE>dTWmSM!t&+@>-+mNK7Fd{`WpkUzSQ@d)5YIBTldwus!Ol; z|N27x$7f1Ef4b`Shoe4!s`{g2zK@RhKH8W0#wO1r3oLslCm)$+I5ES#pjkJ+S+{SB zWm=uC5z8wztU5i)tnGz+mq{ZwIy{}o$mPkb%uNEP;zA{eN^q_Kx3Py+C-eXX8~}l^ zI{|$NaKa1`eGru3%nf8TVHFn>z$M{Yp?=%Q`3_@p8bC%IV#*s6f=be&u+@k~5Z4Qt z5$O_$ivs`#I0>)_upm69&@@8`uAvRy=$1;|!V2Bfqs@O zZH2dY6}BEI?s&d$$N7G(r>fc?ufO}(1$RE2(tUnJ*V9AVAM4Zo^2ocdkM4e9NcT%4 zx?UJ^=Z!Jl=LdH@-F)Lj<(2&vmv)w2Ib8MAnTCI!sr~k`s&5`H|Kw=i`8BC~r|Az( zGwz#cxo@yxXknZ+u{WUiPa5n|B2IAy0M;M@t~^M^gpC*1BoJ1NSt~eiP{0c-z-tn# z0XVWD(jZ#>XU;h5nG6WTnpKc_YhoJE3h3b~0o;kCxNH2sR)9zVCN=g}ZA>qZDZEc+ zEYe`phv2xAZ5X1s*qAiEaY@DWPtgVAV8D{ENsk_y8#gjLc6CMkvF3y)hHGA#k^Im7 zMK`wO-dLD+Yrdm(X?n+o?C#?g9lP^7kCk;jG2qUV1G^vT+i{|y<5*qSBYp2YHK_BU zKAoo;y3RJ=eQ9{t51u2e3<|USRb6N1eBl?UjThCuWTasD>VV!Tf}uv0iB4e34ja@39fNV5$|v? z_W`kd2oM(7dARRm1%Ttqk)0BbxsQ|Cp%1|=sKOOhpB_CdJ9cqt+=i;SbyabP2E@NG zU3d9t>CFw9Z7ZBz8#23gW_NB*@7kB!xhuE(KzZi_jct!LwO<%~?UkWFygcN_JL9@v zAKm%tkXx@be|x^~kI&WLy3n`lx&9rGHr(8tcXht=@>KIb#~J=UT>rNbhVLd=e_Wn^ zeNW-dGkyO4c-2!Y%sVC|&1%$TriQ2LLvX?)2S@<-Paq4zk$}k#(6L7WbnI7HE>;~L z<9j;|;Jva^gdVxU%7B@GPuZXVt15&07n8&noN$Xw$Q=yHU?xxt5^yW%g9CIz$|(Mzz2YJ;Ww3;M$4B+#V;5Q?0Tx{_&OMhgG$kBR(9?z=-imqz9y|}cYf#2yw0up9oq`Ko*VG( zKGz$ot&c5AIkm*`;zrLOj`-f&o%ZfF*O{fMrzZ{VCw+X4=%}Kw!wdmGMgWlcaKE2pDZ%}f1W?Z2srm;X%;fq58 zK!9EWU8Es3sdt*8cZM~{Z3?m_2YD?)*{MOrE(}WSV6^w=faoh{uV0o(F%96rUA(T4 z2@p0)6V7PJ-~^p;s}o;5>&TSAfH{EB1II6BJ<*3L&}$K6!kN<)x_ zd|PCpJrXkVQDBRlS)rR=u3O%axM_fH^AO#M$(nyXR(W${PWR#Ru8sM(XF1vzd+r=4 zZQq!4^M!%GzTa_tqGj=b9{ZlMQW>|JjOg`RXdUu2U z>n#~qHst@jEaPg6>(V6KKZY4U@1y-=Mcf~&HD8W2|Fki$>&@YRe7y9~65Ghyq%vPz zO-_7sk=B}shZym?(4y^S*Y|Rndby0fGgE@fJ;5dJV22^ZX$;A+hh*DAa_u43q+r-% z@3QD{kl+XrI~8{la9|CLAVVMlTuye81C5;f$}S`_p%8P%tp);6#W@VDfhuGOSRZPV zdf;{spmE;fx!3*o8n@*6<>yxDjDNj3`Lh zG*G`~nEud|q`yC2*?y?BYiH4&ZN+W#J-24temPRrxu>M-;;^^3c%Gl@7+t0tU9KHp zlQ^L|acaH3IWHbhUiS?#%&bowS`7Urkrtg)N8dT{G z?q3knkR4i+8J3zH?l1}}NDD9Vgr(|34cZWsR-^%EVWPNai**2enFhee*(!E?#^ z+}T}x_tD0#X9j$7DEp;F&aK0(Ro>X9yoCM*2_wrA>oVgiJkd?ram8to*zu6pT6fey zZ`72$m;?P1KHZSf`e1GQgLNJID>~NXUYl+E`ykzw7H8-FiuOZgUGI;-u+zJ*#ky>S zaYoX>sLUOOCnG$F zmbs$FmTFe?*PobX{`hb~$AfjhoUH!$@v5%1z8iC`o$E7yd2UGO*}i{1f&@68nCU9_ z#1y7Q_bEogUK+4(j&c6rq{$75%>}X9sl5xFy^GR<$~?iD8J>j;7hbq< z;U)QbS@~SNco9knFTVKVi4!LtdgvjO4!5ZwT*`5Vi#w}=FR|tr6Diw@~j)DA5vC1nc8^bH@j93liTWDsL;XIb#38UWCXn&TCtl-o7TQ<6yPE2Y(KfZ%V`pz#$xnIO^0QmI?Bq z=D?^4#vy@qFfczMGbO@p3d8)xses(%*(3YsCsd`!3@Ok|s!UuxIO*%hD%*FK+`=xg z!rQezr*)3w)@*y*=7Kvfjr{7d(zjN-_l>cZyQ2X&$Ym5c5VAf5I}c=!Q6zxmGl!O? zMUE_p-8ocuNtRk)WkB5(c@(7mJeADEYLV1nth2g;CuYvWDVCnUEmcXw|q zYF+5=*iqbde()!!3ZGw=c5s3%-5e$lc7eFtBsepH9DtAmH?E9&u^KY1VKv_9+4b5t zw|cwJ552kEcWZ{@r?J*cqs`Y^Y+YOPIydIGKU8yeg>8IYLQ{TZl`jN0pT7BF%>|KO zj}r;V&d#1beL7}6rawR2i%y?Djk*8egAZaU*o{#s`f!sjl+SdwB(VztMB+$%1@6jI zF^d9XDKkS5xM(2L27=h`c?QT?55SoTRKdeN+`$38Du5Gua1x| z4^LG-x!Ad8hy_?90cil5=mT^qq?fW5?bzwnpmTGY>Bn={E%BKd~J)p zKaID3KQQU)L~F;otoHk|T2EBIwB5aPnzhmw-IR+kLJD1Bd1;Xzmm@tr9ml|wDO3ED zUw)VXpnvAf8Ro!Yj!8+5G$)3c<;zDro!Rx`KB^{wcyVeITtJU16b0^b3xb}+Sr0A@ zlrw<1(;Ecg8E1f+0D->p8(~ZUPX&E^EOrPrs~zw4|0Wp8=M z`uxt_#dlsE@%_cd5BFz}tJPFzhIuR@#qRJ*Uz9t|o}TW(F)(@ZWNbTcyzvIm2gfmh zA|^f-!4pqBarW$4rzI{WIm(r4nT$OcwlI8kTYwIFU+cIDK)}oGQ`u+S&_QVJOu)`V^zng=9AN854uC## z;It-S5m=HUEJ>j*lYbH5K8n4FIUr=UvL%Okts%8OaS|lO ziFZV1t$cSazh+R0lUgkTO@Irm1;kR1Oo*$IBmk{$LByR|6bayuLjg)P0b&J6WXVaC zxg)_B1rXxEjZI#hd*MN5YJKwlX(?YnQ`hy%uaYZlZkcnjC_sGZ+-(!MH>u;BTkvI(C*_ z8D#`r9iQ^gX5E!xhHK-korkMGd9wbAb>2fQo~e!IbZc0@g2+C3(P@s9w6rvj$MgS8 z0Pdhj09F7#9-Gc?j(3=%ZOIWhiqnk2V=975-697dqoyZT17FUAh@e;*@@fPqA@elG z)P@E{aIOrl2|$m8iJZyp3r(0gIrrsXtO4|qp@I`=LQLpMD(Hb}fFu4`91>vF1uY(E z-ZH`b`v*(9-yhrc)PSGodHy+E|KnKGtp(|ATZ_8R4f^KEs^9O+-#SLzg8Z}IpMWqt zljFjZ;s4GD>q9INJf@+DGhk3j{L*0}0XJ74=jmdUgN$);6_`_2b z&uz-yGu^d#h{K?buo)r?JuztxtJCRlyWLCxHXopm-5>i81bGV;yAT#ZhBMKfn&2?S zprJJ>%%BamBnHpw6EvY3mkaUIRJ^#>hy}sNG~npRUHKvmuo6?;Q<)*L0wmlZV1*n| z78{z(0R%DMl`~f6KyE>>CiDVprIv{iOG#M)kU{dkEM9111q?3H9G#W=;zs+8H-~mU z+;D4U=J$j3mqr?IElh9QT-1GGIIf{@ZOnXjnQvH;7SQ8K82EC#_ZY*x5`DP^i4`Cg zfj%TNHLSuLJ-l4AaeVU6PdDF~@3}eI*4pB_y&(PSNK@zXtnSUl-LH;$Vq@mn`?8-} znY(tZ%a9o5Fh{2vV{NGxhr^Bpj2=B&PW^i)FgUg#Bmn3?{`lhs-lRN_)?tprBCzUl z5`^P0a2i8qHwMpX3dR$t%Ot+@!PBTora@*xpvlP&5-Cw~02$Du$P58!6?brwKoSW6 z+*kqrU7qK#vIP-w{~}P91<*&4nE>HxB)-oPUqWGm1ZCSJH;ysBvdP)`+`#r7r8gIP zuZ*|;JTdh~i>q^cY1a!w-#M83%nJ9`@wOe~oOr1AS;a=gbJ(HBu?+6te^L`e_=>`p z5?-AdJGMr9Vqr@A*?vDyvwvG3hgsjgJnQxh=iQA(zdY3ZuZu%>%yMm>?0#r*?#%vn zpFK9k80Sh!u-j6&0!EG;3G})1-~;sWId$q3R{#>wRIJZ%=+MMrj!iWn2Y4=vFeQd# zH@k0GXpTK3D>WF82)J$IY(N^g6eRgq00brjQ=5sA`?DW(XqX$y;6NV$3S_YYfIg-_ zkwreh{V9<%oqCc#A5@AQh+hlPibc>1!DXgK?wf3WZ+AxL!;S5$bFPlJT$^ea37GD@ zv%jkA*}?Db&pb9St=JtsqEuJqjp0cP?w|5Wf;*FgA>d%g)izZhlJAUc$cdZQM|W|H zxBW;BE}%b;HFvGb{`bC$?$x=!9I0=8amd;GygR13H%&}mJls9H&W;n+ovKMOX`N0x z4q==DNC0qW4qklm#lQpr{imLKYGAp+>qttsYjGXIl@xoC-4t!sM`1@ASrIX^JiI0| z%x(xVYJs`=){$v+cL$ zIJ?&6{O_5*|9+_Hf8U<;*8YOyb3CUP=kA%2wR(JJjwdOu{g5KJ}PQ!!*-Kmat)10J~|6B1}K{pFM=vB+e=1_G18FUn8Xj;qrYcoGUcao*IJ90#7% za6E*WbRjtKlJTq{zehtF#HKH=J%CtDc8M=#URbepGYx{2bpTmZKmwG+T0k!o0HC=h zh&Zc+tP~;3)1qf=gjfMM1FVU`qbhXUCtA*}adbU1@b>boe-6=KpJc>y7rdb*<1ea*T(+xmqlN`HEQRo`q6`{2KKG&*Hk^Qxo*_3ev`)y zoj!TYm{G&Cv$OCRjL*Dz^Dyhh_Ad_ra3o;={{6dm@7}X#&&iV~S1z5qeDR!Ri&~a0 zoV8@ZOwiipvrp`py?*7ar3+>(UpQ^qf@w?UO=+1isb$8*$>T?+8lrF*Aabk#TugyA zCNsQ9(6e^5`EZNv%QFp~M`}8^wR|~YUn;vd*|Ir zU%WH%ch8O7v2Mc58Iz_>n=*U$?1c*#u3x{Nm>xfVyuQ9ZJ3BikCkGnbe3$_BN%+vA zL#tP>-nDDj3opDtrCcQ9gC%m|!i9?$FN$qT`5=YRUKVt`fTK*CCJC9D!|<>uo@U)i8w&m=>m!4~BIA?lu30acl? z2WLB8*qYIOw%_eV8Q%{|{CQGJ*V>$4_E+55Ro1z`>az!m$CPXF5P+Qrw>liN*zvLL z;3;};U&GP?#yL$%$7ebY&vNdY?L0i+@xjr8OD_)n<>IKj57c#SE9lso+x=kuokyFx zUmf+?g<&6@9sbedqt-5+Fm=kL>C>lUnlD+hWb@|D2M!#-_JSPDm@y+SFK^tqaex@u z5nP!CkpMu9Y~dOTnM!VwH?mrkL z2|=j>u>TD)PGf9JObM{&I^bR;aF^*J`q0Qc$=^>BZzF;WoRQ@jF(>Ayy>%e3`*ic| z1>URUtk+x8y0;Yka=5B%Lt)q9+Rq;-SvTA~v?!s>9i5#TjwS<&;uj1wt{!PwG{|sZ zddkU`l;>ACeznc};@;fhB({x_hv!`#@Re!LmE&23)x?;IGd$|Mtw_ zGkZoqy?^Y+6_ch;ojPmQti_8LuUfSVGa7TB*PEk9kM7*Lljy4n0IZnc02DH+Z~~)B zT><3yzyJpZ^soo?NW-(wJ`3aLo_h{LT56(MCoZPq$0OyBeDOL2WH~{BFHjPbU4pKj z&$J=IOc>!zKmtH2)|AB@mokVGUt~pAAyqg4q_J25$N?T@vr;1m6l)(`n=ZD{qdfHeUq$P$5}>KXqF5yoL=raw!pS+s%h^m ziR;<8`K6vmTt~Y1To&`+67r+5Z@bl--6Ld~z0L_Oo za0;lR5&}46CSV^1>cLc~wCD9>enOeIj1ffe>52*`nWE>l(jvZAgD zzbO_4;1-B0&tHD%l{*ru)WqPE6E4t48gMg9O$r%Qs(Wy;>%#|1y3Y2ywaj;Y zhO={BUf1^G_WSd?_9FqcHy*COe7gJ(M+<*{s{HLe*?&G=`Q;N;Uz{$#^mKjeOG7%& zHKSqYgMB)W)pi}LyYs~0U*4X6_u|-JULE(#yHo!4V*ls2=kI9Aes6!(vMKd5rjDOB zWx|G~lNQaJ(bCd_-GAA#Wjp|ofG3}P66gbKPIk;G zWHg5*iueF`WDyBKcGFUHmPBzE5-+a(zpf*uGJyi5{$p022h0IE&?of3997~!G(ggb zIN_#DUo5KIk&tDrnh#Z(7~6YTneOOZ$7}nuyPp}@wWs{+jgX?b$e0k=7RR!i4!M|A3q-Z&)m6lvH5J@ zz8&ZvIdTLEz)p?XN}z!wutqY7I534C97SrtWorC6Pz8J-(~=1Q`p-P`30qP0f=zJMkQ`Merpn}c?=L%5`pGYAkY*9ms^%6 zx3-j3RaH)yFk#XpvHRn*Xwjnk?z>Oj{Q(f~Fr2(V5a?q;pa?+aZ1$hJ5Crg23Ai!$ z@j;R3;{!cf(GM~T^pOLc1TGxH+FIM8JqNr0%9Sg(ZrzG|Jx*Or zf561~4k+Jx>#eunew(`ram0sJgjfX~dK4i9emMQr1gJT1rRuN(cnuW~VzJ^EdqG$P ze9jUOOGv?)80J9Slz0-zqObsQnW&2ZXaaHIi=w&$h_YG*≷URU|wQFKNYAFG`uFcYaNxipLxx~k%$zwB4+Qu?SiXEY)&$_=3LwOUn@Vs1x?{%< zoF6d82U{7^i3=4qSXgV;tO17-S6dt{H~^k{>M5su4#1;~_>w^Wx-tL-xWrS17{ue3 z2~byt*sP==v`~@Q7&sys>g)zV13fgXy{C~fa-+UA(#7;z)K~X^_V~IU?1KcfEz9aY zUe|THsq3LWUB_xW4^{uLyL5GP(wl31w;yWkJY4> z*|+Y?xv{?R>i&|?=A}L}%=q}Ew3iq9=G2?V*IH~=Lu!iImYS00bhun;>FMcSuh*x1 zva+)9%!P}8K|w)LQ4u&kC}N3VJHoz%9N+`oF|PqVGJ%~6_t*0B^0KlraC|D{2Ss=& zDJdx}Ek&lOsjaQW3gb6uX(1q(D4 zvs=zeK>#fUa6$5Mf%-`KB^u>~=$_*%wSPR42gF;KW!`FWw{I$H-&NMWtGsP% zNynb@7Zzm<&ySnipnYs{TI(}IJ5LYlJW}1Z&ey&%w_{sT=e~;WQ;i+R8ZXW8T$<(i z`&`FcBNI=Kx4pQ~cY3Dxg{9>O5t#)~^31yJBHAi_i&Masg6Ye85m2RBIG@dehx7onF#prL^ciZF|oUu60d z5Y-dUw7=S&-T7cc>k{9M>CPK-JvZiOT%VVIdv#97(VD}f%)|0x$Ct)0YSzBEyR7x$ zK3xy?y}c&u_Nt8bO}SVNZClEIo}GSudG^nXd_Rn}eYM{A$V}^#Eol!-c0D*JbL-?R zi%E|hSS=>I&Hrte$K&BTzzRSD3Jda!iUf|x0TAQ|o5}01z5LP(&%F4;bDaLz*-xK7 z%@cdWh7FkDnC$ofeP#lggEy`xnaV<@1eVB|%@l_O$S*>~1(b6f^BO1vaexDepdqjj zV1OzJLY4_b706#L(x6;pSpf}kC)}L)yzoGP84N%o0g|9cEi4_$A!k>lwI8c$TatNm zZu(D?oIj4WU7PJ}-%)aVW8O<6^esg(P2Q+crSTK06MlQ3r2TZio9pwg%}KjDG3ClQ z%g{RJ{OW~gUOfK{7XcE0a~qrc z=FOY&?3S06mYJTK;Z8|UGkY9Hw>>#6RqssEIjvf|S%dj*H^{y4+as#7h_f4mqj-H;K^e19mEr85jX^H9ssehrpUSAaMmii7FC`$iY2>$R1W* z(7EN#j)N7g3p1|G_FSIm{O2(1)oFI@@~t~c-k)Y&R2tJaJu=@Oo@b93RiSzNP#GS2 zTaQ*>UzK%rhW+MJAMQf8*A-lz>iB-R_3|WV>yrb{ZO+^^!*OP1&ViN;t3EnO6KPG3 zN;O31do=w^lLwb453We=U#f2^PHrqlGK}d?v&&(2*esZ^Kp#tC?yRZ5dhLaGUpn{7 zOE2Ii!^dMhwJlk)WcBLRn>KCorkUJ!gUgl##2uFSR70#)AC;nyw2JR0!;HER@#aUq zf|eJ5@!Noy`$P=T5m^v5oX5-oiac_;K13PE5ALsi&y)FB~&cYqj+%8Lu zUK3$Sig22u>hqF@RwPgAV_Gygbg>m62|&75G?#{hkUE+SbImaGX$#$=Dj z16L64+1Pf(wMXte0Fkqv(6dN??;??Q)+q=ttc(m^MC7wOw z96GrPA_wcn*iX$*dwP}q%F9E#FOF#4R@kw%y8MVn%X!y>cj zBNF37^$8*RgrLN@-nv+jnD`QRvGX8!F@+_#M3eZcvl(E5!$yEkGbwQ5lh8yofF0XV zATa>|7c$W&1y&Jy-A{RqfN%W+i%Ui9SbiNrt)5 zYbh_x9$H_xU|8{%Wz+D~d;a<7G57Hpg^T?8^XIYoU$SY?h$miRhsjHUu#!0Ci6jWJuv8Mj@9uF(s6WPnM+Aw2 zvbU%$0}+P|n?NN5RTgt!erZe_O?1z-Bg`M|&$@GdX!pU&TXP)OrlsCq>iub&^~%)L z+lQ*2m_+e?3*pYh{l=g+e|KTU;` zv|IDM?HdZaAMgM5v(1~Q7#9pNEFNN9Fu=5EfO*SE+mHh7xDs8xPm^JdPq%7Dms+RP z*hf~_N7iMn7*RO2f6=t5ldtrh`xf?hyFHLQIT+ zfOi|fArbVqC(5W5KnDm!9J3xp+NcB@w>k9Os*HD!7XAC(DR)oRw=eS|0XOHnIydFq zTH(2UwCYa>vfffY*j%cg%ZxN?3*id zuTFJbosfE?#eHjeX6J+T|MOVo)*0sYV@+Ger7Rg>J}}O4WUOPufRsvCLjSD9`}^5W zj89+Q-!Zk;zHm_Xy3vKjg?W=EPQyZY11vyN%5gtiM|%NOX$VUuIws)WR?9y1q}m%%pwv10cL<3paXigh0KOD6HpRd zVgVx1;4J!~mr9_FY;n(F6KHr0pccmEzSzfBXTEc)^55@Izx!Cfw#DhUm-srjmWZF? z-&xT1P{VHz<(^(-zkj6JrVkde$_EZKn(>z zyLOFq&u*|S8JM+eLcyTgf=QDm@$QcgmI8%`kL`PS|HcOnY&(5uOI4PoIp3V^&}OE_ zTazMnalyJcH35D!5g`!=f(V#0N5NX|OO!znQ1qX-N&bs2lnFP6K%i-y+l!rDJM!;b9QpC1 zm21WuC-+IpObs_^dM7B()xI<_y-qI6z4UCKug}%AKGFB~_Tn2WvVNYQ{?p8~YjZr8 zMwosapK@)1_tv)Jo6q)pb63`b)6Fl6Nj5{YQ5&vL z2-e2n<|C#*=e7EcqY4p_MXi8aZa&bEP|E}e8%eZh73|@VivTwFphN)#0YJkD97J5G zXBDrTBs2u{wB$+dG=`3@OZxreHFw_}fBQ)7_2rozn@hX*mbY)tyK|zt>&d=n-kU zb3H$dF#a^hb#p_0>qB*a*qQl7c5K?LNizsC`^vIMzq+g9gCiwx9>{9{aLS!$hj$*Sz57s8>+VXdfa`P9f1Hr= z;}qM?wYhB%)_-@j_{(iMPfc|k8fx9rY}(%6^4J*XljGf|kb}`VQ~DN6XfByOdzRdF z#OJNoUwP}bmp^>*%!?;BJ^8@Cvkx42`qaMp^(jm0ElcW5rD^d-O(-s)Sc?hr&o^*7 zgMgZVo8WR@%Nfl{&8+wlSGFC0t%Ms@%#cbV0ho7$6`*7M5YQ7e=!1x}Zze-jNgJBc z0K|hKHlnB95IV6j`8UT4JDwSKeP_k3jrn(v*W6g?yD`skd!?uCc*WcMvXFokBQ0|W zm`7LX<05-90m4;az9V|z(SO-k$D`}BUw^pn)~}}AI?{0G$wAoDT9@biJk9yT5dHUq z^*_(^++35}ez^MQ#~R*Q>V9>m^O4c1`v+N`o8)?EwBxl|zWWAc&Fi1HU{K+jd6Qmx z{@iOXUwrMAmwx@?**`pg^fxa&eD=hiv&VNmbz((Mb3D8a%4(km`M|y z5Zz1t`x%_h#1}Gf6r_MIpj75NIE%yz<6^=H7X)$?!9k)7_(&K$@_{;G&0~kMk_jkj zLyaFeiJAnir^6VwZnERor%F06jJ&b6taW3~zaMM7vD|%QzO!|Or|n4Ddx!Iuk4m09 z$T+rEzhI!XAT0(B=|QAcd7zWZo+i{`nh8*m1rdGGK(=9HI2AuW zEyE%wp&>2|4rBQKh3OwWP}2Fr@SEF9IuDiqa&ctG&cfR(Gg?=ATMra}bgW?E(4H^R0U8T2jCEULGOf{RhH#5c{P=Bhd~e*- zFh-7@aO>o~9-w35^L9@e0SBTlTCt&2f&`4pgysNYgE5L>vl?50XsG}SVv!oOgh1~g z6lKEvf8Q0e6}9Q+u%-g-l9ATGoU8A8ab(Bg>O05kZ*464<^1rr`?GH>bhYj+{N%x+ zwPTY9muW^-CE=cj2*l!(xHCA>9VbLYkK}~lK_!V3tC9v6#IJ1DzO}^s)5BH&TH?Jj z)A^4<`tJrL;WYkXxZxkelW)TRhPT0*b&|AF0}`glOuvo0%s*HriZ`R*(4jk){!gwB1Hox3aA*5r5Z zukPGka&1o9t?dP$K2)-4qG?h?l3V{2Yr+w2u@w;I_-*9Q7<@UOa+Z(ceY)SiZVfytQCEsn!d25d2#3;)X zlhaR*PCqf)JFzNle3g5{;EbKavljKs8eElKTbehtE`M}GUcbirqlXWg62ncpFiT=c zx-rac2(={!TeZDYb>fE}RB(i#;6TIyJqWNOVA>FF7;r35a@InI29VN>*aB^T1uWPg zkVG@7yq5|2`cpt7F8=->$wC?o3Bj7EouOul)L4Bq09}r%LzFw&kaZA1zLd?FEPI1^xvo9T9zS$YxDYt~LC=K879r4O@pM zotk6(>6yM)?$5crEUWw6z|IpjxA#1$85mXPoPl*$3PG&WsHbZUQFDm9#%~+0g*USL@hKNwJ^XLz(JBQcmao$ zIqP8|+9*4Z>KBt&9#G;vNn%W|${yy09=Q7Rb zRl2LQT&=6Ux3}ee{9whB5oT*rh@LY`dIm?=h(xSEgdyXDti*NnZ_5`F5J?>ek{*4^+RuHsj>P z)YIeb4-BzBG17i|gyY2E)bU07#w=Z(Pdm9hxz4BYTA~UZ*nC3u@x7B1db^TCO6`#r zO>dx|6f4jdSOaw4d9d5a_c`2uK-_;&<%dY72SuO+0o2bE52oHZH=tur@vU{f8>=#}%=27bka2Zh`n8QE-?n62-CcS4Oyh6v zPy54a_n()0e>E>-aixBBtzmwZVPKASNS=01b@H$R?dSsSi2MYLHaOA$gXX>52Jx42 z97*D@p8;Ir3j)^QC<1o~-+mo-_;YvUC#_@-Bf&KPR3tKn1F<9 zGwiKvd>w~M9$oJCrA7cvI3x+&Md@s*kX^L$gs zUl;xR_Y1mCH??gqytOv>#D^{tJ2ml;mE0&;(!9)U4<{Q;0xS$rG^!_uByo*1?FQB|5AEC&7RkZ2j1I zFl$`Np&6#|h1E&lY{>m~N73yQb={Bl>o`((wZ(O9Rl%Q2HJ_Fwd|s`+I>B;tfv5d& z<%9F=sY$`;1+Egs0vDM;#O#zqFG zs7@YRsGV7nI3PQ|$R63?jrN(tc;OL1OIQu@y^3vNMX6zCY~sqC#WfTL#9A0D>i`DC zSLGl}La)UIv5WI#78k}IZcO$iiyWW{JP<~ZY@px^!XTkx9SBw6ss;jQD< zaW!dCgM4vMPIKQmH}vMt%Af8p=sebNduRFe)j4guD!*tnAO~O6B>p(gj2zs$Klklr z&Ky$+wpZNnOxS1R#ovlzzeJz@*&PW*1$_n})`31D*kOw3Tb{gUh3}8g_PhJRw64ec z-Cmb>du`s;*=axF9Nt>|*?{CP$J#z0o%+Qj$EAIxU#xfjpJlcWmZfj%Z)mAZto6jy zr^hsS#UH^gv_+ITBLOs_1P837Vq3UL{^1V5ia3z~A}%bM5-Fn!1|WY`Ob?s3_q6P& zJvG{LYp7QrTx$y-kRC&jNn$KW0R4(FD-%Cpy7`TuRGT3szz7H~u1q>QIAu+}>EUs% zzizAi>OlRc+baKOW&W2NOTO4%{*Oa-w;pZ&=~TaOmgRpn!TG}s`=vRKf6Q}!u_Aq0 zadcTqs8Rky1-cmiLj}SoI%2+g2ti=)lyM~ZuVjc;#M9HD2~M*_j;J>rUGDk#sm6}i zN4B4=yS=fn^GNOO&Bd1&`Tp3T{c4oyuft8B^h^HB*wmjMt^a0M#+O^YZ!EAM9c^0H zkUTO!VL(>g;GDQRPjsdkGrc#_=f*;OQ?$LUxUk7Ts0UI(SD^=CMx)`q_YhG%O!2+O zWJEkP+**?H~Fk|E5Ow*%asH!&R3bDE`w{&)M15$6H+EiW6!*(Sveg#}>w8 z1%Pn(=N6%&jJc1kiNG-!C{^;KuK#Gyyl-WW~Cik==js)^=(h~y}i5i=at$2Y)SuJt@fj8?JHR^ZxzPAR}%ZX zzDYl9FaFol4ezXRJU=t#_&Do=TJ79wT}xFW4(Ad_1ZEY-DB_U=-bE(}I}kCDA9pcSUi*}yiVHbR(GC0KAr68^ z=77<_l7u3>aamXsf|{L?qtl~Cd!r`#qNnFX_i=`oSVIkX%!%oR9Qd0kPCy6=J&KSd zM;F*(K^#B3gRC?ZzabkRgnZqadH7p)&eB*FY+r=TRM{BNcF8*?~_2c@)H*#a& zDv0@2QOx`0@qe9cyLzJThsWzb+2FX?V%j@Ad0w4vS))GF5(XTxIvEB!LXn*Y65>Gs ztOXPx2skzhEg|#rqX)Yqjy3Dgk4jln64%!eo~n`mo{`d4WJ?w~G-%`;4*(jnnD27R z^UGe6XsozEf2uwGiiXN_6J3M&8?2y;l<>aJh_M+_)3RfloDubQBp@tZAB;ti9M@ZI zqDF}#ISJh{_pGJBCTs=Huc_fG%@kJbjhQnz`SFdupWhtS_IUrR_vij&mh+P)?Ykwh z?-XGX#C+UG`{h*IUuHPI-dymv6UArdnYWM9Zyu)4wS`;7{v-YsC|hEX|0RSnK=!VV z8vXLb23a+|oQb`?$-(;@bWaVpobG4XS{gSiI|if9F@*2{haVBGY#TV~#s5$M;t((f zF=lBBC5_Zt>P5!^CxPIK;EzuVlEgJ1l&%jMhyN2w zc=o4R_64p&0D`4h3P=EqWfOEKUR@}Y27*jO&n$c7lxF>j70$n%@7wxR^NqbFmzR4# z8)kmLQuFK5*x%K~f83z?s7CWaz2=WI9N!!+`}A1;OG}Mgh9wOyh#OH9KfW}6U{*|H zdQ_=B+^G-21Az!knY@e#z2kh&G=}7vLmC`mxbw`+k9~8B^TX+`jpYfGGNYOt;rXUe zJOk^*KXdAzLlEFWkdje31_e7*fcpm~38TW~lHYdu_0R|}QYOd5XFwP{1$H0}DTp3SXdiBrz&n*Y3$(a=o)uql^c%;;=2LN?5gtEbye}NOf|mKV*hA?`%lX=Kb~cOYLISsO+ukL#1QAl z9T8GMkb?U$kH2KA@$;d^Px@#+DvN!$F!q!B1T2n^`z3$g;{M@4`IkqEezn~G{!;s! zi*2tgv_3N}`OFl{Q#0+av^YOomHx#l-``edeYGs}hb;v^?alvmnd{uJ#D^N=78gX1 z^+k^MMAW9@mLa}P193Qv4THrHR9Ha%DI+450}#c4{gjzd6TqRu9RyWYeWB>Ll$`+r zbPoXpWBH(<{1XMzUKNBaqg2BMF#%#<3djT#05e3zF4$b1J?u`E>EEag%1etFR2qNZ zD8v7p?bGq*m|MqdF0ak`$9&J%6RdygpZKRH?MF4bUzO|LDb~DGqWP$=@ymI>@0RC$ zwhsVrukFLIzO zVt^|m&lr-O9D?8(2?G8vu9AQZ|Knf;mvH}wtRw>hEx|D`&Q_2>ApmQ&EkR*h>ZOhN z^EPp$NHIs4ErO1s2wFCTKn;^2roWWgJG`+Yk_do9l>`AKnkyVTxWf=!ov<{pH^+_5NkD;9}i3U-5~RaO~wxz4Zj^|{_~`?uaJfnIsd#b z_n&KXzh9H{4?($?Hs$`XE%#5Wz30Xo&kffeYD(B%9oOuPs7ej1cZ4@N!>epzNJFVb z90LeU#H>KUcu-VP6%{NnbTJr2FPlLo5q$wPM<{{7l;monN45pg5(2wa2?o%>m8uU! z5CpfhAwgFCgZ`@uoMD563{EE;LO|~@qZ8y0X~2#&s#<$$f$h2bGcIn-`e1j_PiGpg zKU8yRU+LdgW&drt+*_7sf3Yn4n{|cXZ7sQUuBjV-J!C9KdAI>;S~iw2&G|0{Bmh)Rk49{S({N{JCR zB~Duq(WlJzLUTF@33~z!s(`7uI`~EQ~mUKv0bRq;< zMN0}KHW8u1r}S);znN3*jjqXv9*`T;QWgKeIOB&aU0?0Y`Eq;q=R5QMxFh#}_7weg zQ`Vcy-7n0yJvPN~Y)sPLp}Gf#CvIy@m{t%wEiZOyX*}+oxC>3qj-H(xJ<%6gXb$!0 zgNrPo4I&v4`q*BU1aWsFN{C7fN{-Gy1R0yC<9IkcbyoVvrW8SJKmo+<*gvoUbU^e@ zd&ocvGB}TSXzp1Cq{NS)^vR&v1vt_m#vp@)SzuqHiPDkaGCXi78JlP;BTSIqAfQUt zitkgC;(D1iLC&P$Tx(cUdgQ3w=rQ>*Q!C;ZH)t2sX_nM$7S?G-7sf5A*NrQTTV1DZ zDT%9fMpoJ*n%z-@y-`EGQ3KtPL)?+_${(C(4y|*9SKGt!n2DzxT)UHE#cdnJI6;&V zEypejAZR%NAq0#~9V+yMM%{?P#RwIT|35_N;h#r(pk4&Qb6!!Zo*|H+L=Hgzg*%(T zt%yO&Xa$ZUI2tm4YDPiAkK$ZZNlWyO7$ED#zl7Y&l+fFv4a!dqpH!MKwkW>V6IBej zGhzm3#uTK4kIRiMwS~L%A=&28YDdJx?3i(xG1Bc|9M zS(z3!HZLA)#hegSloIYUg=U#T8(k4ob7ID4Mcc(s5cNvc_I4!p&NhbHv_anFU_NZ( z=?8$YBY36&!bl@S1uPOi1|2XeK%*iBJ)Vg$afrKr0FrZ5w8R)_Pr?A8M_cGQ@ky+O zlJ?92i`1ZqV1#o8R&e^ETY7*7GA$X58XIjOh(Re3Qv=*#hU)|EX}~Vn7KA~mqtit9 zv}%K}jo?XmZJoZ_8JQdhl!J>?!%I@bn%$A(vZC=kj1}NY3c`7SMF8~83B57>P4T^T z(c+O)#3=)YPc;}|0z$u{j0!al)#6?P_&!ojc@T_+EaMZTjF3AC1U47FN}qHE&ni*R zXhf&1ReGci1eF3KQCp#F$o}TC7DYtGsZIavh?bDWG?D}1SfB)PC86{+D9vZ9MEVdCXag82Rt(;v_q;=~HzSXAe91tofc9^>*$ej`O-GmtP17(CaJ zj7AV->Q#Hyk{WP=D2{JTx$8_#d3I8Wh+QHAF!*z|2y^RY?q95x@x(tI(OK{m-yy2F}?*4oi~XOtJJE z%OV638{(8PP^NPVAPxb9I8g-mPhnZ4=3XlWUkGYLzl{_E_4JSw)2qscCxFW!aWxK=MY@%GaP~`A)I%n4LMfg5gO@hyh{(B6R1$jG zJ7m=l$W9Zddl|*m>YZD|40@~j5BlCwMDKIJ!EQL%o38mE2m}cOC2>{WL;L5mIWR>3@ zw<-B^5_t42u!M=9`OpLzaph0w4JB;Uw4n(iWT=oCuv(-HE)u{v*hciE#37oI2aFcp zDKKbt45~7a`>~T%Aa3-OL5v0@s$?ik0Eo4!TM{%_9IzxogHS~m>`U5n0zp7jhz$fp zL=Ke2%2sGDs+2QX)k7wZYztyhR7si0K!e*3uKDOx8!di=BY{8ct#qwgGBy&5LZd(r z5<*}CM0;fbAeySf6ActBRFAY#1%^u-0S%|H0y+h@r9Fy-QWVvB!2~FMv0vz!A)XKr z=z&d8q_HZ9;V5a~3Q+r{PlWm(1D93cFlG~QVW5l%oKEPU$1MDS`*G)Eos5Szl-Wu+ zSCkM`8_+#1?Nk!3Wq;^~=<0gN*7epm>Sfo@R8JzR5KWe zzF_>HNkUdo1!D#vS}8dIi15QMKmt%iBAY{o4Gic6#uNnZDy-5K+tP+9VNvBEwYe&Y zP^AF!Hgi5g@Wpo+nOI7U(Xe_^KzFrz(WdQ)quR4rAaH+DfA1f$jl zwgpE>emgaK)~Ti>Rry~U+ORD&C{m9p1|>U&1|*8oKoFDxRTTVARQ~}2h|R$%unL5t zuu=5rm-bW=VgjcQhXAPo(|`gE=%1lNR*R~Vi-X40KoI=~Sb{__G6o?_KRCm{DU%R} z_zx=Bu|c2<)u~FbL@k{{AT;m`ClR57AgD(rYzPPBKvztUsFguL7BNUA*HGXH*@`@{ z6(_ieL53uhvP$%&bOgO{rI4zp6Tgi#Q_*J^;2@+;xK)NMyh$^mRA;&@svgKO9Fo8! zL;xa=E@h02P?g1hXyf;*%8Ewyiw3F&D_WgXXioUpC3-@yq66uT4$1u*-i4(xWtu^z z0jeMa7c{vyU}cesqO78xuz~`^0H-SvY5*=w1A-TqA~kc0Lw`{T7_w>u63t~g>4!xc xQwAU)b_7BgARbO2q(O}htwa|JU}5nvVW6uvQW(5&%G5oZqW@(!V~X znY@My01$xz0L1*O@Ban`ivs}u-T=UHGyovH4*(F2xeEXE1OSi)Y^0<>AZtfAM^|e{ zCrSk=DM}|7M@yR@765?!P)@3+mewME#AKJJPyRSNv_|+wM=xN;H_1rGG@ZzV9tNF@ zyN;>=8cRkx^NT#_Z_qRds3Tp6iK|tM07RtcAe7N!c9dO+uCDBSyt#SZt#mwZcx-z; z>ze#Z07xuhOG|@Sf&%}Ca}_F_eT1@_*ToqfQTJd&~VnlAH}Im+KO7X_usZC4y@I5)CX z*7doSOo_)m^WRRe(ER{fri>A*S;HBP*^Ew70RH8hKIhKLjEqb(cT;mCH#ZmOdpYRS z{nk-&ZB@pH=&8*Lv+6VYyyk6&7+^9MW!rEY%~FjVG{FKGUVr^Q%MS=DDs?1V>}khP z5oU{mmS~TybJo#G#Y*ev#3s1Icvp+)$*<|Q0*YS5-%J?_Tq~RY3SzA$VPc_C87{FZ z;?gH=-_DD8qCog?Cx@5F_Cn9=$B_w(DvlXd!feVKIzVo<5f)5)%*%Yj=>I4hXv2@1 zdBOsj#RSc{Gl~bCBhVvbQBJ=O7=9Kyc0aLG26%5XCPlk`Uh=(L_5I$V3C+3^n4qB# zo4~%|B6$2ei4B2*l80slBm5^$b_9?zfv*f=ae{T|C3yA~yOE zl|#yEu`A(7`cePQ7c8}lVoRY=zq))A~5emkaNu!CevAzOiCA>C9B2O%n2VQk$W zukT+t6w;g0vByM}Ne)OYF}dP0`oGuR==oQYEl`a9MXvq1#CWEDrhkU%0sRUu_qS|o z%;}<)o)jZ3zM_|`FQ*S}o7Ne{i=mTt1O77JYS;DZ_miw2--loTbdNZg)*9ywktz)M zhgOm%KgB8GD(EUv9$1c56%{Pa>P%gi=oRCY!7uBllt^`)U?4vYq_ROc#yloHW<93K zP+s^Vlvp?neS_}8^$h)t^&AT;^GE)VQV2_(M1gF9)OY!vHlUG)=8S?%lXKWal67yQlubd8?KQf>*LOBV{ z2N@7$a&{z5)p<3E{|&^^LeQN>beQt)TI*4U*N!15K4ucrP)=Mq5og-?r-{=p-bw`D^Ld z?yp%ZQtlywQX)oO23>OgI#M$IYSe0lGP}97MoIY@rER(mYOY2~-$s@q90($>f=Huh;!g`zO@q?hC9?>h^~|P)aL#)Dlm%OaQD~S)X1yoQ45>`*qhk* za#^zzasY`0i7bhm3FC;SWBg)oVg+M!N$d#ah%PxVxIV1Env)F0WxXXBy-RaWJva6k3i-ZmRX1NSv=jO}g=VvU-epCxpK+ml z!8T070+wBoFs*8OVPb)#Qcb_7sjd-giL~W;d|`@r`62Rr&gFbRdp~w`=zQ)h-Q(V) z@WJg>?-k~u5WO5-IRZXnDDEWg#}Mt10-a$Au%u9RGDju*dE$KHmX(+F)L^3ROEr15 zOf`%Hr$fHOyhHrj{2I>Mw>2vfX5j^&>|1Hy7q5#O(rb;I@7_GV<38WKYi=*@sh(k9 zwO)lE=5P03Jzo0)HUc`{$t$M}`o2vcW4v{}dA^FFPND1JT$xeQvQyU5UMYZWKt>>A zb{c-#C;6*W%tP=D_%&ZJ|Ibt|`$+9k?LqCc)8bYA)imO6q&wE)7rZZR35M!RrM0ES zrEMt=Ople>k?#kg4x|mJ(JaxNsiv#C$ydr}Z?`*Dw6P@$C!Hi7B)unL z&;%+Xso5wE{2naM-5a?|^zO3x&t};s^!VlY=W(IkkA*XRuF=PBJ_~W83eI*|t?5av z9*|tC41cOko_^9ZEfe#pbh8^TTZfn&o0ac`dA09Fi=DcizMb!l)-CUTY?bR*-5&C< z6fNCWp)cVfXgDMyyyP3wOUa$bC4Nb7^>4aa{d}GT^msp*2{(7@e*Xp)fQ|X<=RNG! zdFOa9nuE^|Rx6qVnZFYlvhXrg(+3#;VQhPeJ?2Z<^jpE|F@wz2yM3yTscuYc8=`lh zrzxcEr^a4Btgfr8vavA+Hqlv5ru?$NbN5B^{pl;mSm&Ry=I(^aEd*=@LMFsoCc z*U{w>K;gSN6)^N(<*w*H;C_kjgt1okSbAwaWn0Q0DUj}crC_FKw%HQnn3aW_`72A5 zbcc*sgw(CIWx2fVIdUgq2ESEiiPN9^%Ml|pN+CQp2W9A4ovxIdT5)tr3i3+s|w`( z?y&>+IZ(2xWb|K;@SW{)MQ&SAn_P{iG20kHS3;oc6U(msX2+Fh5{mw1-6fOQQNYp1 z(d~6#$(&l=2OLcL?OXfbqgem|B&{GVq2*B0#uoi5>ZeBqVWs-*uegQcFpXfm*2br(0GXGtm~&qf8L8Zr7bLijV}^?s4#`+2!x zd|01rC33izoee&FG`#$3mzQ&;AK|X||13*l=77BSyoGi2S2a%9ZkV@E&}`7AM93$| z4(3zOoUT>q+BIlNtSR@T_7hgBm*MFXjsf@0EMXmDK9^QiB6ud&N7N( z4xKE0)3kap8wiyB!cHf67ViiqxO4x8Hl=~^rh8h3{#y9eH!8wSje3dgqh99YGYfW3 zs7Z96Z}PHMZ4J{v5a8dT7yZNaOwD8I$ToM;=lPT1lyd8m z9lo?Dsblq*aI*i`^Q3Grt9eNm%Q6c&fZS+?lwZl}u9;L!76e*t=E4F<8eaYv! zXPuDe`>&aY4Tda3qS&r_whz`C97g0UUBkRy60oj{}`8hj$`kIUjJbTQv%) zEeHZT9QrBSUKN`(-H+6h}K zxB$k=9j^o$%iUq*hGk%IS9;M^p_YwDp+a01S@ILHcyK%>=ifqw?lcB$D8-{qxn9?| zL-3E9ra9dN$-Lt|HxRqPep^iTeJphvf+3wQ^J`iC|Pzax)k~6tj!!XedF*bGKDxoGoKW$7PN4hLai-8Ogqnl-L|b(Z+TH$Nqh`okpd2}PIWo}YWmYG0lorh!AI z^a8ddXhX1t3JF`Y3i^>ocZYF z47wDGI|N`nD!B6E1Qp)F*-O7;Hfe^Q?Ps*bD9T{+;k z#pD3oXh=>~WK(we8ctVCX`4 zO$i^+Wh(Df27d5EA!VOsf#Af6{4ViF|9>i9EcR&;+{bCkDs-_%`k-w zqlXroL4i6(@%~FPfN=LA{nrwe&%0itpLqU_X8f8pW#6Y;>!4$!5I72aUek8csEsoh z1f@9TN@#{76eGs|$FXIHc;$%;!Q1RmYtdFwlNOQOtbd=7C9s{6rkn z^8@@iAv{<9+v5Ai6Z^sH_IkaEU|NJB#w^QQ43+E_6JRbDvMJav*P``s+zTo>>`26c zdbwNKQ2x(E5aFvH+0|B}7Qr{mLAC`yPG*j;^50_*l6YRCPJr(?Xl1Nu?o6#y{F}IY zZcJ*m@XL(&!+c2M%|?J<;}evt=P0oV?~%e{24$VXMLOPQPv7RNrrm$dN=5CswU$3i z)=InkPq_{deJaYBnj{G`MRJo}g|}-; zcOSA+-y@tW|?r_Y; z%W!s~*@!??npd8aq&Eol#)(yQGHJn0#s8kChW!(*!dbKqL+yH4tl=FmO2hB)H_{|v z8W5bG8H@_I2)9)Py*5HsfObg(ibC$VgUg0{$4jFtK0|#^6)ScwU0Xo|(6}*T?^Z)W zR7lfb(M?8s=dtKnOWthPQjVU&5zqtw7(65@vMpDWdqof76VBH^(NCu8O#d&Wp2vey zh>TS;uUSOtrcz@od&qhqHs9cR9_wJ7fSMHd5aIS>#$@WL->fc&TvT}B_+mYIQi-0S zw%7OmWL`HVCB^W+|Navc3pBdfUu|*hVP#|cEUvDumQ#Wn#)Lw;x=w`a6*-q;+^#;2m3K2YeMd$D?Aw7wES4q~>o;nH4PfeC7@(J=!kziwCIhTr>zI?ttG#2%Lxr=^~ekxVy1w_sJg~wAL zd@S_$aLB@esJ`Z|{wuD2zByxl<~* z>Z!%8kgDT*zkN}1&d0h0oNyb12dAum3v>uflP4qiNdyQJ&cRK1mO+~*z3*7uU0y4w zr^7HHI?*f#LjlFW&CVaBFP>*Sfms>gm3?cN3NMG+Y&-=W;=$2G`+(%LYswjs+$rgf zuwokM(qidXo<@vhH4Zo;5!&?=*#Aza73bYscK_pwv$K$K*i^jnmrXuIcU!?0>aufr z`$JwB!sLTle@uP{cFGfo=Bu z_uAT;l91;`=iT(bQx!<@xZ9Hl%^m&-Alza&LVaR6&!h5ya*N zvJSKDU85J=BbJ;wD@j1@!?(yE%ArO6#W;XACp185{9is+IYzx6Yia!-iPQ^>6N8~w z^Sp6|rCpyO^Kch=^)P`E6l|$!Oc+bi5bT<9j(tjw+0NHQf7W*MLXimIP3VZvEdR1Y z2L;KaZ)gm56~{(gVl2%5u3P^1PEl@kxbkl%NQw5zur1-8TG@D&cEbC@`GS1xH_LUV z6A>O&3ln3)kfek+TKShXnUhOO#^mLAV=V5EZ~&avOI`FZ#$0|7p*jzT zdX6v5&#~tJSe_7mTO2o&$zvM! z(7yBxDXXc1_p-4+$TisAR=YP z%PNe|Vh&e$y{D!%KI;rrTTjOzbwsVOhDI*&sjD?pjKKOudjWwHydcf)@`mpCOkN?0 z-5;*R@6cej;%);#lbMZ?k@Bh}ab3B=Vcsy*>i5Kxbm>#XSNvYN_m*AX-WRFe%onp7 zV~WI+>3C8nJ{{UspVH>9F|?aswHXQ49}mP3VwV!+rnt9z|x@TAx^W|8yAe!f>6 za2y-xUT&6o#UaI^Mn1o&bNvRWIugdcRR?~Z1%u@5f?kklK>`L8iV-K0_qf!VK4FxF z=cR5nLS=#uS?cwMq)m=0VV-AiNO7)*s!h?xc&C}^gqOA!0}kTQdf&eFKV9!;L=GJ- zw$hRn{r=67&|@`8E{kS8=UMWBRt&AeB0fCJ=Hyc5F8}$tBBlu74u_QoFy4dDse#@B zUt-)eaK|ir*^oJ`g8IEZ{Ky-I%^`54u3t-8ojRDs_Au^e$MXF^#-%wB6i&we83AsB z8dqqWUkIg>UOlw>s;?thlgr9g`B7f6W_vBzLB&C$t?7m1$8GS6A%o1u_9M>5&3C1{ zloq*8Ey8pLhGKbAniwREawq*2-~bSoincY;`)aiJRQeYk-GgY9JW{ufZ1#Q*labD- zfWmMLk4$!-qTQuBb#&%b3z+Bu=t`Ku7^2&(Be_LPK%bb~5r_n7B3ER!q6?W4%KGjz z3arZ=8vq18S)mHS7vqhg^8|&+vuG%51A^I5P1Sp=hBMfeS|tnd3GBB1PXDHA2QJ!o zxBtCNeDk80Prb@_iR4YjI7Uc3KA_AQh4O}`0eB!<`Bf;So~kDv6D=)xL#Vf%&$YEk73duup>8l0OOclc_n1vo?i!L9u2Yw_&)uuk5}MHvMgm;88(9bO2eCjiQAFP&%{whUw4zQIymKfLb2anZ<4SJJ;tLs9G zcZ0*SA1W!AFNhjj_ws$LdmW?RFoHLIP&Lul7pDJQttV^+%xgiN#7Bn`$6co~s{YiX zf7FDoto`|N%&Zt>GzO~kU~tL};>tG42uG@i;g7HI$HmB|1GZQ2?O|4M7Np zdw%_vo~1yK1eg`q(!!;FCBB;G8K6Ay2SSC!10lV3`N$v_w}EBpY|e#JfE2XX2aPJn zZ2lWJO8;YQ2KV>uM8JLz{~y?inUE{DNTv~IRgKL^ujyng0A7P0NN59*vA`|gqn<(D zMs7+xTHHGzJrlPrEkQW`O^3&Z3gE*8MYxsm5}IqbZWUMfrb$y;*d$3L^0))0s1WX7 zFF8p+XZCiUs`-^;1QMD?Weh*@@LsA>vY1L ztE>-p$qY4)xDQ`ZD5lIm&oJkq5!azFo%9u>d)^475`e1KQ(`wU%Nlu_3J8Y~oN2y}nA-|aV}Q#2?d_Fj8F?^_3}eK*of%9e7^54*9kdALZ%sCnhhOwU zxq1N47A{J8DBDwg{B?*`O z-Yef^8A#cd4&Wv%FV_Eaipb){=LeXZG?AcIfx1yv3{v_K(}ZhPi1TK%KW6+|NS1>g zv_SEd*a~r45mxqt0m`Tt;i0u*RQHvwLs$SqGw0oiv^j%L1n;RlPSIaRIM z#CHvjg9+e<%jgYHH%t*4A26 z2NlEjuEpQPzh?4c&H~B-A`U@};Iy>Gtl|)dJAs@!>fU+DIe|HrGSA|mS#i?~V89B{ zS_z8Yh8V7wL;JAB@rRil90`1BE%TOMA z0#~adNgw~CBnl9X>7+*5pbmlei+w9J`v_EA?aTURi0WvMv%0pq&waHR+Syd!34U2Q zZv3RMhfQQSm=Z_Q;7jjy-?n=sfWNkO34$WLw z%bsQb;|Gw3gToS$-R)?qc~}nH8d-epJF+-5O(#o%o*pTinEWb)j1|GyOSQfMy( zEF^KLL6$T@3<}N9U*!E-K|pJ2$S3Oub%W z?RCdech*jUwc4{KTDC{{c4>9N{HJTph4Nn|hAT82WeFlHgz_#ZkUlPzl3}lZ zr(N@Xe~Z5XIx0M zgXRw`EmibjzoP}gicj$XdtU+nmZeY3=Z@Z>!$Ubzd$t67|)Y@m0mO4TN6?!-G=> zy`_@r7FZy9?iPoOz;9a|JUY`U)H9Cq(w->GA7bdrTu-9&q7ngfm!}DB?$G#Ys}^IH zHYPLSkNiC+w*I>zthckr2hAy5gAtj#D2vJi&^`Hw3ep3mu?u8IwdG6DakAj2(g8zX$GOIK)shCTdU&{PAx52tE520)@`YtT5Dm`GPmow z#{W*!$%J4m0`k`t@{Iu_u5mP0XBZ5sVWlM2=mBKaa6E-E>D>mz{cslbLfq#!0Qaax z3;xs7a92Qz0F`0xB|+fwMgnGH{|Bi>d!U}b4_InEUp(!Go1$m&wG-OG!NpyGz>&g_ zx6g8C-Mp`PurQzryK}Tv5ipY?40d!2I*6Tsu#%&fM>K35-u5SFr6Me##a~q+B0aES zAR{xQprH73eg7LtfJ3YNZU50xjD&IPh&5^nHtI=mz==jdS)5%oQp#%) zq^35TFOZ3T+5S5%=gssi^`Hw&AN9^PTbPH`O!rKFebS&RhbtEf2}s2g#yEmY>A!;n zGY0$pM5Ax{CDFW$HfQC3k;v8E9jm{+g4hi2#dsZ~OL1*6%K0Xoh5n3g$G<~HC33>m z#oKQuv93Pp?mi^)D6GS6DbP!#*b^X)2 zHHU|Afh9U53P-lD)!EGCW^ZInB(QV80?PStB4=xVe_##qPe-s9X+;1UR4vXFrs?TI zmAFLc{pli1>|3*|JbJ9AQ^o+b*DGO-&80lEaGVVsp83n&F|$_iLqkNB)VuSFF&3c5 zB2=IgI7j?Tc(IJFokF(=K@x_hw_>Ur#Pc6uPw5$==n{NzuS!|?6H-2P8+;QcSIa%> zC_YcsQ!O8IW0tVFrgDAq08@3dNqWQMICe+MBy#p(|4vm>r$SWy?KJLJi&n0a8l%W| zV@LPWt*Yk86r=VBCg|b;_W3IocNJF9_jm$siYpkIY0M`MPfP=q_@L8>h~Aktb#{+2 z`U6%9*~e@FSCjd2?ON|!OWBzOSS>VhdR%C2cz8Wn1(?!sL_|vH=slYp7;B*tDv4K? zM8sKy_Tuo~DtN!Oi9E5qs!?d7Ew_d5 zSc+wbY6_X>+LYTIufB&?@_e#|v4-xBCViLK4c)-8sjW;o0ljCWMB4xoZWcq`QL_LS z;eW27+a;BNR(E<-bbCVNp~P^hwYPt+p6R7?+hC97ijd&58VpOb%XSwRY}T0}0D-{9 z;LThBB2bnGIx_xRKo79vy22D>867t{@B%ftdygoLz5S2P8f((m*B|>>YjdsQwnGvn zgJ$3C{S6C=Q~I0!?eC%FnnK;7$2{KW=uPMcu9s^mnH6*__oJDr4y~sC#+D+|7Sf4d zo`!bnAxq+MtB(7OMH%NRk6tQMZUM8Kk~Xf8qYmzJ6*y<7Mi*BgFCow4Q`P9qm~j%# zI{7ey33muyqt>u&tRvW^2BQ?E5R#$u77J(Uq@8d`rme7be!z8MrJV*72r@$T ztK>htl{O*;<@1ZkFC-I*Up1Ng`iaXT0o5MD4ya8bf@0*!&yB-O#8BnYW{`Szt<)S! zjhd|QXld5JGWZ5jXk*Bbb_b=^zr=*-&(Z=|?$X!995;l+0qKVcfJRKSUO6z2dK}iO z5fm8nNl%mDAI!pN9ppISDe4`1%Jd>5my(WshWRQe87?CJnzR13@qBbGc)PQG&r3wQPJGP4>sdQOHXf}!9O{p|LaAvm<2 zRB7!%&%Y&|)`jO4du@{QD^ZgCEh9J~ego{bTDa13a{d2sDADuh!>S|EaeREdRqtlE zzmODQY=AIzp=5Fge7?z^2M-9=hvQ1SA0Q>omt{4-g0ebEZ z#v1!;zrLm1T306)t_k^W*zq=_h&R#$u_Ic0*=4TJk&-ffH3upOMaWC+m z;ESv9;`0s4bxL@fP8|8~_7e4xlWTmXgyk?zv&`a|TZlK*P@Ds8+sMn~95=;7v%r0f zk}f7u&MOJ$U!OHryuQi!j!tZ1wY};&f}2Q*9W20_)w7; z#~|N^ngzY3U9)7>uzRX@ikSGo2@=3da&nB12Qf{OUjf^{RvyF*-JUQdI0mv1zP(HY z_Y$;tzIHLid9rnM_qRM8A=mlzbJJlu>2ICvpiU=xMlh4K9e z-x0%TXRumb4=4Km#loxR1~A0!2Li+4#Eir`W&?y>F{jDXgjN$65n=*$y_Zc_$kh*&+v;LnS*QCukdY&d9 zL%vAKMZzy{HD9Qyh19JO#UpNUXnL`xVcn~Dc?4Kiz<}6WFI=au2u07+q!&`r{1{++ z_d=V#D&?k8%T(d<`yaCbVsNYrAiOx}Wm>C$aZCZQ)*>~Yr@A@xMP>oilaA5EEi&ie zuGN`trWMHY_4E4JQJ}{l-BDMRZtCnBHt<$X79J)O4b81@7@XKU2Rk-C4mf;p{)wS_ zX-i7rzhjQ^@b)DE@$Bp@okfsbs;M_Q=om_2s#{!oD*-i~xAwQ2hX*_z9i3(L#m>$j ze)9fBcPA%+oSa;EOy({*Ie84UjSlX#;7<}PtZM{H@&755MtKYjk310iQpa{B-*Geh zbytGjMBv;-SdJF>#c^2BvoKmM7&On{%@KYK4mTJ+@LHg0{5K;hA^WXk(1H{^hy;nk zkLBzvOglkQ8R-TI_F-?RG;4L`n6BLUH$JSMF{G-oGS@OpX0m#DIu#!ordO0HdWr|K zPm%P3dzY3X6MM6%f-U1H$odEnVNJ};V49noO&lF3e@rI;yaHC6?O9-lMMr{Sx9m<} z(THjz@2;;+gXAFBK4?e88rz#wVCCH>!Vz$G_85KNRK8T(ors^zrWIYeUSP3Q)K*{! zEM&|=2R+Y2jA?Zj4Lh^v8lRnYtTM+zWr@-kr;KF=) zKhj`C)cDKhE(V&CS0g$ku}7nqUUJu#t~7HjB$LptG;<)BuRnI{p4d*|g0#WP+qL!g zaT33U+(G1ji!seQr)X2qz+h3D;JO4+>x;`>7Nb~f2s9qA|?p0c7>1yVP;yA;M0E}mtFXKYiRed^i!*3 zS@yphzf1X9=zLZk#Cgqe$d?tse{x3>^Ll2bxz_NBcn=`a5mF-z-k|?zzIZu_8@Ri1 z9L@)4bb21&+E+BI;?1QKKlqwL7C)MHj$D)P((DH9Hr#7@6Pe%`Q^n&eaaVu zkUfYBKqhG*`GJH(NmmptxVp_AK%mAs`zyo&$zr~iSJ$kcOXL|DQrOzvdza7lY)&qu`b_#~GaLB| zHI%vLbqL(#39h1$^DnP%G~nnPH#OJOAJpo@{bL5{y~Ytm%llfA1|=1o(G8e~!~TSj z7TYe4Vb73`uPODCNHXbG|BW=3t;tY>%2No=kw)UlEFTAPaW#N4L;O@!RQ_=i#Kgod zXsD=T_jh-w3|oTlFZZWPkG^-uvxg)=0GTKdz}Q=&4+Gh*ga{7t$SL0Xt(&9J|27eM zoDDgYSOJm$MsVjau>RZG-T#o_6LF-qiyu*1q~3X9H>meG64hj(jqAmdmU~T~i2t<6 z3+#|IE8yB{@h3jGg?O+MD9RD_S2&d;CoNO1?jl$`Q`Hv$vwpdLBeiW-X<#%X^7vHf zc;v%qdVTOJubF+#XsOy5Wv?4q#p+JAn1%nE=1;=v#kCaiIhHy4F)=fC1UKHMCuBt`v?-11C$2@G^?cU)?)Qp<7delAvPaabpW zp33k4Y`a6C1Z)uS?|W!S`UW7uU1-Y(dL0zP)r7qM$@+(GI5r50v2(;TNUmgaE_}3{ zr+m@6P{sTX%b;Gq;$?J?+Hx8`%#-4nGqIwT>Fmjcm{+mbruoAHumv&8k28Rpm; zp_cJ6tOsAA4+}?Dxwdao3ek*Sf4zt{O9rhki3xSJBsjo3(!pk?u@McHM$z1&NfRybLt4TabSX0AG%*Y+a9 zM)-ZGXCWFSx7qtwKYF~j&BOCOLKpOr1u9gjCkcrOQ!K-&_9GQ)!^4a`K0rV@G!nzw4`T9_|kf z0gm3M^)aX0|5VIc-ErUeWMN)}J@${qu5k%P_p;DhY0Zy~Z!j|q-J0t755EsNk{?;1 zaKSJ4pLp*=(*N`4g(IV;p!-p4H6-Ad9H0e&74vXLr3qr6kTCBWTTktXG&6muO6dL| zWWvcwfNuB*^?f)ykqY)G4vH4^ycj#4D@$4?F!t-i3<@xM(|;F3he~Iq9QAK*pW1hE zeGmuzaQ^vHMhg;|z$8AX&v(fdO^*Nly83r2+w_&-KA__?)|a&4=(jyAWFxwL0aKS{ z^mT+4r9zEAFD)m&GU4(zV$e&jv|#vAorLOLymo*f)~<_gt$=ch``T<@aTY zGhZCPDhKrIdYy^*#-DW(9_$Wh*0h^urx6gl;^;cKzr+AKKOHt>*r^>SyXq`qv);bo`PGi2TVAT=2aqdgI5sCT%NhHrto$+=u!x&LCz`%Q}a;JjVIn4Q_5Sf&=aZwnW3^`(Xc4hGvJ7q{G!MeqF1;N{yG zq|QY!^CDcE-5I9S8ypT0@Zn=)d?Gl97SHTV{=hm~qZi<)^}C)Qxd^F|z6e-atO!yK zt}*@+hOCUhRY^axM5)gV7%??=v21XEzaR?N_AS<*Vj%VuZQfUMBHF3w} z@t_IZ?9LN|)ToqAz`BHaG@MKE!;v@Is$8gDx5mL##K-OW@@;^?AsO&+*Py4_Qsf|Q zm?nq~7}>}LJnhcrIglXog$pE&_92YC509QGnMq{eqsF3mK_Wdv4yrCFznP-l+^g`uV$sVM zzC~1YZfjjwZC&@)A1y$H|JVJ?7GcF<1wvhb9#Nm>Ik6)`Bcb^Px$R2;EXAX9bb$4w z$5Iaqxkhtkgw*QdpYr@>A$)Y~YKn`#jLTuJTocHuV{NcU%@mY>`-}hWei~~s;LD2u z|J-=#?x&`t3-w6CnY<71vqTNxVqwkSMqD4d7TsCJObD&=Z7uy@h=r#Wo{{fzXp*4SdSc%>>4qz_eVeOcdVzdmNR-4 zNAy1zXHWyRrG!-w8hI)UU`w;D;pa73^0{3Aog_AZd9Edp+N_Mf4&+4<+t|gtJYc*{ zpfa372hm*D@|L&-gR|V=xaO0W74$i9k#EU{5pOBB$r*D$yWuQ3AFj^A74k2k(>v;*kVvNRPe7b^`T7^hiK(2R4T~7kEp(N7b0%-SbOFV~&Bj;d0y`jU1+K=H zyk+GBTRnxocs!BK%Pf{9ele~=Kv;|ABGBIrvOWQ*5L;^ow_3*qYU>Q+c{__+*vE}( zDwvw&aEkzd+)Y|)yb;AsjVeXc#wtRgd|G@?b2X*q?v}jjA3fZu(koc_ax6&*N*$Vfs zrDS)o^E8)C^TUsfsr=!E|jFaJp}=qc}bd*4V53~c8_2HmotY{(Gxc5ujoTC@PMjqH9&XH##dg2BR`iTdlg zeefw+Quj*#Hi2J?$jXiVv{wZm-Ox9YRqmJ?;$60oQUF4_u(w9mUSXb)A>!dLwZ5iK zDR7G&jrrLI>~RNQf8Cr4SYX~mZUZ-K?+?SmDn4x8(5-UgKS|*6_TBxWvDtq7jH9Yy z(kst=;Oo)9- ziweXvn1=hp4Qd{)rJ>yQAt?)`%W}l!jczXYisJ9PJzo&aoi5M`=dPi{znAO7JJ(b7 zxM?^`MR#cAw8eL}nKM~|FOg7GE0*gg-}cwBmc;ARV|OK3%JlGNymx3G*oPxjR_35l@8hfW z5i%!gD~h7a6~M93V*j)u61c+-k2I56aX7;^iCqXxLS|w|d^Es!gR6h%Zhii`i9nHp zj#uq}XSescOBV$H_ORh1{Ghh?G2Fdpc_e&)4#C#HFex?Mg-zraEyZ}5c^HSbEy)TA zYYvWG%@OyWzAY&KYm<3WIjLvUZ5+nTW_?p*6D<6q!B5H0&M(dn;x{42CUiTV8TkS3 z$lWbN^Kf-pbV+*$UpOiI1f*BCSp!Q|!=%iz$vX3U#W0Rw{x5ABlI5=l^@p;N`cN9J z50$hHZQA7p)u|rJ`wJ}_GNbg~9vPwk>il?%w>PF(y)Bu@d9f(SO0_tY2h#$qVdhY8 z*s^RoY>%A|yH?JG{P>BGvSuFaShtMH{l|8!gj31OAfKv1_P4h2>qiJDO$*=-oaAL0 z;A5lb=*-a;TI%*-ckTLxF@4`30{=tN|MAQJhX}wpE)Tyyxi4G~S*N}kcuAHM0d?^X zAlvE;Dq8e4CD_vFw*tum+Ny1~2W5%ZHPr?CNvbnmgJq}vd>Zou17gOS=pyoFs@d%(T9VwnKSCYwUpP(AqBy$8IZ1b9p9 zf!7h*@HR>xDrQ(h!+J-k-!3NAn?%ho7MM$(%(SfeZYsO9WRle{D??ezgh3pb?8|{+ zZdMTG$%SYyE=&uyffa*oVW5{iMEE+vsE7baPfmdSv>n{Na~t@%3Im3CSo=>4;`k4D zw{-Oo=n1S%v{+L`7c*=P&O^Pcxqr)^`DXWV?1MS&qDNn*_VI1o4> z?~_224zMuP9w^qgIG^Yob!DZ^%&gh0NjDdpY%EJOxq~ElJBJPB6HVb|s202k?#C2_ zZzB4`OG<(|{QE0}P_@7sBuUQjd>O0ZmjxCzZBuN6)%L+`SRTxVIsR;z z7r=&z-d3nacm_LJ*bfz(+qkl| zEL|;iOb6QOma@dB)fw-|s{BA5p-`xa zf)9}ZYXT$)qXsmhv<}SWyIxviJ?f`e!Rl+X%$D7mt+)BjCbLV8C;g?h8=R>Un87bW zec=UFftQp3rO|rOu*?b?R`B566f<}?lLa;F97y?kVdMQ6i&q5`P5yFp3|o~llm)wn zvLRY*1|!85up-O~5+ZmoE070aVr%el6v9AH8yM;>gg{>}*s*O3*jTegA|A_H#4~2c z_?z3z@H69%b~Q4M6l&{@u+fHIWz7xgT7TZP`yZyA7zvjsT_Rhb= zneBSK!~A4@cA%_$IUmY!Jz{1E$ac9y!v+_SZEX4V@V8_1;pZ?ND4mY~X2unsueGjz z6leAN%51BO^wAbS=h1p#o{#DGsgahy92~~}A#DWrFY6+>B_q9f$A@?c4=;)oo|qjb zJWL~h{fL47i5~VA0&{Z%b049;#S|}7%aJa6hC^J8bv>;5_VcsW>ci7-yW`hh_S=L1 ze)Rt?0z8T_?{asd@bgD8jyN{|dSk%X5TNBdf%uQ8zG0Sxr;7bZrbjv{66Yx|4=Tf7 z>%iq-zlQ0-1E*f_NZbc1CQFIjGi?eeqZ(W_qzFRWR;@a&g zR=4g<;a#~oiBr6DsMY$_LpU*Ohw-N6OcO5M8ZC^TNM%262*-134G-{b&6UYA{lx#Pb9B{k|88&yD&km}UCW)bX8V7!K>oN@B%-Zbtxg9F+fw2<;W2`#0Zw)~6>W0e?VOlae)d6J8(j z%qY)wzgSw}a8-V9T$AeRSmq0(O&jc?ei>~=7jmH-r;%q^LB%u{RL42M^C@&c(G_Yl z{iH88vR}MeWA(ah1+VnyCBi3%hngMC9c6jC)j&BNLAQ^#;-pP$WNar|5UEMF9L! z@7tpdr`{ZIGT?5@Eb71BS|s1E#>{M9-@mso=9K%{Q=OB;BOHD2ewPMZvRaJ zwr*GBdBe?|3f4PKdUnz$qwZG3)8?P&DAadnFw4>#<87gSsQ_x{aY3@o2Fk`7L4B+U z-mP+mpK;w{ydzZZb#5$MXU7cpN3bEbE0u zv-pz>rdbcmpUDpy;%H*5S=~d4&}D>e&#pI@a1Ecu^11ivc6%i2n@HAYorJ>AJ{ODI zz}Jxd{m=fp?8+EDqnjgiC*2yZH{<#QL!4~-*Bc}KRIVXCum|i9(1QKG2C&6pqI#R- zQ`K(Q=h9TKX2pR(Xxi?{{6nYeg(7(1*b9E31bF1u8!B)~7;VL*+gw4N?UaoF2m&J? z{b4Mt)7=!N5Ntmfnn7w$1PvLG2&e{_TQSG>>G{=HI>uB9JRSP;rwlgrI-ck_`{nT)$nTIUEF^z6VsLwgNA4 zB)9Y1SfRz6wIZ|AbGe-(BR~5ubb7A+XKe4k%YK-m*W>0e-Bs6z>a4y#LU+}7V@$Gd zj5EbMjsIH16rhZ^_foEP^l46Tw1G{|UL;w3P<4Eus&1VtR4x~REZG|x5@@kU^MB)d zS9t8(pCQ3x_r5d*=rSazUoHT}PQkhQrIx18W5r)GYC`>O3iD4bJ~S}s?a6@No&-4X zJ!oOruSbtBb&Yhon7VMZ1tWsYJa?~lnS4Lj`*8KmAy1W8$ASD{AngW((6Cep6|_^R z#6pnP06zw6!;|4g@Mx$ZJRW5N<(r+Fs}e0s%hp&tE=>?TyfKHJa&|g<#jYsx;pyX8 zk=awM!cNcP1|OZwu`ih|upi@Wf_*-|e|%5vW&TeM8yqa|#tOg2|5DbP>i&;r+s=QN zT^niC_inV#%sV6Xj$Rw7=U6h%*yL)ofzOrkmV;ZL@~<-lOSR5^l5&khQgeb!jC_-L zk0RCYi84L(=cc{>k1EzUzN$|Wzme|p`c-z&zf5r?SSmdjB6+viuI}Y%v!-{GjGJp_ zm`ZEsn%C5<AjtL*Oi@#x%1#1i1Y0y9Q_gq5+9B55Czz(4owuoPT`I&zI zUY*Px`C2w3f-HP8);Y}kG1K`()wMy7+5(n9Ut`eim==jRpKcmt**z zIn%9Ku|Z58#`l8ni2@A${lM}fOZ7<-S%j#d6zp;{YU*UlU?-v6t)QK z06dPJz{5ypN%_ClPysMX$u`ek(skkiu+!Io?DiXg>3}H&cYB(V13tDSo%#V6A9b=# z0@)#0N#Z#xWz+Q&YRC28Dw}DrMmgVXeZxHC301QUy{e|0bOlN*W=?^26|H~jZ&`a1 zV3grCzexpOef3#?Oa;F7+5&5{UZUwk%tA9)*(|=l-!8K>$MwFnC`>M)t)XG zLMbf? z7kocnf7^Gntrq;F*Z;2>GZ%oh0DhpBR*>$~57;_Kz;p&J|Eu^LvRgcWB-w>PEN^u4 zbh8DG6AhNiW|&M?%(IwKH{aN|A;v@ul)Yr5{Z}|JEw4qlfB(a22DiNmU}u1nEzFX# z?%luCpFY^a-dUh69O|v-v3?3S`e-bF>8%~Yv{xsbZc0lAH^`2KLLL6LAT0=gi86sZ zo_*o2S1-6lTf_@C-Qluh54hpo7k;62f+ROcR)56qhl)K8SuYZ8;(u7d8}lHJKj`IJ z{*c;u``Pc-*?Bi^w2%HF-Wf@td4K=UhU0OX))M!k^d|ge%z(9br&&I}HPw>csw5w` zF(gS5eyvz4Vk_sd{8V!+hAHNn4VKO`4R4xnGF&>}!k!jMUz05+Um$Ui0Iiq)J$s)3 zn0J}3fI0$z`MAGspRUH!hnPD~8EEc4eXx1(hN;}KC*o|E-`VAK_})Iz@v1W+&l)rQ zNkgI|Gd=uz3RMD+-f*3&K_RazoU`o)mmIpmZU27o27lq?R6w<45ARAtA~&~cgK+oT zc<%Jd1mWb`4ff;fH#m-dx6z)nf0RCw@qdK?nBy-+^c{abLM!U>(Ecg6C!4>xGTE~F zQnaD%v44l;|G%0>`s!#@G{;zpm2=I5l`-Zain*pk74uAnH_bP9Y*@r%mB+Ha!8Cv* zXub6BnPz}Llm^;VfI4#3;Ol^%C=9BFP#T^3<%3wC0ucOGdJmNf%hG0 z0c~4%xI+!C2c8VohdW+<;f$agoD+4061%Q&#kmLkG};I%cG245q+g9Jh5eu@$-JO0 ziL;?{i(pFq7TZ}5);k(wo3~}U$rt}jet+LEU0fZdZ(TB6JMPSo0mE}52RtkoZrD^b zQ2SufAf17i$1p|b$7`CDz{omn??^01(7edfMLEwbR25?}tSQFQMY`C+Ua^$NmagXM z;B&ATY`y&N+4}@&Ukqwg0E;rb3#a?V7oQn->clL{z?C_;JWCYrrW3eyjM>QI4ZO9# z=7FoB;}iAY_#%RA{| z&LQbu?wZCF>*bGA94xL-q9XyYPO3|$toi+l)@BI&%@HPDOD3B2zB%5^@M^SP-kB)F z*BK!?(qn#oF6D;yk1vSOi!2^#z{BFN^|Fu8S_+<40#Fqov9<%qLRN@suEkJgj73oM zA}ew8B94nA_v*E9rZp9W9`uoloPE5j&ZNI)H@OL18iuFb=V6YH

0U!!dfXgll+jsxkXww2uF^5&g&B8e=&3+9dP3JCiJ=-$(21JRjMAUSWhzM8Qx4 zyR%V7dLMlnXj1{K1&{_nm;589Q2``?CJks*K$8mI zCjqW1!iAZr1~_rT{`~XLIPsG#LoaRI_ITBH)@ZWD zYOr!U-&3*6UVvVX?JiR|vpQi~Y*=I6r(&t4Y1twRtD0pNV(DU|$#3Qw4ZSyBZ{oRV zgY?IXc})+dvE&cN7~HrwN^ky+F$Q)e!_0aYM-1qh8Nqy+^y9bRqyi)XE%-3nJkCo&=gzMYt*#iGVA0kPP@u9W#M>cTU^{bNBoWf)OuH z*llVk@OfRm+YQQAh~U+93-~FbKYUNy!|#0i(r%$AJPhm$-~0B4^De#NMt~OlFrF&H zdXcPdukFL;J*<;thtVdo*>o=1WErL0!5v6;T8~q1wF*>h6L1(`&yH?fY82D7$Z&4M zJcIePD_SC3Wm@=R3G3kxG3@Fe=5tlQ&N6%VZmMpwI_f^1=^>A_ep>?0Tza+2Dq{a6#>bBtB!HCu7Pf!FN|jnH?=;w z&f5RSz1A~o^WE|!IYEum6Jb!f+74b!G>0D}bl}lI9k}O1(}7brxJWyNdtN;mmADhA z4UeW+z?;p^AUWdtvN4%+rD2oRE$KGSdBrYvfpW9yQQ0=`A=!4((Z-E}Gc{{@uPRsa z%U>_HmcLlQlb5a$sj8D~l$9&3URKXD$S$9xmHuvu?wse7^@l$gsS|x?xQ_eXiOkKV zPt)3yfZ1o%;dk}@A2JOA-X{U3g7zf9bf8&eiroRK0j?}UML;s3}teA`T60h`kn4jwv-Pqr(43$QTlK{s4v{7#o~4MK2YM^2QJw6 zf(s6m82&o&WEuxv#PH$894@??&x2PBs4v7V7v3!5(bwTYc^n_A*4Q%7DPJX&H70Oh zs}s#HHpb{AS4A+Rr{%|Wq7aoi zcnN!S%UkE9S9Q{LpghNJSMw?NkXH_kB{T{_)FOe5dpH3C14&3ie^l3hB}%>Tt)uHjRhKL6*(>a*PBx9pEo4izN+8t@UroM(~pugx5xE+9PT&n5|zkO_&MsGtW>hoGKp+8UrQ29 zx0BT-%Ty~_!&R}=msotOSZonpwUlisnQbz%ex~8rx@iVO$|&eBWBC1F&9Ja~JHyQR z^(-@w>$B~@`e6#E$45N}@Nc#ck>EpW(4Gt$Li{b)JP)s7t`|~|q`fyz_S{e8c7C2D z?q0D;pk1|&Z&{OIC6>msgOyu2p=7sUFiGW4BD<}}k)6Cr)F+S>n-G#Lm;zgcVPrjL z7Fo+0)x1tK9rD)XlN*uBMS*HJ8PzTFld_SjaVdH_yVMbS_); zdOl|W-jRJq+i2X<_tasn_C5*TCqjENv?qjy6z#qJx%Ss+UPtq~ZGQ_Fc|4`v1!wX^o% zzwa8*+7sgUdi!fX^x7K#E2~Sj?@3Y|97(FP6WQ&~RwTRf$$Hz+niQ{Y=<-BcmMqE6 zKo)Oj(6Ef{B$;PEymp@Xpf|Kl#t45JYuoizEUPCHpmdRSpI_%%>LUqoH88CMP@OvL zf3Ob$^sn&0YfN`@%&Qx&d?tGwyO6au^GKqNs4UUDGuh(YN0Mk`)v(5z)v%1?(y+iH zye7ud1tb66BCCFHVmRig1drzkd*7oq$lF+9@2AskyVCssbw>^GkK2a;{73wM#W3%y zR&k@6HrVJ^tQKfD#POUOS91jQ%d8wEi`ed!3pv8tnPy=Xb1eB7^)DB4dN2`B)c~a* zx468lqYL;%4JX2y*9cr_;pfw^#<@@9N^4$qEZ3@hDVtZli0xDvV`Wn@+jQu=`5X>{ zkD&iRx2OV`_wg}y0gJhGs+(;wtzwQv z(Azmk0&`z%`*0rMA>K5L{KwZ8bl693RjYYANPzkUtkL!JOrz^&nNNN>pT~YjkCo20 z5aW0LaE%0dN7VlT4c9?b)8emgA!|g#Jc|j{3#|g)t+DI(W+}(KGRD&L%@VdQu9U(r z%(UD@V_MM;`=b~}_1g`?-gU7&Tj_ku88x&ZtXfHH1Nyjb3CF7})}im~b+!Y_5*_+t z8`(jCKcL~_n3_c#mzpIU*Vr1;_V&2Xd^dtdI(}WAIoV-ab7Um}T@G;CEPuby$aWSci4k|C)XF+5ZJT2iSCJfh3v$0000 Date: Sun, 21 Apr 2019 03:12:18 -0400 Subject: [PATCH 62/75] Update Splash Show our versioning as well. Recoolorize --- .../java/net/runelite/client/RuneLite.java | 1 + .../client/ui/RuneLiteSplashScreen.java | 25 +++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 71aad5f534..5f3cc9b6c3 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -76,6 +76,7 @@ import org.slf4j.LoggerFactory; @Slf4j public class RuneLite { + public static final String RUNELIT_VERSION = "0.1.0"; public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite"); public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles"); public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins"); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java b/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java index 925238d58e..211997cdf4 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java @@ -24,10 +24,7 @@ */ package net.runelite.client.ui; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Image; -import java.awt.Insets; +import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.ImageIO; @@ -39,6 +36,7 @@ import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.SwingUtilities; import lombok.extern.slf4j.Slf4j; +import net.runelite.client.RuneLite; import net.runelite.client.RuneLiteProperties; import net.runelite.client.util.SwingUtil; import org.pushingpixels.substance.internal.SubstanceSynapse; @@ -116,25 +114,36 @@ public class RuneLiteSplashScreen panel.add(title, titleConstraints); // version - final JLabel version = new JLabel("Version " + runeLiteProperties.getVersion()); + final JLabel version = new JLabel("RuneLite Version : " + runeLiteProperties.getVersion()); + version.setForeground(Color.GREEN); version.setFont(FontManager.getRunescapeSmallFont()); version.setForeground(version.getForeground().darker()); final GridBagConstraints versionConstraints = new GridBagConstraints(); versionConstraints.gridy = 2; panel.add(version, versionConstraints); + // version + final JLabel litVersion = new JLabel("Lit Version : PRE-" + RuneLite.RUNELIT_VERSION); + litVersion.setForeground(Color.GREEN); + litVersion.setFont(FontManager.getRunescapeSmallFont()); + litVersion.setForeground(litVersion.getForeground().darker()); + final GridBagConstraints litVersionConstraints = new GridBagConstraints(); + litVersionConstraints.gridy = 3; + litVersionConstraints.weightx = 4; + panel.add(litVersion, litVersionConstraints); + // progressbar final GridBagConstraints progressConstraints = new GridBagConstraints(); progressConstraints.insets = new Insets(0, 30, 5, 30); progressConstraints.fill = GridBagConstraints.HORIZONTAL; progressConstraints.anchor = GridBagConstraints.SOUTH; - progressConstraints.gridy = 3; + progressConstraints.gridy = 4; panel.add(progressBar, progressConstraints); // main message messageLabel.setFont(FontManager.getRunescapeSmallFont()); final GridBagConstraints messageConstraints = new GridBagConstraints(); - messageConstraints.gridy = 4; + messageConstraints.gridy = 5; panel.add(messageLabel, messageConstraints); // alternate message @@ -142,7 +151,7 @@ public class RuneLiteSplashScreen subMessageLabel.setFont(FontManager.getRunescapeSmallFont()); final GridBagConstraints altConstrains = new GridBagConstraints(); altConstrains.anchor = GridBagConstraints.NORTH; - altConstrains.gridy = 5; + altConstrains.gridy = 6; panel.add(subMessageLabel, altConstrains); frame.setContentPane(panel); From 34bd67af0b441afad5b8945aecf657a4c105538c Mon Sep 17 00:00:00 2001 From: Ganom Date: Sun, 21 Apr 2019 14:33:28 -0400 Subject: [PATCH 63/75] Updated raids plugin (#37) --- .../client/plugins/raids/RaidsConfig.java | 136 +++++++++ .../client/plugins/raids/RaidsOverlay.java | 274 +++++++++++++++++- .../client/plugins/raids/RaidsPlugin.java | 68 ++++- 3 files changed, 466 insertions(+), 12 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java index 2323a15a49..c54ac589ab 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java @@ -24,9 +24,13 @@ */ package net.runelite.client.plugins.raids; +import java.awt.Color; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; 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("raids") public interface RaidsConfig extends Config @@ -154,6 +158,127 @@ public interface RaidsConfig extends Config @ConfigItem( position = 11, + keyName = "showScavsFarms", + name = "Show scavengers and farming", + description = "Adds scavengers and farming to the room breakdown" + ) + default boolean showScavsFarms() + { + return false; + } + + @ConfigItem( + position = 12, + keyName = "enhanceScouterTitle", + name = "Enhance scouter title", + description = "Adds #combat and good puzzles to scouter title" + ) + default boolean enhanceScouterTitle() + { + return false; + } + + @ConfigItem( + position = 16, + keyName = "showRecommendedItems", + name = "Show recommended items", + description = "Adds overlay with recommended items to scouter" + ) + default boolean showRecommendedItems() + { + return false; + } + + @ConfigItem( + position = 17, + keyName = "recommendedItems", + name = "Recommended items", + description = "User-set recommended items in the form: [muttadiles,ice barrage,zamorak godsword],[tekton,elder maul], ..." + ) + default String recommendedItems() + { + return ""; + } + + @ConfigItem( + position = 18, + keyName = "scavsBeforeIce", + name = "Show last scavs for Ice Demon", + description = "Highlights final scavengers before Ice Demon" + ) + default boolean scavsBeforeIce() + { + return false; + } + + @ConfigItem( + position = 19, + keyName = "scavsBeforeOlm", + name = "Show last scavs for Olm", + description = "Highlights final scavengers before Olm" + ) + default boolean scavsBeforeOlm() + { + return false; + } + + @ConfigItem( + position = 20, + keyName = "scavPrepColor", + name = "Last scavs color", + description = "The color of the final scavs before Ice Demon/Olm" + ) + default Color scavPrepColor() + { + return new Color(130, 222, 255); //light blue + } + + @ConfigItem( + position = 21, + keyName = "alwaysShowWorldAndCC", + name = "Always show CC and World", + description = "The CC and World are not removed from being in the in-game scouter" + ) + default boolean alwaysShowWorldAndCC() + { + return false; + } + + @ConfigItem( + position = 22, + keyName = "colorTightrope", + name = "Color tightrope", + description = "Colors tightrope a separate color" + ) + default boolean colorTightrope() + { + return false; + } + + @ConfigItem( + position = 23, + keyName = "tightropeColor", + name = "Tightrope color", + description = "The color of tightropes" + ) + default Color tightropeColor() + { + return Color.MAGENTA; + } + + @ConfigItem( + position = 24, + keyName = "hideRopeless", + name = "Hide no Tightrope raids", + description = "Completely hides raids with no tightrope" + ) + default boolean hideRopeless() + { + return false; + } + + @ConfigItem( + position = 25, keyName = "layoutMessage", name = "Send raid layout message when entering raid", description = "Sends game message with raid layout on entering new raid" @@ -162,4 +287,15 @@ public interface RaidsConfig extends Config { return true; } + + @ConfigItem( + position = 26, + keyName = "displayFloorBreak", + name = "Layout floor break", + description = "Displays floor break in layout" + ) + default boolean displayFloorBreak() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java index 5ca7214b57..fc149415b1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java @@ -24,12 +24,23 @@ */ package net.runelite.client.plugins.raids; +import java.awt.Point; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import lombok.Getter; +import lombok.Setter; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import javax.inject.Inject; -import lombok.Setter; import net.runelite.api.Client; +import net.runelite.api.SpriteID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SpriteManager; import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; import net.runelite.client.plugins.raids.solver.Room; import net.runelite.client.ui.overlay.Overlay; @@ -37,24 +48,48 @@ import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.components.ImageComponent; 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.util.ImageUtil; +import net.runelite.client.util.Text; public class RaidsOverlay extends Overlay { private static final int OLM_PLANE = 0; + private static final int BORDER_OFFSET = 2; + private static final int ICON_SIZE = 32; + private static final int SMALL_ICON_SIZE = 21; + //might need to edit these if they are not standard + private static final int TITLE_COMPONENT_HEIGHT = 20; + private static final int LINE_COMPONENT_HEIGHT = 16; private Client client; private RaidsPlugin plugin; private RaidsConfig config; private final PanelComponent panelComponent = new PanelComponent(); + private final ItemManager itemManager; + private final SpriteManager spriteManager; + private final PanelComponent panelImages = new PanelComponent(); + + @Setter + private boolean sharable = false; @Setter private boolean scoutOverlayShown = false; + @Getter + private boolean scouterActive = false; + + @Getter + private int width; + + @Getter + private int height; + @Inject - private RaidsOverlay(Client client, RaidsPlugin plugin, RaidsConfig config) + private RaidsOverlay(Client client, RaidsPlugin plugin, RaidsConfig config, ItemManager itemManager, SpriteManager spriteManager) { super(plugin); setPosition(OverlayPosition.TOP_LEFT); @@ -62,6 +97,8 @@ public class RaidsOverlay extends Overlay this.client = client; this.plugin = plugin; this.config = config; + this.itemManager = itemManager; + this.spriteManager = spriteManager; getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Raids overlay")); } @@ -73,6 +110,7 @@ public class RaidsOverlay extends Overlay return null; } + scouterActive = false; panelComponent.getChildren().clear(); if (plugin.getRaid() == null || plugin.getRaid().getLayout() == null) @@ -87,25 +125,133 @@ public class RaidsOverlay extends Overlay Color color = Color.WHITE; String layout = plugin.getRaid().getLayout().toCodeString(); + String displayLayout; + if (config.displayFloorBreak()) + { + displayLayout = plugin.getRaid().getLayout().toCode(); + displayLayout = displayLayout.substring(0, displayLayout.length() - 1).replaceAll("#", "").replaceFirst("¤", " | "); + } + else + { + displayLayout = layout; + } if (config.enableLayoutWhitelist() && !plugin.getLayoutWhitelist().contains(layout.toLowerCase())) { color = Color.RED; } + int combatCount = 0; + int roomCount = 0; + List iceRooms = new ArrayList<>(); + List scavRooms = new ArrayList<>(); + List scavsBeforeIceRooms = new ArrayList<>(); + boolean crabs = false; + boolean iceDemon = false; + boolean tightrope = false; + boolean thieving = false; + String puzzles = ""; + if (config.enhanceScouterTitle() || config.scavsBeforeIce() || sharable) + { + for (Room layoutRoom : plugin.getRaid().getLayout().getRooms()) + { + int position = layoutRoom.getPosition(); + RaidRoom room = plugin.getRaid().getRoom(position); + + if (room == null) + { + continue; + } + + switch (room.getType()) + { + case COMBAT: + combatCount++; + break; + case PUZZLE: + String roomName = room.getPuzzle().getName(); + switch (RaidRoom.Puzzle.fromString(roomName)) + { + case CRABS: + crabs = true; + break; + case ICE_DEMON: + iceDemon = true; + iceRooms.add(roomCount); + break; + case THIEVING: + thieving = true; + break; + case TIGHTROPE: + tightrope = true; + break; + } + break; + case SCAVENGERS: + scavRooms.add(roomCount); + break; + } + roomCount++; + } + if (tightrope) + puzzles = crabs ? "cr" : iceDemon ? "ri" : thieving ? "tr" : "?r"; + else if (config.hideRopeless()) + { + panelComponent.getChildren().add(TitleComponent.builder() + .text("No Tightrope!") + .color(Color.RED) + .build()); + + return panelComponent.render(graphics); + } + + scouterActive = true; + displayLayout = (config.enhanceScouterTitle() ? "" + combatCount + "c " + puzzles + " " : "") + displayLayout; + + for (Integer i : iceRooms) + { + int prev = 0; + for (Integer s : scavRooms) + { + if (s > i) + break; + prev = s; + } + scavsBeforeIceRooms.add(prev); + } + } + int lastScavs = scavRooms.get(scavRooms.size() - 1); panelComponent.getChildren().add(TitleComponent.builder() - .text(layout) + .text(displayLayout) .color(color) .build()); + color = Color.ORANGE; + if (sharable || config.alwaysShowWorldAndCC()) + { + String clanOwner = Text.removeTags(client.getWidget(WidgetInfo.CLAN_CHAT_OWNER).getText()); + if (clanOwner.equals("None")) + { + clanOwner = "Open CC tab..."; + color = Color.RED; + } + panelComponent.getChildren().add(LineComponent.builder() + .left("W" + client.getWorld()) + .right("" + clanOwner) + .leftColor(Color.ORANGE) + .rightColor(color) + .build()); + } int bossMatches = 0; int bossCount = 0; + roomCount = 0; if (config.enableRotationWhitelist()) { bossMatches = plugin.getRotationMatches(); } + Set imageIds = new HashSet<>(); for (Room layoutRoom : plugin.getRaid().getLayout().getRooms()) { int position = layoutRoom.getPosition(); @@ -127,38 +273,144 @@ public class RaidsOverlay extends Overlay color = Color.GREEN; } else if (plugin.getRoomBlacklist().contains(room.getBoss().getName().toLowerCase()) - || config.enableRotationWhitelist() && bossCount > bossMatches) + || config.enableRotationWhitelist() && bossCount > bossMatches) { color = Color.RED; } + String bossName = room.getBoss().getName(); + String bossNameLC = bossName.toLowerCase(); + if (config.showRecommendedItems()) + { + if (plugin.getRecommendedItemsList().get(bossNameLC) != null) + imageIds.addAll(plugin.getRecommendedItemsList().get(bossNameLC)); + } + panelComponent.getChildren().add(LineComponent.builder() - .left(room.getType().getName()) - .right(room.getBoss().getName()) + .left(config.showRecommendedItems() ? "" : room.getType().getName()) + .right(bossName) .rightColor(color) .build()); break; case PUZZLE: - if (plugin.getRoomWhitelist().contains(room.getPuzzle().getName().toLowerCase())) + String puzzleName = room.getPuzzle().getName(); + String puzzleNameLC = puzzleName.toLowerCase(); + if (plugin.getRecommendedItemsList().get(puzzleNameLC) != null) + imageIds.addAll(plugin.getRecommendedItemsList().get(puzzleNameLC)); + if (plugin.getRoomWhitelist().contains(puzzleNameLC)) { color = Color.GREEN; } - else if (plugin.getRoomBlacklist().contains(room.getPuzzle().getName().toLowerCase())) + else if (plugin.getRoomBlacklist().contains(puzzleNameLC)) { color = Color.RED; } + if (config.colorTightrope() && puzzleNameLC.equals("tightrope")) + { + color = config.tightropeColor(); + } panelComponent.getChildren().add(LineComponent.builder() - .left(room.getType().getName()) - .right(room.getPuzzle().getName()) + .left(config.showRecommendedItems() ? "" : room.getType().getName()) + .right(puzzleName) .rightColor(color) .build()); break; + case FARMING: + if (config.showScavsFarms()) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("") + .right(room.getType().getName()) + .rightColor(new Color(181, 230, 29)) //yellow green + .build()); + } + break; + case SCAVENGERS: + if (config.scavsBeforeOlm() && roomCount == lastScavs) + { + panelComponent.getChildren().add(LineComponent.builder() + .left(config.showRecommendedItems() ? "" : "OlmPrep") + .right("Scavs") + .rightColor(config.scavPrepColor()) + .build()); + } + else if (config.scavsBeforeIce() && scavsBeforeIceRooms.contains(roomCount)) + { + panelComponent.getChildren().add(LineComponent.builder() + .left(config.showRecommendedItems() ? "" : "IcePrep") + .right("Scavs") + .rightColor(config.scavPrepColor()) + .build()); + } + else if (config.showScavsFarms()) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("") + .right("Scavs") + .rightColor(new Color(181, 230, 29)) //yellow green + .build()); + } + break; } + roomCount++; } - return panelComponent.render(graphics); + Dimension panelDims = panelComponent.render(graphics); + width = (int) panelDims.getWidth(); + height = (int) panelDims.getHeight(); + + //add recommended items + if (config.showRecommendedItems() && imageIds.size() > 0) + { + panelImages.getChildren().clear(); + Integer[] idArray = imageIds.toArray(new Integer[0]); + int imagesVerticalOffset = TITLE_COMPONENT_HEIGHT + (sharable || config.alwaysShowWorldAndCC() ? LINE_COMPONENT_HEIGHT : 0) - BORDER_OFFSET; + int imagesMaxHeight = height - 2 * BORDER_OFFSET - TITLE_COMPONENT_HEIGHT - (sharable || config.alwaysShowWorldAndCC() ? LINE_COMPONENT_HEIGHT : 0); + boolean smallImages = false; + + panelImages.setPreferredLocation(new Point(0, imagesVerticalOffset)); + panelImages.setBackgroundColor(null); + if (2 * (imagesMaxHeight / ICON_SIZE) >= idArray.length ) + { + panelImages.setWrapping(2); + } + else + { + panelImages.setWrapping(3); + smallImages = true; + } + + panelImages.setOrientation(PanelComponent.Orientation.HORIZONTAL); + for (Integer e : idArray) + { + final BufferedImage image = getImage(e, smallImages); + if (image != null) + { + panelImages.getChildren().add(new ImageComponent(image)); + } + } + + panelImages.render(graphics); + } + return panelDims; + } + + private BufferedImage getImage(int id, boolean small) + { + BufferedImage bim; + if (id != SpriteID.SPELL_ICE_BARRAGE) + bim = itemManager.getImage(id); + else + bim = spriteManager.getSprite(id, 0); + if (bim == null) + return null; + if (!small) + return ImageUtil.resizeCanvas(bim, ICON_SIZE, ICON_SIZE); + if (id != SpriteID.SPELL_ICE_BARRAGE) + return ImageUtil.resizeImage(bim, SMALL_ICON_SIZE, SMALL_ICON_SIZE); + return ImageUtil.resizeCanvas(bim, SMALL_ICON_SIZE, SMALL_ICON_SIZE); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index 34db989c71..d2b39880ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -26,10 +26,18 @@ package net.runelite.client.plugins.raids; import com.google.inject.Binder; import com.google.inject.Provides; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; import java.text.DecimalFormat; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledExecutorService; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; @@ -39,9 +47,11 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.InstanceTemplates; +import net.runelite.api.ItemID; import net.runelite.api.NullObjectID; import static net.runelite.api.Perspective.SCENE_SIZE; import net.runelite.api.Point; +import net.runelite.api.SpriteID; import static net.runelite.api.SpriteID.TAB_QUESTS_BROWN_RAIDING_PARTY; import net.runelite.api.Tile; import net.runelite.api.VarPlayer; @@ -55,21 +65,26 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.ItemManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.SpriteManager; +import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.raids.solver.Layout; import net.runelite.client.plugins.raids.solver.LayoutSolver; import net.runelite.client.plugins.raids.solver.RotationSolver; +import net.runelite.client.ui.DrawManager; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.Text; +import net.runelite.client.util.HotkeyListener; @PluginDescriptor( name = "Chambers Of Xeric", description = "Show helpful information for the Chambers of Xeric raid", - tags = {"combat", "raid", "overlay", "pve", "pvm", "bosses"} + tags = {"combat", "raid", "overlay", "pve", "pvm", "bosses", "cox", "olm"} ) @Slf4j public class RaidsPlugin extends Plugin @@ -82,6 +97,10 @@ public class RaidsPlugin extends Plugin static final DecimalFormat POINTS_FORMAT = new DecimalFormat("#,###"); private static final String SPLIT_REGEX = "\\s*,\\s*"; private static final Pattern ROTATION_REGEX = Pattern.compile("\\[(.*?)]"); + private static final int LINE_COMPONENT_HEIGHT = 16; + + @Inject + private ItemManager itemManager; @Inject private ChatMessageManager chatMessageManager; @@ -92,6 +111,12 @@ public class RaidsPlugin extends Plugin @Inject private Client client; + @Inject + private DrawManager drawManager; + + @Inject + private ScheduledExecutorService executor; + @Inject private RaidsConfig config; @@ -110,6 +135,9 @@ public class RaidsPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private KeyManager keyManager; + @Getter private final ArrayList roomWhitelist = new ArrayList<>(); @@ -122,6 +150,9 @@ public class RaidsPlugin extends Plugin @Getter private final ArrayList layoutWhitelist = new ArrayList<>(); + @Getter + private final Map> recommendedItemsList = new HashMap<>(); + @Getter private Raid raid; @@ -346,6 +377,41 @@ public class RaidsPlugin extends Plugin updateList(roomBlacklist, config.blacklistedRooms()); updateList(rotationWhitelist, config.whitelistedRotations()); updateList(layoutWhitelist, config.whitelistedLayouts()); + updateMap(recommendedItemsList, config.recommendedItems()); + } + + private void updateMap(Map> map, String input) + { + map.clear(); + + Matcher m = ROTATION_REGEX.matcher(input); + while (m.find()) + { + String everything = m.group(1).toLowerCase(); + int split = everything.indexOf(','); + if (split < 0) + continue; + String key = everything.substring(0, split); + if (key.length() < 1) + continue; + String[] itemNames = everything.substring(split).split(SPLIT_REGEX); + + map.computeIfAbsent(key, k -> new ArrayList<>()); + + for (String itemName : itemNames) + { + if (itemName.equals("")) + continue; + if (itemName.equals("ice barrage")) + map.get(key).add(SpriteID.SPELL_ICE_BARRAGE); + else if (itemName.startsWith("salve")) + map.get(key).add(ItemID.SALVE_AMULETEI); + else if (itemManager.search(itemName).size() > 0) + map.get(key).add(itemManager.search(itemName).get(0).getId()); + else + log.info("RaidsPlugin: Could not find an item ID for item: " + itemName); + } + } } private void updateList(ArrayList list, String input) From 710745a56ff21a2fff2e728edfea85c9e71febf6 Mon Sep 17 00:00:00 2001 From: James <38226001+james-munson@users.noreply.github.com> Date: Sun, 21 Apr 2019 11:34:53 -0700 Subject: [PATCH 64/75] Added hide take, text outline to ground items etc (#35) * added smelting plugin * Added hide take, text outline to ground items --- .../grounditems/GroundItemsConfig.java | 22 +++ .../grounditems/GroundItemsOverlay.java | 9 ++ .../grounditems/GroundItemsPlugin.java | 30 ++++ .../plugins/smelting/SmeltingConfig.java | 45 ++++++ .../plugins/smelting/SmeltingOverlay.java | 136 ++++++++++++++++++ .../plugins/smelting/SmeltingPlugin.java | 129 +++++++++++++++++ .../plugins/smelting/SmeltingSession.java | 54 +++++++ 7 files changed, 425 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingSession.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java index f9c3a79e85..008429abf1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java @@ -358,4 +358,26 @@ public interface GroundItemsConfig extends Config { return false; } + + @ConfigItem( + position = 27, + keyName = "removeIgnored", + name = "Hide Ignored", + description = "Remove take option for items that are on the hidden items list." + ) + default boolean removeIgnored() + { + return false; + } + + @ConfigItem( + keyName = "toggleOutline", + name = "Text Outline", + description = "Use an outline around text instead of a text shadow", + position = 29 + ) + default boolean toggleOutline() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index 1406bb1747..17c0151ae7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -333,6 +333,15 @@ public class GroundItemsOverlay extends Overlay drawRectangle(graphics, itemHighlightBox, topItem && mouseInHighlightBox ? Color.GREEN : color, highlighted != null, false); } + if (config.toggleOutline()) + { + graphics.setColor(Color.BLACK); + graphics.drawString(itemString, textX + 1, textY + 1); + graphics.drawString(itemString, textX - 1, textY - 1); + graphics.drawString(itemString, textX - 1, textY + 1); + graphics.drawString(itemString, textX + 1, textY - 1); + } + textComponent.setText(itemString); textComponent.setColor(color); textComponent.setPosition(new java.awt.Point(textX, textY)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index 6bb50180df..91718bab79 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -509,10 +509,40 @@ public class GroundItemsPlugin extends Plugin lastEntry.setTarget(lastEntry.getTarget() + " (" + quantity + ")"); } + if(config.removeIgnored() && event.getOption().equals("Take") && hiddenItemList.contains(Text.removeTags(event.getTarget()))) + { + menuEntries = removeOption(event.getOption(), event.getTarget()); + } + client.setMenuEntries(menuEntries); } } + private MenuEntry[] removeOption(String option, String target) + { + MenuEntry[] entries = client.getMenuEntries(); + int j = 0; + if(entries.length > 1) + { + MenuEntry[] newEntries = new MenuEntry[entries.length - 1]; + for (int i = 0; i < entries.length; ++i) + { + if (!(entries[i].getOption().equals(option) && entries[i].getTarget().equals(target))) + { + newEntries[j++] = entries[i]; + } + } + + return newEntries; + } + else + { + return entries; + } + + + } + void updateList(String item, boolean hiddenList) { final Set hiddenItemSet = new HashSet<>(hiddenItemList); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingConfig.java new file mode 100644 index 0000000000..611960ffe5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingConfig.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019, Stephen + * 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.smelting; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("smelting") +public interface SmeltingConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "statTimeout", + name = "Reset stats (minutes)", + description = "The time it takes for the current smelting session to be reset" + ) + default int statTimeout() + { + return 5; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java new file mode 100644 index 0000000000..9c2fd7ea34 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2019, Stephen + * 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.smelting; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.time.Instant; +import java.time.Duration; +import javax.inject.Inject; +import static net.runelite.api.AnimationID.SMITHING_SMELTING; +import static net.runelite.api.AnimationID.SMITHING_CANNONBALL; +import net.runelite.api.Client; +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import net.runelite.api.Skill; +import net.runelite.client.plugins.xptracker.XpTrackerService; +import net.runelite.client.ui.overlay.Overlay; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; +import net.runelite.client.ui.overlay.OverlayMenuEntry; +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; + +class SmeltingOverlay extends Overlay +{ + private static final int SMELT_TIMEOUT = 5; + + private final Client client; + private final SmeltingPlugin plugin; + private final SmeltingConfig config; + private final XpTrackerService xpTrackerService; + + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + public SmeltingOverlay(Client client, SmeltingPlugin plugin, SmeltingConfig config, XpTrackerService xpTrackerService) + { + super(plugin); + setPosition(OverlayPosition.TOP_LEFT); + this.client = client; + this.plugin = plugin; + this.config = config; + this.xpTrackerService = xpTrackerService; + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Smelting overlay")); + } + + @Override + public Dimension render(Graphics2D graphics) + { + SmeltingSession session = plugin.getSession(); + if (session.getLastItemSmelted() == null) + { + return null; + } + + panelComponent.getChildren().clear(); + + if (isSmelting() || Duration.between(session.getLastItemSmelted(), Instant.now()).getSeconds() < SMELT_TIMEOUT) + { + panelComponent.getChildren().add(TitleComponent.builder() + .text("Smelting") + .color(Color.GREEN) + .build()); + } + else + { + panelComponent.getChildren().add(TitleComponent.builder() + .text("NOT smelting") + .color(Color.RED) + .build()); + } + + int actions = xpTrackerService.getActions(Skill.SMITHING); + if (actions > 0) + { + if (plugin.getSession().getBarsSmelted() > 0) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Bars:") + .right(Integer.toString(session.getBarsSmelted())) + .build()); + } + if (plugin.getSession().getCannonBallsSmelted() > 0) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Cannonballs:") + .right(Integer.toString(session.getCannonBallsSmelted())) + .build()); + } + if (actions > 2) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Actions/hr:") + .right(Integer.toString(xpTrackerService.getActionsHr(Skill.SMITHING))) + .build()); + } + } + + return panelComponent.render(graphics); + + } + private boolean isSmelting() + { + switch (client.getLocalPlayer().getAnimation()) + { + case SMITHING_SMELTING: + case SMITHING_CANNONBALL: + return true; + default: + return false; + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java new file mode 100644 index 0000000000..50c72491c3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2019, Stephen + * 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.smelting; + +import com.google.inject.Provides; +import java.time.Duration; +import java.time.Instant; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.ChatMessageType; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameTick; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDependency; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.xptracker.XpTrackerPlugin; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "Smelting", + description = "Show Smelting stats", + tags = {"overlay", "skilling"} +) +@PluginDependency(XpTrackerPlugin.class) +public class SmeltingPlugin extends Plugin +{ + + @Inject + private SmeltingConfig config; + + @Inject + private SmeltingOverlay overlay; + + @Inject + private OverlayManager overlayManager; + + @Getter(AccessLevel.PACKAGE) + private SmeltingSession session; + + @Provides + SmeltingConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(SmeltingConfig.class); + } + + @Override + protected void startUp() throws Exception + { + session = null; + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + session = null; + } + + @Subscribe + public void onChatMessage(ChatMessage event) + { + if (event.getType() != ChatMessageType.SPAM) + { + return; + } + + if (event.getMessage().contains("You retrieve a bar of")) + { + if (session == null) + { + session = new SmeltingSession(); + } + session.setLastItemSmelted(Instant.now()); + session.increaseBarsSmelted(); + } + else if (event.getMessage().contains("You remove the cannonballs from the mould")) + { + if (session == null) + { + session = new SmeltingSession(); + } + session.setLastItemSmelted(Instant.now()); + session.increaseCannonBallsSmelted(); + + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (session.getLastItemSmelted() != null) + { + final Duration statTimeout = Duration.ofMinutes(config.statTimeout()); + final Duration sinceCaught = Duration.between(session.getLastItemSmelted(), Instant.now()); + + if (sinceCaught.compareTo(statTimeout) >= 0) + { + session.setLastItemSmelted(null); + } + } + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingSession.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingSession.java new file mode 100644 index 0000000000..c6b04acabc --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingSession.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, Stephen + * 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.smelting; + +import java.time.Instant; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; + +class SmeltingSession +{ + @Getter(AccessLevel.PACKAGE) + @Setter + private Instant lastItemSmelted; + + @Getter(AccessLevel.PACKAGE) + private int barsSmelted; + + @Getter(AccessLevel.PACKAGE) + private int cannonBallsSmelted; + + void increaseBarsSmelted() + { + barsSmelted++; + } + + void increaseCannonBallsSmelted() + { + cannonBallsSmelted += 4; + } +} \ No newline at end of file From f6873a3bdf52c85db9097b57efef7748c4410240 Mon Sep 17 00:00:00 2001 From: James <38226001+james-munson@users.noreply.github.com> Date: Sun, 21 Apr 2019 11:35:17 -0700 Subject: [PATCH 65/75] Add Skull Timer (#32) --- .../client/plugins/timers/GameTimer.java | 3 ++- .../client/plugins/timers/TimersPlugin.java | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java index 03473991f5..f187d27043 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java @@ -78,7 +78,8 @@ enum GameTimer STAFF_OF_THE_DEAD(ItemID.STAFF_OF_THE_DEAD, GameTimerImageType.ITEM, "Staff of the Dead", 1, ChronoUnit.MINUTES), ABYSSAL_SIRE_STUN(ItemID.ABYSSAL_ORPHAN, GameTimerImageType.ITEM, "Abyssal Sire Stun", 30, ChronoUnit.SECONDS, true), HOME_TELEPORT(SpriteID.SPELL_LUMBRIDGE_HOME_TELEPORT, GameTimerImageType.SPRITE, "Home Teleport", 30, ChronoUnit.MINUTES), - MINIGAME_TELEPORT(SpriteID.TAB_QUESTS_RED_MINIGAMES, GameTimerImageType.SPRITE, "Minigame Teleport", 20, ChronoUnit.MINUTES); + MINIGAME_TELEPORT(SpriteID.TAB_QUESTS_RED_MINIGAMES, GameTimerImageType.SPRITE, "Minigame Teleport", 20, ChronoUnit.MINUTES), + SKULL(SpriteID.PLAYER_KILLER_SKULL_523, GameTimerImageType.SPRITE, "Skull", 20, ChronoUnit.MINUTES); @Getter private final Duration duration; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index 5672ffdd31..18a97e0f00 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -43,6 +43,7 @@ import net.runelite.api.NPC; import net.runelite.api.NpcID; import net.runelite.api.Player; import net.runelite.api.Prayer; +import net.runelite.api.SkullIcon; import net.runelite.api.Varbits; import net.runelite.api.WorldType; import net.runelite.api.coords.WorldPoint; @@ -120,6 +121,7 @@ public class TimersPlugin extends Plugin private int lastAnimation; private boolean loggedInRace; private boolean widgetHiddenChangedOnPvpWorld; + private boolean skulledLastTick = false; @Inject private ItemManager itemManager; @@ -608,6 +610,21 @@ public class TimersPlugin extends Plugin Player player = client.getLocalPlayer(); WorldPoint currentWorldPoint = player.getWorldLocation(); + final boolean isSkulled = player.getSkullIcon() != null && player.getSkullIcon() != SkullIcon.SKULL_FIGHT_PIT; + + if (isSkulled != skulledLastTick) + { + skulledLastTick = isSkulled; + if (isSkulled) + { + createGameTimer(SKULL); + } + else + { + removeGameTimer(SKULL); + } + } + if (freezeTimer != null) { // assume movement means unfrozen From cbb94b499b485cdf1c954ab336098784016de6eb Mon Sep 17 00:00:00 2001 From: zeruth Date: Sun, 21 Apr 2019 17:55:47 -0400 Subject: [PATCH 66/75] Remove plugins TempleTrek Stronghold SlayerMusiq PlankMakeHelper --- .../kittennotifier/KittenNotifierConfig.java | 21 -- .../kittennotifier/KittenNotifierPlugin.java | 86 -------- .../plankmakehelper/PlankMakeOverlay.java | 88 -------- .../plankmakehelper/PlankMakePlugin.java | 50 ----- .../plugins/slayermusiq/QuestGuideLinks.java | 207 ------------------ .../slayermusiq/SlayermusiqPlugin.java | 153 ------------- .../spellbookfixer/SpellbookFixerConfig.java | 110 ---------- .../spellbookfixer/SpellbookFixerPlugin.java | 171 --------------- .../plugins/stronghold/StrongholdAnswer.java | 93 -------- .../plugins/stronghold/StrongholdPlugin.java | 108 --------- .../templetrek/TempleTrekBogOverlay.java | 68 ------ .../plugins/templetrek/TempleTrekConfig.java | 55 ----- .../plugins/templetrek/TempleTrekOverlay.java | 78 ------- .../plugins/templetrek/TempleTrekPlugin.java | 137 ------------ 14 files changed, 1425 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java deleted file mode 100644 index b4d567b16a..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.runelite.client.plugins.kittennotifier; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("kittennotifier") -public interface KittenNotifierConfig extends Config{ - @ConfigItem( - keyName = "absolutelyNeeded", - name = "Notify only on Absolute Need", - description = "Only notify when kitten absolutely needs food or attention." - ) - default boolean absolutelyNeeded() { return false; } - @ConfigItem( - keyName = "catOwned", - name = "", - description = "", - hidden = true - ) - default boolean catOwned() { return false; } -} 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 deleted file mode 100644 index 584cbcde8c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kittennotifier/KittenNotifierPlugin.java +++ /dev/null @@ -1,86 +0,0 @@ -package net.runelite.client.plugins.kittennotifier; -import com.google.inject.Provides; -import net.runelite.api.ChatMessageType; -import net.runelite.api.events.ChatMessage; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.NpcActionChanged; -import net.runelite.api.events.NpcSpawned; -import net.runelite.client.Notifier; -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.api.NPC; -import net.runelite.api.Client; -import javax.inject.Inject; - -@PluginDescriptor( - name = "Kitten Notifier", - description = "Sends a notification when your kitten needs food, attention, or is grown.", - tags = {"kitten, notifications"}, - type = "utility" -) -public class KittenNotifierPlugin extends Plugin{ - - public boolean catOwned = false; - @Inject - private Notifier notifier; - @Inject - private KittenNotifierConfig config; - @Inject - private Client client; - @Provides - KittenNotifierConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(KittenNotifierConfig.class); - } - @Subscribe - public void onChatMessage(ChatMessage event) { - if (event.getType() == ChatMessageType.ENGINE && !config.catOwned()) { - if (!config.absolutelyNeeded()) { - if (event.getMessage().contentEquals("Your kitten is hungry.")) { - notifier.notify("Your kitten is hungry."); - } - if (event.getMessage().contentEquals("Your kitten wants attention.")) { - notifier.notify("Your kitten wants attention."); - } - } - if (event.getMessage().contentEquals("Your kitten is very hungry.")) { - notifier.notify("Your kitten is very hungry."); - } - if (event.getMessage().contentEquals("Your kitten really wants attention.")) { - notifier.notify("Your kitten really wants attention."); - } - } - } - @Subscribe - public void onGameTick(GameTick event) { - if (!config.catOwned()) { - for (NPC npc : client.getNpcs()) { - if (npc.getInteracting()!=null) - if (npc.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) { - if (npc.getName().equals("Cat") && !config.catOwned()) { - // If this if statement is included in previous it could null. - catOwned = true; - notifier.notify("Your kitten has grown into a cat."); - } - } - } - } - } - @Subscribe - public void onNpcSpawned(NpcSpawned event) { - NPC cat = event.getNpc(); - if (cat.getInteracting()!=null) - if (cat.getInteracting().getName().equalsIgnoreCase(client.getLocalPlayer().getName())) { - if (cat.getName().contains("itten") && !config.catOwned()) { - catOwned = false; - } - } - else if (cat.getName().equals("Cat")) { - if (cat.getInteracting().getName().equalsIgnoreCase(client.getLocalPlayer().getName())) { - catOwned = true; - } - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java deleted file mode 100644 index 8295f294b1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakeOverlay.java +++ /dev/null @@ -1,88 +0,0 @@ -package net.runelite.client.plugins.plankmakehelper; - -import net.runelite.api.*; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.widgets.WidgetItem; -import net.runelite.client.ui.overlay.*; - -import javax.inject.Inject; -import java.awt.*; - -public class PlankMakeOverlay extends Overlay { - - private final PlankMakePlugin plugin; - private final Client client; - - @Inject - public PlankMakeOverlay(final PlankMakePlugin plugin, final Client client) { - super(plugin); - this.plugin = plugin; - this.client = client; - - setPosition(OverlayPosition.DETACHED); - setLayer(OverlayLayer.ALWAYS_ON_TOP); - setPriority(OverlayPriority.MED); - } - - @Override - public Dimension render(Graphics2D graphics) { - if (hasPlankableItems()) { - renderInventory(graphics); - renderPlankMakeSpell(graphics); - } - return null; - } - - private void renderInventory(Graphics2D graphics) { - Widget inventory = client.getWidget(WidgetInfo.INVENTORY); - - int firstItemSeenIndex = -1; - - if (inventory != null) { - for (WidgetItem item : inventory.getWidgetItems()) { - if (PlankMakePlugin.isLogAndPlankable(item.getId())) { - if (firstItemSeenIndex == -1) { - firstItemSeenIndex = item.getIndex(); - } - if (!inventory.isHidden()) { - if (item.getIndex() != firstItemSeenIndex) { - OverlayUtil.renderPolygon(graphics, RectangleToPolygon(item.getCanvasBounds()), Color.BLUE); - } - } - } - } - if (firstItemSeenIndex != -1) { - OverlayUtil.renderPolygon(graphics, RectangleToPolygon(inventory.getWidgetItem(firstItemSeenIndex).getCanvasBounds()), Color.CYAN); - } - } - } - - private void renderPlankMakeSpell(Graphics2D graphics) { - Widget plankMakeSpell = client.getWidget(218,128); - if (plankMakeSpell != null && (plankMakeSpell.getCanvasLocation().getX() != 29 & plankMakeSpell.getCanvasLocation().getY() != 32)) { - OverlayUtil.renderPolygon(graphics, RectangleToPolygon(plankMakeSpell.getBounds()), Color.CYAN); - } - } - - private boolean hasPlankableItems() { - ItemContainer invo = client.getItemContainer(InventoryID.INVENTORY); - if (invo != null) { - if (invo.getItems().length > 0) { - for (Item item : invo.getItems()) { - if (PlankMakePlugin.isLogAndPlankable(item.getId())) { - return true; - } - } - } - } - return false; - } - - static Polygon RectangleToPolygon(Rectangle rect) { - int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x}; - int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height}; - return new Polygon(xpoints, ypoints, 4); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java deleted file mode 100644 index 87c35c17b1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/plankmakehelper/PlankMakePlugin.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.runelite.client.plugins.plankmakehelper; - -import net.runelite.api.Client; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.ui.overlay.OverlayManager; - -import javax.inject.Inject; - -@PluginDescriptor( - name = "Plank Make Helper", - description = "Highlights planks and plank make spell", - tags = {"overlay", "plankmaking", "lunar", "money", "moneymaking", "gp"}, - type = "utility" -) - -public class PlankMakePlugin extends Plugin { - - @Inject - private OverlayManager overlayManager; - - @Inject - private Client client; - - @Inject - private PlankMakeOverlay overlay; - - @Override - protected void startUp() { - overlayManager.add(overlay); - } - - @Override - protected void shutDown() { - overlayManager.remove(overlay); - } - - static boolean isLogAndPlankable(int itemID) { - switch (itemID) { - case 6332: //mahogany - case 1521: //oak - case 6333: //teak - case 1511: //plain - return true; - default: - return false; - } - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java deleted file mode 100644 index 078491bb4d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/QuestGuideLinks.java +++ /dev/null @@ -1,207 +0,0 @@ -package net.runelite.client.plugins.slayermusiq; - -import net.runelite.client.util.LinkBrowser; -import net.runelite.api.ChatMessageType; -import net.runelite.api.events.ChatMessage; -import net.runelite.client.chat.ChatColorType; -import net.runelite.client.chat.ChatMessageBuilder; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.chat.QueuedMessage; - -public class QuestGuideLinks { - private static final Link[] QUEST_GUIDE_LINKS = { - // Free Quests - new Link("Cook's Assistant", "https://www.youtube.com/watch?v=ehmtDRelj3c"), - new Link("Romeo & Juliet", "https://www.youtube.com/watch?v=rH_biWSNWVY"), - new Link("Demon Slayer", "https://www.youtube.com/watch?v=hgACrzJSiQk"), - new Link("Shield of Arrav", "https://www.youtube.com/watch?v=a_imLDKUdzg"), - new Link("Sheep Shearer", "https://www.youtube.com/watch?v=XFG3aNwK68s"), - new Link("The Restless Ghost", "https://www.youtube.com/watch?v=UkWNcsG_pXM"), - new Link("Ernest the Chicken", "https://www.youtube.com/watch?v=cq8NIVhSqh4"), - new Link("Vampire Slayer", "https://www.youtube.com/watch?v=FcEuxsDJWCU"), - new Link("Imp Catcher", "https://www.youtube.com/watch?v=LHgnl0FbOzk"), - new Link("Prince Ali Rescue", "https://www.youtube.com/watch?v=hrSPl1GfFaw"), - new Link("Doric's Quest", "https://www.youtube.com/watch?v=5TYyxHU27a4"), - new Link("Black Knights' Fortress", "https://www.youtube.com/watch?v=aekoZi3f9cU"), - new Link("Witch's Potion", "https://www.youtube.com/watch?v=XV4i5sPUvXo"), - new Link("The Knight's Sword", "https://www.youtube.com/watch?v=UkBWaI0rOqE"), - new Link("Goblin Diplomacy", "https://www.youtube.com/watch?v=P9BKOb_dLoY"), - new Link("Pirate's Treasure", "https://www.youtube.com/watch?v=zcD87PQW8Qk"), - new Link("Dragon Slayer", "https://www.youtube.com/watch?v=bMtCjlFOaBI"), - new Link("Rune Mysteries", "https://www.youtube.com/watch?v=l8ZhaN8uoS0"), - new Link("Misthalin Mystery", "https://www.youtube.com/watch?v=QlFqVAobAlQ"), - new Link("The Corsair Curse", "https://www.youtube.com/watch?v=wi7mUAHExz4"), - new Link("X Marks the Spot", "https://www.youtube.com/watch?v=GhRgvEG5jxQ"), - // Members Quests - new Link("Druidic Ritual", "https://www.youtube.com/watch?v=QIfU6HSmH4w"), - new Link("Lost City", "https://www.youtube.com/watch?v=T-kQNUSjFZI"), - new Link("Witch's House", "https://www.youtube.com/watch?v=TLsg7Wa-LUA"), - new Link("Merlin's Crystal", "https://www.youtube.com/watch?v=ESX-qriNtCE"), - new Link("Heroes' Quest", "https://www.youtube.com/watch?v=hK2N0WLKviE"), - new Link("Scorpion Catcher", "https://www.youtube.com/watch?v=xpqdec7_ZWg"), - new Link("Family Crest", "https://www.youtube.com/watch?v=0mk_Cgjr738"), - new Link("Monk's Friend", "https://www.youtube.com/watch?v=avi4y4G3Hcw"), - new Link("Temple of Ikov", "https://www.youtube.com/watch?v=5K7jDgr_4Z4"), - new Link("Clock Tower", "https://www.youtube.com/watch?v=GUCkkQFzyDw"), - new Link("Holy Grail", "https://www.youtube.com/watch?v=cgXoV1QlYco"), - new Link("Tree Gnome Village", "https://www.youtube.com/watch?v=T6Su__yuyRI"), - new Link("Fight Arena", "https://www.youtube.com/watch?v=4Nqjep2E5pw"), - new Link("Hazeel Cult", "https://www.youtube.com/watch?v=2_fhFJW6cNY"), - new Link("Sheep Herder", "https://www.youtube.com/watch?v=akC9FeYCG1Q"), - new Link("Plague City", "https://www.youtube.com/watch?v=Hf2wQQZL5CU"), - new Link("Waterfall Quest", "https://www.youtube.com/watch?v=xWBSnGkQTi4"), - new Link("Jungle Potion", "https://www.youtube.com/watch?v=xqLKsFz08As"), - new Link("The Grand Tree", "https://www.youtube.com/watch?v=N5e_Jus_E-Y"), - new Link("Underground Pass", "https://www.youtube.com/watch?v=5klGJg1wY8k"), - new Link("Observatory Quest", "https://www.youtube.com/watch?v=yxa9B6svv44"), - new Link("Watchtower", "https://www.youtube.com/watch?v=Vb10GoYP7FE"), - new Link("Dwarf Cannon", "https://www.youtube.com/watch?v=pROFg5jcCR0"), - new Link("Murder Mystery", "https://www.youtube.com/watch?v=P1IDGCA2f9o"), - new Link("The Dig Site", "https://www.youtube.com/watch?v=TOdcWV4MzuU"), - new Link("Gertrude's Cat", "https://www.youtube.com/watch?v=g7S09wA8EAY"), - new Link("Legends' Quest", "https://www.youtube.com/watch?v=Lid8enDEF_U"), - new Link("Death Plateau", "https://www.youtube.com/watch?v=SIQFmTvnb6w"), - new Link("Big Chompy Bird Hunting", "https://www.youtube.com/watch?v=s2fytMOHJXI"), - new Link("Elemental Workshop I", "https://www.youtube.com/watch?v=tbZD2RDqvfQ"), - new Link("Nature Spirit", "https://www.youtube.com/watch?v=Enf8vUWb5o0"), - new Link("Priest in Peril", "https://www.youtube.com/watch?v=fyYri6wUQIU"), - new Link("Regicide", "https://www.youtube.com/watch?v=KkWM-ok3C4Y"), - new Link("Tai Bwo Wannai Trio", "https://www.youtube.com/watch?v=Mdair5mvZL0"), - new Link("Troll Stronghold", "https://www.youtube.com/watch?v=zqmUs-f3AKA"), - new Link("Horror from the Deep", "https://www.youtube.com/watch?v=9htK8kb6DR8"), - new Link("Throne of Miscellania", "https://www.youtube.com/watch?v=fzGMnv2skBE"), - new Link("Monkey Madness I", "https://www.youtube.com/watch?v=VnoRfeBnPFA"), - new Link("Haunted Mine", "https://www.youtube.com/watch?v=cIc6loJHm9Q"), - new Link("Troll Romance", "https://www.youtube.com/watch?v=j2zifZVu7Gc"), - new Link("In Search of the Myreque", "https://www.youtube.com/watch?v=5nmYFHdAXAQ"), - new Link("Creature of Fenkenstrain", "https://www.youtube.com/watch?v=swqUVIs7B7M"), - new Link("Roving Elves", "https://www.youtube.com/watch?v=J3qf9DnT9cA"), - new Link("One Small Favour", "https://www.youtube.com/watch?v=ix_0-W3e9ps"), - new Link("Mountain Daughter", "https://www.youtube.com/watch?v=HETx_LX7aiY"), - new Link("Between a Rock...", "https://www.youtube.com/watch?v=cB11I45EGgA"), - new Link("The Golem", "https://www.youtube.com/watch?v=qpEHpiO6lLw"), - new Link("Desert Treasure", "https://www.youtube.com/watch?v=BuIqulIsICo"), - new Link("Icthlarin's Little Helper", "https://www.youtube.com/watch?v=wpNKm8_vUOM"), - new Link("Tears of Guthix", "https://www.youtube.com/watch?v=EMonDNI0uPk"), - new Link("The Lost Tribe", "https://www.youtube.com/watch?v=spZErjRnCdc"), - new Link("The Giant Dwarf", "https://www.youtube.com/watch?v=Z7PsGpOYgxY"), - new Link("Recruitment Drive", "https://www.youtube.com/watch?v=sOuzMpA_xtw"), - new Link("Mourning's Ends Part I", "https://www.youtube.com/watch?v=vuzAdk-h3c0"), - new Link("Garden of Tranquillity", "https://www.youtube.com/watch?v=7hbCzYnLCsQ"), - new Link("A Tail of Two Cats", "https://www.youtube.com/watch?v=SgN9Yw_YqHk"), - new Link("Wanted!", "https://www.youtube.com/watch?v=ZHZAKDCfXGs"), - new Link("Mourning's Ends Part II", "https://www.youtube.com/watch?v=FK5sLogGbU8"), - new Link("Rum Deal", "https://www.youtube.com/watch?v=I14CIu5x2S8"), - new Link("Shadow of the Storm", "https://www.youtube.com/watch?v=5ZvWd3XCQjI"), - new Link("Ratcatchers", "https://www.youtube.com/watch?v=s7G22fEuhTc"), - new Link("Spirits of the Elid", "https://www.youtube.com/watch?v=A1zAX55hZC0"), - new Link("Devious Minds", "https://www.youtube.com/watch?v=_UtlFmrWt1w"), - new Link("Enakhra's Lament", "https://www.youtube.com/watch?v=Y3kEIPYVaVE"), - new Link("Cabin Fever", "https://www.youtube.com/watch?v=k5DtxNXhOaw"), - new Link("Fairytale I - Growing Pains", "https://www.youtube.com/watch?v=cfGI9qFOmsg"), - new Link("Recipe for Disaster", "https://www.youtube.com/watch?v=hrAyyInJaTA"), - new Link("In Aid of the Myreque", "https://www.youtube.com/watch?v=O2Ru2NmuTaA"), - new Link("A Soul's Bane", "https://www.youtube.com/watch?v=dp8dp79qp6I"), - new Link("Rag and Bone Man", "https://www.youtube.com/watch?v=3owXSeN56W8"), - new Link("Swan Song", "https://www.youtube.com/watch?v=IpmERThXv2g"), - new Link("Royal Trouble", "https://www.youtube.com/watch?v=bVWUlKzNXEg"), - new Link("Death to the Dorgeshuun", "https://www.youtube.com/watch?v=2XJHuLhig98"), - new Link("Fairytale II - Cure a Queen", "https://www.youtube.com/watch?v=P6KkRk4_e3U"), - new Link("Lunar Diplomacy", "https://www.youtube.com/watch?v=vmeSKb7IBgQ"), - new Link("The Eyes of Glouphrie", "https://www.youtube.com/watch?v=0YCPwmZcxKA"), - new Link("Darkness of Hallowvale", "https://www.youtube.com/watch?v=QziKl99qdtU"), - new Link("Elemental Workshop II", "https://www.youtube.com/watch?v=Bb4E7ecIgv0"), - new Link("My Arm's Big Adventure", "https://www.youtube.com/watch?v=xa1KWOewgYA"), - new Link("Enlightened Journey", "https://www.youtube.com/watch?v=XAPthC8d7k0"), - new Link("Eagles' Peak", "https://www.youtube.com/watch?v=KDxIrrwXp7U"), - new Link("Animal Magnetism", "https://www.youtube.com/watch?v=kUyjXA7TaFU"), - new Link("Contact!", "https://www.youtube.com/watch?v=czn-yWABBWs"), - new Link("Cold War", "https://www.youtube.com/watch?v=0m1KpP-qKWI"), - new Link("The Fremennik Isles", "https://www.youtube.com/watch?v=EvxhiOWmraY"), - new Link("The Great Brain Robbery", "https://www.youtube.com/watch?v=ImHFASuNUN8"), - new Link("What Lies Below", "https://www.youtube.com/watch?v=f_9nVMGTtuo"), - new Link("Olaf's Quest", "https://www.youtube.com/watch?v=mXV5bM1NFMM"), - new Link("Dream Mentor", "https://www.youtube.com/watch?v=XDLUu0Kf0sE"), - new Link("Grim Tales", "https://www.youtube.com/watch?v=dFB0Q6v8Apw"), - new Link("King's Ransom", "https://www.youtube.com/watch?v=UJz9ZfF3uCY"), - new Link("Shilo Village", "https://www.youtube.com/watch?v=bDvBi8FT-QI"), - new Link("Biohazard", "https://www.youtube.com/watch?v=n9k87LwOGMk"), - new Link("Tower of Life", "https://www.youtube.com/watch?v=KReMcWpeY3k"), - new Link("Rag and Bone Man II", "https://www.youtube.com/watch?v=KGdHiDDUX_U"), - new Link("Zogre Flesh Eaters", "https://www.youtube.com/watch?v=vzm4949kXP4"), - new Link("Monkey Madness II", "https://www.youtube.com/watch?v=ykE5LbjABaI"), - new Link("Client of Kourend", "https://www.youtube.com/watch?v=Y-KIHF-cL9w"), - new Link("The Queen of Thieves", "https://www.youtube.com/watch?v=W94zFZVrHkQ"), - new Link("Bone Voyage", "https://www.youtube.com/watch?v=-VTR4p8kPmI"), - new Link("Dragon Slayer II", "https://www.youtube.com/watch?v=4BMb3Zwzk_U"), - new Link("The Depths of Despair", "https://www.youtube.com/watch?v=CaVUk2eAsKs"), - new Link("A Taste of Hope", "https://www.youtube.com/watch?v=VjdgEIizdSc"), - new Link("Tale of the Righteous", "https://www.youtube.com/watch?v=99yiv0tPl58"), - new Link("Making Friends with My Arm", "https://www.youtube.com/watch?v=DltzzhIsM_Q"), - new Link("The Ascent of Arceuus", "https://www.youtube.com/watch?v=4VQnfrv6S18"), - new Link("The Forsaken Tower", "https://www.youtube.com/watch?v=con0sXl5NBY"), - new Link("Fishing Contest", "https://www.youtube.com/watch?v=XYSv37A_l5w"), - new Link("Tribal Totem", "https://www.youtube.com/watch?v=XkUEIjr886M"), - new Link("Sea Slug", "https://www.youtube.com/watch?v=oOZVfa5SkVQ"), - new Link("The Tourist Trap", "https://www.youtube.com/watch?v=0bmSCCepMvo"), - new Link("Eadgar's Ruse", "https://www.youtube.com/watch?v=aVQ3DjTElXg"), - new Link("Shades of Mort'ton", "https://www.youtube.com/watch?v=eF05R8OMxgg"), - new Link("The Fremennik Trials", "https://www.youtube.com/watch?v=YUIvEgcvl5c"), - new Link("Ghosts Ahoy", "https://www.youtube.com/watch?v=aNBkLOywDfM"), - new Link("The Feud", "https://www.youtube.com/watch?v=nlBSc9IUklA"), - new Link("Forgettable Tale...", "https://www.youtube.com/watch?v=3HvFd6AxNU0"), - new Link("Making History", "https://www.youtube.com/watch?v=bOTGi2zAuhs"), - new Link("The Hand in the Sand", "https://www.youtube.com/watch?v=gdNLcZ-l1Lw"), - new Link("The Slug Menace", "https://www.youtube.com/watch?v=BRQbdr3JEZ8"), - new Link("Another Slice of H.A.M.", "https://www.youtube.com/watch?v=Yq3db7827Lk") - }; - - private static class Link { - - private String questName; - private String url; - - public Link(String questName, String url) { - this.questName = questName; - this.url = url; - } - - public String getQuestName() { - return questName; - } - - public void openURL() { - LinkBrowser.browse(this.url); - } - - } - - private static boolean openGuide(String questName) { - for (Link link : QUEST_GUIDE_LINKS) { - if (link.getQuestName().equals(questName)) { - link.openURL(); - return true; - } - } - return false; - } - - private static void logQuestNotFoundError(String questName, ChatMessageManager chatMessageManager) { - String chatMessage = new ChatMessageBuilder() - .append(ChatColorType.HIGHLIGHT) - .append("Could not find Slayermusiq1 guide for " + questName) - .build(); - - chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.CONSOLE) - .runeLiteFormattedMessage(chatMessage) - .build()); - } - - public static void tryOpenGuide(String questName, ChatMessageManager chatMessageManager) { - boolean success = openGuide(questName); - if (!success) { - logQuestNotFoundError(questName, chatMessageManager); - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java deleted file mode 100644 index c856886cb2..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2018, Jeremy Berchtold - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// Based off RuneLite's Wiki Plugin -/* - * Copyright (c) 2018 Abex - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.slayermusiq; - -import com.google.inject.Provides; -import com.google.common.primitives.Ints; -import java.awt.Dimension; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.inject.Inject; -import javax.swing.SwingUtilities; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.client.util.Text; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; - -@PluginDescriptor( - name = "Slayermusiq1 Guides", - description = "Adds a right-click option to go to Slayermusiq1's guides from the quest tab", - tags = {"quest", "guide", "slayermusiq"}, - type = "utility" -) -@Slf4j -public class SlayermusiqPlugin extends Plugin -{ - - private static final int[] QUESTLIST_WIDGET_IDS = new int[] - { - WidgetInfo.QUESTLIST_FREE_CONTAINER.getId(), - WidgetInfo.QUESTLIST_MEMBERS_CONTAINER.getId(), - WidgetInfo.QUESTLIST_MINIQUEST_CONTAINER.getId(), - }; - - private static final String MENUOP_SLAYERMUSIQ = "Slayermusiq"; - - @Inject - private Client client; - - @Inject - private ChatMessageManager chatMessageManager; - - @Override - protected void startUp() throws Exception - { - // - } - - @Override - protected void shutDown() throws Exception - { - // - } - - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) - { - int widgetID = event.getActionParam1(); - if (Ints.contains(QUESTLIST_WIDGET_IDS, widgetID) && "Read Journal:".equals(event.getOption())) { - MenuEntry[] menuEntries = client.getMenuEntries(); - - MenuEntry newMenuEntry = createSlayermusiqOptionMenuEntry(event); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - menuEntries[menuEntries.length - 1] = newMenuEntry; - - client.setMenuEntries(menuEntries); - } - } - - @Subscribe - private void onMenuOptionClicked(MenuOptionClicked ev) { - if (ev.getMenuAction() == MenuAction.RUNELITE && ev.getMenuOption().equals(MENUOP_SLAYERMUSIQ)) { - ev.consume(); - String quest = Text.removeTags(ev.getMenuTarget()); - QuestGuideLinks.tryOpenGuide(quest, chatMessageManager); - } - } - - private MenuEntry createSlayermusiqOptionMenuEntry(MenuEntryAdded event) { - int widgetIndex = event.getActionParam0(); - int widgetID = event.getActionParam1(); - - MenuEntry menuEntry = new MenuEntry(); - menuEntry.setTarget(event.getTarget()); - menuEntry.setOption(MENUOP_SLAYERMUSIQ); - menuEntry.setParam0(widgetIndex); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - return menuEntry; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java deleted file mode 100644 index bb16cd3709..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerConfig.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.runelite.client.plugins.spellbookfixer; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("spellbookfixer") -public interface SpellbookFixerConfig extends Config -{ - @ConfigItem(position = 0, keyName = "shouldHideOthers", name = "Hide Others", description = "Toggle on to hide spells not useful for pking that cannot be filtered otherwise.") - default boolean shouldHideOthers() - { - return false; - } - - //ice blitz - @ConfigItem(position = 1, keyName = "shouldModifyIceBlitz", name = "Ice Blitz", description = "Toggle on to enable Ice Blitz modifications.") - default boolean shouldModifyIceBlitz() { return false; } - @ConfigItem(position = 2, keyName = "getBlitzPositionX", name = "Ice Blitz Pos X", description = "Modifies the X-axis position of Ice Blitz.") - default int getBlitzPositionX() - { - return 0; - } - @ConfigItem(position = 3, keyName = "getBlitzPositionY", name = "Ice Blitz Pos Y", description = "Modifies the Y-axis position of Ice Blitz.") - default int getBlitzPositionY() - { - return 118; - } - @ConfigItem(position = 4, keyName = "getBlitzSize", name = "Ice Blitz Size", description = "Modifies the width of Ice Blitz.") - default int getBlitzSize() - { - return 80; - } - - //ice barrage - @ConfigItem(position = 5, keyName = "shouldModifyIceBarrage", name = "Ice Barrage", description = "Toggle on to enable Ice Barrage modifications.") - default boolean shouldModifyIceBarrage() { return false; } - @ConfigItem(position = 6, keyName = "getBarragePositionX", name = "Ice Barrage Pos X", description = "Modifies the X-axis position of Ice Barrage.") - default int getBarragePositionX() - { - return 0; - } - @ConfigItem(position = 7, keyName = "getBarragePositionY", name = "Ice Barrage Pos X", description = "Modifies the X-axis position of Ice Barrage.") - default int getBarragePositionY() - { - return 0; - } - @ConfigItem(position = 8, keyName = "getBarrageSize", name = "Ice Barrage Size", description = "Modifies the width position of Ice Barrage.") - default int getBarrageSize() - { - return 80; - } - - //vengeance - @ConfigItem(position = 9, keyName = "shouldModifyVengeance", name = "Vengeance", description = "Toggle on to enable Vengeance modifications.") - default boolean shouldModifyVengeance() { return false; } - @ConfigItem(position = 10, keyName = "getVengeancePositionX", name = "Vengeance Pos X", description = "Modifies the X-axis position of Vengeance.") - default int getVengeancePositionX() - { - return 0; - } - @ConfigItem(position = 11, keyName = "getVengeancePositionY", name = "Vengeance Pos X", description = "Modifies the X-axis position of Vengeance.") - default int getVengeancePositionY() - { - return 0; - } - @ConfigItem(position = 12, keyName = "getVengeanceSize", name = "Vengeance Size", description = "Modifies the width position of Vengeance.") - default int getVengeanceSize() - { - return 80; - } - - //teleblock - @ConfigItem(position = 13, keyName = "shouldModifyTeleBlock", name = "TeleBlock", description = "Toggle on to enable TeleBlock modifications.") - default boolean shouldModifyTeleBlock() { return false; } - @ConfigItem(position = 14, keyName = "getTeleBlockPositionX", name = "TeleBlock Pos X", description = "Modifies the X-axis position of TeleBlock.") - default int getTeleBlockPositionX() - { - return 0; - } - @ConfigItem(position = 15, keyName = "getTeleBlockPositionY", name = "TeleBlock Pos X", description = "Modifies the X-axis position of TeleBlock.") - default int getTeleBlockPositionY() - { - return 0; - } - @ConfigItem(position = 16, keyName = "getTeleBlockSize", name = "TeleBlock Size", description = "Modifies the width position of TeleBlock.") - default int getTeleBlockSize() - { - return 80; - } - - //entangle - @ConfigItem(position = 17, keyName = "shouldModifyEntangle", name = "Entangle", description = "Toggle on to enable Entangle modifications.") - default boolean shouldModifyEntangle() { return false; } - @ConfigItem(position = 18, keyName = "getEntanglePositionX", name = "Entangle Pos X", description = "Modifies the X-axis position of Entangle.") - default int getEntanglePositionX() - { - return 0; - } - @ConfigItem(position = 19, keyName = "getEntanglePositionY", name = "Entangle Pos X", description = "Modifies the X-axis position of Entangle.") - default int getEntanglePositionY() - { - return 118; - } - @ConfigItem(position = 20, keyName = "getEntangleSize", name = "Entangle Size", description = "Modifies the width position of Entangle.") - default int getEntangleSize() - { - return 80; - } -} 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 deleted file mode 100644 index 4f4456e4fb..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbookfixer/SpellbookFixerPlugin.java +++ /dev/null @@ -1,171 +0,0 @@ -package net.runelite.client.plugins.spellbookfixer; - -import com.google.inject.Provides; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.WidgetLoaded; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetID; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; - -import javax.inject.Inject; - - -@PluginDescriptor( - name = "Spellbook Fixer", - description = "Resize and filter spellbook for PKing", - tags = {"resize", "spellbook", "magic", "spell", "pk", "book", "filter", "bogla"}, - type = "PVP" -) -@Slf4j -public class SpellbookFixerPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - SpellbookFixerConfig config; - - @Provides - SpellbookFixerConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(SpellbookFixerConfig.class); } - - @Override - protected void startUp() throws Exception - { - adjustSpellbook(); - } - - @Override - protected void shutDown() throws Exception - { - resetSpellbook(); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - adjustSpellbook(); - } - - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) - { - if (event.getGroupId() == WidgetID.SPELLBOOK_GROUP_ID) - adjustSpellbook(); - } - - @Subscribe - public void onGameTick(GameTick event) - { - adjustSpellbook(); - } - - private void adjustSpellbook() - { - if (client.getGameState() != GameState.LOGGED_IN) - return; - - try - { - if (config.shouldModifyIceBarrage()) - modifySpell(WidgetInfo.SPELL_ICE_BARRAGE, config.getBarragePositionX(), config.getBarragePositionY(), config.getBarrageSize()); - - if (config.shouldModifyIceBlitz()) - modifySpell(WidgetInfo.SPELL_ICE_BLITZ, config.getBlitzPositionX(), config.getBlitzPositionY(), config.getBlitzSize()); - - if (config.shouldModifyVengeance()) - modifySpell(WidgetInfo.SPELL_VENGEANCE, config.getVengeancePositionX(), config.getVengeancePositionY(), config.getVengeanceSize()); - - if (config.shouldModifyTeleBlock()) - modifySpell(WidgetInfo.SPELL_TELE_BLOCK, config.getTeleBlockPositionX(), config.getTeleBlockPositionY(), config.getTeleBlockSize()); - - if (config.shouldModifyEntangle()) - modifySpell(WidgetInfo.SPELL_ENTANGLE, config.getEntanglePositionX(), config.getEntanglePositionY(), config.getEntangleSize()); - - setSpellHidden(WidgetInfo.SPELL_BLOOD_BLITZ, config.shouldHideOthers()); - setSpellHidden(WidgetInfo.SPELL_VENGEANCE_OTHER, config.shouldHideOthers()); - setSpellHidden(WidgetInfo.SPELL_BIND, config.shouldHideOthers()); - setSpellHidden(WidgetInfo.SPELL_SNARE, config.shouldHideOthers()); - } - catch (Exception e) - { - //swallow - } - - - } - - private void resetSpellbook() - { - if (client.getGameState() != GameState.LOGGED_IN) - return; - - try - { - if (config.shouldModifyIceBarrage()) - modifySpell(WidgetInfo.SPELL_ICE_BARRAGE, config.getBarragePositionX(), config.getBarragePositionY(), 24); - - if (config.shouldModifyIceBlitz()) - modifySpell(WidgetInfo.SPELL_ICE_BLITZ, config.getBlitzPositionX(), config.getBlitzPositionY(), 24); - - if (config.shouldModifyVengeance()) - modifySpell(WidgetInfo.SPELL_VENGEANCE, config.getVengeancePositionX(), config.getVengeancePositionY(), 24); - - if (config.shouldModifyTeleBlock()) - modifySpell(WidgetInfo.SPELL_TELE_BLOCK, config.getTeleBlockPositionX(), config.getTeleBlockPositionY(), 24); - - if (config.shouldModifyEntangle()) - modifySpell(WidgetInfo.SPELL_ENTANGLE, config.getEntanglePositionX(), config.getEntanglePositionY(), 24); - - setSpellHidden(WidgetInfo.SPELL_BLOOD_BLITZ, false); - setSpellHidden(WidgetInfo.SPELL_VENGEANCE_OTHER, false); - setSpellHidden(WidgetInfo.SPELL_BIND, false); - setSpellHidden(WidgetInfo.SPELL_SNARE, false); - } - catch (Exception e) - { - //swallow - } - } - - private void modifySpell(WidgetInfo widgetInfo, int posX, int posY, int size) - { - Widget widget = client.getWidget(widgetInfo); - - if (widget == null) - return; - - try - { - widget.setOriginalX(posX); - widget.setOriginalY(posY); - widget.setOriginalWidth(size); - widget.setOriginalHeight(size); - widget.revalidate(); - } - catch (Exception e) - { - //swallow - } - - } - - private void setSpellHidden(WidgetInfo widgetInfo, boolean hidden) - { - Widget widget = client.getWidget(widgetInfo); - - if (widget == null) - return; - - widget.setHidden(hidden); - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java deleted file mode 100644 index 2146cd8708..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2019, FlaxOnEm - * 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.stronghold; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import net.runelite.api.widgets.Widget; - -import java.util.HashMap; -import java.util.Map; - -@Getter -@RequiredArgsConstructor -enum StrongholdAnswer { - PAIR_0("To pass you must answer me this: Hey adventurer!
You've been randomly selected for a prize of 1 year of
free membership! I'm just going to need some of your
account details so I can put it on your account!", "No way! I'm reporting you to Jagex!"), - PAIR_1("To pass you must answer me this: Can I leave my
account logged in while I'm out of the room?", "No."), - PAIR_2("To pass you must answer me this: How do I remove a
hijacker from my account?", "Use the Account Recovery System."), - PAIR_3("To pass you must answer me this: What do you do if
someone asks you for your password or bank PIN to
make you a player moderator?", "Don't give them the information and send an 'Abuse report'."), - PAIR_4("To pass you must answer me this: You're watching a
stream by someone claiming to be Jagex offering double
xp. What do you do?", "Report the stream as a scam. Real Jagex streams have a 'verified' mark."), - PAIR_5("To pass you must answer me this: My friend asks me
for my password so that he can do a difficult quest for
me. Do I give it to them?", "Don't give them my password."), - PAIR_6("To pass you must answer me this: Who can I give my
password to?", "Nobody."), - PAIR_7("To pass you must answer me this: How do I set up
two-factor authentication for my Old School RuneScape
account?", "Through account settings on oldschool.runescape.com."), - PAIR_8("To pass you must answer me this: What is an example
of a good bank PIN?", "The birthday of a famous person or event."), - PAIR_9("To pass you must answer me this: What should you do
if your real-life friend asks for your password so he
can check your stats?", "Don't give out your password to anyone. Not even close friends."), - PAIR_A("To pass you must answer me this: A player tells you to
search for a video online, click the link in the description
and comment on the forum post to win a cash prize.
What do you do?", "Report the player for phishing."), - PAIR_B("To pass you must answer me this: You have been
offered an opportunity to check out a free giveaway or
double XP signup via email or in game chat. What
should I do?", "Report the incident and do not click any links."), - PAIR_C("To pass you must answer me this: How do I set a
bank PIN?", "Talk to any banker."), - PAIR_D("To pass you must answer me this: What do I do if a
moderator asks me for my account details?", "Politely tell them no and then use the 'Report Abuse' button."), - PAIR_E("To pass you must answer me this: You are part way
through the Stronghold of Security when you have to
answer another question. After you answer the question,
you should...", "Read the text and follow the advice given."), - PAIR_F("To pass you must answer me this: Will Jagex prevent
me from saying my PIN in game?", "No."), - PAIR_G("that sound?", "No way! You'll just take my gold for your own! Reported!"), - PAIR_H("To pass you must answer me this: What should I do if
I receive an email asking me to verify my identity or
Account details due to suspicious activity?", "Don't click any links, forward the email to reportphishing@jagex.com."), - PAIR_I("To pass you must answer me this: A website claims that
they can make me a player moderator. What should I
do?", "Inform Jagex by emailing reportphishing@jagex.com."), - PAIR_J("react?", "Don't share your information and report the player."), - PAIR_K("To pass you must answer me this: What do you do if
someone asks you for your password or bank PIN to
make you a member for free?", "Don't tell them anything and click the 'Report Abuse' button."), - PAIR_L("To pass you must answer me this: Is it OK to buy an
Old School RuneScape account?", "No, you should never buy an account."), - PAIR_M("To pass you must answer me this: You have been
offered an opportunity to check out a free giveaway or
double XP signup via social media or stream. What
should I do?", "Report the incident and do not click any links."), - PAIR_N("To pass you must answer me this: Where is it safe to
use my Old School RuneScape password?", "Only on the Old School RuneScape website."), - PAIR_O("To pass you must answer me this: What is the best
way to secure your account?", "Authenticator and two-step login on my registered email."), - PAIR_P("To pass you must answer me this: Who is it ok to
share my account with?", "Nobody."), - PAIR_Q("To pass you must answer me this: What should you do
if another player messages you recommending a website
to purchase items and/or gold?", "Do not visit the website and report the player who messaged you."), - PAIR_R("To pass you must answer me this: Whose responsibility
is it to keep your account secure?", "Me."), - PAIR_S("To pass you must answer me this: Is it safe to pay
someone to level your account?", "No, you should never allow anyone to level your account."), - PAIR_T("To pass you must answer me this: What do I do if my
account is compromised?", "Secure my device and reset my password."), - PAIR_U("respond?", "Decline the offer and report that player."), - PAIR_V("To pass you must answer me this: A player says that
Jagex prevents you from saying your password
backwards in game. What do you do?", "Don't type in my password backwards and report the player."), - PAIR_W("To pass you must answer me this: What do I do if I
think I have a keylogger or virus?", "Virus scan my device then change my password."), - PAIR_X("To pass you must answer me this: What is the best
security step you can take to keep your registered
email secure?", "Set up 2 step authentication with my email provider."); - - static final Map MATCHES = new HashMap<>(); - - static { - for (StrongholdAnswer strongholdAnswer : StrongholdAnswer.values()) { - MATCHES.put(strongholdAnswer.question, strongholdAnswer.answer); - } - } - - private final String question; - private final String answer; - - static Widget findCorrect(final String question, final Widget[] widgets) { - final String s = MATCHES.get(question); - - for (Widget widget: widgets) { - if (widget != null && widget.getText().equals(s)) - return widget; - } - - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java deleted file mode 100644 index cae099dc1e..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2019, FlaxOnEm - * 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.stronghold; - -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.events.ClientTick; -import net.runelite.api.events.WidgetLoaded; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetID; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.util.ColorUtil; - -import javax.inject.Inject; -import java.awt.Color; - -@PluginDescriptor( - name = "Stronghold", - description = "Highlights the correct answer to Stronghold of Security questions", - tags = {"stronghold", "security", "overlay", "answer", "highlight"}, - type = "utility" -) -@Slf4j -public class StrongholdPlugin extends Plugin { - private static final Color ANSWER_COLOR = new Color(230, 0, 230); - - @Inject - private Client client; - - private boolean queueNPCDialogue; - private boolean queueNPCOption; - private String questionCache; - - @Subscribe - public void onWidgetLoaded(WidgetLoaded widgetLoaded) { - switch (widgetLoaded.getGroupId()) { - case WidgetID.DIALOG_NPC_GROUP_ID: - queueNPCDialogue = true; - break; - case WidgetID.DIALOG_OPTION_GROUP_ID: - queueNPCOption = true; - break; - } - } - - @Subscribe - public void onClientTick(ClientTick t) { - if (queueNPCDialogue) { - queueNPCDialogue = false; - onNPCDialogue(); - } - if (queueNPCOption) { - queueNPCOption = false; - onNPCOption(); - } - } - - private void onNPCDialogue() { - final Widget debugWidget = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT); - final String npcText = debugWidget.getText(); - if (StrongholdAnswer.MATCHES.containsKey(npcText)) - questionCache = npcText; - } - - private void onNPCOption() { - if (questionCache == null) - return; - - final Widget optionsWidget = client.getWidget(WidgetInfo.DIALOG_OPTION); - if (optionsWidget == null) - return; - - final Widget[] widgets = optionsWidget.getParent().getChildren(); - - final Widget answerWidget = StrongholdAnswer.findCorrect(questionCache, widgets); - questionCache = null; - if (answerWidget == null) - return; - - final String answerText = answerWidget.getText(); - answerWidget.setText(ColorUtil.wrapWithColorTag(answerText, ANSWER_COLOR)); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java deleted file mode 100644 index 119a70f245..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekBogOverlay.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2018, Frosty Fridge - * 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.templetrek; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; -import javax.inject.Inject; -import net.runelite.api.GroundObject; -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; - -public class TempleTrekBogOverlay extends Overlay -{ - private final TempleTrekConfig config; - private final TempleTrekPlugin plugin; - - private static final Color GREEN = new Color(0, 200, 83); - - @Inject - private TempleTrekBogOverlay(TempleTrekConfig config, TempleTrekPlugin plugin) - { - super(plugin); - this.config = config; - this.plugin = plugin; - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.LOW); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (config.bogMapActive()) - { - for (GroundObject bog : plugin.getBogList()) - { - Polygon bogPoly = bog.getCanvasTilePoly(); - OverlayUtil.renderPolygon(graphics, bogPoly, GREEN); - } - } - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java deleted file mode 100644 index 090d1a9cab..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2018, Frosty Fridge - * 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.templetrek; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("templetrek") -public interface TempleTrekConfig extends Config -{ - @ConfigItem( - keyName = "bogMapActive", - name = "Bog Map", - description = "Marks out a safe route through the bog event", - position = 0 - ) - default boolean bogMapActive() - { - return true; - } - - @ConfigItem( - keyName = "pointTrackerActive", - name = "Point Tracker", - description = "Track your Temple Trek reward points, which determine the size of your reward.", - position = 1 - ) - default boolean pointTrackerActive() - { - return true; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java deleted file mode 100644 index afbf4c88a5..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekOverlay.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2018, Frosty Fridge - * 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.templetrek; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import javax.inject.Inject; -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.components.LineComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; - -public class TempleTrekOverlay extends Overlay -{ - private final TempleTrekConfig config; - private final TempleTrekPlugin plugin; - - private final PanelComponent panelComponent = new PanelComponent(); - - @Inject - private TempleTrekOverlay(TempleTrekConfig config, TempleTrekPlugin plugin) - { - super(plugin); - this.config = config; - this.plugin = plugin; - setPosition(OverlayPosition.TOP_LEFT); - setPriority(OverlayPriority.LOW); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (config.pointTrackerActive() && plugin.isInTrek()) - { - int points = plugin.getRewardPoints(); - double percentage = plugin.getRewardPercentage() * 100; - panelComponent.getChildren().clear(); - panelComponent.getChildren().add(LineComponent.builder() - .left("Trek Points: ") - .right(Integer.toString(points)) - .rightColor(percentage < 25 ? Color.RED : percentage >= 25 && percentage < 50 ? Color.YELLOW : - percentage >= 50 && percentage < 75 ? Color.BLUE : Color.GREEN) - .build()); - panelComponent.getChildren().add(LineComponent.builder() - .left("Reward %: ") - .right(String.format("%.2f", percentage) + "%") - .rightColor(percentage < 25 ? Color.RED : percentage >= 25 && percentage < 50 ? Color.YELLOW : - percentage >= 50 && percentage < 75 ? Color.BLUE : Color.GREEN) - .build()); - return panelComponent.render(graphics); - } - return null; - } -} 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 deleted file mode 100644 index 2f2d7a8495..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/templetrek/TempleTrekPlugin.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2018, Frosty Fridge - * 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.templetrek; - -import com.google.inject.Provides; -import java.util.HashSet; -import java.util.Set; -import javax.inject.Inject; -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.GroundObject; -import net.runelite.api.ObjectID; -import net.runelite.api.Varbits; -import net.runelite.api.events.GroundObjectSpawned; -import net.runelite.api.events.VarbitChanged; -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.ui.overlay.OverlayManager; - -@PluginDescriptor( - name = "Temple Trekking", - description = "Helpers for the Temple Trek minigame", - tags = {"minigame", "overlay", "temple trek"}, - type = "utility" -) -public class TempleTrekPlugin extends Plugin -{ - - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private TempleTrekOverlay overlay; - - @Inject - private TempleTrekBogOverlay bogOverlay; - - @Inject - private TempleTrekConfig config; - - @Getter - private final Set bogList = new HashSet(); - - @Getter - private boolean inTrek = false; - - @Provides - TempleTrekConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(TempleTrekConfig.class); - } - - @Override - protected void startUp() - { - overlayManager.add(overlay); - overlayManager.add(bogOverlay); - } - - @Override - protected void shutDown() - { - overlayManager.remove(overlay); - overlayManager.remove(bogOverlay); - bogList.clear(); - } - - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) - { - GroundObject obj = event.getGroundObject(); - if (obj.getId() == ObjectID.BOG) - { - bogList.add(obj); - } - } - - //onGroundObjectDespawned is having issues handling this, so bogmap removal is here instead. - @Subscribe - public void onVarbitChanged(VarbitChanged event) - { - if (!bogList.isEmpty() && client.getVar(Varbits.TREK_EVENT) == 0) - { - bogList.clear(); - } - if (!inTrek && client.getVar(Varbits.TREK_STARTED) == 1) - { - inTrek = true; - } - else if (inTrek) - { - if (client.getVar(Varbits.TREK_STATUS) == 0 && client.getVar(Varbits.TREK_POINTS) == 0) - { - inTrek = false; - } - } - } - - protected int getRewardPoints() - { - return client.getVar(Varbits.TREK_POINTS); - } - - protected double getRewardPercentage() - { - double percentage = 0.000126945 * getRewardPoints() - 0.0357188951; - return Math.max(percentage, 0); - } - -} From b0b11cf9c89b840bdd7a0145c0c756ce564c6c60 Mon Sep 17 00:00:00 2001 From: Tyler Bochard Date: Sun, 21 Apr 2019 21:51:25 -0400 Subject: [PATCH 67/75] ByteCodePatcher (#39) Adds ErrorTransform -This prevents the client from sending any stack traces to Jagex. (a huge client detection system they use) --- .../client/rs/bytecode/ByteCodePatcher.java | 7 ++-- .../bytecode/transformers/ErrorTransform.java | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ErrorTransform.java diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java index 1ab7c2da3e..abd4a970dc 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java @@ -9,6 +9,7 @@ import net.runelite.client.RuneLite; import net.runelite.client.rs.ClientLoader; import net.runelite.client.rs.bytecode.transformers.ActorTransform; import net.runelite.client.rs.bytecode.transformers.ClientTransform; +import net.runelite.client.rs.bytecode.transformers.ErrorTransform; import net.runelite.client.rs.bytecode.transformers.PlayerTransform; import net.runelite.client.rs.bytecode.transformers.ProjectileTransform; import net.runelite.http.api.RuneLiteAPI; @@ -50,11 +51,13 @@ public class ByteCodePatcher { transformProjectile(projectileClass); Class playerClass = Class.forName(hooks.playerClass, false, child); transformPlayer(playerClass); - - //experimental Class clientClass = Class.forName("client", false, child); transformBlackjack(clientClass); + //Odds and ends + ErrorTransform et = new ErrorTransform(); + et.modify(null); + ByteCodeUtils.updateHijackedJar(); } catch (Exception e) { e.printStackTrace(); diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ErrorTransform.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ErrorTransform.java new file mode 100644 index 0000000000..0799613feb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ErrorTransform.java @@ -0,0 +1,36 @@ +package net.runelite.client.rs.bytecode.transformers; + +import javassist.CtClass; +import javassist.CtMethod; +import javassist.CtNewMethod; +import net.runelite.client.rs.bytecode.ByteCodePatcher; + +//This prevents the client from sending stack traces to Jagex at all, even classes outside of runelite. +public class ErrorTransform implements Transform { + public CtClass ct = null; + + //Where Runelites error interceptor is located, not auto-scraped. + private final String ERROR_INSTANCE_CLASS = "dp"; + private final String ERROR_INSTANCE_METHOD = "a"; + + @Override + public void modify(Class clazz) { + try { + System.out.println("[RuneLit] Transforming error method at class: "+ERROR_INSTANCE_CLASS); + ct = ByteCodePatcher.classPool.get(ERROR_INSTANCE_CLASS); + CtMethod error = ct.getDeclaredMethod(ERROR_INSTANCE_METHOD); + ct.removeMethod(error); + error = CtMethod.make("public static void a(String string, Throwable throwable, byte by) {"+ + " return;"+ + " }", ct); + ct.addMethod(error); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void transform() { + + } +} From a533e82677905998fa687e55bb8bfe03d99cbfaf Mon Sep 17 00:00:00 2001 From: Tyler Bochard Date: Sun, 21 Apr 2019 22:49:29 -0400 Subject: [PATCH 68/75] Update ErrorTransform.java (#40) Fixes hijacked method not being injected. Prints stack trace for us to view --- .../client/rs/bytecode/transformers/ErrorTransform.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ErrorTransform.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ErrorTransform.java index 0799613feb..89a3075970 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ErrorTransform.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ErrorTransform.java @@ -12,6 +12,7 @@ public class ErrorTransform implements Transform { //Where Runelites error interceptor is located, not auto-scraped. private final String ERROR_INSTANCE_CLASS = "dp"; private final String ERROR_INSTANCE_METHOD = "a"; + private final String ERROR_WARNING = "Tried to send a warning"; @Override public void modify(Class clazz) { @@ -21,9 +22,11 @@ public class ErrorTransform implements Transform { CtMethod error = ct.getDeclaredMethod(ERROR_INSTANCE_METHOD); ct.removeMethod(error); error = CtMethod.make("public static void a(String string, Throwable throwable, byte by) {"+ - " return;"+ + " throwable.printStackTrace();"+ + " System.out.println(\"[RuneLit] Prevented preceeding stack trace from being sent to Jagex\");"+ " }", ct); ct.addMethod(error); + ByteCodePatcher.modifiedClasses.add(ct); } catch (Exception e) { e.printStackTrace(); } From 77d9e18f014bc336f2e55ff3284c8089a2a0a2af Mon Sep 17 00:00:00 2001 From: zeruth Date: Sun, 21 Apr 2019 23:18:42 -0400 Subject: [PATCH 69/75] Hooks Now dumps protected fields / methods on rev update. makes it easier to look for things to transform :) --- .../net/runelite/client/rs/ClientLoader.java | 38 ++++++++++++++++--- .../runelite/client/rs/bytecode/Hooks.java | 1 + 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index 9c70435b0b..696acb15f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -45,13 +45,16 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.jar.Attributes; import java.util.jar.JarEntry; @@ -88,6 +91,7 @@ public class ClientLoader private final ClientConfigLoader clientConfigLoader; private ClientUpdateCheckMode updateCheckMode; private JarOutputStream target; + private static String[] preotectedStuffs; @Inject private ClientLoader( @@ -236,7 +240,7 @@ public class ClientLoader hooks.actorClass.equals("") || hooks.playerClass.equals("")) { System.out.println("[RuneLit] Bad hooks, re-scraping."); - ByteCodePatcher.clientInstance = getClientInstance(ByteCodeUtils.injectedClientFile.getPath()); + ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath()); ByteCodePatcher.findHooks(injectedClientFile.getPath()); } else { ByteCodePatcher.clientInstance = hooks.clientInstance; @@ -246,7 +250,8 @@ public class ClientLoader } else { System.out.println("[RuneLit] Hooks file not found, scraping hooks."); - ByteCodePatcher.clientInstance = getClientInstance(ByteCodeUtils.injectedClientFile.getPath()); + ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath()); + ByteCodePatcher.hooks.protectedStuff = preotectedStuffs; ByteCodePatcher.findHooks(injectedClientFile.getPath()); } @@ -335,7 +340,9 @@ public class ClientLoader return certificates.toArray(new Certificate[certificates.size()]); } - public static String getClientInstance(String jarFile) { + public static String initHookScrape(String jarFile) { + List protectedStuff = new ArrayList(); + String clientInstance = ""; JarClassLoader jcl = new JarClassLoader(); try { ClassPool classPool = new ClassPool(true); @@ -363,17 +370,26 @@ public class ClientLoader try { jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile)); Field[] fields = classToLoad.getDeclaredFields(); + Method[] methods = classToLoad.getDeclaredMethods(); for (Field f : fields) { try { + if (f.getName().contains("$")) { + System.out.println(classToLoad.getName()+"."+f.getName()); + protectedStuff.add(classToLoad.getName()+"."+f.getName()); + } if (f.getType().getName()=="client") { ByteCodePatcher.hooks.clientInstance = classToLoad.getName()+"."+f.getName(); - System.out.println("[RuneLit] Found client instance at "+classToLoad.getName()+"."+f.getName()); - return classToLoad.getName()+"."+f.getName(); + clientInstance = classToLoad.getName()+"."+f.getName(); } } catch (Exception e) { e.printStackTrace(); } } + for (Method m : methods) { + if (m.getName().contains("$")) { + protectedStuff.add(classToLoad.getName()+"."+m.getName()); + } + } } catch (FileNotFoundException e) { e.printStackTrace(); } @@ -391,6 +407,16 @@ public class ClientLoader } catch (Exception e) { e.printStackTrace(); } - return ""; + int i = 0; + for (Object o : protectedStuff) { + i++; + } + preotectedStuffs = new String[i]; + i = 0; + for (Object o : protectedStuff) { + preotectedStuffs[i] = (String) o; + i++; + } + return clientInstance; } } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java index 6d75fc81da..6bbd0ebe01 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java @@ -6,6 +6,7 @@ public class Hooks { public String actorClass = ""; public String projectileClass = ""; public String playerClass = ""; + public String[] protectedStuff; public Hooks() { } From 3a01eb67dc9755823dba601426b465d56c1eeeb7 Mon Sep 17 00:00:00 2001 From: zeruth Date: Mon, 22 Apr 2019 02:17:36 -0400 Subject: [PATCH 70/75] Various Fixes some smithing NPE's Adds flexo launch arg which enables flexo config plugin Adds external plugin to sorter using type "external" --- runelite-client/pom.xml | 5 + .../java/net/runelite/client/RuneLite.java | 8 + .../client/config/RuneLiteConfig.java | 2 +- .../java/net/runelite/client/flexo/Flexo.java | 248 ++++++++++++++++++ .../net/runelite/client/flexo/FlexoMouse.java | 88 +++++++ .../net/runelite/client/flexo/FlexoUtils.java | 16 ++ .../client/plugins/config/ConfigPanel.java | 30 ++- .../client/plugins/flexo/FlexoConfig.java | 180 +++++++++++++ .../client/plugins/flexo/FlexoOverlay.java | 42 +++ .../client/plugins/flexo/FlexoPlugin.java | 127 +++++++++ .../pluginsorter/PluginSorterConfig.java | 11 + .../pluginsorter/PluginSorterPlugin.java | 9 +- .../plugins/smelting/SmeltingOverlay.java | 3 + .../plugins/smelting/SmeltingPlugin.java | 1 + .../java/net/runelite/client/ui/ClientUI.java | 6 +- 15 files changed, 770 insertions(+), 6 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/flexo/Flexo.java create mode 100644 runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java create mode 100644 runelite-client/src/main/java/net/runelite/client/flexo/FlexoUtils.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index fda33e1eb1..de9c9846be 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -259,6 +259,11 @@ annotations 17.0.0 + + com.github.joonasvali.naturalmouse + naturalmouse + [1.0.0,) + diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 5f3cc9b6c3..4c8cefbdac 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -58,6 +58,7 @@ import net.runelite.client.menus.MenuManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginInstantiationException; import net.runelite.client.plugins.PluginManager; +import net.runelite.client.plugins.config.ConfigPanel; import net.runelite.client.rs.ClientUpdateCheckMode; import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.DrawManager; @@ -165,6 +166,7 @@ public class RuneLite parser.accepts("developer-mode", "Enable developer tools"); parser.accepts("debug", "Show extra debugging output"); parser.accepts("no-splash", "Do not show the splash screen"); + parser.accepts("flexo", "Allow flexo api configuration"); final ArgumentAcceptingOptionSpec updateMode = parser .accepts("rs", "Select client type") @@ -209,6 +211,12 @@ public class RuneLite logger.setLevel(Level.DEBUG); } + if (options.has("flexo")) + { + System.out.println("[RuneLit] Flexo config enabled"); + ConfigPanel.flexoConfigEnabled = true; + } + Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { log.error("Uncaught exception:", throwable); diff --git a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java index da48d2d116..78ec89a46f 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java @@ -71,7 +71,7 @@ public interface RuneLiteConfig extends Config ) default boolean enablePlugins() { - return false; + return true; } @ConfigItem( diff --git a/runelite-client/src/main/java/net/runelite/client/flexo/Flexo.java b/runelite-client/src/main/java/net/runelite/client/flexo/Flexo.java new file mode 100644 index 0000000000..298621b87e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/flexo/Flexo.java @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* +Modified java.awt.Robot for use with RuneLit. Hopefully we can make it stand far apart. +Uses +https://github.com/JoonasVali/NaturalMouseMotion +for mouse motion. + */ + +package net.runelite.client.flexo; + +import java.awt.*; +import java.awt.event.InputEvent; +import java.awt.peer.RobotPeer; +import java.util.Random; +import java.util.logging.Logger; + +import com.github.joonasvali.naturalmouse.api.MouseMotionFactory; +import net.runelite.api.Client; +import net.runelite.client.plugins.flexo.FlexoOverlay; +import net.runelite.client.ui.ClientUI; +import sun.awt.ComponentFactory; +import sun.awt.SunToolkit; + +public class Flexo extends java.awt.Robot{ + public static double scale; + public static Client client; + public static int fixedWidth = 765; + public static int fixedHeight = 503; + public static boolean isStretched; + public static int minDelay = 45; + public static MouseMotionFactory currentMouseMotionFactory; + private static final int MAX_DELAY = 60000; + private RobotPeer peer; + private static int LEGAL_BUTTON_MASK = 0; + + public Flexo() throws AWTException { + if (GraphicsEnvironment.isHeadless()) { + throw new AWTException("headless environment"); + } + init(GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice()); + } + + private void init(GraphicsDevice screen) throws AWTException { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + if (toolkit instanceof ComponentFactory) { + peer = ((ComponentFactory)toolkit).createRobot(this, screen); + disposer = new RobotDisposer(peer); + sun.java2d.Disposer.addRecord(anchor, disposer); + } + initLegalButtonMask(); + } + + private static synchronized void initLegalButtonMask() { + if (LEGAL_BUTTON_MASK != 0) return; + + int tmpMask = 0; + if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){ + if (Toolkit.getDefaultToolkit() instanceof SunToolkit) { + final int buttonsNumber = ((SunToolkit)(Toolkit.getDefaultToolkit())).getNumberOfButtons(); + for (int i = 0; i < buttonsNumber; i++){ + tmpMask |= InputEvent.getMaskForButton(i+1); + } + } + } + tmpMask |= InputEvent.BUTTON1_MASK| + InputEvent.BUTTON2_MASK| + InputEvent.BUTTON3_MASK| + InputEvent.BUTTON1_DOWN_MASK| + InputEvent.BUTTON2_DOWN_MASK| + InputEvent.BUTTON3_DOWN_MASK; + LEGAL_BUTTON_MASK = tmpMask; + } + private transient Object anchor = new Object(); + + static class RobotDisposer implements sun.java2d.DisposerRecord { + private final RobotPeer peer; + private RobotDisposer(RobotPeer peer) { + this.peer = peer; + } + public void dispose() { + if (peer != null) { + peer.dispose(); + } + } + } + + private RobotDisposer disposer; + + @Override + public synchronized void mouseMove(int x, int y) { + try { + //TODO: Must be better way to determine titlebar width + currentMouseMotionFactory.build(ClientUI.frame.getX()+x, ClientUI.frame.getY()+y+20).move(); + this.delay(getMinDelay()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Override + public synchronized void mousePress(int buttonID) { + if (buttonID<1 || buttonID >5) { + Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5."); + return; + } + peer.mousePress(InputEvent.getMaskForButton(buttonID)); + resetOverlay(); + this.delay(getMinDelay()); + } + + public void resetOverlay() { + FlexoOverlay.clickArea = null; + } + + public synchronized void mousePressAndRelease(int buttonID) { + if (buttonID<1 || buttonID >5) { + Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5."); + return; + } + peer.mousePress(InputEvent.getMaskForButton(buttonID)); + this.delay(getMinDelay()); + peer.mouseRelease(InputEvent.getMaskForButton(buttonID)); + resetOverlay(); + this.delay(getMinDelay()); + } + + @Override + public synchronized void mouseRelease(int buttonID) { + if (buttonID<1 || buttonID >5) { + Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5."); + return; + } + peer.mouseRelease(InputEvent.getMaskForButton(buttonID)); + resetOverlay(); + this.delay(getMinDelay()); + } + + private int getMinDelay() { + Random random = new Random(); + int random1 = random.nextInt(minDelay); + if (random1 < minDelay/2) + random1 = random.nextInt(minDelay/2) + minDelay/2+random.nextInt(minDelay/2); + return random1; + } + + private int getWheelDelay() { + //TODO: implement random timer. + return 40; + } + + /** + * Rotates the scroll wheel on wheel-equipped mice. + * + * @param wheelAmt number of "notches" to move the mouse wheel + * Negative values indicate movement up/away from the user, + * positive values indicate movement down/towards the user. + * + * @since 1.4 + */ + @Override + public synchronized void mouseWheel(int wheelAmt) { + for (int i : new int[wheelAmt]) { + peer.mouseWheel(wheelAmt); + this.delay(getWheelDelay()); + } + } + + /** + * Presses a given key. The key should be released using the + * keyRelease method. + *

+ * Key codes that have more than one physical key associated with them + * (e.g. KeyEvent.VK_SHIFT could mean either the + * left or right shift key) will map to the left key. + * + * @param keycode Key to press (e.g. KeyEvent.VK_A) + * @throws IllegalArgumentException if keycode is not + * a valid key + * @see #keyRelease(int) + * @see java.awt.event.KeyEvent + */ + @Override + public synchronized void keyPress(int keycode) { + peer.keyPress(keycode); + this.delay(getMinDelay()); + } + + @Override + public synchronized void keyRelease(int keycode) { + peer.keyRelease(keycode); + this.delay(getMinDelay()); + } + + @Override + public synchronized Color getPixelColor(int x, int y) { + Color color = new Color(peer.getRGBPixel(x, y)); + return color; + } + + /** + * Sleeps for the specified time. + * To catch any InterruptedExceptions that occur, + * Thread.sleep() may be used instead. + * @param ms time to sleep in milliseconds + * @throws IllegalArgumentException if ms is not between 0 and 60,000 milliseconds inclusive + * @see java.lang.Thread#sleep + */ + @Override + public synchronized void delay(int ms) { + checkDelayArgument(ms); + try { + Thread.sleep(ms); + } catch(InterruptedException ite) { + ite.printStackTrace(); + } + } + + private void checkDelayArgument(int ms) { + if (ms < 0 || ms > MAX_DELAY) { + throw new IllegalArgumentException("Delay must be to 0 to 60,000ms"); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java new file mode 100644 index 0000000000..2ba6a92181 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java @@ -0,0 +1,88 @@ +package net.runelite.client.flexo; + +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.client.ui.ClientUI; + +import java.awt.*; +import java.util.Random; + +public class FlexoMouse { + + /* + Should pass unstretched coords, handles all conversions here. + */ + public static net.runelite.api.Point getClickPoint(Rectangle rect) + { + if (Flexo.isStretched) + { + double wScale; + double hScale; + + if (Flexo.client.isResized()) { + wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width); + hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height); + } else { + wScale = ((double)Flexo.client.getStretchedDimensions().width) / Flexo.fixedWidth; + hScale = ((double)Flexo.client.getStretchedDimensions().height) / Flexo.fixedHeight; + } + + int xPadding = (int)rect.getWidth()/8; + int yPadding = (int)rect.getHeight()/8; + Random r = new Random(); + Rectangle clickRect = new Rectangle(); + clickRect.width = rect.width-xPadding; + clickRect.height = rect.height-yPadding; + clickRect.x = rect.x+xPadding; + clickRect.y = rect.y+yPadding; + int x = clickRect.x+r.nextInt(clickRect.width); + int y = clickRect.y+r.nextInt(clickRect.height); + double tScale = 1 + (Flexo.scale / 100); + + if (Flexo.client.isResized()) { + return new net.runelite.api.Point( (int)(x * wScale * tScale), (int)(y * hScale * tScale)); + } else { + return new net.runelite.api.Point( (int)(x * wScale), (int)(y * hScale)); + } + + } + //Fixed, not stretched + else if (!Flexo.client.isResized()) { + int fixedWidth = 765; + int widthDif = ClientUI.frame.getWidth(); + + if (ClientUI.pluginToolbar.isVisible()) { + widthDif -= ClientUI.pluginToolbar.getWidth(); + } + if (ClientUI.pluginPanel!=null) + widthDif -= ClientUI.pluginPanel.getWidth(); + + widthDif -= fixedWidth; + int xPadding = (int)rect.getWidth()/8; + int yPadding = (int)rect.getHeight()/8; + Random r = new Random(); + Rectangle clickRect = new Rectangle(); + clickRect.width = rect.width-xPadding; + clickRect.height = rect.height-yPadding; + clickRect.x = rect.x+xPadding+(widthDif/2); + clickRect.y = rect.y+yPadding; + int x = clickRect.x+r.nextInt(clickRect.width); + int y = clickRect.y+r.nextInt(clickRect.height); + return new net.runelite.api.Point(x, y); + } + //Resizable, not stretched + else { + int xPadding = (int)rect.getWidth()/8; + int yPadding = (int)rect.getHeight()/8; + Random r = new Random(); + Rectangle clickRect = new Rectangle(); + clickRect.width = rect.width-xPadding; + clickRect.height = rect.height-yPadding; + clickRect.x = rect.x+xPadding; + clickRect.y = rect.y+yPadding; + int x = clickRect.x+r.nextInt(clickRect.width); + int y = clickRect.y+r.nextInt(clickRect.height); + return new Point(x, y); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/flexo/FlexoUtils.java b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoUtils.java new file mode 100644 index 0000000000..7c3c9e1637 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoUtils.java @@ -0,0 +1,16 @@ +package net.runelite.client.flexo; + +import net.runelite.api.widgets.WidgetItem; +import net.runelite.client.plugins.flexo.FlexoOverlay; + +import java.awt.*; + +public class FlexoUtils { + + public static Rectangle getInvItemClickArea(WidgetItem item) { + Rectangle clickArea = item.getCanvasBounds(); + FlexoOverlay.clickArea = clickArea; + return clickArea; + } + +} 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 6759c7fa58..ea8908b824 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 @@ -107,6 +107,7 @@ public class ConfigPanel extends PluginPanel private static final String PINNED_PLUGINS_CONFIG_KEY = "pinnedPlugins"; private static final String RUNELITE_PLUGIN = "RuneLite"; private static final String CHAT_COLOR_PLUGIN = "Chat Color"; + public static boolean flexoConfigEnabled = false; private final PluginManager pluginManager; private final ConfigManager configManager; @@ -195,6 +196,26 @@ public class ConfigPanel extends PluginPanel { final List pinnedPlugins = getPinnedPluginNames(); + List externalPlugins = new ArrayList<>(); + // populate pluginList with all external Plugins + pluginManager.getPlugins().stream() + .filter(plugin -> plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("external")) + .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())); + externalPlugins.add(listItem); + }); + + externalPlugins.sort(Comparator.comparing(PluginListItem::getName)); + for (PluginListItem plugin : externalPlugins) + pluginList.add(plugin); + List pvmPlugins = new ArrayList<>(); // populate pluginList with all PVM Plugins pluginManager.getPlugins().stream() @@ -236,7 +257,7 @@ public class ConfigPanel extends PluginPanel pluginList.add(plugin); List utilPlugins = new ArrayList<>(); - // populate pluginList with all PVP Plugins + // populate pluginList with all utility Plugins pluginManager.getPlugins().stream() .filter(plugin -> plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("utility")) .forEach(plugin -> @@ -246,9 +267,16 @@ public class ConfigPanel extends PluginPanel final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config); final PluginListItem listItem = new PluginListItem(this, configManager, plugin, descriptor, config, configDescriptor); + if (listItem.getName().contains("Flexo") && flexoConfigEnabled) { + System.out.println("Started "+listItem.getName()); + listItem.setPinned(pinnedPlugins.contains(listItem.getName())); + utilPlugins.add(listItem); + } else if (!listItem.getName().contains("Flexo")) { System.out.println("Started "+listItem.getName()); listItem.setPinned(pinnedPlugins.contains(listItem.getName())); utilPlugins.add(listItem); + } + }); utilPlugins.sort(Comparator.comparing(PluginListItem::getName)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoConfig.java new file mode 100644 index 0000000000..b24a585f2e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoConfig.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2018, Adam + * 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.flexo; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +import java.awt.*; + +@ConfigGroup("flexo") +public interface FlexoConfig extends Config { + + @ConfigItem( + position = 0, + keyName = "overlayEnabled", + name = "Overlay Enabled", + description = "Shows clicking area and points etc." + ) + default boolean overlayEnabled() { + return true; + } + + @ConfigItem( + position = 1, + keyName = "minDelayAmount", + name = "Min Delay", + description = "Minimum delay that is applied to every action at the end (ms)" + ) + default int minDelayAmt() { + return 45; + } + + + @ConfigItem( + position = 2, + keyName = "reactionTime", + name = "Reaction Time", + description = "The base time between actions (ms)" + ) + default int getReactionTimeVariation() { + return 80; + } + + @ConfigItem( + position = 3, + keyName = "mouseDragSpeed", + name = "Mouse drag speed", + description = "The speed at which steps are executed. Keep at 49? cuz jagex mouse recorder?" + ) + default int getMouseDragSpeed() { + return 49; + } + + + @ConfigItem( + position = 4, + keyName = "overshoots", + name = "Overshoots", + description = "Higher number = more overshoots" + ) + default int getOvershoots() { + return 4; + } + + @ConfigItem( + position = 5, + keyName = "variatingFlow", + name = "Flow - Variating", + description = "" + ) + default boolean getVariatingFlow() { + return true; + } + + @ConfigItem( + position = 6, + keyName = "slowStartupFlow", + name = "Flow - Slow startup", + description = "" + ) + default boolean getSlowStartupFlow() { + return true; + } + + + @ConfigItem( + position = 7, + keyName = "slowStartup2Flow", + name = "Flow - Slow startup 2", + description = "" + ) + default boolean getSlowStartup2Flow() { + return true; + } + + @ConfigItem( + position = 8, + keyName = "jaggedFlow", + name = "Flow - Jagged", + description = "" + ) + default boolean getJaggedFlow() { + return true; + } + + @ConfigItem( + position = 9, + keyName = "interruptedFlow", + name = "Flow - Interrupted", + description = "" + ) + default boolean getInterruptedFlow() { + return false; + } + + + @ConfigItem( + position = 10, + keyName = "interruptedFlow2", + name = "Flow - Interrupted 2", + description = "" + ) + default boolean getInterruptedFlow2() { + return false; + } + + @ConfigItem( + position = 11, + keyName = "stoppingFlow", + name = "Flow - Stopping", + description = "" + ) + default boolean getStoppingFlow() { + return false; + } + + @ConfigItem( + position = 12, + keyName = "deviationSlopeDivider", + name = "Deviation slope divider", + description = "" + ) + default int getDeviationSlope() { + return 10; + } + + + @ConfigItem( + position = 13, + keyName = "noisinessDivider", + name = "Noisiness divider", + description = "" + ) + default String getNoisinessDivider() { + return "2.0D"; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoOverlay.java new file mode 100644 index 0000000000..99072b88bf --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoOverlay.java @@ -0,0 +1,42 @@ +package net.runelite.client.plugins.flexo; + +import net.runelite.api.Client; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import java.awt.*; +import java.awt.geom.Ellipse2D; + +public class FlexoOverlay extends Overlay { + + public static Rectangle clickArea; + + @Inject + private Client client; + + @Inject + private FlexoPlugin plugin; + + @Inject + private FlexoConfig config; + + @Inject + public FlexoOverlay(@Nullable Client client, FlexoPlugin plugin, FlexoConfig config) { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_WIDGETS); + this.client = client; + this.plugin = plugin; + this.config = config; + } + + + @Override + public Dimension render(Graphics2D graphics) { + if (clickArea!=null) + graphics.draw(clickArea); + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java new file mode 100644 index 0000000000..7cd7b961bc --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java @@ -0,0 +1,127 @@ +package net.runelite.client.plugins.flexo; + +import com.github.joonasvali.naturalmouse.api.MouseMotionFactory; +import com.github.joonasvali.naturalmouse.support.DefaultNoiseProvider; +import com.github.joonasvali.naturalmouse.support.DefaultOvershootManager; +import com.github.joonasvali.naturalmouse.support.DefaultSpeedManager; +import com.github.joonasvali.naturalmouse.support.Flow; +import com.github.joonasvali.naturalmouse.support.SinusoidalDeviationProvider; +import com.github.joonasvali.naturalmouse.util.FlowTemplates; +import com.google.inject.Provides; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameTick; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.flexo.Flexo; +import net.runelite.client.flexo.FlexoUtils; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.stretchedmode.StretchedModeConfig; +import net.runelite.client.ui.overlay.OverlayManager; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; + +@PluginDescriptor( + name = "Flexo Config", + description = "Customizes Flexo, the MouseInput Assistant ;)", + tags = {"flexo", "null"}, + type = "utility" +) +@Slf4j +public class FlexoPlugin extends Plugin { + + @Inject + private Client client; + + @Inject + private ConfigManager configManager; + + @Inject + private OverlayManager overlayManager; + + @Inject + private FlexoOverlay overlay; + + @Provides + FlexoConfig getConfig(ConfigManager configManager) { + return configManager.getConfig(FlexoConfig.class); + } + + @Subscribe + private void onConfigChanged(ConfigChanged event) { + if (event.getKey().compareTo("overlayEnabled")==0) { + if (getConfig(configManager).overlayEnabled()) { + overlayManager.add(overlay); + } else { + overlayManager.remove(overlay); + } + } + updateMouseMotionFactory(); + } + + @Subscribe + public void onGameTick(GameTick event) { + Flexo.isStretched = client.isStretchedEnabled(); + Flexo.scale = configManager.getConfig(StretchedModeConfig.class).scalingFactor(); + } + + private void updateMouseMotionFactory() { + Flexo.minDelay = getConfig(configManager).minDelayAmt(); + MouseMotionFactory factory = new MouseMotionFactory(); + //TODO:Add Options for various flows to allow more personalization + List flows = new ArrayList<>(); + + //Always add random + flows.add(new Flow(FlowTemplates.random())); + + if (getConfig(configManager).getVariatingFlow()) + flows.add(new Flow(FlowTemplates.variatingFlow())); + + if (getConfig(configManager).getSlowStartupFlow()) + flows.add(new Flow(FlowTemplates.slowStartupFlow())); + + if (getConfig(configManager).getSlowStartup2Flow()) + flows.add(new Flow(FlowTemplates.slowStartup2Flow())); + + if (getConfig(configManager).getJaggedFlow()) + flows.add(new Flow(FlowTemplates.jaggedFlow())); + + if (getConfig(configManager).getInterruptedFlow()) + flows.add(new Flow(FlowTemplates.interruptedFlow())); + + if (getConfig(configManager).getInterruptedFlow2()) + flows.add(new Flow(FlowTemplates.interruptedFlow2())); + + if (getConfig(configManager).getStoppingFlow()) + flows.add(new Flow(FlowTemplates.stoppingFlow())); + + DefaultSpeedManager manager = new DefaultSpeedManager(flows); + //TODO:Add options for custom Deviation Provider and Noise Provider + factory.setDeviationProvider(new SinusoidalDeviationProvider(getConfig(configManager).getDeviationSlope())); + factory.setNoiseProvider(new DefaultNoiseProvider(Double.valueOf(getConfig(configManager).getNoisinessDivider()))); + factory.getNature().setReactionTimeVariationMs(getConfig(configManager).getReactionTimeVariation()); + manager.setMouseMovementBaseTimeMs(getConfig(configManager).getMouseDragSpeed()); + + DefaultOvershootManager overshootManager = (DefaultOvershootManager) factory.getOvershootManager(); + overshootManager.setOvershoots(getConfig(configManager).getOvershoots()); + + factory.setSpeedManager(manager); + Flexo.currentMouseMotionFactory = factory; + } + + @Override + protected void startUp() throws Exception { + Flexo.isStretched = client.isStretchedEnabled(); + overlayManager.add(overlay); + updateMouseMotionFactory(); + } + + @Override + protected void shutDown() throws Exception { + overlayManager.remove(overlay); + } +} 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 index 2287b5a0ef..0b910beea5 100644 --- 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 @@ -24,6 +24,17 @@ public interface PluginSorterConfig extends Config { return pluginsHidden; } + @ConfigItem( + position = 1, + keyName = "externalColor", + name = "External color", + description = "Configure the color of external plugins" + ) + default Color externalColor() + { + return Color.MAGENTA; + } + @ConfigItem( position = 1, keyName = "pvmColor", 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 index ca7f54c836..99c4e3e02a 100644 --- 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 @@ -76,7 +76,9 @@ public class PluginSorterPlugin extends Plugin { 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")) + if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("external")) + pli.nameLabel.setForeground(config.pvmColor()); + else 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()); @@ -93,6 +95,11 @@ public class PluginSorterPlugin extends Plugin { 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("external")) { + iter.remove(); + removedPlugins.add(pli); + } if (!pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("")) if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("PVM")) { iter.remove(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java index 9c2fd7ea34..b1c93b09bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java @@ -71,6 +71,8 @@ class SmeltingOverlay extends Overlay public Dimension render(Graphics2D graphics) { SmeltingSession session = plugin.getSession(); + + if (session!=null) if (session.getLastItemSmelted() == null) { return null; @@ -78,6 +80,7 @@ class SmeltingOverlay extends Overlay panelComponent.getChildren().clear(); + if (session!=null) if (isSmelting() || Duration.between(session.getLastItemSmelted(), Instant.now()).getSeconds() < SMELT_TIMEOUT) { panelComponent.getChildren().add(TitleComponent.builder() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java index 50c72491c3..9534129ad1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java @@ -114,6 +114,7 @@ public class SmeltingPlugin extends Plugin @Subscribe public void onGameTick(GameTick event) { + if (session!=null) if (session.getLastItemSmelted() != null) { final Duration statTimeout = Duration.ofMinutes(config.statTimeout()); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 4722b0027e..4cb09686b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -121,10 +121,10 @@ public class ClientUI private boolean withTitleBar; private BufferedImage sidebarOpenIcon; private BufferedImage sidebarClosedIcon; - private ContainableFrame frame; + public static ContainableFrame frame; private JPanel navContainer; - private PluginPanel pluginPanel; - private ClientPluginToolbar pluginToolbar; + public static PluginPanel pluginPanel; + public static ClientPluginToolbar pluginToolbar; private ClientTitleToolbar titleToolbar; private JButton currentButton; private NavigationButton currentNavButton; From 41c12a858d0b3527d76a7603654db4bb67f0e01f Mon Sep 17 00:00:00 2001 From: James <38226001+james-munson@users.noreply.github.com> Date: Mon, 22 Apr 2019 01:49:35 -0700 Subject: [PATCH 71/75] Changes 2 (#43) * Initial commit for maxhit plugin * WIP: Magic max hit calculator * Add chance to obtain a Unique from Chambers of Xeric Based on the formula from the wiki. Does not handle >80% chance properly (it should go into a second item) * MaxHit Refactor a lot for magic max hit * Wip: refactoring * Pest Control Update * Pest Control: Add Intermediate portals * Revert "Remove raids points overlay" This reverts commit fbd3ea6202a07b4dc4d3aab4eeebf62afa793c7c. * Wip: refactoring * Fixed WidgetInfo merge issue * Fixed trident * Implement range * Refactored according to intellij analyzer * Run checkstyle from xml and fix code style issues * Fix copyright * Replace item names with item id's * Code cleanup with reformat code * Fixed checkstyle * Use game slotitem * Use game slotitem * Fixed prayer bonus * Looked up value for saradomin strike * Fixed prayer bonus * Fixed surge spell id's * Fixed magix max hit tests * Fixed rounding after obisidian * Fix dharok custom formula * Add melee max hit * Refactored spellbonus items for magic * Added voidknight * Use boosted skill levels and add copyright * Add accurate attack style for ranging * Add range Tests * Cleanup code * Cleanup code * Rename calculate methods to be more distinguishable * Add parenthesis to dharok maxhit formula for clarification * Fix widgetinfo merge * Remove print in MaxHitPlugin * Make sure an Item is not null when checking if the player is wearing it. * Add daily notification for collection of ogre arrows from Rantz. Add varbit for rantz arrow collection Fix continuation indent settings Group ifs to single check. * Refactor all relevant daily checks to have grouped if check. Further refactor grouped ifs * Adds type * Raids point overlay --- .../main/java/net/runelite/api/Varbits.java | 9 + .../net/runelite/api/widgets/WidgetID.java | 45 ++ .../net/runelite/api/widgets/WidgetInfo.java | 13 +- .../dailytaskindicators/DailyTasksConfig.java | 11 + .../dailytaskindicators/DailyTasksPlugin.java | 81 +-- .../client/plugins/maxhit/MaxHitPlugin.java | 138 ++++ .../maxhit/attackstyle/AttackStyle.java | 51 ++ .../maxhit/attackstyle/WeaponType.java | 89 +++ .../calculators/MagicMaxHitCalculator.java | 113 ++++ .../maxhit/calculators/MaxHitCalculator.java | 178 +++++ .../calculators/MeleeMaxHitCalculator.java | 137 ++++ .../calculators/RangeMaxHitCalculator.java | 59 ++ .../maxhit/config/CustomFormulaConfig.java | 233 +++++++ .../maxhit/config/EquipmentBonusConfig.java | 418 ++++++++++++ .../maxhit/config/PrayerBonusConfig.java | 68 ++ .../maxhit/config/SpellBaseDamageConfig.java | 134 ++++ .../equipment/EquipmentCombatBonus.java | 57 ++ .../maxhit/equipment/EquipmentHelper.java | 55 ++ .../maxhit/equipment/EquipmentItemset.java | 42 ++ .../maxhit/equipment/EquipmentSlotItem.java | 51 ++ .../AutocastSpellRequirement.java | 58 ++ .../EquipmentItemRequirement.java | 54 ++ .../EquipmentItemSetRequirement.java | 55 ++ .../maxhit/requirements/Requirement.java | 32 + .../requirements/SpellBookRequirement.java | 52 ++ .../maxhit/requirements/SpellRequirement.java | 51 ++ .../MenuEntrySwapperConfig.java | 10 + .../MenuEntrySwapperPlugin.java | 4 + .../client/plugins/pestcontrol/Game.java | 230 ++++++- .../plugins/pestcontrol/GangplankOverlay.java | 170 +++++ .../plugins/pestcontrol/HintArrowOverlay.java | 175 +++++ .../pestcontrol/NpcHighlightContext.java | 41 ++ .../pestcontrol/NpcHighlightOverlay.java | 163 +++++ .../pestcontrol/PestControlConfig.java | 194 ++++++ .../plugins/pestcontrol/PestControlNpc.java | 259 ++++++++ .../pestcontrol/PestControlPlugin.java | 610 +++++++++++++++++- .../pestcontrol/PestControlRepairObject.java | 75 +++ .../pestcontrol/PointsInfoboxCounter.java | 39 ++ .../client/plugins/pestcontrol/Portal.java | 44 +- .../{PortalContext.java => PortalColor.java} | 15 +- .../{Rotation.java => PortalRotation.java} | 27 +- .../plugins/pestcontrol/PortalState.java | 32 + .../pestcontrol/PortalWeaknessOverlay.java | 198 ++++++ .../plugins/pestcontrol/RepairOverlay.java | 227 +++++++ .../plugins/pestcontrol/TimerOverlay.java | 88 +++ ...ControlOverlay.java => WidgetOverlay.java} | 227 +++---- .../plugins/pestcontrol/WidgetPortal.java | 45 ++ .../config/HighlightPortalOption.java | 46 ++ .../pestcontrol/config/NpcHighlightStyle.java | 46 ++ .../client/plugins/raids/RaidsPlugin.java | 30 + .../plugins/raids/RaidsPointsOverlay.java | 120 ++++ .../plugins/suppliestracker/back_icon.png | Bin 0 -> 15109 bytes .../plugins/suppliestracker/panel_icon.png | Bin 0 -> 1095 bytes .../plugins/suppliestracker/plus_icon.png | Bin 0 -> 179 bytes .../plugins/suppliestracker/sarabrew.jpg | Bin 0 -> 1714 bytes .../calculators/MaxHitCalculatorTest.java | 69 ++ .../testconfig/MagicMaxHitConfig.java | 243 +++++++ .../calculators/testconfig/MaxHitConfig.java | 32 + .../testconfig/MeleeMaxHitConfig.java | 217 +++++++ .../testconfig/RangeMaxHitConfig.java | 167 +++++ 60 files changed, 5848 insertions(+), 279 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/MaxHitPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/attackstyle/AttackStyle.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/attackstyle/WeaponType.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MagicMaxHitCalculator.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MaxHitCalculator.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MeleeMaxHitCalculator.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/RangeMaxHitCalculator.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/CustomFormulaConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/EquipmentBonusConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/PrayerBonusConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/SpellBaseDamageConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentCombatBonus.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentHelper.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentItemset.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentSlotItem.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/AutocastSpellRequirement.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/EquipmentItemRequirement.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/EquipmentItemSetRequirement.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/Requirement.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/SpellBookRequirement.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/SpellRequirement.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/GangplankOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/HintArrowOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/NpcHighlightContext.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/NpcHighlightOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlNpc.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlRepairObject.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PointsInfoboxCounter.java rename runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/{PortalContext.java => PortalColor.java} (84%) rename runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/{Rotation.java => PortalRotation.java} (72%) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalState.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalWeaknessOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/RepairOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/TimerOverlay.java rename runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/{PestControlOverlay.java => WidgetOverlay.java} (62%) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/WidgetPortal.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/config/HighlightPortalOption.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/config/NpcHighlightStyle.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPointsOverlay.java create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/back_icon.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/panel_icon.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/plus_icon.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/sarabrew.jpg create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/MaxHitCalculatorTest.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MagicMaxHitConfig.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MaxHitConfig.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MeleeMaxHitConfig.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/RangeMaxHitConfig.java 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 038362c66d..66dfcef672 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -372,6 +372,7 @@ public enum Varbits { DAILY_ESSENCE_COLLECTED(4547), DAILY_RUNES_COLLECTED(4540), DAILY_SAND_COLLECTED(4549), + DAILY_ARROWS_STATE(4563), DAILY_FLAX_STATE(4559), /** * This varbit tracks how much bonemeal has been redeemed from Robin @@ -481,6 +482,14 @@ public enum Varbits { */ GE_OFFER_CREATION_TYPE(4397), + + /* + * Spells being auto-casted + * + * */ + AUTO_CAST_SPELL(276), + + /** * The active tab within the quest interface */ 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 471c0acbe4..360f1a556c 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 @@ -55,6 +55,8 @@ public class WidgetID public static final int DIARY_GROUP_ID = 259; public static final int PEST_CONTROL_BOAT_GROUP_ID = 407; public static final int PEST_CONTROL_GROUP_ID = 408; + public static final int PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID = 243; + public static final int PEST_CONTROL_DIALOG_GROUP_ID = 229; public static final int CLAN_CHAT_GROUP_ID = 7; public static final int MINIMAP_GROUP_ID = 160; public static final int LOGIN_CLICK_TO_PLAY_GROUP_ID = 378; @@ -127,6 +129,7 @@ public class WidgetID public static final int FULLSCREEN_MAP_GROUP_ID = 165; public static final int QUESTLIST_GROUP_ID = 399; public static final int SKILLS_GROUP_ID = 320; + public static final int EQUIPMENT_PAGE_GROUP_ID = 84; public static final int QUESTTAB_GROUP_ID = 629; public static final int MUSIC_GROUP_ID = 239; public static final int MUSICTAB_GROUP_ID = 239; @@ -164,12 +167,32 @@ public class WidgetID static class PestControlBoat { static final int INFO = 3; + + static final int NEXT_DEPARTURE = 4; + static final int PLAYERS_READY = 5; + static final int POINTS = 6; + } + + static class PestControlExchangeWindow + { + static final int ITEM_LIST = 2; + static final int BOTTOM = 5; + static final int POINTS = 8; + static final int CONFIRM_BUTTON = 6; + } + + static class PestControlDialog + { + static final int TEXT = 1; + static final int CONTINUE = 2; } static class PestControl { static final int INFO = 3; + static final int TIME = 6; + static final int ACTIVITY_BAR = 12; static final int ACTIVITY_PROGRESS = 14; @@ -675,6 +698,28 @@ public class WidgetID static final int DESTROY_ITEM_NO = 3; } + static class EquipmentWidgetIdentifiers + { + static final int EQUIP_YOUR_CHARACTER = 3; + static final int STAB_ATTACK_BONUS = 23; + static final int SLASH_ATTACK_BONUS = 24; + static final int CRUSH_ATTACK_BONUS = 25; + static final int MAGIC_ATTACK_BONUS = 26; + static final int RANGED_ATTACK_BONUS = 27; + static final int STAB_DEFENCE_BONUS = 29; + static final int SLASH_DEFENCE_BONUS = 30; + static final int CRUSH_DEFENCE_BONUS = 31; + static final int MAGIC_DEFENCE_BONUS = 32; + static final int RANGED_DEFENCE_BONUS = 33; + static final int MELEE_STRENGTH = 35; + static final int RANGED_STRENGTH = 36; + static final int MAGIC_DAMAGE = 37; + static final int PRAYER_BONUS = 38; + static final int UNDEAD_DAMAGE_BONUS = 40; + static final int SLAYER_DAMAGE_BONUS = 41; + static final int WEIGHT = 43; + } + static class VarrockMuseum { static final int VARROCK_MUSEUM_QUESTION = 28; 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 df7951b840..9872efeb23 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 @@ -83,8 +83,14 @@ public enum WidgetInfo DIARY_QUEST_WIDGET_TITLE(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TITLE), DIARY_QUEST_WIDGET_TEXT(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TEXT), + PEST_CONTROL_DIALOG(WidgetID.PEST_CONTROL_DIALOG_GROUP_ID, 0), + PEST_CONTROL_DIALOG_TEXT(WidgetID.PEST_CONTROL_DIALOG_GROUP_ID, WidgetID.PestControlDialog.TEXT), + PEST_CONTROL_EXCHANGE_WINDOW(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, 0), + PEST_CONTROL_EXCHANGE_WINDOW_POINTS(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, WidgetID.PestControlExchangeWindow.POINTS), PEST_CONTROL_BOAT_INFO(WidgetID.PEST_CONTROL_BOAT_GROUP_ID, WidgetID.PestControlBoat.INFO), + PEST_CONTROL_BOAT_INFO_POINTS(WidgetID.PEST_CONTROL_BOAT_GROUP_ID, WidgetID.PestControlBoat.POINTS), PEST_CONTROL_INFO(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.INFO), + PEST_CONTROL_INFO_TIME(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.TIME), PEST_CONTROL_PURPLE_SHIELD(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.PURPLE_SHIELD), PEST_CONTROL_BLUE_SHIELD(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.BLUE_SHIELD), PEST_CONTROL_YELLOW_SHIELD(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.YELLOW_SHIELD), @@ -550,7 +556,12 @@ public enum WidgetInfo MUSICTAB_LOOP_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 12), MUSICTAB_UNLOCKED_SONGS(WidgetID.MUSICTAB_GROUP_ID, 13), - QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB); + QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB), + + EQUIPMENT_MELEE_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MELEE_STRENGTH), + EQUIPMENT_RANGED_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.RANGED_STRENGTH), + EQUIPMENT_MAGIC_DAMAGE(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MAGIC_DAMAGE), + EQUIP_YOUR_CHARACTER(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.EQUIP_YOUR_CHARACTER); private final int groupId; private final int childId; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksConfig.java index 09752b89a7..a1bd666f93 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksConfig.java @@ -109,4 +109,15 @@ public interface DailyTasksConfig extends Config { return true; } + + @ConfigItem( + position = 8, + keyName = "showArrows", + name = "Show Claimable Ogre Arrows", + description = "Show a message when you can collect ogre arrows from Rantz." + ) + default boolean showArrows() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java index 4076ef693c..97404aacd6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java @@ -63,6 +63,7 @@ public class DailyTasksPlugin extends Plugin private static final String SAND_MESSAGE = "You have sand waiting to be collected from Bert."; private static final int SAND_QUEST_COMPLETE = 160; private static final String FLAX_MESSAGE = "You have bowstrings waiting to be converted from flax from the Flax keeper."; + private static final String ARROWS_MESSAGE = "You have ogre arrows waiting to be collected from Rantz."; private static final String BONEMEAL_MESSAGE = "You have bonemeal and slime waiting to be collected from Robin."; private static final int BONEMEAL_PER_DIARY = 13; private static final String RELOG_MESSAGE = " (May require a relog)"; @@ -153,22 +154,21 @@ public class DailyTasksPlugin extends Plugin { checkBonemeal(dailyReset); } + + if (config.showArrows()) + { + checkArrows(dailyReset); + } } } private void checkHerbBoxes(boolean dailyReset) { - if (client.getAccountType() == AccountType.NORMAL + if ((client.getAccountType() == AccountType.NORMAL && client.getVar(VarPlayer.NMZ_REWARD_POINTS) >= HERB_BOX_COST) + && (dailyReset || client.getVar(Varbits.DAILY_HERB_BOXES_COLLECTED) < HERB_BOX_MAX)) { - if (client.getVar(Varbits.DAILY_HERB_BOXES_COLLECTED) < HERB_BOX_MAX) - { - sendChatMessage(HERB_BOX_MESSAGE); - } - else if (dailyReset) - { - sendChatMessage(HERB_BOX_MESSAGE); - } + sendChatMessage(HERB_BOX_MESSAGE); } } @@ -189,61 +189,46 @@ public class DailyTasksPlugin extends Plugin private void checkEssence(boolean dailyReset) { - if (client.getVar(Varbits.DIARY_ARDOUGNE_MEDIUM) == 1) + if ((client.getVar(Varbits.DIARY_ARDOUGNE_MEDIUM) == 1) + && (dailyReset || client.getVar(Varbits.DAILY_ESSENCE_COLLECTED) == 0)) { - if (client.getVar(Varbits.DAILY_ESSENCE_COLLECTED) == 0) - { - sendChatMessage(ESSENCE_MESSAGE); - } - else if (dailyReset) - { - sendChatMessage(ESSENCE_MESSAGE); - } + sendChatMessage(ESSENCE_MESSAGE); } } private void checkRunes(boolean dailyReset) { - if (client.getVar(Varbits.DIARY_WILDERNESS_EASY) == 1) + if ((client.getVar(Varbits.DIARY_WILDERNESS_EASY) == 1) + && (dailyReset || client.getVar(Varbits.DAILY_RUNES_COLLECTED) == 0)) { - if (client.getVar(Varbits.DAILY_RUNES_COLLECTED) == 0) - { - sendChatMessage(RUNES_MESSAGE); - } - else if (dailyReset) - { - sendChatMessage(RUNES_MESSAGE); - } + sendChatMessage(RUNES_MESSAGE); } } private void checkSand(boolean dailyReset) { - if (client.getVar(Varbits.QUEST_THE_HAND_IN_THE_SAND) >= SAND_QUEST_COMPLETE) + if ((client.getVar(Varbits.QUEST_THE_HAND_IN_THE_SAND) >= SAND_QUEST_COMPLETE) + && (dailyReset || client.getVar(Varbits.DAILY_SAND_COLLECTED) == 0)) { - if (client.getVar(Varbits.DAILY_SAND_COLLECTED) == 0) - { - sendChatMessage(SAND_MESSAGE); - } - else if (dailyReset) - { - sendChatMessage(SAND_MESSAGE); - } + sendChatMessage(SAND_MESSAGE); } } private void checkFlax(boolean dailyReset) { - if (client.getVar(Varbits.DIARY_KANDARIN_EASY) == 1) + if ((client.getVar(Varbits.DIARY_KANDARIN_EASY) == 1) + && (dailyReset || client.getVar(Varbits.DAILY_FLAX_STATE) == 0)) { - if (client.getVar(Varbits.DAILY_FLAX_STATE) == 0) - { - sendChatMessage(FLAX_MESSAGE); - } - else if (dailyReset) - { - sendChatMessage(FLAX_MESSAGE); - } + sendChatMessage(FLAX_MESSAGE); + } + } + + private void checkArrows(boolean dailyReset) + { + if ((client.getVar(Varbits.DIARY_WESTERN_EASY) == 1) + && (dailyReset || client.getVar(Varbits.DAILY_ARROWS_STATE) == 0)) + { + sendChatMessage(ARROWS_MESSAGE); } } @@ -261,11 +246,7 @@ public class DailyTasksPlugin extends Plugin max += BONEMEAL_PER_DIARY; } } - if (collected < max) - { - sendChatMessage(BONEMEAL_MESSAGE); - } - else if (dailyReset) + if (dailyReset || collected < max) { sendChatMessage(BONEMEAL_MESSAGE); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/MaxHitPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/MaxHitPlugin.java new file mode 100644 index 0000000000..874f038774 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/MaxHitPlugin.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit; + +import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.ItemContainerChanged; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.widgets.Widget; +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.maxhit.calculators.MagicMaxHitCalculator; +import net.runelite.client.plugins.maxhit.calculators.MeleeMaxHitCalculator; +import net.runelite.client.plugins.maxhit.calculators.RangeMaxHitCalculator; + +import javax.inject.Inject; + +@PluginDescriptor( + name = "Max Hit", + description = "Max Hit Calculator", + type = "PVM", + enabledByDefault = false +) +public class MaxHitPlugin extends Plugin +{ + + @Inject + private Client client; + + @Subscribe + public void onItemContainerChanged(final ItemContainerChanged event) + { + this.updateMaxHitWidget(); + } + + @Subscribe + public void onConfigChanged(final ConfigChanged event) + { + this.updateMaxHitWidget(); + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + this.updateMaxHitWidget(); + } + + private void updateMaxHitWidget() + { + Widget equipmentStats = client.getWidget(WidgetInfo.EQUIPMENT_INVENTORY_ITEMS_CONTAINER); + + ItemContainer equipmentContainer = client.getItemContainer(InventoryID.EQUIPMENT); + Item[] equipedItems = new Item[14]; + + if (equipmentStats != null && !equipmentStats.isHidden()) + { + if (equipmentContainer != null) + { + equipedItems = equipmentContainer.getItems(); + } + + MeleeMaxHitCalculator meleeMaxHitCalculator = new MeleeMaxHitCalculator(this.client, equipedItems); + RangeMaxHitCalculator rangeMaxHitCalculator = new RangeMaxHitCalculator(this.client, equipedItems); + MagicMaxHitCalculator magicMaxHitCalculator = new MagicMaxHitCalculator(this.client, equipedItems); + + MaxHit maxHit = new MaxHit(meleeMaxHitCalculator.getMaxHit(), rangeMaxHitCalculator.getMaxHit(), magicMaxHitCalculator.getMaxHit()); + this.setWidgetMaxHit(maxHit); + } + } + + private void setWidgetMaxHit(MaxHit maxhit) + { + Widget equipYourCharacter = client.getWidget(WidgetInfo.EQUIP_YOUR_CHARACTER); + String maxHitText = "Melee Max Hit: " + maxhit.getMaxMeleeHit(); + maxHitText += "
Range Max Hit: " + maxhit.getMaxRangeHit(); + maxHitText += "
Magic Max Hit: " + maxhit.getMaxMagicHit(); + + + equipYourCharacter.setText(maxHitText); + } + + private class MaxHit + { + private final double maxMeleeHit; + private final double maxRangeHit; + private final double maxMagicHit; + + MaxHit(double maxMeleeHit, double maxRangeHit, double maxMagicHit) + { + this.maxMeleeHit = maxMeleeHit; + this.maxRangeHit = maxRangeHit; + this.maxMagicHit = maxMagicHit; + } + + double getMaxMeleeHit() + { + return maxMeleeHit; + } + + double getMaxRangeHit() + { + return maxRangeHit; + } + + double getMaxMagicHit() + { + return maxMagicHit; + } + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/attackstyle/AttackStyle.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/attackstyle/AttackStyle.java new file mode 100644 index 0000000000..e9e9d9b18d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/attackstyle/AttackStyle.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.attackstyle; + +public enum AttackStyle +{ + ACCURATE(0), + AGGRESSIVE(3), + DEFENSIVE(0), + CONTROLLED(1), + ACCURATERANGING(3), + RANGING(0), + LONGRANGE(0), + CASTING(0), + DEFENSIVE_CASTING(0), + OTHER(0); + + private final int maxHitBonus; + + AttackStyle(int maxHitBonus) + { + this.maxHitBonus = maxHitBonus; + } + + public double getMaxHitBonus() + { + return this.maxHitBonus; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/attackstyle/WeaponType.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/attackstyle/WeaponType.java new file mode 100644 index 0000000000..97ed177f27 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/attackstyle/WeaponType.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.attackstyle; + +import java.util.HashMap; +import java.util.Map; + +import static net.runelite.client.plugins.maxhit.attackstyle.AttackStyle.*; + +public enum WeaponType +{ + TYPE_0(ACCURATE, AGGRESSIVE, null, DEFENSIVE), + TYPE_1(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE), + TYPE_2(ACCURATE, AGGRESSIVE, null, DEFENSIVE), + TYPE_3(ACCURATERANGING, RANGING, null, LONGRANGE), + TYPE_4(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE), + TYPE_5(ACCURATERANGING, RANGING, null, LONGRANGE), + TYPE_6(AGGRESSIVE, RANGING, DEFENSIVE_CASTING, null), + TYPE_7(ACCURATERANGING, RANGING, null, LONGRANGE), + TYPE_8(OTHER, AGGRESSIVE, null, null), + TYPE_9(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE), + TYPE_10(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE), + TYPE_11(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE), + TYPE_12(CONTROLLED, AGGRESSIVE, null, DEFENSIVE), + TYPE_13(ACCURATE, AGGRESSIVE, null, DEFENSIVE), + TYPE_14(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE), + TYPE_15(CONTROLLED, CONTROLLED, CONTROLLED, DEFENSIVE), + TYPE_16(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE), + TYPE_17(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE), + TYPE_18(ACCURATE, AGGRESSIVE, null, DEFENSIVE, CASTING, DEFENSIVE_CASTING), + TYPE_19(ACCURATERANGING, RANGING, null, LONGRANGE), + TYPE_20(ACCURATE, CONTROLLED, null, DEFENSIVE), + TYPE_21(ACCURATE, AGGRESSIVE, null, DEFENSIVE, CASTING, DEFENSIVE_CASTING), + TYPE_22(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE), + TYPE_23(CASTING, CASTING, null, DEFENSIVE_CASTING), + TYPE_24(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE), + TYPE_25(CONTROLLED, AGGRESSIVE, null, DEFENSIVE), + TYPE_26(AGGRESSIVE, AGGRESSIVE, null, AGGRESSIVE), + TYPE_27(ACCURATE, null, null, OTHER); + + private static final Map weaponTypes = new HashMap<>(); + + static + { + for (WeaponType weaponType : values()) + { + weaponTypes.put(weaponType.ordinal(), weaponType); + } + } + + private final AttackStyle[] attackStyles; + + WeaponType(AttackStyle... attackStyles) + { + this.attackStyles = attackStyles; + } + + public static WeaponType getWeaponType(int id) + { + return weaponTypes.get(id); + } + + public AttackStyle[] getAttackStyles() + { + return attackStyles; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MagicMaxHitCalculator.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MagicMaxHitCalculator.java new file mode 100644 index 0000000000..8b14e3d988 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MagicMaxHitCalculator.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.calculators; + +import net.runelite.api.Client; +import net.runelite.api.Item; +import net.runelite.api.Skill; +import net.runelite.api.Varbits; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.plugins.maxhit.config.EquipmentBonusConfig; +import net.runelite.client.plugins.maxhit.config.SpellBaseDamageConfig; + +public class MagicMaxHitCalculator extends MaxHitCalculator +{ + + public MagicMaxHitCalculator(Client client, Item[] equipedItems) + { + super(client, CombatMethod.MAGIC, equipedItems); + } + + @Override + protected String getSkillStrengthText(String equipmentText) + { + return equipmentText.replace("Magic damage: ", "").replace(".", "").replace("%", ""); + } + + @Override + Widget equipmentSkillPower() + { + return this.client.getWidget(WidgetInfo.EQUIPMENT_MAGIC_DAMAGE); + } + + @Override + public double getCurrentSkillPower() + { + return this.client.getBoostedSkillLevel(Skill.MAGIC); + } + + /* + * Damage formula based on: + * http://services.runescape.com/m=forum/forums.ws?317,318,712,65587452 + * Section 4. + * */ + @Override + public double calculate() + { + int spellBaseDamage = this.baseDamage; + + if (spellBaseDamage == 0) + { + int autoCastSpellId = client.getVar(Varbits.AUTO_CAST_SPELL); + if (autoCastSpellId == 0) + { + return 0.0; + } + + SpellBaseDamageConfig autoCastSpell = SpellBaseDamageConfig.findSpellById(autoCastSpellId); + spellBaseDamage = autoCastSpell.getBaseDamage(); + } + +// a.Find the base maximum damage a spell can deal. +// See CustomFormulaConfig for spells based on magic lvl + double maxHit = spellBaseDamage; + +// b. Increase the base damage (Chaos Gauntlets) + maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.SPECIAL); + +// c. The following bonuses stack by adding up. (List of bonus items) + maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.EQUIPMENT); + +// d. Round down to the nearest integer. + maxHit = Math.floor(maxHit); + +// e. On a slayer task, multiply by 1.15 (imbued) + maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.SLAYER); + +// f. Round down to the nearest integer. + maxHit = Math.floor(maxHit); + +// g. If a fire spell is used, multiply by 1.5 (Tome of fire) + maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.MAGIC_SPECIAL); + +// h. Round down to the nearest integer. + maxHit = Math.floor(maxHit); + +// i, j. Castle Wars will not be included + return maxHit; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MaxHitCalculator.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MaxHitCalculator.java new file mode 100644 index 0000000000..95cc98a266 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MaxHitCalculator.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.calculators; + +import net.runelite.api.Client; +import net.runelite.api.Item; +import net.runelite.api.VarPlayer; +import net.runelite.api.Varbits; +import net.runelite.api.widgets.Widget; +import net.runelite.client.plugins.maxhit.attackstyle.AttackStyle; +import net.runelite.client.plugins.maxhit.attackstyle.WeaponType; +import net.runelite.client.plugins.maxhit.config.CustomFormulaConfig; +import net.runelite.client.plugins.maxhit.config.EquipmentBonusConfig; +import net.runelite.client.plugins.maxhit.config.PrayerBonusConfig; +import net.runelite.client.plugins.maxhit.equipment.EquipmentHelper; +import net.runelite.client.plugins.maxhit.equipment.EquipmentItemset; + +import java.util.ArrayList; +import java.util.function.BiFunction; + +public abstract class MaxHitCalculator +{ + + final Client client; + private final CombatMethod combatMethod; + private final Item[] equipedItems; + int baseDamage = 0; + + MaxHitCalculator(Client client, CombatMethod combatMethod, Item[] equipedItems) + { + this.client = client; + this.combatMethod = combatMethod; + this.equipedItems = equipedItems; + } + + protected abstract String getSkillStrengthText(String equipmentText); + + abstract Widget equipmentSkillPower(); + + public abstract double getCurrentSkillPower(); + + AttackStyle getAttackStyle() + { + int equippedWeaponTypeId = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE); + int attackStyleId = client.getVar(VarPlayer.ATTACK_STYLE); + + AttackStyle[] attackStyles = WeaponType.getWeaponType(equippedWeaponTypeId).getAttackStyles(); + + if (attackStyleId < attackStyles.length) + { + AttackStyle attackStyle = attackStyles[attackStyleId]; + if (attackStyle != null) + { + return attackStyle; + } + } + + return AttackStyle.OTHER; + } + + double getPrayerBonus() + { + double bonus = 1; + for (PrayerBonusConfig prayerBonus : PrayerBonusConfig.values()) + { + boolean prayerActive = client.getVar(prayerBonus.getPrayerVarbit()) == 1; + boolean sameCombatMethod = prayerBonus.getCombatMethod() == this.combatMethod; + if (prayerActive && sameCombatMethod) + { + bonus += prayerBonus.getStrengthBonus(); + } + } + return bonus; + } + + double applyEquipmentBonus(double maxhit, EquipmentBonusConfig.BonusType bonusType) + { + double bonus = 1; + ArrayList addList = new ArrayList<>(); + + ArrayList equipmentBonuses = EquipmentBonusConfig.getBonusByType(bonusType); + + for (EquipmentBonusConfig equipmentBonus : equipmentBonuses) + { + EquipmentItemset itemSet = equipmentBonus.getItemset(); + boolean wearsSet = EquipmentHelper.wearsItemSet(this.equipedItems, itemSet); + if (wearsSet && equipmentBonus.meetsRequirements(this.client)) + { + if (equipmentBonus.getOperation() == EquipmentBonusConfig.Operation.MULTIPLY) + { + bonus += equipmentBonus.getBonus(this.combatMethod); + } + else if (equipmentBonus.getOperation() == EquipmentBonusConfig.Operation.ADD) + { + addList.add(equipmentBonus.getBonus(this.combatMethod)); + } + } + } + + maxhit *= bonus; + + maxhit = maxhit + addList.stream().reduce(0.0, Double::sum); + + return maxhit; + } + + public double getMaxHit() + { + BiFunction customFormula = this.getCustomFormula(); + if (customFormula != null) + { + return customFormula.apply(this.client, this); + } + + return this.calculate(); + } + + private BiFunction getCustomFormula() + { + for (CustomFormulaConfig customFormula : CustomFormulaConfig.values()) + { + if (this.combatMethod != customFormula.getRequiredCombatMethod()) + { + continue; + } + + boolean meetsRequirements = customFormula.getRequirements().stream().allMatch(requirement -> requirement.meetsRequirements(this.client)); + + if (meetsRequirements) + { + return customFormula.getCustomFormula(); + } + } + + return null; + } + + public abstract double calculate(); + + public void setBaseDamage(int baseDamage) + { + this.baseDamage = baseDamage; + } + + double getSkillStrength() + { + return Double.parseDouble(this.getSkillStrengthText(this.equipmentSkillPower().getText())); + } + + public enum CombatMethod + { + MELEE, + RANGE, + MAGIC + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MeleeMaxHitCalculator.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MeleeMaxHitCalculator.java new file mode 100644 index 0000000000..d3f6d78a0b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/MeleeMaxHitCalculator.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.calculators; + +import net.runelite.api.Client; +import net.runelite.api.Item; +import net.runelite.api.Skill; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.plugins.maxhit.attackstyle.AttackStyle; +import net.runelite.client.plugins.maxhit.config.EquipmentBonusConfig; + +public class MeleeMaxHitCalculator extends MaxHitCalculator +{ + + public MeleeMaxHitCalculator(Client client, Item[] equipedItems) + { + super(client, CombatMethod.MELEE, equipedItems); + } + + MeleeMaxHitCalculator(Client client, CombatMethod combatMethod, Item[] equipedItems) + { + super(client, combatMethod, equipedItems); + } + + @Override + protected String getSkillStrengthText(String equipmentText) + { + return equipmentText.replace("Melee strength: ", ""); + } + + @Override + public Widget equipmentSkillPower() + { + return this.client.getWidget(WidgetInfo.EQUIPMENT_MELEE_STRENGTH); + } + + @Override + public double getCurrentSkillPower() + { + return this.client.getBoostedSkillLevel(Skill.STRENGTH); + } + + private double getEffectiveLevel() + { +// a. Take the visible strength or ranged level from the skills interface. + double skillPower = this.getCurrentSkillPower(); + +// b. Multiply the level by the prayer adjustment + double effectiveLevel = skillPower * this.getPrayerBonus(); + +// c. Round down to the nearest integer. + effectiveLevel = Math.floor(effectiveLevel); + +// d. Add the stance bonus from the combat options interface. +// Melee: +// • Aggressive: +3 +// • Controlled: +1 +// Ranged: +// * Accurate: +3 + AttackStyle attackStyle = this.getAttackStyle(); + effectiveLevel += attackStyle.getMaxHitBonus(); + +// e. Add up +8. + effectiveLevel += 8; + +// f. Multiply by the void bonus: +// • Void melee: multiply by 1.10. Round down. +// • Void ranged: multiply by 1.10. Round down. +// • Elite void ranged: multiply by 1.125. Round down. + effectiveLevel = this.applyEquipmentBonus(effectiveLevel, EquipmentBonusConfig.BonusType.VOID_KNIGHT); + +// g. This is the effective (ranged) strength level. Let this equal 'A' in the formula in + return effectiveLevel; + } + + // 3.3 Take the melee or ranged strength bonus from the equipment stats interface and let this equal 'B' in the formula in 3.1. + private double getEquipmentBonus() + { + return this.getSkillStrength(); + } + + /* + * Damage formula based on: + * http://services.runescape.com/m=forum/forums.ws?317,318,712,65587452 + * Section 3.1 + * */ + @Override + public double calculate() + { + +// a. Max hit = 0.5 + A * (B+64) /640 (A is effective level, B is Equipment bonus) + double maxHit = 0.5 + this.getEffectiveLevel() * (this.getEquipmentBonus() + 64) / 640; + +// b. Round down the max hit to the nearest integer. + maxHit = Math.floor(maxHit); + +// 3.4 Special attacks (not actually taking weapon special attacks into account) +// a. Multiply by the bonus of one of the following items (slayer) + maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.SLAYER); + +// b. Round down the max hit to the nearest integer. + maxHit = Math.floor(maxHit); + +// c. Multiply by the bonus of one of the following items + maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.SPECIAL); + +// d. Round down to the nearest integer. + maxHit = Math.floor(maxHit); + + return maxHit; + } +} + + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/RangeMaxHitCalculator.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/RangeMaxHitCalculator.java new file mode 100644 index 0000000000..0b397e76d5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/calculators/RangeMaxHitCalculator.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.calculators; + +import net.runelite.api.Client; +import net.runelite.api.Item; +import net.runelite.api.Skill; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; + +public class RangeMaxHitCalculator extends MeleeMaxHitCalculator +{ + + public RangeMaxHitCalculator(Client client, Item[] equipedItems) + { + super(client, CombatMethod.RANGE, equipedItems); + } + + @Override + protected String getSkillStrengthText(String equipmentText) + { + return equipmentText.replace("Ranged strength: ", "").replace(".", "").replace("%", ""); + } + + @Override + public Widget equipmentSkillPower() + { + return this.client.getWidget(WidgetInfo.EQUIPMENT_RANGED_STRENGTH); + } + + @Override + public double getCurrentSkillPower() + { + return this.client.getBoostedSkillLevel(Skill.RANGED); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/CustomFormulaConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/CustomFormulaConfig.java new file mode 100644 index 0000000000..b050af543d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/CustomFormulaConfig.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.config; + +import net.runelite.api.Client; +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.api.ItemID; +import net.runelite.api.Skill; +import net.runelite.client.plugins.maxhit.calculators.MaxHitCalculator; +import net.runelite.client.plugins.maxhit.equipment.EquipmentItemset; +import net.runelite.client.plugins.maxhit.equipment.EquipmentSlotItem; +import net.runelite.client.plugins.maxhit.requirements.EquipmentItemRequirement; +import net.runelite.client.plugins.maxhit.requirements.EquipmentItemSetRequirement; +import net.runelite.client.plugins.maxhit.requirements.Requirement; +import net.runelite.client.plugins.maxhit.requirements.SpellRequirement; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.function.BiFunction; + +public enum CustomFormulaConfig +{ + + MAGIC_DART( + MaxHitCalculator.CombatMethod.MAGIC, + new ArrayList<>(Arrays.asList( + new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList( + ItemID.SLAYERS_STAFF, + ItemID.SLAYERS_STAFF_E + )))), + new SpellRequirement(SpellBaseDamageConfig.MAGIC_DART) + )), + (client, calculator) -> + { + int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC); + return Math.floor((magicLevel / 10.0) + 10.0); + } + ), + + TRIDENT_OF_SEAS( + MaxHitCalculator.CombatMethod.MAGIC, + new ArrayList<>(Collections.singletonList( + new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList( + ItemID.TRIDENT_OF_THE_SEAS_FULL, + ItemID.TRIDENT_OF_THE_SEAS, + ItemID.TRIDENT_OF_THE_SEAS_E + )))) + )), + (client, calculator) -> + { + int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC); + + int baseDamage = (int) Math.floor(magicLevel / 3.0) - 5; + calculator.setBaseDamage(baseDamage); + + return calculator.calculate(); + } + ), + + TRIDENT_OF_SWAMP( + MaxHitCalculator.CombatMethod.MAGIC, + new ArrayList<>(Collections.singletonList( + new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList( + ItemID.TRIDENT_OF_THE_SWAMP, + ItemID.TRIDENT_OF_THE_SWAMP_E + )))) + )), + (client, calculator) -> + { + int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC); + + int baseDamage = (int) Math.floor(magicLevel / 3.0) - 2; + calculator.setBaseDamage(baseDamage); + + return calculator.calculate(); + } + ), + + SWAMP_LIZARD( + MaxHitCalculator.CombatMethod.MAGIC, + new ArrayList<>(Collections.singletonList( + new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList( + ItemID.SWAMP_LIZARD + )))) + )), + (client, calculator) -> + { + int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC); + return Math.floor(0.5 + magicLevel * (64.0 + 56.0) / 640.0); + } + ), + + ORANGE_SALAMANDER( + MaxHitCalculator.CombatMethod.MAGIC, + new ArrayList<>(Collections.singletonList( + new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList( + ItemID.ORANGE_SALAMANDER + )))) + )), + (client, calculator) -> + { + int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC); + return Math.floor(0.5 + magicLevel * (64.0 + 59.0) / 640.0); + } + ), + + RED_SALAMANDER( + MaxHitCalculator.CombatMethod.MAGIC, + new ArrayList<>(Collections.singletonList( + new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList( + ItemID.RED_SALAMANDER + )))) + )), + (client, calculator) -> + { + int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC); + return Math.floor(0.5 + magicLevel * (64.0 + 77.0) / 640.0); + } + ), + + BLACK_SALAMANDER( + MaxHitCalculator.CombatMethod.MAGIC, + new ArrayList<>(Collections.singletonList( + new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList( + ItemID.BLACK_SALAMANDER + )))) + )), + (client, calculator) -> + { + int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC); + return Math.floor(0.5 + magicLevel * (64.0 + 92.0) / 640.0); + } + ), + + DHAROK( + MaxHitCalculator.CombatMethod.MELEE, + new ArrayList<>(Collections.singletonList(new EquipmentItemSetRequirement(new EquipmentItemset(Arrays.asList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.DHAROKS_HELM, + ItemID.DHAROKS_HELM_100, + ItemID.DHAROKS_HELM_75, + ItemID.DHAROKS_HELM_50, + ItemID.DHAROKS_HELM_25, + ItemID.DHAROKS_HELM_0 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Arrays.asList( + ItemID.DHAROKS_PLATEBODY, + ItemID.DHAROKS_PLATEBODY_100, + ItemID.DHAROKS_PLATEBODY_75, + ItemID.DHAROKS_PLATEBODY_50, + ItemID.DHAROKS_PLATEBODY_25, + ItemID.DHAROKS_PLATEBODY_0 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Arrays.asList( + ItemID.DHAROKS_PLATELEGS, + ItemID.DHAROKS_PLATELEGS_100, + ItemID.DHAROKS_PLATELEGS_75, + ItemID.DHAROKS_PLATELEGS_50, + ItemID.DHAROKS_PLATELEGS_25, + ItemID.DHAROKS_PLATELEGS_0 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList( + ItemID.DHAROKS_GREATAXE, + ItemID.DHAROKS_GREATAXE_100, + ItemID.DHAROKS_GREATAXE_75, + ItemID.DHAROKS_GREATAXE_50, + ItemID.DHAROKS_GREATAXE_25, + ItemID.DHAROKS_GREATAXE_0 + ))) + ))))), + (client, calculator) -> + { + int currentHP = client.getBoostedSkillLevel(Skill.HITPOINTS); + int maxHP = client.getRealSkillLevel(Skill.HITPOINTS); + int lostHP = maxHP - currentHP; + + double initialMaxHit = calculator.calculate(); + + double multiplier = (1.0 + ((lostHP / 100.0) * (maxHP / 100.0))); + + return Math.floor(initialMaxHit * multiplier); + } + ); + + private final MaxHitCalculator.CombatMethod requiredCombatMethod; + private final ArrayList requirements; + private final BiFunction customFormula; + + CustomFormulaConfig(MaxHitCalculator.CombatMethod requiredCombatMethod, ArrayList requirements, BiFunction customFormula) + { + this.requiredCombatMethod = requiredCombatMethod; + this.requirements = requirements; + this.customFormula = customFormula; + } + + public MaxHitCalculator.CombatMethod getRequiredCombatMethod() + { + return requiredCombatMethod; + } + + public BiFunction getCustomFormula() + { + return customFormula; + } + + public ArrayList getRequirements() + { + return this.requirements; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/EquipmentBonusConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/EquipmentBonusConfig.java new file mode 100644 index 0000000000..fce5816c64 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/EquipmentBonusConfig.java @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.config; + +import net.runelite.api.Client; +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.api.ItemID; +import net.runelite.client.plugins.maxhit.calculators.MaxHitCalculator; +import net.runelite.client.plugins.maxhit.equipment.EquipmentCombatBonus; +import net.runelite.client.plugins.maxhit.equipment.EquipmentItemset; +import net.runelite.client.plugins.maxhit.equipment.EquipmentSlotItem; +import net.runelite.client.plugins.maxhit.requirements.AutocastSpellRequirement; +import net.runelite.client.plugins.maxhit.requirements.Requirement; +import net.runelite.client.plugins.maxhit.requirements.SpellBookRequirement; + +import java.util.*; + + +public enum EquipmentBonusConfig +{ + + /* + * Slayer bonus items + */ + BLACKMASK(BonusType.SLAYER, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.BLACK_MASK_10, + ItemID.BLACK_MASK_9, + ItemID.BLACK_MASK_8, + ItemID.BLACK_MASK_7, + ItemID.BLACK_MASK_6, + ItemID.BLACK_MASK_5, + ItemID.BLACK_MASK_4, + ItemID.BLACK_MASK_3, + ItemID.BLACK_MASK_2, + ItemID.BLACK_MASK_1, + ItemID.BLACK_MASK + ))) + )), new EquipmentCombatBonus(((7.0 / 6.0) - 1), 0, 0)), + + SLAYERHELM(BonusType.SLAYER, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.SLAYER_HELMET, + ItemID.BLACK_SLAYER_HELMET, + ItemID.GREEN_SLAYER_HELMET, + ItemID.RED_SLAYER_HELMET, + ItemID.PURPLE_SLAYER_HELMET, + ItemID.TURQUOISE_SLAYER_HELMET, + ItemID.HYDRA_SLAYER_HELMET + ))) + )), new EquipmentCombatBonus(((7.0 / 6.0) - 1), 0, 0)), + + BLACKMASKI(BonusType.SLAYER, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.BLACK_MASK_10_I, + ItemID.BLACK_MASK_9_I, + ItemID.BLACK_MASK_8_I, + ItemID.BLACK_MASK_7_I, + ItemID.BLACK_MASK_6_I, + ItemID.BLACK_MASK_5_I, + ItemID.BLACK_MASK_4_I, + ItemID.BLACK_MASK_3_I, + ItemID.BLACK_MASK_2_I, + ItemID.BLACK_MASK_1_I, + ItemID.BLACK_MASK_I + ))) + )), new EquipmentCombatBonus(((7.0 / 6.0) - 1), 0.15, 0.15)), + + SLAYERHELMI(BonusType.SLAYER, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.SLAYER_HELMET_I, + ItemID.BLACK_SLAYER_HELMET_I, + ItemID.GREEN_SLAYER_HELMET_I, + ItemID.RED_SLAYER_HELMET_I, + ItemID.PURPLE_SLAYER_HELMET_I, + ItemID.TURQUOISE_SLAYER_HELMET_I, + ItemID.HYDRA_SLAYER_HELMET_I + ))) + )), new EquipmentCombatBonus(((7.0 / 6.0) - 1), 0.15, 0.15)), + + /* + * Void bonus items + * */ + MELEEVOID(BonusType.VOID_KNIGHT, new EquipmentItemset(Arrays.asList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.VOID_MELEE_HELM, + ItemID.VOID_MELEE_HELM_11676 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Arrays.asList( + ItemID.VOID_KNIGHT_TOP, + ItemID.VOID_KNIGHT_TOP_10611 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList( + ItemID.VOID_KNIGHT_ROBE + ))), + new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList( + ItemID.VOID_KNIGHT_GLOVES + ))) + )), new EquipmentCombatBonus(0.1, 0, 0)), + + RANGERVOID(BonusType.VOID_KNIGHT, new EquipmentItemset(Arrays.asList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.VOID_RANGER_HELM, + ItemID.VOID_RANGER_HELM_11675 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Arrays.asList( + ItemID.VOID_KNIGHT_TOP, + ItemID.VOID_KNIGHT_TOP_10611 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList( + ItemID.VOID_KNIGHT_ROBE + ))), + new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList( + ItemID.VOID_KNIGHT_GLOVES + ))) + )), new EquipmentCombatBonus(0, 0.1, 0)), + + + ELITEMELEERVOID(BonusType.VOID_KNIGHT, new EquipmentItemset(Arrays.asList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.VOID_MELEE_HELM, + ItemID.VOID_MELEE_HELM_11676 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList( + ItemID.ELITE_VOID_TOP + ))), + new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList( + ItemID.ELITE_VOID_ROBE + ))), + new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList( + ItemID.VOID_KNIGHT_GLOVES + ))) + )), new EquipmentCombatBonus(0.125, 0, 0)), + + + ELITERANGERVOID(BonusType.VOID_KNIGHT, new EquipmentItemset(Arrays.asList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.VOID_RANGER_HELM, + ItemID.VOID_RANGER_HELM_11675 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList( + ItemID.ELITE_VOID_TOP + ))), + new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList( + ItemID.ELITE_VOID_ROBE + ))), + new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList( + ItemID.VOID_KNIGHT_GLOVES + ))) + )), new EquipmentCombatBonus(0, 0.125, 0)), + + ELITEMAGICVOID(BonusType.EQUIPMENT, new EquipmentItemset(Arrays.asList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList( + ItemID.VOID_MAGE_HELM, + ItemID.VOID_MAGE_HELM_11674 + ))), + new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList( + ItemID.ELITE_VOID_TOP + ))), + new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList( + ItemID.ELITE_VOID_ROBE + ))), + new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList( + ItemID.VOID_KNIGHT_GLOVES + ))) + )), new EquipmentCombatBonus(0, 0, 0.025)), + + /* + * Special Melee Equipment + * */ + OBISIDIAN(BonusType.SPECIAL, new EquipmentItemset(Arrays.asList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Collections.singletonList( + ItemID.OBSIDIAN_HELMET + ))), + new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList( + ItemID.OBSIDIAN_PLATEBODY + ))), + new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList( + ItemID.OBSIDIAN_PLATELEGS + ))), + new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList( + ItemID.TOKTZXILAK, + ItemID.TOKTZXILEK, + ItemID.TZHAARKETEM, + ItemID.TZHAARKETOM, + ItemID.TOKTZXILAK_20554 + ))) + )), new EquipmentCombatBonus(0.1, 0, 0)), + + BERSERKERNECKLACE(BonusType.SPECIAL, new EquipmentItemset(Arrays.asList( + new EquipmentSlotItem(EquipmentInventorySlot.AMULET, new ArrayList<>(Collections.singletonList(ItemID.BERSERKER_NECKLACE))), + new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList( + ItemID.TOKTZXILAK, + ItemID.TOKTZXILEK, + ItemID.TZHAARKETEM, + ItemID.TZHAARKETOM, + ItemID.TOKTZXILAK_20554 + ))) + )), new EquipmentCombatBonus(0.2, 0, 0)), + + + /* + * Magic Equipment + */ + ANCESTRAL_HAT(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Collections.singletonList( + ItemID.ANCESTRAL_HAT + ))) + )), new EquipmentCombatBonus(0, 0, 0.02)), + + ANCESTRAL_ROBE_TOP(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList( + ItemID.ANCESTRAL_ROBE_TOP + ))) + )), new EquipmentCombatBonus(0, 0, 0.02)), + + ANCESTRAL_ROBE_BOTTOM(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList( + ItemID.ANCESTRAL_ROBE_BOTTOM + ))) + )), new EquipmentCombatBonus(0, 0, 0.02)), + + IMBUED_GOD_CAPE(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.CAPE, new ArrayList<>(Arrays.asList( + ItemID.IMBUED_SARADOMIN_MAX_CAPE, + ItemID.IMBUED_SARADOMIN_CAPE, + ItemID.IMBUED_ZAMORAK_MAX_CAPE, + ItemID.IMBUED_ZAMORAK_CAPE, + ItemID.IMBUED_GUTHIX_MAX_CAPE, + ItemID.IMBUED_GUTHIX_CAPE + ))) + )), new EquipmentCombatBonus(0, 0, 0.02)), + + KODAI_WAND(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList( + ItemID.KODAI_WAND + ))) + )), new EquipmentCombatBonus(0, 0, 0.15)), + + OCCULT_NECKLACE(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.AMULET, new ArrayList<>(Arrays.asList( + ItemID.OCCULT_NECKLACE, + ItemID.OCCULT_NECKLACE_OR + ))) + )), new EquipmentCombatBonus(0, 0, 0.10)), + + STAFF_OF_THE_DEAD(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList( + ItemID.STAFF_OF_THE_DEAD, + ItemID.TOXIC_STAFF_OF_THE_DEAD, + ItemID.STAFF_OF_LIGHT + ))) + )), new EquipmentCombatBonus(0, 0, 0.15)), + + TORMENTED_BRACELET(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList( + ItemID.TORMENTED_BRACELET + ))) + )), new EquipmentCombatBonus(0, 0, 0.05)), + + SMOKE_STAFF(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList( + ItemID.SMOKE_BATTLESTAFF, + ItemID.MYSTIC_SMOKE_STAFF + ))) + )), new EquipmentCombatBonus(0, 0, 0.10), Collections.singletonList(new SpellBookRequirement(SpellBaseDamageConfig.SpellBook.NORMAL))), + + + /* + * Special magic bonusses + * */ + + CHAOS_GAUNTLETS(BonusType.SPECIAL, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList( + ItemID.CHAOS_GAUNTLETS + ))))), + new EquipmentCombatBonus(0, 0, 3), + Collections.singletonList( + new AutocastSpellRequirement(new ArrayList<>(Arrays.asList( + SpellBaseDamageConfig.AIR_BOLT, + SpellBaseDamageConfig.WATER_BOLT, + SpellBaseDamageConfig.EARTH_BOLT, + SpellBaseDamageConfig.FIRE_BOLT + ))) + ), + Operation.ADD + ), + + TOME_OF_FIRE(BonusType.MAGIC_SPECIAL, new EquipmentItemset(Collections.singletonList( + new EquipmentSlotItem(EquipmentInventorySlot.SHIELD, new ArrayList<>(Collections.singletonList( + ItemID.TOME_OF_FIRE + ))))), + new EquipmentCombatBonus(0, 0, 0.5), + Collections.singletonList( + new AutocastSpellRequirement(new ArrayList<>(Arrays.asList( + SpellBaseDamageConfig.FIRE_BLAST, + SpellBaseDamageConfig.FIRE_BOLT, + SpellBaseDamageConfig.FIRE_STRIKE, + SpellBaseDamageConfig.FIRE_SURGE, + SpellBaseDamageConfig.FIRE_WAVE + ))) + ) + ); + + + private static final Map> bonusTypes = new HashMap<>(); + + static + { + for (EquipmentBonusConfig equipmentBonus : values()) + { + BonusType bonusType = equipmentBonus.bonusType; + if (!bonusTypes.containsKey(bonusType)) + { + bonusTypes.put(bonusType, new ArrayList<>()); + } + ArrayList list = bonusTypes.get(bonusType); + list.add(equipmentBonus); + bonusTypes.put(bonusType, list); + } + } + + private final EquipmentItemset itemset; + private BonusType bonusType; + private EquipmentCombatBonus equipmentCombatBonus; + private List requirements = new ArrayList<>(); + private Operation operation = Operation.MULTIPLY; + EquipmentBonusConfig(BonusType bonusType, EquipmentItemset itemset, EquipmentCombatBonus equipmentCombatBonus) + { + this.bonusType = bonusType; + this.itemset = itemset; + this.equipmentCombatBonus = equipmentCombatBonus; + } + EquipmentBonusConfig(BonusType bonusType, EquipmentItemset itemset, EquipmentCombatBonus equipmentCombatBonus, List requirements) + { + this.bonusType = bonusType; + this.itemset = itemset; + this.equipmentCombatBonus = equipmentCombatBonus; + this.requirements = requirements; + } + + EquipmentBonusConfig(BonusType bonusType, EquipmentItemset itemset, EquipmentCombatBonus equipmentCombatBonus, List requirements, Operation operation) + { + this.bonusType = bonusType; + this.itemset = itemset; + this.equipmentCombatBonus = equipmentCombatBonus; + this.requirements = requirements; + this.operation = operation; + } + + public static ArrayList getBonusByType(BonusType bonusType) + { + if (!bonusTypes.containsKey(bonusType)) + { + return new ArrayList<>(); + } + return bonusTypes.get(bonusType); + } + + public EquipmentItemset getItemset() + { + return itemset; + } + + public Operation getOperation() + { + return operation; + } + + public double getBonus(MaxHitCalculator.CombatMethod combatMethod) + { + return this.equipmentCombatBonus.getCombatBonus(combatMethod); + } + + public boolean meetsRequirements(Client client) + { + return requirements.stream().allMatch(requirement -> requirement.meetsRequirements(client)); + } + + public enum BonusType + { + EQUIPMENT, + SLAYER, + VOID_KNIGHT, + SPECIAL, + MAGIC_SPECIAL + } + + public enum Operation + { + ADD, + MULTIPLY + } + +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/PrayerBonusConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/PrayerBonusConfig.java new file mode 100644 index 0000000000..fda776f170 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/PrayerBonusConfig.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.config; + +import net.runelite.api.Varbits; +import net.runelite.client.plugins.maxhit.calculators.MaxHitCalculator; + +public enum PrayerBonusConfig +{ + BURST_OF_STRENGTH(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_BURST_OF_STRENGTH, 0.05), + SUPERHUMAN_STRENGTH(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_SUPERHUMAN_STRENGTH, 0.1), + ULTIMATE_STRENGTH(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_ULTIMATE_STRENGTH, 0.15), + CHIVALRY(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_CHIVALRY, 0.18), + PIETY(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_PIETY, 0.23), + + SHARP_EYE(MaxHitCalculator.CombatMethod.RANGE, Varbits.PRAYER_SHARP_EYE, 0.05), + HAWK_EYE(MaxHitCalculator.CombatMethod.RANGE, Varbits.PRAYER_HAWK_EYE, 0.1), + EAGLE_EYE(MaxHitCalculator.CombatMethod.RANGE, Varbits.PRAYER_EAGLE_EYE, 0.15), + RIGOUR(MaxHitCalculator.CombatMethod.RANGE, Varbits.PRAYER_RIGOUR, 0.23); + + private final MaxHitCalculator.CombatMethod combatMethod; + private final Varbits prayerVarbit; + private final double strengthBonus; + + PrayerBonusConfig(MaxHitCalculator.CombatMethod combatMethod, Varbits prayerVarbit, double strengthBonus) + { + this.combatMethod = combatMethod; + this.prayerVarbit = prayerVarbit; + this.strengthBonus = strengthBonus; + } + + public MaxHitCalculator.CombatMethod getCombatMethod() + { + return combatMethod; + } + + public Varbits getPrayerVarbit() + { + return prayerVarbit; + } + + public double getStrengthBonus() + { + return strengthBonus; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/SpellBaseDamageConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/SpellBaseDamageConfig.java new file mode 100644 index 0000000000..cc47af1562 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/config/SpellBaseDamageConfig.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.config; + +import java.util.Arrays; + +public enum SpellBaseDamageConfig +{ + + /* + * Normal Spellbook + * */ + AIR_STRIKE(SpellBook.NORMAL, 1, 2), + WATER_STRIKE(SpellBook.NORMAL, 2, 4), + EARTH_STRIKE(SpellBook.NORMAL, 3, 6), + FIRE_STRIKE(SpellBook.NORMAL, 4, 8), + + AIR_BOLT(SpellBook.NORMAL, 5, 9), + WATER_BOLT(SpellBook.NORMAL, 6, 10), + EARTH_BOLT(SpellBook.NORMAL, 7, 11), + FIRE_BOLT(SpellBook.NORMAL, 8, 12), + + WIND_BLAST(SpellBook.NORMAL, 9, 13), + WATER_BLAST(SpellBook.NORMAL, 10, 14), + EARTH_BLAST(SpellBook.NORMAL, 11, 15), + FIRE_BLAST(SpellBook.NORMAL, 12, 16), + + AIR_WAVE(SpellBook.NORMAL, 13, 17), + WATER_WAVE(SpellBook.NORMAL, 14, 18), + EARTH_WAVE(SpellBook.NORMAL, 15, 19), + FIRE_WAVE(SpellBook.NORMAL, 16, 20), + + AIR_SURGE(SpellBook.NORMAL, 48, 21), + WATER_SURGE(SpellBook.NORMAL, 49, 22), + EARTH_SURGE(SpellBook.NORMAL, 50, 23), + FIRE_SURGE(SpellBook.NORMAL, 51, 24), + + /* + * Ancient Spellbook + * */ + SMOKE_RUSH(SpellBook.ANCIENT, 31, 14), + SHADOW_RUSH(SpellBook.ANCIENT, 32, 15), + BLOOD_RUSH(SpellBook.ANCIENT, 33, 16), + ICE_RUSH(SpellBook.ANCIENT, 34, 17), + + SMOKE_BURST(SpellBook.ANCIENT, 35, 18), + SHADOW_BURST(SpellBook.ANCIENT, 36, 19), + BLOOD_BURST(SpellBook.ANCIENT, 37, 21), + ICE_BURST(SpellBook.ANCIENT, 38, 22), + + SMOKE_BLITZ(SpellBook.ANCIENT, 39, 23), + SHADOW_BLITZ(SpellBook.ANCIENT, 40, 24), + BLOOD_BLITZ(SpellBook.ANCIENT, 41, 25), + ICE_BLITZ(SpellBook.ANCIENT, 42, 26), + + SMOKE_BARRAGE(SpellBook.ANCIENT, 43, 27), + SHADOW_BARRAGE(SpellBook.ANCIENT, 44, 28), + BLOOD_BARRAGE(SpellBook.ANCIENT, 55, 29), + ICE_BARRAGE(SpellBook.ANCIENT, 46, 30), + + /* + * Other spells + * */ + CRUMBLE_UNDEAD(SpellBook.OTHER, 17, 15), + IBAN_BLAST(SpellBook.OTHER, 47, 25), + FLAMES_OF_ZAMAROK(SpellBook.OTHER, 20, 20), + CLAWS_OF_GUTHIX(SpellBook.OTHER, 19, 20), + SARADOMIN_STRIKE(SpellBook.OTHER, 52, 20), + + /* + * Custom Formula spells + * */ + MAGIC_DART(SpellBook.OTHER, 18, 0); + + private final SpellBook spellBook; + private final int spellID; + private final int baseDamage; + + SpellBaseDamageConfig(SpellBook spellBook, int spellID, int baseDamage) + { + this.spellBook = spellBook; + this.spellID = spellID; + this.baseDamage = baseDamage; + } + + public static SpellBaseDamageConfig findSpellById(int spellID) + { + return Arrays.stream(values()).filter(spell -> spell.getSpellID() == spellID).findFirst().orElse(null); + } + + public int getSpellID() + { + return spellID; + } + + public int getBaseDamage() + { + return baseDamage; + } + + public SpellBook getSpellBook() + { + return spellBook; + } + + public enum SpellBook + { + NORMAL, + ANCIENT, + OTHER + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentCombatBonus.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentCombatBonus.java new file mode 100644 index 0000000000..33ca175d4d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentCombatBonus.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.equipment; + +import net.runelite.client.plugins.maxhit.calculators.MaxHitCalculator; + +public class EquipmentCombatBonus +{ + + private final double meleeBonus; + private final double rangeBonus; + private final double magicBonus; + + public EquipmentCombatBonus(double meleeBonus, double rangeBonus, double magicBonus) + { + this.meleeBonus = meleeBonus; + this.rangeBonus = rangeBonus; + this.magicBonus = magicBonus; + } + + public double getCombatBonus(MaxHitCalculator.CombatMethod combatMethod) + { + switch (combatMethod) + { + default: + case MELEE: + return this.meleeBonus; + case RANGE: + return this.rangeBonus; + case MAGIC: + return this.magicBonus; + } + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentHelper.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentHelper.java new file mode 100644 index 0000000000..e13dee215c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentHelper.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.equipment; + +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.api.Item; + +public class EquipmentHelper +{ + + public static boolean wearsItemSet(Item[] equipedItems, EquipmentItemset itemSet) + { + return itemSet.getItems().stream().allMatch(item -> wearsItem(equipedItems, item)); + } + + private static boolean wearsItem(Item[] equipedItems, EquipmentInventorySlot slot, int itemId) + { + Item item = equipedItems[slot.getSlotIdx()]; + if (item == null) + { + return false; + } + return item.getId() == itemId; + } + + public static boolean wearsItem(Item[] equipedItems, EquipmentSlotItem equipmentSlotItem) + { + return equipmentSlotItem.getItems().stream().anyMatch(itemId -> + wearsItem(equipedItems, equipmentSlotItem.getEquipmentSlot(), itemId) + ); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentItemset.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentItemset.java new file mode 100644 index 0000000000..12c295443f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentItemset.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.equipment; + +import java.util.List; + +public class EquipmentItemset +{ + private final List items; + + public EquipmentItemset(List items) + { + this.items = items; + } + + public List getItems() + { + return items; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentSlotItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentSlotItem.java new file mode 100644 index 0000000000..dbc44b3a53 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/equipment/EquipmentSlotItem.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.equipment; + +import net.runelite.api.EquipmentInventorySlot; + +import java.util.ArrayList; + +public class EquipmentSlotItem +{ + private final EquipmentInventorySlot equipmentSlot; + private final ArrayList itemIds; + + public EquipmentSlotItem(EquipmentInventorySlot equipmentSlot, ArrayList itemIds) + { + this.equipmentSlot = equipmentSlot; + this.itemIds = itemIds; + } + + public ArrayList getItems() + { + return this.itemIds; + } + + public EquipmentInventorySlot getEquipmentSlot() + { + return this.equipmentSlot; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/AutocastSpellRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/AutocastSpellRequirement.java new file mode 100644 index 0000000000..988e459631 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/AutocastSpellRequirement.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.requirements; + +import net.runelite.api.Client; +import net.runelite.api.Varbits; +import net.runelite.client.plugins.maxhit.config.SpellBaseDamageConfig; + +import java.util.ArrayList; + +public class AutocastSpellRequirement implements Requirement +{ + + private final ArrayList autocastSpells; + + public AutocastSpellRequirement(ArrayList autocastSpells) + { + this.autocastSpells = autocastSpells; + } + + @Override + public boolean meetsRequirements(Client client) + { + int autoCastSpellId = client.getVar(Varbits.AUTO_CAST_SPELL); + + if (autoCastSpellId == 0) + { + + return false; + + } + + return this.autocastSpells.stream().anyMatch(spell -> spell.getSpellID() == autoCastSpellId); + + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/EquipmentItemRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/EquipmentItemRequirement.java new file mode 100644 index 0000000000..d0ed360f43 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/EquipmentItemRequirement.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.requirements; + +import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.client.plugins.maxhit.equipment.EquipmentHelper; +import net.runelite.client.plugins.maxhit.equipment.EquipmentSlotItem; + +public class EquipmentItemRequirement implements Requirement +{ + private final EquipmentSlotItem item; + + public EquipmentItemRequirement(EquipmentSlotItem item) + { + this.item = item; + } + + @Override + public boolean meetsRequirements(Client client) + { + ItemContainer equipmentContainer = client.getItemContainer(InventoryID.EQUIPMENT); + if (equipmentContainer == null) + { + return false; + } + Item[] equipedItems = equipmentContainer.getItems(); + return EquipmentHelper.wearsItem(equipedItems, this.item); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/EquipmentItemSetRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/EquipmentItemSetRequirement.java new file mode 100644 index 0000000000..31b322c02d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/EquipmentItemSetRequirement.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.requirements; + +import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.client.plugins.maxhit.equipment.EquipmentHelper; +import net.runelite.client.plugins.maxhit.equipment.EquipmentItemset; + +public class EquipmentItemSetRequirement implements Requirement +{ + private final EquipmentItemset itemSet; + + public EquipmentItemSetRequirement(EquipmentItemset itemSet) + { + this.itemSet = itemSet; + } + + @Override + public boolean meetsRequirements(Client client) + { + ItemContainer equipmentContainer = client.getItemContainer(InventoryID.EQUIPMENT); + if (equipmentContainer == null) + { + return false; + } + Item[] equipedItems = equipmentContainer.getItems(); + + return EquipmentHelper.wearsItemSet(equipedItems, this.itemSet); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/Requirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/Requirement.java new file mode 100644 index 0000000000..48e9cc677a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/Requirement.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.requirements; + +import net.runelite.api.Client; + +public interface Requirement +{ + boolean meetsRequirements(Client client); +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/SpellBookRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/SpellBookRequirement.java new file mode 100644 index 0000000000..d59723577e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/SpellBookRequirement.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.requirements; + +import net.runelite.api.Client; +import net.runelite.api.Varbits; +import net.runelite.client.plugins.maxhit.config.SpellBaseDamageConfig; + +public class SpellBookRequirement implements Requirement +{ + private final SpellBaseDamageConfig.SpellBook spellBook; + + public SpellBookRequirement(SpellBaseDamageConfig.SpellBook spellBook) + { + this.spellBook = spellBook; + } + + @Override + public boolean meetsRequirements(Client client) + { + int autoCastSpellId = client.getVar(Varbits.AUTO_CAST_SPELL); + if (autoCastSpellId == 0) + { + return false; + } + + SpellBaseDamageConfig autoCastSpell = SpellBaseDamageConfig.findSpellById(autoCastSpellId); + return autoCastSpell.getSpellBook() == this.spellBook; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/SpellRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/SpellRequirement.java new file mode 100644 index 0000000000..4084044048 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/requirements/SpellRequirement.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.requirements; + +import net.runelite.api.Client; +import net.runelite.api.Varbits; +import net.runelite.client.plugins.maxhit.config.SpellBaseDamageConfig; + +public class SpellRequirement implements Requirement +{ + private final SpellBaseDamageConfig spellBaseDamageConfig; + + public SpellRequirement(SpellBaseDamageConfig spellBaseDamageConfig) + { + this.spellBaseDamageConfig = spellBaseDamageConfig; + } + + @Override + public boolean meetsRequirements(Client client) + { + int autoCastSpellId = client.getVar(Varbits.AUTO_CAST_SPELL); + if (autoCastSpellId == 0) + { + return false; + } + + return autoCastSpellId == this.spellBaseDamageConfig.getSpellID(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index 36185d8aed..cb68438e51 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -282,4 +282,14 @@ public interface MenuEntrySwapperConfig extends Config { return true; } + + @ConfigItem( + keyName = "swapRogueschests", + name = "Rogueschests", + description = "Swap Rogueschests from open to Search for traps" + ) + default boolean swapRogueschests() + { + return true; + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index b164d10b86..d051028e5b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -544,6 +544,10 @@ public class MenuEntrySwapperPlugin extends Plugin { swap("pick-lots", option, target, true); } + else if (config.swapRogueschests() && target.contains("chest")) + { + swap("search for traps", option, target, true); + } else if (config.shiftClickCustomization() && shiftModifier && !option.equals("use")) { Integer customOption = getSwapConfig(eventId); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Game.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Game.java index db9659994f..6e9e4274bd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Game.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Game.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, Adam + * Copyright (c) 2019, Yani * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,97 +25,220 @@ */ package net.runelite.client.plugins.pestcontrol; +import java.time.Duration; +import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.List; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import static net.runelite.client.plugins.pestcontrol.Portal.BLUE; -import static net.runelite.client.plugins.pestcontrol.Portal.PURPLE; -import static net.runelite.client.plugins.pestcontrol.Portal.RED; -import static net.runelite.client.plugins.pestcontrol.Portal.YELLOW; +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.GameTick; @Slf4j -class Game +public class Game { + private Client client; + + private PestControlPlugin plugin; + + @Getter + private Portal bluePortal = new Portal(PortalColor.BLUE, WidgetPortal.BLUE); + + @Getter + private Portal purplePortal = new Portal(PortalColor.PURPLE, WidgetPortal.PURPLE); + + @Getter + private Portal yellowPortal = new Portal(PortalColor.YELLOW, WidgetPortal.YELLOW); + + @Getter + private Portal redPortal = new Portal(PortalColor.RED, WidgetPortal.RED); + + @Getter + private int shieldsDropped = 0; + // Game starts with all possible rotations - private Rotation[] possibleRotations = Rotation.values(); - // Number of shields dropped - private int shieldsDropped; + private PortalRotation[] possibleRotations = PortalRotation.values(); - @Getter - private final PortalContext purple = new PortalContext(PURPLE); - @Getter - private final PortalContext blue = new PortalContext(BLUE); - @Getter - private final PortalContext yellow = new PortalContext(YELLOW); - @Getter - private final PortalContext red = new PortalContext(RED); + private boolean portalLocationsSet = false; - void fall(String color) + + private Instant startTime = Instant.now(); + + public Game(Client client, PestControlPlugin plugin) { - switch (color.toLowerCase()) + this.client = client; + this.plugin = plugin; + } + + public void onGameTick(GameTick gameTickEvent) + { + if (!portalLocationsSet) + { + loadPortalLocations(); + } + + WidgetOverlay widgetOverlay = plugin.getWidgetOverlay(); + + if (!purplePortal.isDead() && widgetOverlay.getPortalHitpoints(PortalColor.PURPLE) == 0) + { + killPortal(purplePortal); + } + + if (!yellowPortal.isDead() && widgetOverlay.getPortalHitpoints(PortalColor.YELLOW) == 0) + { + killPortal(yellowPortal); + } + + if (!redPortal.isDead() && widgetOverlay.getPortalHitpoints(PortalColor.RED) == 0) + { + killPortal(redPortal); + } + + if (!bluePortal.isDead() && widgetOverlay.getPortalHitpoints(PortalColor.BLUE) == 0) + { + killPortal(bluePortal); + } + } + + public void lowerPortalShield(String portalColor) + { + switch (portalColor.toLowerCase()) { case "purple": - fall(purple); + lowerPortalShield(purplePortal); break; case "red": - fall(red); + lowerPortalShield(redPortal); break; case "yellow": - fall(yellow); + lowerPortalShield(yellowPortal); break; case "blue": - fall(blue); + lowerPortalShield(bluePortal); break; } } - private void fall(PortalContext portal) + private void lowerPortalShield(Portal portal) { if (!portal.isShielded()) { return; } - log.debug("Shield dropped for {}", portal.getPortal()); + log.debug("Shield dropped for {}", portal.getColor()); + + portal.setPortalState(PortalState.ACTIVE); - portal.setShielded(false); int shieldDrop = shieldsDropped++; // Remove impossible rotations - List rotations = new ArrayList<>(); + List rotations = new ArrayList<>(); - for (Rotation rotation : possibleRotations) + for (PortalRotation rotation : possibleRotations) { - if (rotation.getPortal(shieldDrop) == portal.getPortal()) + if (rotation.getPortal(this, shieldDrop) == portal) { rotations.add(rotation); } } - possibleRotations = rotations.toArray(new Rotation[rotations.size()]); + possibleRotations = rotations.toArray(new PortalRotation[rotations.size()]); } - void die(PortalContext portal) + public void killPortal(Portal portal) { if (portal.isDead()) { return; } - log.debug("Portal {} died", portal.getPortal()); + log.debug("Portal {} died", portal.getColor()); - portal.setDead(true); + portal.setPortalState(PortalState.DEAD); } - Collection getNextPortals() + private boolean loadPortalLocations() + { + NPC squire = null; + + for (NPC npc : client.getNpcs()) + { + if (PestControlNpc.isIngameSquireId(npc.getId())) + { + squire = npc; + break; + } + } + + if (squire != null) + { + log.debug("In-game Squire found: {}", squire); + setPortalLocations(squire.getWorldLocation()); + + return true; + } + + return false; + } + + public void setPortalLocations(WorldPoint squireLocation) + { + int x = squireLocation.getX(); + int y = squireLocation.getY(); + + purplePortal.setLocation(new WorldPoint(x - 26, y - 15, 0)); + bluePortal.setLocation(new WorldPoint(x + 26, y - 18, 0)); + yellowPortal.setLocation(new WorldPoint(x + 15, y - 36, 0)); + redPortal.setLocation(new WorldPoint(x - 9, y - 37, 0)); + + portalLocationsSet = true; + } + + public List getPortals() + { + List portalList = new ArrayList(); + + portalList.add(getPurplePortal()); + portalList.add(getBluePortal()); + portalList.add(getYellowPortal()); + portalList.add(getRedPortal()); + + return portalList; + } + + public Portal getPortal(PortalColor portalColor) + { + if (bluePortal.getColor() == portalColor) + { + return bluePortal; + } + if (redPortal.getColor() == portalColor) + { + return redPortal; + } + if (purplePortal.getColor() == portalColor) + { + return purplePortal; + } + if (yellowPortal.getColor() == portalColor) + { + return yellowPortal; + } + + return null; + } + + public Collection getNextPortals() { List portals = new ArrayList<>(); - for (Rotation rotation : possibleRotations) + for (PortalRotation rotation : possibleRotations) { - Portal portal = rotation.getPortal(shieldsDropped); + Portal portal = rotation.getPortal(this, shieldsDropped); if (portal != null && !portals.contains(portal)) { @@ -124,4 +248,40 @@ class Game return portals; } + + public Collection getActivePortals() + { + List portals = new ArrayList<>(); + + for (Portal portal : getPortals()) + { + if (portal.isActive()) + { + portals.add(portal); + } + } + + return portals; + } + + public Duration getTimeTillNextPortal() + { + Instant nextShieldDrop; + + if (shieldsDropped == 4) + { + return null; + } + + if (shieldsDropped == 0) + { + nextShieldDrop = Instant.ofEpochSecond(startTime.getEpochSecond() + 17); + } + else + { + nextShieldDrop = Instant.ofEpochSecond(startTime.getEpochSecond() + 17 + (30 * shieldsDropped)); + } + + return Duration.between(Instant.now(), nextShieldDrop); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/GangplankOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/GangplankOverlay.java new file mode 100644 index 0000000000..db8abe87b7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/GangplankOverlay.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import com.google.inject.Inject; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.api.Tile; +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.tooltip.Tooltip; +import net.runelite.client.ui.overlay.tooltip.TooltipManager; +import net.runelite.client.util.ColorUtil; + +@Slf4j +public class GangplankOverlay extends Overlay +{ + private final Client client; + private final PestControlConfig config; + private final PestControlPlugin plugin; + private final TooltipManager tooltipManager; + + @Inject + GangplankOverlay(Client client, PestControlConfig config, PestControlPlugin plugin, TooltipManager toolTipManager) + { + this.config = config; + this.plugin = plugin; + this.client = client; + this.tooltipManager = toolTipManager; + + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!plugin.isOnPestControlMainIsland()) + { + return null; + } + + Player localPlayer = client.getLocalPlayer(); + + if (localPlayer == null) + { + return null; + } + + int combatLevel = localPlayer.getCombatLevel(); + + Color noviceCbColor = (combatLevel >= 40) ? Color.GREEN : Color.RED; + Color intermediateCbColor = (combatLevel >= 70) ? Color.GREEN : Color.RED; + Color veteranCbColor = (combatLevel >= 100) ? Color.GREEN : Color.RED; + + Tile noviceGangplankTile = plugin.getNoviceGangplankTile(); + Tile intermediateGangplankTile = plugin.getIntermediateGangplankTile(); + Tile veteranGangplankTile = plugin.getVeteranGangplankTile(); + + Point mousePosition = client.getMouseCanvasPosition(); + String tooltipString = null; + + if (noviceGangplankTile != null) + { + Polygon polygon = noviceGangplankTile.getGameObjects()[0].getConvexHull(); + if (polygon != null) + { + graphics.setColor(noviceCbColor); + graphics.setStroke(new BasicStroke(2)); + graphics.drawPolygon(polygon); + graphics.setColor(setColorAlpha(noviceCbColor, 45)); + graphics.fill(polygon); + + if (polygon.contains(mousePosition.getX(), mousePosition.getY())) + { + tooltipString = ColorUtil.wrapWithColorTag("Combat 40+", noviceCbColor) + " (3 points)"; + graphics.setColor(setColorAlpha(noviceCbColor, 65)); + graphics.fill(polygon); + } + } + } + + if (intermediateGangplankTile != null) + { + Polygon polygon = intermediateGangplankTile.getGameObjects()[0].getConvexHull(); + if (polygon != null) + { + graphics.setColor(intermediateCbColor); + graphics.setStroke(new BasicStroke(2)); + graphics.drawPolygon(polygon); + graphics.setColor(setColorAlpha(intermediateCbColor, 45)); + graphics.fill(polygon); + + if (polygon.contains(mousePosition.getX(), mousePosition.getY())) + { + tooltipString = ColorUtil.wrapWithColorTag("Combat 70+", intermediateCbColor) + " (4 points)"; + graphics.setColor(setColorAlpha(intermediateCbColor, 65)); + graphics.fill(polygon); + } + } + } + + if (veteranGangplankTile != null) + { + Polygon polygon = veteranGangplankTile.getGameObjects()[0].getConvexHull(); + if (polygon != null) + { + graphics.setColor(veteranCbColor); + graphics.setStroke(new BasicStroke(2)); + graphics.drawPolygon(polygon); + graphics.setColor(setColorAlpha(veteranCbColor, 45)); + graphics.fill(polygon); + + if (polygon.contains(mousePosition.getX(), mousePosition.getY())) + { + tooltipString = ColorUtil.wrapWithColorTag("Combat 100+", veteranCbColor) + " (5 points)"; + graphics.setColor(setColorAlpha(veteranCbColor, 65)); + graphics.fill(polygon); + } + } + } + + if (tooltipString != null) + { + tooltipManager.add(new Tooltip(tooltipString)); + } + + return null; + } + + private Color setColorAlpha(Color color, int alpha) + { + return new Color( + color.getRed(), + color.getGreen(), + color.getBlue(), + alpha + ); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/HintArrowOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/HintArrowOverlay.java new file mode 100644 index 0000000000..0d9660ed37 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/HintArrowOverlay.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; + +public class HintArrowOverlay extends Overlay +{ + private final PestControlConfig config; + private final PestControlPlugin plugin; + private final Client client; + + @Inject + HintArrowOverlay(PestControlConfig config, PestControlPlugin plugin, Client client) + { + this.config = config; + this.plugin = plugin; + this.client = client; + + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (plugin.getGame() == null) + { + return null; + } + + List visibleActivePortals = new ArrayList<>(); + List visibleShieldedPortals = new ArrayList<>(); + + for (NPC npc : client.getNpcs()) + { + if (PestControlNpc.isActivePortalId(npc.getId())) + { + visibleActivePortals.add(npc); + } + } + + if (!visibleActivePortals.isEmpty()) + { + NPC closestPortalNpc = getClosestNpc(visibleActivePortals); + + if (closestPortalNpc != null) + { + NPC currentHintArrowTarget = client.getHintArrowNpc(); + + if (currentHintArrowTarget == null || currentHintArrowTarget != closestPortalNpc) + { + client.setHintArrow(closestPortalNpc); + } + } + + return null; + } + + Portal closestActivePortal = getClosestPortal(PortalState.ACTIVE); + + if (closestActivePortal != null) + { + WorldPoint currentHintArrowLocation = client.getHintArrowPoint(); + WorldPoint closestActivePortalLocation = closestActivePortal.getLocation(); + + if (currentHintArrowLocation == null || currentHintArrowLocation != closestActivePortalLocation) + { + client.setHintArrow(closestActivePortalLocation); + } + + return null; + } + + Collection nextPortalList = plugin.getGame().getNextPortals(); + + if (nextPortalList.size() == 1) + { + client.setHintArrow(nextPortalList.iterator().next().getLocation()); + + return null; + } + + return null; + } + + private NPC getClosestNpc(List npcList) + { + WorldPoint currentLocation = client.getLocalPlayer().getWorldLocation(); + + NPC closestNpc = null; + int currentShortestDistance = 1337; + int distanceToNpc; + + for (NPC npc : npcList) + { + if (closestNpc != null) + { + distanceToNpc = npc.getWorldLocation().distanceTo(currentLocation); + + if (distanceToNpc < currentShortestDistance) + { + closestNpc = npc; + currentShortestDistance = distanceToNpc; + } + } + else + { + closestNpc = npc; + } + } + + return closestNpc; + } + + private Portal getClosestPortal(PortalState portalState) + { + WorldPoint currentLocation = client.getLocalPlayer().getWorldLocation(); + + Portal closestPortal = null; + int currentShortestDistance = 1337; + int distanceToWorldPoint; + + for (Portal portal : plugin.getGame().getPortals()) + { + if (portal.getPortalState() != portalState) + { + continue; + } + + distanceToWorldPoint = portal.getLocation().distanceTo(currentLocation); + + if (distanceToWorldPoint < currentShortestDistance) + { + closestPortal = portal; + currentShortestDistance = distanceToWorldPoint; + } + } + + return closestPortal; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/NpcHighlightContext.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/NpcHighlightContext.java new file mode 100644 index 0000000000..56c51fdd8d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/NpcHighlightContext.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import java.awt.Color; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import net.runelite.client.plugins.pestcontrol.config.NpcHighlightStyle; + +@AllArgsConstructor +@Getter +@Setter +public class NpcHighlightContext +{ + private NpcHighlightStyle npcRenderStyle; + private Color color; + private boolean showNpcName = false; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/NpcHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/NpcHighlightOverlay.java new file mode 100644 index 0000000000..bb8e94c175 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/NpcHighlightOverlay.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import com.google.inject.Inject; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.util.HashMap; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.client.plugins.pestcontrol.config.NpcHighlightStyle; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayUtil; + +@Slf4j +public class NpcHighlightOverlay extends Overlay +{ + private final PestControlConfig config; + private final PestControlPlugin plugin; + private final Client client; + + @Inject + NpcHighlightOverlay(PestControlConfig config, PestControlPlugin plugin, Client client) + { + this.config = config; + this.plugin = plugin; + this.client = client; + + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (plugin.getGame() == null) + { + return null; + } + + HashMap highlightedNpcList = plugin.getHighlightedNpcList(); + + for (NPC npc : client.getNpcs()) + { + if (!highlightedNpcList.containsKey(npc.getId())) + { + continue; + } + + NpcHighlightContext npcHighlightContext = plugin.getHighlightedNpcList().get(npc.getId()); + + String name = npcHighlightContext.isShowNpcName() ? npc.getName() : null; + Color color = npcHighlightContext.getColor(); + NpcHighlightStyle highlightStyle = npcHighlightContext.getNpcRenderStyle(); + + switch (highlightStyle) + { + case HULL: + { + renderHullOverlay(graphics, npc, color); + break; + } + case TILE: + { + renderTileOverlay(graphics, npc, color); + break; + } + case BOTH: + { + renderHullOverlay(graphics, npc, color); + renderTileOverlay(graphics, npc, color); + break; + } + } + + if (name != null) + { + renderTextOverlay(graphics, npc, name, color); + } + } + + return null; + } + + private void renderTileOverlay(Graphics2D graphics, NPC npc, Color color) + { + Polygon polygon; + Color fillColor; + + // Double the polygon size if it's a Brawler + if (PestControlNpc.isBrawlerId(npc.getId())) + { + polygon = Perspective.getCanvasTileAreaPoly(client, npc.getLocalLocation(), 2); + fillColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), 35); + } + else + { + polygon = npc.getCanvasTilePoly(); + fillColor = new Color(0, 0, 0, 50); + } + + if (polygon != null) + { + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2)); + graphics.drawPolygon(polygon); + graphics.setColor(fillColor); + graphics.fillPolygon(polygon); + } + } + + private void renderHullOverlay(Graphics2D graphics, NPC npc, Color color) + { + Polygon objectClickbox = npc.getConvexHull(); + if (objectClickbox != null) + { + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2)); + graphics.draw(objectClickbox); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 20)); + graphics.fill(objectClickbox); + } + } + + private void renderTextOverlay(Graphics2D graphics, NPC npc, String text, Color color) + { + Point textLocation = npc.getCanvasTextLocation(graphics, text, npc.getLogicalHeight() + 40); + if (textLocation != null) + { + OverlayUtil.renderTextLocation(graphics, textLocation, text, color); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlConfig.java new file mode 100644 index 0000000000..03162389ad --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlConfig.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.plugins.pestcontrol.config.HighlightPortalOption; +import net.runelite.client.plugins.pestcontrol.config.NpcHighlightStyle; + +@ConfigGroup("pestcontrol") +public interface PestControlConfig extends Config +{ + @ConfigItem( + keyName = "showHintArrow", + name = "Show hint arrows", + description = "Show hint arrows to the portals that can be attacked.", + position = 1 + ) + default boolean showHintArrow() + { + return true; + } + + @ConfigItem( + keyName = "showPortalWeakness", + name = "Show portal weakness", + description = "Show the combat style weakness of the portals. For melee the attack styles are shown: Stab/Crush/Slash", + position = 2 + ) + default boolean showPortalWeakness() + { + return false; + } + + @ConfigItem( + keyName = "highlightGangplanks", + name = "Highlight gangplanks", + description = "Highlight the boarding gangplanks and show the required combat level.", + position = 3 + ) + default boolean highlightGangplanks() + { + return true; + } + + @ConfigItem( + keyName = "highlightPortals", + name = "Highlight portals", + description = "Highlight all, active or shielded portals.", + position = 4 + ) + default HighlightPortalOption portalHighlight() + { + return HighlightPortalOption.ACTIVE; + } + + @ConfigItem( + keyName = "activePortalColor", + name = "Active portal color", + description = "Color of the portals that can be attacked.", + position = 5 + ) + default Color activePortalColor() + { + return Color.GREEN; + } + + @ConfigItem( + keyName = "shieldedPortalColor", + name = "Shielded portal color", + description = "Color of the portals that are shielded.", + position = 6 + ) + default Color shieldedPortalColor() + { + return Color.BLUE; + } + + @ConfigItem( + keyName = "highlightSpinners", + name = "Highlight Spinners", + description = "Highlights Spinners. Highlighting them is recommended as Spinners heal the portals.", + position = 7 + ) + default NpcHighlightStyle highlightSpinners() + { + return NpcHighlightStyle.BOTH; + } + + @ConfigItem( + keyName = "spinnerColor", + name = "Spinner color", + description = "Color of highlighted Spinners.", + position = 8 + ) + default Color spinnerColor() + { + return Color.CYAN; + } + + @ConfigItem( + keyName = "highlightBrawlers", + name = "Highlight Brawlers", + description = "Highlights Brawlers.", + position = 9 + ) + default NpcHighlightStyle highlightBrawlers() + { + return NpcHighlightStyle.TILE; + } + + @ConfigItem( + keyName = "brawlerColor", + name = "Brawler color", + description = "Color of highlighted Brawlers.", + position = 10 + ) + default Color brawlerColor() + { + return Color.ORANGE; + } + + @ConfigItem( + keyName = "highlightRepairables", + name = "Highlight repairables", + description = "Highlight repairable barricades and gates.", + position = 11 + ) + default boolean highlightRepairables() + { + return false; + } + + @ConfigItem( + keyName = "repairableColor", + name = "Repairable color", + description = "Color of highlighted repairables.", + position = 12 + ) + /*default Color repairableColor() + { + return new Color(193, 141, 255); + }*/ + default Color repairableColor() + { + return Color.YELLOW; + } + + @ConfigItem( + keyName = "showPoints", + name = "Show points indicator", + description = "Always display your points when on the island or in the minigame.", + position = 13 + ) + default boolean showPoints() + { + return true; + } + + @ConfigItem( + keyName = "showTimeTillNextPortal", + name = "Show time till next portal", + description = "Show a timer that counts down till the next portal is attackable.", + position = 14 + ) + default boolean showTimeTillNextPortal() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlNpc.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlNpc.java new file mode 100644 index 0000000000..e1b9ef143e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlNpc.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import com.google.common.collect.ImmutableSet; +import java.util.Set; +import lombok.Getter; +import net.runelite.api.NpcID; + +@Getter +public class PestControlNpc +{ + @Getter + private static final Set splatterIdSet = ImmutableSet.of( + NpcID.SPLATTER, + NpcID.SPLATTER_1690, + NpcID.SPLATTER_1691, + NpcID.SPLATTER_1692, + NpcID.SPLATTER_1693 + ); + + @Getter + public static final Set shifterIdSet = ImmutableSet.of( + NpcID.SHIFTER, + NpcID.SHIFTER_1695, + NpcID.SHIFTER_1696, + NpcID.SHIFTER_1697, + NpcID.SHIFTER_1698, + NpcID.SHIFTER_1699, + NpcID.SHIFTER_1700, + NpcID.SHIFTER_1701, + NpcID.SHIFTER_1702, + NpcID.SHIFTER_1703 + ); + + @Getter + private static final Set spinnerIdSet = ImmutableSet.of( + NpcID.SPINNER, + NpcID.SPINNER_1710, + NpcID.SPINNER_1711, + NpcID.SPINNER_1712, + NpcID.SPINNER_1713 + ); + + @Getter + private static final Set torcherIdSet = ImmutableSet.of( + NpcID.TORCHER, + NpcID.TORCHER_1715, + NpcID.TORCHER_1716, + NpcID.TORCHER_1717, + NpcID.TORCHER_1718, + NpcID.TORCHER_1719, + NpcID.TORCHER_1720, + NpcID.TORCHER_1721, + NpcID.TORCHER_1722, + NpcID.TORCHER_1723 + ); + + @Getter + private static final Set defilerIdSet = ImmutableSet.of( + NpcID.DEFILER, + NpcID.DEFILER_1725, + NpcID.DEFILER_1726, + NpcID.DEFILER_1727, + NpcID.DEFILER_1728, + NpcID.DEFILER_1729, + NpcID.DEFILER_1730, + NpcID.DEFILER_1731, + NpcID.DEFILER_1732, + NpcID.DEFILER_1733 + ); + + @Getter + private static final Set brawlerIdSet = ImmutableSet.of( + NpcID.BRAWLER, + NpcID.BRAWLER_1735, + NpcID.BRAWLER_1736, + NpcID.BRAWLER_1737, + NpcID.BRAWLER_1738 + ); + + @Getter + private static final Set ravagerIdSet = ImmutableSet.of( + NpcID.RAVAGER, + NpcID.RAVAGER_1705, + NpcID.RAVAGER_1706, + NpcID.RAVAGER_1707, + NpcID.RAVAGER_1708 + ); + + @Getter + private static final Set activePortalIdSet = ImmutableSet.of( + NpcID.PORTAL_1747, // Novice Purple Active + NpcID.PORTAL_1748, // Novice Blue Active + NpcID.PORTAL_1749, // Novice Yellow Active + NpcID.PORTAL_1750, // Novice Red Active + NpcID.PORTAL, // Intermediate Purple Active + NpcID.PORTAL_1740, // Intermediate Blue Active + NpcID.PORTAL_1741, // Intermediate Yellow Active + NpcID.PORTAL_1742 // Intermediate Red Active + ); + + @Getter + private static final Set shieldedPortalIdSet = ImmutableSet.of( + NpcID.PORTAL_1751, // Novice Purple Shielded + NpcID.PORTAL_1752, // Novice Blue Shielded + NpcID.PORTAL_1753, // Novice Yellow Shielded + NpcID.PORTAL_1754, // Novice Red Shielded + NpcID.PORTAL_1743, // Intermediate Purple Shielded + NpcID.PORTAL_1744, // Intermediate Blue Shielded + NpcID.PORTAL_1745, // Intermediate Yellow Shielded + NpcID.PORTAL_1746 // Intermediate Red Shielded + ); + + @Getter + private static final Set purplePortalIdSet = ImmutableSet.of( + NpcID.PORTAL_1747, // Novice Purple Active + NpcID.PORTAL_1751, // Novice Purple Shielded + NpcID.PORTAL, // Intermediate Purple Active + NpcID.PORTAL_1743 // Intermediate Purple Shielded + ); + + @Getter + private static final Set bluePortalIdSet = ImmutableSet.of( + NpcID.PORTAL_1748, // Novice Blue Active + NpcID.PORTAL_1752, // Novice Blue Shielded + NpcID.PORTAL_1740, // Intermediate Blue Active + NpcID.PORTAL_1744 // Intermediate Blue Shielded + ); + + @Getter + private static final Set yellowPortalIdSet = ImmutableSet.of( + NpcID.PORTAL_1749, // Novice Yellow Active + NpcID.PORTAL_1753, // Novice Yellow Shielded + NpcID.PORTAL_1741, // Intermediate Yellow Active + NpcID.PORTAL_1745 // Intermediate Yellow Shielded + ); + + @Getter + private static final Set redPortalIdSet = ImmutableSet.of( + NpcID.PORTAL_1750, // Novice Red Active + NpcID.PORTAL_1754, // Novice Red Shielded + NpcID.PORTAL_1742, // Intermediate Red Active + NpcID.PORTAL_1746 // Intermediate Red Shielded + ); + + @Getter + private static final Set ingameVoidKnightIdSet = ImmutableSet.of( + NpcID.VOID_KNIGHT_2950, + NpcID.VOID_KNIGHT_2951, + NpcID.VOID_KNIGHT_2952, + NpcID.VOID_KNIGHT_2953 + ); + + @Getter + private static final Integer ingameSquireId = NpcID.SQUIRE_2949; + + public static boolean isSplatterId(int npcId) + { + return splatterIdSet.contains(npcId); + } + + public static boolean isShifterId(int npcId) + { + return shifterIdSet.contains(npcId); + } + + public static boolean isSpinnerId(int npcId) + { + return brawlerIdSet.contains(npcId); + } + + public static boolean isTorcherId(int npcId) + { + return torcherIdSet.contains(npcId); + } + + public static boolean isDefilerId(int npcId) + { + return defilerIdSet.contains(npcId); + } + + public static boolean isBrawlerId(int npcId) + { + return brawlerIdSet.contains(npcId); + } + + public static boolean isRavagerId(int npcId) + { + return ravagerIdSet.contains(npcId); + } + + public static boolean isIngameVoidKnightId(int npcId) + { + return ingameVoidKnightIdSet.contains(npcId); + } + + public static boolean isIngameSquireId(int npcId) + { + return ingameSquireId == npcId; + } + + public static boolean isPortalId(int npcId) + { + return (isActivePortalId(npcId) || isShieldedPortalId(npcId)); + } + + public static boolean isActivePortalId(int npcId) + { + return activePortalIdSet.contains(npcId); + } + + public static boolean isShieldedPortalId(int npcId) + { + return shieldedPortalIdSet.contains(npcId); + } + + public static boolean isPurplePortalId(int npcId) + { + return purplePortalIdSet.contains(npcId); + } + + public static boolean isBluePortalId(int npcId) + { + return bluePortalIdSet.contains(npcId); + } + + public static boolean isYellowPortalId(int npcId) + { + return yellowPortalIdSet.contains(npcId); + } + + public static boolean isRedPortalId(int npcId) + { + return redPortalIdSet.contains(npcId); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java index 960b589737..090874604a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, Kronos + * Copyright (c) 2019, Yani * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,29 +25,47 @@ */ package net.runelite.client.plugins.pestcontrol; -import com.google.common.collect.ImmutableSet; +import com.google.inject.Inject; +import com.google.inject.Provides; +import java.awt.image.BufferedImage; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.inject.Inject; -import lombok.AccessLevel; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameState; -import net.runelite.api.NPC; -import net.runelite.api.NpcID; +import net.runelite.api.ItemID; +import net.runelite.api.Tile; +import net.runelite.api.TileObject; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameObjectChanged; +import net.runelite.api.events.GameObjectDespawned; +import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.NpcDespawned; -import net.runelite.api.events.NpcSpawned; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.GroundObjectChanged; +import net.runelite.api.events.GroundObjectDespawned; +import net.runelite.api.events.GroundObjectSpawned; +import net.runelite.api.events.WidgetLoaded; +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.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.pestcontrol.config.HighlightPortalOption; +import net.runelite.client.plugins.pestcontrol.config.NpcHighlightStyle; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.util.Text; +@Slf4j @PluginDescriptor( name = "Pest Control", description = "Show helpful information for the Pest Control minigame", @@ -54,77 +73,598 @@ import net.runelite.client.ui.overlay.OverlayManager; ) public class PestControlPlugin extends Plugin { - private static final Set SPINNER_IDS = ImmutableSet.of( - NpcID.SPINNER, - NpcID.SPINNER_1710, - NpcID.SPINNER_1711, - NpcID.SPINNER_1712, - NpcID.SPINNER_1713 - ); + private final int NOVICE_GANGPLANK = 14315; // Combat 40+ (3 points) + private final int INTERMEDIATE_GANGPLANK = 25631; // Combat 70+ (4 points) + private final int VETERAN_GANGPLANK = 25632; // Combat 100+ (5 points) - private final Pattern SHIELD_DROP = Pattern.compile("The ([a-z]+), [^ ]+ portal shield has dropped!", Pattern.CASE_INSENSITIVE); + private final Pattern SHIELD_DROP_PATTERN = Pattern.compile("The ([a-z]+), [^ ]+ portal shield has dropped!"); + private final Pattern EXCHANGE_WINDOW_POINTS_PATTERN = Pattern.compile("Points: ([0-9]+)"); + private final Pattern BOAT_POINTS_PATTERN = Pattern.compile("Pest Points: ([0-9]+)"); + private final Pattern AWARDED_PATTERN = Pattern.compile("We've awarded you ([0-9]+) Void Knight Commendation points."); + private final Pattern PURCHASE_PATTERN = Pattern.compile("Remaining Void Knight Commendation Points: ([0-9]+)"); - @Getter(AccessLevel.PACKAGE) - private List spinners = new ArrayList<>(); + @Inject + @Getter + private Client client; @Inject private OverlayManager overlayManager; @Inject - private Client client; + private ConfigManager configManager; @Inject - private PestControlOverlay overlay; + private InfoBoxManager infoBoxManager; + + @Inject + @Getter + private ItemManager itemManager; + + @Inject + @Getter + private PestControlConfig config; + + @Inject + @Getter + private WidgetOverlay widgetOverlay; + + @Inject + private HintArrowOverlay hintArrowOverlay; + + @Inject + private NpcHighlightOverlay npcHighlightOverlay; + + @Inject + private RepairOverlay repairOverlay; + + @Inject + private GangplankOverlay gangplankOverlay; + + @Inject + private TimerOverlay timerOverlay; + + @Inject + private PortalWeaknessOverlay portalWeaknessOverlay; + + @Getter + private Game game; + + @Getter + private HashMap highlightedNpcList = new HashMap(); + + @Getter + private List highlightedRepairList = new ArrayList(); + + @Getter + private Tile noviceGangplankTile; + + @Getter + private Tile intermediateGangplankTile; + + @Getter + private Tile veteranGangplankTile; + + @Getter + private Integer commendationPoints; + + private String userConfigKey; + + private boolean checkForPointWidgets; + + private boolean pointsRewarded = false; + + private PointsInfoboxCounter pointsInfoboxCounter; + + + @Provides + PestControlConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(PestControlConfig.class); + } @Override protected void startUp() throws Exception { - overlayManager.add(overlay); + loadPlugin(); } @Override protected void shutDown() throws Exception { - overlayManager.remove(overlay); - spinners.clear(); + unloadPlugin(); + } + + @Subscribe + public void onConfigChanged(ConfigChanged configEvent) + { + if (configEvent.getGroup().equals("pestcontrol")) + { + unloadPlugin(); + loadPlugin(); + } + } + + private boolean loadLocalUserPoints() + { + if (userConfigKey != null) + { + String configKey = "points." + userConfigKey; + String pointString = configManager.getConfiguration("pestcontrol", configKey); + if (pointString != null) + { + commendationPoints = Integer.parseInt(pointString); + + return true; + } + } + + return false; + } + + private void loadPlugin() + { + if (loadLocalUserPoints()) + { + handlePointsInfoboxCounter(); + } + + overlayManager.add(widgetOverlay); + + if (config.highlightSpinners() != NpcHighlightStyle.OFF) + { + for (Integer npcId : PestControlNpc.getSpinnerIdSet()) + { + highlightedNpcList.put(npcId, new NpcHighlightContext( + config.highlightSpinners(), + config.spinnerColor(), + true + )); + } + } + + if (config.highlightBrawlers() != NpcHighlightStyle.OFF) + { + for (Integer npcId : PestControlNpc.getBrawlerIdSet()) + { + highlightedNpcList.put(npcId, new NpcHighlightContext( + config.highlightBrawlers(), + config.brawlerColor(), + false + )); + } + } + + if (config.portalHighlight() != HighlightPortalOption.OFF) + { + if (config.portalHighlight() == HighlightPortalOption.ACTIVE || + config.portalHighlight() == HighlightPortalOption.ALL) + { + for (Integer portalNpcId : PestControlNpc.getActivePortalIdSet()) + { + highlightedNpcList.put(portalNpcId, new NpcHighlightContext( + NpcHighlightStyle.HULL, + config.activePortalColor(), + false + )); + } + } + + if (config.portalHighlight() == HighlightPortalOption.SHIELDED || + config.portalHighlight() == HighlightPortalOption.ALL) + { + for (Integer portalNpcId : PestControlNpc.getShieldedPortalIdSet()) + { + highlightedNpcList.put(portalNpcId, new NpcHighlightContext( + NpcHighlightStyle.HULL, + config.shieldedPortalColor(), + false + )); + } + } + } + + if (!highlightedNpcList.isEmpty()) + { + overlayManager.add(npcHighlightOverlay); + } + + if (config.highlightRepairables()) + { + overlayManager.add(repairOverlay); + } + + if (config.showHintArrow()) + { + overlayManager.add(hintArrowOverlay); + + if (game != null && client.hasHintArrow()) + { + client.clearHintArrow(); + } + } + + if (config.highlightGangplanks()) + { + overlayManager.add(gangplankOverlay); + } + + if (config.showTimeTillNextPortal()) + { + overlayManager.add(timerOverlay); + } + + if (config.showPortalWeakness()) + { + overlayManager.add(portalWeaknessOverlay); + } + } + + private void unloadPlugin() + { + overlayManager.remove(widgetOverlay); + overlayManager.remove(npcHighlightOverlay); + overlayManager.remove(repairOverlay); + overlayManager.remove(gangplankOverlay); + overlayManager.remove(hintArrowOverlay); + overlayManager.remove(timerOverlay); + overlayManager.remove(portalWeaknessOverlay); + + infoBoxManager.removeInfoBox(pointsInfoboxCounter); + pointsInfoboxCounter = null; + + highlightedNpcList.clear(); + + if (game != null && config.showHintArrow() && client.hasHintArrow()) + { + client.clearHintArrow(); + } } @Subscribe public void onGameStateChanged(GameStateChanged event) { - GameState gameState = event.getGameState(); - if (gameState == GameState.CONNECTION_LOST || gameState == GameState.LOGIN_SCREEN || gameState == GameState.HOPPING) + // LOGGED_IN also triggers when teleporting to the island + if (event.getGameState() == GameState.LOGGED_IN) { - spinners.clear(); + handlePointsInfoboxCounter(); } } + public void handlePointsInfoboxCounter() + { + if (!config.showPoints()) + { + return; + } + + if (!isOnPestControlMainIsland() && !isInPestControlInstance()) + { + infoBoxManager.removeInfoBox(pointsInfoboxCounter); + pointsInfoboxCounter = null; + + return; + } + + if (commendationPoints == null) + { + if (pointsInfoboxCounter != null) + { + infoBoxManager.removeInfoBox(pointsInfoboxCounter); + pointsInfoboxCounter = null; + } + + return; + } + + if (pointsInfoboxCounter != null) + { + pointsInfoboxCounter.setCount(commendationPoints); + } + else + { + BufferedImage image = itemManager.getImage(ItemID.VOID_SEAL1); + pointsInfoboxCounter = new PointsInfoboxCounter(image, this, commendationPoints); + pointsInfoboxCounter.setTooltip("Void Knight Commendation Points"); + infoBoxManager.addInfoBox(pointsInfoboxCounter); + } + } + + + public void getPointsFromWidgets() + { + + // Get points from dialog after the game + Widget npcDialog = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT); + if (npcDialog != null) + { + String npcText = Text.sanitizeMultilineText(npcDialog.getText()); + Matcher matcher = AWARDED_PATTERN.matcher(npcText); + + if (matcher.find()) + { + int newPoints = Integer.parseInt(matcher.group(1)); + + if (commendationPoints != null) + { + newPoints += commendationPoints; + } + + setCommendationPoints(newPoints); + log.debug("PEST CONTROL [POINTS REWARDED] UPDATE: {}", commendationPoints); + return; + } + } + + // Get points from dialog after purchase + Widget pestControlDialog = client.getWidget(WidgetInfo.PEST_CONTROL_DIALOG_TEXT); + if (pestControlDialog != null) + { + String pestControlDialogText = Text.sanitizeMultilineText(pestControlDialog.getText()); + Matcher matcher = PURCHASE_PATTERN.matcher(pestControlDialogText); + + if (matcher.find()) + { + setCommendationPoints(Integer.parseInt(matcher.group(1))); + log.debug("PEST CONTROL [DIALOG] POINTS UPDATE: {}", commendationPoints); + return; + } + } + + // Get points from exchange window + Widget exchangeWindowPointsWidget = client.getWidget(WidgetInfo.PEST_CONTROL_EXCHANGE_WINDOW_POINTS); + if (exchangeWindowPointsWidget != null) + { + String pointsString = exchangeWindowPointsWidget.getText(); + + Matcher matcher = EXCHANGE_WINDOW_POINTS_PATTERN.matcher(pointsString); + if (matcher.lookingAt()) + { + setCommendationPoints(Integer.parseInt(matcher.group(1))); + log.debug("PEST CONTROL [EXCHANGE WINDOW] POINTS UPDATE: {}", commendationPoints); + return; + } + } + + // Get points in boat + // NOTE: The boat info widget is still active right after the game + // We should therefor only check for point updates if there are no dialogs + Widget boatPointsWidget = client.getWidget(WidgetInfo.PEST_CONTROL_BOAT_INFO_POINTS); + if (boatPointsWidget != null && npcDialog == null && pestControlDialog == null) + { + String pointsString = boatPointsWidget.getText(); + Matcher matcher = BOAT_POINTS_PATTERN.matcher(pointsString); + + if (matcher.lookingAt()) + { + log.debug(matcher.toString()); + log.debug("MATCHER GROUP 1: {}", matcher.group(1)); + setCommendationPoints(Integer.parseInt(matcher.group(1))); + log.debug("PEST CONTROL [BOAT] POINTS UPDATE: {}", commendationPoints); + } + } + } + + public void setCommendationPoints(int newPoints) + { + if (userConfigKey == null) + { + return; + } + + if (commendationPoints == null || commendationPoints != newPoints) + { + commendationPoints = newPoints; + + configManager.setConfiguration( + "pestcontrol", + "points." + userConfigKey, + String.valueOf(commendationPoints) + ); + } + + handlePointsInfoboxCounter(); + } + + @Subscribe + public void onGameTick(GameTick gameTickEvent) + { + // Check for widgets on main island + if (game == null && isOnPestControlMainIsland()) + { + // This must be synchronized for some reason + synchronized (this) + { + if (checkForPointWidgets) + { + checkForPointWidgets = false; + getPointsFromWidgets(); + } + } + } + + // Load the points of the user + if (userConfigKey == null) + { + String username = client.getUsername(); + + if (username == null) + { + return; + } + + userConfigKey = String.valueOf(username.hashCode()); + + log.debug("USER CONFIG SCOPE: {}", userConfigKey); + + if (loadLocalUserPoints()) + { + handlePointsInfoboxCounter(); + } + } + + // Check if the game has started + if (game == null && isInPestControlInstance()) + { + log.debug("Pest control game has started"); + game = new Game(client, this); + pointsRewarded = false; + } + + // Check if we are in a game + if (game == null) + { + return; + } + + // Check if we left the game + if (!isInPestControlInstance()) + { + if (game != null) + { + log.debug("Pest control game has ended"); + game = null; + } + + return; + } + + game.onGameTick(gameTickEvent); + } + @Subscribe public void onChatMessage(ChatMessage chatMessage) { - if (overlay.getGame() != null && chatMessage.getType() == ChatMessageType.GAMEMESSAGE) + if (game != null && chatMessage.getType() == ChatMessageType.GAMEMESSAGE) { - Matcher matcher = SHIELD_DROP.matcher(chatMessage.getMessage()); + Matcher matcher = SHIELD_DROP_PATTERN.matcher(chatMessage.getMessage()); if (matcher.lookingAt()) { - overlay.getGame().fall(matcher.group(1)); + game.lowerPortalShield(matcher.group(1)); } } } @Subscribe - public void onNpcSpawned(NpcSpawned event) + public void onWidgetLoaded(WidgetLoaded event) { - final NPC npc = event.getNpc(); - if (SPINNER_IDS.contains(npc.getId())) + if (game != null) { - spinners.add(npc); + log.debug(event.toString()); + } + + if (isOnPestControlMainIsland() && game == null) + { + checkForPointWidgets = true; + } + } + + private void unlistTileObject(TileObject tileObject) + { + int tileObjectId = tileObject.getId(); + + if (PestControlRepairObject.isRepairableBarricadeId(tileObjectId) || + PestControlRepairObject.isRepairableGateId(tileObjectId)) + { + highlightedRepairList.remove(tileObject); + return; + } + + switch (tileObjectId) + { + case NOVICE_GANGPLANK: + { + noviceGangplankTile = null; + break; + } + case INTERMEDIATE_GANGPLANK: + { + intermediateGangplankTile = null; + break; + } + case VETERAN_GANGPLANK: + { + veteranGangplankTile = null; + break; + } + } + } + + private void handleTileObject(Tile tile, TileObject tileObject) + { + int tileObjectId = tileObject.getId(); + + if (PestControlRepairObject.isRepairableBarricadeId(tileObjectId) || + PestControlRepairObject.isRepairableGateId(tileObjectId)) + { + highlightedRepairList.add(tileObject); + return; + } + + switch (tileObjectId) + { + case NOVICE_GANGPLANK: + { + noviceGangplankTile = tile; + break; + } + case INTERMEDIATE_GANGPLANK: + { + intermediateGangplankTile = tile; + break; + } + case VETERAN_GANGPLANK: + { + veteranGangplankTile = tile; + break; + } } } @Subscribe - public void onNpcDespawned(NpcDespawned event) + public void onGameObjectSpawned(GameObjectSpawned event) { - spinners.remove(event.getNpc()); + handleTileObject(event.getTile(), event.getGameObject()); + } + + @Subscribe + public void onGameObjectChanged(GameObjectChanged event) + { + unlistTileObject(event.getPrevious()); + handleTileObject(event.getTile(), event.getGameObject()); + } + + @Subscribe + public void onGameObjectDespawned(GameObjectDespawned event) + { + unlistTileObject(event.getGameObject()); + } + + @Subscribe + public void onGroundObjectSpawned(GroundObjectSpawned event) + { + handleTileObject(event.getTile(), event.getGroundObject()); + } + + @Subscribe + public void onGroundObjectChanged(GroundObjectChanged event) + { + unlistTileObject(event.getPrevious()); + handleTileObject(event.getTile(), event.getGroundObject()); + } + + @Subscribe + public void onGroundObjectDespawned(GroundObjectDespawned event) + { + unlistTileObject(event.getGroundObject()); + } + + public boolean isInPestControlInstance() + { + return client.getWidget(WidgetInfo.PEST_CONTROL_BLUE_SHIELD) != null; + } + + public boolean isOnPestControlMainIsland() + { + return client.getLocalPlayer().getWorldLocation().getRegionID() == 10537; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlRepairObject.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlRepairObject.java new file mode 100644 index 0000000000..f3a8d457dd --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlRepairObject.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import com.google.common.collect.ImmutableSet; +import java.util.Set; +import lombok.Getter; +import net.runelite.api.ObjectID; + +@Getter +public class PestControlRepairObject +{ + @Getter + private static final Set repairableBarricades = ImmutableSet.of( + //ObjectID.BARRICADE_14224, + ObjectID.BARRICADE_14227, + ObjectID.BARRICADE_14228, + ObjectID.BARRICADE_14229, + ObjectID.BARRICADE_14230, + ObjectID.BARRICADE_14231, + ObjectID.BARRICADE_14232 + ); + + @Getter + private static final Set repairableGates = ImmutableSet.of( + ObjectID.GATE_14238, + ObjectID.GATE_14239, + ObjectID.GATE_14240, + ObjectID.GATE_14241, + ObjectID.GATE_14242, + ObjectID.GATE_14243, + ObjectID.GATE_14244, + ObjectID.GATE_14245, + ObjectID.GATE_14246, + ObjectID.GATE_14247, + ObjectID.GATE_14248 + ); + + public static boolean isRepairableBarricadeId(int objectId) + { + return repairableBarricades.contains(objectId); + } + + public static boolean isRepairableGateId(int objectId) + { + return repairableGates.contains(objectId); + } + + public static boolean isRepairableId(int objectId) + { + return isRepairableBarricadeId(objectId) || isRepairableGateId(objectId); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PointsInfoboxCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PointsInfoboxCounter.java new file mode 100644 index 0000000000..1fa3155625 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PointsInfoboxCounter.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import java.awt.image.BufferedImage; +import net.runelite.client.ui.overlay.infobox.Counter; + +public class PointsInfoboxCounter extends Counter +{ + private final PestControlPlugin plugin; + + PointsInfoboxCounter(BufferedImage image, PestControlPlugin plugin, int count) + { + super(image, plugin, count); + this.plugin = plugin; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Portal.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Portal.java index 2807ff9fcb..2ad85a24ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Portal.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Portal.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, Adam + * Copyright (c) 2019, Yani * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,22 +24,39 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package net.runelite.client.plugins.pestcontrol; -import lombok.AllArgsConstructor; + import lombok.Getter; -import lombok.ToString; -import net.runelite.api.widgets.WidgetInfo; +import lombok.Setter; +import net.runelite.api.coords.WorldPoint; -@AllArgsConstructor @Getter -@ToString -enum Portal +@Setter +class Portal { - PURPLE(WidgetInfo.PEST_CONTROL_PURPLE_SHIELD, WidgetInfo.PEST_CONTROL_PURPLE_HEALTH, WidgetInfo.PEST_CONTROL_PURPLE_ICON), - BLUE(WidgetInfo.PEST_CONTROL_BLUE_SHIELD, WidgetInfo.PEST_CONTROL_BLUE_HEALTH, WidgetInfo.PEST_CONTROL_BLUE_ICON), - YELLOW(WidgetInfo.PEST_CONTROL_YELLOW_SHIELD, WidgetInfo.PEST_CONTROL_YELLOW_HEALTH, WidgetInfo.PEST_CONTROL_YELLOW_ICON), - RED(WidgetInfo.PEST_CONTROL_RED_SHIELD, WidgetInfo.PEST_CONTROL_RED_HEALTH, WidgetInfo.PEST_CONTROL_RED_ICON); + private PortalColor color; + private WidgetPortal widget; + private WorldPoint location; - private final WidgetInfo shield; - private final WidgetInfo hitpoints; - private final WidgetInfo icon; + private PortalState portalState = PortalState.SHIELDED; + + public Portal(PortalColor color, WidgetPortal widget) + { + this.color = color; + this.widget = widget; + } + + public boolean isShielded() + { + return portalState == PortalState.SHIELDED; + } + + public boolean isDead() + { + return portalState == PortalState.DEAD; + } + + public boolean isActive() + { + return (!isShielded() && !isDead()); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalContext.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalColor.java similarity index 84% rename from runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalContext.java rename to runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalColor.java index 6ad91ea6e3..07e7336c0b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalContext.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalColor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Adam + * Copyright (c) 2019, Yani * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,15 +25,12 @@ package net.runelite.client.plugins.pestcontrol; import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; -@RequiredArgsConstructor @Getter -@Setter -class PortalContext +public enum PortalColor { - private final Portal portal; - private boolean isShielded = true; - private boolean isDead; + BLUE, + PURPLE, + YELLOW, + RED } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Rotation.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalRotation.java similarity index 72% rename from runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Rotation.java rename to runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalRotation.java index e761edf383..b49d536bb8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/Rotation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalRotation.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, Adam + * Copyright (c) 2019, Yani * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,12 +25,12 @@ */ package net.runelite.client.plugins.pestcontrol; -import static net.runelite.client.plugins.pestcontrol.Portal.BLUE; -import static net.runelite.client.plugins.pestcontrol.Portal.PURPLE; -import static net.runelite.client.plugins.pestcontrol.Portal.RED; -import static net.runelite.client.plugins.pestcontrol.Portal.YELLOW; +import static net.runelite.client.plugins.pestcontrol.PortalColor.BLUE; +import static net.runelite.client.plugins.pestcontrol.PortalColor.PURPLE; +import static net.runelite.client.plugins.pestcontrol.PortalColor.RED; +import static net.runelite.client.plugins.pestcontrol.PortalColor.YELLOW; -enum Rotation +enum PortalRotation { PBYR(PURPLE, BLUE, YELLOW, RED), PYBR(PURPLE, YELLOW, BLUE, RED), @@ -38,23 +39,23 @@ enum Rotation YRPB(YELLOW, RED, PURPLE, BLUE), YPRB(YELLOW, PURPLE, RED, BLUE); - private final Portal[] portals; + private final PortalColor[] portals; - Rotation(Portal first, Portal second, Portal third, Portal fourth) + PortalRotation(PortalColor first, PortalColor second, PortalColor third, PortalColor fourth) { - portals = new Portal[] - { - first, second, third, fourth - }; + portals = new PortalColor[] + { + first, second, third, fourth + }; } - public Portal getPortal(int index) + public Portal getPortal(Game game, int index) { if (index < 0 || index >= portals.length) { return null; } - return portals[index]; + return game.getPortal(portals[index]); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalState.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalState.java new file mode 100644 index 0000000000..0a569d54b3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalState.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +public enum PortalState +{ + ACTIVE, + SHIELDED, + DEAD +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalWeaknessOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalWeaknessOverlay.java new file mode 100644 index 0000000000..ff0deee9c2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PortalWeaknessOverlay.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import com.google.inject.Inject; +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.ItemID; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.Skill; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SkillIconManager; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayUtil; + +@Slf4j +public class PortalWeaknessOverlay extends Overlay +{ + private int zOffset = 100; + + private final PestControlConfig config; + private final PestControlPlugin plugin; + private final Client client; + + private BufferedImage magicImage; + private BufferedImage rangedImage; + private BufferedImage stabImage; + private BufferedImage slashImage; + private BufferedImage crushImage; + + @Inject + PortalWeaknessOverlay( + PestControlConfig config, + PestControlPlugin plugin, + Client client, + ItemManager itemManager, + SkillIconManager skillIconManager + ) + { + this.config = config; + this.plugin = plugin; + this.client = client; + + this.magicImage = skillIconManager.getSkillImage(Skill.MAGIC); + this.rangedImage = skillIconManager.getSkillImage(Skill.RANGED); + + this.stabImage = itemManager.getImage(ItemID.WHITE_DAGGER); + this.slashImage = itemManager.getImage(ItemID.WHITE_SCIMITAR); + this.crushImage = itemManager.getImage(ItemID.WHITE_WARHAMMER); + + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.UNDER_WIDGETS); + } + + private Point getPortalPoint(Portal portal) + { + WorldPoint portalLocation = portal.getLocation(); + LocalPoint localLocation = LocalPoint.fromWorld(client, portalLocation); + + if (localLocation == null) + { + return null; + } + + // We can use any image here as it's only needed to calculate the position + Point imageLocation = Perspective.getCanvasImageLocation(client, localLocation, magicImage, zOffset); + + if (imageLocation != null) + { + return imageLocation; + } + + return null; + } + + private void renderPortalWeakness(Graphics2D graphics, Portal portal, BufferedImage image) + { + Point portalPoint = getPortalPoint(portal); + + if (portalPoint != null) + { + Composite originalComposite = graphics.getComposite(); + Composite translucentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); + graphics.setComposite(translucentComposite); + + OverlayUtil.renderImageLocation(graphics, portalPoint, image); + + graphics.setComposite(originalComposite); + } + } + + private void renderDoublePortalWeakness( + Graphics2D graphics, + Portal portal, + BufferedImage imageLeft, + BufferedImage imageRight + ) + { + Point portalPoint = getPortalPoint(portal); + + if (portalPoint != null) + { + Point portalLeft = new Point( + portalPoint.getX() - (imageLeft.getWidth() / 2) - 5, + portalPoint.getY() + ); + + Point portalRight = new Point( + portalPoint.getX() + (imageRight.getWidth() / 2) + 5, + portalPoint.getY() + ); + + Composite originalComposite = graphics.getComposite(); + Composite translucentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f); + graphics.setComposite(translucentComposite); + + OverlayUtil.renderImageLocation(graphics, portalLeft, imageLeft); + OverlayUtil.renderImageLocation(graphics, portalPoint, imageRight); + + graphics.setComposite(originalComposite); + } + } + + @Override + public Dimension render(Graphics2D graphics) + { + Game game = plugin.getGame(); + + if (game == null) + { + return null; + } + + for (Portal portal : game.getPortals()) + { + if (!portal.isDead()) + { + switch (portal.getColor()) + { + case BLUE: + { + renderPortalWeakness(graphics, portal, magicImage); + break; + } + case YELLOW: + { + renderDoublePortalWeakness(graphics, portal, stabImage, slashImage); + break; + } + case RED: + { + renderPortalWeakness(graphics, portal, crushImage); + break; + } + case PURPLE: + { + renderPortalWeakness(graphics, portal, rangedImage); + break; + } + } + } + } + + return null; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/RepairOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/RepairOverlay.java new file mode 100644 index 0000000000..a0ee3bf09f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/RepairOverlay.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import com.google.inject.Inject; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.geom.Area; +import net.runelite.api.Client; +import net.runelite.api.Constants; +import net.runelite.api.GameObject; +import net.runelite.api.GroundObject; +import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.api.Scene; +import net.runelite.api.Tile; +import net.runelite.api.WallObject; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; + +public class RepairOverlay extends Overlay +{ + private final PestControlConfig config; + private final PestControlPlugin plugin; + private final Client client; + + private static final int MAX_DISTANCE = 2400; + + @Inject + RepairOverlay(PestControlConfig config, PestControlPlugin plugin, Client client) + { + this.config = config; + this.plugin = plugin; + this.client = client; + + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (plugin.getGame() == null) + { + return null; + } + + Point mousePosition = client.getMouseCanvasPosition(); + Scene scene = client.getScene(); + Color color = config.repairableColor(); + Tile[][][] tiles = scene.getTiles(); + int z = client.getPlane(); + + for (int x = 0; x < Constants.SCENE_SIZE; ++x) + { + for (int y = 0; y < Constants.SCENE_SIZE; ++y) + { + Tile tile = tiles[z][x][y]; + + if (tile == null) + { + continue; + } + + Player player = client.getLocalPlayer(); + if (player == null) + { + continue; + } + + // Render GameObjects + GameObject[] gameObjects = tile.getGameObjects(); + if (gameObjects != null) + { + for (GameObject gameObject : gameObjects) + { + if (gameObject == null) + { + continue; + } + + if (PestControlRepairObject.isRepairableId(gameObject.getId())) + { + + if (player.getLocalLocation().distanceTo(gameObject.getLocalLocation()) <= MAX_DISTANCE) + { + renderObjectOverlay(graphics, gameObject.getClickbox(), color, mousePosition); + } + } + } + } + + // Render GameObject + GroundObject groundObject = tile.getGroundObject(); + if (groundObject != null) + { + if (groundObject == null) + { + continue; + } + + if (PestControlRepairObject.isRepairableId(groundObject.getId())) + { + + if (player.getLocalLocation().distanceTo(groundObject.getLocalLocation()) <= MAX_DISTANCE) + { + renderObjectOverlay(graphics, groundObject.getClickbox(), color, mousePosition); + } + } + } + + // Render WallObject + WallObject wallObject = tile.getWallObject(); + if (wallObject != null) + { + if (wallObject == null) + { + continue; + } + + if (PestControlRepairObject.isRepairableId(wallObject.getId())) + { + + if (player.getLocalLocation().distanceTo(wallObject.getLocalLocation()) <= MAX_DISTANCE) + { + renderObjectOverlay(graphics, wallObject.getClickbox(), color, mousePosition); + } + } + } + } + } + + + + + + + + /*if(plugin.getGame() == null) + { + return null; + } + + Point mousePosition = client.getMouseCanvasPosition(); + + List repairList = plugin.getHighlightedRepairList(); + + for(TileObject tileObject: repairList) + { + //tileObject.getWorldLocation().distanceTo(client.getLocalPlayer().getWorldLocation()); + + Polygon polygon = tileObject.getCanvasTilePoly(); + + if(polygon != null) + { + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2)); + graphics.drawPolygon(polygon); + graphics.setColor(setColorAlpha(color, 40)); + graphics.fill(polygon); + + if(polygon.contains(mousePosition.getX(), mousePosition.getY())) + { + graphics.setColor(setColorAlpha(color, 65)); + graphics.fill(polygon); + } + } + } +*/ + return null; + } + + private void renderObjectOverlay(Graphics2D graphics, Area area, Color color, Point mousePosition) + { + if (area == null) + { + return; + } + + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2)); + graphics.draw(area); + graphics.setColor(setColorAlpha(color, 50)); + graphics.fill(area); + + if (area.contains(mousePosition.getX(), mousePosition.getY())) + { + graphics.setColor(setColorAlpha(color, 60)); + graphics.fill(area); + } + } + + private Color setColorAlpha(Color color, int alpha) + { + return new Color( + color.getRed(), + color.getGreen(), + color.getBlue(), + alpha + ); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/TimerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/TimerOverlay.java new file mode 100644 index 0000000000..be45fc728e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/TimerOverlay.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol; + +import com.google.inject.Inject; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.time.Duration; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayUtil; + +public class TimerOverlay extends Overlay +{ + private final PestControlConfig config; + private final PestControlPlugin plugin; + private final Client client; + + @Inject + TimerOverlay(PestControlConfig config, PestControlPlugin plugin, Client client) + { + this.config = config; + this.plugin = plugin; + this.client = client; + + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (plugin.getGame() == null) + { + return null; + } + + Widget timeWidget = client.getWidget(WidgetInfo.PEST_CONTROL_INFO_TIME); + + if (timeWidget == null) + { + return null; + } + + int x = timeWidget.getCanvasLocation().getX() + 38; + int y = timeWidget.getCanvasLocation().getY() + 11; + + Duration timeTillNextPortal = plugin.getGame().getTimeTillNextPortal(); + + if (timeTillNextPortal != null) + { + String firstOrNext = (plugin.getGame().getShieldsDropped() == 0) ? "first" : "next"; + String string = String.format("- %s portal: %ds", firstOrNext, timeTillNextPortal.getSeconds()); + + OverlayUtil.renderTextLocation(graphics, new Point(x, y), string, new Color(204, 204, 204)); + } + + return null; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/WidgetOverlay.java similarity index 62% rename from runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlOverlay.java rename to runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/WidgetOverlay.java index d8126c966e..4633128d6d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/WidgetOverlay.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2017, Kronos * Copyright (c) 2017, Adam + * Copyright (c) 2019, Yani * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,151 +32,107 @@ import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import javax.inject.Inject; -import lombok.AccessLevel; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import net.runelite.api.NPC; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; -import static net.runelite.client.plugins.pestcontrol.Portal.BLUE; -import static net.runelite.client.plugins.pestcontrol.Portal.PURPLE; -import static net.runelite.client.plugins.pestcontrol.Portal.RED; -import static net.runelite.client.plugins.pestcontrol.Portal.YELLOW; import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayUtil; @Slf4j -public class PestControlOverlay extends Overlay +public class WidgetOverlay extends Overlay { - private final PestControlPlugin plugin; private final Client client; - // Pest control game - @Getter(AccessLevel.PACKAGE) - private Game game; + private final PestControlPlugin plugin; @Inject - public PestControlOverlay(PestControlPlugin plugin, Client client) + public WidgetOverlay(Client client, PestControlPlugin plugin) { - setPosition(OverlayPosition.DYNAMIC); this.plugin = plugin; this.client = client; + + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + public Integer getPortalHitpoints(PortalColor color) + { + if (plugin.getGame() == null) + { + return null; + } + + WidgetInfo healthWidgetInfo = null; + + switch (color) + { + case RED: + { + healthWidgetInfo = WidgetPortal.RED.getHitpoints(); + break; + } + case BLUE: + { + healthWidgetInfo = WidgetPortal.BLUE.getHitpoints(); + break; + } + case PURPLE: + { + healthWidgetInfo = WidgetPortal.PURPLE.getHitpoints(); + break; + } + case YELLOW: + { + healthWidgetInfo = WidgetPortal.YELLOW.getHitpoints(); + break; + } + } + + if (healthWidgetInfo == null) + { + return null; + } + + Widget healthWidget = client.getWidget(healthWidgetInfo); + + if (healthWidget == null) + { + return null; + } + + return Integer.parseInt(healthWidget.getText().trim()); } @Override public Dimension render(Graphics2D graphics) { - // See if we are in a game or not - if (client.getWidget(WidgetInfo.PEST_CONTROL_BLUE_SHIELD) == null) + if (plugin.getGame() == null) { - if (game != null) - { - log.debug("Pest control game has ended"); - game = null; - } - return null; } - if (game == null) - { - log.debug("Pest control game has started"); - game = new Game(); - } - - renderSpinners(graphics); - renderPortalWidgets(graphics); - - return null; - } - - private void renderSpinners(Graphics2D graphics) - { - for (NPC npc : plugin.getSpinners()) - { - OverlayUtil.renderActorOverlay(graphics, npc, npc.getName(), Color.CYAN); - } - } - - private void renderPortalWidgets(Graphics2D graphics) - { - PortalContext purple = game.getPurple(); - PortalContext blue = game.getBlue(); - PortalContext yellow = game.getYellow(); - PortalContext red = game.getRed(); - - Widget purpleHealth = client.getWidget(PURPLE.getHitpoints()); - Widget blueHealth = client.getWidget(BLUE.getHitpoints()); - Widget yellowHealth = client.getWidget(YELLOW.getHitpoints()); - Widget redHealth = client.getWidget(RED.getHitpoints()); - - // Check for dead portals - if (isZero(purpleHealth)) - { - game.die(purple); - } - if (isZero(blueHealth)) - { - game.die(blue); - } - if (isZero(yellowHealth)) - { - game.die(yellow); - } - if (isZero(redHealth)) - { - game.die(red); - } - - // display "ATK" overlay on recorded portals without shields - renderAttack(graphics, purple); - renderAttack(graphics, blue); - renderAttack(graphics, yellow); - renderAttack(graphics, red); - - // display "NEXT" overlay on predicted portals - for (Portal portal : game.getNextPortals()) + for (Portal portal : plugin.getGame().getNextPortals()) { renderWidgetOverlay(graphics, portal, "NEXT", Color.ORANGE); } - renderProgressWidget(graphics); - } - - private void renderProgressWidget(Graphics2D graphics) - { - Widget bar = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_BAR).getChild(0); - Rectangle2D bounds = bar.getBounds().getBounds2D(); - - Widget prgs = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_PROGRESS).getChild(0); - int perc = (int) ((prgs.getBounds().getWidth() / bounds.getWidth()) * 100); - - Color color = Color.GREEN; - if (perc < 25) + for (Portal portal : plugin.getGame().getActivePortals()) { - color = Color.RED; + renderWidgetOverlay(graphics, portal, "ATT", Color.RED); } - String text = String.valueOf(perc) + "%"; + renderProgressWidget(graphics); - FontMetrics fm = graphics.getFontMetrics(); - Rectangle2D textBounds = fm.getStringBounds(text, graphics); - int x = (int) (bounds.getX() - textBounds.getWidth()); - int y = (int) (bounds.getY() + fm.getHeight() - 2); - - graphics.setColor(Color.BLACK); - graphics.drawString(text, x + 1, y + 1); - graphics.setColor(color); - graphics.drawString(text, x, y); + return null; } private void renderWidgetOverlay(Graphics2D graphics, Portal portal, String text, Color color) { - Widget shield = client.getWidget(portal.getShield()); - Widget icon = client.getWidget(portal.getIcon()); - Widget hp = client.getWidget(portal.getHitpoints()); + Widget shield = client.getWidget(portal.getWidget().getShield()); + Widget icon = client.getWidget(portal.getWidget().getIcon()); + Widget hp = client.getWidget(portal.getWidget().getHitpoints()); Widget bar = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_BAR).getChild(0); @@ -199,6 +156,45 @@ public class PestControlOverlay extends Overlay graphics.drawString(text, x, y + 4); } + private void renderProgressWidget(Graphics2D graphics) + { + String text; + int percentage; + + Widget bar = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_BAR).getChild(0); + Rectangle2D bounds = bar.getBounds().getBounds2D(); + + Widget prgs = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_PROGRESS).getChild(0); + + // At 0% the inner widget changes and your progress will not increase anymore + if ((int) (prgs.getBounds().getX()) - bounds.getX() != 2) + { + percentage = 0; + text = "FAILED"; + } + else + { + percentage = (int) ((prgs.getBounds().getWidth() / bounds.getWidth()) * 100); + text = String.valueOf(percentage) + "%"; + } + + Color color = Color.GREEN; + if (percentage < 25) + { + color = Color.RED; + } + + FontMetrics fm = graphics.getFontMetrics(); + Rectangle2D textBounds = fm.getStringBounds(text, graphics); + int x = (int) (bounds.getX() - textBounds.getWidth() - 4); + int y = (int) (bounds.getY() + fm.getHeight() - 2); + + graphics.setColor(Color.BLACK); + graphics.drawString(text, x + 1, y + 1); + graphics.setColor(color); + graphics.drawString(text, x, y); + } + private static Rectangle2D union(Rectangle2D src1, Rectangle2D src2) { double x1 = Math.min(src1.getMinX(), src2.getMinX()); @@ -211,19 +207,4 @@ public class PestControlOverlay extends Overlay return result; } - - private void renderAttack(Graphics2D graphics, PortalContext portal) - { - if (portal.isShielded() || portal.isDead()) - { - return; - } - - renderWidgetOverlay(graphics, portal.getPortal(), "ATK", Color.RED); - } - - private static boolean isZero(Widget widget) - { - return widget.getText().trim().equals("0"); - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/WidgetPortal.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/WidgetPortal.java new file mode 100644 index 0000000000..7570cfb87f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/WidgetPortal.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017, Adam + * 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.pestcontrol; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; +import net.runelite.api.widgets.WidgetInfo; + +@AllArgsConstructor +@Getter +@ToString +enum WidgetPortal +{ + PURPLE(WidgetInfo.PEST_CONTROL_PURPLE_SHIELD, WidgetInfo.PEST_CONTROL_PURPLE_HEALTH, WidgetInfo.PEST_CONTROL_PURPLE_ICON), + BLUE(WidgetInfo.PEST_CONTROL_BLUE_SHIELD, WidgetInfo.PEST_CONTROL_BLUE_HEALTH, WidgetInfo.PEST_CONTROL_BLUE_ICON), + YELLOW(WidgetInfo.PEST_CONTROL_YELLOW_SHIELD, WidgetInfo.PEST_CONTROL_YELLOW_HEALTH, WidgetInfo.PEST_CONTROL_YELLOW_ICON), + RED(WidgetInfo.PEST_CONTROL_RED_SHIELD, WidgetInfo.PEST_CONTROL_RED_HEALTH, WidgetInfo.PEST_CONTROL_RED_ICON); + + private final WidgetInfo shield; + private final WidgetInfo hitpoints; + private final WidgetInfo icon; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/config/HighlightPortalOption.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/config/HighlightPortalOption.java new file mode 100644 index 0000000000..8e169edde9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/config/HighlightPortalOption.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol.config; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum HighlightPortalOption +{ + OFF("Off"), + ACTIVE("Active"), + SHIELDED("Shielded"), + ALL("All"); + + private final String option; + + @Override + public String toString() + { + return option; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/config/NpcHighlightStyle.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/config/NpcHighlightStyle.java new file mode 100644 index 0000000000..af60c7b789 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/config/NpcHighlightStyle.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, Yani + * 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.pestcontrol.config; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum NpcHighlightStyle +{ + OFF("Off"), + TILE("Tile"), + HULL("Hull"), + BOTH("Hull + Tile"); + + private final String style; + + @Override + public String toString() + { + return style; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index d2b39880ec..4e1689eaee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -59,6 +59,9 @@ import net.runelite.api.Varbits; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.VarbitChanged; +import net.runelite.api.events.WidgetHiddenChanged; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; @@ -126,6 +129,9 @@ public class RaidsPlugin extends Plugin @Inject private RaidsOverlay overlay; + @Inject + private RaidsPointsOverlay pointsOverlay; + @Inject private LayoutSolver layoutSolver; @@ -177,6 +183,7 @@ public class RaidsPlugin extends Plugin protected void startUp() throws Exception { overlayManager.add(overlay); + overlayManager.add(pointsOverlay); updateLists(); clientThread.invokeLater(() -> checkRaidPresence(true)); } @@ -185,10 +192,17 @@ public class RaidsPlugin extends Plugin protected void shutDown() throws Exception { overlayManager.remove(overlay); + overlayManager.remove(pointsOverlay); infoBoxManager.removeInfoBox(timer); inRaidChambers = false; raid = null; timer = null; + + final Widget widget = client.getWidget(WidgetInfo.RAIDS_POINTS_INFOBOX); + if (widget != null) + { + widget.setHidden(false); + } } @Subscribe @@ -209,6 +223,22 @@ public class RaidsPlugin extends Plugin clientThread.invokeLater(() -> checkRaidPresence(true)); } + @Subscribe + public void onWidgetHiddenChanged(WidgetHiddenChanged event) + { + if (!inRaidChambers || event.isHidden()) + { + return; + } + + Widget widget = event.getWidget(); + + if (widget == client.getWidget(WidgetInfo.RAIDS_POINTS_INFOBOX)) + { + widget.setHidden(true); + } + } + @Subscribe public void onVarbitChanged(VarbitChanged event) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPointsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPointsOverlay.java new file mode 100644 index 0000000000..3c2cc3e5f1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPointsOverlay.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2018, Kamiel + * 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.raids; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.text.NumberFormat; +import java.util.Locale; +import javax.inject.Inject; +import net.runelite.api.Client; +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import net.runelite.api.Varbits; +import static net.runelite.client.plugins.raids.RaidsPlugin.POINTS_FORMAT; +import net.runelite.client.ui.overlay.Overlay; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; +import net.runelite.client.ui.overlay.OverlayMenuEntry; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +public class RaidsPointsOverlay extends Overlay +{ + @Inject + private Client client; + + @Inject + private RaidsPlugin plugin; + + private final PanelComponent panel = new PanelComponent(); + + private static final NumberFormat UNIQUE_FORMAT = NumberFormat.getPercentInstance(Locale.ENGLISH); + static + { + UNIQUE_FORMAT.setMaximumFractionDigits(2); + UNIQUE_FORMAT.setMinimumFractionDigits(2); + } + + @Inject + private RaidsPointsOverlay(RaidsPlugin plugin) + { + super(plugin); + setPosition(OverlayPosition.TOP_RIGHT); + setPriority(OverlayPriority.HIGH); + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Raids overlay")); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!plugin.isInRaidChambers()) + { + return null; + } + + int totalPoints = client.getVar(Varbits.TOTAL_POINTS); + int personalPoints = client.getVar(Varbits.PERSONAL_POINTS); + int partySize = client.getVar(Varbits.RAID_PARTY_SIZE); + double uniqueChance = totalPoints / 867500f; + + panel.getChildren().clear(); + panel.getChildren().add(LineComponent.builder() + .left("Total:") + .right(POINTS_FORMAT.format(totalPoints)) + .build()); + + panel.getChildren().add(LineComponent.builder() + .left(client.getLocalPlayer().getName() + ":") + .right(POINTS_FORMAT.format(personalPoints)) + .build()); + + + if (partySize > 1) + { + panel.getChildren().add(LineComponent.builder() + .left("Party size:") + .right(String.valueOf(partySize)) + .build()); + } + + panel.getChildren().add(LineComponent.builder() + .left("Unique:") + .right(UNIQUE_FORMAT.format(uniqueChance)) + .build()); + + if (partySize > 1) + { + double personalChance = uniqueChance * (personalPoints / totalPoints); + + panel.getChildren().add(LineComponent.builder() + .left("Personal:") + .right(UNIQUE_FORMAT.format(personalChance)) + .build()); + } + + return panel.render(graphics); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/back_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/back_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..96b9200f60ed5303ee3bd6c247e8811a250b83fd GIT binary patch literal 15109 zcmeI3PmB{)9LEPS3MClgpJ-NuNdZA&I{!L5ov|%}7ThHk*JY7K6T|DwYdfKxDKoRQ zyBEl+2M!oS5)Dz|U`$NZ;6)E48WRpCs3-qKH1XoWL=sK(LO9@?nf{r5ZC^G4t}h6ALapu&{r|SU75EW^!jfk!|ZJKm+=KZ8z$+r?+#-Fs_ci2g7`l z4X5}=bIDynLUy(^#TFbFvPx>4GlX%KRkf6;sA^i>!AgRt@Pf?C0w>9OTF}!H+j%AP z3G^-NniYMzxVMuIS-E7*_nSJ;w_2@KOHMg%l@~Ql;{}PABo58sym{LPZO-;KMM1i8 ziqJD$tLa;g%?5En*_rcm$z+hI_v);x(d;F%y$(A>k#B=0FQx>3n3HMre42A^J-js2 z;9(s$pzV9ePaNvktU12p)tnJ2d-BM{XirL|UhbjS+h`0;?fH9-BLp3!Lp{Bj`6lG2 zq36uG2HbNTEoIZN)%#YZzd1`H1Vmdi5OqO_1&L;2 zF-neURpy7skmPub*i1YI>K_yMU|CV(b7OH#L$5e)1NeEX0jiL1+SM%IAB@fHRh3?F z>W+&p3+Cl4KWsSW6;_%)X?s4f4LDiMqk)uVnR-R7ND5R%&Xi?^(}eUmSFR{!4yxk- zmZ zRG5}~iDJP95= z5wr(H6qbzkFRSO-akB=ub9o4&_%Zj zV?xI<+N#)XS=fWoD7xuG_nUn0hI61jd#Bi){L)|1os5dbqDe3yWRv0|^TAY#3j;zn zDK0V}Or^LmAY_x`BJ;siiVFimHYqMLA55jVFd$@;;v)0GREi4&LN+NbG9OH(xG*4O zlj0)t!BmP1141?_E;1iXrMNI4WRv0|^TAY#3j;znDK0V}Or^LmAY_x`BJ;siiVFim zHYqMLA55jVFd$@;;v)0GREi4&LN+NbG9OH(xG*4Olj0)t!BmP1141?_E;1iXrMNI4 zWRv0|^TAY#3j;znDK0V}Or^LmAY_x`BJ;siiVFimHi@_r{YN;Vjh@?Vp$9aNZ9itB zhdWtgV!FgI3tJfGT`cp*{LT+9 zzj)&2!mZbTc>L${n?HZ|xm7psP8|7r>(qT;pZ@5=zO6r9SpDgDAKv)YF*h>%UR}As Uefie+!Go%kd-fMU-hE{8Uz>eky#N3J literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/panel_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/panel_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..833bbc37c49fad091460fec4ec434189daecdd83 GIT binary patch literal 1095 zcmV-N1i1T&P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1KdeOK~zXfwN*=t zTtyWA>T&z_V|pf|%qogOLBSs(S-5xQFrY31#)TRO4UW@FqFa%WRTlA$Om+$`TqQ_A zVL%boKj1<`rgfa@$4uY8&nmyFZhI2CZ}&#O=2Exop8D!Lr_MQr{{vz?mg2^TEgQ!N zNU{|D$YA@@7Yo-cH2C@U`!-NLq!#%7P7j@49p_&DVD36O9?N0-FvZ^xri-HBgQM|> zax5e*Lo0!*Y8BT%`ef$% zQqniK-?G9c&?;sKGAI=w8l*@Qs?UL#LH_jf&t|SK^+hZCEUSFhAoN32b{d6w07f(r zCj#*>9a~PLoKz}=I)LD*Ybl}llI01KBtcqa7!ISc7SQcO|sifQ1*a@Kl>>z}IVyxHKH|8>z zlD1kcn`KOV5;+v6@T2=5@Brtb{Pd|Z2u>CoV|+NIl9M=>VJ2y-#l)9XW`{hO0j(k! z8Ioqh_ zR2Ad#Cr%?u`>dV>gJa;Yb{}c1k)#q?W-u6LxUuui6vx!Wk3U_uCcjJ93)c6LWocOR z3Gz%Ki3?x*X>O6G8S=b=3$J`RpY-;(E&Irsl#}~hl(K&oNKDR@5?+~WBxz#Uu~K@X z5XCjVKa7p_tM~CtVtVt|8#WC0(E0NY>bi-Q+9@nAHSyr`GES{jvC^!dxiorKS87w&zt7ObA*!`U z@!a#*CtP0X&0FtStuj9`BIH4EzXBDe65F4tLW(M@sX`0MlC_MnVMZ`-b&BJoyLkQ8 zrza`qNh_g*X6{K*L2g(*?%rU`Mg*?@71eUil0@p!ccrPA+iGVU^N6O4H=x z2JfMeE>oSKX60~i*GFC6f{$e-xlP@MDo_Y&0c~AQTka9#%9R(rT2K1a*)3trGMjH5 zMh5<;>Z5u*pgu@*67+Qch){Pogn+KVlx^Y zTr+WTcl{+!Bzm0++Is=Ew!WH3xmT0N?(Vx*h+}R*PuzuP9evI&#R6apOn9EXeuSfb zhF%xA@Y>f?98(kb;)mU9HqW{|;hb5(bfWoQyF+yuUOInm?%Mwtz(1Z6y6xxefcpRd N002ovPDHLkV1oIE2VnpJ literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/plus_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/suppliestracker/plus_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9634216e10404080082e5c9bd5143163c461840d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!pogc6V~B-+vIOgt=Klc~H990&04ej3~ChmDm}2}#i<#Y(m-;pXy?VYF0Y38l*%eJ zfk-5xFnT0i0trtb5|$nTLDYAkFijXtlYmB|3IDlNcL5v%umn~^K&t^T4g|r0RQG|E z004ri(=G-6t3Y6NMz{t-QwymcsKx?d5Cj5-LY7jir_ZR*0VocJH?-UV*Ks?fu{xBn zDK5PLVYIWNiAe96Hn#F($7^co>XDW$H(6u4)@aOmL*Zr8mnhq+p`On&~|RE6+n zOh*i5dMf?4V$@SEI#=&m-dfmYb74zTz@5Gg*%21KK3$nu82y%Ji#Hdw(X&y(Kow-f z7qf8PPo6uqU+dhUldHR()q^hvk7EdA~TFV6rv3AOx_XjtbyQr6Lh9LwdsDUl=g+c&2b zN3&|CKUChl)Vy99*ZBqy+w(rY6?xBN!wV;$iZjqjXROT|i`Ud|4G8HRW|c({c@S>9jt`2B3k$3^H6K1v=K>k*yx3gDOMc~?wv83q%yE*DSXDW; zDPe-Z0f9h%u5GbevM8pIUE!~pqfJ+9>#rgWH&jSTtn>9VlYFzIrI%UyY@rnvl5mW? zFp?(tW-+oj*Lm&_PU%tfOBD#9#v)mkrA4@H#6Pp@>W0M&+Du5Jj5*8*) zqDYE|pSI6DDhhgqa%^660+dwjZapCJu*xfaK}kll7dK90l0-+Scty?`syO7f(zO3u zJujR2-5q!ZePmVYyO1i0`HWfYs2{d0qINjFbA^GTcI>?lvny0rFofUL-gq!2f`ewe?aaPizx9Z@ zz}G+Qj^o}dbLKST=Q-;?xp&wFhzw%KgeyNVV^*ku0g>rqMgw7wM!V=&kupz1?7Bd* S5Y4VzOkG=eR!iMf)!^?)JNLc- literal 0 HcmV?d00001 diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/MaxHitCalculatorTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/MaxHitCalculatorTest.java new file mode 100644 index 0000000000..8c28256b89 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/MaxHitCalculatorTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.calculators; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import net.runelite.api.Client; +import net.runelite.client.plugins.maxhit.calculators.testconfig.MagicMaxHitConfig; +import net.runelite.client.plugins.maxhit.calculators.testconfig.MaxHitConfig; +import net.runelite.client.plugins.maxhit.calculators.testconfig.MeleeMaxHitConfig; +import net.runelite.client.plugins.maxhit.calculators.testconfig.RangeMaxHitConfig; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class MaxHitCalculatorTest +{ + @Mock + @Bind + protected Client client; + + @Before + public void setUp() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void calculate() + { + testMaxHitConfig(MeleeMaxHitConfig.values()); + testMaxHitConfig(RangeMaxHitConfig.values()); + testMaxHitConfig(MagicMaxHitConfig.values()); + } + + private void testMaxHitConfig(MaxHitConfig[] maxHitConfigs) + { + for (MaxHitConfig maxHitConfig : maxHitConfigs) + { + maxHitConfig.test(client); + } + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MagicMaxHitConfig.java b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MagicMaxHitConfig.java new file mode 100644 index 0000000000..452aa484fc --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MagicMaxHitConfig.java @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.calculators.testconfig; + +import net.runelite.api.*; +import net.runelite.client.plugins.maxhit.calculators.MagicMaxHitCalculator; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public enum MagicMaxHitConfig implements MaxHitConfig +{ + + TRIDENT_SLAYER(new int[] {75, 83, 99}, 0, new Item[] + { + mockItem(ItemID.SLAYER_HELMET_I), + mockItem(ItemID.SARADOMIN_CAPE), + mockItem(ItemID.OCCULT_NECKLACE), + mockItem(ItemID.TRIDENT_OF_THE_SEAS), + mockItem(ItemID.MYSTIC_ROBE_TOP), + mockItem(ItemID.BROODOO_SHIELD), + null, + mockItem(ItemID.MYSTIC_ROBE_BOTTOM), + null, + mockItem(ItemID.MYSTIC_GLOVES), + mockItem(ItemID.WIZARD_BOOTS), + mockItem(ItemID.RING_OF_WEALTH) + }, new int[] {25, 27, 34}), + + TRIDENT_OF_SEAS(new int[] {75, 83, 99}, 0, new Item[] + { + mockItem(ItemID.MYSTIC_HAT), + mockItem(ItemID.SARADOMIN_CAPE), + mockItem(ItemID.AMULET_OF_GLORY), + mockItem(ItemID.TRIDENT_OF_THE_SEAS), + mockItem(ItemID.MYSTIC_ROBE_TOP), + mockItem(ItemID.BROODOO_SHIELD), + null, + mockItem(ItemID.MYSTIC_ROBE_BOTTOM), + null, + mockItem(ItemID.MYSTIC_GLOVES), + mockItem(ItemID.WIZARD_BOOTS), + mockItem(ItemID.RING_OF_WEALTH) + }, new int[] {20, 22, 28}), + + TRIDENT_OF_SWAMP(new int[] {75, 83, 99}, 0, new Item[] + { + mockItem(ItemID.MYSTIC_HAT), + mockItem(ItemID.SARADOMIN_CAPE), + mockItem(ItemID.AMULET_OF_GLORY), + mockItem(ItemID.TRIDENT_OF_THE_SWAMP), + mockItem(ItemID.MYSTIC_ROBE_TOP), + mockItem(ItemID.BROODOO_SHIELD), + null, + mockItem(ItemID.MYSTIC_ROBE_BOTTOM), + null, + mockItem(ItemID.MYSTIC_GLOVES), + mockItem(ItemID.WIZARD_BOOTS), + mockItem(ItemID.RING_OF_WEALTH) + }, new int[] {23, 25, 31}), + + MAGIC_DART(new int[] {75, 83, 99}, 18, new Item[] + { + mockItem(ItemID.MYSTIC_HAT), + mockItem(ItemID.SARADOMIN_CAPE), + mockItem(ItemID.AMULET_OF_GLORY), + mockItem(ItemID.SLAYERS_STAFF), + mockItem(ItemID.MYSTIC_ROBE_TOP), + mockItem(ItemID.BROODOO_SHIELD), + null, + mockItem(ItemID.MYSTIC_ROBE_BOTTOM), + null, + mockItem(ItemID.MYSTIC_GLOVES), + mockItem(ItemID.WIZARD_BOOTS), + mockItem(ItemID.RING_OF_WEALTH) + }, new int[] {17, 18, 19}), + + + FIRE_BOLT(75, 8, new Item[] + { + mockItem(ItemID.SLAYER_HELMET_I), + mockItem(ItemID.IMBUED_SARADOMIN_CAPE), + mockItem(ItemID.OCCULT_NECKLACE), + mockItem(ItemID.STAFF_OF_THE_DEAD), + mockItem(ItemID.MYSTIC_ROBE_TOP), + mockItem(ItemID.TOME_OF_FIRE), + null, + mockItem(ItemID.MYSTIC_ROBE_BOTTOM), + null, + mockItem(ItemID.CHAOS_GAUNTLETS), + mockItem(ItemID.WIZARD_BOOTS), + mockItem(ItemID.RING_OF_WEALTH) + }, 31), + + + WIND_BLAST(75, 9, new Item[] + { + mockItem(ItemID.MYSTIC_HAT), + mockItem(ItemID.SARADOMIN_CAPE), + mockItem(ItemID.AMULET_OF_GLORY), + mockItem(ItemID.STAFF_OF_AIR), + mockItem(ItemID.MYSTIC_ROBE_TOP), + mockItem(ItemID.BROODOO_SHIELD), + null, + mockItem(ItemID.MYSTIC_ROBE_BOTTOM), + null, + mockItem(ItemID.MYSTIC_GLOVES), + mockItem(ItemID.WIZARD_BOOTS), + mockItem(ItemID.RING_OF_WEALTH) + }, 13), + + + EARTH_WAVE(75, 15, new Item[] + { + mockItem(ItemID.MYSTIC_HAT), + mockItem(ItemID.SARADOMIN_CAPE), + mockItem(ItemID.OCCULT_NECKLACE), + mockItem(ItemID.STAFF_OF_EARTH), + mockItem(ItemID.MYSTIC_ROBE_TOP), + mockItem(ItemID.TOME_OF_FIRE), + null, + mockItem(ItemID.MYSTIC_ROBE_BOTTOM), + null, + mockItem(ItemID.MYSTIC_GLOVES), + mockItem(ItemID.WIZARD_BOOTS), + mockItem(ItemID.RING_OF_WEALTH) + }, 20), + + FLAMES_OF_ZAMORAK(75, 20, new Item[] + { + mockItem(ItemID.MYSTIC_HAT), + mockItem(ItemID.SARADOMIN_CAPE), + mockItem(ItemID.AMULET_OF_GLORY), + mockItem(ItemID.STAFF_OF_THE_DEAD), + mockItem(ItemID.MYSTIC_ROBE_TOP), + mockItem(ItemID.BROODOO_SHIELD), + null, + mockItem(ItemID.MYSTIC_ROBE_BOTTOM), + null, + mockItem(ItemID.MYSTIC_GLOVES), + mockItem(ItemID.WIZARD_BOOTS), + mockItem(ItemID.RING_OF_WEALTH) + }, 23), + + SARADOMIN_STRIKE(75, 52, new Item[] + { + mockItem(ItemID.MYSTIC_HAT), + mockItem(ItemID.SARADOMIN_CAPE), + mockItem(ItemID.AMULET_OF_GLORY), + mockItem(ItemID.STAFF_OF_LIGHT), + mockItem(ItemID.MYSTIC_ROBE_TOP), + mockItem(ItemID.BROODOO_SHIELD), + null, + mockItem(ItemID.MYSTIC_ROBE_BOTTOM), + null, + mockItem(ItemID.MYSTIC_GLOVES), + mockItem(ItemID.WIZARD_BOOTS), + mockItem(ItemID.RING_OF_WEALTH) + }, 23), + + + ; + + + private final int[] magicLevels; + private final int spellId; + private final Item[] equipedItems; + private final int[] expectedMaxHits; + + MagicMaxHitConfig(int magicLevel, int spellId, Item[] equipedItems, int expectedMaxHit) + { + this.magicLevels = new int[] {magicLevel}; + this.spellId = spellId; + this.equipedItems = equipedItems; + this.expectedMaxHits = new int[] {expectedMaxHit}; + } + + MagicMaxHitConfig(int[] magicLevels, int spellId, Item[] equipedItems, int[] expectedMaxHits) + { + this.magicLevels = magicLevels; + this.spellId = spellId; + this.equipedItems = equipedItems; + this.expectedMaxHits = expectedMaxHits; + } + + + private static Item mockItem(int itemId) + { + Item item = mock(Item.class); + when(item.getId()).thenReturn(itemId); + return item; + } + + public void test(Client client) + { + int[] magicLevels = this.magicLevels; + for (int i = 0, magicLevelsLength = magicLevels.length; i < magicLevelsLength; i++) + { + int magicLevel = magicLevels[i]; + int expectedMaxHit = this.expectedMaxHits[i]; + + // Mock equipment container + ItemContainer equipmentContainer = mock(ItemContainer.class); + when(equipmentContainer.getItems()) + .thenReturn(this.equipedItems); + when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipmentContainer); + + // Mock Varbits + when(client.getBoostedSkillLevel(Skill.MAGIC)).thenReturn(magicLevel); + when(client.getVar(Varbits.AUTO_CAST_SPELL)).thenReturn(this.spellId); + + // Test + MagicMaxHitCalculator maxHitCalculator = new MagicMaxHitCalculator(client, this.equipedItems); + assertEquals(this.toString(), expectedMaxHit, maxHitCalculator.getMaxHit(), 0); + + } + + } + +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MaxHitConfig.java b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MaxHitConfig.java new file mode 100644 index 0000000000..309abe1727 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MaxHitConfig.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.calculators.testconfig; + +import net.runelite.api.Client; + +public interface MaxHitConfig +{ + void test(Client client); +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MeleeMaxHitConfig.java b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MeleeMaxHitConfig.java new file mode 100644 index 0000000000..dd03f9487e --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/MeleeMaxHitConfig.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.calculators.testconfig; + +import net.runelite.api.*; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.plugins.maxhit.attackstyle.WeaponType; +import net.runelite.client.plugins.maxhit.calculators.MeleeMaxHitCalculator; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public enum MeleeMaxHitConfig implements MaxHitConfig +{ + + DRAGON_SCIMITAR(new int[] {75, 83, 99}, 66, WeaponType.TYPE_9, 1, new Item[] + { + mockItem(ItemID.IRON_FULL_HELM), + mockItem(ItemID.BLACK_CAPE), + mockItem(ItemID.GOLD_NECKLACE), + mockItem(ItemID.DRAGON_SCIMITAR), + mockItem(ItemID.IRON_PLATEBODY), + mockItem(ItemID.IRON_KITESHIELD), + null, + mockItem(ItemID.IRON_PLATELEGS), + null, + mockItem(ItemID.LEATHER_GLOVES), + mockItem(ItemID.LEATHER_BOOTS), + mockItem(ItemID.GOLD_RING) + }, new int[] {17, 19, 22}), + + DRAGON_SCIMITAR_DEFENDER(new int[] {75, 83, 99}, 76, WeaponType.TYPE_9, 1, new Item[] + { + mockItem(ItemID.IRON_FULL_HELM), + mockItem(ItemID.BLACK_CAPE), + mockItem(ItemID.GOLD_NECKLACE), + mockItem(ItemID.DRAGON_SCIMITAR), + mockItem(ItemID.IRON_PLATEBODY), + mockItem(ItemID.DRAGON_DEFENDER), + null, + mockItem(ItemID.IRON_PLATELEGS), + null, + mockItem(ItemID.LEATHER_GLOVES), + mockItem(ItemID.LEATHER_BOOTS), + mockItem(ItemID.GOLD_RING) + }, new int[] {19, 21, 24}), + + DRAGON_SCIMITAR_COMPLETE(new int[] {75, 83, 99}, 108, WeaponType.TYPE_9, 1, new Item[] + { + mockItem(ItemID.SLAYER_HELMET), + mockItem(ItemID.FIRE_CAPE), + mockItem(ItemID.AMULET_OF_FURY), + mockItem(ItemID.DRAGON_SCIMITAR), + mockItem(ItemID.FIGHTER_TORSO), + mockItem(ItemID.DRAGON_DEFENDER), + null, + mockItem(ItemID.IRON_PLATELEGS), + null, + mockItem(ItemID.BARROWS_GLOVES), + mockItem(ItemID.DRAGON_BOOTS), + mockItem(ItemID.BERSERKER_RING) + }, new int[] {26, 29, 35}), + + OBSIDIAN_SET(new int[] {75, 83, 99}, 61, WeaponType.TYPE_17, 2, new Item[] + { + mockItem(ItemID.OBSIDIAN_HELMET), + mockItem(ItemID.OBSIDIAN_CAPE), + mockItem(ItemID.GOLD_NECKLACE), + mockItem(ItemID.TOKTZXILAK), + mockItem(ItemID.OBSIDIAN_PLATEBODY), + mockItem(ItemID.TOKTZKETXIL), + null, + mockItem(ItemID.OBSIDIAN_PLATELEGS), + null, + mockItem(ItemID.LEATHER_GLOVES), + mockItem(ItemID.LEATHER_BOOTS), + mockItem(ItemID.GOLD_RING) + }, new int[] {18, 19, 23}), + + DHAROK_SET(new int[] {75, 75, 75, 83, 83, 83, 99, 99, 99}, 105, WeaponType.TYPE_1, 1, + new int[][] {{99, 99}, {1, 99}, {32, 75}, {99, 99}, {1, 99}, {32, 75}, {99, 99}, {1, 99}, {32, 75}}, + new Item[] + { + mockItem(ItemID.DHAROKS_HELM_100), + mockItem(ItemID.BLACK_CAPE), + mockItem(ItemID.GOLD_NECKLACE), + mockItem(ItemID.DHAROKS_GREATAXE_100), + mockItem(ItemID.DHAROKS_PLATEBODY_100), + null, + null, + mockItem(ItemID.DHAROKS_PLATELEGS_100), + null, + mockItem(ItemID.LEATHER_GLOVES), + mockItem(ItemID.LEATHER_BOOTS), + mockItem(ItemID.GOLD_RING) + }, new int[] {23, 45, 30, 25, 49, 33, 29, 57, 38}), + + VOID_SET(new int[] {75, 83, 99}, 66, WeaponType.TYPE_9, 1, new Item[] + { + mockItem(ItemID.VOID_MELEE_HELM), + mockItem(ItemID.BLACK_CAPE), + mockItem(ItemID.GOLD_NECKLACE), + mockItem(ItemID.DRAGON_SCIMITAR), + mockItem(ItemID.VOID_KNIGHT_TOP), + mockItem(ItemID.IRON_KITESHIELD), + null, + mockItem(ItemID.VOID_KNIGHT_ROBE), + null, + mockItem(ItemID.VOID_KNIGHT_GLOVES), + mockItem(ItemID.LEATHER_BOOTS), + mockItem(ItemID.GOLD_RING) + }, new int[] {19, 21, 25}), + ; + + + private final int[] strengthLevels; + private final WeaponType weaponType; + private final int attackStyleId; + private final Item[] equipedItems; + private final int[] expectedMaxHits; + private final int[][] hitpoints; + private final int meleeEquipmentStrength; + + MeleeMaxHitConfig(int[] strengthLevels, int meleeEquipmentStrength, WeaponType weaponType, int attackStyleId, int[][] hitpoints, Item[] equipedItems, int[] expectedMaxHits) + { + this.strengthLevels = strengthLevels; + this.meleeEquipmentStrength = meleeEquipmentStrength; + this.weaponType = weaponType; + this.attackStyleId = attackStyleId; + this.hitpoints = hitpoints; + this.equipedItems = equipedItems; + this.expectedMaxHits = expectedMaxHits; + } + + MeleeMaxHitConfig(int[] strengthLevels, int meleeEquipmentStrength, WeaponType weaponType, int attackStyleId, Item[] equipedItems, int[] expectedMaxHits) + { + this.strengthLevels = strengthLevels; + this.hitpoints = new int[strengthLevels.length][2]; + this.meleeEquipmentStrength = meleeEquipmentStrength; + this.weaponType = weaponType; + this.attackStyleId = attackStyleId; + this.equipedItems = equipedItems; + this.expectedMaxHits = expectedMaxHits; + } + + + private static Item mockItem(int itemId) + { + Item item = mock(Item.class); + when(item.getId()).thenReturn(itemId); + return item; + } + + public void test(Client client) + { + int[] strengthLevels = this.strengthLevels; + for (int i = 0, strengthLevelsLength = strengthLevels.length; i < strengthLevelsLength; i++) + { + int strengthLevel = strengthLevels[i]; + int[] hitpoints = this.hitpoints[i]; + int expectedMaxHit = this.expectedMaxHits[i]; + + // Mock equipment container + ItemContainer equipmentContainer = mock(ItemContainer.class); + when(equipmentContainer.getItems()) + .thenReturn(this.equipedItems); + when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipmentContainer); + + // Mock equipment strength + Widget equipmentWidget = mock(Widget.class); + when(client.getWidget(WidgetInfo.EQUIPMENT_MELEE_STRENGTH)).thenReturn(equipmentWidget); + when(equipmentWidget.getText()).thenReturn("Melee strength: " + this.meleeEquipmentStrength); + + // Mock Varbits + when(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE)).thenReturn(this.weaponType.ordinal()); + when(client.getVar(VarPlayer.ATTACK_STYLE)).thenReturn(this.attackStyleId); + + // Mock strength + when(client.getBoostedSkillLevel(Skill.STRENGTH)).thenReturn(strengthLevel); + + // Mock hitpoints + when(client.getBoostedSkillLevel(Skill.HITPOINTS)).thenReturn(hitpoints[0]); + when(client.getRealSkillLevel(Skill.HITPOINTS)).thenReturn(hitpoints[1]); + + // Test + MeleeMaxHitCalculator maxHitCalculator = new MeleeMaxHitCalculator(client, this.equipedItems); + assertEquals(this.toString(), expectedMaxHit, maxHitCalculator.getMaxHit(), 0); + + } + + } + +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/RangeMaxHitConfig.java b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/RangeMaxHitConfig.java new file mode 100644 index 0000000000..31ac795bb5 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/maxhit/calculators/testconfig/RangeMaxHitConfig.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2019, Bartvollebregt + * 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.maxhit.calculators.testconfig; + +import net.runelite.api.*; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.plugins.maxhit.attackstyle.WeaponType; +import net.runelite.client.plugins.maxhit.calculators.RangeMaxHitCalculator; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public enum RangeMaxHitConfig implements MaxHitConfig +{ + + MAGIC_SHORTBOW(new int[] {75, 83, 99}, 49, WeaponType.TYPE_3, 1, new Item[] + { + mockItem(ItemID.IRON_FULL_HELM), + mockItem(ItemID.BLACK_CAPE), + mockItem(ItemID.GOLD_NECKLACE), + mockItem(ItemID.MAGIC_SHORTBOW), + mockItem(ItemID.IRON_PLATEBODY), + null, + null, + mockItem(ItemID.IRON_PLATELEGS), + null, + mockItem(ItemID.LEATHER_GLOVES), + mockItem(ItemID.LEATHER_BOOTS), + mockItem(ItemID.GOLD_RING), + mockItem(ItemID.RUNE_ARROW) + }, new int[] {15, 16, 19}), + + RUNE_CROSSBOW(new int[] {75, 83, 99}, 115, WeaponType.TYPE_5, 0, new Item[] + { + mockItem(ItemID.IRON_FULL_HELM), + mockItem(ItemID.BLACK_CAPE), + mockItem(ItemID.GOLD_NECKLACE), + mockItem(ItemID.RUNE_CROSSBOW), + mockItem(ItemID.IRON_PLATEBODY), + null, + null, + mockItem(ItemID.IRON_PLATELEGS), + null, + mockItem(ItemID.LEATHER_GLOVES), + mockItem(ItemID.LEATHER_BOOTS), + mockItem(ItemID.GOLD_RING), + mockItem(ItemID.RUNITE_BOLTS) + }, new int[] {24, 26, 31}), + + BLOwPIPE(new int[] {75, 83, 99}, 50, WeaponType.TYPE_19, 1, new Item[] + { + mockItem(ItemID.IRON_FULL_HELM), + mockItem(ItemID.BLACK_CAPE), + mockItem(ItemID.GOLD_NECKLACE), + mockItem(ItemID.TOXIC_BLOWPIPE), + mockItem(ItemID.IRON_PLATEBODY), + null, + null, + mockItem(ItemID.IRON_PLATELEGS), + null, + mockItem(ItemID.LEATHER_GLOVES), + mockItem(ItemID.LEATHER_BOOTS), + mockItem(ItemID.GOLD_RING) + }, new int[] {15, 16, 19}), + + VOID_SET(new int[] {75, 83, 99}, 115, WeaponType.TYPE_5, 1, new Item[] + { + mockItem(ItemID.VOID_RANGER_HELM), + mockItem(ItemID.BLACK_CAPE), + mockItem(ItemID.GOLD_NECKLACE), + mockItem(ItemID.RUNE_CROSSBOW), + mockItem(ItemID.VOID_KNIGHT_TOP), + mockItem(ItemID.IRON_KITESHIELD), + null, + mockItem(ItemID.VOID_KNIGHT_ROBE), + null, + mockItem(ItemID.VOID_KNIGHT_GLOVES), + mockItem(ItemID.LEATHER_BOOTS), + mockItem(ItemID.GOLD_RING) + }, new int[] {26, 28, 33}), + + ; + + private final int[] rangeLevels; + private final WeaponType weaponType; + private final int attackStyleId; + private final Item[] equipedItems; + private final int[] expectedMaxHits; + private final int ammoEquipmentStrength; + + RangeMaxHitConfig(int[] rangeLevels, int ammoEquipmentStrength, WeaponType weaponType, int attackStyleId, Item[] equipedItems, int[] expectedMaxHits) + { + this.rangeLevels = rangeLevels; + this.ammoEquipmentStrength = ammoEquipmentStrength; + this.weaponType = weaponType; + this.attackStyleId = attackStyleId; + this.equipedItems = equipedItems; + this.expectedMaxHits = expectedMaxHits; + } + + + private static Item mockItem(int itemId) + { + Item item = mock(Item.class); + when(item.getId()).thenReturn(itemId); + return item; + } + + public void test(Client client) + { + int[] rangeLevels = this.rangeLevels; + for (int i = 0, rangeLevelsLength = rangeLevels.length; i < rangeLevelsLength; i++) + { + int rangeLevel = rangeLevels[i]; + int expectedMaxHit = this.expectedMaxHits[i]; + + // Mock equipment container + ItemContainer equipmentContainer = mock(ItemContainer.class); + when(equipmentContainer.getItems()) + .thenReturn(this.equipedItems); + when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipmentContainer); + + // Mock equipment strength + Widget equipmentWidget = mock(Widget.class); + when(client.getWidget(WidgetInfo.EQUIPMENT_RANGED_STRENGTH)).thenReturn(equipmentWidget); + when(equipmentWidget.getText()).thenReturn("Ranged strength: " + this.ammoEquipmentStrength); + + // Mock Varbits + when(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE)).thenReturn(this.weaponType.ordinal()); + when(client.getVar(VarPlayer.ATTACK_STYLE)).thenReturn(this.attackStyleId); + + // Mock strength + when(client.getBoostedSkillLevel(Skill.RANGED)).thenReturn(rangeLevel); + + // Test + RangeMaxHitCalculator maxHitCalculator = new RangeMaxHitCalculator(client, this.equipedItems); + assertEquals(this.toString(), expectedMaxHit, maxHitCalculator.getMaxHit(), 0); + + } + + } + +} From e74a4af7c05e00e5a56d3d5eea1f28d4b2bca1da Mon Sep 17 00:00:00 2001 From: zeruth Date: Mon, 22 Apr 2019 04:54:50 -0400 Subject: [PATCH 72/75] Fix external plugin color --- .../client/plugins/pluginsorter/PluginSorterConfig.java | 6 +++--- .../client/plugins/pluginsorter/PluginSorterPlugin.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) 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 index 0b910beea5..2477c8070a 100644 --- 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 @@ -36,7 +36,7 @@ public interface PluginSorterConfig extends Config { } @ConfigItem( - position = 1, + position = 2, keyName = "pvmColor", name = "PVM color", description = "Configure the color of PVM related plugins" @@ -47,7 +47,7 @@ public interface PluginSorterConfig extends Config { } @ConfigItem( - position = 2, + position = 3, keyName = "pvpColor", name = "PVP color", description = "Configure the color of PVP related plugins" @@ -58,7 +58,7 @@ public interface PluginSorterConfig extends Config { } @ConfigItem( - position = 3, + position = 4, keyName = "utilityColor", name = "Utility color", description = "Configure the color of utility related plugins" 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 index 99c4e3e02a..ba31160a32 100644 --- 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 @@ -77,7 +77,7 @@ public class PluginSorterPlugin extends Plugin { if (pli.getPlugin()!=null) { if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type()!=null) if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("external")) - pli.nameLabel.setForeground(config.pvmColor()); + pli.nameLabel.setForeground(config.externalColor()); else 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")) From 9a4461f7e9ec9fc3ba58bbba8b9af81c6896d0f5 Mon Sep 17 00:00:00 2001 From: James <38226001+james-munson@users.noreply.github.com> Date: Mon, 22 Apr 2019 12:02:04 -0700 Subject: [PATCH 73/75] Group boost notifications (#47) * Add option to group multiple boost notifications into one * Show names of skills in the grouped notification * Update style of for loop per feedback --- .../client/plugins/boosts/BoostsConfig.java | 11 +++++ .../client/plugins/boosts/BoostsPlugin.java | 41 ++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsConfig.java index e623442da3..cc5344771a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsConfig.java @@ -103,4 +103,15 @@ public interface BoostsConfig extends Config { return 0; } + + @ConfigItem( + keyName = "groupNotifications", + name = "Group Notifications", + description = "Configures whether or not to group notifications for multiple skills into a single notification", + position = 7 + ) + default boolean groupNotifications() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java index 4f09b12a8b..086e2535f3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java @@ -26,8 +26,10 @@ package net.runelite.client.plugins.boosts; import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; @@ -100,6 +102,7 @@ public class BoostsPlugin extends Plugin private int lastChangeUp = -1; private boolean preserveBeenActive = false; private long lastTickMillis; + private List boostedSkillsChanged = new ArrayList<>(); @Provides BoostsConfig provideConfig(ConfigManager configManager) @@ -213,7 +216,14 @@ public class BoostsPlugin extends Plugin int boost = cur - real; if (boost <= boostThreshold && boostThreshold < lastBoost) { - notifier.notify(skill.getName() + " level is getting low!"); + if (config.groupNotifications()) + { + boostedSkillsChanged.add(skill.getName()); + } + else + { + notifier.notify(skill.getName() + " level is getting low!"); + } } } } @@ -223,6 +233,35 @@ public class BoostsPlugin extends Plugin { lastTickMillis = System.currentTimeMillis(); + if (config.groupNotifications() && !boostedSkillsChanged.isEmpty()) + { + if (boostedSkillsChanged.size() == 1) + { + notifier.notify(boostedSkillsChanged.get(0) + " level is getting low!"); + } + else + { + String notification = ""; + for (int i = 0; i < boostedSkillsChanged.size(); i++) + { + if (i == 0) + { + notification = boostedSkillsChanged.get(i); + } + else if (i < boostedSkillsChanged.size() - 1) + { + notification = notification + ", " + boostedSkillsChanged.get(i); + } + else + { + notification = notification + " and " + boostedSkillsChanged.get(i) + " levels are getting low!"; + notifier.notify(notification); + } + } + } + boostedSkillsChanged.clear(); + } + if (getChangeUpTicks() <= 0) { switch (config.displayNextDebuffChange()) From b3a43ac9d77b5448ba809bcea2b5fd4661d66739 Mon Sep 17 00:00:00 2001 From: sdburns1998 <49877861+sdburns1998@users.noreply.github.com> Date: Mon, 22 Apr 2019 21:02:33 +0200 Subject: [PATCH 74/75] Check Matcher#find (#45) Fixes #44 --- .../client/plugins/freezetimers/FreezeTimersPlugin.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 5e0c7a7824..cb97861189 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 @@ -129,9 +129,9 @@ public class FreezeTimersPlugin extends Plugin final Pattern ppattern = Pattern.compile("> (.+?) Date: Mon, 22 Apr 2019 12:02:56 -0700 Subject: [PATCH 75/75] npc aggro timer: Add option to hide hint overlay (#46) --- .../npcunaggroarea/NpcAggroAreaConfig.java | 12 ++++++++++++ .../npcunaggroarea/NpcAggroAreaPlugin.java | 15 +++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaConfig.java index a0e4992e31..311e286b0b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaConfig.java @@ -37,6 +37,7 @@ public interface NpcAggroAreaConfig extends Config String CONFIG_CENTER2 = "center2"; String CONFIG_LOCATION = "location"; String CONFIG_DURATION = "duration"; + String CONFIG_NOT_WORKING_OVERLAY = "overlay"; @ConfigItem( keyName = "npcUnaggroAlwaysActive", @@ -92,4 +93,15 @@ public interface NpcAggroAreaConfig extends Config { return Color.YELLOW; } + + @ConfigItem( + keyName = "npcUnaggroShowNotWorkingOverlay", + name = "Show not working hint", + description = "Show hint if plugin is enabled in unsupported area", + position = 6 + ) + default boolean showNotWorkingOverlay() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java index 79096a5b35..10dd5752f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java @@ -128,6 +128,7 @@ public class NpcAggroAreaPlugin extends Plugin private WorldPoint previousUnknownCenter; private boolean loggingIn; private List npcNamePatterns; + private boolean notWorkingOverlayShown = false; @Provides NpcAggroAreaConfig provideConfig(ConfigManager configManager) @@ -139,7 +140,12 @@ public class NpcAggroAreaPlugin extends Plugin protected void startUp() throws Exception { overlayManager.add(overlay); - overlayManager.add(notWorkingOverlay); + if (config.showNotWorkingOverlay()) + { + overlayManager.add(notWorkingOverlay); + notWorkingOverlayShown = true; + } + npcNamePatterns = NAME_SPLITTER.splitToList(config.npcNamePatterns()); recheckActive(); } @@ -149,7 +155,11 @@ public class NpcAggroAreaPlugin extends Plugin { removeTimer(); overlayManager.remove(overlay); - overlayManager.remove(notWorkingOverlay); + if (notWorkingOverlayShown) + { + overlayManager.remove(notWorkingOverlay); + } + Arrays.fill(safeCenters, null); lastPlayerLocation = null; currentTimer = null; @@ -406,6 +416,7 @@ public class NpcAggroAreaPlugin extends Plugin configManager.unsetConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER2); configManager.unsetConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_LOCATION); configManager.unsetConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_DURATION); + configManager.unsetConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_NOT_WORKING_OVERLAY); } private void saveConfig()