From a0df460eac4ded7d9e22e0ee3f5fc37fcecf1eb6 Mon Sep 17 00:00:00 2001 From: sethtroll Date: Tue, 18 Jul 2017 16:29:32 -0500 Subject: [PATCH] Add binding necklace to runecraft plugin -Since all charges are same ID, it will display a "?" until your current necklace breaks/or you right click check it --- .../plugins/runecraft/BindNeckOverlay.java | 137 ++++++++++++++++++ .../client/plugins/runecraft/Runecraft.java | 62 +++++++- .../plugins/runecraft/RunecraftConfig.java | 57 ++++++++ .../plugins/runecraft/RunecraftOverlay.java | 22 ++- 4 files changed, 271 insertions(+), 7 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/runecraft/BindNeckOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftConfig.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/BindNeckOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/BindNeckOverlay.java new file mode 100644 index 0000000000..59cd26ec42 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/BindNeckOverlay.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2017, 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 HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.runecraft; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.geom.Rectangle2D; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import static net.runelite.api.ItemID.BINDING_NECKLACE; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetItem; +import net.runelite.client.RuneLite; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; + +public class BindNeckOverlay extends Overlay +{ + private final Client client = RuneLite.getClient(); + private final RunecraftConfig config; + int bindingCharges; + + public BindNeckOverlay(Runecraft plugin) + { + super(OverlayPosition.DYNAMIC); + this.config = plugin.getConfig(); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (client.getGameState() != GameState.LOGGED_IN + || !config.showBindNeck() + || client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN) != null) + { + return null; + } + + Widget inventory = client.getWidget(WidgetInfo.INVENTORY); + + if (inventory == null) + { + return null; + } + + if (!inventory.isHidden()) + { + for (WidgetItem item : inventory.getWidgetItems()) + { + if (item.getId() != BINDING_NECKLACE) + { + continue; + } + + if (bindingCharges == 1) + { + renderBindNeck(graphics, item.getCanvasBounds(), bindingCharges, Color.red); + } + else + { + renderBindNeck(graphics, item.getCanvasBounds(), bindingCharges, Color.white); + } + } + } + + Widget equipment = client.getWidget(WidgetInfo.EQUIPMENT); + + if (equipment != null) + { + Widget amuletSlot = client.getWidget(WidgetInfo.EQUIPMENT_AMULET).getChild(1); + + if (!amuletSlot.isHidden() && amuletSlot.getItemId() == BINDING_NECKLACE) + { + Rectangle widgetBounds = amuletSlot.getBounds(); + + //to match inventory text + widgetBounds.x -= 5; + widgetBounds.y -= 1; + + if (bindingCharges == 1) + { + renderBindNeck(graphics, widgetBounds, bindingCharges, Color.red); + } + else + { + renderBindNeck(graphics, widgetBounds, bindingCharges, Color.white); + } + } + } + + return null; + } + + private void renderBindNeck(Graphics2D graphics, Rectangle bounds, int charges, Color color) + { + String text = charges <= 0 ? "?" : charges + ""; + FontMetrics fm = graphics.getFontMetrics(); + Rectangle2D textBounds = fm.getStringBounds(text, graphics); + + int textX = (int) (bounds.getX() + bounds.getWidth() - textBounds.getWidth()); + int textY = (int) (bounds.getY() + (textBounds.getHeight())); + + //text shadow + graphics.setColor(Color.BLACK); + graphics.drawString(text, textX + 1, textY + 1); + + graphics.setColor(color); + graphics.drawString(text, textX, textY); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/Runecraft.java b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/Runecraft.java index b12abcc1e2..0b7393a3f7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/Runecraft.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/Runecraft.java @@ -24,17 +24,29 @@ */ package net.runelite.client.plugins.runecraft; +import com.google.common.eventbus.Subscribe; +import java.util.Arrays; +import java.util.Collection; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import net.runelite.api.ChatMessageType; +import net.runelite.client.RuneLite; +import net.runelite.client.events.ChatMessage; import net.runelite.client.plugins.Plugin; import net.runelite.client.ui.overlay.Overlay; public class Runecraft extends Plugin { - private static final RunecraftOverlay overlay = new RunecraftOverlay(); + public static Pattern bindNeckString = Pattern.compile("You have ([0-9]+) charges left before your Binding necklace disintegrates."); + + private final RunecraftConfig config = RuneLite.getRunelite().getConfigManager().getConfig(RunecraftConfig.class); + private final RunecraftOverlay overlay = new RunecraftOverlay(this); + private final BindNeckOverlay bindNeckOverlay = new BindNeckOverlay(this); @Override - public Overlay getOverlay() + public Collection getOverlays() { - return overlay; + return Arrays.asList(overlay, bindNeckOverlay); } @Override @@ -46,4 +58,46 @@ public class Runecraft extends Plugin protected void shutDown() throws Exception { } -} + + public RunecraftConfig getConfig() + { + return config; + } + + @Subscribe + public void onChatMessage(ChatMessage event) + { + if (event.getType() != ChatMessageType.SERVER) + { + return; + } + + Matcher match = bindNeckString.matcher(event.getMessage()); + if (match.find()) + { + bindNeckOverlay.bindingCharges = Integer.parseInt(match.group(1)); + return; + } + + if (event.getMessage().contains("You bind the temple's power")) + { + if (event.getMessage().contains("mud") + || event.getMessage().contains("lava") + || event.getMessage().contains("steam") + || event.getMessage().contains("dust") + || event.getMessage().contains("smoke") + || event.getMessage().contains("mist")) + { + bindNeckOverlay.bindingCharges -= 1; + return; + } + } + + if (event.getMessage().contains("Your Binding necklace has disintegrated.")) + { + //set it to 17 because this message is triggered first before the above chat event + bindNeckOverlay.bindingCharges = 17; + return; + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftConfig.java new file mode 100644 index 0000000000..2208a41358 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftConfig.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017, 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 HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.runecraft; + +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup( + keyName = "runecraft", + name = "Runecraft", + description = "Configuration for the runecrafting plugin" +) +public interface RunecraftConfig +{ + @ConfigItem( + keyName = "showPouch", + name = "Show Pouch count", + description = "Configures whether the pouch ess count is displayed" + ) + default boolean showPouch() + { + return true; + } + + @ConfigItem( + keyName = "showBindNeck", + name = "Show Binding Neck charges", + description = "Configures whether the binding neck charge is displayed" + ) + default boolean showBindNeck() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftOverlay.java index 34eb3164f5..6171bb76dd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftOverlay.java @@ -24,9 +24,11 @@ */ package net.runelite.client.plugins.runecraft; -import java.awt.*; - +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; import net.runelite.api.Client; +import net.runelite.api.GameState; import net.runelite.api.ItemID; import net.runelite.api.Point; import net.runelite.api.Varbits; @@ -41,14 +43,24 @@ public class RunecraftOverlay extends Overlay { private final Client client = RuneLite.getClient(); - public RunecraftOverlay() + private final RunecraftConfig config; + + public RunecraftOverlay(Runecraft plugin) { super(OverlayPosition.DYNAMIC); + this.config = plugin.getConfig(); } @Override public Dimension render(Graphics2D graphics) { + if (client.getGameState() != GameState.LOGGED_IN + || !config.showPouch() + || client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN) != null) + { + return null; + } + Widget inventoryWidget = client.getWidget(WidgetInfo.INVENTORY); if (inventoryWidget == null || inventoryWidget.isHidden()) @@ -82,6 +94,10 @@ public class RunecraftOverlay extends Overlay if (location != null) { int value = client.getSetting(varbits); + graphics.setColor(Color.black); + graphics.drawString("" + value, location.getX() + 1, location.getY() + graphics.getFontMetrics().getHeight() + 1); + + graphics.setColor(Color.white); graphics.drawString("" + value, location.getX(), location.getY() + graphics.getFontMetrics().getHeight()); } }