From 604e034a9a0e60fa4c72b58dbc83e442a5ebe949 Mon Sep 17 00:00:00 2001 From: OnlyHereToPlayOsrs <37775694+xperiaclash@users.noreply.github.com> Date: Fri, 26 Jul 2019 16:04:43 +0200 Subject: [PATCH] gauntlet: add boss helper (#1141) * Gauntlet Boss Helper * xd --- .../java/net/runelite/api/AnimationID.java | 4 + .../java/net/runelite/api/ProjectileID.java | 3 + .../plugins/gauntlet/GauntletInfoBox.java | 133 +++++++++++ .../plugins/gauntlet/GauntletPlugin.java | 207 ++++++++++++++++++ .../gauntlet/GauntletPluginConfig.java | 42 ++++ .../plugins/gauntlet/protect_from_magic.png | Bin 0 -> 254 bytes .../gauntlet/protect_from_missiles.png | Bin 0 -> 220 bytes 7 files changed, 389 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletInfoBox.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPluginConfig.java create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/gauntlet/protect_from_magic.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/gauntlet/protect_from_missiles.png 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 578ce50408..22c5da122b 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -321,4 +321,8 @@ public final class AnimationID // Combat counter public static final int BARRAGE_ANIMATION = 1979; public static final int CHIN_ANIMATION = 7618; + + // Gauntlet Hunleff + public static final int HUNLEFF_ATTACK = 8419; + public static final int HUNLEFF_TORNADO = 8418; } \ No newline at end of file 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 a9bb550df1..5380223df2 100644 --- a/runelite-api/src/main/java/net/runelite/api/ProjectileID.java +++ b/runelite-api/src/main/java/net/runelite/api/ProjectileID.java @@ -101,4 +101,7 @@ public class ProjectileID public static final int HYDRA_LIGHTNING = 1664; public static final int HYDRA_LIGHTNING_2 = 1665; public static final int DRAKE_BREATH = 1637; + + public static final int HUNLEFF_MAGE_ATTACK = 1707; + public static final int HUNLEFF_RANGE_ATTACK = 1711; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletInfoBox.java new file mode 100644 index 0000000000..5dc00462c7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletInfoBox.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2019, lyzrds + * Copyright (c) 2019, ganom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.gauntlet; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.Prayer; +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.InfoBoxComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +@Singleton +@Slf4j +public class GauntletInfoBox extends Overlay +{ + private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150); + private final Client client; + private final GauntletPlugin plugin; + private final PanelComponent panelComponent = new PanelComponent(); + private final SpriteManager spriteManager; + + @Inject + GauntletInfoBox(final @Nullable Client client, final GauntletPlugin plugin, final SpriteManager spriteManager) + { + this.client = client; + this.plugin = plugin; + this.spriteManager = spriteManager; + setPosition(OverlayPosition.BOTTOM_RIGHT); + setPriority(OverlayPriority.HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + panelComponent.getChildren().clear(); + + if (plugin.getHunllef() == null) + { + return null; + } + + Prayer prayer = plugin.getNextPrayer(); + + if (prayer == null) + { + return null; + } + InfoBoxComponent prayComponent = new InfoBoxComponent(); + BufferedImage prayImg = scaleImg(getPrayerImage(prayer)); + prayComponent.setImage(prayImg); + prayComponent.setColor(Color.WHITE); + prayComponent.setBackgroundColor(client.isPrayerActive(prayer) + ? ComponentConstants.STANDARD_BACKGROUND_COLOR + : NOT_ACTIVATED_BACKGROUND_COLOR); + prayComponent.setPreferredSize(new Dimension(40, 40)); + panelComponent.getChildren().add(prayComponent); + panelComponent.setPreferredSize(new Dimension(40, 40)); + panelComponent.setBorder(new Rectangle(0, 0, 0, 0)); + + return panelComponent.render(graphics); + } + + private BufferedImage getPrayerImage(Prayer prayer) + { + switch (prayer) + { + case PROTECT_FROM_MAGIC: + return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0); + case PROTECT_FROM_MELEE: + return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MELEE, 0); + case PROTECT_FROM_MISSILES: + return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0); + } + return null; + } + + private static BufferedImage scaleImg(final BufferedImage img) + { + if (img == null) + { + return null; + } + final double width = img.getWidth(null); + final double height = img.getHeight(null); + final double size = 36; // Limit size to 2 as that is minimum size not causing breakage + final double scalex = size / width; + final double scaley = size / height; + final double scale = Math.min(scalex, scaley); + final int newWidth = (int) (width * scale); + final int newHeight = (int) (height * scale); + final BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); + final Graphics g = scaledImage.createGraphics(); + g.drawImage(img, 0, 0, newWidth, newHeight, null); + g.dispose(); + return scaledImage; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPlugin.java new file mode 100644 index 0000000000..8a7003b174 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPlugin.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2019, xperiaclash + * Copyright (c) 2019, ganom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.gauntlet; + +import com.google.common.collect.ImmutableSet; +import java.util.Set; +import javax.inject.Inject; +import javax.inject.Singleton; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.AnimationID; +import net.runelite.api.HeadIcon; +import net.runelite.api.NPC; +import net.runelite.api.NPCDefinition; +import net.runelite.api.Prayer; +import net.runelite.api.Projectile; +import net.runelite.api.ProjectileID; +import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.NpcSpawned; +import net.runelite.api.events.ProjectileSpawned; +import net.runelite.client.eventbus.EventBus; +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; + +@PluginDescriptor( + name = "Gauntlet Boss Helper", + description = "Prayer Overlay For The Gauntlet Boss", + tags = {"gauntlet"}, + type = PluginType.PVM, + enabledByDefault = false +) + +@Singleton +@Slf4j +public class GauntletPlugin extends Plugin +{ + + private static final Set HUNLEFF_ATTACKS = ImmutableSet.of(AnimationID.HUNLEFF_ATTACK, AnimationID.HUNLEFF_TORNADO); + @Inject + private EventBus eventBus; + @Inject + private OverlayManager overlayManager; + @Inject + private GauntletInfoBox GauntletInfoBox; + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private int attacks = 0; + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private Prayer nextPrayer; + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private NPC hunllef; + @Getter(AccessLevel.PRIVATE) + @Setter(AccessLevel.PRIVATE) + private boolean firstHitDetected; + + + @Override + protected void startUp() throws Exception + { + addSubscriptions(); + overlayManager.add(GauntletInfoBox); + } + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + overlayManager.remove(GauntletInfoBox); + reset(); + } + + private void addSubscriptions() + { + + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + } + + private void onNpcSpawned(NpcSpawned event) + { + final NPC npc = event.getNpc(); + + if (npc.getName() == null || !npc.getName().toLowerCase().contains("hunllef")) + { + return; + } + + setHunllef(npc); + + eventBus.subscribe(AnimationChanged.class, "gauntlet", this::onAnimationChanged); + eventBus.subscribe(ProjectileSpawned.class, "gauntlet", this::onProjectileSpawned); + } + + private void onNpcDespawned(NpcDespawned event) + { + final NPC npc = event.getNpc(); + + if (npc.getName() == null || !npc.getName().toLowerCase().contains("hunllef")) + { + return; + } + + eventBus.unregister("gauntlet"); + reset(); + } + + private void onProjectileSpawned(ProjectileSpawned event) + { + if (getHunllef() == null || isFirstHitDetected()) + { + return; + } + + final Projectile projectile = event.getProjectile(); + + if (projectile.getId() == ProjectileID.HUNLEFF_MAGE_ATTACK) + { + setNextPrayer(Prayer.PROTECT_FROM_MAGIC); + setFirstHitDetected(true); + } + else if (projectile.getId() == ProjectileID.HUNLEFF_RANGE_ATTACK) + { + setNextPrayer(Prayer.PROTECT_FROM_MISSILES); + setFirstHitDetected(true); + } + } + + private void onAnimationChanged(AnimationChanged event) + { + if (hunllef == null) + { + return; + } + + final int anim = event.getActor().getAnimation(); + + if (!HUNLEFF_ATTACKS.contains(anim)) + { + return; + } + + setAttacks(getAttacks() + 1); + + if (getAttacks() == 4) + { + if (getNextPrayer() == Prayer.PROTECT_FROM_MISSILES) + { + log.debug("Attacks are: {}, switching to prot mage", getAttacks()); + setNextPrayer(Prayer.PROTECT_FROM_MAGIC); + } + else if (getNextPrayer() == Prayer.PROTECT_FROM_MAGIC) + { + log.debug("Attacks are: {}, switching to prot missiles", getAttacks()); + setNextPrayer(Prayer.PROTECT_FROM_MISSILES); + } + setAttacks(0); + } + } + + private void reset() + { + setHunllef(null); + setNextPrayer(null); + setFirstHitDetected(false); + setAttacks(0); + } + + private HeadIcon getOverheadIcon(NPC npc) + { + NPCDefinition composition = npc.getDefinition(); + if (composition != null) + { + return composition.getOverheadIcon(); + } + return null; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPluginConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPluginConfig.java new file mode 100644 index 0000000000..d714001209 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPluginConfig.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019, xperiaclash + * Copyright (c) 2019, ganom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.gauntlet; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigItem; + +public interface GauntletPluginConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "gauntletEnable", + name = "Enable gauntlet", + description = "gauntlet boss prayer" + ) + default boolean enableGauntlet() + { + return true; + } +} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/gauntlet/protect_from_magic.png b/runelite-client/src/main/resources/net/runelite/client/plugins/gauntlet/protect_from_magic.png new file mode 100644 index 0000000000000000000000000000000000000000..b71e1d395f683ca6150ae39b926c29d074e1555a GIT binary patch literal 254 zcmV8GPN`dnpChx$8M{uAowI;xEI0b!SxPD#W9s{jB107*qoM6N<$ Eg4{1=YybcN literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/gauntlet/protect_from_missiles.png b/runelite-client/src/main/resources/net/runelite/client/plugins/gauntlet/protect_from_missiles.png new file mode 100644 index 0000000000000000000000000000000000000000..210e0ff6d639b57de416f970b83b1573e2abd54b GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gji#=T&Ln>}1CoEtvFf#aayiIZi zV?x{7lD&Z)Rv&8D{;EOR4Kragx$ZHBpPTvlJLQZY}t? UbQRlWpmP~KUHx3vIVCg!02zE#GXMYp literal 0 HcmV?d00001