diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/DuskAttack.java b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/DuskAttack.java new file mode 100644 index 0000000000..ece52fe62e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/DuskAttack.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018, https://runelitepl.us + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 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 net.runelite.api.Prayer; + +public enum DuskAttack +{ + MELEE(7800, Prayer.PROTECT_FROM_MELEE), + RANGE(7801, Prayer.PROTECT_FROM_MISSILES); + + private final int animation; + private final Prayer prayer; + + DuskAttack(int animation, Prayer prayer) + { + this.animation = animation; + this.prayer = prayer; + } + + public int getAnimation() + { + return animation; + } + + public Prayer getPrayer() + { + return prayer; + } +} 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 index 8f90c59363..0c02d79b92 100644 --- 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 @@ -38,20 +38,23 @@ 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.TextComponent; class GrotesqueGuardiansOverlay extends Overlay { private static final int GROTESQUE_GUARDIANS_REGION_ID = 6727; private final Client client; + private final GrotesqueGuardiansPlugin plugin; 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) + private GrotesqueGuardiansOverlay(Client client, GrotesqueGuardiansPlugin plugin) { this.client = client; + this.plugin = plugin; setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_SCENE); setPriority(OverlayPriority.LOW); @@ -94,6 +97,24 @@ class GrotesqueGuardiansOverlay extends Overlay { OverlayUtil.renderPolygon(graphics, poly, color); } + if ((plugin.isInGargs()) && (plugin.isNeedingToRun())) + { + if ((plugin.getDusk() != null) && (plugin.getDusk().getLocalLocation() != null)) + { + TextComponent textComponent = new TextComponent(); + LocalPoint duskPoint; + + duskPoint = new LocalPoint(plugin.getDusk().getLocalLocation().getX() + 128 * (plugin.getDusk().getTransformedDefinition().getSize() - 1) / 2, plugin.getDusk().getLocalLocation().getY() + 128 * (plugin.getDusk().getTransformedDefinition().getSize() - 1) / 2); + net.runelite.api.Point duskLoc = Perspective.getCanvasTextLocation(client, graphics, duskPoint, "RUN AWAY", 500); + if (duskLoc != null) + { + textComponent.setText("RUN AWAY"); + textComponent.setPosition(new java.awt.Point(duskLoc.getX(), duskLoc.getY())); + textComponent.setColor(Color.red); + textComponent.render(graphics); + } + } + } } 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 index 507f6d75f6..77332e3c93 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 @@ -29,19 +29,45 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.eventbus.Subscribe; +import java.util.ArrayList; +import net.runelite.api.events.GameTick; +import net.runelite.api.NPC; +import javax.annotation.Nullable; +import net.runelite.api.Client; + +import static net.runelite.api.NpcID.DUSK_7888; + @PluginDescriptor( name = "Grotesque Guardians", - description = "Display tile indicators for the Grotesque Guardian special attacks", - tags = {"grotesque", "guardians", "gargoyle", "garg"}, + description = "Show various helpful utitiles during the Grotesque Gaurdians (Gargoyles) fight", + tags = { "bosses", "combat", "gargs", "overlay", "grotesque", "pve", "pvm" }, type = PluginType.PVM, enabledByDefault = false ) public class GrotesqueGuardiansPlugin extends Plugin { + private static final int GARGOYLES_REGION = 6727; + @Inject + private Client client; @Inject private OverlayManager overlayManager; + @Inject + private GrotesqueGuardiansPrayerOverlay prayerOverlay; + @Nullable + private DuskAttack prayAgainst; + @Nullable + private NPC dusk; + private boolean inGargs; + private boolean needingToRun; + + public GrotesqueGuardiansPlugin() + { + inGargs = false; + needingToRun = false; + } @Inject private GrotesqueGuardiansOverlay overlay; @@ -50,11 +76,94 @@ public class GrotesqueGuardiansPlugin extends Plugin protected void startUp() throws Exception { overlayManager.add(overlay); + overlayManager.add(prayerOverlay); + dusk = null; + prayAgainst = null; } @Override protected void shutDown() throws Exception { overlayManager.remove(overlay); + overlayManager.remove(prayerOverlay); + dusk = null; + prayAgainst = null; } + + @Subscribe + public void onGameTick(final GameTick event) + { + final ArrayList regions = new ArrayList(); + for (final int intValue : client.getMapRegions()) + { + regions.add(intValue); + } + if (regions.contains(GARGOYLES_REGION)) + { + dusk = null; + inGargs = true; + for (final NPC npc : client.getNpcs()) + { + if (npc.getName() != null && npc.getName().contains("Dusk") && !npc.isDead()) + { + dusk = npc; + } + } + if (inGargs && dusk != null) + { + if (dusk.getId() == DUSK_7888) + { + if (dusk.getAnimation() == DuskAttack.MELEE.getAnimation()) + { + prayAgainst = DuskAttack.MELEE; + } + else if (dusk.getAnimation() == DuskAttack.RANGE.getAnimation()) + { + prayAgainst = DuskAttack.RANGE; + } + } + else + { + prayAgainst = null; + } + if (dusk.getAnimation() == 7802) + { + needingToRun = true; + } + else + { + needingToRun = false; + } + } + } + else + { + inGargs = false; + prayAgainst = null; + dusk = null; + } + } + + @Nullable + DuskAttack getPrayAgainst() + { + return prayAgainst; + } + + @Nullable + NPC getDusk() + { + return dusk; + } + + boolean isInGargs() + { + return inGargs; + } + + boolean isNeedingToRun() + { + return needingToRun; + } + } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPrayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPrayerOverlay.java new file mode 100644 index 0000000000..c63c0845da --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPrayerOverlay.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018, https://runelitepl.us + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 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.image.BufferedImage; + +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.Perspective; +import net.runelite.api.coords.LocalPoint; +import net.runelite.client.game.SpriteManager; +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.ComponentConstants; +import net.runelite.client.ui.overlay.components.ImageComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +public class GrotesqueGuardiansPrayerOverlay extends Overlay +{ + private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150); + private final Client client; + private final GrotesqueGuardiansPlugin plugin; + private final SpriteManager spriteManager; + private final PanelComponent imagePanelComponent = new PanelComponent(); + + @Inject + private GrotesqueGuardiansPrayerOverlay(Client client, GrotesqueGuardiansPlugin plugin, SpriteManager spriteManager) + { + setLayer(OverlayLayer.ABOVE_SCENE); + setPriority(OverlayPriority.HIGH); + setPosition(OverlayPosition.DYNAMIC); + this.client = client; + this.plugin = plugin; + this.spriteManager = spriteManager; + } + + public Dimension render(Graphics2D graphics) + { + imagePanelComponent.getChildren().clear(); + if ((plugin.isInGargs()) && (plugin.getPrayAgainst() != null) && (plugin.getDusk() != null)) + { + DuskAttack attack = plugin.getPrayAgainst(); + BufferedImage prayerImage = null; + prayerImage = getPrayerImage(attack); + imagePanelComponent.setBackgroundColor(client + .isPrayerActive(attack.getPrayer()) ? ComponentConstants.STANDARD_BACKGROUND_COLOR : NOT_ACTIVATED_BACKGROUND_COLOR); + + NPC dusk = plugin.getDusk(); + imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); + + + LocalPoint duskPoint = new LocalPoint(dusk.getLocalLocation().getX() + 128 * (dusk.getTransformedDefinition().getSize() - 1) / 2, dusk.getLocalLocation().getY() + 128 * (dusk.getTransformedDefinition().getSize() - 1) / 2); + net.runelite.api.Point duskLoc = Perspective.getCanvasImageLocation(client, duskPoint, prayerImage, 400); + if (duskLoc != null) + { + imagePanelComponent.setPreferredLocation(new java.awt.Point(duskLoc.getX(), duskLoc.getY())); + } + return imagePanelComponent.render(graphics); + } + return null; + } + + private BufferedImage getPrayerImage(DuskAttack attack) + { + int prayerSpriteID = attack == DuskAttack.MELEE ? 129 : 128; + + return spriteManager.getSprite(prayerSpriteID, 0); + } +}