From 1c654aa995fe2ed84e581f227a9e8c9d59575fbb Mon Sep 17 00:00:00 2001 From: Lucwousin Date: Fri, 26 Apr 2019 16:50:09 +0200 Subject: [PATCH] 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 --- .../client/plugins/poison/PoisonInfobox.java | 30 ++- .../client/plugins/poison/PoisonPlugin.java | 66 ++++--- .../client/plugins/timers/GameTimer.java | 39 ++-- .../client/plugins/timers/TimerTimer.java | 18 +- .../client/plugins/timers/TimersConfig.java | 2 +- .../client/plugins/timers/TimersPlugin.java | 178 ++++++++++-------- 6 files changed, 180 insertions(+), 153 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonInfobox.java b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonInfobox.java index 44d7746781..f8d7233ab1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonInfobox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonInfobox.java @@ -25,6 +25,8 @@ package net.runelite.client.plugins.poison; import java.awt.Color; +import java.time.Duration; +import java.time.Instant; import java.time.temporal.ChronoUnit; import java.awt.image.BufferedImage; import net.runelite.client.ui.overlay.infobox.Timer; @@ -33,9 +35,9 @@ class PoisonInfobox extends Timer { 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; } @@ -50,5 +52,29 @@ class PoisonInfobox extends Timer { 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; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java index 84a4c5e3d6..05fc574947 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Hydrox6 + * Copyright (c) 2019, Lucas * All rights reserved. * * 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 { - 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_MAXIUMUM_DAMAGE = 20; + private static final int VENOM_MAXIMUM_DAMAGE = 20; private static final BufferedImage HEART_DISEASE; private static final BufferedImage HEART_POISON; @@ -100,11 +101,11 @@ public class PoisonPlugin extends Plugin private int lastDamage; private boolean envenomed; private PoisonInfobox infobox; - private Instant poisonNaturalCure; private Instant nextPoisonTick; - private int lastValue = -1; - private int lastDiseaseValue = -1; + private int lastValue = 0; + private int lastDiseaseValue = 0; private BufferedImage heart; + private int nextTickCount; @Provides PoisonConfig getConfig(ConfigManager configManager) @@ -136,10 +137,9 @@ public class PoisonPlugin extends Plugin envenomed = false; lastDamage = 0; - poisonNaturalCure = null; nextPoisonTick = null; - lastValue = -1; - lastDiseaseValue = -1; + lastValue = 0; + lastDiseaseValue = 0; clientThread.invoke(this::resetHealthIcon); } @@ -150,23 +150,18 @@ public class PoisonPlugin extends Plugin final int poisonValue = client.getVar(VarPlayer.POISON); 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; - if (poisonValue < VENOM_THRESHOLD) + if (nextTickCount - client.getTickCount() <= 30 || lastValue == 0) { - poisonNaturalCure = Instant.now().plus(Duration.of(POISON_TICK_MILLIS * poisonValue, ChronoUnit.MILLIS)); - } - else - { - poisonNaturalCure = null; + nextPoisonTick = Instant.now().plus(Duration.of(POISON_TICK_MILLIS, ChronoUnit.MILLIS)); + nextTickCount = client.getTickCount() + 30; } + lastValue = poisonValue; + final int damage = nextDamage(poisonValue); + this.lastDamage = damage; + if (config.showInfoboxes()) { if (infobox != null) @@ -181,12 +176,12 @@ public class PoisonPlugin extends Plugin if (image != null) { - infobox = new PoisonInfobox(image, this); + int duration = 600 * (nextTickCount - client.getTickCount()); + infobox = new PoisonInfobox(duration, image, this); infoBoxManager.addInfoBox(infobox); } } } - checkHealthIcon(); } @@ -233,9 +228,9 @@ public class PoisonPlugin extends Plugin poisonValue -= VENOM_THRESHOLD - 3; damage = poisonValue * 2; //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 @@ -277,9 +272,13 @@ public class PoisonPlugin extends Plugin 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 minutes = seconds / 60; int secs = seconds % 60; @@ -289,9 +288,20 @@ public class PoisonPlugin extends Plugin 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}
Time until damage: {2}", - envenomed ? "venom" : "poison", ColorUtil.wrapWithColorTag(String.valueOf(lastDamage), Color.RED), getFormattedTime(nextPoisonTick)); - String line2 = envenomed ? "" : MessageFormat.format("
Time until cure: {0}", getFormattedTime(poisonNaturalCure)); + envenomed ? "venom" : "poison", ColorUtil.wrapWithColorTag(String.valueOf(lastDamage), Color.RED), + getFormattedTime(Duration.between(Instant.now(), nextPoisonTick))); + String line2 = envenomed ? "" : MessageFormat.format("
Time until cure: {0}", getFormattedTime(timeLeft)); return line1 + line2; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java index f187d27043..dcd739fad6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java @@ -2,6 +2,7 @@ * Copyright (c) 2017, Seth * Copyright (c) 2017, Adam * Copyright (c) 2018, Jordan Atwood + * Copyright (c) 2019, Lucas * All rights reserved. * * 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), 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), - 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), - ANTIDOTEPLUSPLUS(ItemID.ANTIDOTE4_5952, GameTimerImageType.ITEM, "Antidote++", 12, ChronoUnit.MINUTES), 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), 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), IMBUEDHEART(ItemID.IMBUED_HEART, GameTimerImageType.ITEM, "Imbued heart", GraphicID.IMBUED_HEART, 420, 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), - 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), 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), - 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), 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), 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), - 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 private final Duration duration; @@ -89,12 +83,11 @@ enum GameTimer private final String description; @Getter private final boolean removedOnDeath; - @Getter - private final Duration initialDelay; + private final int imageId; 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.graphicId = graphicId; @@ -102,12 +95,6 @@ enum GameTimer this.imageId = imageId; this.imageType = idType; 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) @@ -115,19 +102,19 @@ enum GameTimer 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) { 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) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java index 8e1fd3c9d4..0a648a43f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, Adam + * Copyright (c) 2019, Lucas * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,8 +26,6 @@ package net.runelite.client.plugins.timers; import java.awt.image.BufferedImage; -import java.time.Duration; -import java.time.Instant; import java.time.temporal.ChronoUnit; import net.runelite.client.plugins.Plugin; import net.runelite.client.ui.overlay.infobox.InfoBoxPriority; @@ -43,18 +42,11 @@ class TimerTimer extends Timer setPriority(InfoBoxPriority.MED); } - @Override - public boolean render() + TimerTimer(GameTimer timer, int amount, Plugin plugin, BufferedImage image) { - final boolean rendered = super.render(); - - if (rendered) - { - final Duration fromStart = Duration.between(getStartTime(), Instant.now()); - return !fromStart.minus(timer.getInitialDelay()).isNegative(); - } - - return false; + super(timer.getDuration().toMillis() * amount, ChronoUnit.MILLIS, image, plugin); + this.timer = timer; + setPriority(InfoBoxPriority.MED); } public GameTimer getTimer() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java index dd42787d73..81f5e818dc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java @@ -44,7 +44,7 @@ public interface TimersConfig extends Config @ConfigItem( keyName = "showAntipoison", 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() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index 18a97e0f00..ebe8f976b0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2017, Seth * Copyright (c) 2018, Jordan Atwood + * Copyright (c) 2019, Lucas * All rights reserved. * * 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.Prayer; import net.runelite.api.SkullIcon; +import net.runelite.api.VarPlayer; +import net.runelite.api.Skill; import net.runelite.api.Varbits; import net.runelite.api.WorldType; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.BoostedLevelChanged; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; 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_EXPIRED_MESSAGE = "Your antifire potion has expired."; - 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_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."; @@ -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 HALF_TELEBLOCK_MESSAGE = "A teleblock spell has been cast on you. It will expire in 2 minutes, 30 seconds."; private static final String IMBUED_HEART_READY_MESSAGE = "Your imbued heart has regained its magical power."; + 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_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_MESSAGE = "Spirits of deceased evildoers offer you their protection"; 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 = "Your stamina potion has expired."; private static final String SUPER_ANTIFIRE_DRINK_MESSAGE = "You drink some of your super antifire potion"; private static final String SUPER_ANTIFIRE_EXPIRED_MESSAGE = "Your super antifire potion has expired."; - 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 int freezeTime = -1; // time frozen, in game ticks @@ -116,12 +120,15 @@ public class TimersPlugin extends Plugin private int lastWildernessVarb; private int lastVengCooldownVarb; private int lastIsVengeancedVarb; + private int lastPoisonVarp; + private int nextPoisonTick; private WorldPoint lastPoint; private TeleportWidget lastTeleportClicked; private int lastAnimation; private boolean loggedInRace; private boolean widgetHiddenChangedOnPvpWorld; private boolean skulledLastTick = false; + private boolean imbuedHeartClicked; @Inject private ItemManager itemManager; @@ -154,6 +161,9 @@ public class TimersPlugin extends Plugin lastAnimation = -1; loggedInRace = false; widgetHiddenChangedOnPvpWorld = false; + lastPoisonVarp = 0; + nextPoisonTick = 0; + imbuedHeartClicked = false; } @Subscribe @@ -162,6 +172,7 @@ public class TimersPlugin extends Plugin int raidVarb = client.getVar(Varbits.IN_RAID); int vengCooldownVarb = client.getVar(Varbits.VENGEANCE_COOLDOWN); int isVengeancedVarb = client.getVar(Varbits.VENGEANCE_ACTIVE); + int poisonVarp = client.getVar(VarPlayer.POISON); if (lastRaidVarb != raidVarb) { @@ -213,6 +224,34 @@ public class TimersPlugin extends Plugin 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 @@ -235,17 +274,6 @@ public class TimersPlugin extends Plugin 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()) { removeGameTimer(ANTIFIRE); @@ -322,63 +350,17 @@ public class TimersPlugin extends Plugin removeGameTimer(ICEBLITZ); removeGameTimer(ICEBARRAGE); } + + if (!config.showAntiPoison()) + { + removeGameTimer(ANTIPOISON); + removeGameTimer(ANTIVENOM); + } } @Subscribe 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() && event.getMenuOption().contains("Drink") && (event.getId() == ItemID.STAMINA_MIX1 @@ -434,6 +416,13 @@ public class TimersPlugin extends Plugin { 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 @@ -504,12 +493,6 @@ public class TimersPlugin extends Plugin 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)) { createGameTimer(MAGICIMBUE); @@ -554,22 +537,17 @@ public class TimersPlugin extends Plugin 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)) { 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")) { createGameTimer(PRAYER_ENHANCE); @@ -871,6 +849,29 @@ public class TimersPlugin extends Plugin 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) { removeGameTimer(timer); @@ -882,6 +883,17 @@ public class TimersPlugin extends Plugin 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) { infoBoxManager.removeIf(t -> t instanceof TimerTimer && ((TimerTimer) t).getTimer() == timer);