Merge pull request #555 from Infinitay/vorkath-refactor
Vorkath refactor + Fire ball ("tick fire") overlay
This commit is contained in:
@@ -173,7 +173,7 @@ public final class AnimationID
|
|||||||
public static final int VORKATH_DEATH = 7949;
|
public static final int VORKATH_DEATH = 7949;
|
||||||
public static final int VORKATH_SLASH_ATTACK = 7951;
|
public static final int VORKATH_SLASH_ATTACK = 7951;
|
||||||
public static final int VORKATH_ATTACK = 7952;
|
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 VORKATH_ACID_ATTACK = 7957;
|
||||||
public static final int BLACKJACK_KO = 838;
|
public static final int BLACKJACK_KO = 838;
|
||||||
public static final int VETION_EARTHQUAKE = 5507;
|
public static final int VETION_EARTHQUAKE = 5507;
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class ProjectileID
|
|||||||
public static final int VORKATH_MAGIC = 1479;
|
public static final int VORKATH_MAGIC = 1479;
|
||||||
public static final int VORKATH_PRAYER_DISABLE = 1471;
|
public static final int VORKATH_PRAYER_DISABLE = 1471;
|
||||||
public static final int VORKATH_VENOM = 1470;
|
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_MAGIC = 1662;
|
||||||
public static final int HYDRA_RANGED = 1663;
|
public static final int HYDRA_RANGED = 1663;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, https://runelitepl.us
|
* Copyright (c) 2018, https://runelitepl.us
|
||||||
|
* Copyright (c) 2019, Infinitay <https://github.com/Infinitay>
|
||||||
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,45 +26,85 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.vorkath;
|
package net.runelite.client.plugins.vorkath;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Data;
|
||||||
import lombok.Setter;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.NPC;
|
import net.runelite.api.NPC;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Slf4j
|
||||||
public class Vorkath
|
public class Vorkath
|
||||||
{
|
{
|
||||||
static final int ATTACKS_PER_SWITCH = 6;
|
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,
|
UNKNOWN,
|
||||||
ICE,
|
|
||||||
ACID,
|
ACID,
|
||||||
SPECIAL
|
FIRE_BALL,
|
||||||
|
SPAWN
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
public Vorkath(NPC vorkath)
|
||||||
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.vorkath = vorkath;
|
||||||
this.attacksUntilSwitch = ATTACKS_PER_SWITCH;
|
this.attacksLeft = ATTACKS_PER_SWITCH;
|
||||||
this.phase = 0;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, https://runelitepl.us
|
* Copyright (c) 2018, https://runelitepl.us
|
||||||
|
* Copyright (c) 2019, Infinitay <https://github.com/Infinitay>
|
||||||
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -59,20 +61,6 @@ public class VorkathOverlay extends Overlay
|
|||||||
this.plugin = plugin;
|
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
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
@@ -80,29 +68,17 @@ public class VorkathOverlay extends Overlay
|
|||||||
{
|
{
|
||||||
Vorkath vorkath = plugin.getVorkath();
|
Vorkath vorkath = plugin.getVorkath();
|
||||||
|
|
||||||
LocalPoint localLocation = vorkath.getNpc().getLocalLocation();
|
LocalPoint localLocation = vorkath.getVorkath().getLocalLocation();
|
||||||
if (localLocation != null)
|
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)
|
if (point != null)
|
||||||
{
|
{
|
||||||
point = new Point(point.getX(), point.getY());
|
point = new Point(point.getX(), point.getY());
|
||||||
|
|
||||||
BufferedImage icon = null;
|
BufferedImage currentPhaseIcon = getIcon(vorkath);
|
||||||
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 totalWidth = currentPhaseIcon.getWidth() * OVERLAY_ICON_MARGIN;
|
||||||
int bgPadding = 8;
|
int bgPadding = 8;
|
||||||
int currentPosX = 0;
|
int currentPosX = 0;
|
||||||
|
|
||||||
@@ -110,32 +86,31 @@ public class VorkathOverlay extends Overlay
|
|||||||
graphics.setColor(COLOR_ICON_BACKGROUND);
|
graphics.setColor(COLOR_ICON_BACKGROUND);
|
||||||
graphics.fillOval(
|
graphics.fillOval(
|
||||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
||||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
||||||
icon.getWidth() + bgPadding * 2,
|
currentPhaseIcon.getWidth() + bgPadding * 2,
|
||||||
icon.getHeight() + bgPadding * 2);
|
currentPhaseIcon.getHeight() + bgPadding * 2);
|
||||||
|
|
||||||
graphics.setColor(COLOR_ICON_BORDER);
|
graphics.setColor(COLOR_ICON_BORDER);
|
||||||
graphics.drawOval(
|
graphics.drawOval(
|
||||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
||||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
||||||
icon.getWidth() + bgPadding * 2,
|
currentPhaseIcon.getWidth() + bgPadding * 2,
|
||||||
icon.getHeight() + bgPadding * 2);
|
currentPhaseIcon.getHeight() + bgPadding * 2);
|
||||||
|
|
||||||
graphics.drawImage(
|
graphics.drawImage(
|
||||||
icon,
|
currentPhaseIcon,
|
||||||
point.getX() - totalWidth / 2 + currentPosX,
|
point.getX() - totalWidth / 2 + currentPosX,
|
||||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE,
|
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE,
|
||||||
null);
|
null);
|
||||||
|
|
||||||
graphics.setColor(COLOR_ICON_BORDER_FILL);
|
graphics.setColor(COLOR_ICON_BORDER_FILL);
|
||||||
Arc2D.Double arc = new Arc2D.Double(
|
Arc2D.Double arc = new Arc2D.Double(
|
||||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
||||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
||||||
icon.getWidth() + bgPadding * 2,
|
currentPhaseIcon.getWidth() + bgPadding * 2,
|
||||||
icon.getHeight() + bgPadding * 2,
|
currentPhaseIcon.getHeight() + bgPadding * 2,
|
||||||
90.0,
|
90.0,
|
||||||
-360.0 * (Vorkath.ATTACKS_PER_SWITCH -
|
-360.0 * getAttacksLeftProgress(),
|
||||||
vorkath.getAttacksUntilSwitch()) / Vorkath.ATTACKS_PER_SWITCH,
|
|
||||||
Arc2D.OPEN);
|
Arc2D.OPEN);
|
||||||
graphics.draw(arc);
|
graphics.draw(arc);
|
||||||
}
|
}
|
||||||
@@ -144,4 +119,39 @@ public class VorkathOverlay extends Overlay
|
|||||||
|
|
||||||
return null;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, https://runelitepl.us
|
* Copyright (c) 2018, https://runelitepl.us
|
||||||
|
* Copyright (c) 2019, Infinitay <https://github.com/Infinitay>
|
||||||
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,25 +26,24 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.vorkath;
|
package net.runelite.client.plugins.vorkath;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import javax.inject.Inject;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.runelite.api.AnimationID;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.GameState;
|
|
||||||
import net.runelite.api.NPC;
|
import net.runelite.api.NPC;
|
||||||
import net.runelite.api.NpcID;
|
import net.runelite.api.NpcID;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
import net.runelite.api.events.AnimationChanged;
|
||||||
import net.runelite.api.events.GameTick;
|
|
||||||
import net.runelite.api.events.NpcDespawned;
|
import net.runelite.api.events.NpcDespawned;
|
||||||
import net.runelite.api.events.NpcSpawned;
|
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.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 net.runelite.client.util.ImageUtil;
|
import net.runelite.client.util.ImageUtil;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Vorkath Helper",
|
name = "Vorkath Helper",
|
||||||
@@ -51,9 +52,11 @@ import net.runelite.client.util.ImageUtil;
|
|||||||
type = PluginType.PVM,
|
type = PluginType.PVM,
|
||||||
enabledByDefault = false
|
enabledByDefault = false
|
||||||
)
|
)
|
||||||
|
@Slf4j
|
||||||
public class VorkathPlugin extends Plugin
|
public class VorkathPlugin extends Plugin
|
||||||
{
|
{
|
||||||
|
private static final int VORKATH_REGION = 9023;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
@@ -66,156 +69,177 @@ public class VorkathPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ZombifiedSpawnOverlay SpawnOverlay;
|
private ZombifiedSpawnOverlay SpawnOverlay;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ClientThread clientThread;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private Vorkath vorkath;
|
private Vorkath vorkath;
|
||||||
|
|
||||||
@Getter
|
@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 ACID;
|
||||||
static final BufferedImage ICE;
|
static final BufferedImage FIRE_BALL;
|
||||||
static final BufferedImage MAGERANGE;
|
static final BufferedImage SPAWN;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
|
UNKNOWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png");
|
||||||
ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png");
|
ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png");
|
||||||
ICE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png");
|
FIRE_BALL = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "fire_strike.png");
|
||||||
MAGERANGE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png");
|
SPAWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onNpcSpawned(NpcSpawned event)
|
public void onNpcSpawned(NpcSpawned event)
|
||||||
{
|
{
|
||||||
NPC npc = event.getNpc();
|
if (isAtVorkath())
|
||||||
if (isNpcVorkath(npc.getId()))
|
|
||||||
{
|
{
|
||||||
this.vorkath = new Vorkath(npc);
|
if (isVorkath(event.getNpc().getId()))
|
||||||
}
|
|
||||||
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())
|
|
||||||
{
|
{
|
||||||
this.vorkath = null;
|
vorkath = new Vorkath(event.getNpc());
|
||||||
reset();
|
lastProjectileCycle = -1;
|
||||||
|
overlayManager.add(overlay);
|
||||||
}
|
}
|
||||||
}
|
else if (isZombifiedSpawn(event.getNpc().getId()))
|
||||||
|
|
||||||
if (this.spawn != null)
|
|
||||||
{
|
|
||||||
if (npc.getId() == this.spawn.getNpc().getId())
|
|
||||||
{
|
{
|
||||||
this.spawn = null;
|
zombifiedSpawn = event.getNpc();
|
||||||
|
overlayManager.add(SpawnOverlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onGameStateChanged(GameStateChanged event)
|
public void onNpcDespawned(NpcDespawned event)
|
||||||
{
|
{
|
||||||
GameState gs = event.getGameState();
|
if (isAtVorkath())
|
||||||
if (gs == GameState.LOGGING_IN ||
|
|
||||||
gs == GameState.CONNECTION_LOST ||
|
|
||||||
gs == GameState.HOPPING)
|
|
||||||
{
|
{
|
||||||
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
|
@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.setAttacksLeft(vorkath.getAttacksLeft() - 1);
|
||||||
{
|
}
|
||||||
vorkath.setPhase(2);
|
else if (vorkathAttack == VorkathAttack.ACID)
|
||||||
vorkath.setAttacksUntilSwitch(Vorkath.ATTACKS_PER_SWITCH);
|
{
|
||||||
}
|
vorkath.updatePhase(Vorkath.Phase.ACID);
|
||||||
else if (animationId == AnimationID.VORKATH_ATTACK && vorkath.getAttacksUntilSwitch() == 0)
|
// Sets the phase's progress indicator to done
|
||||||
{
|
vorkath.setAttacksLeft(0);
|
||||||
vorkath.setPhase(1);
|
}
|
||||||
vorkath.setAttacksUntilSwitch(Vorkath.ATTACKS_PER_SWITCH);
|
else if (vorkathAttack == VorkathAttack.FIRE_BALL)
|
||||||
//Vorkath does a bomb animation after the ice dragon breathe, we need to account for it
|
{
|
||||||
vorkath.setIcePhaseAttack(true);
|
vorkath.updatePhase(Vorkath.Phase.FIRE_BALL);
|
||||||
}
|
// Decrement to account for this fire ball
|
||||||
else if (animationId == AnimationID.VORKATH_ATTACK || animationId == AnimationID.VORKATH_FIRE_BOMB_ATTACK)
|
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1);
|
||||||
{
|
}
|
||||||
if (vorkath.isIcePhaseAttack())
|
else if (vorkathAttack == VorkathAttack.FREEZE_BREATH && vorkath.getLastAttack() != VorkathAttack.ZOMBIFIED_SPAWN)
|
||||||
{
|
{
|
||||||
vorkath.setIcePhaseAttack(false);
|
// Filters out second invisible freeze attack that is immediately after the Zombified Spawn
|
||||||
}
|
vorkath.updatePhase(Vorkath.Phase.SPAWN);
|
||||||
else
|
// Sets progress of the phase to half
|
||||||
{
|
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - (vorkath.getAttacksLeft() / 2));
|
||||||
vorkath.setAttacksUntilSwitch(vorkath.getAttacksUntilSwitch() - 1);
|
}
|
||||||
}
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -48,10 +48,9 @@ public class ZombifiedSpawnOverlay extends Overlay
|
|||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
if (plugin.getSpawn() != null)
|
if (plugin.getZombifiedSpawn() != null)
|
||||||
{
|
{
|
||||||
ZombifiedSpawn spawn = plugin.getSpawn();
|
OverlayUtil.renderActorOverlayImage(graphics, plugin.getZombifiedSpawn(), VorkathPlugin.SPAWN, Color.green, 10);
|
||||||
OverlayUtil.renderActorOverlayImage(graphics, spawn.getNpc(), VorkathPlugin.ICE, Color.green, 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 153 B |
Reference in New Issue
Block a user