Nicer vorkath plugin (#61)

This commit is contained in:
sdburns1998
2019-04-23 22:04:12 +02:00
committed by runelite-ext
parent 73cb82eb64
commit 432cf40f7e
11 changed files with 350 additions and 293 deletions

View File

@@ -1,8 +0,0 @@
package net.runelite.client.plugins.vorkath;
public enum TileHighlight
{
None,
Single,
All
}

View File

@@ -0,0 +1,44 @@
package net.runelite.client.plugins.vorkath;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.NPC;
public class Vorkath
{
static final int ATTACKS_PER_SWITCH = 6;
enum AttackStyle
{
MAGERANGE,
ICE,
ACID,
SPECIAL
}
@Getter
private NPC npc;
@Getter
@Setter
private int phase;
@Getter
@Setter
private int attacksUntilSwitch;
@Getter
@Setter
private int lastTickAnimation;
@Getter
@Setter
private boolean icePhaseAttack;
public Vorkath(NPC npc)
{
this.npc = npc;
this.attacksUntilSwitch = ATTACKS_PER_SWITCH;
this.phase = 0;
}
}

View File

@@ -1,51 +0,0 @@
package net.runelite.client.plugins.vorkath;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import java.awt.*;
@ConfigGroup("vorkath")
public interface VorkathConfig extends Config {
@ConfigItem(
position = 0,
keyName = "Vorkathenable",
name = "Enable Vorkath Helper",
description = "Configures whether or not to enable Vorkath Helper."
)
default boolean EnableVorkath() { return true; }
@ConfigItem(
position = 1,
keyName = "countercolor",
name = "Indicator color",
description = "Configures color of text displaying Vorkath hits left to special attack."
)
default Color CounterColor() { return Color.YELLOW; }
@ConfigItem(
position = 2,
keyName = "countersize",
name = "Bold indicator",
description = "Configures if text indicator is bold or not."
)
default boolean BoldText() { return true; }
@ConfigItem(
position = 3,
keyName = "enumConfig",
name = "Fireball Tile Highlight",
description = "Select how to apply tile highlighting for Vorkath's fireball attack"
)
default TileHighlight TileHighlight() { return TileHighlight.All; }
@ConfigItem(
position = 4,
keyName = "overlayindicators",
name = "Overlay Indicators",
description = "Configures if an overlay box displaying vorkath information should be displayed."
)
default boolean VorkathBox() { return false; }
}

View File

@@ -1,53 +0,0 @@
package net.runelite.client.plugins.vorkath;
import java.awt.*;
import javax.inject.Inject;
import net.runelite.api.*;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldArea;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.*;
import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.PanelComponent;
public class VorkathIndicatorOverlay extends Overlay {
private final VorkathConfig config;
private final VorkathPlugin plugin;
private final PanelComponent panelComponent = new PanelComponent();
@Inject
private Client client;
@Inject
private VorkathIndicatorOverlay(VorkathConfig config, VorkathPlugin plugin) {
this.config = config;
this.plugin = plugin;
setPosition(OverlayPosition.BOTTOM_RIGHT);
setPriority(OverlayPriority.MED);
panelComponent.setPreferredSize(new Dimension(150, 0));
}
@Override
public Dimension render(Graphics2D graphics) {
if (!config.EnableVorkath()) {
return null;
}
NPC Vorkath = plugin.Vorkath;
if (Vorkath != null) {
if (config.VorkathBox()) {
panelComponent.getChildren().clear();
if (plugin.venomticks != 0) {
if (plugin.venomticks + 5 <= plugin.ticks) {
panelComponent.getChildren().add(LineComponent.builder().left("Quickfire Barrage:").right(Integer.toString(30 - (plugin.ticks - plugin.venomticks))).rightColor(Color.ORANGE).build());
}
}
panelComponent.getChildren().add(LineComponent.builder().left("Special Attack:").right(Integer.toString(7 - plugin.hits)).rightColor(config.CounterColor()).build());
return panelComponent.render(graphics);
}
}
return null;
}
}

View File

@@ -1,84 +1,123 @@
package net.runelite.client.plugins.vorkath;
import java.awt.*;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Arc2D;
import java.awt.image.BufferedImage;
import javax.inject.Inject;
import net.runelite.api.*;
import net.runelite.api.Client;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldArea;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.*;
import net.runelite.client.ui.overlay.components.PanelComponent;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
public class VorkathOverlay extends Overlay {
private final VorkathConfig config;
private final VorkathPlugin plugin;
private final PanelComponent panelComponent = new PanelComponent();
public class VorkathOverlay extends Overlay
{
private static final Color COLOR_ICON_BACKGROUND = new Color(0, 0, 0, 128);
private static final Color COLOR_ICON_BORDER = new Color(0, 0, 0, 255);
private static final Color COLOR_ICON_BORDER_FILL = new Color(219, 175, 0, 255);
private static final int OVERLAY_ICON_DISTANCE = 30;
private static final int OVERLAY_ICON_MARGIN = 1;
@Inject
private Client client;
private VorkathPlugin plugin;
@Inject
private VorkathOverlay(VorkathConfig config, VorkathPlugin plugin) {
this.config = config;
this.plugin = plugin;
setLayer(OverlayLayer.ABOVE_SCENE);
public VorkathOverlay(Client client, VorkathPlugin plugin)
{
setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.MED);
panelComponent.setPreferredSize(new Dimension(150, 0));
setLayer(OverlayLayer.ABOVE_SCENE);
this.client = client;
this.plugin = plugin;
}
@Override
public Dimension render(Graphics2D graphics) {
if (!config.EnableVorkath()) {
return null;
}
Actor local = client.getLocalPlayer();
WorldArea area = local.getWorldArea();
if (area == null)
private BufferedImage getIcon(Vorkath.AttackStyle attackStyle)
{
switch (attackStyle)
{
return null;
}
NPC Vorkath = plugin.Vorkath;
if (Vorkath != null) {
if (plugin.fireball != null) {
if (config.TileHighlight() == TileHighlight.Single) {
final Polygon poly = Perspective.getCanvasTilePoly(client, plugin.fireball);
if (poly != null) {
OverlayUtil.renderPolygon(graphics, poly, Color.RED);
}
} else if (config.TileHighlight() == TileHighlight.All) {
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0) {
continue;
}
LocalPoint lp = new LocalPoint(plugin.fireball.getX() + dx * Perspective.LOCAL_TILE_SIZE + dx * Perspective.LOCAL_TILE_SIZE * (area.getWidth() - 1) / 2, plugin.fireball.getY() + dy * Perspective.LOCAL_TILE_SIZE + dy * Perspective.LOCAL_TILE_SIZE * (area.getHeight() - 1) / 2);
Polygon polyadj = Perspective.getCanvasTilePoly(client, lp);
if (polyadj != null) {
OverlayUtil.renderPolygon(graphics, polyadj, Color.ORANGE);
}
}
}
}
}
if (config.BoldText()) {
graphics.setFont(FontManager.getRunescapeBoldFont());
}
if (plugin.venomticks != 0) {
if (plugin.venomticks + 5 <= plugin.ticks) {
OverlayUtil.renderTextLocation(graphics, Vorkath.getCanvasTextLocation(graphics, Integer.toString(30 - (plugin.ticks - plugin.venomticks)), Vorkath.getLogicalHeight() + 150), Integer.toString(30 - (plugin.ticks - plugin.venomticks)), Color.ORANGE);
}
}
OverlayUtil.renderTextLocation(graphics, Vorkath.getCanvasTextLocation(graphics, Integer.toString(7 - plugin.hits), Vorkath.getLogicalHeight() + 40), Integer.toString(7 - plugin.hits), config.CounterColor());
graphics.setFont(FontManager.getRunescapeFont());
case MAGERANGE:
return VorkathPlugin.MAGERANGE;
case ICE:
return VorkathPlugin.ICE;
case ACID:
return VorkathPlugin.ACID;
}
return null;
}
}
@Override
public Dimension render(Graphics2D graphics)
{
if (plugin.getVorkath() != null)
{
Vorkath vorkath = plugin.getVorkath();
LocalPoint localLocation = vorkath.getNpc().getLocalLocation();
if (localLocation != null)
{
Point point = Perspective.localToCanvas(client, localLocation, client.getPlane(), vorkath.getNpc().getLogicalHeight() + 16);
if (point != null)
{
point = new Point(point.getX(), point.getY());
BufferedImage icon = null;
if (vorkath.getPhase() == 0)
{
icon = getIcon(Vorkath.AttackStyle.MAGERANGE);
}
else if (vorkath.getPhase() == 1)
{
icon = getIcon(Vorkath.AttackStyle.ACID);
}
else if (vorkath.getPhase() == 2)
{
icon = getIcon(Vorkath.AttackStyle.ICE);
}
int totalWidth = icon.getWidth() * OVERLAY_ICON_MARGIN;
int bgPadding = 8;
int currentPosX = 0;
graphics.setStroke(new BasicStroke(2));
graphics.setColor(COLOR_ICON_BACKGROUND);
graphics.fillOval(
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
icon.getWidth() + bgPadding * 2,
icon.getHeight() + bgPadding * 2);
graphics.setColor(COLOR_ICON_BORDER);
graphics.drawOval(
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
icon.getWidth() + bgPadding * 2,
icon.getHeight() + bgPadding * 2);
graphics.drawImage(
icon,
point.getX() - totalWidth / 2 + currentPosX,
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE,
null);
graphics.setColor(COLOR_ICON_BORDER_FILL);
Arc2D.Double arc = new Arc2D.Double(
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
icon.getWidth() + bgPadding * 2,
icon.getHeight() + bgPadding * 2,
90.0,
-360.0 * (Vorkath.ATTACKS_PER_SWITCH -
vorkath.getAttacksUntilSwitch()) / Vorkath.ATTACKS_PER_SWITCH,
Arc2D.OPEN);
graphics.draw(arc);
}
}
}
return null;
}
}

View File

@@ -1,159 +1,195 @@
package net.runelite.client.plugins.vorkath;
import net.runelite.api.events.*;
import net.runelite.client.eventbus.Subscribe;
import com.google.inject.Provides;
import java.awt.image.BufferedImage;
import javax.inject.Inject;
import net.runelite.api.*;
import net.runelite.api.coords.LocalPoint;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.game.SpriteManager;
import lombok.Getter;
import net.runelite.api.AnimationID;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.NPC;
import net.runelite.api.NpcID;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.Subscribe;
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 org.apache.commons.lang3.ArrayUtils;
import net.runelite.client.util.ImageUtil;
@PluginDescriptor(
name = "Vorkath Helper",
description = "Vorkath Helper",
tags = {"Vorkath", "Helper"},
name = "Vorkath",
description = "Count vorkath attacks, and which phase is coming next",
tags = {"combat", "overlay", "pve", "pvm"},
type = PluginType.PVM
)
public class VorkathPlugin extends Plugin
{
@Inject
private OverlayManager overlayManager;
@Inject
private VorkathConfig config;
@Inject
private VorkathOverlay VorkathOverlay;
@Inject
private VorkathIndicatorOverlay VorkathIndicatorOverlay;
@Inject
private Client client;
@Inject
private SpriteManager spriteManager;
private OverlayManager overlayManager;
@Provides
VorkathConfig provideConfig(ConfigManager configManager) {
return configManager.getConfig(VorkathConfig.class);
}
@Inject
private VorkathOverlay overlay;
NPC Vorkath;
int hits;
int ticks;
Boolean ice = false;
LocalPoint fireball;
int fireballticks = 0;
int lastattack;
int venomticks;
@Inject
private ZombifiedSpawnOverlay SpawnOverlay;
int[] VorkathIDs = {393, 395, 1470, 1471, 1477, 1479};
@Inject
private ClientThread clientThread;
@Override
protected void startUp() throws Exception {
overlayManager.add(VorkathOverlay);
overlayManager.add(VorkathIndicatorOverlay);
@Getter
private Vorkath vorkath;
@Getter
private ZombifiedSpawn spawn;
static final BufferedImage ACID;
static final BufferedImage ICE;
static final BufferedImage MAGERANGE;
static
{
ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png");
ICE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png");
MAGERANGE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png");
}
@Override
protected void shutDown() throws Exception {
overlayManager.remove(VorkathOverlay);
overlayManager.remove(VorkathIndicatorOverlay);
Vorkath = null;
hits = 0;
fireball = null;
fireballticks = 0;
ice = false;
lastattack = 0;
protected void startUp()
{
overlayManager.add(overlay);
overlayManager.add(SpawnOverlay);
clientThread.invoke(this::reset);
}
@Subscribe
public void onGameTick(GameTick event) {
if (!config.EnableVorkath()) {
return;
}
ticks++;
if (ticks - fireballticks > 5) {
fireballticks = 0;
fireball = null;
}
@Override
protected void shutDown()
{
overlayManager.remove(overlay);
overlayManager.remove(SpawnOverlay);
}
if (venomticks + 30 <= ticks) {
venomticks = 0;
}
boolean foundVorkath = false;
for (NPC monster : client.getNpcs())
private void reset()
{
this.vorkath = null;
for (NPC npc : client.getNpcs())
{
if (monster == null || monster.getName() == null || monster.getCombatLevel() == 0)
if (isNpcVorkath(npc.getId()))
{
continue;
this.vorkath = new Vorkath(npc);
}
if (monster.getName().equalsIgnoreCase("Vorkath")) {
foundVorkath = true;
Vorkath = monster;
break;
else if (isNpcZombifiedSpawn(npc.getId()))
{
this.spawn = new ZombifiedSpawn(npc);
}
}
if (!foundVorkath) {
Vorkath = null;
hits = 0;
fireball = null;
fireballticks = 0;
ice = false;
lastattack = 0;
}
private static boolean isNpcVorkath(int npcId)
{
return npcId == NpcID.VORKATH ||
npcId == NpcID.VORKATH_8058 ||
npcId == NpcID.VORKATH_8059 ||
npcId == NpcID.VORKATH_8060 ||
npcId == NpcID.VORKATH_8061;
}
private static boolean isNpcZombifiedSpawn(int id)
{
return id == NpcID.ZOMBIFIED_SPAWN ||
id == NpcID.ZOMBIFIED_SPAWN_8063;
}
@Subscribe
public void onNpcSpawned(NpcSpawned event)
{
NPC npc = event.getNpc();
if (isNpcVorkath(npc.getId()))
{
this.vorkath = new Vorkath(npc);
}
else if (isNpcZombifiedSpawn(npc.getId()))
{
this.spawn = new ZombifiedSpawn(npc);
}
}
@Subscribe
public void onProjectileMoved(ProjectileMoved event) {
if (Vorkath != null) {
Projectile ball = event.getProjectile();
if (ArrayUtils.contains(VorkathIDs, ball.getId())) {
if (ticks - lastattack > 4) {
if (ball.getId() == 395) {
ice = true;
}
hits++;
lastattack = ticks;
if (hits == 7) {
hits = 0;
}
}
public void onNpcDespawned(NpcDespawned npcDespawned)
{
final NPC npc = npcDespawned.getNpc();
if (this.vorkath != null)
{
if (npc.getId() == this.vorkath.getNpc().getId())
{
this.vorkath = null;
reset();
}
}
if (this.spawn != null)
{
if (npc.getId() == this.spawn.getNpc().getId())
{
this.spawn = null;
}
}
}
@Subscribe
public void onGameStateChanged(GameStateChanged event)
{
GameState gs = event.getGameState();
if (gs == GameState.LOGGING_IN ||
gs == GameState.CONNECTION_LOST ||
gs == GameState.HOPPING)
{
reset();
}
}
@Subscribe
public void onAnimationChanged(AnimationChanged event) {
Actor vorki = event.getActor();
Actor local = client.getLocalPlayer();
if (vorki instanceof NPC) {
if (vorki.equals(Vorkath)) {
if (vorki.getAnimation() != -1 && vorki.getAnimation() != 7948 && vorki.getAnimation() != 7952) {
if (ice) {
ice = false;
} else {
hits++;
if (hits == 7) {
venomticks = ticks;
hits = 0;
}
if (vorki.getAnimation() == 7960) {
fireball = local.getLocalLocation();
fireballticks = ticks;
}
public void onGameTick(GameTick event)
{
if (vorkath != null)
{
int animationId = vorkath.getNpc().getAnimation();
if (animationId != vorkath.getLastTickAnimation())
{
if (animationId == AnimationID.VORKATH_ACID_ATTACK)
{
vorkath.setPhase(2);
vorkath.setAttacksUntilSwitch(Vorkath.ATTACKS_PER_SWITCH);
}
else if (animationId == AnimationID.VORKATH_ATTACK && vorkath.getAttacksUntilSwitch() == 0)
{
vorkath.setPhase(1);
vorkath.setAttacksUntilSwitch(Vorkath.ATTACKS_PER_SWITCH);
//Vorkath does a bomb animation after the ice dragon breathe, we need to account for it
vorkath.setIcePhaseAttack(true);
}
else if (animationId == AnimationID.VORKATH_ATTACK || animationId == AnimationID.VORKATH_FIRE_BOMB_ATTACK)
{
if (vorkath.isIcePhaseAttack())
{
vorkath.setIcePhaseAttack(false);
}
else
{
vorkath.setAttacksUntilSwitch(vorkath.getAttacksUntilSwitch() - 1);
}
}
}
vorkath.setLastTickAnimation(animationId);
}
}
}
}

View File

@@ -0,0 +1,15 @@
package net.runelite.client.plugins.vorkath;
import lombok.Getter;
import net.runelite.api.NPC;
class ZombifiedSpawn
{
@Getter
private NPC npc;
ZombifiedSpawn(NPC npc)
{
this.npc = npc;
}
}

View File

@@ -0,0 +1,35 @@
package net.runelite.client.plugins.vorkath;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import javax.inject.Inject;
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.OverlayUtil;
public class ZombifiedSpawnOverlay extends Overlay
{
private VorkathPlugin plugin;
@Inject
public ZombifiedSpawnOverlay(VorkathPlugin plugin)
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_SCENE);
this.plugin = plugin;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (plugin.getSpawn() != null)
{
ZombifiedSpawn spawn = plugin.getSpawn();
OverlayUtil.renderActorOverlayImage(graphics, spawn.getNpc(), VorkathPlugin.ICE, Color.green, 10);
}
return null;
}
}