Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion runelite-plugin.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
displayName=AttackTimer
author=ngraves95,Lexer747
build=standard
version=1.3.1
version=1.3.2
description=A plugin to countdown until your next attack
tags=pvm,timer,attack,combat,weapon
plugins=com.attacktimer.AttackTimerMetronomePlugin
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ default boolean debugLogs()
@ConfigItem(
position = 10000,
keyName = "attacktimerVersion",
name = "Plugin version: v1.3.1",
name = "Plugin version: v1.3.2",
description = ""
)
default void version()
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/com/attacktimer/AttackTimerMetronomePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ else if (SLOW_FOOD.matcher(message).find())
pendingEatDelayTicks += attackDelay;
}
VariableSpeed.onChatMessage(client, event);
pendingEatDelayTicks += VariableSpeed.MAGGOT_KING.onChatMessage(client, message);
}

// endregion
Expand Down Expand Up @@ -463,8 +464,11 @@ public void onRender()
attackState = AttackState.NOT_ATTACKING;
}
}
attackDelayHoldoffTicks = VariableSpeed.MAGGOT_KING.onRender(client, itemManager, attackDelayHoldoffTicks, currentSpellBook, config.debugLogs());
attackDelayHoldoffTicks = VariableSpeed.DOOM_OF_MOKHAIOTL.onRender(client, itemManager, attackDelayHoldoffTicks, currentSpellBook, config.debugLogs());
if (VariableSpeed.MAGGOT_KING.onRender(client, itemManager, config.debugLogs())
|| VariableSpeed.DOOM_OF_MOKHAIOTL.onRender(client, itemManager, currentSpellBook, config.debugLogs()))
{
performAttack();
}
checkForLateWeaponSwaps();
}

Expand Down
25 changes: 11 additions & 14 deletions src/main/java/com/attacktimer/VariableSpeed/DoomOfMokhaiotl.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

import com.attacktimer.AnimationData;
import com.attacktimer.AttackProcedure;
import com.attacktimer.AttackSpeed;
import com.attacktimer.Attacking.Attacking;
import com.attacktimer.ClientUtils.Utils;
import com.attacktimer.Spellbook;
Expand Down Expand Up @@ -78,14 +77,12 @@ public class DoomOfMokhaiotl implements IVariableSpeed
.build();

private final TickCount tickCount;
private final AttackSpeed attackSpeed;
private int larvaeConsumed = -1;
private int shieldConsumed = -1;

DoomOfMokhaiotl(final TickCount tc, final AttackSpeed attackSpeed)
DoomOfMokhaiotl(final TickCount tc)
{
this.tickCount = tc;
this.attackSpeed = attackSpeed;
}

// https://oldschool.runescape.wiki/w/Doom_of_Mokhaiotl/Strategies#Demonic_larvae
Expand All @@ -97,18 +94,18 @@ public class DoomOfMokhaiotl implements IVariableSpeed
//
// The https://oldschool.runescape.wiki/w/Volatile_earth also has the same larvae mechanics and allow list
// of items.
public int onRender(final Client client, final ItemManager itemManager, final int attackDelayHoldoffTicks, final Spellbook spellbook, final boolean debugLogs)
public boolean onRender(final Client client, final ItemManager itemManager, final Spellbook spellbook, final boolean debugLogs)
{
if (!Utils.isInRegionId(client, DOOM_REGION_IDS))
{
return attackDelayHoldoffTicks;
return false;
}

final var atk = Attacking.PlayerAttack(client);
final AnimationData anim = AnimationData.fromId(atk.getAnimationId());
if (anim == null || atk.getTarget() == null || !(atk.getTarget() instanceof NPC) || anim.isBlockListAnimation())
{
return attackDelayHoldoffTicks;
return false;
}

final NPC npc = (NPC) atk.getTarget();
Expand All @@ -117,27 +114,27 @@ public int onRender(final Client client, final ItemManager itemManager, final in
{
if (tickCount.isWithinNTicks(larvaeConsumed, 1))
{
return attackDelayHoldoffTicks;
return false;
}
final int weaponId = Utils.getWeaponId(client);
final boolean isDemonbaneSpell = spellbook == Spellbook.ARCEUUS && AnimationData.isManualCasting(anim) && anim == AnimationData.MAGIC_ARCEUUS_DEMONBANE;
if (NO_COOLDOWN_WEAPON.contains(weaponId) || isDemonbaneSpell)
{
return attackDelayHoldoffTicks;
return false;
}

if (debugLogs)
{
log.debug("DoomOfMokhaiotl success, attacking larvae with normal weapon");
}
larvaeConsumed = tickCount.get();
return attackSpeed.compute(client, anim, spellbook, itemManager);
return true;
}
else if (npcId == NpcID.DOM_BOSS)
{
if (tickCount.isWithinNTicks(shieldConsumed, 30))
{
return attackDelayHoldoffTicks;
return false;
}
final var animId = npc.getAnimation();
// Undocumented in the wiki but from my testing these can be hit while on cooldown but unlike the
Expand All @@ -160,14 +157,14 @@ else if (npcId == NpcID.DOM_BOSS)
log.debug("DoomOfMokhaiotl success, on cooldown melee swing");
}
shieldConsumed = tickCount.get();
return attackSpeed.compute(client, anim, spellbook, itemManager);
return true;
}
}
return attackDelayHoldoffTicks;
return false;
}
else
{
return attackDelayHoldoffTicks;
return false;
}
}

Expand Down
42 changes: 30 additions & 12 deletions src/main/java/com/attacktimer/VariableSpeed/MaggotKing.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@
*/

import com.attacktimer.AnimationData;
import com.attacktimer.AttackSpeed;
import com.attacktimer.Attacking.Attacking;
import com.attacktimer.ClientUtils.Utils;
import com.attacktimer.Spellbook;
import com.attacktimer.VariableSpeed.State.TickCount;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
Expand All @@ -44,14 +42,12 @@ public class MaggotKing
private static final int MAGGOT_KING_REGION_ID = 11645;

private final TickCount tickCount;
private final AttackSpeed attackSpeed;
// the tick count if a larvae was hit, this is purely to debounce
private int consumed = -1;

MaggotKing(final TickCount tc, final AttackSpeed attackSpeed)
MaggotKing(final TickCount tc)
{
this.tickCount = tc;
this.attackSpeed = attackSpeed;
}

// https://oldschool.runescape.wiki/w/Maggot_King/Strategies#Ur-maggot_larvae
Expand All @@ -62,30 +58,52 @@ public class MaggotKing
// Therefore this method returns `attackDelayHoldoffTicks` in all cases where this condition isn't met.
// But if the condition is met this method returns a brand new number which is the attack speed of the bow
// used. This number can be the same as the current delay and that's ok.
public int onRender(final Client client, final ItemManager itemManager, final int attackDelayHoldoffTicks, final Spellbook spellbook, final boolean debugLogs)
public boolean onRender(final Client client, final ItemManager itemManager, final boolean debugLogs)
{
if (!Utils.isInRegionId(client, MAGGOT_KING_REGION_ID) || tickCount.isWithinNTicks(consumed, 1))
{
return attackDelayHoldoffTicks;
return false;
}

final var atk = Attacking.PlayerAttack(client);
final AnimationData anim = AnimationData.fromId(atk.getAnimationId());
if (anim == null || atk.getTarget() == null || !(atk.getTarget() instanceof NPC))
{
return attackDelayHoldoffTicks;
return false;
}

final NPC npc = (NPC) atk.getTarget();
if (npc.getId() != NpcID.UR_MAGGOT_LARVAE || !anim.isStandardBowAttack() || npc.getAnimation() != AnimationID.UR_MAGGOT_LARVAE_FLY)
if (npc.getId() != NpcID.UR_MAGGOT_LARVAE || !anim.isStandardBowAttack()
|| npc.getAnimation() != AnimationID.UR_MAGGOT_LARVAE_FLY)
{
return attackDelayHoldoffTicks;
return false;
}
consumed = tickCount.get();
if (debugLogs)
{
log.debug("MaggotKing success, attacking flying maggot with bow");
}
consumed = tickCount.get();
return attackSpeed.compute(client, anim, spellbook, itemManager);
return true;
}

public int onChatMessage(final Client client, final String message)
{
// https://oldschool.runescape.wiki/w/Maggot_King/Strategies#Fight_overview
// Standing on the sticky bile will ... delay the player's next attack by one tick.
if (message.contains("The sticky acid hampers your ability to attack!"))
{
log.debug("MaggotKing sticky acid");
return 1;
}
// this isn't in the wiki but being screeched at also slows down attack speed, more significantly than
// the bile. Each screech instance causes the effect for a total of 9 extra ticks if all goes wrong.
//
// note don't use equals colouring of messages breaks stuff: e.g.: '@mes_hl_red@The Maggot King's screech disrupts your concentration!' but it has also been <col=XXXXXX>
else if (message.contains("The Maggot King's screech disrupts your concentration!"))
{
log.debug("MaggotKing screech");
return 3;
}
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ public static void onNpcDespawned(final Client client, final NpcDespawned npcDes
// Variable speed that doesn't neatly fit in to the IVariable speed pattern (it's not weapon related
// but boss related).
public static final ShadowCrash SHADOW_CRASH = new ShadowCrash(YAMA, MARK_OF_DARKNESS, AttackTimerMetronomePlugin.TC);
public static final MaggotKing MAGGOT_KING = new MaggotKing(AttackTimerMetronomePlugin.TC, AttackTimerMetronomePlugin.ATTACK_SPEED);
public static final DoomOfMokhaiotl DOOM_OF_MOKHAIOTL = new DoomOfMokhaiotl(AttackTimerMetronomePlugin.TC, AttackTimerMetronomePlugin.ATTACK_SPEED);
public static final MaggotKing MAGGOT_KING = new MaggotKing(AttackTimerMetronomePlugin.TC);
public static final DoomOfMokhaiotl DOOM_OF_MOKHAIOTL = new DoomOfMokhaiotl(AttackTimerMetronomePlugin.TC);

private static final IStateTracker[] TO_TRACK = {
// State tracking, these do not contribute themselves to any variable speed weapon/mechanic but
Expand Down
Loading