Loads of poison improvements, and a touch of imbued heart (#135)

* Fix poison plugin (check rl #7967 for more info)

* Timers: make antipoison/venom more accurate (rl #7956)

* Timers: Make imbued heart timer work in combat
This commit is contained in:
Lucwousin
2019-04-26 16:50:09 +02:00
committed by Kyleeld
parent 24d7f431db
commit 1c654aa995
6 changed files with 180 additions and 153 deletions

View File

@@ -25,6 +25,8 @@
package net.runelite.client.plugins.poison; package net.runelite.client.plugins.poison;
import java.awt.Color; import java.awt.Color;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import net.runelite.client.ui.overlay.infobox.Timer; import net.runelite.client.ui.overlay.infobox.Timer;
@@ -33,9 +35,9 @@ class PoisonInfobox extends Timer
{ {
private final PoisonPlugin plugin; private final PoisonPlugin plugin;
PoisonInfobox(BufferedImage image, PoisonPlugin plugin) PoisonInfobox(int duration, BufferedImage image, PoisonPlugin plugin)
{ {
super(PoisonPlugin.POISON_TICK_MILLIS, ChronoUnit.MILLIS, image, plugin); super(duration, ChronoUnit.MILLIS, image, plugin);
this.plugin = plugin; this.plugin = plugin;
} }
@@ -50,5 +52,29 @@ class PoisonInfobox extends Timer
{ {
return Color.RED.brighter(); return Color.RED.brighter();
} }
@Override
public String getText()
{
Duration timeLeft = Duration.between(Instant.now(), getEndTime());
if (!timeLeft.isNegative())
{
return super.getText();
}
return " ";
}
@Override
public boolean render()
{
return true;
}
@Override
public boolean cull()
{
return false;
}
} }

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 Hydrox6 <ikada@protonmail.ch> * Copyright (c) 2018 Hydrox6 <ikada@protonmail.ch>
* Copyright (c) 2019, Lucas <https://github.com/Lucwousin>
* 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
@@ -60,9 +61,9 @@ import net.runelite.client.util.ImageUtil;
) )
public class PoisonPlugin extends Plugin public class PoisonPlugin extends Plugin
{ {
static final int POISON_TICK_MILLIS = 18200; private static final int POISON_TICK_MILLIS = 18000;
private static final int VENOM_THRESHOLD = 1000000; private static final int VENOM_THRESHOLD = 1000000;
private static final int VENOM_MAXIUMUM_DAMAGE = 20; private static final int VENOM_MAXIMUM_DAMAGE = 20;
private static final BufferedImage HEART_DISEASE; private static final BufferedImage HEART_DISEASE;
private static final BufferedImage HEART_POISON; private static final BufferedImage HEART_POISON;
@@ -100,11 +101,11 @@ public class PoisonPlugin extends Plugin
private int lastDamage; private int lastDamage;
private boolean envenomed; private boolean envenomed;
private PoisonInfobox infobox; private PoisonInfobox infobox;
private Instant poisonNaturalCure;
private Instant nextPoisonTick; private Instant nextPoisonTick;
private int lastValue = -1; private int lastValue = 0;
private int lastDiseaseValue = -1; private int lastDiseaseValue = 0;
private BufferedImage heart; private BufferedImage heart;
private int nextTickCount;
@Provides @Provides
PoisonConfig getConfig(ConfigManager configManager) PoisonConfig getConfig(ConfigManager configManager)
@@ -136,10 +137,9 @@ public class PoisonPlugin extends Plugin
envenomed = false; envenomed = false;
lastDamage = 0; lastDamage = 0;
poisonNaturalCure = null;
nextPoisonTick = null; nextPoisonTick = null;
lastValue = -1; lastValue = 0;
lastDiseaseValue = -1; lastDiseaseValue = 0;
clientThread.invoke(this::resetHealthIcon); clientThread.invoke(this::resetHealthIcon);
} }
@@ -150,23 +150,18 @@ public class PoisonPlugin extends Plugin
final int poisonValue = client.getVar(VarPlayer.POISON); final int poisonValue = client.getVar(VarPlayer.POISON);
if (poisonValue != lastValue) if (poisonValue != lastValue)
{ {
lastValue = poisonValue;
nextPoisonTick = Instant.now().plus(Duration.of(POISON_TICK_MILLIS, ChronoUnit.MILLIS));
final int damage = nextDamage(poisonValue);
this.lastDamage = damage;
envenomed = poisonValue >= VENOM_THRESHOLD; envenomed = poisonValue >= VENOM_THRESHOLD;
if (poisonValue < VENOM_THRESHOLD) if (nextTickCount - client.getTickCount() <= 30 || lastValue == 0)
{ {
poisonNaturalCure = Instant.now().plus(Duration.of(POISON_TICK_MILLIS * poisonValue, ChronoUnit.MILLIS)); nextPoisonTick = Instant.now().plus(Duration.of(POISON_TICK_MILLIS, ChronoUnit.MILLIS));
} nextTickCount = client.getTickCount() + 30;
else
{
poisonNaturalCure = null;
} }
lastValue = poisonValue;
final int damage = nextDamage(poisonValue);
this.lastDamage = damage;
if (config.showInfoboxes()) if (config.showInfoboxes())
{ {
if (infobox != null) if (infobox != null)
@@ -181,12 +176,12 @@ public class PoisonPlugin extends Plugin
if (image != null) if (image != null)
{ {
infobox = new PoisonInfobox(image, this); int duration = 600 * (nextTickCount - client.getTickCount());
infobox = new PoisonInfobox(duration, image, this);
infoBoxManager.addInfoBox(infobox); infoBoxManager.addInfoBox(infobox);
} }
} }
} }
checkHealthIcon(); checkHealthIcon();
} }
@@ -233,9 +228,9 @@ public class PoisonPlugin extends Plugin
poisonValue -= VENOM_THRESHOLD - 3; poisonValue -= VENOM_THRESHOLD - 3;
damage = poisonValue * 2; damage = poisonValue * 2;
//Venom Damage caps at 20, but the VarPlayer keeps increasing //Venom Damage caps at 20, but the VarPlayer keeps increasing
if (damage > VENOM_MAXIUMUM_DAMAGE) if (damage > VENOM_MAXIMUM_DAMAGE)
{ {
damage = VENOM_MAXIUMUM_DAMAGE; damage = VENOM_MAXIMUM_DAMAGE;
} }
} }
else else
@@ -277,9 +272,13 @@ public class PoisonPlugin extends Plugin
return splat; return splat;
} }
private static String getFormattedTime(Instant endTime) private static String getFormattedTime(Duration timeLeft)
{ {
final Duration timeLeft = Duration.between(Instant.now(), endTime); if (timeLeft.isNegative())
{
return "Now!";
}
int seconds = (int) (timeLeft.toMillis() / 1000L); int seconds = (int) (timeLeft.toMillis() / 1000L);
int minutes = seconds / 60; int minutes = seconds / 60;
int secs = seconds % 60; int secs = seconds % 60;
@@ -289,9 +288,20 @@ public class PoisonPlugin extends Plugin
String createTooltip() String createTooltip()
{ {
Duration timeLeft;
if (nextPoisonTick.isBefore(Instant.now()) && !envenomed)
{
timeLeft = Duration.of(POISON_TICK_MILLIS * (lastValue - 1), ChronoUnit.MILLIS);
}
else
{
timeLeft = Duration.between(Instant.now(), nextPoisonTick).plusMillis(POISON_TICK_MILLIS * (lastValue - 1));
}
String line1 = MessageFormat.format("Next {0} damage: {1}</br>Time until damage: {2}", String line1 = MessageFormat.format("Next {0} damage: {1}</br>Time until damage: {2}",
envenomed ? "venom" : "poison", ColorUtil.wrapWithColorTag(String.valueOf(lastDamage), Color.RED), getFormattedTime(nextPoisonTick)); envenomed ? "venom" : "poison", ColorUtil.wrapWithColorTag(String.valueOf(lastDamage), Color.RED),
String line2 = envenomed ? "" : MessageFormat.format("</br>Time until cure: {0}", getFormattedTime(poisonNaturalCure)); getFormattedTime(Duration.between(Instant.now(), nextPoisonTick)));
String line2 = envenomed ? "" : MessageFormat.format("</br>Time until cure: {0}", getFormattedTime(timeLeft));
return line1 + line2; return line1 + line2;
} }

View File

@@ -2,6 +2,7 @@
* Copyright (c) 2017, Seth <Sethtroll3@gmail.com> * Copyright (c) 2017, Seth <Sethtroll3@gmail.com>
* Copyright (c) 2017, Adam <Adam@sigterm.info> * Copyright (c) 2017, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com> * Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
* Copyright (c) 2019, Lucas <https://github.com/Lucwousin>
* 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
@@ -48,10 +49,7 @@ enum GameTimer
HALFTB(SpriteID.SPELL_TELE_BLOCK, GameTimerImageType.SPRITE, "Half Teleblock", 150, ChronoUnit.SECONDS, true), HALFTB(SpriteID.SPELL_TELE_BLOCK, GameTimerImageType.SPRITE, "Half Teleblock", 150, ChronoUnit.SECONDS, true),
DMM_FULLTB(SpriteID.SPELL_TELE_BLOCK, GameTimerImageType.SPRITE, "Deadman Mode Full Teleblock", 150, ChronoUnit.SECONDS, true), DMM_FULLTB(SpriteID.SPELL_TELE_BLOCK, GameTimerImageType.SPRITE, "Deadman Mode Full Teleblock", 150, ChronoUnit.SECONDS, true),
DMM_HALFTB(SpriteID.SPELL_TELE_BLOCK, GameTimerImageType.SPRITE, "Deadman Mode Half Teleblock", 75, ChronoUnit.SECONDS, true), DMM_HALFTB(SpriteID.SPELL_TELE_BLOCK, GameTimerImageType.SPRITE, "Deadman Mode Half Teleblock", 75, ChronoUnit.SECONDS, true),
ANTIVENOMPLUS(ItemID.ANTIVENOM4_12913, GameTimerImageType.ITEM, "Anti-venom+", 3, ChronoUnit.MINUTES, true),
ANTIVENOMPLUS_ANTIPOSION(ItemID.SUPERANTIPOISON4, GameTimerImageType.ITEM, "Anti-venom+ Antipoison", 15, ChronoUnit.MINUTES, 3),
SUPERANTIFIRE(ItemID.SUPER_ANTIFIRE_POTION4, GameTimerImageType.ITEM, "Super antifire", 3, ChronoUnit.MINUTES), SUPERANTIFIRE(ItemID.SUPER_ANTIFIRE_POTION4, GameTimerImageType.ITEM, "Super antifire", 3, ChronoUnit.MINUTES),
ANTIDOTEPLUSPLUS(ItemID.ANTIDOTE4_5952, GameTimerImageType.ITEM, "Antidote++", 12, ChronoUnit.MINUTES),
BIND(SpriteID.SPELL_BIND, GameTimerImageType.SPRITE, "Bind", GraphicID.BIND, 5, ChronoUnit.SECONDS, true), BIND(SpriteID.SPELL_BIND, GameTimerImageType.SPRITE, "Bind", GraphicID.BIND, 5, ChronoUnit.SECONDS, true),
HALFBIND(SpriteID.SPELL_BIND, GameTimerImageType.SPRITE, "Half Bind", GraphicID.BIND, 2500, ChronoUnit.MILLIS, true), HALFBIND(SpriteID.SPELL_BIND, GameTimerImageType.SPRITE, "Half Bind", GraphicID.BIND, 2500, ChronoUnit.MILLIS, true),
SNARE(SpriteID.SPELL_SNARE, GameTimerImageType.SPRITE, "Snare", GraphicID.SNARE, 10, ChronoUnit.SECONDS, true), SNARE(SpriteID.SPELL_SNARE, GameTimerImageType.SPRITE, "Snare", GraphicID.SNARE, 10, ChronoUnit.SECONDS, true),
@@ -64,22 +62,18 @@ enum GameTimer
ICEBARRAGE(SpriteID.SPELL_ICE_BARRAGE, GameTimerImageType.SPRITE, "Ice barrage", GraphicID.ICE_BARRAGE, 20, ChronoUnit.SECONDS, true), ICEBARRAGE(SpriteID.SPELL_ICE_BARRAGE, GameTimerImageType.SPRITE, "Ice barrage", GraphicID.ICE_BARRAGE, 20, ChronoUnit.SECONDS, true),
IMBUEDHEART(ItemID.IMBUED_HEART, GameTimerImageType.ITEM, "Imbued heart", GraphicID.IMBUED_HEART, 420, ChronoUnit.SECONDS), IMBUEDHEART(ItemID.IMBUED_HEART, GameTimerImageType.ITEM, "Imbued heart", GraphicID.IMBUED_HEART, 420, ChronoUnit.SECONDS),
VENGEANCE(SpriteID.SPELL_VENGEANCE, GameTimerImageType.SPRITE, "Vengeance", 30, ChronoUnit.SECONDS), VENGEANCE(SpriteID.SPELL_VENGEANCE, GameTimerImageType.SPRITE, "Vengeance", 30, ChronoUnit.SECONDS),
ANTIDOTEPLUS(ItemID.ANTIDOTE4, GameTimerImageType.ITEM, "Antidote+", 518, ChronoUnit.SECONDS),
ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom", 1, ChronoUnit.MINUTES, true),
ANTIVENOM_ANTIPOISON(ItemID.ANTIPOISON4, GameTimerImageType.ITEM, "Anti-venom Antipoison", 12, ChronoUnit.MINUTES, 1),
EXSUPERANTIFIRE(ItemID.EXTENDED_SUPER_ANTIFIRE4, GameTimerImageType.ITEM, "Extended Super AntiFire", 6, ChronoUnit.MINUTES), EXSUPERANTIFIRE(ItemID.EXTENDED_SUPER_ANTIFIRE4, GameTimerImageType.ITEM, "Extended Super AntiFire", 6, ChronoUnit.MINUTES),
SANFEW(ItemID.SANFEW_SERUM4, GameTimerImageType.ITEM, "Sanfew serum", 6, ChronoUnit.MINUTES, true),
OVERLOAD_RAID(ItemID.OVERLOAD_4_20996, GameTimerImageType.ITEM, "Overload", 5, ChronoUnit.MINUTES, true), OVERLOAD_RAID(ItemID.OVERLOAD_4_20996, GameTimerImageType.ITEM, "Overload", 5, ChronoUnit.MINUTES, true),
PRAYER_ENHANCE(ItemID.PRAYER_ENHANCE_4, GameTimerImageType.ITEM, "Prayer enhance", 290, ChronoUnit.SECONDS, true), PRAYER_ENHANCE(ItemID.PRAYER_ENHANCE_4, GameTimerImageType.ITEM, "Prayer enhance", 290, ChronoUnit.SECONDS, true),
GOD_WARS_ALTAR(SpriteID.SKILL_PRAYER, GameTimerImageType.SPRITE, "God wars altar", 10, ChronoUnit.MINUTES), GOD_WARS_ALTAR(SpriteID.SKILL_PRAYER, GameTimerImageType.SPRITE, "God wars altar", 10, ChronoUnit.MINUTES),
ANTIPOISON(ItemID.ANTIPOISON4, GameTimerImageType.ITEM, "Antipoison", 90, ChronoUnit.SECONDS),
SUPERANTIPOISON(ItemID.SUPERANTIPOISON4, GameTimerImageType.ITEM, "Superantipoison", 346, ChronoUnit.SECONDS),
CHARGE(SpriteID.SPELL_CHARGE, GameTimerImageType.SPRITE, "Charge", 6, ChronoUnit.MINUTES), CHARGE(SpriteID.SPELL_CHARGE, GameTimerImageType.SPRITE, "Charge", 6, ChronoUnit.MINUTES),
STAFF_OF_THE_DEAD(ItemID.STAFF_OF_THE_DEAD, GameTimerImageType.ITEM, "Staff of the Dead", 1, ChronoUnit.MINUTES), STAFF_OF_THE_DEAD(ItemID.STAFF_OF_THE_DEAD, GameTimerImageType.ITEM, "Staff of the Dead", 1, ChronoUnit.MINUTES),
ABYSSAL_SIRE_STUN(ItemID.ABYSSAL_ORPHAN, GameTimerImageType.ITEM, "Abyssal Sire Stun", 30, ChronoUnit.SECONDS, true), ABYSSAL_SIRE_STUN(ItemID.ABYSSAL_ORPHAN, GameTimerImageType.ITEM, "Abyssal Sire Stun", 30, ChronoUnit.SECONDS, true),
HOME_TELEPORT(SpriteID.SPELL_LUMBRIDGE_HOME_TELEPORT, GameTimerImageType.SPRITE, "Home Teleport", 30, ChronoUnit.MINUTES), HOME_TELEPORT(SpriteID.SPELL_LUMBRIDGE_HOME_TELEPORT, GameTimerImageType.SPRITE, "Home Teleport", 30, ChronoUnit.MINUTES),
MINIGAME_TELEPORT(SpriteID.TAB_QUESTS_RED_MINIGAMES, GameTimerImageType.SPRITE, "Minigame Teleport", 20, ChronoUnit.MINUTES), MINIGAME_TELEPORT(SpriteID.TAB_QUESTS_RED_MINIGAMES, GameTimerImageType.SPRITE, "Minigame Teleport", 20, ChronoUnit.MINUTES),
SKULL(SpriteID.PLAYER_KILLER_SKULL_523, GameTimerImageType.SPRITE, "Skull", 20, ChronoUnit.MINUTES); SKULL(SpriteID.PLAYER_KILLER_SKULL_523, GameTimerImageType.SPRITE, "Skull", 20, ChronoUnit.MINUTES),
ANTIPOISON(ItemID.ANTIPOISON4, GameTimerImageType.ITEM, "Antipoison"),
ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom");
@Getter @Getter
private final Duration duration; private final Duration duration;
@@ -89,12 +83,11 @@ enum GameTimer
private final String description; private final String description;
@Getter @Getter
private final boolean removedOnDeath; private final boolean removedOnDeath;
@Getter
private final Duration initialDelay;
private final int imageId; private final int imageId;
private final GameTimerImageType imageType; private final GameTimerImageType imageType;
GameTimer(int imageId, GameTimerImageType idType, String description, Integer graphicId, long time, ChronoUnit unit, long delay, boolean removedOnDeath) GameTimer(int imageId, GameTimerImageType idType, String description, Integer graphicId, long time, ChronoUnit unit, boolean removedOnDeath)
{ {
this.description = description; this.description = description;
this.graphicId = graphicId; this.graphicId = graphicId;
@@ -102,12 +95,6 @@ enum GameTimer
this.imageId = imageId; this.imageId = imageId;
this.imageType = idType; this.imageType = idType;
this.removedOnDeath = removedOnDeath; this.removedOnDeath = removedOnDeath;
this.initialDelay = Duration.of(delay, unit);
}
GameTimer(int imageId, GameTimerImageType idType, String description, Integer graphicId, long time, ChronoUnit unit, boolean removedOnDeath)
{
this(imageId, idType, description, graphicId, time, unit, 0, removedOnDeath);
} }
GameTimer(int imageId, GameTimerImageType idType, String description, long time, ChronoUnit unit, boolean removeOnDeath) GameTimer(int imageId, GameTimerImageType idType, String description, long time, ChronoUnit unit, boolean removeOnDeath)
@@ -115,19 +102,19 @@ enum GameTimer
this(imageId, idType, description, null, time, unit, removeOnDeath); this(imageId, idType, description, null, time, unit, removeOnDeath);
} }
GameTimer(int imageId, GameTimerImageType idType, String description, long time, ChronoUnit unit)
{
this(imageId, idType, description, null, time, unit, false);
}
GameTimer(int imageId, GameTimerImageType idType, String description, Integer graphicId, long time, ChronoUnit unit) GameTimer(int imageId, GameTimerImageType idType, String description, Integer graphicId, long time, ChronoUnit unit)
{ {
this(imageId, idType, description, graphicId, time, unit, false); this(imageId, idType, description, graphicId, time, unit, false);
} }
GameTimer(int imageId, GameTimerImageType idType, String description, long time, ChronoUnit unit, long delay) GameTimer(int imageId, GameTimerImageType idType, String description, long time, ChronoUnit unit)
{ {
this(imageId, idType, description, null, time, unit, delay, false); this(imageId, idType, description, null, time, unit, false);
}
GameTimer(int imageId, GameTimerImageType idType, String description)
{
this(imageId, idType, description, null, 1, ChronoUnit.MILLIS, false);
} }
BufferedImage getImage(ItemManager itemManager, SpriteManager spriteManager) BufferedImage getImage(ItemManager itemManager, SpriteManager spriteManager)

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2017, Adam <Adam@sigterm.info> * Copyright (c) 2017, Adam <Adam@sigterm.info>
* Copyright (c) 2019, Lucas <https://github.com/Lucwousin>
* 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
@@ -25,8 +26,6 @@
package net.runelite.client.plugins.timers; package net.runelite.client.plugins.timers;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.ui.overlay.infobox.InfoBoxPriority; import net.runelite.client.ui.overlay.infobox.InfoBoxPriority;
@@ -43,18 +42,11 @@ class TimerTimer extends Timer
setPriority(InfoBoxPriority.MED); setPriority(InfoBoxPriority.MED);
} }
@Override TimerTimer(GameTimer timer, int amount, Plugin plugin, BufferedImage image)
public boolean render()
{ {
final boolean rendered = super.render(); super(timer.getDuration().toMillis() * amount, ChronoUnit.MILLIS, image, plugin);
this.timer = timer;
if (rendered) setPriority(InfoBoxPriority.MED);
{
final Duration fromStart = Duration.between(getStartTime(), Instant.now());
return !fromStart.minus(timer.getInitialDelay()).isNegative();
}
return false;
} }
public GameTimer getTimer() public GameTimer getTimer()

View File

@@ -44,7 +44,7 @@ public interface TimersConfig extends Config
@ConfigItem( @ConfigItem(
keyName = "showAntipoison", keyName = "showAntipoison",
name = "Antipoison/Venom timers", name = "Antipoison/Venom timers",
description = "Configures whether timers for Antipoision, Antidoe, Antivenom are is displayed" description = "Configures whether timers for poison and venom protection are displayed"
) )
default boolean showAntiPoison() default boolean showAntiPoison()
{ {

View File

@@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2017, Seth <Sethtroll3@gmail.com> * Copyright (c) 2017, Seth <Sethtroll3@gmail.com>
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com> * Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
* Copyright (c) 2019, Lucas <https://github.com/Lucwousin>
* 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
@@ -44,10 +45,13 @@ import net.runelite.api.NpcID;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.Prayer; import net.runelite.api.Prayer;
import net.runelite.api.SkullIcon; import net.runelite.api.SkullIcon;
import net.runelite.api.VarPlayer;
import net.runelite.api.Skill;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import net.runelite.api.WorldType; import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.AnimationChanged;
import net.runelite.api.events.BoostedLevelChanged;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
@@ -83,7 +87,6 @@ public class TimersPlugin extends Plugin
{ {
private static final String ANTIFIRE_DRINK_MESSAGE = "You drink some of your antifire potion."; private static final String ANTIFIRE_DRINK_MESSAGE = "You drink some of your antifire potion.";
private static final String ANTIFIRE_EXPIRED_MESSAGE = "<col=7f007f>Your antifire potion has expired.</col>"; private static final String ANTIFIRE_EXPIRED_MESSAGE = "<col=7f007f>Your antifire potion has expired.</col>";
private static final String ANTIVENOM_DRINK_MESSAGE = "You drink some of your antivenom potion";
private static final String CANNON_FURNACE_MESSAGE = "You add the furnace."; private static final String CANNON_FURNACE_MESSAGE = "You add the furnace.";
private static final String CANNON_PICKUP_MESSAGE = "You pick up the cannon. It's really heavy."; private static final String CANNON_PICKUP_MESSAGE = "You pick up the cannon. It's really heavy.";
private static final String CANNON_REPAIR_MESSAGE = "You repair your cannon, restoring it to working order."; private static final String CANNON_REPAIR_MESSAGE = "You repair your cannon, restoring it to working order.";
@@ -97,9 +100,9 @@ public class TimersPlugin extends Plugin
private static final String GOD_WARS_ALTAR_MESSAGE = "you recharge your prayer."; private static final String GOD_WARS_ALTAR_MESSAGE = "you recharge your prayer.";
private static final String HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A teleblock spell has been cast on you. It will expire in 2 minutes, 30 seconds.</col>"; private static final String HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A teleblock spell has been cast on you. It will expire in 2 minutes, 30 seconds.</col>";
private static final String IMBUED_HEART_READY_MESSAGE = "<col=ef1020>Your imbued heart has regained its magical power.</col>"; private static final String IMBUED_HEART_READY_MESSAGE = "<col=ef1020>Your imbued heart has regained its magical power.</col>";
private static final String IMBUED_HEART_NOTREADY_MESSAGE = "The heart is still drained of its power.";
private static final String MAGIC_IMBUE_EXPIRED_MESSAGE = "Your Magic Imbue charge has ended."; private static final String MAGIC_IMBUE_EXPIRED_MESSAGE = "Your Magic Imbue charge has ended.";
private static final String MAGIC_IMBUE_MESSAGE = "You are charged to combine runes!"; private static final String MAGIC_IMBUE_MESSAGE = "You are charged to combine runes!";
private static final String SANFEW_SERUM_DRINK_MESSAGE = "You drink some of your Sanfew Serum.";
private static final String STAFF_OF_THE_DEAD_SPEC_EXPIRED_MESSAGE = "Your protection fades away"; private static final String STAFF_OF_THE_DEAD_SPEC_EXPIRED_MESSAGE = "Your protection fades away";
private static final String STAFF_OF_THE_DEAD_SPEC_MESSAGE = "Spirits of deceased evildoers offer you their protection"; private static final String STAFF_OF_THE_DEAD_SPEC_MESSAGE = "Spirits of deceased evildoers offer you their protection";
private static final String STAMINA_DRINK_MESSAGE = "You drink some of your stamina potion."; private static final String STAMINA_DRINK_MESSAGE = "You drink some of your stamina potion.";
@@ -107,7 +110,8 @@ public class TimersPlugin extends Plugin
private static final String STAMINA_EXPIRED_MESSAGE = "<col=8f4808>Your stamina potion has expired.</col>"; private static final String STAMINA_EXPIRED_MESSAGE = "<col=8f4808>Your stamina potion has expired.</col>";
private static final String SUPER_ANTIFIRE_DRINK_MESSAGE = "You drink some of your super antifire potion"; private static final String SUPER_ANTIFIRE_DRINK_MESSAGE = "You drink some of your super antifire potion";
private static final String SUPER_ANTIFIRE_EXPIRED_MESSAGE = "<col=7f007f>Your super antifire potion has expired.</col>"; private static final String SUPER_ANTIFIRE_EXPIRED_MESSAGE = "<col=7f007f>Your super antifire potion has expired.</col>";
private static final String SUPER_ANTIVENOM_DRINK_MESSAGE = "You drink some of your super antivenom potion"; private static final int VENOM_VALUE_CUTOFF = -40; // Antivenom < -40 =< Antipoison < 0
private static final int POISON_TICK_LENGTH = 30;
private TimerTimer freezeTimer; private TimerTimer freezeTimer;
private int freezeTime = -1; // time frozen, in game ticks private int freezeTime = -1; // time frozen, in game ticks
@@ -116,12 +120,15 @@ public class TimersPlugin extends Plugin
private int lastWildernessVarb; private int lastWildernessVarb;
private int lastVengCooldownVarb; private int lastVengCooldownVarb;
private int lastIsVengeancedVarb; private int lastIsVengeancedVarb;
private int lastPoisonVarp;
private int nextPoisonTick;
private WorldPoint lastPoint; private WorldPoint lastPoint;
private TeleportWidget lastTeleportClicked; private TeleportWidget lastTeleportClicked;
private int lastAnimation; private int lastAnimation;
private boolean loggedInRace; private boolean loggedInRace;
private boolean widgetHiddenChangedOnPvpWorld; private boolean widgetHiddenChangedOnPvpWorld;
private boolean skulledLastTick = false; private boolean skulledLastTick = false;
private boolean imbuedHeartClicked;
@Inject @Inject
private ItemManager itemManager; private ItemManager itemManager;
@@ -154,6 +161,9 @@ public class TimersPlugin extends Plugin
lastAnimation = -1; lastAnimation = -1;
loggedInRace = false; loggedInRace = false;
widgetHiddenChangedOnPvpWorld = false; widgetHiddenChangedOnPvpWorld = false;
lastPoisonVarp = 0;
nextPoisonTick = 0;
imbuedHeartClicked = false;
} }
@Subscribe @Subscribe
@@ -162,6 +172,7 @@ public class TimersPlugin extends Plugin
int raidVarb = client.getVar(Varbits.IN_RAID); int raidVarb = client.getVar(Varbits.IN_RAID);
int vengCooldownVarb = client.getVar(Varbits.VENGEANCE_COOLDOWN); int vengCooldownVarb = client.getVar(Varbits.VENGEANCE_COOLDOWN);
int isVengeancedVarb = client.getVar(Varbits.VENGEANCE_ACTIVE); int isVengeancedVarb = client.getVar(Varbits.VENGEANCE_ACTIVE);
int poisonVarp = client.getVar(VarPlayer.POISON);
if (lastRaidVarb != raidVarb) if (lastRaidVarb != raidVarb)
{ {
@@ -213,6 +224,34 @@ public class TimersPlugin extends Plugin
lastWildernessVarb = inWilderness; lastWildernessVarb = inWilderness;
} }
if (lastPoisonVarp != poisonVarp && config.showAntiPoison())
{
if (nextPoisonTick - client.getTickCount() <= 0 || lastPoisonVarp == 0)
{
nextPoisonTick = client.getTickCount() + 30;
}
if (poisonVarp >= 0)
{
removeGameTimer(ANTIPOISON);
removeGameTimer(ANTIVENOM);
}
else if (poisonVarp >= VENOM_VALUE_CUTOFF)
{
int duration = 600 * (nextPoisonTick - client.getTickCount() + Math.abs((poisonVarp + 1) * POISON_TICK_LENGTH));
removeGameTimer(ANTIVENOM);
createGameTimer(ANTIPOISON, duration);
}
else
{
int duration = 600 * (nextPoisonTick - client.getTickCount() + Math.abs((poisonVarp + 1 - VENOM_VALUE_CUTOFF) * POISON_TICK_LENGTH));
removeGameTimer(ANTIPOISON);
createGameTimer(ANTIVENOM, duration);
}
lastPoisonVarp = poisonVarp;
}
} }
@Subscribe @Subscribe
@@ -235,17 +274,6 @@ public class TimersPlugin extends Plugin
removeGameTimer(MINIGAME_TELEPORT); removeGameTimer(MINIGAME_TELEPORT);
} }
if (!config.showAntiPoison())
{
removeGameTimer(ANTIDOTEPLUS);
removeGameTimer(ANTIDOTEPLUSPLUS);
removeGameTimer(SANFEW);
removeGameTimer(ANTIVENOM);
removeGameTimer(ANTIVENOMPLUS);
removeGameTimer(ANTIVENOM_ANTIPOISON);
removeGameTimer(ANTIVENOMPLUS_ANTIPOSION);
}
if (!config.showAntiFire()) if (!config.showAntiFire())
{ {
removeGameTimer(ANTIFIRE); removeGameTimer(ANTIFIRE);
@@ -322,63 +350,17 @@ public class TimersPlugin extends Plugin
removeGameTimer(ICEBLITZ); removeGameTimer(ICEBLITZ);
removeGameTimer(ICEBARRAGE); removeGameTimer(ICEBARRAGE);
} }
if (!config.showAntiPoison())
{
removeGameTimer(ANTIPOISON);
removeGameTimer(ANTIVENOM);
}
} }
@Subscribe @Subscribe
public void onMenuOptionClicked(MenuOptionClicked event) public void onMenuOptionClicked(MenuOptionClicked event)
{ {
if (config.showAntiPoison()
&& event.getMenuOption().contains("Drink")
&& (event.getId() == ItemID.ANTIDOTE1_5958
|| event.getId() == ItemID.ANTIDOTE2_5956
|| event.getId() == ItemID.ANTIDOTE3_5954
|| event.getId() == ItemID.ANTIDOTE4_5952))
{
// Needs menu option hook because drink message is intercepting with antipoison message
createGameTimer(ANTIDOTEPLUSPLUS);
return;
}
if (config.showAntiPoison()
&& event.getMenuOption().contains("Drink")
&& (event.getId() == ItemID.ANTIDOTE1
|| event.getId() == ItemID.ANTIDOTE2
|| event.getId() == ItemID.ANTIDOTE3
|| event.getId() == ItemID.ANTIDOTE4
|| event.getId() == ItemID.ANTIDOTE_MIX1
|| event.getId() == ItemID.ANTIDOTE_MIX2))
{
// Needs menu option hook because drink message is intercepting with antipoison message
createGameTimer(ANTIDOTEPLUS);
return;
}
if (config.showAntiPoison()
&& event.getMenuOption().contains("Drink")
&& (event.getId() == ItemID.ANTIPOISON1
|| event.getId() == ItemID.ANTIPOISON2
|| event.getId() == ItemID.ANTIPOISON3
|| event.getId() == ItemID.ANTIPOISON4
|| event.getId() == ItemID.ANTIPOISON_MIX1
|| event.getId() == ItemID.ANTIPOISON_MIX2))
{
createGameTimer(ANTIPOISON);
return;
}
if (config.showAntiPoison()
&& event.getMenuOption().contains("Drink")
&& (event.getId() == ItemID.SUPERANTIPOISON1
|| event.getId() == ItemID.SUPERANTIPOISON2
|| event.getId() == ItemID.SUPERANTIPOISON3
|| event.getId() == ItemID.SUPERANTIPOISON4
|| event.getId() == ItemID.ANTIPOISON_SUPERMIX1
|| event.getId() == ItemID.ANTIPOISON_SUPERMIX2))
{
createGameTimer(SUPERANTIPOISON);
return;
}
if (config.showStamina() if (config.showStamina()
&& event.getMenuOption().contains("Drink") && event.getMenuOption().contains("Drink")
&& (event.getId() == ItemID.STAMINA_MIX1 && (event.getId() == ItemID.STAMINA_MIX1
@@ -434,6 +416,13 @@ public class TimersPlugin extends Plugin
{ {
lastTeleportClicked = teleportWidget; lastTeleportClicked = teleportWidget;
} }
if (config.showImbuedHeart()
&& event.getMenuOption().contains("Invigorate"))
{
// Needs a hook as there's a few cases where potions boost the same amount as the heart
imbuedHeartClicked = true;
}
} }
@Subscribe @Subscribe
@@ -504,12 +493,6 @@ public class TimersPlugin extends Plugin
removeGameTimer(CANNON); removeGameTimer(CANNON);
} }
if (config.showAntiPoison() && event.getMessage().contains(SUPER_ANTIVENOM_DRINK_MESSAGE))
{
createGameTimer(ANTIVENOMPLUS);
createGameTimer(ANTIVENOMPLUS_ANTIPOSION);
}
if (config.showMagicImbue() && event.getMessage().equals(MAGIC_IMBUE_MESSAGE)) if (config.showMagicImbue() && event.getMessage().equals(MAGIC_IMBUE_MESSAGE))
{ {
createGameTimer(MAGICIMBUE); createGameTimer(MAGICIMBUE);
@@ -554,22 +537,17 @@ public class TimersPlugin extends Plugin
removeGameTimer(SUPERANTIFIRE); removeGameTimer(SUPERANTIFIRE);
} }
if (config.showImbuedHeart() && event.getMessage().contains(IMBUED_HEART_NOTREADY_MESSAGE))
{
imbuedHeartClicked = false;
return;
}
if (config.showImbuedHeart() && event.getMessage().equals(IMBUED_HEART_READY_MESSAGE)) if (config.showImbuedHeart() && event.getMessage().equals(IMBUED_HEART_READY_MESSAGE))
{ {
removeGameTimer(IMBUEDHEART); removeGameTimer(IMBUEDHEART);
} }
if (config.showAntiPoison() && event.getMessage().contains(ANTIVENOM_DRINK_MESSAGE))
{
createGameTimer(ANTIVENOM);
createGameTimer(ANTIVENOM_ANTIPOISON);
}
if (config.showAntiPoison() && event.getMessage().contains(SANFEW_SERUM_DRINK_MESSAGE))
{
createGameTimer(SANFEW);
}
if (config.showPrayerEnhance() && event.getMessage().startsWith("You drink some of your") && event.getMessage().contains("prayer enhance")) if (config.showPrayerEnhance() && event.getMessage().startsWith("You drink some of your") && event.getMessage().contains("prayer enhance"))
{ {
createGameTimer(PRAYER_ENHANCE); createGameTimer(PRAYER_ENHANCE);
@@ -871,6 +849,29 @@ public class TimersPlugin extends Plugin
infoBoxManager.removeIf(t -> t instanceof TimerTimer && ((TimerTimer) t).getTimer().isRemovedOnDeath()); infoBoxManager.removeIf(t -> t instanceof TimerTimer && ((TimerTimer) t).getTimer().isRemovedOnDeath());
} }
@Subscribe
public void onBoostedLevelChanged(BoostedLevelChanged event)
{
Skill skill = event.getSkill();
if (skill != Skill.MAGIC || !config.showImbuedHeart() || !imbuedHeartClicked)
{
return;
}
int magicLvl = client.getRealSkillLevel(skill);
int magicBoost = client.getBoostedSkillLevel(skill);
int heartBoost = 1 + (int) (magicLvl * 0.1);
if (magicBoost - magicLvl != heartBoost)
{
return;
}
imbuedHeartClicked = false;
createGameTimer(IMBUEDHEART);
}
private TimerTimer createGameTimer(final GameTimer timer) private TimerTimer createGameTimer(final GameTimer timer)
{ {
removeGameTimer(timer); removeGameTimer(timer);
@@ -882,6 +883,17 @@ public class TimersPlugin extends Plugin
return t; return t;
} }
private TimerTimer createGameTimer(final GameTimer timer, final int duration)
{
removeGameTimer(timer);
BufferedImage image = timer.getImage(itemManager, spriteManager);
TimerTimer t = new TimerTimer(timer, duration, this, image);
t.setTooltip(timer.getDescription());
infoBoxManager.addInfoBox(t);
return t;
}
private void removeGameTimer(GameTimer timer) private void removeGameTimer(GameTimer timer)
{ {
infoBoxManager.removeIf(t -> t instanceof TimerTimer && ((TimerTimer) t).getTimer() == timer); infoBoxManager.removeIf(t -> t instanceof TimerTimer && ((TimerTimer) t).getTimer() == timer);