Add dynamic hitpoints orb icon to poison plugin (#6517)
To improve visibility of poison/venom/disease on low HP, also recolor heart icon when poisoned/venomed/diseased.
This commit is contained in:
committed by
Tomas Slusny
parent
8ae13515fc
commit
ffb60d5b2a
@@ -37,6 +37,10 @@ public enum VarPlayer
|
||||
ATTACK_STYLE(43),
|
||||
QUEST_POINTS(101),
|
||||
IS_POISONED(102),
|
||||
/**
|
||||
* Seems to start at 50(10 splash) and goes down by 1 every 30 seconds
|
||||
*/
|
||||
DISEASE_VALUE(456),
|
||||
|
||||
BANK_TAB(115),
|
||||
|
||||
|
||||
@@ -42,4 +42,14 @@ public interface PoisonConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "changeHealthIcon",
|
||||
name = "Change HP Orb Icon",
|
||||
description = "Configures whether the hp orb icon should change color to match poison/disease"
|
||||
)
|
||||
default boolean changeHealthIcon()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,12 +35,13 @@ import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
@@ -50,22 +51,36 @@ import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Poison",
|
||||
description = "Tracks current damage values for Poison and Venom",
|
||||
tags = {"combat", "poison", "venom"}
|
||||
tags = {"combat", "poison", "venom", "heart", "hp"}
|
||||
)
|
||||
@Slf4j
|
||||
public class PoisonPlugin extends Plugin
|
||||
{
|
||||
static final int POISON_TICK_MILLIS = 18200;
|
||||
private static final int VENOM_THRESHOLD = 1000000;
|
||||
private static final int VENOM_MAXIUMUM_DAMAGE = 20;
|
||||
|
||||
private static final BufferedImage HEART_DISEASE;
|
||||
private static final BufferedImage HEART_POISON;
|
||||
private static final BufferedImage HEART_VENOM;
|
||||
|
||||
static
|
||||
{
|
||||
HEART_DISEASE = ImageUtil.resizeCanvas(ImageUtil.getResourceStreamFromClass(PoisonPlugin.class, "1067-DISEASE.png"), 26, 26);
|
||||
HEART_POISON = ImageUtil.resizeCanvas(ImageUtil.getResourceStreamFromClass(PoisonPlugin.class, "1067-POISON.png"), 26, 26);
|
||||
HEART_VENOM = ImageUtil.resizeCanvas(ImageUtil.getResourceStreamFromClass(PoisonPlugin.class, "1067-VENOM.png"), 26, 26);
|
||||
}
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private PoisonOverlay poisonOverlay;
|
||||
|
||||
@@ -88,6 +103,8 @@ public class PoisonPlugin extends Plugin
|
||||
private Instant poisonNaturalCure;
|
||||
private Instant nextPoisonTick;
|
||||
private int lastValue = -1;
|
||||
private int lastDiseaseValue = -1;
|
||||
private BufferedImage heart;
|
||||
|
||||
@Provides
|
||||
PoisonConfig getConfig(ConfigManager configManager)
|
||||
@@ -99,6 +116,11 @@ public class PoisonPlugin extends Plugin
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(poisonOverlay);
|
||||
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
clientThread.invoke(this::checkHealthIcon);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,64 +139,87 @@ public class PoisonPlugin extends Plugin
|
||||
poisonNaturalCure = null;
|
||||
nextPoisonTick = null;
|
||||
lastValue = -1;
|
||||
lastDiseaseValue = -1;
|
||||
|
||||
clientThread.invoke(this::resetHealthIcon);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
final int poisonValue = client.getVar(VarPlayer.POISON);
|
||||
if (poisonValue == lastValue)
|
||||
if (poisonValue != lastValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lastValue = poisonValue;
|
||||
nextPoisonTick = Instant.now().plus(Duration.of(POISON_TICK_MILLIS, ChronoUnit.MILLIS));
|
||||
|
||||
lastValue = poisonValue;
|
||||
nextPoisonTick = Instant.now().plus(Duration.of(POISON_TICK_MILLIS, ChronoUnit.MILLIS));
|
||||
final int damage = nextDamage(poisonValue);
|
||||
this.lastDamage = damage;
|
||||
|
||||
final int damage = nextDamage(poisonValue);
|
||||
this.lastDamage = damage;
|
||||
envenomed = poisonValue >= VENOM_THRESHOLD;
|
||||
|
||||
envenomed = poisonValue >= VENOM_THRESHOLD;
|
||||
|
||||
if (poisonValue < VENOM_THRESHOLD)
|
||||
{
|
||||
poisonNaturalCure = Instant.now().plus(Duration.of(POISON_TICK_MILLIS * poisonValue, ChronoUnit.MILLIS));
|
||||
}
|
||||
else
|
||||
{
|
||||
poisonNaturalCure = null;
|
||||
}
|
||||
|
||||
if (config.showInfoboxes())
|
||||
{
|
||||
if (infobox != null)
|
||||
if (poisonValue < VENOM_THRESHOLD)
|
||||
{
|
||||
infoBoxManager.removeInfoBox(infobox);
|
||||
infobox = null;
|
||||
poisonNaturalCure = Instant.now().plus(Duration.of(POISON_TICK_MILLIS * poisonValue, ChronoUnit.MILLIS));
|
||||
}
|
||||
else
|
||||
{
|
||||
poisonNaturalCure = null;
|
||||
}
|
||||
|
||||
if (damage > 0)
|
||||
if (config.showInfoboxes())
|
||||
{
|
||||
final BufferedImage image = getSplat(envenomed ? SpriteID.HITSPLAT_DARK_GREEN_VENOM : SpriteID.HITSPLAT_GREEN_POISON, damage);
|
||||
|
||||
if (image != null)
|
||||
if (infobox != null)
|
||||
{
|
||||
infobox = new PoisonInfobox(image, this);
|
||||
infoBoxManager.addInfoBox(infobox);
|
||||
infoBoxManager.removeInfoBox(infobox);
|
||||
infobox = null;
|
||||
}
|
||||
|
||||
if (damage > 0)
|
||||
{
|
||||
final BufferedImage image = getSplat(envenomed ? SpriteID.HITSPLAT_DARK_GREEN_VENOM : SpriteID.HITSPLAT_GREEN_POISON, damage);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
infobox = new PoisonInfobox(image, this);
|
||||
infoBoxManager.addInfoBox(infobox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkHealthIcon();
|
||||
}
|
||||
|
||||
final int diseaseValue = client.getVar(VarPlayer.DISEASE_VALUE);
|
||||
if (diseaseValue != lastDiseaseValue)
|
||||
{
|
||||
lastDiseaseValue = diseaseValue;
|
||||
checkHealthIcon();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals(PoisonConfig.GROUP) && !config.showInfoboxes() && infobox != null)
|
||||
if (!event.getGroup().equals(PoisonConfig.GROUP))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.showInfoboxes() && infobox != null)
|
||||
{
|
||||
infoBoxManager.removeInfoBox(infobox);
|
||||
infobox = null;
|
||||
}
|
||||
|
||||
if (config.changeHealthIcon())
|
||||
{
|
||||
clientThread.invoke(this::checkHealthIcon);
|
||||
}
|
||||
else
|
||||
{
|
||||
clientThread.invoke(this::resetHealthIcon);
|
||||
}
|
||||
}
|
||||
|
||||
private static int nextDamage(int poisonValue)
|
||||
@@ -250,4 +295,53 @@ public class PoisonPlugin extends Plugin
|
||||
|
||||
return line1 + line2;
|
||||
}
|
||||
|
||||
private void checkHealthIcon()
|
||||
{
|
||||
if (!config.changeHealthIcon())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final BufferedImage newHeart;
|
||||
final int poison = client.getVar(VarPlayer.IS_POISONED);
|
||||
|
||||
if (poison >= VENOM_THRESHOLD)
|
||||
{
|
||||
newHeart = HEART_VENOM;
|
||||
}
|
||||
else if (poison > 0)
|
||||
{
|
||||
newHeart = HEART_POISON;
|
||||
}
|
||||
else if (client.getVar(VarPlayer.DISEASE_VALUE) > 0)
|
||||
{
|
||||
newHeart = HEART_DISEASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetHealthIcon();
|
||||
return;
|
||||
}
|
||||
|
||||
// Only update sprites when the heart icon actually changes
|
||||
if (newHeart != heart)
|
||||
{
|
||||
heart = newHeart;
|
||||
client.getWidgetSpriteCache().reset();
|
||||
client.getSpriteOverrides().put(SpriteID.MINIMAP_ORB_HITPOINTS_ICON, ImageUtil.getImageSpritePixels(heart, client));
|
||||
}
|
||||
}
|
||||
|
||||
private void resetHealthIcon()
|
||||
{
|
||||
if (heart == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.getWidgetSpriteCache().reset();
|
||||
client.getSpriteOverrides().remove(SpriteID.MINIMAP_ORB_HITPOINTS_ICON);
|
||||
heart = null;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Reference in New Issue
Block a user