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; 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 javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.*; import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldArea; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.*; import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.components.PanelComponent;
public class VorkathOverlay extends Overlay { public class VorkathOverlay extends Overlay
private final VorkathConfig config; {
private final VorkathPlugin plugin; private static final Color COLOR_ICON_BACKGROUND = new Color(0, 0, 0, 128);
private final PanelComponent panelComponent = new PanelComponent(); 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 Client client;
private VorkathPlugin plugin;
@Inject @Inject
private VorkathOverlay(VorkathConfig config, VorkathPlugin plugin) { public VorkathOverlay(Client client, VorkathPlugin plugin)
this.config = config; {
this.plugin = plugin;
setLayer(OverlayLayer.ABOVE_SCENE);
setPosition(OverlayPosition.DYNAMIC); setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.MED); setLayer(OverlayLayer.ABOVE_SCENE);
panelComponent.setPreferredSize(new Dimension(150, 0)); this.client = client;
this.plugin = plugin;
} }
@Override private BufferedImage getIcon(Vorkath.AttackStyle attackStyle)
public Dimension render(Graphics2D graphics) { {
if (!config.EnableVorkath()) { switch (attackStyle)
return null;
}
Actor local = client.getLocalPlayer();
WorldArea area = local.getWorldArea();
if (area == null)
{ {
return null; case MAGERANGE:
} return VorkathPlugin.MAGERANGE;
case ICE:
NPC Vorkath = plugin.Vorkath; return VorkathPlugin.ICE;
if (Vorkath != null) { case ACID:
if (plugin.fireball != null) { return VorkathPlugin.ACID;
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());
} }
return null; 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; package net.runelite.client.plugins.vorkath;
import net.runelite.api.events.*; import java.awt.image.BufferedImage;
import net.runelite.client.eventbus.Subscribe;
import com.google.inject.Provides;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.*; import lombok.Getter;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.AnimationID;
import net.runelite.client.config.ConfigManager; import net.runelite.api.Client;
import net.runelite.client.game.SpriteManager; 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.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import org.apache.commons.lang3.ArrayUtils; import net.runelite.client.util.ImageUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Vorkath Helper", name = "Vorkath",
description = "Vorkath Helper", description = "Count vorkath attacks, and which phase is coming next",
tags = {"Vorkath", "Helper"}, tags = {"combat", "overlay", "pve", "pvm"},
type = PluginType.PVM type = PluginType.PVM
) )
public class VorkathPlugin extends Plugin public class VorkathPlugin extends Plugin
{ {
@Inject
private OverlayManager overlayManager;
@Inject
private VorkathConfig config;
@Inject
private VorkathOverlay VorkathOverlay;
@Inject
private VorkathIndicatorOverlay VorkathIndicatorOverlay;
@Inject @Inject
private Client client; private Client client;
@Inject @Inject
private SpriteManager spriteManager; private OverlayManager overlayManager;
@Provides @Inject
VorkathConfig provideConfig(ConfigManager configManager) { private VorkathOverlay overlay;
return configManager.getConfig(VorkathConfig.class);
}
NPC Vorkath; @Inject
int hits; private ZombifiedSpawnOverlay SpawnOverlay;
int ticks;
Boolean ice = false;
LocalPoint fireball;
int fireballticks = 0;
int lastattack;
int venomticks;
int[] VorkathIDs = {393, 395, 1470, 1471, 1477, 1479}; @Inject
private ClientThread clientThread;
@Override @Getter
protected void startUp() throws Exception { private Vorkath vorkath;
overlayManager.add(VorkathOverlay);
overlayManager.add(VorkathIndicatorOverlay); @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 @Override
protected void shutDown() throws Exception { protected void startUp()
overlayManager.remove(VorkathOverlay); {
overlayManager.remove(VorkathIndicatorOverlay); overlayManager.add(overlay);
Vorkath = null; overlayManager.add(SpawnOverlay);
hits = 0; clientThread.invoke(this::reset);
fireball = null;
fireballticks = 0;
ice = false;
lastattack = 0;
} }
@Subscribe @Override
public void onGameTick(GameTick event) { protected void shutDown()
if (!config.EnableVorkath()) { {
return; overlayManager.remove(overlay);
} overlayManager.remove(SpawnOverlay);
ticks++; }
if (ticks - fireballticks > 5) {
fireballticks = 0;
fireball = null;
}
if (venomticks + 30 <= ticks) { private void reset()
venomticks = 0; {
} this.vorkath = null;
for (NPC npc : client.getNpcs())
boolean foundVorkath = false;
for (NPC monster : 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")) { else if (isNpcZombifiedSpawn(npc.getId()))
foundVorkath = true; {
Vorkath = monster; this.spawn = new ZombifiedSpawn(npc);
break;
} }
} }
if (!foundVorkath) { }
Vorkath = null;
hits = 0; private static boolean isNpcVorkath(int npcId)
fireball = null; {
fireballticks = 0; return npcId == NpcID.VORKATH ||
ice = false; npcId == NpcID.VORKATH_8058 ||
lastattack = 0; 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 @Subscribe
public void onProjectileMoved(ProjectileMoved event) { public void onNpcDespawned(NpcDespawned npcDespawned)
if (Vorkath != null) { {
Projectile ball = event.getProjectile(); final NPC npc = npcDespawned.getNpc();
if (ArrayUtils.contains(VorkathIDs, ball.getId())) { if (this.vorkath != null)
if (ticks - lastattack > 4) { {
if (ball.getId() == 395) { if (npc.getId() == this.vorkath.getNpc().getId())
ice = true; {
} this.vorkath = null;
hits++; reset();
lastattack = ticks;
if (hits == 7) {
hits = 0;
}
}
} }
} }
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 @Subscribe
public void onAnimationChanged(AnimationChanged event) { public void onGameTick(GameTick event)
Actor vorki = event.getActor(); {
Actor local = client.getLocalPlayer(); if (vorkath != null)
if (vorki instanceof NPC) { {
if (vorki.equals(Vorkath)) { int animationId = vorkath.getNpc().getAnimation();
if (vorki.getAnimation() != -1 && vorki.getAnimation() != 7948 && vorki.getAnimation() != 7952) {
if (ice) { if (animationId != vorkath.getLastTickAnimation())
ice = false; {
} else { if (animationId == AnimationID.VORKATH_ACID_ATTACK)
hits++; {
if (hits == 7) { vorkath.setPhase(2);
venomticks = ticks; vorkath.setAttacksUntilSwitch(Vorkath.ATTACKS_PER_SWITCH);
hits = 0; }
} else if (animationId == AnimationID.VORKATH_ATTACK && vorkath.getAttacksUntilSwitch() == 0)
if (vorki.getAnimation() == 7960) { {
fireball = local.getLocalLocation(); vorkath.setPhase(1);
fireballticks = ticks; 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;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 827 B