gauntlet: add boss helper (#1141)

* Gauntlet Boss Helper

* xd
This commit is contained in:
OnlyHereToPlayOsrs
2019-07-26 16:04:43 +02:00
committed by Ganom
parent ffb7ce6160
commit 604e034a9a
7 changed files with 389 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2019, lyzrds <https://discord.gg/5eb9Fe>
* Copyright (c) 2019, ganom <https://github.com/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;
}
}

View File

@@ -0,0 +1,207 @@
/*
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
* Copyright (c) 2019, ganom <https://github.com/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<Integer> 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;
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
* Copyright (c) 2019, ganom <https://github.com/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;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B