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 ad4f9fd57b..dede24adbe 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 @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.cannon; +import java.awt.Color; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -44,4 +45,34 @@ public interface CannonConfig extends Config { return true; } + + @ConfigItem( + keyName = "showOverlay", + name = "Show the cannonballs left overlay", + description = "Configures whether to show the cannonballs in an overlay" + ) + default boolean showAmountOnScreen() + { + return false; + } + + @ConfigItem( + keyName = "showDoubleHitSpot", + name = "Show double hit spots", + description = "Configures whether to show the NPC double hit spot" + ) + default boolean showDoubleHitSpot() + { + return false; + } + + @ConfigItem( + keyName = "highlightDoubleHitColor", + name = "Color of double hit spots", + description = "Configures the highlight color of double hit spots" + ) + default Color highlightDoubleHitColor() + { + return Color.RED; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonOverlay.java index f92c26a698..930c4c7995 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonOverlay.java @@ -24,19 +24,20 @@ */ package net.runelite.client.plugins.cannon; -import static java.awt.Color.GREEN; -import static java.awt.Color.ORANGE; -import static java.awt.Color.RED; +import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Polygon; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.Perspective; +import static net.runelite.api.Perspective.LOCAL_TILE_SIZE; import net.runelite.api.widgets.Widget; 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.ui.overlay.components.TextComponent; class CannonOverlay extends Overlay @@ -59,44 +60,87 @@ class CannonOverlay extends Overlay @Override public Dimension render(Graphics2D graphics, Point parent) { - if (!plugin.cannonPlaced || plugin.myCannon == null) + if (!plugin.isCannonPlaced() || plugin.getCannonPosition() == null) { return null; } - if (!Perspective.isWorldInScene(client, plugin.myCannon)) + if (!Perspective.isWorldInScene(client, plugin.getCannonPosition())) + { + return null; + } + + net.runelite.api.Point cannonPoint = Perspective.worldToLocal(client, plugin.getCannonPosition()); + + if (cannonPoint == null) { return null; } net.runelite.api.Point cannonLoc = Perspective.getCanvasTextLocation(client, graphics, - Perspective.worldToLocal(client, plugin.myCannon), - String.valueOf(plugin.cballsLeft), 200); + cannonPoint, + String.valueOf(plugin.getCballsLeft()), 200); Widget viewport = client.getViewportWidget(); - if (viewport != null && cannonLoc != null && viewport.contains(cannonLoc)) + if (viewport == null) { - textComponent.setText(String.valueOf(plugin.cballsLeft)); + return null; + } + + if (cannonLoc != null && viewport.contains(cannonLoc)) + { + textComponent.setText(String.valueOf(plugin.getCballsLeft())); textComponent.setPosition(new Point(cannonLoc.getX(), cannonLoc.getY())); - - if (plugin.cballsLeft > 15) - { - textComponent.setColor(GREEN);; - } - else if (plugin.cballsLeft > 5) - { - textComponent.setColor(ORANGE); - } - else - { - textComponent.setColor(RED); - } - + textComponent.setColor(plugin.getStateColor()); textComponent.render(graphics, parent); } + if (config.showDoubleHitSpot()) + { + Color color = config.highlightDoubleHitColor(); + drawDoubleHitSpots(graphics, plugin.getCannon().getLocalLocation(), color); + } + return null; } -} + + + /** + * Draw the double hit spots on a 6 by 6 grid around the cannon + * @param startTile The position of the cannon + */ + private void drawDoubleHitSpots(Graphics2D graphics, net.runelite.api.Point startTile, Color color) + { + for (int x = -3; x <= 3; x++) + { + for (int y = -3; y <= 3; y++) + { + if (y != 1 && x != 1 && y != -1 && x != -1) + { + continue; + } + + //Ignore center square + if (y >= -1 && y <= 1 && x >= -1 && x <= 1) + { + continue; + } + + int xPos = startTile.getX() - (x * LOCAL_TILE_SIZE); + int yPos = startTile.getY() - (y * LOCAL_TILE_SIZE); + + net.runelite.api.Point marker = new net.runelite.api.Point(xPos, yPos); + Polygon poly = Perspective.getCanvasTilePoly(client, marker); + + if (poly == null) + { + continue; + } + + OverlayUtil.renderPolygon(graphics, poly, color); + } + } + } +} \ No newline at end of file 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 f6d17459e3..07e187b2bd 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 @@ -26,9 +26,13 @@ package net.runelite.client.plugins.cannon; import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; +import java.awt.Color; +import java.util.Arrays; +import java.util.Collection; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; +import lombok.Getter; import net.runelite.api.AnimationID; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; @@ -53,14 +57,20 @@ import net.runelite.client.ui.overlay.Overlay; ) public class CannonPlugin extends Plugin { - private static final Pattern LOAD_CANNON_PATTERN = Pattern.compile("([0-9]+)"); + private static final Pattern NUMBER_PATTERN = Pattern.compile("([0-9]+)"); private static final int MAX_CBALLS = 30; - int cballsLeft = 0; + @Getter + private int cballsLeft; - boolean cannonPlaced = false; + @Getter + private boolean cannonPlaced; - net.runelite.api.Point myCannon; + @Getter + private net.runelite.api.Point cannonPosition; + + @Getter + private GameObject cannon; @Inject private Notifier notifier; @@ -68,6 +78,9 @@ public class CannonPlugin extends Plugin @Inject private CannonOverlay cannonOverlay; + @Inject + private CannonUiOverlay cannonUiOverlay; + @Inject private CannonConfig config; @@ -81,16 +94,16 @@ public class CannonPlugin extends Plugin } @Override - public Overlay getOverlay() + public Collection getOverlays() { - return cannonOverlay; + return Arrays.asList(cannonOverlay, cannonUiOverlay); } @Override protected void shutDown() throws Exception { cannonPlaced = false; - myCannon = null; + cannonPosition = null; cballsLeft = 0; } @@ -105,7 +118,8 @@ public class CannonPlugin extends Plugin if (localPlayer.getWorldLocation().distanceTo(gameObject.getWorldLocation()) <= 2 && localPlayer.getAnimation() == AnimationID.BURYING_BONES) { - myCannon = gameObject.getWorldLocation(); + cannonPosition = gameObject.getWorldLocation(); + cannon = gameObject; } } } @@ -115,12 +129,12 @@ public class CannonPlugin extends Plugin { Projectile projectile = event.getProjectile(); - if ((projectile.getId() == CANNONBALL || projectile.getId() == GRANITE_CANNONBALL) && myCannon != null) + if ((projectile.getId() == CANNONBALL || projectile.getId() == GRANITE_CANNONBALL) && cannonPosition != null) { net.runelite.api.Point projectileLoc = Perspective.localToWorld(client, new net.runelite.api.Point(projectile.getX1(), projectile.getY1())); //Check to see if projectile x,y is 0 else it will continuously decrease while ball is flying. - if (projectileLoc.equals(myCannon) && projectile.getX() == 0 && projectile.getY() == 0) + if (projectileLoc.equals(cannonPosition) && projectile.getX() == 0 && projectile.getY() == 0) { cballsLeft--; } @@ -149,7 +163,7 @@ public class CannonPlugin extends Plugin if (event.getMessage().startsWith("You load the cannon with")) { - Matcher m = LOAD_CANNON_PATTERN.matcher(event.getMessage()); + Matcher m = NUMBER_PATTERN.matcher(event.getMessage()); if (m.find()) { int amt = Integer.valueOf(m.group()); @@ -180,5 +194,38 @@ public class CannonPlugin extends Plugin notifier.notify("Your cannon is out of ammo!"); } } + + if (event.getMessage().contains("You unload your cannon and receive Cannonball")) + { + Matcher m = NUMBER_PATTERN.matcher(event.getMessage()); + if (m.find()) + { + int unload = Integer.valueOf(m.group()); + + // make sure cballs doesn't go below 0 + if (cballsLeft - unload < 0) + { + cballsLeft = 0; + } + else + { + cballsLeft -= unload; + } + } + } + } + + Color getStateColor() + { + if (cballsLeft > 15) + { + return Color.green; + } + else if (cballsLeft > 5) + { + return Color.orange; + } + + return Color.red; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonUiOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonUiOverlay.java new file mode 100644 index 0000000000..e9eee08368 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonUiOverlay.java @@ -0,0 +1,70 @@ +/* + * 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.cannon; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import javax.inject.Inject; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.PanelComponent; + +class CannonUiOverlay extends Overlay +{ + private static final int COMPONENT_WIDTH = 40; + + private final CannonConfig config; + private final CannonPlugin plugin; + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + CannonUiOverlay(CannonConfig config, CannonPlugin plugin) + { + setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); + this.config = config; + this.plugin = plugin; + } + + @Override + public Dimension render(Graphics2D graphics, Point parent) + { + if (!plugin.isCannonPlaced() || plugin.getCannonPosition() == null) + { + return null; + } + + if (!config.showAmountOnScreen()) + { + return null; + } + + panelComponent.setTitleColor(plugin.getStateColor()); + panelComponent.setTitle(String.valueOf(plugin.getCballsLeft())); + panelComponent.setWidth(COMPONENT_WIDTH); + + return panelComponent.render(graphics, parent); + } +} \ No newline at end of file