Merge pull request #555 from Infinitay/vorkath-refactor

Vorkath refactor + Fire ball ("tick fire") overlay
This commit is contained in:
Tyler Bochard
2019-06-11 18:27:30 -04:00
committed by GitHub
9 changed files with 406 additions and 237 deletions

View File

@@ -173,7 +173,7 @@ public final class AnimationID
public static final int VORKATH_DEATH = 7949;
public static final int VORKATH_SLASH_ATTACK = 7951;
public static final int VORKATH_ATTACK = 7952;
public static final int VORKATH_FIRE_BOMB_ATTACK = 7960;
public static final int VORKATH_FIRE_BOMB_OR_SPAWN_ATTACK = 7960;
public static final int VORKATH_ACID_ATTACK = 7957;
public static final int BLACKJACK_KO = 838;
public static final int VETION_EARTHQUAKE = 5507;

View File

@@ -93,7 +93,7 @@ public class ProjectileID
public static final int VORKATH_MAGIC = 1479;
public static final int VORKATH_PRAYER_DISABLE = 1471;
public static final int VORKATH_VENOM = 1470;
public static final int VORKATH_ICE = 350;
public static final int VORKATH_ICE = 395;
public static final int HYDRA_MAGIC = 1662;
public static final int HYDRA_RANGED = 1663;

View File

@@ -1,5 +1,7 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2019, Infinitay <https://github.com/Infinitay>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,45 +26,85 @@
*/
package net.runelite.client.plugins.vorkath;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.NPC;
@Data
@Slf4j
public class Vorkath
{
static final int ATTACKS_PER_SWITCH = 6;
static final int FIRE_BALL_ATTACKS = 25;
enum AttackStyle
private NPC vorkath;
private VorkathAttack lastAttack;
private Phase currentPhase;
private Phase nextPhase;
private Phase lastPhase;
private int attacksLeft;
enum Phase
{
MAGERANGE,
ICE,
UNKNOWN,
ACID,
SPECIAL
FIRE_BALL,
SPAWN
}
@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)
public Vorkath(NPC vorkath)
{
this.npc = npc;
this.attacksUntilSwitch = ATTACKS_PER_SWITCH;
this.phase = 0;
this.vorkath = vorkath;
this.attacksLeft = ATTACKS_PER_SWITCH;
this.currentPhase = Phase.UNKNOWN;
this.nextPhase = Phase.UNKNOWN;
this.lastPhase = Phase.UNKNOWN;
log.debug("[Vorkath] Created Vorkath: {}", this);
}
/**
* Updates the existing Vorkath object depending on the new phase it is currently on
*
* @param newPhase the new phase Vorkath is current on
*/
public void updatePhase(Phase newPhase)
{
Phase oldLastPhase = this.lastPhase;
Phase oldCurrentPhase = this.currentPhase;
Phase oldNextPhase = this.currentPhase;
int oldAttacksLeft = this.attacksLeft;
this.lastPhase = this.currentPhase;
this.currentPhase = newPhase;
switch (newPhase)
{
case ACID:
this.nextPhase = Phase.FIRE_BALL;
break;
case FIRE_BALL:
this.nextPhase = Phase.SPAWN;
break;
case SPAWN:
this.nextPhase = Phase.ACID;
break;
default:
this.nextPhase = Phase.UNKNOWN;
break;
}
if (this.currentPhase == Phase.FIRE_BALL)
{
this.attacksLeft = FIRE_BALL_ATTACKS;
}
else
{
this.attacksLeft = ATTACKS_PER_SWITCH;
}
log.debug("[Vorkath] Update! Last Phase: {}->{}, Current Phase: {}->{}, Next Phase: {}->{}, Attacks: {}->{}",
oldLastPhase, this.lastPhase, oldCurrentPhase, this.currentPhase, oldNextPhase, this.nextPhase, oldAttacksLeft, this.attacksLeft);
}
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2019, Infinitay <https://github.com/Infinitay>
*
* 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.vorkath;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.AnimationID;
import net.runelite.api.ProjectileID;
@AllArgsConstructor
@Getter
public enum VorkathAttack
{
/**
* Vorkath's melee attack (see VorkathPlugin#onAnimationChanged)
*/
SLASH_ATTACK(AnimationID.VORKATH_SLASH_ATTACK, -1),
/**
* Vorkath's dragon breath attack
*/
FIRE_BREATH(AnimationID.VORKATH_ATTACK, ProjectileID.VORKATH_DRAGONBREATH),
/**
* Vorkath's dragon breath attack causing the player's active prayers to be deactivated
*/
PRAYER_BREATH(AnimationID.VORKATH_ATTACK, ProjectileID.VORKATH_PRAYER_DISABLE),
/**
* Vorkath's dragon breath attack causing the player to become poisoned with venom
*/
VENOM_BREATH(AnimationID.VORKATH_ATTACK, ProjectileID.VORKATH_VENOM),
/**
* Vorkath's ranged attack
*/
SPIKE(AnimationID.VORKATH_ATTACK, ProjectileID.VORKATH_RANGED),
/**
* Vorkath's magic attack
*/
ICE(AnimationID.VORKATH_ATTACK, ProjectileID.VORKATH_MAGIC),
/**
* Vorkath's aoe fire bomb attack (3x3 from where player was originally standing)
*/
FIRE_BOMB(AnimationID.VORKATH_FIRE_BOMB_OR_SPAWN_ATTACK, ProjectileID.VORKATH_BOMB_AOE),
/**
* Vorkath's aoe acid attacking, spewing acid across the instance
*/
ACID(AnimationID.VORKATH_ACID_ATTACK, ProjectileID.VORKATH_POISON_POOL_AOE),
/**
* Vorkath's fire ball attack that is fired during the acid phase, almost every tick for 25(?) attacks total
*/
FIRE_BALL(AnimationID.VORKATH_ACID_ATTACK, ProjectileID.VORKATH_TICK_FIRE_AOE),
/**
* Vorkath's dragon breath attack causing the player to be frozen during Zombified Spawn phase
*/
FREEZE_BREATH(AnimationID.VORKATH_ATTACK, ProjectileID.VORKATH_ICE),
/**
* Vorkath's spawning of a Zombified Spawn
*/
ZOMBIFIED_SPAWN(AnimationID.VORKATH_FIRE_BOMB_OR_SPAWN_ATTACK, ProjectileID.VORKATH_SPAWN_AOE);
private final int vorkathAnimationID;
private final int projectileID;
private static final Map<Integer, VorkathAttack> VORKATH_ATTACKS;
private static final Map<Integer, VorkathAttack> VORKATH_BASIC_ATTACKS;
static
{
ImmutableMap.Builder<Integer, VorkathAttack> builder = new ImmutableMap.Builder<>();
for (VorkathAttack vorkathAttack : values())
{
builder.put(vorkathAttack.getProjectileID(), vorkathAttack);
}
VORKATH_ATTACKS = builder.build();
}
static
{
ImmutableMap.Builder<Integer, VorkathAttack> builder = new ImmutableMap.Builder<>();
builder.put(FIRE_BREATH.getProjectileID(), FIRE_BREATH)
.put(PRAYER_BREATH.getProjectileID(), PRAYER_BREATH)
.put(VENOM_BREATH.getProjectileID(), VENOM_BREATH)
.put(SPIKE.getProjectileID(), SPIKE)
.put(ICE.getProjectileID(), ICE)
.put(FIRE_BOMB.getProjectileID(), FIRE_BOMB)
.put(FIRE_BALL.getProjectileID(), FIRE_BALL);
// FIRE_BOMB and FIRE_BALL are also basic attacks
// Although SLASH_ATTACK is a basic attack, we're going to handle it differently
VORKATH_BASIC_ATTACKS = builder.build();
}
/**
* @param projectileID id of projectile
* @return {@link VorkathAttack} associated with the specified projectile
*/
public static VorkathAttack getVorkathAttack(int projectileID)
{
return VORKATH_ATTACKS.get(projectileID);
}
/**
* @param projectileID
* @return true if the projectile id matches a {@link VorkathAttack#getProjectileID()} within {@link VorkathAttack#VORKATH_BASIC_ATTACKS},
* false otherwise
*/
public static boolean isBasicAttack(int projectileID)
{
return VORKATH_BASIC_ATTACKS.get(projectileID) != null;
}
}

View File

@@ -1,5 +1,7 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2019, Infinitay <https://github.com/Infinitay>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -59,20 +61,6 @@ public class VorkathOverlay extends Overlay
this.plugin = plugin;
}
private BufferedImage getIcon(Vorkath.AttackStyle attackStyle)
{
switch (attackStyle)
{
case MAGERANGE:
return VorkathPlugin.MAGERANGE;
case ICE:
return VorkathPlugin.ICE;
case ACID:
return VorkathPlugin.ACID;
}
return null;
}
@Override
public Dimension render(Graphics2D graphics)
{
@@ -80,29 +68,17 @@ public class VorkathOverlay extends Overlay
{
Vorkath vorkath = plugin.getVorkath();
LocalPoint localLocation = vorkath.getNpc().getLocalLocation();
LocalPoint localLocation = vorkath.getVorkath().getLocalLocation();
if (localLocation != null)
{
Point point = Perspective.localToCanvas(client, localLocation, client.getPlane(), vorkath.getNpc().getLogicalHeight() + 16);
Point point = Perspective.localToCanvas(client, localLocation, client.getPlane(), vorkath.getVorkath().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);
}
BufferedImage currentPhaseIcon = getIcon(vorkath);
int totalWidth = icon.getWidth() * OVERLAY_ICON_MARGIN;
int totalWidth = currentPhaseIcon.getWidth() * OVERLAY_ICON_MARGIN;
int bgPadding = 8;
int currentPosX = 0;
@@ -110,32 +86,31 @@ public class VorkathOverlay extends Overlay
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);
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
currentPhaseIcon.getWidth() + bgPadding * 2,
currentPhaseIcon.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);
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
currentPhaseIcon.getWidth() + bgPadding * 2,
currentPhaseIcon.getHeight() + bgPadding * 2);
graphics.drawImage(
icon,
currentPhaseIcon,
point.getX() - totalWidth / 2 + currentPosX,
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE,
point.getY() - currentPhaseIcon.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,
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
currentPhaseIcon.getWidth() + bgPadding * 2,
currentPhaseIcon.getHeight() + bgPadding * 2,
90.0,
-360.0 * (Vorkath.ATTACKS_PER_SWITCH -
vorkath.getAttacksUntilSwitch()) / Vorkath.ATTACKS_PER_SWITCH,
-360.0 * getAttacksLeftProgress(),
Arc2D.OPEN);
graphics.draw(arc);
}
@@ -144,4 +119,39 @@ public class VorkathOverlay extends Overlay
return null;
}
/**
* @param vorkath Vorkath object
* @return image of the current phase Vorkath is on
*/
private BufferedImage getIcon(Vorkath vorkath)
{
switch (vorkath.getCurrentPhase())
{
case UNKNOWN:
return VorkathPlugin.UNKNOWN;
case ACID:
return VorkathPlugin.ACID;
case FIRE_BALL:
return VorkathPlugin.FIRE_BALL;
case SPAWN:
return VorkathPlugin.SPAWN;
}
return null;
}
/**
* @return number of attacks Vorkath has left in the current phase
*/
private double getAttacksLeftProgress()
{
if (plugin.getVorkath().getCurrentPhase() != Vorkath.Phase.FIRE_BALL)
{
return (double) (Vorkath.ATTACKS_PER_SWITCH - plugin.getVorkath().getAttacksLeft()) / Vorkath.ATTACKS_PER_SWITCH;
}
else
{
return (double) (Vorkath.FIRE_BALL_ATTACKS - plugin.getVorkath().getAttacksLeft()) / Vorkath.FIRE_BALL_ATTACKS;
}
}
}

View File

@@ -1,5 +1,7 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2019, Infinitay <https://github.com/Infinitay>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,25 +26,24 @@
*/
package net.runelite.client.plugins.vorkath;
import com.google.inject.Inject;
import java.awt.image.BufferedImage;
import javax.inject.Inject;
import lombok.Getter;
import net.runelite.api.AnimationID;
import lombok.extern.slf4j.Slf4j;
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.AnimationChanged;
import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned;
import net.runelite.client.callback.ClientThread;
import net.runelite.api.events.ProjectileMoved;
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 net.runelite.client.util.ImageUtil;
import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor(
name = "Vorkath Helper",
@@ -51,9 +52,11 @@ import net.runelite.client.util.ImageUtil;
type = PluginType.PVM,
enabledByDefault = false
)
@Slf4j
public class VorkathPlugin extends Plugin
{
private static final int VORKATH_REGION = 9023;
@Inject
private Client client;
@@ -66,156 +69,177 @@ public class VorkathPlugin extends Plugin
@Inject
private ZombifiedSpawnOverlay SpawnOverlay;
@Inject
private ClientThread clientThread;
@Getter
private Vorkath vorkath;
@Getter
private ZombifiedSpawn spawn;
private NPC zombifiedSpawn;
/**
* The last projectile's starting movement cycle
*/
private int lastProjectileCycle;
static final BufferedImage UNKNOWN;
static final BufferedImage ACID;
static final BufferedImage ICE;
static final BufferedImage MAGERANGE;
static final BufferedImage FIRE_BALL;
static final BufferedImage SPAWN;
static
{
UNKNOWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png");
ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png");
ICE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png");
MAGERANGE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png");
}
@Override
protected void startUp()
{
overlayManager.add(overlay);
overlayManager.add(SpawnOverlay);
clientThread.invoke(this::reset);
}
@Override
protected void shutDown()
{
overlayManager.remove(overlay);
overlayManager.remove(SpawnOverlay);
}
private void reset()
{
this.vorkath = null;
for (NPC npc : client.getNpcs())
{
if (isNpcVorkath(npc.getId()))
{
this.vorkath = new Vorkath(npc);
}
else if (isNpcZombifiedSpawn(npc.getId()))
{
this.spawn = new ZombifiedSpawn(npc);
}
}
}
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;
FIRE_BALL = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "fire_strike.png");
SPAWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png");
}
@Subscribe
public void onNpcSpawned(NpcSpawned event)
{
NPC npc = event.getNpc();
if (isNpcVorkath(npc.getId()))
if (isAtVorkath())
{
this.vorkath = new Vorkath(npc);
}
else if (isNpcZombifiedSpawn(npc.getId()))
{
this.spawn = new ZombifiedSpawn(npc);
}
}
@Subscribe
public void onNpcDespawned(NpcDespawned npcDespawned)
{
final NPC npc = npcDespawned.getNpc();
if (this.vorkath != null)
{
if (npc.getId() == this.vorkath.getNpc().getId())
if (isVorkath(event.getNpc().getId()))
{
this.vorkath = null;
reset();
vorkath = new Vorkath(event.getNpc());
lastProjectileCycle = -1;
overlayManager.add(overlay);
}
}
if (this.spawn != null)
{
if (npc.getId() == this.spawn.getNpc().getId())
else if (isZombifiedSpawn(event.getNpc().getId()))
{
this.spawn = null;
zombifiedSpawn = event.getNpc();
overlayManager.add(SpawnOverlay);
}
}
}
@Subscribe
public void onGameStateChanged(GameStateChanged event)
public void onNpcDespawned(NpcDespawned event)
{
GameState gs = event.getGameState();
if (gs == GameState.LOGGING_IN ||
gs == GameState.CONNECTION_LOST ||
gs == GameState.HOPPING)
if (isAtVorkath())
{
reset();
if (isVorkath(event.getNpc().getId()))
{
vorkath = null;
lastProjectileCycle = -1;
overlayManager.remove(overlay);
}
else if (isZombifiedSpawn(event.getNpc().getId()))
{
zombifiedSpawn = null;
overlayManager.remove(SpawnOverlay);
}
}
}
@Subscribe
public void onGameTick(GameTick event)
public void onProjectileMoved(ProjectileMoved event)
{
if (vorkath != null)
// Only capture initial projectile
if (!isAtVorkath() || event.getProjectile().getStartMovementCycle() == lastProjectileCycle)
{
int animationId = vorkath.getNpc().getAnimation();
return;
}
if (animationId != vorkath.getLastTickAnimation())
VorkathAttack vorkathAttack = VorkathAttack.getVorkathAttack(event.getProjectile().getId());
if (vorkathAttack != null)
{
/*log.debug("[Projectile ({})] Game Tick: {}, Game Cycle: {}, Starting Cyle: {} Last Cycle: {}, Initial Projectile?: {}",
vorkathAttack, client.getTickCount(), client.getGameCycle(), event.getProjectile().getStartMovementCycle(),
lastProjectileCycle, event.getProjectile().getStartMovementCycle() == client.getGameCycle());*/
if (VorkathAttack.isBasicAttack(vorkathAttack.getProjectileID()) && vorkath.getAttacksLeft() > 0)
{
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.setAttacksLeft(vorkath.getAttacksLeft() - 1);
}
else if (vorkathAttack == VorkathAttack.ACID)
{
vorkath.updatePhase(Vorkath.Phase.ACID);
// Sets the phase's progress indicator to done
vorkath.setAttacksLeft(0);
}
else if (vorkathAttack == VorkathAttack.FIRE_BALL)
{
vorkath.updatePhase(Vorkath.Phase.FIRE_BALL);
// Decrement to account for this fire ball
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1);
}
else if (vorkathAttack == VorkathAttack.FREEZE_BREATH && vorkath.getLastAttack() != VorkathAttack.ZOMBIFIED_SPAWN)
{
// Filters out second invisible freeze attack that is immediately after the Zombified Spawn
vorkath.updatePhase(Vorkath.Phase.SPAWN);
// Sets progress of the phase to half
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - (vorkath.getAttacksLeft() / 2));
}
else if (vorkathAttack == VorkathAttack.ZOMBIFIED_SPAWN || (vorkath.getLastAttack() == VorkathAttack.ZOMBIFIED_SPAWN))
{
// Also consumes the second invisible freeze attack that is immediately after the Zombified Spawn
// Sets progress of the phase to done as there are no more attacks within this phase
vorkath.setAttacksLeft(0);
}
else
{
// Vorkath fired a basic attack AND there are no more attacks left, typically after phases are over
vorkath.updatePhase(vorkath.getNextPhase());
// Decrement to account for this basic attack
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1);
}
vorkath.setLastTickAnimation(animationId);
log.debug("[Vorkath ({})] {}", vorkathAttack, vorkath);
vorkath.setLastAttack(vorkathAttack);
lastProjectileCycle = event.getProjectile().getStartMovementCycle();
}
}
@Subscribe
public void onAnimationChanged(AnimationChanged event)
{
if (isAtVorkath() && vorkath != null && event.getActor().equals(vorkath.getVorkath())
&& event.getActor().getAnimation() == VorkathAttack.SLASH_ATTACK.getVorkathAnimationID())
{
if (vorkath.getAttacksLeft() > 0)
{
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1);
}
else
{
// No more attacks left, typically after phases are over
vorkath.updatePhase(vorkath.getNextPhase());
// Decrement to account for this basic attack
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1);
}
log.debug("[Vorkath (SLASH_ATTACK)] {}", vorkath);
}
}
/**
* @return true if the player is in the Vorkath region, false otherwise
*/
private boolean isAtVorkath()
{
return ArrayUtils.contains(client.getMapRegions(), VORKATH_REGION);
}
/**
* @param npcID
* @return true if the npc is Vorkath, false otherwise
*/
private boolean isVorkath(int npcID)
{
// Could be done with a a simple name check instead...
return npcID == NpcID.VORKATH ||
npcID == NpcID.VORKATH_8058 ||
npcID == NpcID.VORKATH_8059 ||
npcID == NpcID.VORKATH_8060 ||
npcID == NpcID.VORKATH_8061;
}
/**
* @param npcID
* @return true if the npc is a Zombified Spawn, otherwise false
*/
private boolean isZombifiedSpawn(int npcID)
{
// Could be done with a a simple name check instead...
return npcID == NpcID.ZOMBIFIED_SPAWN ||
npcID == NpcID.ZOMBIFIED_SPAWN_8063;
}
}

View File

@@ -1,39 +0,0 @@
/*
* 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.vorkath;
import lombok.Getter;
import net.runelite.api.NPC;
class ZombifiedSpawn
{
@Getter
private NPC npc;
ZombifiedSpawn(NPC npc)
{
this.npc = npc;
}
}

View File

@@ -48,10 +48,9 @@ public class ZombifiedSpawnOverlay extends Overlay
@Override
public Dimension render(Graphics2D graphics)
{
if (plugin.getSpawn() != null)
if (plugin.getZombifiedSpawn() != null)
{
ZombifiedSpawn spawn = plugin.getSpawn();
OverlayUtil.renderActorOverlayImage(graphics, spawn.getNpc(), VorkathPlugin.ICE, Color.green, 10);
OverlayUtil.renderActorOverlayImage(graphics, plugin.getZombifiedSpawn(), VorkathPlugin.SPAWN, Color.green, 10);
}
return null;

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B